diff --git a/flake.lock b/flake.lock index 5e8a32a..42ea3b1 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1743964447, - "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", + "lastModified": 1771369470, + "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", + "rev": "0182a361324364ae3f436a63005877674cf45efb", "type": "github" }, "original": { @@ -18,22 +18,7 @@ }, "root": { "inputs": { - "nixpkgs": "nixpkgs", - "systems": "systems" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "id": "systems", - "type": "indirect" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index ea66976..c3a010d 100644 --- a/flake.nix +++ b/flake.nix @@ -8,10 +8,9 @@ outputs = { self, nixpkgs, - systems, }: let eachSystem = f: - nixpkgs.lib.genAttrs (import systems) (system: + nixpkgs.lib.genAttrs ["x86_64-linux" "aarch64-linux"] (system: f rec { inherit system; pkgs = nixpkgs.legacyPackages.${system}; diff --git a/go.mod b/go.mod index 9ec83cf..7556996 100644 --- a/go.mod +++ b/go.mod @@ -1,84 +1,65 @@ module ben.soroos.net/tsnet-proxy -go 1.24.0 +go 1.25.5 -toolchain go1.24.1 - -require tailscale.com v1.82.0 +require tailscale.com v1.94.1 require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/akutz/memconn v0.1.0 // indirect github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect - github.com/aws/aws-sdk-go-v2 v1.36.0 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.29.5 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.58 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 // indirect - github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 // indirect - github.com/aws/smithy-go v1.22.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect + github.com/aws/smithy-go v1.24.0 // indirect github.com/coder/websocket v1.8.12 // indirect - github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect + github.com/creachadair/msync v0.7.1 // indirect github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect - github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/gaissmai/bart v0.18.0 // indirect - github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect - github.com/illarion/gonotify/v3 v3.0.2 // indirect - github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/jsimonetti/rtnetlink v1.4.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect - github.com/mdlayher/genetlink v1.3.2 // indirect + github.com/klauspost/compress v1.18.2 // indirect github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect - github.com/mdlayher/sdnotify v1.0.0 // indirect github.com/mdlayher/socket v0.5.0 // indirect - github.com/miekg/dns v1.1.58 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect - github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pires/go-proxyproto v0.8.1 // indirect github.com/prometheus-community/pro-bing v0.4.0 // indirect github.com/safchain/ethtool v0.3.0 // indirect github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect - github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect - github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect - github.com/tailscale/wireguard-go v0.0.0-20250107165329-0b8b35511f19 // indirect - github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect - github.com/vishvananda/netns v0.0.4 // indirect + github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da // indirect github.com/x448/float16 v0.8.4 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/net v0.36.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.10.0 // indirect - golang.org/x/tools v0.30.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.32.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/time v0.12.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 // indirect diff --git a/go.sum b/go.sum index 7e7d91c..135345d 100644 --- a/go.sum +++ b/go.sum @@ -1,94 +1,99 @@ +9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f h1:1C7nZuxUMNz7eiQALRfiqNOm04+m3edWlRff/BYHf0Q= +9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f/go.mod h1:hHyrZRryGqVdqrknjq5OWDLGCTJ2NeEvtrpR96mjraM= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk= -github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= +github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4= +github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= github.com/aws/aws-sdk-go-v2/config v1.29.5 h1:4lS2IB+wwkj5J43Tq/AwvnscBerBJtQQ6YS7puzCI1k= github.com/aws/aws-sdk-go-v2/config v1.29.5/go.mod h1:SNzldMlDVbN6nWxM7XsUiNXPSa1LWlqiXtvh/1PrJGg= github.com/aws/aws-sdk-go-v2/credentials v1.17.58 h1:/d7FUpAPU8Lf2KUdjniQvfNdlMID0Sd9pS23FJ3SS9Y= github.com/aws/aws-sdk-go-v2/credentials v1.17.58/go.mod h1:aVYW33Ow10CyMQGFgC0ptMRIqJWvJ4nxZb0sUiuQT/A= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 h1:O+8vD2rGjfihBewr5bT+QUfYUHIxCVgG61LHoT59shM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12/go.mod h1:usVdWJaosa66NMvmCrr08NcWDBRv4E6+YFG2pUdw1Lk= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM= github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 h1:a8HvP/+ew3tKwSXqL3BCSjiuicr+XTU2eFYeogV9GJE= github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7/go.mod h1:Q7XIWsMo0JcMpI/6TGD6XXcXcV1DbTj6e9BKNntIMIM= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 h1:3LXNnmtH3TURctC23hnC0p/39Q5gre3FI7BNOiDcVWc= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.13/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w= -github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= -github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk= -github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk= +github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= +github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02 h1:bXAPYSbdYbS5VTy92NIUbeDI1qyggi+JYh5op9IFlcQ= +github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= +github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= +github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho= +github.com/creachadair/msync v0.7.1/go.mod h1:8CcFlLsSujfHE5wWm19uUBLHIPDAUr6LXDwneVMO008= +github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc= +github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g= github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= -github.com/dsnet/try v0.0.3 h1:ptR59SsrcFUYbT/FhAbKTV6iLkeD6O18qfIWRml2fqI= -github.com/dsnet/try v0.0.3/go.mod h1:WBM8tRpUmnXXhY1U6/S8dt6UWdHTQ7y8A5YSkRCkq40= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo= github.com/gaissmai/bart v0.18.0/go.mod h1:JJzMAhNF5Rjo4SF4jWBrANuJfqY+FvsFhW7t1UZJ+XY= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= -github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= -github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I= +github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 h1:cf60tHxREO3g1nroKr2osU3JWZsJzkfi7rEg+oAB0Lo= +github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737/go.mod h1:MIS0jDzbU/vuM9MC4YnBITCv+RYuTRq8dJzmCrFsK9g= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.4 h1:awZRf9FwOeTunQmHoDYSHJps3ie6f1UlhS1fOdPEt1I= +github.com/google/go-tpm v0.9.4/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI= github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 h1:fiJdrgVBkjZ5B1HJ2WQwNOaXB+QyYcNXTA3t1XYLz0M= -github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeVNmJMk= github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U= github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA= @@ -97,12 +102,10 @@ github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJ github.com/jellydator/ttlcache/v3 v3.1.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I= github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= @@ -129,32 +132,26 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= 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/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0= +github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4= github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= -github.com/tailscale/golang-x-crypto v0.0.0-20250218230618-9a281fd8faca h1:ecjHwH73Yvqf/oIdQ2vxAX+zc6caQsYdPzsxNW1J3G8= -github.com/tailscale/golang-x-crypto v0.0.0-20250218230618-9a281fd8faca/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= -github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio= -github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= +github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM= +github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= @@ -165,74 +162,66 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:U github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y= -github.com/tailscale/wireguard-go v0.0.0-20250107165329-0b8b35511f19 h1:BcEJP2ewTIK2ZCsqgl6YGpuO6+oKqqag5HHb7ehljKw= -github.com/tailscale/wireguard-go v0.0.0-20250107165329-0b8b35511f19/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg= github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= -github.com/u-root/u-root v0.12.0 h1:K0AuBFriwr0w/PGS3HawiAw89e3+MU7ks80GpghAsNs= -github.com/u-root/u-root v0.12.0/go.mod h1:FYjTOh4IkIZHhjsd17lb8nYW6udgXdJhG1c0r6u0arI= +github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg= +github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE= 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/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= -github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4hOxG5YpKCzkek= go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= -golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= -golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= +golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 h1:2gap+Kh/3F47cO6hAu3idFvsJ0ue6TRcEi2IUkv/F8k= gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= -honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= -honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= +honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho= +honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0/go.mod h1:EPDDhEZqVHhWuPI5zPAsjU0U7v9xNIWjoOVyZ5ZcniQ= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= -tailscale.com v1.82.0 h1:pposomel4h6Je4brJydcdc2ixNQWDaZyGr5v5MdRr/o= -tailscale.com v1.82.0/go.mod h1:iU6kohVzG+bP0/5XjqBAnW8/6nSG/Du++bO+x7VJZD0= +tailscale.com v1.94.1 h1:0dAst/ozTuFkgmxZULc3oNwR9+qPIt5ucvzH7kaM0Jw= +tailscale.com v1.94.1/go.mod h1:gLnVrEOP32GWvroaAHHGhjSGMPJ1i4DvqNwEg+Yuov4= diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go deleted file mode 100644 index fe63fed..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/arn/arn.go +++ /dev/null @@ -1,92 +0,0 @@ -// Package arn provides a parser for interacting with Amazon Resource Names. -package arn - -import ( - "errors" - "strings" -) - -const ( - arnDelimiter = ":" - arnSections = 6 - arnPrefix = "arn:" - - // zero-indexed - sectionPartition = 1 - sectionService = 2 - sectionRegion = 3 - sectionAccountID = 4 - sectionResource = 5 - - // errors - invalidPrefix = "arn: invalid prefix" - invalidSections = "arn: not enough sections" -) - -// ARN captures the individual fields of an Amazon Resource Name. -// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information. -type ARN struct { - // The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in - // other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China - // (Beijing) region is "aws-cn". - Partition string - - // The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of - // namespaces, see - // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces. - Service string - - // The region the resource resides in. Note that the ARNs for some resources do not require a region, so this - // component might be omitted. - Region string - - // The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the - // ARNs for some resources don't require an account number, so this component might be omitted. - AccountID string - - // The content of this part of the ARN varies by service. It often includes an indicator of the type of resource — - // for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the - // resource name itself. Some services allows paths for resource names, as described in - // http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths. - Resource string -} - -// Parse parses an ARN into its constituent parts. -// -// Some example ARNs: -// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment -// arn:aws:iam::123456789012:user/David -// arn:aws:rds:eu-west-1:123456789012:db:mysql-db -// arn:aws:s3:::my_corporate_bucket/exampleobject.png -func Parse(arn string) (ARN, error) { - if !strings.HasPrefix(arn, arnPrefix) { - return ARN{}, errors.New(invalidPrefix) - } - sections := strings.SplitN(arn, arnDelimiter, arnSections) - if len(sections) != arnSections { - return ARN{}, errors.New(invalidSections) - } - return ARN{ - Partition: sections[sectionPartition], - Service: sections[sectionService], - Region: sections[sectionRegion], - AccountID: sections[sectionAccountID], - Resource: sections[sectionResource], - }, nil -} - -// IsARN returns whether the given string is an arn -// by looking for whether the string starts with arn: -func IsARN(arn string) bool { - return strings.HasPrefix(arn, arnPrefix) && strings.Count(arn, ":") >= arnSections-1 -} - -// String returns the canonical representation of the ARN -func (arn ARN) String() string { - return arnPrefix + - arn.Partition + arnDelimiter + - arn.Service + arnDelimiter + - arn.Region + arnDelimiter + - arn.AccountID + arnDelimiter + - arn.Resource -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go index a015cc5..3219517 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go @@ -6,6 +6,7 @@ import ( smithybearer "github.com/aws/smithy-go/auth/bearer" "github.com/aws/smithy-go/logging" "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" ) // HTTPClient provides the interface to provide custom HTTPClients. Generally @@ -192,6 +193,17 @@ type Config struct { // This variable is sourced from environment variable AWS_RESPONSE_CHECKSUM_VALIDATION or // the shared config profile attribute "response_checksum_validation". ResponseChecksumValidation ResponseChecksumValidation + + // Registry of HTTP interceptors. + Interceptors smithyhttp.InterceptorRegistry + + // Priority list of preferred auth scheme IDs. + AuthSchemePreference []string + + // ServiceOptions provides service specific configuration options that will be applied + // when constructing clients for specific services. Each callback function receives the service ID + // and the service's Options struct, allowing for dynamic configuration based on the service. + ServiceOptions []func(string, any) } // NewConfig returns a new Config pointer that can be chained with builder diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go index 781ac0a..623890e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go @@ -172,6 +172,17 @@ func (p *CredentialsCache) getCreds() (Credentials, bool) { return *c, true } +// ProviderSources returns a list of where the underlying credential provider +// has been sourced, if available. Returns empty if the provider doesn't implement +// the interface +func (p *CredentialsCache) ProviderSources() []CredentialSource { + asSource, ok := p.provider.(CredentialProviderSource) + if !ok { + return []CredentialSource{} + } + return asSource.ProviderSources() +} + // Invalidate will invalidate the cached credentials. The next call to Retrieve // will cause the provider's Retrieve method to be called. func (p *CredentialsCache) Invalidate() { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go index 98ba770..9f94cfe 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go @@ -70,6 +70,60 @@ func (AnonymousCredentials) Retrieve(context.Context) (Credentials, error) { fmt.Errorf("the AnonymousCredentials is not a valid credential provider, and cannot be used to sign AWS requests with") } +// CredentialSource is the source of the credential provider. +// A provider can have multiple credential sources: For example, a provider that reads a profile, calls ECS to +// get credentials and then assumes a role using STS will have all these as part of its provider chain. +type CredentialSource int + +const ( + // CredentialSourceUndefined is the sentinel zero value + CredentialSourceUndefined CredentialSource = iota + // CredentialSourceCode credentials resolved from code, cli parameters, session object, or client instance + CredentialSourceCode + // CredentialSourceEnvVars credentials resolved from environment variables + CredentialSourceEnvVars + // CredentialSourceEnvVarsSTSWebIDToken credentials resolved from environment variables for assuming a role with STS using a web identity token + CredentialSourceEnvVarsSTSWebIDToken + // CredentialSourceSTSAssumeRole credentials resolved from STS using AssumeRole + CredentialSourceSTSAssumeRole + // CredentialSourceSTSAssumeRoleSaml credentials resolved from STS using assume role with SAML + CredentialSourceSTSAssumeRoleSaml + // CredentialSourceSTSAssumeRoleWebID credentials resolved from STS using assume role with web identity + CredentialSourceSTSAssumeRoleWebID + // CredentialSourceSTSFederationToken credentials resolved from STS using a federation token + CredentialSourceSTSFederationToken + // CredentialSourceSTSSessionToken credentials resolved from STS using a session token S + CredentialSourceSTSSessionToken + // CredentialSourceProfile credentials resolved from a config file(s) profile with static credentials + CredentialSourceProfile + // CredentialSourceProfileSourceProfile credentials resolved from a source profile in a config file(s) profile + CredentialSourceProfileSourceProfile + // CredentialSourceProfileNamedProvider credentials resolved from a named provider in a config file(s) profile (like EcsContainer) + CredentialSourceProfileNamedProvider + // CredentialSourceProfileSTSWebIDToken credentials resolved from configuration for assuming a role with STS using web identity token in a config file(s) profile + CredentialSourceProfileSTSWebIDToken + // CredentialSourceProfileSSO credentials resolved from an SSO session in a config file(s) profile + CredentialSourceProfileSSO + // CredentialSourceSSO credentials resolved from an SSO session + CredentialSourceSSO + // CredentialSourceProfileSSOLegacy credentials resolved from an SSO session in a config file(s) profile using legacy format + CredentialSourceProfileSSOLegacy + // CredentialSourceSSOLegacy credentials resolved from an SSO session using legacy format + CredentialSourceSSOLegacy + // CredentialSourceProfileProcess credentials resolved from a process in a config file(s) profile + CredentialSourceProfileProcess + // CredentialSourceProcess credentials resolved from a process + CredentialSourceProcess + // CredentialSourceHTTP credentials resolved from an HTTP endpoint + CredentialSourceHTTP + // CredentialSourceIMDS credentials resolved from the instance metadata service (IMDS) + CredentialSourceIMDS + // CredentialSourceProfileLogin credentials resolved from an `aws login` session sourced from a profile + CredentialSourceProfileLogin + // CredentialSourceLogin credentials resolved from an `aws login` session + CredentialSourceLogin +) + // A Credentials is the AWS credentials value for individual credential fields. type Credentials struct { // AWS Access key ID @@ -125,6 +179,13 @@ type CredentialsProvider interface { Retrieve(ctx context.Context) (Credentials, error) } +// CredentialProviderSource allows any credential provider to track +// all providers where a credential provider were sourced. For example, if the credentials came from a +// call to a role specified in the profile, this method will give the whole breadcrumb trail +type CredentialProviderSource interface { + ProviderSources() []CredentialSource +} + // CredentialsProviderFunc provides a helper wrapping a function value to // satisfy the CredentialsProvider interface. type CredentialsProviderFunc func(context.Context) (Credentials, error) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go index 512d8d8..c9d0bdc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go @@ -3,4 +3,4 @@ package aws // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.36.0" +const goModuleVersion = "1.41.0" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go index 01d758d..157a715 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go @@ -76,30 +76,97 @@ type UserAgentFeature string // Enumerates UserAgentFeature. const ( - UserAgentFeatureResourceModel UserAgentFeature = "A" // n/a (we don't generate separate resource types) - UserAgentFeatureWaiter = "B" - UserAgentFeaturePaginator = "C" - UserAgentFeatureRetryModeLegacy = "D" // n/a (equivalent to standard) - UserAgentFeatureRetryModeStandard = "E" - UserAgentFeatureRetryModeAdaptive = "F" - UserAgentFeatureS3Transfer = "G" - UserAgentFeatureS3CryptoV1N = "H" // n/a (crypto client is external) - UserAgentFeatureS3CryptoV2 = "I" // n/a - UserAgentFeatureS3ExpressBucket = "J" - UserAgentFeatureS3AccessGrants = "K" // not yet implemented - UserAgentFeatureGZIPRequestCompression = "L" - UserAgentFeatureProtocolRPCV2CBOR = "M" - UserAgentFeatureRequestChecksumCRC32 = "U" - UserAgentFeatureRequestChecksumCRC32C = "V" - UserAgentFeatureRequestChecksumCRC64 = "W" - UserAgentFeatureRequestChecksumSHA1 = "X" - UserAgentFeatureRequestChecksumSHA256 = "Y" - UserAgentFeatureRequestChecksumWhenSupported = "Z" - UserAgentFeatureRequestChecksumWhenRequired = "a" - UserAgentFeatureResponseChecksumWhenSupported = "b" - UserAgentFeatureResponseChecksumWhenRequired = "c" + UserAgentFeatureResourceModel UserAgentFeature = "A" // n/a (we don't generate separate resource types) + + UserAgentFeatureWaiter = "B" + UserAgentFeaturePaginator = "C" + + UserAgentFeatureRetryModeLegacy = "D" // n/a (equivalent to standard) + UserAgentFeatureRetryModeStandard = "E" + UserAgentFeatureRetryModeAdaptive = "F" + + UserAgentFeatureS3Transfer = "G" + UserAgentFeatureS3CryptoV1N = "H" // n/a (crypto client is external) + UserAgentFeatureS3CryptoV2 = "I" // n/a + UserAgentFeatureS3ExpressBucket = "J" + UserAgentFeatureS3AccessGrants = "K" // not yet implemented + + UserAgentFeatureGZIPRequestCompression = "L" + + UserAgentFeatureProtocolRPCV2CBOR = "M" + + UserAgentFeatureAccountIDEndpoint = "O" // DO NOT IMPLEMENT: rules output is not currently defined. SDKs should not parse endpoints for feature information. + UserAgentFeatureAccountIDModePreferred = "P" + UserAgentFeatureAccountIDModeDisabled = "Q" + UserAgentFeatureAccountIDModeRequired = "R" + + UserAgentFeatureRequestChecksumCRC32 = "U" + UserAgentFeatureRequestChecksumCRC32C = "V" + UserAgentFeatureRequestChecksumCRC64 = "W" + UserAgentFeatureRequestChecksumSHA1 = "X" + UserAgentFeatureRequestChecksumSHA256 = "Y" + UserAgentFeatureRequestChecksumWhenSupported = "Z" + UserAgentFeatureRequestChecksumWhenRequired = "a" + UserAgentFeatureResponseChecksumWhenSupported = "b" + UserAgentFeatureResponseChecksumWhenRequired = "c" + + UserAgentFeatureDynamoDBUserAgent = "d" // not yet implemented + + UserAgentFeatureCredentialsCode = "e" + UserAgentFeatureCredentialsJvmSystemProperties = "f" // n/a (this is not a JVM sdk) + UserAgentFeatureCredentialsEnvVars = "g" + UserAgentFeatureCredentialsEnvVarsStsWebIDToken = "h" + UserAgentFeatureCredentialsStsAssumeRole = "i" + UserAgentFeatureCredentialsStsAssumeRoleSaml = "j" // not yet implemented + UserAgentFeatureCredentialsStsAssumeRoleWebID = "k" + UserAgentFeatureCredentialsStsFederationToken = "l" // not yet implemented + UserAgentFeatureCredentialsStsSessionToken = "m" // not yet implemented + UserAgentFeatureCredentialsProfile = "n" + UserAgentFeatureCredentialsProfileSourceProfile = "o" + UserAgentFeatureCredentialsProfileNamedProvider = "p" + UserAgentFeatureCredentialsProfileStsWebIDToken = "q" + UserAgentFeatureCredentialsProfileSso = "r" + UserAgentFeatureCredentialsSso = "s" + UserAgentFeatureCredentialsProfileSsoLegacy = "t" + UserAgentFeatureCredentialsSsoLegacy = "u" + UserAgentFeatureCredentialsProfileProcess = "v" + UserAgentFeatureCredentialsProcess = "w" + UserAgentFeatureCredentialsBoto2ConfigFile = "x" // n/a (this is not boto/Python) + UserAgentFeatureCredentialsAwsSdkStore = "y" // n/a (this is used by .NET based sdk) + UserAgentFeatureCredentialsHTTP = "z" + UserAgentFeatureCredentialsIMDS = "0" + + UserAgentFeatureBearerServiceEnvVars = "3" + + UserAgentFeatureCredentialsProfileLogin = "AC" + UserAgentFeatureCredentialsLogin = "AD" ) +var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{ + aws.CredentialSourceCode: UserAgentFeatureCredentialsCode, + aws.CredentialSourceEnvVars: UserAgentFeatureCredentialsEnvVars, + aws.CredentialSourceEnvVarsSTSWebIDToken: UserAgentFeatureCredentialsEnvVarsStsWebIDToken, + aws.CredentialSourceSTSAssumeRole: UserAgentFeatureCredentialsStsAssumeRole, + aws.CredentialSourceSTSAssumeRoleSaml: UserAgentFeatureCredentialsStsAssumeRoleSaml, + aws.CredentialSourceSTSAssumeRoleWebID: UserAgentFeatureCredentialsStsAssumeRoleWebID, + aws.CredentialSourceSTSFederationToken: UserAgentFeatureCredentialsStsFederationToken, + aws.CredentialSourceSTSSessionToken: UserAgentFeatureCredentialsStsSessionToken, + aws.CredentialSourceProfile: UserAgentFeatureCredentialsProfile, + aws.CredentialSourceProfileSourceProfile: UserAgentFeatureCredentialsProfileSourceProfile, + aws.CredentialSourceProfileNamedProvider: UserAgentFeatureCredentialsProfileNamedProvider, + aws.CredentialSourceProfileSTSWebIDToken: UserAgentFeatureCredentialsProfileStsWebIDToken, + aws.CredentialSourceProfileSSO: UserAgentFeatureCredentialsProfileSso, + aws.CredentialSourceSSO: UserAgentFeatureCredentialsSso, + aws.CredentialSourceProfileSSOLegacy: UserAgentFeatureCredentialsProfileSsoLegacy, + aws.CredentialSourceSSOLegacy: UserAgentFeatureCredentialsSsoLegacy, + aws.CredentialSourceProfileProcess: UserAgentFeatureCredentialsProfileProcess, + aws.CredentialSourceProcess: UserAgentFeatureCredentialsProcess, + aws.CredentialSourceHTTP: UserAgentFeatureCredentialsHTTP, + aws.CredentialSourceIMDS: UserAgentFeatureCredentialsIMDS, + aws.CredentialSourceProfileLogin: UserAgentFeatureCredentialsProfileLogin, + aws.CredentialSourceLogin: UserAgentFeatureCredentialsLogin, +} + // RequestUserAgent is a build middleware that set the User-Agent for the request. type RequestUserAgent struct { sdkAgent, userAgent *smithyhttp.UserAgentBuilder @@ -252,6 +319,14 @@ func (u *RequestUserAgent) AddSDKAgentKeyValue(keyType SDKAgentKeyType, key, val u.userAgent.AddKeyValue(keyType.string(), strings.Map(rules, key)+"#"+strings.Map(rules, value)) } +// AddCredentialsSource adds the credential source as a feature on the User-Agent string +func (u *RequestUserAgent) AddCredentialsSource(source aws.CredentialSource) { + x, ok := credentialSourceToFeature[source] + if ok { + u.AddUserAgentFeature(x) + } +} + // ID the name of the middleware. func (u *RequestUserAgent) ID() string { return "UserAgent" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go index 52d59b0..5549922 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go @@ -260,7 +260,7 @@ func (r *Attempt) handleAttempt( // Get a retry token that will be released after the releaseRetryToken, retryTokenErr := r.retryer.GetRetryToken(ctx, err) if retryTokenErr != nil { - return out, attemptResult, nopRelease, retryTokenErr + return out, attemptResult, nopRelease, errors.Join(err, retryTokenErr) } //------------------------------ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go index 66aa2bd..32875e0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go @@ -59,7 +59,7 @@ func (s *StreamSigner) GetSignature(ctx context.Context, headers, payload []byte prevSignature := s.prevSignature - st := v4Internal.NewSigningTime(signingTime) + st := v4Internal.NewSigningTime(signingTime.UTC()) sigKey := s.signingKeyDeriver.DeriveKey(s.credentials, s.service, s.region, st) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go index 8d7c35a..c7ef0ac 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go @@ -18,6 +18,7 @@ var ( // Default connection pool options DefaultHTTPTransportMaxIdleConns = 100 DefaultHTTPTransportMaxIdleConnsPerHost = 10 + DefaultHTTPTransportMaxConnsPerHost = 2048 // Default connection timeouts DefaultHTTPTransportIdleConnTimeout = 90 * time.Second @@ -186,6 +187,7 @@ func defaultHTTPTransport() *http.Transport { TLSHandshakeTimeout: DefaultHTTPTransportTLSHandleshakeTimeout, MaxIdleConns: DefaultHTTPTransportMaxIdleConns, MaxIdleConnsPerHost: DefaultHTTPTransportMaxIdleConnsPerHost, + MaxConnsPerHost: DefaultHTTPTransportMaxConnsPerHost, IdleConnTimeout: DefaultHTTPTransportIdleConnTimeout, ExpectContinueTimeout: DefaultHTTPTransportExpectContinueTimeout, ForceAttemptHTTP2: true, diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go index 993929b..4881ae1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go @@ -64,6 +64,11 @@ func (r *timeoutReadCloser) Close() error { // AddResponseReadTimeoutMiddleware adds a middleware to the stack that wraps the // response body so that a read that takes too long will return an error. +// +// Deprecated: This API was previously exposed to customize behavior of the +// Kinesis service. That customization has been removed and this middleware's +// implementation can cause panics within the standard library networking loop. +// See #2752. func AddResponseReadTimeoutMiddleware(stack *middleware.Stack, duration time.Duration) error { return stack.Deserialize.Add(&readTimeout{duration: duration}, middleware.After) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md index 113b1da..6ffdf06 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md @@ -1,3 +1,102 @@ +# v1.4.16 (2025-12-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.15 (2025-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. + +# v1.4.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.4.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.37 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.36 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.35 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.34 (2025-02-27) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.33 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.32 (2025-02-05) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.3.31 (2025-01-31) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go index 28c635d..72df7b8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go @@ -3,4 +3,4 @@ package configsources // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.3.31" +const goModuleVersion = "1.4.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go index 5f07799..6ab4d96 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go @@ -3,7 +3,8 @@ package awsrulesfn // GetPartition returns an AWS [Partition] for the region provided. If the -// partition cannot be determined nil will be returned. +// partition cannot be determined then the default partition (AWS commercial) +// will be returned. func GetPartition(region string) *PartitionConfig { return getPartition(partitions, region) } @@ -11,7 +12,7 @@ func GetPartition(region string) *PartitionConfig { var partitions = []Partition{ { ID: "aws", - RegionRegex: "^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$", + RegionRegex: "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", DefaultConfig: PartitionConfig{ Name: "aws", DnsSuffix: "amazonaws.com", @@ -35,6 +36,13 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "ap-east-2": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "ap-northeast-1": { Name: nil, DnsSuffix: nil, @@ -98,6 +106,27 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "ap-southeast-5": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "ap-southeast-6": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "ap-southeast-7": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "aws-global": { Name: nil, DnsSuffix: nil, @@ -196,6 +225,13 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "mx-central-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "sa-east-1": { Name: nil, DnsSuffix: nil, @@ -268,6 +304,160 @@ var partitions = []Partition{ }, }, }, + { + ID: "aws-eusc", + RegionRegex: "^eusc\\-(de)\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-eusc", + DnsSuffix: "amazonaws.eu", + DualStackDnsSuffix: "api.amazonwebservices.eu", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "eusc-de-east-1", + }, + Regions: map[string]RegionOverrides{ + "eusc-de-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, + { + ID: "aws-iso", + RegionRegex: "^us\\-iso\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-iso", + DnsSuffix: "c2s.ic.gov", + DualStackDnsSuffix: "api.aws.ic.gov", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "us-iso-east-1", + }, + Regions: map[string]RegionOverrides{ + "aws-iso-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-iso-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-iso-west-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, + { + ID: "aws-iso-b", + RegionRegex: "^us\\-isob\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-iso-b", + DnsSuffix: "sc2s.sgov.gov", + DualStackDnsSuffix: "api.aws.scloud", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "us-isob-east-1", + }, + Regions: map[string]RegionOverrides{ + "aws-iso-b-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isob-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isob-west-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, + { + ID: "aws-iso-e", + RegionRegex: "^eu\\-isoe\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-iso-e", + DnsSuffix: "cloud.adc-e.uk", + DualStackDnsSuffix: "api.cloud-aws.adc-e.uk", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "eu-isoe-west-1", + }, + Regions: map[string]RegionOverrides{ + "aws-iso-e-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "eu-isoe-west-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, + { + ID: "aws-iso-f", + RegionRegex: "^us\\-isof\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-iso-f", + DnsSuffix: "csp.hci.ic.gov", + DualStackDnsSuffix: "api.aws.hci.ic.gov", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "us-isof-south-1", + }, + Regions: map[string]RegionOverrides{ + "aws-iso-f-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isof-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isof-south-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, { ID: "aws-us-gov", RegionRegex: "^us\\-gov\\-\\w+\\-\\d+$", @@ -303,101 +493,4 @@ var partitions = []Partition{ }, }, }, - { - ID: "aws-iso", - RegionRegex: "^us\\-iso\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso", - DnsSuffix: "c2s.ic.gov", - DualStackDnsSuffix: "c2s.ic.gov", - SupportsFIPS: true, - SupportsDualStack: false, - ImplicitGlobalRegion: "us-iso-east-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-iso-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-iso-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-b", - RegionRegex: "^us\\-isob\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-b", - DnsSuffix: "sc2s.sgov.gov", - DualStackDnsSuffix: "sc2s.sgov.gov", - SupportsFIPS: true, - SupportsDualStack: false, - ImplicitGlobalRegion: "us-isob-east-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-b-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-isob-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-e", - RegionRegex: "^eu\\-isoe\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-e", - DnsSuffix: "cloud.adc-e.uk", - DualStackDnsSuffix: "cloud.adc-e.uk", - SupportsFIPS: true, - SupportsDualStack: false, - ImplicitGlobalRegion: "eu-isoe-west-1", - }, - Regions: map[string]RegionOverrides{ - "eu-isoe-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-f", - RegionRegex: "^us\\-isof\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-f", - DnsSuffix: "csp.hci.ic.gov", - DualStackDnsSuffix: "csp.hci.ic.gov", - SupportsFIPS: true, - SupportsDualStack: false, - ImplicitGlobalRegion: "us-isof-south-1", - }, - Regions: map[string]RegionOverrides{}, - }, } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json index 43f6449..c789264 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json @@ -17,6 +17,9 @@ "ap-east-1" : { "description" : "Asia Pacific (Hong Kong)" }, + "ap-east-2" : { + "description" : "Asia Pacific (Taipei)" + }, "ap-northeast-1" : { "description" : "Asia Pacific (Tokyo)" }, @@ -47,11 +50,14 @@ "ap-southeast-5" : { "description" : "Asia Pacific (Malaysia)" }, + "ap-southeast-6" : { + "description" : "Asia Pacific (New Zealand)" + }, "ap-southeast-7" : { "description" : "Asia Pacific (Thailand)" }, "aws-global" : { - "description" : "AWS Standard global region" + "description" : "aws global region" }, "ca-central-1" : { "description" : "Canada (Central)" @@ -124,7 +130,7 @@ "regionRegex" : "^cn\\-\\w+\\-\\d+$", "regions" : { "aws-cn-global" : { - "description" : "AWS China global region" + "description" : "aws-cn global region" }, "cn-north-1" : { "description" : "China (Beijing)" @@ -133,6 +139,107 @@ "description" : "China (Ningxia)" } } + }, { + "id" : "aws-eusc", + "outputs" : { + "dnsSuffix" : "amazonaws.eu", + "dualStackDnsSuffix" : "api.amazonwebservices.eu", + "implicitGlobalRegion" : "eusc-de-east-1", + "name" : "aws-eusc", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", + "regions" : { + "eusc-de-east-1" : { + "description" : "EU (Germany)" + } + } + }, { + "id" : "aws-iso", + "outputs" : { + "dnsSuffix" : "c2s.ic.gov", + "dualStackDnsSuffix" : "api.aws.ic.gov", + "implicitGlobalRegion" : "us-iso-east-1", + "name" : "aws-iso", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-global" : { + "description" : "aws-iso global region" + }, + "us-iso-east-1" : { + "description" : "US ISO East" + }, + "us-iso-west-1" : { + "description" : "US ISO WEST" + } + } + }, { + "id" : "aws-iso-b", + "outputs" : { + "dnsSuffix" : "sc2s.sgov.gov", + "dualStackDnsSuffix" : "api.aws.scloud", + "implicitGlobalRegion" : "us-isob-east-1", + "name" : "aws-iso-b", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-b-global" : { + "description" : "aws-iso-b global region" + }, + "us-isob-east-1" : { + "description" : "US ISOB East (Ohio)" + }, + "us-isob-west-1" : { + "description" : "US ISOB West" + } + } + }, { + "id" : "aws-iso-e", + "outputs" : { + "dnsSuffix" : "cloud.adc-e.uk", + "dualStackDnsSuffix" : "api.cloud-aws.adc-e.uk", + "implicitGlobalRegion" : "eu-isoe-west-1", + "name" : "aws-iso-e", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-e-global" : { + "description" : "aws-iso-e global region" + }, + "eu-isoe-west-1" : { + "description" : "EU ISOE West" + } + } + }, { + "id" : "aws-iso-f", + "outputs" : { + "dnsSuffix" : "csp.hci.ic.gov", + "dualStackDnsSuffix" : "api.aws.hci.ic.gov", + "implicitGlobalRegion" : "us-isof-south-1", + "name" : "aws-iso-f", + "supportsDualStack" : true, + "supportsFIPS" : true + }, + "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", + "regions" : { + "aws-iso-f-global" : { + "description" : "aws-iso-f global region" + }, + "us-isof-east-1" : { + "description" : "US ISOF EAST" + }, + "us-isof-south-1" : { + "description" : "US ISOF SOUTH" + } + } }, { "id" : "aws-us-gov", "outputs" : { @@ -146,7 +253,7 @@ "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", "regions" : { "aws-us-gov-global" : { - "description" : "AWS GovCloud (US) global region" + "description" : "aws-us-gov global region" }, "us-gov-east-1" : { "description" : "AWS GovCloud (US-East)" @@ -155,75 +262,6 @@ "description" : "AWS GovCloud (US-West)" } } - }, { - "id" : "aws-iso", - "outputs" : { - "dnsSuffix" : "c2s.ic.gov", - "dualStackDnsSuffix" : "c2s.ic.gov", - "implicitGlobalRegion" : "us-iso-east-1", - "name" : "aws-iso", - "supportsDualStack" : false, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-global" : { - "description" : "AWS ISO (US) global region" - }, - "us-iso-east-1" : { - "description" : "US ISO East" - }, - "us-iso-west-1" : { - "description" : "US ISO WEST" - } - } - }, { - "id" : "aws-iso-b", - "outputs" : { - "dnsSuffix" : "sc2s.sgov.gov", - "dualStackDnsSuffix" : "sc2s.sgov.gov", - "implicitGlobalRegion" : "us-isob-east-1", - "name" : "aws-iso-b", - "supportsDualStack" : false, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-b-global" : { - "description" : "AWS ISOB (US) global region" - }, - "us-isob-east-1" : { - "description" : "US ISOB East (Ohio)" - } - } - }, { - "id" : "aws-iso-e", - "outputs" : { - "dnsSuffix" : "cloud.adc-e.uk", - "dualStackDnsSuffix" : "cloud.adc-e.uk", - "implicitGlobalRegion" : "eu-isoe-west-1", - "name" : "aws-iso-e", - "supportsDualStack" : false, - "supportsFIPS" : true - }, - "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", - "regions" : { - "eu-isoe-west-1" : { - "description" : "EU ISOE West" - } - } - }, { - "id" : "aws-iso-f", - "outputs" : { - "dnsSuffix" : "csp.hci.ic.gov", - "dualStackDnsSuffix" : "csp.hci.ic.gov", - "implicitGlobalRegion" : "us-isof-south-1", - "name" : "aws-iso-f", - "supportsDualStack" : false, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", - "regions" : { } } ], "version" : "1.1" } \ No newline at end of file diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md index 1cab71d..b2d3477 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md @@ -1,3 +1,102 @@ +# v2.7.16 (2025-12-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.15 (2025-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. + +# v2.7.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v2.7.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.37 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.36 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.35 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.34 (2025-02-27) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.33 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.32 (2025-02-05) + +* **Dependency Update**: Updated to the latest SDK module versions + # v2.6.31 (2025-01-31) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go index 589a4a7..1a524ae 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go @@ -3,4 +3,4 @@ package endpoints // goModuleVersion is the tagged release for this module -const goModuleVersion = "2.6.31" +const goModuleVersion = "2.7.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md index ef78753..6ffbf3f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md @@ -1,3 +1,31 @@ +# v1.13.4 (2025-12-02) + +* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. + +# v1.13.3 (2025-11-04) + +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.13.2 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. + +# v1.13.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. + +# v1.13.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. + +# v1.12.4 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. + +# v1.12.3 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 + # v1.12.2 (2025-01-24) * **Dependency Update**: Upgrade to smithy-go v1.22.2. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go index cbf79b4..970bb21 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go @@ -3,4 +3,4 @@ package acceptencoding // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.2" +const goModuleVersion = "1.13.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md index 04186fd..743183c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md @@ -1,3 +1,102 @@ +# v1.13.16 (2025-12-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.15 (2025-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. + +# v1.13.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.13.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.18 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.17 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.16 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.15 (2025-02-27) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.14 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.13 (2025-02-05) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.12.12 (2025-01-31) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go index 66771d9..a8a2e69 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go @@ -3,4 +3,4 @@ package presignedurl // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.12" +const goModuleVersion = "1.13.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/CHANGELOG.md deleted file mode 100644 index 0238ce1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/CHANGELOG.md +++ /dev/null @@ -1,454 +0,0 @@ -# v1.44.7 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.44.6 (2023-12-20) - -* No change notes available for this release. - -# v1.44.5 (2023-12-08) - -* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. - -# v1.44.4 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.44.3 (2023-12-06) - -* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. - -# v1.44.2 (2023-12-01) - -* **Bug Fix**: Correct wrapping of errors in authentication workflow. -* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.44.1 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.44.0 (2023-11-29) - -* **Feature**: Expose Options() accessor on service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.43.3 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.43.2 (2023-11-28) - -* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. - -# v1.43.1 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.43.0 (2023-11-16) - -* **Feature**: This release introduces the ability to filter automation execution steps which have parent steps. In addition, runbook variable information is returned by GetAutomationExecution and parent step information is returned by the DescribeAutomationStepExecutions API. - -# v1.42.2 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.42.1 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.42.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.41.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.40.0 (2023-10-24) - -* **Feature**: **BREAKFIX**: Correct nullability and default value representation of various input fields across a large number of services. Calling code that references one or more of the affected fields will need to update usage accordingly. See [2162](https://github.com/aws/aws-sdk-go-v2/issues/2162). - -# v1.39.0 (2023-10-20) - -* **Feature**: This release introduces a new API: DeleteOpsItem. This allows deletion of an OpsItem. - -# v1.38.2 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.1 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.0 (2023-09-25) - -* **Feature**: This release updates the enum values for ResourceType in SSM DescribeInstanceInformation input and ConnectionStatus in GetConnectionStatus output. - -# v1.37.5 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.37.4 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.37.3 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.37.2 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.37.1 (2023-08-01) - -* No change notes available for this release. - -# v1.37.0 (2023-07-31) - -* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.9 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.8 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.7 (2023-06-27) - -* **Documentation**: Systems Manager doc-only update for June 2023. - -# v1.36.6 (2023-06-15) - -* No change notes available for this release. - -# v1.36.5 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.4 (2023-05-04) - -* No change notes available for this release. - -# v1.36.3 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.2 (2023-04-10) - -* No change notes available for this release. - -# v1.36.1 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.0 (2023-03-22) - -* **Feature**: This Patch Manager release supports creating, updating, and deleting Patch Baselines for AmazonLinux2023, AlmaLinux. - -# v1.35.7 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.6 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.5 (2023-02-22) - -* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. -* **Documentation**: Document only update for Feb 2023 - -# v1.35.4 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.3 (2023-02-15) - -* **Announcement**: When receiving an error response in restJson-based services, an incorrect error type may have been returned based on the content of the response. This has been fixed via PR #2012 tracked in issue #1910. -* **Bug Fix**: Correct error type parsing for restJson services. - -# v1.35.2 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.1 (2023-01-23) - -* No change notes available for this release. - -# v1.35.0 (2023-01-05) - -* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). - -# v1.34.0 (2023-01-04) - -* **Feature**: Adding support for QuickSetup Document Type in Systems Manager - -# v1.33.4 (2022-12-21) - -* **Documentation**: Doc-only updates for December 2022. - -# v1.33.3 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.2 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.1 (2022-11-22) - -* No change notes available for this release. - -# v1.33.0 (2022-11-16) - -* **Feature**: This release adds support for cross account access in CreateOpsItem, UpdateOpsItem and GetOpsItem. It introduces new APIs to setup resource policies for SSM resources: PutResourcePolicy, GetResourcePolicies and DeleteResourcePolicy. - -# v1.32.1 (2022-11-10) - -* No change notes available for this release. - -# v1.32.0 (2022-11-07) - -* **Feature**: This release includes support for applying a CloudWatch alarm to multi account multi region Systems Manager Automation - -# v1.31.3 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.31.2 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.31.1 (2022-10-20) - -* No change notes available for this release. - -# v1.31.0 (2022-10-13) - -* **Feature**: Support of AmazonLinux2022 by Patch Manager - -# v1.30.0 (2022-09-26) - -* **Feature**: This release includes support for applying a CloudWatch alarm to Systems Manager capabilities like Automation, Run Command, State Manager, and Maintenance Windows. - -# v1.29.0 (2022-09-23) - -* **Feature**: This release adds new SSM document types ConformancePackTemplate and CloudFormation - -# v1.28.1 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.0 (2022-09-14) - -* **Feature**: Fixed a bug in the API client generation which caused some operation parameters to be incorrectly generated as value types instead of pointer types. The service API always required these affected parameters to be nilable. This fixes the SDK client to match the expectations of the the service API. -* **Feature**: This release adds support for Systems Manager State Manager Association tagging. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.13 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.12 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.11 (2022-08-30) - -* No change notes available for this release. - -# v1.27.10 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.9 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.8 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.7 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.6 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.5 (2022-07-27) - -* **Documentation**: Adding doc updates for OpsCenter support in Service Setting actions. - -# v1.27.4 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.3 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.2 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.1 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.0 (2022-05-04) - -* **Feature**: This release adds the TargetMaps parameter in SSM State Manager API. - -# v1.26.0 (2022-04-29) - -* **Feature**: Update the StartChangeRequestExecution, adding TargetMaps to the Runbook parameter - -# v1.25.1 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.0 (2022-04-19) - -* **Feature**: Added offset support for specifying the number of days to wait after the date and time specified by a CRON expression when creating SSM association. - -# v1.24.1 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.0 (2022-03-25) - -* **Feature**: This Patch Manager release supports creating, updating, and deleting Patch Baselines for Rocky Linux OS. - -# v1.23.1 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.0 (2022-03-23) - -* **Feature**: Update AddTagsToResource, ListTagsForResource, and RemoveTagsFromResource APIs to reflect the support for tagging Automation resources. Includes other minor documentation updates. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.0 (2022-02-24) - -* **Feature**: API client updated -* **Feature**: Adds RetryMaxAttempts and RetryMod to API client Options. This allows the API clients' default Retryer to be configured from the shared configuration files or environment variables. Adding a new Retry mode of `Adaptive`. `Adaptive` retry mode is an experimental mode, adding client rate limiting when throttles reponses are received from an API. See [retry.AdaptiveMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AdaptiveMode) for more details, and configuration options. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.0 (2022-01-14) - -* **Feature**: Updated API models -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.0 (2021-12-21) - -* **Feature**: API Paginators now support specifying the initial starting token, and support stopping on empty string tokens. -* **Feature**: Updated to latest service endpoints - -# v1.17.1 (2021-12-02) - -* **Bug Fix**: Fixes a bug that prevented aws.EndpointResolverWithOptions from being used by the service client. ([#1514](https://github.com/aws/aws-sdk-go-v2/pull/1514)) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.0 (2021-11-30) - -* **Feature**: API client updated - -# v1.16.0 (2021-11-19) - -* **Feature**: API client updated -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2021-11-12) - -* **Feature**: Service clients now support custom endpoints that have an initial URI path defined. -* **Feature**: Waiters now have a `WaitForOutput` method, which can be used to retrieve the output of the successful wait operation. Thank you to [Andrew Haines](https://github.com/haines) for contributing this feature. - -# v1.14.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2021-10-11) - -* **Feature**: API client updated -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2021-09-24) - -* **Feature**: API client updated - -# v1.10.1 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.1 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2021-08-12) - -* **Feature**: API client updated - -# v1.8.1 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2021-07-15) - -* **Feature**: Updated service model to latest version. -* **Documentation**: Updated service model to latest revision. -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.2 (2021-06-04) - -* **Documentation**: Updated service client to latest API model. - -# v1.6.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Feature**: Updated to latest service API model. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_client.go deleted file mode 100644 index 973f468..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_client.go +++ /dev/null @@ -1,492 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - cryptorand "crypto/rand" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/defaults" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - smithy "github.com/aws/smithy-go" - smithydocument "github.com/aws/smithy-go/document" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" - smithyrand "github.com/aws/smithy-go/rand" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net" - "net/http" - "time" -) - -const ServiceID = "SSM" -const ServiceAPIVersion = "2014-11-06" - -// Client provides the API client to make operations call for Amazon Simple -// Systems Manager (SSM). -type Client struct { - options Options -} - -// New returns an initialized Client based on the functional options. Provide -// additional functional options to further configure the behavior of the client, -// such as changing the client's endpoint or adding custom middleware behavior. -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - resolveDefaultLogger(&options) - - setResolvedDefaultsMode(&options) - - resolveRetryer(&options) - - resolveHTTPClient(&options) - - resolveHTTPSignerV4(&options) - - resolveIdempotencyTokenProvider(&options) - - resolveEndpointResolverV2(&options) - - resolveAuthSchemeResolver(&options) - - for _, fn := range optFns { - fn(&options) - } - - finalizeRetryMaxAttempts(&options) - - ignoreAnonymousAuth(&options) - - wrapWithAnonymousAuth(&options) - - resolveAuthSchemes(&options) - - client := &Client{ - options: options, - } - - return client -} - -// Options returns a copy of the client configuration. -// -// Callers SHOULD NOT perform mutations on any inner structures within client -// config. Config overrides should instead be made on a per-operation basis through -// functional options. -func (c *Client) Options() Options { - return c.options.Copy() -} - -func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) { - ctx = middleware.ClearStackValues(ctx) - stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) - options := c.options.Copy() - - for _, fn := range optFns { - fn(&options) - } - - finalizeOperationRetryMaxAttempts(&options, *c) - - finalizeClientEndpointResolverOptions(&options) - - for _, fn := range stackFns { - if err := fn(stack, options); err != nil { - return nil, metadata, err - } - } - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, metadata, err - } - } - - handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack) - result, metadata, err = handler.Handle(ctx, params) - if err != nil { - err = &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: err, - } - } - return result, metadata, err -} - -type operationInputKey struct{} - -func setOperationInput(ctx context.Context, input interface{}) context.Context { - return middleware.WithStackValue(ctx, operationInputKey{}, input) -} - -func getOperationInput(ctx context.Context) interface{} { - return middleware.GetStackValue(ctx, operationInputKey{}) -} - -type setOperationInputMiddleware struct { -} - -func (*setOperationInputMiddleware) ID() string { - return "setOperationInput" -} - -func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - ctx = setOperationInput(ctx, in.Parameters) - return next.HandleSerialize(ctx, in) -} - -func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %v", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %v", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} -func resolveAuthSchemeResolver(options *Options) { - if options.AuthSchemeResolver == nil { - options.AuthSchemeResolver = &defaultAuthSchemeResolver{} - } -} - -func resolveAuthSchemes(options *Options) { - if options.AuthSchemes == nil { - options.AuthSchemes = []smithyhttp.AuthScheme{ - internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ - Signer: options.HTTPSignerV4, - Logger: options.Logger, - LogSigning: options.ClientLogMode.IsSigning(), - }), - } - } -} - -type noSmithyDocumentSerde = smithydocument.NoSerde - -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - -func resolveDefaultLogger(o *Options) { - if o.Logger != nil { - return - } - o.Logger = logging.Nop{} -} - -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) -} - -func setResolvedDefaultsMode(o *Options) { - if len(o.resolvedDefaultsMode) > 0 { - return - } - - var mode aws.DefaultsMode - mode.SetFromString(string(o.DefaultsMode)) - - if mode == aws.DefaultsModeAuto { - mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) - } - - o.resolvedDefaultsMode = mode -} - -// NewFromConfig returns a new client from the provided config. -func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { - opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - } - resolveAWSRetryerProvider(cfg, &opts) - resolveAWSRetryMaxAttempts(cfg, &opts) - resolveAWSRetryMode(cfg, &opts) - resolveAWSEndpointResolver(cfg, &opts) - resolveUseDualStackEndpoint(cfg, &opts) - resolveUseFIPSEndpoint(cfg, &opts) - resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) -} - -func resolveHTTPClient(o *Options) { - var buildable *awshttp.BuildableClient - - if o.HTTPClient != nil { - var ok bool - buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) - if !ok { - return - } - } else { - buildable = awshttp.NewBuildableClient() - } - - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { - if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { - dialer.Timeout = dialerTimeout - } - }) - - buildable = buildable.WithTransportOptions(func(transport *http.Transport) { - if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { - transport.TLSHandshakeTimeout = tlsHandshakeTimeout - } - }) - } - - o.HTTPClient = buildable -} - -func resolveRetryer(o *Options) { - if o.Retryer != nil { - return - } - - if len(o.RetryMode) == 0 { - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - o.RetryMode = modeConfig.RetryMode - } - } - if len(o.RetryMode) == 0 { - o.RetryMode = aws.RetryModeStandard - } - - var standardOptions []func(*retry.StandardOptions) - if v := o.RetryMaxAttempts; v != 0 { - standardOptions = append(standardOptions, func(so *retry.StandardOptions) { - so.MaxAttempts = v - }) - } - - switch o.RetryMode { - case aws.RetryModeAdaptive: - var adaptiveOptions []func(*retry.AdaptiveModeOptions) - if len(standardOptions) != 0 { - adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { - ao.StandardOptions = append(ao.StandardOptions, standardOptions...) - }) - } - o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) - - default: - o.Retryer = retry.NewStandard(standardOptions...) - } -} - -func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { - if cfg.Retryer == nil { - return - } - o.Retryer = cfg.Retryer() -} - -func resolveAWSRetryMode(cfg aws.Config, o *Options) { - if len(cfg.RetryMode) == 0 { - return - } - o.RetryMode = cfg.RetryMode -} -func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { - if cfg.RetryMaxAttempts == 0 { - return - } - o.RetryMaxAttempts = cfg.RetryMaxAttempts -} - -func finalizeRetryMaxAttempts(o *Options) { - if o.RetryMaxAttempts == 0 { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func finalizeOperationRetryMaxAttempts(o *Options, client Client) { - if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { - if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { - return - } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) -} - -func addClientUserAgent(stack *middleware.Stack, options Options) error { - if err := awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ssm", goModuleVersion)(stack); err != nil { - return err - } - - if len(options.AppID) > 0 { - return awsmiddleware.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)(stack) - } - - return nil -} - -type HTTPSignerV4 interface { - SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error -} - -func resolveHTTPSignerV4(o *Options) { - if o.HTTPSignerV4 != nil { - return - } - o.HTTPSignerV4 = newDefaultV4Signer(*o) -} - -func newDefaultV4Signer(o Options) *v4.Signer { - return v4.NewSigner(func(so *v4.SignerOptions) { - so.Logger = o.Logger - so.LogSigning = o.ClientLogMode.IsSigning() - }) -} - -func resolveIdempotencyTokenProvider(o *Options) { - if o.IdempotencyTokenProvider != nil { - return - } - o.IdempotencyTokenProvider = smithyrand.NewUUIDIdempotencyToken(cryptorand.Reader) -} - -func addRetryMiddlewares(stack *middleware.Stack, o Options) error { - mo := retry.AddRetryMiddlewaresOptions{ - Retryer: o.Retryer, - LogRetryAttempts: o.ClientLogMode.IsRetries(), - } - return retry.AddRetryMiddlewares(stack, mo) -} - -// resolves dual-stack endpoint configuration -func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseDualStackEndpoint = value - } - return nil -} - -// resolves FIPS endpoint configuration -func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseFIPSEndpoint = value - } - return nil -} - -// IdempotencyTokenProvider interface for providing idempotency token -type IdempotencyTokenProvider interface { - GetIdempotencyToken() (string, error) -} - -func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return awsmiddleware.AddRequestIDRetrieverMiddleware(stack) -} - -func addResponseErrorMiddleware(stack *middleware.Stack) error { - return awshttp.AddResponseErrorMiddleware(stack) -} - -func addRequestResponseLogging(stack *middleware.Stack, o Options) error { - return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ - LogRequest: o.ClientLogMode.IsRequest(), - LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), - LogResponse: o.ClientLogMode.IsResponse(), - LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), - }, middleware.After) -} - -type disableHTTPSMiddleware struct { - DisableHTTPS bool -} - -func (*disableHTTPSMiddleware) ID() string { - return "disableHTTPS" -} - -func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { - req.URL.Scheme = "http" - } - - return next.HandleFinalize(ctx, in) -} - -func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { - return stack.Finalize.Insert(&disableHTTPSMiddleware{ - DisableHTTPS: o.EndpointOptions.DisableHTTPS, - }, "ResolveEndpointV2", middleware.After) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AddTagsToResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AddTagsToResource.go deleted file mode 100644 index e1b972c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AddTagsToResource.go +++ /dev/null @@ -1,183 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Adds or overwrites one or more tags for the specified resource. Tags are -// metadata that you can assign to your automations, documents, managed nodes, -// maintenance windows, Parameter Store parameters, and patch baselines. Tags -// enable you to categorize your resources in different ways, for example, by -// purpose, owner, or environment. Each tag consists of a key and an optional -// value, both of which you define. For example, you could define a set of tags for -// your account's managed nodes that helps you track each node's owner and stack -// level. For example: -// - Key=Owner,Value=DbAdmin -// - Key=Owner,Value=SysAdmin -// - Key=Owner,Value=Dev -// - Key=Stack,Value=Production -// - Key=Stack,Value=Pre-Production -// - Key=Stack,Value=Test -// -// Most resources can have a maximum of 50 tags. Automations can have a maximum of -// 5 tags. We recommend that you devise a set of tag keys that meets your needs for -// each resource type. Using a consistent set of tag keys makes it easier for you -// to manage your resources. You can search and filter the resources based on the -// tags you add. Tags don't have any semantic meaning to and are interpreted -// strictly as a string of characters. For more information about using tags with -// Amazon Elastic Compute Cloud (Amazon EC2) instances, see Tagging your Amazon -// EC2 resources (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) -// in the Amazon EC2 User Guide. -func (c *Client) AddTagsToResource(ctx context.Context, params *AddTagsToResourceInput, optFns ...func(*Options)) (*AddTagsToResourceOutput, error) { - if params == nil { - params = &AddTagsToResourceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AddTagsToResource", params, optFns, c.addOperationAddTagsToResourceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AddTagsToResourceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AddTagsToResourceInput struct { - - // The resource ID you want to tag. Use the ID of the resource. Here are some - // examples: MaintenanceWindow : mw-012345abcde PatchBaseline : pb-012345abcde - // Automation : example-c160-4567-8519-012345abcde OpsMetadata object: ResourceID - // for tagging is created from the Amazon Resource Name (ARN) for the object. - // Specifically, ResourceID is created from the strings that come after the word - // opsmetadata in the ARN. For example, an OpsMetadata object with an ARN of - // arn:aws:ssm:us-east-2:1234567890:opsmetadata/aws/ssm/MyGroup/appmanager has a - // ResourceID of either aws/ssm/MyGroup/appmanager or /aws/ssm/MyGroup/appmanager . - // For the Document and Parameter values, use the name of the resource. If you're - // tagging a shared document, you must use the full ARN of the document. - // ManagedInstance : mi-012345abcde The ManagedInstance type for this API - // operation is only for on-premises managed nodes. You must specify the name of - // the managed node in the following format: mi-ID_number . For example, - // mi-1a2b3c4d5e6f . - // - // This member is required. - ResourceId *string - - // Specifies the type of resource you are tagging. The ManagedInstance type for - // this API operation is for on-premises managed nodes. You must specify the name - // of the managed node in the following format: mi-ID_number . For example, - // mi-1a2b3c4d5e6f . - // - // This member is required. - ResourceType types.ResourceTypeForTagging - - // One or more tags. The value parameter is required. Don't enter personally - // identifiable information in this field. - // - // This member is required. - Tags []types.Tag - - noSmithyDocumentSerde -} - -type AddTagsToResourceOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAddTagsToResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpAddTagsToResource{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpAddTagsToResource{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AddTagsToResource"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpAddTagsToResourceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAddTagsToResource(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAddTagsToResource(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AddTagsToResource", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AssociateOpsItemRelatedItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AssociateOpsItemRelatedItem.go deleted file mode 100644 index 90104d7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_AssociateOpsItemRelatedItem.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Associates a related item to a Systems Manager OpsCenter OpsItem. For example, -// you can associate an Incident Manager incident or analysis with an OpsItem. -// Incident Manager and OpsCenter are capabilities of Amazon Web Services Systems -// Manager. -func (c *Client) AssociateOpsItemRelatedItem(ctx context.Context, params *AssociateOpsItemRelatedItemInput, optFns ...func(*Options)) (*AssociateOpsItemRelatedItemOutput, error) { - if params == nil { - params = &AssociateOpsItemRelatedItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AssociateOpsItemRelatedItem", params, optFns, c.addOperationAssociateOpsItemRelatedItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AssociateOpsItemRelatedItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AssociateOpsItemRelatedItemInput struct { - - // The type of association that you want to create between an OpsItem and a - // resource. OpsCenter supports IsParentOf and RelatesTo association types. - // - // This member is required. - AssociationType *string - - // The ID of the OpsItem to which you want to associate a resource as a related - // item. - // - // This member is required. - OpsItemId *string - - // The type of resource that you want to associate with an OpsItem. OpsCenter - // supports the following types: AWS::SSMIncidents::IncidentRecord : an Incident - // Manager incident. AWS::SSM::Document : a Systems Manager (SSM) document. - // - // This member is required. - ResourceType *string - - // The Amazon Resource Name (ARN) of the Amazon Web Services resource that you - // want to associate with the OpsItem. - // - // This member is required. - ResourceUri *string - - noSmithyDocumentSerde -} - -type AssociateOpsItemRelatedItemOutput struct { - - // The association ID. - AssociationId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAssociateOpsItemRelatedItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpAssociateOpsItemRelatedItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpAssociateOpsItemRelatedItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AssociateOpsItemRelatedItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpAssociateOpsItemRelatedItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssociateOpsItemRelatedItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAssociateOpsItemRelatedItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AssociateOpsItemRelatedItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelCommand.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelCommand.go deleted file mode 100644 index 278ec72..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelCommand.go +++ /dev/null @@ -1,141 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Attempts to cancel the command specified by the Command ID. There is no -// guarantee that the command will be terminated and the underlying process -// stopped. -func (c *Client) CancelCommand(ctx context.Context, params *CancelCommandInput, optFns ...func(*Options)) (*CancelCommandOutput, error) { - if params == nil { - params = &CancelCommandInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CancelCommand", params, optFns, c.addOperationCancelCommandMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CancelCommandOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CancelCommandInput struct { - - // The ID of the command you want to cancel. - // - // This member is required. - CommandId *string - - // (Optional) A list of managed node IDs on which you want to cancel the command. - // If not provided, the command is canceled on every node on which it was - // requested. - InstanceIds []string - - noSmithyDocumentSerde -} - -// Whether or not the command was successfully canceled. There is no guarantee -// that a request can be canceled. -type CancelCommandOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCancelCommandMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCancelCommand{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCancelCommand{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CancelCommand"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCancelCommandValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCancelCommand(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCancelCommand(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CancelCommand", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelMaintenanceWindowExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelMaintenanceWindowExecution.go deleted file mode 100644 index 0b887cb..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CancelMaintenanceWindowExecution.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Stops a maintenance window execution that is already in progress and cancels -// any tasks in the window that haven't already starting running. Tasks already in -// progress will continue to completion. -func (c *Client) CancelMaintenanceWindowExecution(ctx context.Context, params *CancelMaintenanceWindowExecutionInput, optFns ...func(*Options)) (*CancelMaintenanceWindowExecutionOutput, error) { - if params == nil { - params = &CancelMaintenanceWindowExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CancelMaintenanceWindowExecution", params, optFns, c.addOperationCancelMaintenanceWindowExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CancelMaintenanceWindowExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CancelMaintenanceWindowExecutionInput struct { - - // The ID of the maintenance window execution to stop. - // - // This member is required. - WindowExecutionId *string - - noSmithyDocumentSerde -} - -type CancelMaintenanceWindowExecutionOutput struct { - - // The ID of the maintenance window execution that has been stopped. - WindowExecutionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCancelMaintenanceWindowExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCancelMaintenanceWindowExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCancelMaintenanceWindowExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CancelMaintenanceWindowExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCancelMaintenanceWindowExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCancelMaintenanceWindowExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCancelMaintenanceWindowExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CancelMaintenanceWindowExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateActivation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateActivation.go deleted file mode 100644 index 9aad0ee..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateActivation.go +++ /dev/null @@ -1,200 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Generates an activation code and activation ID you can use to register your -// on-premises servers, edge devices, or virtual machine (VM) with Amazon Web -// Services Systems Manager. Registering these machines with Systems Manager makes -// it possible to manage them using Systems Manager capabilities. You use the -// activation code and ID when installing SSM Agent on machines in your hybrid -// environment. For more information about requirements for managing on-premises -// machines using Systems Manager, see Setting up Amazon Web Services Systems -// Manager for hybrid environments (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-managedinstances.html) -// in the Amazon Web Services Systems Manager User Guide. Amazon Elastic Compute -// Cloud (Amazon EC2) instances, edge devices, and on-premises servers and VMs that -// are configured for Systems Manager are all called managed nodes. -func (c *Client) CreateActivation(ctx context.Context, params *CreateActivationInput, optFns ...func(*Options)) (*CreateActivationOutput, error) { - if params == nil { - params = &CreateActivationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateActivation", params, optFns, c.addOperationCreateActivationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateActivationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateActivationInput struct { - - // The name of the Identity and Access Management (IAM) role that you want to - // assign to the managed node. This IAM role must provide AssumeRole permissions - // for the Amazon Web Services Systems Manager service principal ssm.amazonaws.com - // . For more information, see Create an IAM service role for a hybrid environment (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-service-role.html) - // in the Amazon Web Services Systems Manager User Guide. You can't specify an IAM - // service-linked role for this parameter. You must create a unique role. - // - // This member is required. - IamRole *string - - // The name of the registered, managed node as it will appear in the Amazon Web - // Services Systems Manager console or when you use the Amazon Web Services command - // line tools to list Systems Manager resources. Don't enter personally - // identifiable information in this field. - DefaultInstanceName *string - - // A user-defined description of the resource that you want to register with - // Systems Manager. Don't enter personally identifiable information in this field. - Description *string - - // The date by which this activation request should expire, in timestamp format, - // such as "2021-07-07T00:00:00". You can specify a date up to 30 days in advance. - // If you don't provide an expiration date, the activation code expires in 24 - // hours. - ExpirationDate *time.Time - - // Specify the maximum number of managed nodes you want to register. The default - // value is 1 . - RegistrationLimit *int32 - - // Reserved for internal use. - RegistrationMetadata []types.RegistrationMetadataItem - - // Optional metadata that you assign to a resource. Tags enable you to categorize - // a resource in different ways, such as by purpose, owner, or environment. For - // example, you might want to tag an activation to identify which servers or - // virtual machines (VMs) in your on-premises environment you intend to activate. - // In this case, you could specify the following key-value pairs: - // - Key=OS,Value=Windows - // - Key=Environment,Value=Production - // When you install SSM Agent on your on-premises servers and VMs, you specify an - // activation ID and code. When you specify the activation ID and code, tags - // assigned to the activation are automatically applied to the on-premises servers - // or VMs. You can't add tags to or delete tags from an existing activation. You - // can tag your on-premises servers, edge devices, and VMs after they connect to - // Systems Manager for the first time and are assigned a managed node ID. This - // means they are listed in the Amazon Web Services Systems Manager console with an - // ID that is prefixed with "mi-". For information about how to add tags to your - // managed nodes, see AddTagsToResource . For information about how to remove tags - // from your managed nodes, see RemoveTagsFromResource . - Tags []types.Tag - - noSmithyDocumentSerde -} - -type CreateActivationOutput struct { - - // The code the system generates when it processes the activation. The activation - // code functions like a password to validate the activation ID. - ActivationCode *string - - // The ID number generated by the system when it processed the activation. The - // activation ID functions like a user name. - ActivationId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateActivationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateActivation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateActivation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateActivation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateActivationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateActivation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateActivation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateActivation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociation.go deleted file mode 100644 index 4468b48..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociation.go +++ /dev/null @@ -1,286 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// A State Manager association defines the state that you want to maintain on your -// managed nodes. For example, an association can specify that anti-virus software -// must be installed and running on your managed nodes, or that certain ports must -// be closed. For static targets, the association specifies a schedule for when the -// configuration is reapplied. For dynamic targets, such as an Amazon Web Services -// resource group or an Amazon Web Services autoscaling group, State Manager, a -// capability of Amazon Web Services Systems Manager applies the configuration when -// new managed nodes are added to the group. The association also specifies actions -// to take when applying the configuration. For example, an association for -// anti-virus software might run once a day. If the software isn't installed, then -// State Manager installs it. If the software is installed, but the service isn't -// running, then the association might instruct State Manager to start the service. -func (c *Client) CreateAssociation(ctx context.Context, params *CreateAssociationInput, optFns ...func(*Options)) (*CreateAssociationOutput, error) { - if params == nil { - params = &CreateAssociationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateAssociation", params, optFns, c.addOperationCreateAssociationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateAssociationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateAssociationInput struct { - - // The name of the SSM Command document or Automation runbook that contains the - // configuration information for the managed node. You can specify Amazon Web - // Services-predefined documents, documents you created, or a document that is - // shared with you from another Amazon Web Services account. For Systems Manager - // documents (SSM documents) that are shared with you from other Amazon Web - // Services accounts, you must specify the complete SSM document ARN, in the - // following format: arn:partition:ssm:region:account-id:document/document-name - // For example: arn:aws:ssm:us-east-2:12345678912:document/My-Shared-Document For - // Amazon Web Services-predefined documents and SSM documents you created in your - // account, you only need to specify the document name. For example, - // AWS-ApplyPatchBaseline or My-Document . - // - // This member is required. - Name *string - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - AlarmConfiguration *types.AlarmConfiguration - - // By default, when you create a new association, the system runs it immediately - // after it is created and then according to the schedule you specified. Specify - // this option if you don't want an association to run immediately after you create - // it. This parameter isn't supported for rate expressions. - ApplyOnlyAtCronInterval bool - - // Specify a descriptive name for the association. - AssociationName *string - - // Choose the parameter that will define how your automation will branch out. This - // target is required for associations that use an Automation runbook and target - // resources by using rate controls. Automation is a capability of Amazon Web - // Services Systems Manager. - AutomationTargetParameterName *string - - // The names or Amazon Resource Names (ARNs) of the Change Calendar type documents - // you want to gate your associations under. The associations only run when that - // change calendar is open. For more information, see Amazon Web Services Systems - // Manager Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar) - // . - CalendarNames []string - - // The severity level to assign to the association. - ComplianceSeverity types.AssociationComplianceSeverity - - // The document version you want to associate with the target(s). Can be a - // specific version or the default version. State Manager doesn't support running - // associations that use a new version of a document if that document is shared - // from another account. State Manager always runs the default version of a - // document if shared from another account, even though the Systems Manager console - // shows that a new version was processed. If you want to run an association using - // a new version of a document shared form another account, you must set the - // document version to default . - DocumentVersion *string - - // The managed node ID. InstanceId has been deprecated. To specify a managed node - // ID for an association, use the Targets parameter. Requests that include the - // parameter InstanceID with Systems Manager documents (SSM documents) that use - // schema version 2.0 or later will fail. In addition, if you use the parameter - // InstanceId , you can't use the parameters AssociationName , DocumentVersion , - // MaxErrors , MaxConcurrency , OutputLocation , or ScheduleExpression . To use - // these parameters, you must use the Targets parameter. - InstanceId *string - - // The maximum number of targets allowed to run the association at the same time. - // You can specify a number, for example 10, or a percentage of the target set, for - // example 10%. The default value is 100%, which means all targets run the - // association at the same time. If a new managed node starts and attempts to run - // an association while Systems Manager is running MaxConcurrency associations, - // the association is allowed to run. During the next association interval, the new - // managed node will process its association within the limit specified for - // MaxConcurrency . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops sending requests - // to run the association on additional targets. You can specify either an absolute - // number of errors, for example 10, or a percentage of the target set, for example - // 10%. If you specify 3, for example, the system stops sending requests when the - // fourth error is received. If you specify 0, then the system stops sending - // requests after the first error is returned. If you run an association on 50 - // managed nodes and set MaxError to 10%, then the system stops sending the - // request when the sixth error is received. Executions that are already running an - // association when MaxErrors is reached are allowed to complete, but some of - // these executions may fail as well. If you need to ensure that there won't be - // more than max-errors failed executions, set MaxConcurrency to 1 so that - // executions proceed one at a time. - MaxErrors *string - - // An Amazon Simple Storage Service (Amazon S3) bucket where you want to store the - // output details of the request. - OutputLocation *types.InstanceAssociationOutputLocation - - // The parameters for the runtime configuration of the document. - Parameters map[string][]string - - // A cron expression when the association will be applied to the target(s). - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. For - // example, if you specified a cron schedule of cron(0 0 ? * THU#2 *) , you could - // specify an offset of 3 to run the association each Sunday after the second - // Thursday of the month. For more information about cron schedules for - // associations, see Reference: Cron and rate expressions for Systems Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/reference-cron-and-rate-expressions.html) - // in the Amazon Web Services Systems Manager User Guide. To use offsets, you must - // specify the ApplyOnlyAtCronInterval parameter. This option tells the system not - // to run an association immediately after you create it. - ScheduleOffset *int32 - - // The mode for generating association compliance. You can specify AUTO or MANUAL . - // In AUTO mode, the system uses the status of the association execution to - // determine the compliance status. If the association execution runs successfully, - // then the association is COMPLIANT . If the association execution doesn't run - // successfully, the association is NON-COMPLIANT . In MANUAL mode, you must - // specify the AssociationId as a parameter for the PutComplianceItems API - // operation. In this case, compliance data isn't managed by State Manager. It is - // managed by your direct call to the PutComplianceItems API operation. By - // default, all associations use AUTO mode. - SyncCompliance types.AssociationSyncCompliance - - // Adds or overwrites one or more tags for a State Manager association. Tags are - // metadata that you can assign to your Amazon Web Services resources. Tags enable - // you to categorize your resources in different ways, for example, by purpose, - // owner, or environment. Each tag consists of a key and an optional value, both of - // which you define. - Tags []types.Tag - - // A location is a combination of Amazon Web Services Regions and Amazon Web - // Services accounts where you want to run the association. Use this action to - // create an association in multiple Regions and multiple accounts. - TargetLocations []types.TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The targets for the association. You can target managed nodes by using tags, - // Amazon Web Services resource groups, all managed nodes in an Amazon Web Services - // account, or individual managed node IDs. You can target all managed nodes in an - // Amazon Web Services account by specifying the InstanceIds key with a value of * - // . For more information about choosing targets for an association, see Using - // targets and rate controls with State Manager associations (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-state-manager-targets-and-rate-controls.html) - // in the Amazon Web Services Systems Manager User Guide. - Targets []types.Target - - noSmithyDocumentSerde -} - -type CreateAssociationOutput struct { - - // Information about the association. - AssociationDescription *types.AssociationDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateAssociation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateAssociation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateAssociation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateAssociationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateAssociation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateAssociation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateAssociation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociationBatch.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociationBatch.go deleted file mode 100644 index 9d42a18..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateAssociationBatch.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Associates the specified Amazon Web Services Systems Manager document (SSM -// document) with the specified managed nodes or targets. When you associate a -// document with one or more managed nodes using IDs or tags, Amazon Web Services -// Systems Manager Agent (SSM Agent) running on the managed node processes the -// document and configures the node as specified. If you associate a document with -// a managed node that already has an associated document, the system returns the -// AssociationAlreadyExists exception. -func (c *Client) CreateAssociationBatch(ctx context.Context, params *CreateAssociationBatchInput, optFns ...func(*Options)) (*CreateAssociationBatchOutput, error) { - if params == nil { - params = &CreateAssociationBatchInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateAssociationBatch", params, optFns, c.addOperationCreateAssociationBatchMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateAssociationBatchOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateAssociationBatchInput struct { - - // One or more associations. - // - // This member is required. - Entries []types.CreateAssociationBatchRequestEntry - - noSmithyDocumentSerde -} - -type CreateAssociationBatchOutput struct { - - // Information about the associations that failed. - Failed []types.FailedCreateAssociation - - // Information about the associations that succeeded. - Successful []types.AssociationDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateAssociationBatchMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateAssociationBatch{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateAssociationBatch{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateAssociationBatch"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateAssociationBatchValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateAssociationBatch(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateAssociationBatch(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateAssociationBatch", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateDocument.go deleted file mode 100644 index ef56324..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateDocument.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates a Amazon Web Services Systems Manager (SSM document). An SSM document -// defines the actions that Systems Manager performs on your managed nodes. For -// more information about SSM documents, including information about supported -// schemas, features, and syntax, see Amazon Web Services Systems Manager Documents (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-ssm-docs.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) CreateDocument(ctx context.Context, params *CreateDocumentInput, optFns ...func(*Options)) (*CreateDocumentOutput, error) { - if params == nil { - params = &CreateDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateDocument", params, optFns, c.addOperationCreateDocumentMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateDocumentInput struct { - - // The content for the new SSM document in JSON or YAML format. The content of the - // document must not exceed 64KB. This quota also includes the content specified - // for input parameters at runtime. We recommend storing the contents for your new - // document in an external JSON or YAML file and referencing the file in a command. - // For examples, see the following topics in the Amazon Web Services Systems - // Manager User Guide. - // - Create an SSM document (Amazon Web Services API) (https://docs.aws.amazon.com/systems-manager/latest/userguide/create-ssm-document-api.html) - // - Create an SSM document (Amazon Web Services CLI) (https://docs.aws.amazon.com/systems-manager/latest/userguide/create-ssm-document-cli.html) - // - Create an SSM document (API) (https://docs.aws.amazon.com/systems-manager/latest/userguide/create-ssm-document-api.html) - // - // This member is required. - Content *string - - // A name for the SSM document. You can't use the following strings as document - // name prefixes. These are reserved by Amazon Web Services for use as document - // name prefixes: - // - aws - // - amazon - // - amzn - // - // This member is required. - Name *string - - // A list of key-value pairs that describe attachments to a version of a document. - Attachments []types.AttachmentsSource - - // An optional field where you can specify a friendly name for the SSM document. - // This value can differ for each version of the document. You can update this - // value at a later time using the UpdateDocument operation. - DisplayName *string - - // Specify the document format for the request. The document format can be JSON, - // YAML, or TEXT. JSON is the default format. - DocumentFormat types.DocumentFormat - - // The type of document to create. The DeploymentStrategy document type is an - // internal-use-only document type reserved for AppConfig. - DocumentType types.DocumentType - - // A list of SSM documents required by a document. This parameter is used - // exclusively by AppConfig. When a user creates an AppConfig configuration in an - // SSM document, the user must also specify a required document for validation - // purposes. In this case, an ApplicationConfiguration document requires an - // ApplicationConfigurationSchema document for validation purposes. For more - // information, see What is AppConfig? (https://docs.aws.amazon.com/appconfig/latest/userguide/what-is-appconfig.html) - // in the AppConfig User Guide. - Requires []types.DocumentRequires - - // Optional metadata that you assign to a resource. Tags enable you to categorize - // a resource in different ways, such as by purpose, owner, or environment. For - // example, you might want to tag an SSM document to identify the types of targets - // or the environment where it will run. In this case, you could specify the - // following key-value pairs: - // - Key=OS,Value=Windows - // - Key=Environment,Value=Production - // To add tags to an existing SSM document, use the AddTagsToResource operation. - Tags []types.Tag - - // Specify a target type to define the kinds of resources the document can run on. - // For example, to run a document on EC2 instances, specify the following value: - // /AWS::EC2::Instance . If you specify a value of '/' the document can run on all - // types of resources. If you don't specify a value, the document can't run on any - // resources. For a list of valid resource types, see Amazon Web Services resource - // and property types reference (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) - // in the CloudFormation User Guide. - TargetType *string - - // An optional field specifying the version of the artifact you are creating with - // the document. For example, Release12.1 . This value is unique across all - // versions of a document, and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -type CreateDocumentOutput struct { - - // Information about the SSM document. - DocumentDescription *types.DocumentDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateDocumentMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateDocument{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateDocument{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateDocument"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateDocumentValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateDocument(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateDocument(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateDocument", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateMaintenanceWindow.go deleted file mode 100644 index ba9b529..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateMaintenanceWindow.go +++ /dev/null @@ -1,247 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates a new maintenance window. The value you specify for Duration determines -// the specific end time for the maintenance window based on the time it begins. No -// maintenance window tasks are permitted to start after the resulting endtime -// minus the number of hours you specify for Cutoff . For example, if the -// maintenance window starts at 3 PM, the duration is three hours, and the value -// you specify for Cutoff is one hour, no maintenance window tasks can start after -// 5 PM. -func (c *Client) CreateMaintenanceWindow(ctx context.Context, params *CreateMaintenanceWindowInput, optFns ...func(*Options)) (*CreateMaintenanceWindowOutput, error) { - if params == nil { - params = &CreateMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateMaintenanceWindow", params, optFns, c.addOperationCreateMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateMaintenanceWindowInput struct { - - // Enables a maintenance window task to run on managed nodes, even if you haven't - // registered those nodes as targets. If enabled, then you must specify the - // unregistered managed nodes (by node ID) when you register a task with the - // maintenance window. If you don't enable this option, then you must specify - // previously-registered targets when you register a task with the maintenance - // window. - // - // This member is required. - AllowUnassociatedTargets bool - - // The number of hours before the end of the maintenance window that Amazon Web - // Services Systems Manager stops scheduling new tasks for execution. - // - // This member is required. - Cutoff int32 - - // The duration of the maintenance window in hours. - // - // This member is required. - Duration *int32 - - // The name of the maintenance window. - // - // This member is required. - Name *string - - // The schedule of the maintenance window in the form of a cron or rate expression. - // - // This member is required. - Schedule *string - - // User-provided idempotency token. - ClientToken *string - - // An optional description for the maintenance window. We recommend specifying a - // description to help you organize your maintenance windows. - Description *string - - // The date and time, in ISO-8601 Extended format, for when you want the - // maintenance window to become inactive. EndDate allows you to set a date and - // time in the future when the maintenance window will no longer run. - EndDate *string - - // The number of days to wait after the date and time specified by a cron - // expression before running the maintenance window. For example, the following - // cron expression schedules a maintenance window to run on the third Tuesday of - // every month at 11:30 PM. cron(30 23 ? * TUE#3 *) If the schedule offset is 2 , - // the maintenance window won't run until two days later. - ScheduleOffset *int32 - - // The time zone that the scheduled maintenance window executions are based on, in - // Internet Assigned Numbers Authority (IANA) format. For example: - // "America/Los_Angeles", "UTC", or "Asia/Seoul". For more information, see the - // Time Zone Database (https://www.iana.org/time-zones) on the IANA website. - ScheduleTimezone *string - - // The date and time, in ISO-8601 Extended format, for when you want the - // maintenance window to become active. StartDate allows you to delay activation - // of the maintenance window until the specified future date. - StartDate *string - - // Optional metadata that you assign to a resource. Tags enable you to categorize - // a resource in different ways, such as by purpose, owner, or environment. For - // example, you might want to tag a maintenance window to identify the type of - // tasks it will run, the types of targets, and the environment it will run in. In - // this case, you could specify the following key-value pairs: - // - Key=TaskType,Value=AgentUpdate - // - Key=OS,Value=Windows - // - Key=Environment,Value=Production - // To add tags to an existing maintenance window, use the AddTagsToResource - // operation. - Tags []types.Tag - - noSmithyDocumentSerde -} - -type CreateMaintenanceWindowOutput struct { - - // The ID of the created maintenance window. - WindowId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addIdempotencyToken_opCreateMaintenanceWindowMiddleware(stack, options); err != nil { - return err - } - if err = addOpCreateMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -type idempotencyToken_initializeOpCreateMaintenanceWindow struct { - tokenProvider IdempotencyTokenProvider -} - -func (*idempotencyToken_initializeOpCreateMaintenanceWindow) ID() string { - return "OperationIdempotencyTokenAutoFill" -} - -func (m *idempotencyToken_initializeOpCreateMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.tokenProvider == nil { - return next.HandleInitialize(ctx, in) - } - - input, ok := in.Parameters.(*CreateMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("expected middleware input to be of type *CreateMaintenanceWindowInput ") - } - - if input.ClientToken == nil { - t, err := m.tokenProvider.GetIdempotencyToken() - if err != nil { - return out, metadata, err - } - input.ClientToken = &t - } - return next.HandleInitialize(ctx, in) -} -func addIdempotencyToken_opCreateMaintenanceWindowMiddleware(stack *middleware.Stack, cfg Options) error { - return stack.Initialize.Add(&idempotencyToken_initializeOpCreateMaintenanceWindow{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before) -} - -func newServiceMetadataMiddleware_opCreateMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsItem.go deleted file mode 100644 index cd081f9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsItem.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Creates a new OpsItem. You must have permission in Identity and Access -// Management (IAM) to create a new OpsItem. For more information, see Set up -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setup.html) -// in the Amazon Web Services Systems Manager User Guide. Operations engineers and -// IT professionals use Amazon Web Services Systems Manager OpsCenter to view, -// investigate, and remediate operational issues impacting the performance and -// health of their Amazon Web Services resources. For more information, see Amazon -// Web Services Systems Manager OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) CreateOpsItem(ctx context.Context, params *CreateOpsItemInput, optFns ...func(*Options)) (*CreateOpsItemOutput, error) { - if params == nil { - params = &CreateOpsItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateOpsItem", params, optFns, c.addOperationCreateOpsItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateOpsItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateOpsItemInput struct { - - // User-defined text that contains information about the OpsItem, in Markdown - // format. Provide enough information so that users viewing this OpsItem for the - // first time understand the issue. - // - // This member is required. - Description *string - - // The origin of the OpsItem, such as Amazon EC2 or Systems Manager. The source - // name can't contain the following strings: aws , amazon , and amzn . - // - // This member is required. - Source *string - - // A short heading that describes the nature of the OpsItem and the impacted - // resource. - // - // This member is required. - Title *string - - // The target Amazon Web Services account where you want to create an OpsItem. To - // make this call, your account must be configured to work with OpsItems across - // accounts. For more information, see Set up OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setup.html) - // in the Amazon Web Services Systems Manager User Guide. - AccountId *string - - // The time a runbook workflow ended. Currently reported only for the OpsItem type - // /aws/changerequest . - ActualEndTime *time.Time - - // The time a runbook workflow started. Currently reported only for the OpsItem - // type /aws/changerequest . - ActualStartTime *time.Time - - // Specify a category to assign to an OpsItem. - Category *string - - // The Amazon Resource Name (ARN) of an SNS topic where notifications are sent - // when this OpsItem is edited or changed. - Notifications []types.OpsItemNotification - - // Operational data is custom data that provides useful reference details about - // the OpsItem. For example, you can specify log files, error strings, license - // keys, troubleshooting tips, or other relevant data. You enter operational data - // as key-value pairs. The key has a maximum length of 128 characters. The value - // has a maximum size of 20 KB. Operational data keys can't begin with the - // following: amazon , aws , amzn , ssm , /amazon , /aws , /amzn , /ssm . You can - // choose to make the data searchable by other users in the account or you can - // restrict search access. Searchable data means that all users with access to the - // OpsItem Overview page (as provided by the DescribeOpsItems API operation) can - // view and search on the specified data. Operational data that isn't searchable is - // only viewable by users who have access to the OpsItem (as provided by the - // GetOpsItem API operation). Use the /aws/resources key in OperationalData to - // specify a related resource in the request. Use the /aws/automations key in - // OperationalData to associate an Automation runbook with the OpsItem. To view - // Amazon Web Services CLI example commands that use these keys, see Creating - // OpsItems manually (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-manually-create-OpsItems.html) - // in the Amazon Web Services Systems Manager User Guide. - OperationalData map[string]types.OpsItemDataValue - - // The type of OpsItem to create. Systems Manager supports the following types of - // OpsItems: - // - /aws/issue This type of OpsItem is used for default OpsItems created by - // OpsCenter. - // - /aws/changerequest This type of OpsItem is used by Change Manager for - // reviewing and approving or rejecting change requests. - // - /aws/insight This type of OpsItem is used by OpsCenter for aggregating and - // reporting on duplicate OpsItems. - OpsItemType *string - - // The time specified in a change request for a runbook workflow to end. Currently - // supported only for the OpsItem type /aws/changerequest . - PlannedEndTime *time.Time - - // The time specified in a change request for a runbook workflow to start. - // Currently supported only for the OpsItem type /aws/changerequest . - PlannedStartTime *time.Time - - // The importance of this OpsItem in relation to other OpsItems in the system. - Priority *int32 - - // One or more OpsItems that share something in common with the current OpsItems. - // For example, related OpsItems can include OpsItems with similar error messages, - // impacted resources, or statuses for the impacted resource. - RelatedOpsItems []types.RelatedOpsItem - - // Specify a severity to assign to an OpsItem. - Severity *string - - // Optional metadata that you assign to a resource. Tags use a key-value pair. For - // example: Key=Department,Value=Finance To add tags to a new OpsItem, a user must - // have IAM permissions for both the ssm:CreateOpsItems operation and the - // ssm:AddTagsToResource operation. To add tags to an existing OpsItem, use the - // AddTagsToResource operation. - Tags []types.Tag - - noSmithyDocumentSerde -} - -type CreateOpsItemOutput struct { - - // The OpsItem Amazon Resource Name (ARN). - OpsItemArn *string - - // The ID of the OpsItem. - OpsItemId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateOpsItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateOpsItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateOpsItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateOpsItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateOpsItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateOpsItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateOpsItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateOpsItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsMetadata.go deleted file mode 100644 index dc87bc2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateOpsMetadata.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// If you create a new application in Application Manager, Amazon Web Services -// Systems Manager calls this API operation to specify information about the new -// application, including the application type. -func (c *Client) CreateOpsMetadata(ctx context.Context, params *CreateOpsMetadataInput, optFns ...func(*Options)) (*CreateOpsMetadataOutput, error) { - if params == nil { - params = &CreateOpsMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateOpsMetadata", params, optFns, c.addOperationCreateOpsMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateOpsMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateOpsMetadataInput struct { - - // A resource ID for a new Application Manager application. - // - // This member is required. - ResourceId *string - - // Metadata for a new Application Manager application. - Metadata map[string]types.MetadataValue - - // Optional metadata that you assign to a resource. You can specify a maximum of - // five tags for an OpsMetadata object. Tags enable you to categorize a resource in - // different ways, such as by purpose, owner, or environment. For example, you - // might want to tag an OpsMetadata object to identify an environment or target - // Amazon Web Services Region. In this case, you could specify the following - // key-value pairs: - // - Key=Environment,Value=Production - // - Key=Region,Value=us-east-2 - Tags []types.Tag - - noSmithyDocumentSerde -} - -type CreateOpsMetadataOutput struct { - - // The Amazon Resource Name (ARN) of the OpsMetadata Object or blob created by the - // call. - OpsMetadataArn *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateOpsMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateOpsMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateOpsMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateOpsMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateOpsMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateOpsMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateOpsMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateOpsMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreatePatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreatePatchBaseline.go deleted file mode 100644 index d1f8cc0..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreatePatchBaseline.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates a patch baseline. For information about valid key-value pairs in -// PatchFilters for each supported operating system type, see PatchFilter . -func (c *Client) CreatePatchBaseline(ctx context.Context, params *CreatePatchBaselineInput, optFns ...func(*Options)) (*CreatePatchBaselineOutput, error) { - if params == nil { - params = &CreatePatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreatePatchBaseline", params, optFns, c.addOperationCreatePatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreatePatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreatePatchBaselineInput struct { - - // The name of the patch baseline. - // - // This member is required. - Name *string - - // A set of rules used to include patches in the baseline. - ApprovalRules *types.PatchRuleGroup - - // A list of explicitly approved patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - ApprovedPatches []string - - // Defines the compliance level for approved patches. When an approved patch is - // reported as missing, this value describes the severity of the compliance - // violation. The default value is UNSPECIFIED . - ApprovedPatchesComplianceLevel types.PatchComplianceLevel - - // Indicates whether the list of approved patches includes non-security updates - // that should be applied to the managed nodes. The default value is false . - // Applies to Linux managed nodes only. - ApprovedPatchesEnableNonSecurity *bool - - // User-provided idempotency token. - ClientToken *string - - // A description of the patch baseline. - Description *string - - // A set of global filters used to include patches in the baseline. - GlobalFilters *types.PatchFilterGroup - - // Defines the operating system the patch baseline applies to. The default value - // is WINDOWS . - OperatingSystem types.OperatingSystem - - // A list of explicitly rejected patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - RejectedPatches []string - - // The action for Patch Manager to take on patches included in the RejectedPackages - // list. - // - ALLOW_AS_DEPENDENCY : A package in the Rejected patches list is installed - // only if it is a dependency of another package. It is considered compliant with - // the patch baseline, and its status is reported as InstalledOther . This is the - // default action if no option is specified. - // - BLOCK : Packages in the RejectedPatches list, and packages that include them - // as dependencies, aren't installed under any circumstances. If a package was - // installed before it was added to the Rejected patches list, it is considered - // non-compliant with the patch baseline, and its status is reported as - // InstalledRejected . - RejectedPatchesAction types.PatchAction - - // Information about the patches to use to update the managed nodes, including - // target operating systems and source repositories. Applies to Linux managed nodes - // only. - Sources []types.PatchSource - - // Optional metadata that you assign to a resource. Tags enable you to categorize - // a resource in different ways, such as by purpose, owner, or environment. For - // example, you might want to tag a patch baseline to identify the severity level - // of patches it specifies and the operating system family it applies to. In this - // case, you could specify the following key-value pairs: - // - Key=PatchSeverity,Value=Critical - // - Key=OS,Value=Windows - // To add tags to an existing patch baseline, use the AddTagsToResource operation. - Tags []types.Tag - - noSmithyDocumentSerde -} - -type CreatePatchBaselineOutput struct { - - // The ID of the created patch baseline. - BaselineId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreatePatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreatePatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreatePatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreatePatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addIdempotencyToken_opCreatePatchBaselineMiddleware(stack, options); err != nil { - return err - } - if err = addOpCreatePatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreatePatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -type idempotencyToken_initializeOpCreatePatchBaseline struct { - tokenProvider IdempotencyTokenProvider -} - -func (*idempotencyToken_initializeOpCreatePatchBaseline) ID() string { - return "OperationIdempotencyTokenAutoFill" -} - -func (m *idempotencyToken_initializeOpCreatePatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.tokenProvider == nil { - return next.HandleInitialize(ctx, in) - } - - input, ok := in.Parameters.(*CreatePatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("expected middleware input to be of type *CreatePatchBaselineInput ") - } - - if input.ClientToken == nil { - t, err := m.tokenProvider.GetIdempotencyToken() - if err != nil { - return out, metadata, err - } - input.ClientToken = &t - } - return next.HandleInitialize(ctx, in) -} -func addIdempotencyToken_opCreatePatchBaselineMiddleware(stack *middleware.Stack, cfg Options) error { - return stack.Initialize.Add(&idempotencyToken_initializeOpCreatePatchBaseline{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before) -} - -func newServiceMetadataMiddleware_opCreatePatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreatePatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateResourceDataSync.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateResourceDataSync.go deleted file mode 100644 index 69343ce..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_CreateResourceDataSync.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// A resource data sync helps you view data from multiple sources in a single -// location. Amazon Web Services Systems Manager offers two types of resource data -// sync: SyncToDestination and SyncFromSource . You can configure Systems Manager -// Inventory to use the SyncToDestination type to synchronize Inventory data from -// multiple Amazon Web Services Regions to a single Amazon Simple Storage Service -// (Amazon S3) bucket. For more information, see Configuring resource data sync -// for Inventory (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-datasync.html) -// in the Amazon Web Services Systems Manager User Guide. You can configure Systems -// Manager Explorer to use the SyncFromSource type to synchronize operational work -// items (OpsItems) and operational data (OpsData) from multiple Amazon Web -// Services Regions to a single Amazon S3 bucket. This type can synchronize -// OpsItems and OpsData from multiple Amazon Web Services accounts and Amazon Web -// Services Regions or EntireOrganization by using Organizations. For more -// information, see Setting up Systems Manager Explorer to display data from -// multiple accounts and Regions (https://docs.aws.amazon.com/systems-manager/latest/userguide/Explorer-resource-data-sync.html) -// in the Amazon Web Services Systems Manager User Guide. A resource data sync is -// an asynchronous operation that returns immediately. After a successful initial -// sync is completed, the system continuously syncs data. To check the status of a -// sync, use the ListResourceDataSync . By default, data isn't encrypted in Amazon -// S3. We strongly recommend that you enable encryption in Amazon S3 to ensure -// secure data storage. We also recommend that you secure access to the Amazon S3 -// bucket by creating a restrictive bucket policy. -func (c *Client) CreateResourceDataSync(ctx context.Context, params *CreateResourceDataSyncInput, optFns ...func(*Options)) (*CreateResourceDataSyncOutput, error) { - if params == nil { - params = &CreateResourceDataSyncInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateResourceDataSync", params, optFns, c.addOperationCreateResourceDataSyncMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateResourceDataSyncOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateResourceDataSyncInput struct { - - // A name for the configuration. - // - // This member is required. - SyncName *string - - // Amazon S3 configuration details for the sync. This parameter is required if the - // SyncType value is SyncToDestination. - S3Destination *types.ResourceDataSyncS3Destination - - // Specify information about the data sources to synchronize. This parameter is - // required if the SyncType value is SyncFromSource. - SyncSource *types.ResourceDataSyncSource - - // Specify SyncToDestination to create a resource data sync that synchronizes data - // to an S3 bucket for Inventory. If you specify SyncToDestination , you must - // provide a value for S3Destination . Specify SyncFromSource to synchronize data - // from a single account and multiple Regions, or multiple Amazon Web Services - // accounts and Amazon Web Services Regions, as listed in Organizations for - // Explorer. If you specify SyncFromSource , you must provide a value for - // SyncSource . The default value is SyncToDestination . - SyncType *string - - noSmithyDocumentSerde -} - -type CreateResourceDataSyncOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateResourceDataSyncMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateResourceDataSync{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateResourceDataSync{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateResourceDataSync"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpCreateResourceDataSyncValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateResourceDataSync(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateResourceDataSync(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateResourceDataSync", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteActivation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteActivation.go deleted file mode 100644 index 1f5d44d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteActivation.go +++ /dev/null @@ -1,135 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes an activation. You aren't required to delete an activation. If you -// delete an activation, you can no longer use it to register additional managed -// nodes. Deleting an activation doesn't de-register managed nodes. You must -// manually de-register managed nodes. -func (c *Client) DeleteActivation(ctx context.Context, params *DeleteActivationInput, optFns ...func(*Options)) (*DeleteActivationOutput, error) { - if params == nil { - params = &DeleteActivationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteActivation", params, optFns, c.addOperationDeleteActivationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteActivationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteActivationInput struct { - - // The ID of the activation that you want to delete. - // - // This member is required. - ActivationId *string - - noSmithyDocumentSerde -} - -type DeleteActivationOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteActivationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteActivation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteActivation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteActivation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteActivationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteActivation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteActivation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteActivation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteAssociation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteAssociation.go deleted file mode 100644 index 5309e98..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteAssociation.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Disassociates the specified Amazon Web Services Systems Manager document (SSM -// document) from the specified managed node. If you created the association by -// using the Targets parameter, then you must delete the association by using the -// association ID. When you disassociate a document from a managed node, it doesn't -// change the configuration of the node. To change the configuration state of a -// managed node after you disassociate a document, you must create a new document -// with the desired configuration and associate it with the node. -func (c *Client) DeleteAssociation(ctx context.Context, params *DeleteAssociationInput, optFns ...func(*Options)) (*DeleteAssociationOutput, error) { - if params == nil { - params = &DeleteAssociationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteAssociation", params, optFns, c.addOperationDeleteAssociationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteAssociationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteAssociationInput struct { - - // The association ID that you want to delete. - AssociationId *string - - // The managed node ID. InstanceId has been deprecated. To specify a managed node - // ID for an association, use the Targets parameter. Requests that include the - // parameter InstanceID with Systems Manager documents (SSM documents) that use - // schema version 2.0 or later will fail. In addition, if you use the parameter - // InstanceId , you can't use the parameters AssociationName , DocumentVersion , - // MaxErrors , MaxConcurrency , OutputLocation , or ScheduleExpression . To use - // these parameters, you must use the Targets parameter. - InstanceId *string - - // The name of the SSM document. - Name *string - - noSmithyDocumentSerde -} - -type DeleteAssociationOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteAssociation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteAssociation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteAssociation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteAssociation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteAssociation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteAssociation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteDocument.go deleted file mode 100644 index 22c5089..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteDocument.go +++ /dev/null @@ -1,149 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes the Amazon Web Services Systems Manager document (SSM document) and all -// managed node associations to the document. Before you delete the document, we -// recommend that you use DeleteAssociation to disassociate all managed nodes that -// are associated with the document. -func (c *Client) DeleteDocument(ctx context.Context, params *DeleteDocumentInput, optFns ...func(*Options)) (*DeleteDocumentOutput, error) { - if params == nil { - params = &DeleteDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteDocument", params, optFns, c.addOperationDeleteDocumentMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteDocumentInput struct { - - // The name of the document. - // - // This member is required. - Name *string - - // The version of the document that you want to delete. If not provided, all - // versions of the document are deleted. - DocumentVersion *string - - // Some SSM document types require that you specify a Force flag before you can - // delete the document. For example, you must specify a Force flag to delete a - // document of type ApplicationConfigurationSchema . You can restrict access to the - // Force flag in an Identity and Access Management (IAM) policy. - Force bool - - // The version name of the document that you want to delete. If not provided, all - // versions of the document are deleted. - VersionName *string - - noSmithyDocumentSerde -} - -type DeleteDocumentOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteDocumentMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteDocument{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteDocument{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteDocument"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteDocumentValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteDocument(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteDocument(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteDocument", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteInventory.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteInventory.go deleted file mode 100644 index af8a010..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteInventory.go +++ /dev/null @@ -1,207 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Delete a custom inventory type or the data associated with a custom Inventory -// type. Deleting a custom inventory type is also referred to as deleting a custom -// inventory schema. -func (c *Client) DeleteInventory(ctx context.Context, params *DeleteInventoryInput, optFns ...func(*Options)) (*DeleteInventoryOutput, error) { - if params == nil { - params = &DeleteInventoryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteInventory", params, optFns, c.addOperationDeleteInventoryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteInventoryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteInventoryInput struct { - - // The name of the custom inventory type for which you want to delete either all - // previously collected data or the inventory type itself. - // - // This member is required. - TypeName *string - - // User-provided idempotency token. - ClientToken *string - - // Use this option to view a summary of the deletion request without deleting any - // data or the data type. This option is useful when you only want to understand - // what will be deleted. Once you validate that the data to be deleted is what you - // intend to delete, you can run the same command without specifying the DryRun - // option. - DryRun bool - - // Use the SchemaDeleteOption to delete a custom inventory type (schema). If you - // don't choose this option, the system only deletes existing inventory data - // associated with the custom inventory type. Choose one of the following options: - // DisableSchema: If you choose this option, the system ignores all inventory data - // for the specified version, and any earlier versions. To enable this schema - // again, you must call the PutInventory operation for a version greater than the - // disabled version. DeleteSchema: This option deletes the specified custom type - // from the Inventory service. You can recreate the schema later, if you want. - SchemaDeleteOption types.InventorySchemaDeleteOption - - noSmithyDocumentSerde -} - -type DeleteInventoryOutput struct { - - // Every DeleteInventory operation is assigned a unique ID. This option returns a - // unique ID. You can use this ID to query the status of a delete operation. This - // option is useful for ensuring that a delete operation has completed before you - // begin other operations. - DeletionId *string - - // A summary of the delete operation. For more information about this summary, see - // Deleting custom inventory (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-custom.html#sysman-inventory-delete-summary) - // in the Amazon Web Services Systems Manager User Guide. - DeletionSummary *types.InventoryDeletionSummary - - // The name of the inventory data type specified in the request. - TypeName *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteInventoryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteInventory{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteInventory{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteInventory"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addIdempotencyToken_opDeleteInventoryMiddleware(stack, options); err != nil { - return err - } - if err = addOpDeleteInventoryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteInventory(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -type idempotencyToken_initializeOpDeleteInventory struct { - tokenProvider IdempotencyTokenProvider -} - -func (*idempotencyToken_initializeOpDeleteInventory) ID() string { - return "OperationIdempotencyTokenAutoFill" -} - -func (m *idempotencyToken_initializeOpDeleteInventory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.tokenProvider == nil { - return next.HandleInitialize(ctx, in) - } - - input, ok := in.Parameters.(*DeleteInventoryInput) - if !ok { - return out, metadata, fmt.Errorf("expected middleware input to be of type *DeleteInventoryInput ") - } - - if input.ClientToken == nil { - t, err := m.tokenProvider.GetIdempotencyToken() - if err != nil { - return out, metadata, err - } - input.ClientToken = &t - } - return next.HandleInitialize(ctx, in) -} -func addIdempotencyToken_opDeleteInventoryMiddleware(stack *middleware.Stack, cfg Options) error { - return stack.Initialize.Add(&idempotencyToken_initializeOpDeleteInventory{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before) -} - -func newServiceMetadataMiddleware_opDeleteInventory(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteInventory", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteMaintenanceWindow.go deleted file mode 100644 index bc6c70a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteMaintenanceWindow.go +++ /dev/null @@ -1,136 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes a maintenance window. -func (c *Client) DeleteMaintenanceWindow(ctx context.Context, params *DeleteMaintenanceWindowInput, optFns ...func(*Options)) (*DeleteMaintenanceWindowOutput, error) { - if params == nil { - params = &DeleteMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteMaintenanceWindow", params, optFns, c.addOperationDeleteMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteMaintenanceWindowInput struct { - - // The ID of the maintenance window to delete. - // - // This member is required. - WindowId *string - - noSmithyDocumentSerde -} - -type DeleteMaintenanceWindowOutput struct { - - // The ID of the deleted maintenance window. - WindowId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsItem.go deleted file mode 100644 index 173debc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsItem.go +++ /dev/null @@ -1,149 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Delete an OpsItem. You must have permission in Identity and Access Management -// (IAM) to delete an OpsItem. Note the following important information about this -// operation. -// - Deleting an OpsItem is irreversible. You can't restore a deleted OpsItem. -// - This operation uses an eventual consistency model, which means the system -// can take a few minutes to complete this operation. If you delete an OpsItem and -// immediately call, for example, GetOpsItem , the deleted OpsItem might still -// appear in the response. -// - This operation is idempotent. The system doesn't throw an exception if you -// repeatedly call this operation for the same OpsItem. If the first call is -// successful, all additional calls return the same successful response as the -// first call. -// - This operation doesn't support cross-account calls. A delegated -// administrator or management account can't delete OpsItems in other accounts, -// even if OpsCenter has been set up for cross-account administration. For more -// information about cross-account administration, see Setting up OpsCenter to -// centrally manage OpsItems across accounts (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setting-up-cross-account.html) -// in the Systems Manager User Guide. -func (c *Client) DeleteOpsItem(ctx context.Context, params *DeleteOpsItemInput, optFns ...func(*Options)) (*DeleteOpsItemOutput, error) { - if params == nil { - params = &DeleteOpsItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteOpsItem", params, optFns, c.addOperationDeleteOpsItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteOpsItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteOpsItemInput struct { - - // The ID of the OpsItem that you want to delete. - // - // This member is required. - OpsItemId *string - - noSmithyDocumentSerde -} - -type DeleteOpsItemOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteOpsItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteOpsItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteOpsItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteOpsItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteOpsItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteOpsItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteOpsItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteOpsItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsMetadata.go deleted file mode 100644 index 04e2826..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteOpsMetadata.go +++ /dev/null @@ -1,132 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Delete OpsMetadata related to an application. -func (c *Client) DeleteOpsMetadata(ctx context.Context, params *DeleteOpsMetadataInput, optFns ...func(*Options)) (*DeleteOpsMetadataOutput, error) { - if params == nil { - params = &DeleteOpsMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteOpsMetadata", params, optFns, c.addOperationDeleteOpsMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteOpsMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteOpsMetadataInput struct { - - // The Amazon Resource Name (ARN) of an OpsMetadata Object to delete. - // - // This member is required. - OpsMetadataArn *string - - noSmithyDocumentSerde -} - -type DeleteOpsMetadataOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteOpsMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteOpsMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteOpsMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteOpsMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteOpsMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteOpsMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteOpsMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteOpsMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameter.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameter.go deleted file mode 100644 index 066e055..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameter.go +++ /dev/null @@ -1,133 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Delete a parameter from the system. After deleting a parameter, wait for at -// least 30 seconds to create a parameter with the same name. -func (c *Client) DeleteParameter(ctx context.Context, params *DeleteParameterInput, optFns ...func(*Options)) (*DeleteParameterOutput, error) { - if params == nil { - params = &DeleteParameterInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteParameter", params, optFns, c.addOperationDeleteParameterMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteParameterOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteParameterInput struct { - - // The name of the parameter to delete. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -type DeleteParameterOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteParameterMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteParameter{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteParameter{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteParameter"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteParameterValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteParameter(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteParameter(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteParameter", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameters.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameters.go deleted file mode 100644 index ce6c9da..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteParameters.go +++ /dev/null @@ -1,142 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Delete a list of parameters. After deleting a parameter, wait for at least 30 -// seconds to create a parameter with the same name. -func (c *Client) DeleteParameters(ctx context.Context, params *DeleteParametersInput, optFns ...func(*Options)) (*DeleteParametersOutput, error) { - if params == nil { - params = &DeleteParametersInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteParameters", params, optFns, c.addOperationDeleteParametersMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteParametersOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteParametersInput struct { - - // The names of the parameters to delete. After deleting a parameter, wait for at - // least 30 seconds to create a parameter with the same name. - // - // This member is required. - Names []string - - noSmithyDocumentSerde -} - -type DeleteParametersOutput struct { - - // The names of the deleted parameters. - DeletedParameters []string - - // The names of parameters that weren't deleted because the parameters aren't - // valid. - InvalidParameters []string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteParametersMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteParameters{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteParameters{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteParameters"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteParametersValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteParameters(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteParameters(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteParameters", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeletePatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeletePatchBaseline.go deleted file mode 100644 index 7320e69..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeletePatchBaseline.go +++ /dev/null @@ -1,136 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes a patch baseline. -func (c *Client) DeletePatchBaseline(ctx context.Context, params *DeletePatchBaselineInput, optFns ...func(*Options)) (*DeletePatchBaselineOutput, error) { - if params == nil { - params = &DeletePatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeletePatchBaseline", params, optFns, c.addOperationDeletePatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeletePatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeletePatchBaselineInput struct { - - // The ID of the patch baseline to delete. - // - // This member is required. - BaselineId *string - - noSmithyDocumentSerde -} - -type DeletePatchBaselineOutput struct { - - // The ID of the deleted patch baseline. - BaselineId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeletePatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeletePatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeletePatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeletePatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeletePatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeletePatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeletePatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeletePatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourceDataSync.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourceDataSync.go deleted file mode 100644 index a2584fa..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourceDataSync.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes a resource data sync configuration. After the configuration is deleted, -// changes to data on managed nodes are no longer synced to or from the target. -// Deleting a sync configuration doesn't delete data. -func (c *Client) DeleteResourceDataSync(ctx context.Context, params *DeleteResourceDataSyncInput, optFns ...func(*Options)) (*DeleteResourceDataSyncOutput, error) { - if params == nil { - params = &DeleteResourceDataSyncInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteResourceDataSync", params, optFns, c.addOperationDeleteResourceDataSyncMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteResourceDataSyncOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteResourceDataSyncInput struct { - - // The name of the configuration to delete. - // - // This member is required. - SyncName *string - - // Specify the type of resource data sync to delete. - SyncType *string - - noSmithyDocumentSerde -} - -type DeleteResourceDataSyncOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteResourceDataSyncMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteResourceDataSync{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteResourceDataSync{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteResourceDataSync"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteResourceDataSyncValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteResourceDataSync(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteResourceDataSync(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteResourceDataSync", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourcePolicy.go deleted file mode 100644 index c290f83..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeleteResourcePolicy.go +++ /dev/null @@ -1,148 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes a Systems Manager resource policy. A resource policy helps you to -// define the IAM entity (for example, an Amazon Web Services account) that can -// manage your Systems Manager resources. Currently, OpsItemGroup is the only -// resource that supports Systems Manager resource policies. The resource policy -// for OpsItemGroup enables Amazon Web Services accounts to view and interact with -// OpsCenter operational work items (OpsItems). -func (c *Client) DeleteResourcePolicy(ctx context.Context, params *DeleteResourcePolicyInput, optFns ...func(*Options)) (*DeleteResourcePolicyOutput, error) { - if params == nil { - params = &DeleteResourcePolicyInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeleteResourcePolicy", params, optFns, c.addOperationDeleteResourcePolicyMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeleteResourcePolicyOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeleteResourcePolicyInput struct { - - // ID of the current policy version. The hash helps to prevent multiple calls from - // attempting to overwrite a policy. - // - // This member is required. - PolicyHash *string - - // The policy ID. - // - // This member is required. - PolicyId *string - - // Amazon Resource Name (ARN) of the resource to which the policies are attached. - // - // This member is required. - ResourceArn *string - - noSmithyDocumentSerde -} - -type DeleteResourcePolicyOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeleteResourcePolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteResourcePolicy{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeleteResourcePolicy{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteResourcePolicy"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeleteResourcePolicyValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteResourcePolicy(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeleteResourcePolicy(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeleteResourcePolicy", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterManagedInstance.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterManagedInstance.go deleted file mode 100644 index 8c199ab..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterManagedInstance.go +++ /dev/null @@ -1,135 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes the server or virtual machine from the list of registered servers. You -// can reregister the node again at any time. If you don't plan to use Run Command -// on the server, we suggest uninstalling SSM Agent first. -func (c *Client) DeregisterManagedInstance(ctx context.Context, params *DeregisterManagedInstanceInput, optFns ...func(*Options)) (*DeregisterManagedInstanceOutput, error) { - if params == nil { - params = &DeregisterManagedInstanceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeregisterManagedInstance", params, optFns, c.addOperationDeregisterManagedInstanceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeregisterManagedInstanceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeregisterManagedInstanceInput struct { - - // The ID assigned to the managed node when you registered it using the activation - // process. - // - // This member is required. - InstanceId *string - - noSmithyDocumentSerde -} - -type DeregisterManagedInstanceOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeregisterManagedInstanceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeregisterManagedInstance{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeregisterManagedInstance{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeregisterManagedInstance"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeregisterManagedInstanceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeregisterManagedInstance(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeregisterManagedInstance(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeregisterManagedInstance", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterPatchBaselineForPatchGroup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterPatchBaselineForPatchGroup.go deleted file mode 100644 index 4e2fadc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterPatchBaselineForPatchGroup.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes a patch group from a patch baseline. -func (c *Client) DeregisterPatchBaselineForPatchGroup(ctx context.Context, params *DeregisterPatchBaselineForPatchGroupInput, optFns ...func(*Options)) (*DeregisterPatchBaselineForPatchGroupOutput, error) { - if params == nil { - params = &DeregisterPatchBaselineForPatchGroupInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeregisterPatchBaselineForPatchGroup", params, optFns, c.addOperationDeregisterPatchBaselineForPatchGroupMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeregisterPatchBaselineForPatchGroupOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeregisterPatchBaselineForPatchGroupInput struct { - - // The ID of the patch baseline to deregister the patch group from. - // - // This member is required. - BaselineId *string - - // The name of the patch group that should be deregistered from the patch baseline. - // - // This member is required. - PatchGroup *string - - noSmithyDocumentSerde -} - -type DeregisterPatchBaselineForPatchGroupOutput struct { - - // The ID of the patch baseline the patch group was deregistered from. - BaselineId *string - - // The name of the patch group deregistered from the patch baseline. - PatchGroup *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeregisterPatchBaselineForPatchGroupMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeregisterPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeregisterPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeregisterPatchBaselineForPatchGroup"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeregisterPatchBaselineForPatchGroupValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeregisterPatchBaselineForPatchGroup(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeregisterPatchBaselineForPatchGroup(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeregisterPatchBaselineForPatchGroup", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTargetFromMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTargetFromMaintenanceWindow.go deleted file mode 100644 index e2b33cf..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTargetFromMaintenanceWindow.go +++ /dev/null @@ -1,149 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes a target from a maintenance window. -func (c *Client) DeregisterTargetFromMaintenanceWindow(ctx context.Context, params *DeregisterTargetFromMaintenanceWindowInput, optFns ...func(*Options)) (*DeregisterTargetFromMaintenanceWindowOutput, error) { - if params == nil { - params = &DeregisterTargetFromMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeregisterTargetFromMaintenanceWindow", params, optFns, c.addOperationDeregisterTargetFromMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeregisterTargetFromMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeregisterTargetFromMaintenanceWindowInput struct { - - // The ID of the maintenance window the target should be removed from. - // - // This member is required. - WindowId *string - - // The ID of the target definition to remove. - // - // This member is required. - WindowTargetId *string - - // The system checks if the target is being referenced by a task. If the target is - // being referenced, the system returns an error and doesn't deregister the target - // from the maintenance window. - Safe *bool - - noSmithyDocumentSerde -} - -type DeregisterTargetFromMaintenanceWindowOutput struct { - - // The ID of the maintenance window the target was removed from. - WindowId *string - - // The ID of the removed target definition. - WindowTargetId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeregisterTargetFromMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeregisterTargetFromMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeregisterTargetFromMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeregisterTargetFromMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeregisterTargetFromMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeregisterTargetFromMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeregisterTargetFromMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeregisterTargetFromMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTaskFromMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTaskFromMaintenanceWindow.go deleted file mode 100644 index 8aa5233..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DeregisterTaskFromMaintenanceWindow.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes a task from a maintenance window. -func (c *Client) DeregisterTaskFromMaintenanceWindow(ctx context.Context, params *DeregisterTaskFromMaintenanceWindowInput, optFns ...func(*Options)) (*DeregisterTaskFromMaintenanceWindowOutput, error) { - if params == nil { - params = &DeregisterTaskFromMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DeregisterTaskFromMaintenanceWindow", params, optFns, c.addOperationDeregisterTaskFromMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DeregisterTaskFromMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DeregisterTaskFromMaintenanceWindowInput struct { - - // The ID of the maintenance window the task should be removed from. - // - // This member is required. - WindowId *string - - // The ID of the task to remove from the maintenance window. - // - // This member is required. - WindowTaskId *string - - noSmithyDocumentSerde -} - -type DeregisterTaskFromMaintenanceWindowOutput struct { - - // The ID of the maintenance window the task was removed from. - WindowId *string - - // The ID of the task removed from the maintenance window. - WindowTaskId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDeregisterTaskFromMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeregisterTaskFromMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDeregisterTaskFromMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DeregisterTaskFromMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDeregisterTaskFromMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeregisterTaskFromMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDeregisterTaskFromMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DeregisterTaskFromMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeActivations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeActivations.go deleted file mode 100644 index f844c5f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeActivations.go +++ /dev/null @@ -1,238 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Describes details about the activation, such as the date and time the -// activation was created, its expiration date, the Identity and Access Management -// (IAM) role assigned to the managed nodes in the activation, and the number of -// nodes registered by using this activation. -func (c *Client) DescribeActivations(ctx context.Context, params *DescribeActivationsInput, optFns ...func(*Options)) (*DescribeActivationsOutput, error) { - if params == nil { - params = &DescribeActivationsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeActivations", params, optFns, c.addOperationDescribeActivationsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeActivationsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeActivationsInput struct { - - // A filter to view information about your activations. - Filters []types.DescribeActivationsFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeActivationsOutput struct { - - // A list of activations for your Amazon Web Services account. - ActivationList []types.Activation - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeActivationsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeActivations{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeActivations{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeActivations"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeActivations(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeActivationsAPIClient is a client that implements the -// DescribeActivations operation. -type DescribeActivationsAPIClient interface { - DescribeActivations(context.Context, *DescribeActivationsInput, ...func(*Options)) (*DescribeActivationsOutput, error) -} - -var _ DescribeActivationsAPIClient = (*Client)(nil) - -// DescribeActivationsPaginatorOptions is the paginator options for -// DescribeActivations -type DescribeActivationsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeActivationsPaginator is a paginator for DescribeActivations -type DescribeActivationsPaginator struct { - options DescribeActivationsPaginatorOptions - client DescribeActivationsAPIClient - params *DescribeActivationsInput - nextToken *string - firstPage bool -} - -// NewDescribeActivationsPaginator returns a new DescribeActivationsPaginator -func NewDescribeActivationsPaginator(client DescribeActivationsAPIClient, params *DescribeActivationsInput, optFns ...func(*DescribeActivationsPaginatorOptions)) *DescribeActivationsPaginator { - if params == nil { - params = &DescribeActivationsInput{} - } - - options := DescribeActivationsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeActivationsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeActivationsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeActivations page. -func (p *DescribeActivationsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeActivationsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeActivations(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeActivations(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeActivations", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociation.go deleted file mode 100644 index 16a63ed..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociation.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Describes the association for the specified target or managed node. If you -// created the association by using the Targets parameter, then you must retrieve -// the association by using the association ID. -func (c *Client) DescribeAssociation(ctx context.Context, params *DescribeAssociationInput, optFns ...func(*Options)) (*DescribeAssociationOutput, error) { - if params == nil { - params = &DescribeAssociationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAssociation", params, optFns, c.addOperationDescribeAssociationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAssociationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAssociationInput struct { - - // The association ID for which you want information. - AssociationId *string - - // Specify the association version to retrieve. To view the latest version, either - // specify $LATEST for this parameter, or omit this parameter. To view a list of - // all associations for a managed node, use ListAssociations . To get a list of - // versions for a specific association, use ListAssociationVersions . - AssociationVersion *string - - // The managed node ID. - InstanceId *string - - // The name of the SSM document. - Name *string - - noSmithyDocumentSerde -} - -type DescribeAssociationOutput struct { - - // Information about the association. - AssociationDescription *types.AssociationDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAssociation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAssociation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAssociation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAssociation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDescribeAssociation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAssociation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutionTargets.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutionTargets.go deleted file mode 100644 index 620edf4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutionTargets.go +++ /dev/null @@ -1,252 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Views information about a specific execution of a specific association. -func (c *Client) DescribeAssociationExecutionTargets(ctx context.Context, params *DescribeAssociationExecutionTargetsInput, optFns ...func(*Options)) (*DescribeAssociationExecutionTargetsOutput, error) { - if params == nil { - params = &DescribeAssociationExecutionTargetsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAssociationExecutionTargets", params, optFns, c.addOperationDescribeAssociationExecutionTargetsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAssociationExecutionTargetsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAssociationExecutionTargetsInput struct { - - // The association ID that includes the execution for which you want to view - // details. - // - // This member is required. - AssociationId *string - - // The execution ID for which you want to view details. - // - // This member is required. - ExecutionId *string - - // Filters for the request. You can specify the following filters and values. - // Status (EQUAL) ResourceId (EQUAL) ResourceType (EQUAL) - Filters []types.AssociationExecutionTargetsFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeAssociationExecutionTargetsOutput struct { - - // Information about the execution. - AssociationExecutionTargets []types.AssociationExecutionTarget - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAssociationExecutionTargetsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAssociationExecutionTargets{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAssociationExecutionTargets{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAssociationExecutionTargets"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeAssociationExecutionTargetsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAssociationExecutionTargets(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeAssociationExecutionTargetsAPIClient is a client that implements the -// DescribeAssociationExecutionTargets operation. -type DescribeAssociationExecutionTargetsAPIClient interface { - DescribeAssociationExecutionTargets(context.Context, *DescribeAssociationExecutionTargetsInput, ...func(*Options)) (*DescribeAssociationExecutionTargetsOutput, error) -} - -var _ DescribeAssociationExecutionTargetsAPIClient = (*Client)(nil) - -// DescribeAssociationExecutionTargetsPaginatorOptions is the paginator options -// for DescribeAssociationExecutionTargets -type DescribeAssociationExecutionTargetsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeAssociationExecutionTargetsPaginator is a paginator for -// DescribeAssociationExecutionTargets -type DescribeAssociationExecutionTargetsPaginator struct { - options DescribeAssociationExecutionTargetsPaginatorOptions - client DescribeAssociationExecutionTargetsAPIClient - params *DescribeAssociationExecutionTargetsInput - nextToken *string - firstPage bool -} - -// NewDescribeAssociationExecutionTargetsPaginator returns a new -// DescribeAssociationExecutionTargetsPaginator -func NewDescribeAssociationExecutionTargetsPaginator(client DescribeAssociationExecutionTargetsAPIClient, params *DescribeAssociationExecutionTargetsInput, optFns ...func(*DescribeAssociationExecutionTargetsPaginatorOptions)) *DescribeAssociationExecutionTargetsPaginator { - if params == nil { - params = &DescribeAssociationExecutionTargetsInput{} - } - - options := DescribeAssociationExecutionTargetsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeAssociationExecutionTargetsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeAssociationExecutionTargetsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeAssociationExecutionTargets page. -func (p *DescribeAssociationExecutionTargetsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAssociationExecutionTargetsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeAssociationExecutionTargets(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeAssociationExecutionTargets(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAssociationExecutionTargets", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutions.go deleted file mode 100644 index 9cf86d1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAssociationExecutions.go +++ /dev/null @@ -1,246 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Views all executions for a specific association ID. -func (c *Client) DescribeAssociationExecutions(ctx context.Context, params *DescribeAssociationExecutionsInput, optFns ...func(*Options)) (*DescribeAssociationExecutionsOutput, error) { - if params == nil { - params = &DescribeAssociationExecutionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAssociationExecutions", params, optFns, c.addOperationDescribeAssociationExecutionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAssociationExecutionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAssociationExecutionsInput struct { - - // The association ID for which you want to view execution history details. - // - // This member is required. - AssociationId *string - - // Filters for the request. You can specify the following filters and values. - // ExecutionId (EQUAL) Status (EQUAL) CreatedTime (EQUAL, GREATER_THAN, LESS_THAN) - Filters []types.AssociationExecutionFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeAssociationExecutionsOutput struct { - - // A list of the executions for the specified association ID. - AssociationExecutions []types.AssociationExecution - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAssociationExecutionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAssociationExecutions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAssociationExecutions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAssociationExecutions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeAssociationExecutionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAssociationExecutions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeAssociationExecutionsAPIClient is a client that implements the -// DescribeAssociationExecutions operation. -type DescribeAssociationExecutionsAPIClient interface { - DescribeAssociationExecutions(context.Context, *DescribeAssociationExecutionsInput, ...func(*Options)) (*DescribeAssociationExecutionsOutput, error) -} - -var _ DescribeAssociationExecutionsAPIClient = (*Client)(nil) - -// DescribeAssociationExecutionsPaginatorOptions is the paginator options for -// DescribeAssociationExecutions -type DescribeAssociationExecutionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeAssociationExecutionsPaginator is a paginator for -// DescribeAssociationExecutions -type DescribeAssociationExecutionsPaginator struct { - options DescribeAssociationExecutionsPaginatorOptions - client DescribeAssociationExecutionsAPIClient - params *DescribeAssociationExecutionsInput - nextToken *string - firstPage bool -} - -// NewDescribeAssociationExecutionsPaginator returns a new -// DescribeAssociationExecutionsPaginator -func NewDescribeAssociationExecutionsPaginator(client DescribeAssociationExecutionsAPIClient, params *DescribeAssociationExecutionsInput, optFns ...func(*DescribeAssociationExecutionsPaginatorOptions)) *DescribeAssociationExecutionsPaginator { - if params == nil { - params = &DescribeAssociationExecutionsInput{} - } - - options := DescribeAssociationExecutionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeAssociationExecutionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeAssociationExecutionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeAssociationExecutions page. -func (p *DescribeAssociationExecutionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAssociationExecutionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeAssociationExecutions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeAssociationExecutions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAssociationExecutions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationExecutions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationExecutions.go deleted file mode 100644 index c40bc79..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationExecutions.go +++ /dev/null @@ -1,242 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Provides details about all active and terminated Automation executions. -func (c *Client) DescribeAutomationExecutions(ctx context.Context, params *DescribeAutomationExecutionsInput, optFns ...func(*Options)) (*DescribeAutomationExecutionsOutput, error) { - if params == nil { - params = &DescribeAutomationExecutionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAutomationExecutions", params, optFns, c.addOperationDescribeAutomationExecutionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAutomationExecutionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAutomationExecutionsInput struct { - - // Filters used to limit the scope of executions that are requested. - Filters []types.AutomationExecutionFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeAutomationExecutionsOutput struct { - - // The list of details about each automation execution which has occurred which - // matches the filter specification, if any. - AutomationExecutionMetadataList []types.AutomationExecutionMetadata - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAutomationExecutionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAutomationExecutions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAutomationExecutions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAutomationExecutions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeAutomationExecutionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAutomationExecutions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeAutomationExecutionsAPIClient is a client that implements the -// DescribeAutomationExecutions operation. -type DescribeAutomationExecutionsAPIClient interface { - DescribeAutomationExecutions(context.Context, *DescribeAutomationExecutionsInput, ...func(*Options)) (*DescribeAutomationExecutionsOutput, error) -} - -var _ DescribeAutomationExecutionsAPIClient = (*Client)(nil) - -// DescribeAutomationExecutionsPaginatorOptions is the paginator options for -// DescribeAutomationExecutions -type DescribeAutomationExecutionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeAutomationExecutionsPaginator is a paginator for -// DescribeAutomationExecutions -type DescribeAutomationExecutionsPaginator struct { - options DescribeAutomationExecutionsPaginatorOptions - client DescribeAutomationExecutionsAPIClient - params *DescribeAutomationExecutionsInput - nextToken *string - firstPage bool -} - -// NewDescribeAutomationExecutionsPaginator returns a new -// DescribeAutomationExecutionsPaginator -func NewDescribeAutomationExecutionsPaginator(client DescribeAutomationExecutionsAPIClient, params *DescribeAutomationExecutionsInput, optFns ...func(*DescribeAutomationExecutionsPaginatorOptions)) *DescribeAutomationExecutionsPaginator { - if params == nil { - params = &DescribeAutomationExecutionsInput{} - } - - options := DescribeAutomationExecutionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeAutomationExecutionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeAutomationExecutionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeAutomationExecutions page. -func (p *DescribeAutomationExecutionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAutomationExecutionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeAutomationExecutions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeAutomationExecutions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAutomationExecutions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationStepExecutions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationStepExecutions.go deleted file mode 100644 index dac3401..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAutomationStepExecutions.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Information about all active and terminated step executions in an Automation -// workflow. -func (c *Client) DescribeAutomationStepExecutions(ctx context.Context, params *DescribeAutomationStepExecutionsInput, optFns ...func(*Options)) (*DescribeAutomationStepExecutionsOutput, error) { - if params == nil { - params = &DescribeAutomationStepExecutionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAutomationStepExecutions", params, optFns, c.addOperationDescribeAutomationStepExecutionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAutomationStepExecutionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAutomationStepExecutionsInput struct { - - // The Automation execution ID for which you want step execution descriptions. - // - // This member is required. - AutomationExecutionId *string - - // One or more filters to limit the number of step executions returned by the - // request. - Filters []types.StepExecutionFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // Indicates whether to list step executions in reverse order by start time. The - // default value is 'false'. - ReverseOrder *bool - - noSmithyDocumentSerde -} - -type DescribeAutomationStepExecutionsOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // A list of details about the current state of all steps that make up an - // execution. - StepExecutions []types.StepExecution - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAutomationStepExecutionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAutomationStepExecutions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAutomationStepExecutions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAutomationStepExecutions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeAutomationStepExecutionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAutomationStepExecutions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeAutomationStepExecutionsAPIClient is a client that implements the -// DescribeAutomationStepExecutions operation. -type DescribeAutomationStepExecutionsAPIClient interface { - DescribeAutomationStepExecutions(context.Context, *DescribeAutomationStepExecutionsInput, ...func(*Options)) (*DescribeAutomationStepExecutionsOutput, error) -} - -var _ DescribeAutomationStepExecutionsAPIClient = (*Client)(nil) - -// DescribeAutomationStepExecutionsPaginatorOptions is the paginator options for -// DescribeAutomationStepExecutions -type DescribeAutomationStepExecutionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeAutomationStepExecutionsPaginator is a paginator for -// DescribeAutomationStepExecutions -type DescribeAutomationStepExecutionsPaginator struct { - options DescribeAutomationStepExecutionsPaginatorOptions - client DescribeAutomationStepExecutionsAPIClient - params *DescribeAutomationStepExecutionsInput - nextToken *string - firstPage bool -} - -// NewDescribeAutomationStepExecutionsPaginator returns a new -// DescribeAutomationStepExecutionsPaginator -func NewDescribeAutomationStepExecutionsPaginator(client DescribeAutomationStepExecutionsAPIClient, params *DescribeAutomationStepExecutionsInput, optFns ...func(*DescribeAutomationStepExecutionsPaginatorOptions)) *DescribeAutomationStepExecutionsPaginator { - if params == nil { - params = &DescribeAutomationStepExecutionsInput{} - } - - options := DescribeAutomationStepExecutionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeAutomationStepExecutionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeAutomationStepExecutionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeAutomationStepExecutions page. -func (p *DescribeAutomationStepExecutionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAutomationStepExecutionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeAutomationStepExecutions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeAutomationStepExecutions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAutomationStepExecutions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAvailablePatches.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAvailablePatches.go deleted file mode 100644 index cd57e0c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeAvailablePatches.go +++ /dev/null @@ -1,263 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists all patches eligible to be included in a patch baseline. -func (c *Client) DescribeAvailablePatches(ctx context.Context, params *DescribeAvailablePatchesInput, optFns ...func(*Options)) (*DescribeAvailablePatchesOutput, error) { - if params == nil { - params = &DescribeAvailablePatchesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeAvailablePatches", params, optFns, c.addOperationDescribeAvailablePatchesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeAvailablePatchesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeAvailablePatchesInput struct { - - // Each element in the array is a structure containing a key-value pair. Windows - // Server Supported keys for Windows Server managed node patches include the - // following: - // - PATCH_SET Sample values: OS | APPLICATION - // - PRODUCT Sample values: WindowsServer2012 | Office 2010 | - // MicrosoftDefenderAntivirus - // - PRODUCT_FAMILY Sample values: Windows | Office - // - MSRC_SEVERITY Sample values: ServicePacks | Important | Moderate - // - CLASSIFICATION Sample values: ServicePacks | SecurityUpdates | - // DefinitionUpdates - // - PATCH_ID Sample values: KB123456 | KB4516046 - // Linux When specifying filters for Linux patches, you must specify a key-pair - // for PRODUCT . For example, using the Command Line Interface (CLI), the following - // command fails: aws ssm describe-available-patches --filters - // Key=CVE_ID,Values=CVE-2018-3615 However, the following command succeeds: aws - // ssm describe-available-patches --filters Key=PRODUCT,Values=AmazonLinux2018.03 - // Key=CVE_ID,Values=CVE-2018-3615 Supported keys for Linux managed node patches - // include the following: - // - PRODUCT Sample values: AmazonLinux2018.03 | AmazonLinux2.0 - // - NAME Sample values: kernel-headers | samba-python | php - // - SEVERITY Sample values: Critical | Important | Medium | Low - // - EPOCH Sample values: 0 | 1 - // - VERSION Sample values: 78.6.1 | 4.10.16 - // - RELEASE Sample values: 9.56.amzn1 | 1.amzn2 - // - ARCH Sample values: i686 | x86_64 - // - REPOSITORY Sample values: Core | Updates - // - ADVISORY_ID Sample values: ALAS-2018-1058 | ALAS2-2021-1594 - // - CVE_ID Sample values: CVE-2018-3615 | CVE-2020-1472 - // - BUGZILLA_ID Sample values: 1463241 - Filters []types.PatchOrchestratorFilter - - // The maximum number of patches to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeAvailablePatchesOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // An array of patches. Each entry in the array is a patch structure. - Patches []types.Patch - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeAvailablePatchesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeAvailablePatches{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeAvailablePatches{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeAvailablePatches"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAvailablePatches(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeAvailablePatchesAPIClient is a client that implements the -// DescribeAvailablePatches operation. -type DescribeAvailablePatchesAPIClient interface { - DescribeAvailablePatches(context.Context, *DescribeAvailablePatchesInput, ...func(*Options)) (*DescribeAvailablePatchesOutput, error) -} - -var _ DescribeAvailablePatchesAPIClient = (*Client)(nil) - -// DescribeAvailablePatchesPaginatorOptions is the paginator options for -// DescribeAvailablePatches -type DescribeAvailablePatchesPaginatorOptions struct { - // The maximum number of patches to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeAvailablePatchesPaginator is a paginator for DescribeAvailablePatches -type DescribeAvailablePatchesPaginator struct { - options DescribeAvailablePatchesPaginatorOptions - client DescribeAvailablePatchesAPIClient - params *DescribeAvailablePatchesInput - nextToken *string - firstPage bool -} - -// NewDescribeAvailablePatchesPaginator returns a new -// DescribeAvailablePatchesPaginator -func NewDescribeAvailablePatchesPaginator(client DescribeAvailablePatchesAPIClient, params *DescribeAvailablePatchesInput, optFns ...func(*DescribeAvailablePatchesPaginatorOptions)) *DescribeAvailablePatchesPaginator { - if params == nil { - params = &DescribeAvailablePatchesInput{} - } - - options := DescribeAvailablePatchesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeAvailablePatchesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeAvailablePatchesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeAvailablePatches page. -func (p *DescribeAvailablePatchesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAvailablePatchesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeAvailablePatches(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeAvailablePatches(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeAvailablePatches", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocument.go deleted file mode 100644 index e523906..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocument.go +++ /dev/null @@ -1,147 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Describes the specified Amazon Web Services Systems Manager document (SSM -// document). -func (c *Client) DescribeDocument(ctx context.Context, params *DescribeDocumentInput, optFns ...func(*Options)) (*DescribeDocumentOutput, error) { - if params == nil { - params = &DescribeDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeDocument", params, optFns, c.addOperationDescribeDocumentMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeDocumentInput struct { - - // The name of the SSM document. - // - // This member is required. - Name *string - - // The document version for which you want information. Can be a specific version - // or the default version. - DocumentVersion *string - - // An optional field specifying the version of the artifact associated with the - // document. For example, "Release 12, Update 6". This value is unique across all - // versions of a document, and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -type DescribeDocumentOutput struct { - - // Information about the SSM document. - Document *types.DocumentDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeDocumentMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeDocument{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeDocument{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeDocument"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeDocumentValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeDocument(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDescribeDocument(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeDocument", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocumentPermission.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocumentPermission.go deleted file mode 100644 index f3f11a3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeDocumentPermission.go +++ /dev/null @@ -1,162 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Describes the permissions for a Amazon Web Services Systems Manager document -// (SSM document). If you created the document, you are the owner. If a document is -// shared, it can either be shared privately (by specifying a user's Amazon Web -// Services account ID) or publicly (All). -func (c *Client) DescribeDocumentPermission(ctx context.Context, params *DescribeDocumentPermissionInput, optFns ...func(*Options)) (*DescribeDocumentPermissionOutput, error) { - if params == nil { - params = &DescribeDocumentPermissionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeDocumentPermission", params, optFns, c.addOperationDescribeDocumentPermissionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeDocumentPermissionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeDocumentPermissionInput struct { - - // The name of the document for which you are the owner. - // - // This member is required. - Name *string - - // The permission type for the document. The permission type can be Share. - // - // This member is required. - PermissionType types.DocumentPermissionType - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeDocumentPermissionOutput struct { - - // The account IDs that have permission to use this document. The ID can be either - // an Amazon Web Services account or All. - AccountIds []string - - // A list of Amazon Web Services accounts where the current document is shared and - // the version shared with each account. - AccountSharingInfoList []types.AccountSharingInfo - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeDocumentPermissionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeDocumentPermission{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeDocumentPermission{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeDocumentPermission"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeDocumentPermissionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeDocumentPermission(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDescribeDocumentPermission(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeDocumentPermission", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectiveInstanceAssociations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectiveInstanceAssociations.go deleted file mode 100644 index c84ee26..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectiveInstanceAssociations.go +++ /dev/null @@ -1,243 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// All associations for the managed node(s). -func (c *Client) DescribeEffectiveInstanceAssociations(ctx context.Context, params *DescribeEffectiveInstanceAssociationsInput, optFns ...func(*Options)) (*DescribeEffectiveInstanceAssociationsOutput, error) { - if params == nil { - params = &DescribeEffectiveInstanceAssociationsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeEffectiveInstanceAssociations", params, optFns, c.addOperationDescribeEffectiveInstanceAssociationsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeEffectiveInstanceAssociationsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeEffectiveInstanceAssociationsInput struct { - - // The managed node ID for which you want to view all associations. - // - // This member is required. - InstanceId *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeEffectiveInstanceAssociationsOutput struct { - - // The associations for the requested managed node. - Associations []types.InstanceAssociation - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeEffectiveInstanceAssociationsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeEffectiveInstanceAssociations{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeEffectiveInstanceAssociations{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeEffectiveInstanceAssociations"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeEffectiveInstanceAssociationsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeEffectiveInstanceAssociations(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeEffectiveInstanceAssociationsAPIClient is a client that implements the -// DescribeEffectiveInstanceAssociations operation. -type DescribeEffectiveInstanceAssociationsAPIClient interface { - DescribeEffectiveInstanceAssociations(context.Context, *DescribeEffectiveInstanceAssociationsInput, ...func(*Options)) (*DescribeEffectiveInstanceAssociationsOutput, error) -} - -var _ DescribeEffectiveInstanceAssociationsAPIClient = (*Client)(nil) - -// DescribeEffectiveInstanceAssociationsPaginatorOptions is the paginator options -// for DescribeEffectiveInstanceAssociations -type DescribeEffectiveInstanceAssociationsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeEffectiveInstanceAssociationsPaginator is a paginator for -// DescribeEffectiveInstanceAssociations -type DescribeEffectiveInstanceAssociationsPaginator struct { - options DescribeEffectiveInstanceAssociationsPaginatorOptions - client DescribeEffectiveInstanceAssociationsAPIClient - params *DescribeEffectiveInstanceAssociationsInput - nextToken *string - firstPage bool -} - -// NewDescribeEffectiveInstanceAssociationsPaginator returns a new -// DescribeEffectiveInstanceAssociationsPaginator -func NewDescribeEffectiveInstanceAssociationsPaginator(client DescribeEffectiveInstanceAssociationsAPIClient, params *DescribeEffectiveInstanceAssociationsInput, optFns ...func(*DescribeEffectiveInstanceAssociationsPaginatorOptions)) *DescribeEffectiveInstanceAssociationsPaginator { - if params == nil { - params = &DescribeEffectiveInstanceAssociationsInput{} - } - - options := DescribeEffectiveInstanceAssociationsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeEffectiveInstanceAssociationsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeEffectiveInstanceAssociationsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeEffectiveInstanceAssociations page. -func (p *DescribeEffectiveInstanceAssociationsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeEffectiveInstanceAssociationsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeEffectiveInstanceAssociations(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeEffectiveInstanceAssociations(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeEffectiveInstanceAssociations", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectivePatchesForPatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectivePatchesForPatchBaseline.go deleted file mode 100644 index 72dd933..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeEffectivePatchesForPatchBaseline.go +++ /dev/null @@ -1,242 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the current effective patches (the patch and the approval state) for -// the specified patch baseline. Applies to patch baselines for Windows only. -func (c *Client) DescribeEffectivePatchesForPatchBaseline(ctx context.Context, params *DescribeEffectivePatchesForPatchBaselineInput, optFns ...func(*Options)) (*DescribeEffectivePatchesForPatchBaselineOutput, error) { - if params == nil { - params = &DescribeEffectivePatchesForPatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeEffectivePatchesForPatchBaseline", params, optFns, c.addOperationDescribeEffectivePatchesForPatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeEffectivePatchesForPatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeEffectivePatchesForPatchBaselineInput struct { - - // The ID of the patch baseline to retrieve the effective patches for. - // - // This member is required. - BaselineId *string - - // The maximum number of patches to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeEffectivePatchesForPatchBaselineOutput struct { - - // An array of patches and patch status. - EffectivePatches []types.EffectivePatch - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeEffectivePatchesForPatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeEffectivePatchesForPatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeEffectivePatchesForPatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeEffectivePatchesForPatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeEffectivePatchesForPatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeEffectivePatchesForPatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeEffectivePatchesForPatchBaselineAPIClient is a client that implements -// the DescribeEffectivePatchesForPatchBaseline operation. -type DescribeEffectivePatchesForPatchBaselineAPIClient interface { - DescribeEffectivePatchesForPatchBaseline(context.Context, *DescribeEffectivePatchesForPatchBaselineInput, ...func(*Options)) (*DescribeEffectivePatchesForPatchBaselineOutput, error) -} - -var _ DescribeEffectivePatchesForPatchBaselineAPIClient = (*Client)(nil) - -// DescribeEffectivePatchesForPatchBaselinePaginatorOptions is the paginator -// options for DescribeEffectivePatchesForPatchBaseline -type DescribeEffectivePatchesForPatchBaselinePaginatorOptions struct { - // The maximum number of patches to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeEffectivePatchesForPatchBaselinePaginator is a paginator for -// DescribeEffectivePatchesForPatchBaseline -type DescribeEffectivePatchesForPatchBaselinePaginator struct { - options DescribeEffectivePatchesForPatchBaselinePaginatorOptions - client DescribeEffectivePatchesForPatchBaselineAPIClient - params *DescribeEffectivePatchesForPatchBaselineInput - nextToken *string - firstPage bool -} - -// NewDescribeEffectivePatchesForPatchBaselinePaginator returns a new -// DescribeEffectivePatchesForPatchBaselinePaginator -func NewDescribeEffectivePatchesForPatchBaselinePaginator(client DescribeEffectivePatchesForPatchBaselineAPIClient, params *DescribeEffectivePatchesForPatchBaselineInput, optFns ...func(*DescribeEffectivePatchesForPatchBaselinePaginatorOptions)) *DescribeEffectivePatchesForPatchBaselinePaginator { - if params == nil { - params = &DescribeEffectivePatchesForPatchBaselineInput{} - } - - options := DescribeEffectivePatchesForPatchBaselinePaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeEffectivePatchesForPatchBaselinePaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeEffectivePatchesForPatchBaselinePaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeEffectivePatchesForPatchBaseline page. -func (p *DescribeEffectivePatchesForPatchBaselinePaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeEffectivePatchesForPatchBaselineOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeEffectivePatchesForPatchBaseline(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeEffectivePatchesForPatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeEffectivePatchesForPatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceAssociationsStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceAssociationsStatus.go deleted file mode 100644 index 4f437bb..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceAssociationsStatus.go +++ /dev/null @@ -1,243 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// The status of the associations for the managed node(s). -func (c *Client) DescribeInstanceAssociationsStatus(ctx context.Context, params *DescribeInstanceAssociationsStatusInput, optFns ...func(*Options)) (*DescribeInstanceAssociationsStatusOutput, error) { - if params == nil { - params = &DescribeInstanceAssociationsStatusInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInstanceAssociationsStatus", params, optFns, c.addOperationDescribeInstanceAssociationsStatusMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInstanceAssociationsStatusOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInstanceAssociationsStatusInput struct { - - // The managed node IDs for which you want association status information. - // - // This member is required. - InstanceId *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInstanceAssociationsStatusOutput struct { - - // Status information about the association. - InstanceAssociationStatusInfos []types.InstanceAssociationStatusInfo - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInstanceAssociationsStatusMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInstanceAssociationsStatus{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInstanceAssociationsStatus{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInstanceAssociationsStatus"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeInstanceAssociationsStatusValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInstanceAssociationsStatus(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInstanceAssociationsStatusAPIClient is a client that implements the -// DescribeInstanceAssociationsStatus operation. -type DescribeInstanceAssociationsStatusAPIClient interface { - DescribeInstanceAssociationsStatus(context.Context, *DescribeInstanceAssociationsStatusInput, ...func(*Options)) (*DescribeInstanceAssociationsStatusOutput, error) -} - -var _ DescribeInstanceAssociationsStatusAPIClient = (*Client)(nil) - -// DescribeInstanceAssociationsStatusPaginatorOptions is the paginator options for -// DescribeInstanceAssociationsStatus -type DescribeInstanceAssociationsStatusPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInstanceAssociationsStatusPaginator is a paginator for -// DescribeInstanceAssociationsStatus -type DescribeInstanceAssociationsStatusPaginator struct { - options DescribeInstanceAssociationsStatusPaginatorOptions - client DescribeInstanceAssociationsStatusAPIClient - params *DescribeInstanceAssociationsStatusInput - nextToken *string - firstPage bool -} - -// NewDescribeInstanceAssociationsStatusPaginator returns a new -// DescribeInstanceAssociationsStatusPaginator -func NewDescribeInstanceAssociationsStatusPaginator(client DescribeInstanceAssociationsStatusAPIClient, params *DescribeInstanceAssociationsStatusInput, optFns ...func(*DescribeInstanceAssociationsStatusPaginatorOptions)) *DescribeInstanceAssociationsStatusPaginator { - if params == nil { - params = &DescribeInstanceAssociationsStatusInput{} - } - - options := DescribeInstanceAssociationsStatusPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInstanceAssociationsStatusPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInstanceAssociationsStatusPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInstanceAssociationsStatus page. -func (p *DescribeInstanceAssociationsStatusPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInstanceAssociationsStatusOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInstanceAssociationsStatus(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInstanceAssociationsStatus(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInstanceAssociationsStatus", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceInformation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceInformation.go deleted file mode 100644 index b133f5a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstanceInformation.go +++ /dev/null @@ -1,261 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Provides information about one or more of your managed nodes, including the -// operating system platform, SSM Agent version, association status, and IP -// address. This operation does not return information for nodes that are either -// Stopped or Terminated. If you specify one or more node IDs, the operation -// returns information for those managed nodes. If you don't specify node IDs, it -// returns information for all your managed nodes. If you specify a node ID that -// isn't valid or a node that you don't own, you receive an error. The IamRole -// field returned for this API operation is the Identity and Access Management -// (IAM) role assigned to on-premises managed nodes. This operation does not return -// the IAM role for EC2 instances. -func (c *Client) DescribeInstanceInformation(ctx context.Context, params *DescribeInstanceInformationInput, optFns ...func(*Options)) (*DescribeInstanceInformationOutput, error) { - if params == nil { - params = &DescribeInstanceInformationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInstanceInformation", params, optFns, c.addOperationDescribeInstanceInformationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInstanceInformationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInstanceInformationInput struct { - - // One or more filters. Use a filter to return a more specific list of managed - // nodes. You can filter based on tags applied to your managed nodes. Tag filters - // can't be combined with other filter types. Use this Filters data type instead - // of InstanceInformationFilterList , which is deprecated. - Filters []types.InstanceInformationStringFilter - - // This is a legacy method. We recommend that you don't use this method. Instead, - // use the Filters data type. Filters enables you to return node information by - // filtering based on tags applied to managed nodes. Attempting to use - // InstanceInformationFilterList and Filters leads to an exception error. - InstanceInformationFilterList []types.InstanceInformationFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - // The default value is 10 items. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInstanceInformationOutput struct { - - // The managed node information list. - InstanceInformationList []types.InstanceInformation - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInstanceInformationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInstanceInformation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInstanceInformation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInstanceInformation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeInstanceInformationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInstanceInformation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInstanceInformationAPIClient is a client that implements the -// DescribeInstanceInformation operation. -type DescribeInstanceInformationAPIClient interface { - DescribeInstanceInformation(context.Context, *DescribeInstanceInformationInput, ...func(*Options)) (*DescribeInstanceInformationOutput, error) -} - -var _ DescribeInstanceInformationAPIClient = (*Client)(nil) - -// DescribeInstanceInformationPaginatorOptions is the paginator options for -// DescribeInstanceInformation -type DescribeInstanceInformationPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - // The default value is 10 items. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInstanceInformationPaginator is a paginator for -// DescribeInstanceInformation -type DescribeInstanceInformationPaginator struct { - options DescribeInstanceInformationPaginatorOptions - client DescribeInstanceInformationAPIClient - params *DescribeInstanceInformationInput - nextToken *string - firstPage bool -} - -// NewDescribeInstanceInformationPaginator returns a new -// DescribeInstanceInformationPaginator -func NewDescribeInstanceInformationPaginator(client DescribeInstanceInformationAPIClient, params *DescribeInstanceInformationInput, optFns ...func(*DescribeInstanceInformationPaginatorOptions)) *DescribeInstanceInformationPaginator { - if params == nil { - params = &DescribeInstanceInformationInput{} - } - - options := DescribeInstanceInformationPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInstanceInformationPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInstanceInformationPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInstanceInformation page. -func (p *DescribeInstanceInformationPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInstanceInformationOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInstanceInformation(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInstanceInformation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInstanceInformation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStates.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStates.go deleted file mode 100644 index 4c5d69c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStates.go +++ /dev/null @@ -1,242 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the high-level patch state of one or more managed nodes. -func (c *Client) DescribeInstancePatchStates(ctx context.Context, params *DescribeInstancePatchStatesInput, optFns ...func(*Options)) (*DescribeInstancePatchStatesOutput, error) { - if params == nil { - params = &DescribeInstancePatchStatesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInstancePatchStates", params, optFns, c.addOperationDescribeInstancePatchStatesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInstancePatchStatesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInstancePatchStatesInput struct { - - // The ID of the managed node for which patch state information should be - // retrieved. - // - // This member is required. - InstanceIds []string - - // The maximum number of managed nodes to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInstancePatchStatesOutput struct { - - // The high-level patch state for the requested managed nodes. - InstancePatchStates []types.InstancePatchState - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInstancePatchStatesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInstancePatchStates{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInstancePatchStates{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInstancePatchStates"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeInstancePatchStatesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInstancePatchStates(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInstancePatchStatesAPIClient is a client that implements the -// DescribeInstancePatchStates operation. -type DescribeInstancePatchStatesAPIClient interface { - DescribeInstancePatchStates(context.Context, *DescribeInstancePatchStatesInput, ...func(*Options)) (*DescribeInstancePatchStatesOutput, error) -} - -var _ DescribeInstancePatchStatesAPIClient = (*Client)(nil) - -// DescribeInstancePatchStatesPaginatorOptions is the paginator options for -// DescribeInstancePatchStates -type DescribeInstancePatchStatesPaginatorOptions struct { - // The maximum number of managed nodes to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInstancePatchStatesPaginator is a paginator for -// DescribeInstancePatchStates -type DescribeInstancePatchStatesPaginator struct { - options DescribeInstancePatchStatesPaginatorOptions - client DescribeInstancePatchStatesAPIClient - params *DescribeInstancePatchStatesInput - nextToken *string - firstPage bool -} - -// NewDescribeInstancePatchStatesPaginator returns a new -// DescribeInstancePatchStatesPaginator -func NewDescribeInstancePatchStatesPaginator(client DescribeInstancePatchStatesAPIClient, params *DescribeInstancePatchStatesInput, optFns ...func(*DescribeInstancePatchStatesPaginatorOptions)) *DescribeInstancePatchStatesPaginator { - if params == nil { - params = &DescribeInstancePatchStatesInput{} - } - - options := DescribeInstancePatchStatesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInstancePatchStatesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInstancePatchStatesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInstancePatchStates page. -func (p *DescribeInstancePatchStatesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInstancePatchStatesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInstancePatchStates(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInstancePatchStates(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInstancePatchStates", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStatesForPatchGroup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStatesForPatchGroup.go deleted file mode 100644 index 48bcb33..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatchStatesForPatchGroup.go +++ /dev/null @@ -1,249 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the high-level patch state for the managed nodes in the specified -// patch group. -func (c *Client) DescribeInstancePatchStatesForPatchGroup(ctx context.Context, params *DescribeInstancePatchStatesForPatchGroupInput, optFns ...func(*Options)) (*DescribeInstancePatchStatesForPatchGroupOutput, error) { - if params == nil { - params = &DescribeInstancePatchStatesForPatchGroupInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInstancePatchStatesForPatchGroup", params, optFns, c.addOperationDescribeInstancePatchStatesForPatchGroupMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInstancePatchStatesForPatchGroupOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInstancePatchStatesForPatchGroupInput struct { - - // The name of the patch group for which the patch state information should be - // retrieved. - // - // This member is required. - PatchGroup *string - - // Each entry in the array is a structure containing: - // - Key (string between 1 and 200 characters) - // - Values (array containing a single string) - // - Type (string "Equal", "NotEqual", "LessThan", "GreaterThan") - Filters []types.InstancePatchStateFilter - - // The maximum number of patches to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInstancePatchStatesForPatchGroupOutput struct { - - // The high-level patch state for the requested managed nodes. - InstancePatchStates []types.InstancePatchState - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInstancePatchStatesForPatchGroupMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInstancePatchStatesForPatchGroup{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInstancePatchStatesForPatchGroup{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInstancePatchStatesForPatchGroup"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeInstancePatchStatesForPatchGroupValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInstancePatchStatesForPatchGroup(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInstancePatchStatesForPatchGroupAPIClient is a client that implements -// the DescribeInstancePatchStatesForPatchGroup operation. -type DescribeInstancePatchStatesForPatchGroupAPIClient interface { - DescribeInstancePatchStatesForPatchGroup(context.Context, *DescribeInstancePatchStatesForPatchGroupInput, ...func(*Options)) (*DescribeInstancePatchStatesForPatchGroupOutput, error) -} - -var _ DescribeInstancePatchStatesForPatchGroupAPIClient = (*Client)(nil) - -// DescribeInstancePatchStatesForPatchGroupPaginatorOptions is the paginator -// options for DescribeInstancePatchStatesForPatchGroup -type DescribeInstancePatchStatesForPatchGroupPaginatorOptions struct { - // The maximum number of patches to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInstancePatchStatesForPatchGroupPaginator is a paginator for -// DescribeInstancePatchStatesForPatchGroup -type DescribeInstancePatchStatesForPatchGroupPaginator struct { - options DescribeInstancePatchStatesForPatchGroupPaginatorOptions - client DescribeInstancePatchStatesForPatchGroupAPIClient - params *DescribeInstancePatchStatesForPatchGroupInput - nextToken *string - firstPage bool -} - -// NewDescribeInstancePatchStatesForPatchGroupPaginator returns a new -// DescribeInstancePatchStatesForPatchGroupPaginator -func NewDescribeInstancePatchStatesForPatchGroupPaginator(client DescribeInstancePatchStatesForPatchGroupAPIClient, params *DescribeInstancePatchStatesForPatchGroupInput, optFns ...func(*DescribeInstancePatchStatesForPatchGroupPaginatorOptions)) *DescribeInstancePatchStatesForPatchGroupPaginator { - if params == nil { - params = &DescribeInstancePatchStatesForPatchGroupInput{} - } - - options := DescribeInstancePatchStatesForPatchGroupPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInstancePatchStatesForPatchGroupPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInstancePatchStatesForPatchGroupPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInstancePatchStatesForPatchGroup page. -func (p *DescribeInstancePatchStatesForPatchGroupPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInstancePatchStatesForPatchGroupOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInstancePatchStatesForPatchGroup(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInstancePatchStatesForPatchGroup(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInstancePatchStatesForPatchGroup", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatches.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatches.go deleted file mode 100644 index 045aade..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInstancePatches.go +++ /dev/null @@ -1,258 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves information about the patches on the specified managed node and their -// state relative to the patch baseline being used for the node. -func (c *Client) DescribeInstancePatches(ctx context.Context, params *DescribeInstancePatchesInput, optFns ...func(*Options)) (*DescribeInstancePatchesOutput, error) { - if params == nil { - params = &DescribeInstancePatchesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInstancePatches", params, optFns, c.addOperationDescribeInstancePatchesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInstancePatchesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInstancePatchesInput struct { - - // The ID of the managed node whose patch state information should be retrieved. - // - // This member is required. - InstanceId *string - - // Each element in the array is a structure containing a key-value pair. Supported - // keys for DescribeInstancePatches include the following: - // - Classification Sample values: Security | SecurityUpdates - // - KBId Sample values: KB4480056 | java-1.7.0-openjdk.x86_64 - // - Severity Sample values: Important | Medium | Low - // - State Sample values: Installed | InstalledOther | InstalledPendingReboot For - // lists of all State values, see Understanding patch compliance state values (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-compliance-states.html) - // in the Amazon Web Services Systems Manager User Guide. - Filters []types.PatchOrchestratorFilter - - // The maximum number of patches to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInstancePatchesOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Each entry in the array is a structure containing: - // - Title (string) - // - KBId (string) - // - Classification (string) - // - Severity (string) - // - State (string, such as "INSTALLED" or "FAILED") - // - InstalledTime (DateTime) - // - InstalledBy (string) - Patches []types.PatchComplianceData - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInstancePatchesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInstancePatches{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInstancePatches{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInstancePatches"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeInstancePatchesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInstancePatches(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInstancePatchesAPIClient is a client that implements the -// DescribeInstancePatches operation. -type DescribeInstancePatchesAPIClient interface { - DescribeInstancePatches(context.Context, *DescribeInstancePatchesInput, ...func(*Options)) (*DescribeInstancePatchesOutput, error) -} - -var _ DescribeInstancePatchesAPIClient = (*Client)(nil) - -// DescribeInstancePatchesPaginatorOptions is the paginator options for -// DescribeInstancePatches -type DescribeInstancePatchesPaginatorOptions struct { - // The maximum number of patches to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInstancePatchesPaginator is a paginator for DescribeInstancePatches -type DescribeInstancePatchesPaginator struct { - options DescribeInstancePatchesPaginatorOptions - client DescribeInstancePatchesAPIClient - params *DescribeInstancePatchesInput - nextToken *string - firstPage bool -} - -// NewDescribeInstancePatchesPaginator returns a new -// DescribeInstancePatchesPaginator -func NewDescribeInstancePatchesPaginator(client DescribeInstancePatchesAPIClient, params *DescribeInstancePatchesInput, optFns ...func(*DescribeInstancePatchesPaginatorOptions)) *DescribeInstancePatchesPaginator { - if params == nil { - params = &DescribeInstancePatchesInput{} - } - - options := DescribeInstancePatchesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInstancePatchesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInstancePatchesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInstancePatches page. -func (p *DescribeInstancePatchesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInstancePatchesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInstancePatches(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInstancePatches(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInstancePatches", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInventoryDeletions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInventoryDeletions.go deleted file mode 100644 index 06982c2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeInventoryDeletions.go +++ /dev/null @@ -1,238 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Describes a specific delete inventory operation. -func (c *Client) DescribeInventoryDeletions(ctx context.Context, params *DescribeInventoryDeletionsInput, optFns ...func(*Options)) (*DescribeInventoryDeletionsOutput, error) { - if params == nil { - params = &DescribeInventoryDeletionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeInventoryDeletions", params, optFns, c.addOperationDescribeInventoryDeletionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeInventoryDeletionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeInventoryDeletionsInput struct { - - // Specify the delete inventory ID for which you want information. This ID was - // returned by the DeleteInventory operation. - DeletionId *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeInventoryDeletionsOutput struct { - - // A list of status items for deleted inventory. - InventoryDeletions []types.InventoryDeletionStatusItem - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeInventoryDeletionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeInventoryDeletions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeInventoryDeletions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeInventoryDeletions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeInventoryDeletions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeInventoryDeletionsAPIClient is a client that implements the -// DescribeInventoryDeletions operation. -type DescribeInventoryDeletionsAPIClient interface { - DescribeInventoryDeletions(context.Context, *DescribeInventoryDeletionsInput, ...func(*Options)) (*DescribeInventoryDeletionsOutput, error) -} - -var _ DescribeInventoryDeletionsAPIClient = (*Client)(nil) - -// DescribeInventoryDeletionsPaginatorOptions is the paginator options for -// DescribeInventoryDeletions -type DescribeInventoryDeletionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeInventoryDeletionsPaginator is a paginator for -// DescribeInventoryDeletions -type DescribeInventoryDeletionsPaginator struct { - options DescribeInventoryDeletionsPaginatorOptions - client DescribeInventoryDeletionsAPIClient - params *DescribeInventoryDeletionsInput - nextToken *string - firstPage bool -} - -// NewDescribeInventoryDeletionsPaginator returns a new -// DescribeInventoryDeletionsPaginator -func NewDescribeInventoryDeletionsPaginator(client DescribeInventoryDeletionsAPIClient, params *DescribeInventoryDeletionsInput, optFns ...func(*DescribeInventoryDeletionsPaginatorOptions)) *DescribeInventoryDeletionsPaginator { - if params == nil { - params = &DescribeInventoryDeletionsInput{} - } - - options := DescribeInventoryDeletionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeInventoryDeletionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeInventoryDeletionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeInventoryDeletions page. -func (p *DescribeInventoryDeletionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeInventoryDeletionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeInventoryDeletions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeInventoryDeletions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeInventoryDeletions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTaskInvocations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTaskInvocations.go deleted file mode 100644 index 7adfd3c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTaskInvocations.go +++ /dev/null @@ -1,256 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the individual task executions (one per target) for a particular task -// run as part of a maintenance window execution. -func (c *Client) DescribeMaintenanceWindowExecutionTaskInvocations(ctx context.Context, params *DescribeMaintenanceWindowExecutionTaskInvocationsInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionTaskInvocationsOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowExecutionTaskInvocationsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowExecutionTaskInvocations", params, optFns, c.addOperationDescribeMaintenanceWindowExecutionTaskInvocationsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowExecutionTaskInvocationsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowExecutionTaskInvocationsInput struct { - - // The ID of the specific task in the maintenance window task that should be - // retrieved. - // - // This member is required. - TaskId *string - - // The ID of the maintenance window execution the task is part of. - // - // This member is required. - WindowExecutionId *string - - // Optional filters used to scope down the returned task invocations. The - // supported filter key is STATUS with the corresponding values PENDING , - // IN_PROGRESS , SUCCESS , FAILED , TIMED_OUT , CANCELLING , and CANCELLED . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowExecutionTaskInvocationsOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the task invocation results per invocation. - WindowExecutionTaskInvocationIdentities []types.MaintenanceWindowExecutionTaskInvocationIdentity - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowExecutionTaskInvocationsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTaskInvocations{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTaskInvocations{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowExecutionTaskInvocations"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowExecutionTaskInvocationsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutionTaskInvocations(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowExecutionTaskInvocationsAPIClient is a client that -// implements the DescribeMaintenanceWindowExecutionTaskInvocations operation. -type DescribeMaintenanceWindowExecutionTaskInvocationsAPIClient interface { - DescribeMaintenanceWindowExecutionTaskInvocations(context.Context, *DescribeMaintenanceWindowExecutionTaskInvocationsInput, ...func(*Options)) (*DescribeMaintenanceWindowExecutionTaskInvocationsOutput, error) -} - -var _ DescribeMaintenanceWindowExecutionTaskInvocationsAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowExecutionTaskInvocationsPaginatorOptions is the -// paginator options for DescribeMaintenanceWindowExecutionTaskInvocations -type DescribeMaintenanceWindowExecutionTaskInvocationsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowExecutionTaskInvocationsPaginator is a paginator for -// DescribeMaintenanceWindowExecutionTaskInvocations -type DescribeMaintenanceWindowExecutionTaskInvocationsPaginator struct { - options DescribeMaintenanceWindowExecutionTaskInvocationsPaginatorOptions - client DescribeMaintenanceWindowExecutionTaskInvocationsAPIClient - params *DescribeMaintenanceWindowExecutionTaskInvocationsInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowExecutionTaskInvocationsPaginator returns a new -// DescribeMaintenanceWindowExecutionTaskInvocationsPaginator -func NewDescribeMaintenanceWindowExecutionTaskInvocationsPaginator(client DescribeMaintenanceWindowExecutionTaskInvocationsAPIClient, params *DescribeMaintenanceWindowExecutionTaskInvocationsInput, optFns ...func(*DescribeMaintenanceWindowExecutionTaskInvocationsPaginatorOptions)) *DescribeMaintenanceWindowExecutionTaskInvocationsPaginator { - if params == nil { - params = &DescribeMaintenanceWindowExecutionTaskInvocationsInput{} - } - - options := DescribeMaintenanceWindowExecutionTaskInvocationsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowExecutionTaskInvocationsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowExecutionTaskInvocationsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowExecutionTaskInvocations -// page. -func (p *DescribeMaintenanceWindowExecutionTaskInvocationsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionTaskInvocationsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowExecutionTaskInvocations(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutionTaskInvocations(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowExecutionTaskInvocations", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTasks.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTasks.go deleted file mode 100644 index b3983b3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutionTasks.go +++ /dev/null @@ -1,249 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// For a given maintenance window execution, lists the tasks that were run. -func (c *Client) DescribeMaintenanceWindowExecutionTasks(ctx context.Context, params *DescribeMaintenanceWindowExecutionTasksInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionTasksOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowExecutionTasksInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowExecutionTasks", params, optFns, c.addOperationDescribeMaintenanceWindowExecutionTasksMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowExecutionTasksOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowExecutionTasksInput struct { - - // The ID of the maintenance window execution whose task executions should be - // retrieved. - // - // This member is required. - WindowExecutionId *string - - // Optional filters used to scope down the returned tasks. The supported filter - // key is STATUS with the corresponding values PENDING , IN_PROGRESS , SUCCESS , - // FAILED , TIMED_OUT , CANCELLING , and CANCELLED . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowExecutionTasksOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the task executions. - WindowExecutionTaskIdentities []types.MaintenanceWindowExecutionTaskIdentity - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowExecutionTasksMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTasks{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTasks{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowExecutionTasks"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowExecutionTasksValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutionTasks(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowExecutionTasksAPIClient is a client that implements -// the DescribeMaintenanceWindowExecutionTasks operation. -type DescribeMaintenanceWindowExecutionTasksAPIClient interface { - DescribeMaintenanceWindowExecutionTasks(context.Context, *DescribeMaintenanceWindowExecutionTasksInput, ...func(*Options)) (*DescribeMaintenanceWindowExecutionTasksOutput, error) -} - -var _ DescribeMaintenanceWindowExecutionTasksAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowExecutionTasksPaginatorOptions is the paginator -// options for DescribeMaintenanceWindowExecutionTasks -type DescribeMaintenanceWindowExecutionTasksPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowExecutionTasksPaginator is a paginator for -// DescribeMaintenanceWindowExecutionTasks -type DescribeMaintenanceWindowExecutionTasksPaginator struct { - options DescribeMaintenanceWindowExecutionTasksPaginatorOptions - client DescribeMaintenanceWindowExecutionTasksAPIClient - params *DescribeMaintenanceWindowExecutionTasksInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowExecutionTasksPaginator returns a new -// DescribeMaintenanceWindowExecutionTasksPaginator -func NewDescribeMaintenanceWindowExecutionTasksPaginator(client DescribeMaintenanceWindowExecutionTasksAPIClient, params *DescribeMaintenanceWindowExecutionTasksInput, optFns ...func(*DescribeMaintenanceWindowExecutionTasksPaginatorOptions)) *DescribeMaintenanceWindowExecutionTasksPaginator { - if params == nil { - params = &DescribeMaintenanceWindowExecutionTasksInput{} - } - - options := DescribeMaintenanceWindowExecutionTasksPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowExecutionTasksPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowExecutionTasksPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowExecutionTasks page. -func (p *DescribeMaintenanceWindowExecutionTasksPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionTasksOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowExecutionTasks(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutionTasks(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowExecutionTasks", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutions.go deleted file mode 100644 index d3da2f1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowExecutions.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the executions of a maintenance window. This includes information about -// when the maintenance window was scheduled to be active, and information about -// tasks registered and run with the maintenance window. -func (c *Client) DescribeMaintenanceWindowExecutions(ctx context.Context, params *DescribeMaintenanceWindowExecutionsInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionsOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowExecutionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowExecutions", params, optFns, c.addOperationDescribeMaintenanceWindowExecutionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowExecutionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowExecutionsInput struct { - - // The ID of the maintenance window whose executions should be retrieved. - // - // This member is required. - WindowId *string - - // Each entry in the array is a structure containing: - // - Key. A string between 1 and 128 characters. Supported keys include - // ExecutedBefore and ExecutedAfter . - // - Values. An array of strings, each between 1 and 256 characters. Supported - // values are date/time strings in a valid ISO 8601 date/time format, such as - // 2021-11-04T05:00:00Z . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowExecutionsOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the maintenance window executions. - WindowExecutions []types.MaintenanceWindowExecution - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowExecutionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowExecutions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowExecutionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowExecutionsAPIClient is a client that implements the -// DescribeMaintenanceWindowExecutions operation. -type DescribeMaintenanceWindowExecutionsAPIClient interface { - DescribeMaintenanceWindowExecutions(context.Context, *DescribeMaintenanceWindowExecutionsInput, ...func(*Options)) (*DescribeMaintenanceWindowExecutionsOutput, error) -} - -var _ DescribeMaintenanceWindowExecutionsAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowExecutionsPaginatorOptions is the paginator options -// for DescribeMaintenanceWindowExecutions -type DescribeMaintenanceWindowExecutionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowExecutionsPaginator is a paginator for -// DescribeMaintenanceWindowExecutions -type DescribeMaintenanceWindowExecutionsPaginator struct { - options DescribeMaintenanceWindowExecutionsPaginatorOptions - client DescribeMaintenanceWindowExecutionsAPIClient - params *DescribeMaintenanceWindowExecutionsInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowExecutionsPaginator returns a new -// DescribeMaintenanceWindowExecutionsPaginator -func NewDescribeMaintenanceWindowExecutionsPaginator(client DescribeMaintenanceWindowExecutionsAPIClient, params *DescribeMaintenanceWindowExecutionsInput, optFns ...func(*DescribeMaintenanceWindowExecutionsPaginatorOptions)) *DescribeMaintenanceWindowExecutionsPaginator { - if params == nil { - params = &DescribeMaintenanceWindowExecutionsInput{} - } - - options := DescribeMaintenanceWindowExecutionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowExecutionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowExecutionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowExecutions page. -func (p *DescribeMaintenanceWindowExecutionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowExecutionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowExecutions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowExecutions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowExecutions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowSchedule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowSchedule.go deleted file mode 100644 index 942a9c2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowSchedule.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves information about upcoming executions of a maintenance window. -func (c *Client) DescribeMaintenanceWindowSchedule(ctx context.Context, params *DescribeMaintenanceWindowScheduleInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowScheduleOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowScheduleInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowSchedule", params, optFns, c.addOperationDescribeMaintenanceWindowScheduleMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowScheduleOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowScheduleInput struct { - - // Filters used to limit the range of results. For example, you can limit - // maintenance window executions to only those scheduled before or after a certain - // date and time. - Filters []types.PatchOrchestratorFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // The type of resource you want to retrieve information about. For example, - // INSTANCE . - ResourceType types.MaintenanceWindowResourceType - - // The managed node ID or key-value pair to retrieve information about. - Targets []types.Target - - // The ID of the maintenance window to retrieve information about. - WindowId *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowScheduleOutput struct { - - // The token for the next set of items to return. (You use this token in the next - // call.) - NextToken *string - - // Information about maintenance window executions scheduled for the specified - // time range. - ScheduledWindowExecutions []types.ScheduledWindowExecution - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowScheduleMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowSchedule{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowSchedule{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowSchedule"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowSchedule(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowScheduleAPIClient is a client that implements the -// DescribeMaintenanceWindowSchedule operation. -type DescribeMaintenanceWindowScheduleAPIClient interface { - DescribeMaintenanceWindowSchedule(context.Context, *DescribeMaintenanceWindowScheduleInput, ...func(*Options)) (*DescribeMaintenanceWindowScheduleOutput, error) -} - -var _ DescribeMaintenanceWindowScheduleAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowSchedulePaginatorOptions is the paginator options for -// DescribeMaintenanceWindowSchedule -type DescribeMaintenanceWindowSchedulePaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowSchedulePaginator is a paginator for -// DescribeMaintenanceWindowSchedule -type DescribeMaintenanceWindowSchedulePaginator struct { - options DescribeMaintenanceWindowSchedulePaginatorOptions - client DescribeMaintenanceWindowScheduleAPIClient - params *DescribeMaintenanceWindowScheduleInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowSchedulePaginator returns a new -// DescribeMaintenanceWindowSchedulePaginator -func NewDescribeMaintenanceWindowSchedulePaginator(client DescribeMaintenanceWindowScheduleAPIClient, params *DescribeMaintenanceWindowScheduleInput, optFns ...func(*DescribeMaintenanceWindowSchedulePaginatorOptions)) *DescribeMaintenanceWindowSchedulePaginator { - if params == nil { - params = &DescribeMaintenanceWindowScheduleInput{} - } - - options := DescribeMaintenanceWindowSchedulePaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowSchedulePaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowSchedulePaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowSchedule page. -func (p *DescribeMaintenanceWindowSchedulePaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowScheduleOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowSchedule(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowSchedule(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowSchedule", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTargets.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTargets.go deleted file mode 100644 index 922c370..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTargets.go +++ /dev/null @@ -1,248 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the targets registered with the maintenance window. -func (c *Client) DescribeMaintenanceWindowTargets(ctx context.Context, params *DescribeMaintenanceWindowTargetsInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowTargetsOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowTargetsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowTargets", params, optFns, c.addOperationDescribeMaintenanceWindowTargetsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowTargetsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowTargetsInput struct { - - // The ID of the maintenance window whose targets should be retrieved. - // - // This member is required. - WindowId *string - - // Optional filters that can be used to narrow down the scope of the returned - // window targets. The supported filter keys are Type , WindowTargetId , and - // OwnerInformation . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowTargetsOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the targets in the maintenance window. - Targets []types.MaintenanceWindowTarget - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowTargetsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowTargets{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowTargets{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowTargets"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowTargetsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowTargets(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowTargetsAPIClient is a client that implements the -// DescribeMaintenanceWindowTargets operation. -type DescribeMaintenanceWindowTargetsAPIClient interface { - DescribeMaintenanceWindowTargets(context.Context, *DescribeMaintenanceWindowTargetsInput, ...func(*Options)) (*DescribeMaintenanceWindowTargetsOutput, error) -} - -var _ DescribeMaintenanceWindowTargetsAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowTargetsPaginatorOptions is the paginator options for -// DescribeMaintenanceWindowTargets -type DescribeMaintenanceWindowTargetsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowTargetsPaginator is a paginator for -// DescribeMaintenanceWindowTargets -type DescribeMaintenanceWindowTargetsPaginator struct { - options DescribeMaintenanceWindowTargetsPaginatorOptions - client DescribeMaintenanceWindowTargetsAPIClient - params *DescribeMaintenanceWindowTargetsInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowTargetsPaginator returns a new -// DescribeMaintenanceWindowTargetsPaginator -func NewDescribeMaintenanceWindowTargetsPaginator(client DescribeMaintenanceWindowTargetsAPIClient, params *DescribeMaintenanceWindowTargetsInput, optFns ...func(*DescribeMaintenanceWindowTargetsPaginatorOptions)) *DescribeMaintenanceWindowTargetsPaginator { - if params == nil { - params = &DescribeMaintenanceWindowTargetsInput{} - } - - options := DescribeMaintenanceWindowTargetsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowTargetsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowTargetsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowTargets page. -func (p *DescribeMaintenanceWindowTargetsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowTargetsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowTargets(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowTargets(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowTargets", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTasks.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTasks.go deleted file mode 100644 index e482424..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowTasks.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the tasks in a maintenance window. For maintenance window tasks without a -// specified target, you can't supply values for --max-errors and --max-concurrency -// . Instead, the system inserts a placeholder value of 1 , which may be reported -// in the response to this command. These values don't affect the running of your -// task and can be ignored. -func (c *Client) DescribeMaintenanceWindowTasks(ctx context.Context, params *DescribeMaintenanceWindowTasksInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowTasksOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowTasksInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowTasks", params, optFns, c.addOperationDescribeMaintenanceWindowTasksMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowTasksOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowTasksInput struct { - - // The ID of the maintenance window whose tasks should be retrieved. - // - // This member is required. - WindowId *string - - // Optional filters used to narrow down the scope of the returned tasks. The - // supported filter keys are WindowTaskId , TaskArn , Priority , and TaskType . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowTasksOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the tasks in the maintenance window. - Tasks []types.MaintenanceWindowTask - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowTasksMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowTasks{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowTasks{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowTasks"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowTasksValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowTasks(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowTasksAPIClient is a client that implements the -// DescribeMaintenanceWindowTasks operation. -type DescribeMaintenanceWindowTasksAPIClient interface { - DescribeMaintenanceWindowTasks(context.Context, *DescribeMaintenanceWindowTasksInput, ...func(*Options)) (*DescribeMaintenanceWindowTasksOutput, error) -} - -var _ DescribeMaintenanceWindowTasksAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowTasksPaginatorOptions is the paginator options for -// DescribeMaintenanceWindowTasks -type DescribeMaintenanceWindowTasksPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowTasksPaginator is a paginator for -// DescribeMaintenanceWindowTasks -type DescribeMaintenanceWindowTasksPaginator struct { - options DescribeMaintenanceWindowTasksPaginatorOptions - client DescribeMaintenanceWindowTasksAPIClient - params *DescribeMaintenanceWindowTasksInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowTasksPaginator returns a new -// DescribeMaintenanceWindowTasksPaginator -func NewDescribeMaintenanceWindowTasksPaginator(client DescribeMaintenanceWindowTasksAPIClient, params *DescribeMaintenanceWindowTasksInput, optFns ...func(*DescribeMaintenanceWindowTasksPaginatorOptions)) *DescribeMaintenanceWindowTasksPaginator { - if params == nil { - params = &DescribeMaintenanceWindowTasksInput{} - } - - options := DescribeMaintenanceWindowTasksPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowTasksPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowTasksPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowTasks page. -func (p *DescribeMaintenanceWindowTasksPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowTasksOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowTasks(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowTasks(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowTasks", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindows.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindows.go deleted file mode 100644 index b892905..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindows.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the maintenance windows in an Amazon Web Services account. -func (c *Client) DescribeMaintenanceWindows(ctx context.Context, params *DescribeMaintenanceWindowsInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowsOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindows", params, optFns, c.addOperationDescribeMaintenanceWindowsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowsInput struct { - - // Optional filters used to narrow down the scope of the returned maintenance - // windows. Supported filter keys are Name and Enabled . For example, - // Name=MyMaintenanceWindow and Enabled=True . - Filters []types.MaintenanceWindowFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowsOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Information about the maintenance windows. - WindowIdentities []types.MaintenanceWindowIdentity - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindows{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindows{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindows"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindows(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowsAPIClient is a client that implements the -// DescribeMaintenanceWindows operation. -type DescribeMaintenanceWindowsAPIClient interface { - DescribeMaintenanceWindows(context.Context, *DescribeMaintenanceWindowsInput, ...func(*Options)) (*DescribeMaintenanceWindowsOutput, error) -} - -var _ DescribeMaintenanceWindowsAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowsPaginatorOptions is the paginator options for -// DescribeMaintenanceWindows -type DescribeMaintenanceWindowsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowsPaginator is a paginator for -// DescribeMaintenanceWindows -type DescribeMaintenanceWindowsPaginator struct { - options DescribeMaintenanceWindowsPaginatorOptions - client DescribeMaintenanceWindowsAPIClient - params *DescribeMaintenanceWindowsInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowsPaginator returns a new -// DescribeMaintenanceWindowsPaginator -func NewDescribeMaintenanceWindowsPaginator(client DescribeMaintenanceWindowsAPIClient, params *DescribeMaintenanceWindowsInput, optFns ...func(*DescribeMaintenanceWindowsPaginatorOptions)) *DescribeMaintenanceWindowsPaginator { - if params == nil { - params = &DescribeMaintenanceWindowsInput{} - } - - options := DescribeMaintenanceWindowsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindows page. -func (p *DescribeMaintenanceWindowsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindows(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindows(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindows", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowsForTarget.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowsForTarget.go deleted file mode 100644 index aabf1a5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeMaintenanceWindowsForTarget.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves information about the maintenance window targets or tasks that a -// managed node is associated with. -func (c *Client) DescribeMaintenanceWindowsForTarget(ctx context.Context, params *DescribeMaintenanceWindowsForTargetInput, optFns ...func(*Options)) (*DescribeMaintenanceWindowsForTargetOutput, error) { - if params == nil { - params = &DescribeMaintenanceWindowsForTargetInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeMaintenanceWindowsForTarget", params, optFns, c.addOperationDescribeMaintenanceWindowsForTargetMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeMaintenanceWindowsForTargetOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeMaintenanceWindowsForTargetInput struct { - - // The type of resource you want to retrieve information about. For example, - // INSTANCE . - // - // This member is required. - ResourceType types.MaintenanceWindowResourceType - - // The managed node ID or key-value pair to retrieve information about. - // - // This member is required. - Targets []types.Target - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeMaintenanceWindowsForTargetOutput struct { - - // The token for the next set of items to return. (You use this token in the next - // call.) - NextToken *string - - // Information about the maintenance window targets and tasks a managed node is - // associated with. - WindowIdentities []types.MaintenanceWindowIdentityForTarget - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeMaintenanceWindowsForTargetMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeMaintenanceWindowsForTarget{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeMaintenanceWindowsForTarget{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeMaintenanceWindowsForTarget"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeMaintenanceWindowsForTargetValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeMaintenanceWindowsForTarget(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeMaintenanceWindowsForTargetAPIClient is a client that implements the -// DescribeMaintenanceWindowsForTarget operation. -type DescribeMaintenanceWindowsForTargetAPIClient interface { - DescribeMaintenanceWindowsForTarget(context.Context, *DescribeMaintenanceWindowsForTargetInput, ...func(*Options)) (*DescribeMaintenanceWindowsForTargetOutput, error) -} - -var _ DescribeMaintenanceWindowsForTargetAPIClient = (*Client)(nil) - -// DescribeMaintenanceWindowsForTargetPaginatorOptions is the paginator options -// for DescribeMaintenanceWindowsForTarget -type DescribeMaintenanceWindowsForTargetPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeMaintenanceWindowsForTargetPaginator is a paginator for -// DescribeMaintenanceWindowsForTarget -type DescribeMaintenanceWindowsForTargetPaginator struct { - options DescribeMaintenanceWindowsForTargetPaginatorOptions - client DescribeMaintenanceWindowsForTargetAPIClient - params *DescribeMaintenanceWindowsForTargetInput - nextToken *string - firstPage bool -} - -// NewDescribeMaintenanceWindowsForTargetPaginator returns a new -// DescribeMaintenanceWindowsForTargetPaginator -func NewDescribeMaintenanceWindowsForTargetPaginator(client DescribeMaintenanceWindowsForTargetAPIClient, params *DescribeMaintenanceWindowsForTargetInput, optFns ...func(*DescribeMaintenanceWindowsForTargetPaginatorOptions)) *DescribeMaintenanceWindowsForTargetPaginator { - if params == nil { - params = &DescribeMaintenanceWindowsForTargetInput{} - } - - options := DescribeMaintenanceWindowsForTargetPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeMaintenanceWindowsForTargetPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeMaintenanceWindowsForTargetPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeMaintenanceWindowsForTarget page. -func (p *DescribeMaintenanceWindowsForTargetPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeMaintenanceWindowsForTargetOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeMaintenanceWindowsForTarget(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeMaintenanceWindowsForTarget(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeMaintenanceWindowsForTarget", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeOpsItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeOpsItems.go deleted file mode 100644 index a1c4f7c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeOpsItems.go +++ /dev/null @@ -1,264 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Query a set of OpsItems. You must have permission in Identity and Access -// Management (IAM) to query a list of OpsItems. For more information, see Set up -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setup.html) -// in the Amazon Web Services Systems Manager User Guide. Operations engineers and -// IT professionals use Amazon Web Services Systems Manager OpsCenter to view, -// investigate, and remediate operational issues impacting the performance and -// health of their Amazon Web Services resources. For more information, see -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) DescribeOpsItems(ctx context.Context, params *DescribeOpsItemsInput, optFns ...func(*Options)) (*DescribeOpsItemsOutput, error) { - if params == nil { - params = &DescribeOpsItemsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeOpsItems", params, optFns, c.addOperationDescribeOpsItemsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeOpsItemsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeOpsItemsInput struct { - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - // One or more filters to limit the response. - // - Key: CreatedTime Operations: GreaterThan, LessThan - // - Key: LastModifiedBy Operations: Contains, Equals - // - Key: LastModifiedTime Operations: GreaterThan, LessThan - // - Key: Priority Operations: Equals - // - Key: Source Operations: Contains, Equals - // - Key: Status Operations: Equals - // - Key: Title* Operations: Equals,Contains - // - Key: OperationalData** Operations: Equals - // - Key: OperationalDataKey Operations: Equals - // - Key: OperationalDataValue Operations: Equals, Contains - // - Key: OpsItemId Operations: Equals - // - Key: ResourceId Operations: Contains - // - Key: AutomationId Operations: Equals - // - Key: AccountId Operations: Equals - // *The Equals operator for Title matches the first 100 characters. If you specify - // more than 100 characters, they system returns an error that the filter value - // exceeds the length limit. **If you filter the response by using the - // OperationalData operator, specify a key-value pair by using the following JSON - // format: {"key":"key_name","value":"a_value"} - OpsItemFilters []types.OpsItemFilter - - noSmithyDocumentSerde -} - -type DescribeOpsItemsOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A list of OpsItems. - OpsItemSummaries []types.OpsItemSummary - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeOpsItemsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeOpsItems{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeOpsItems{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeOpsItems"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeOpsItemsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeOpsItems(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeOpsItemsAPIClient is a client that implements the DescribeOpsItems -// operation. -type DescribeOpsItemsAPIClient interface { - DescribeOpsItems(context.Context, *DescribeOpsItemsInput, ...func(*Options)) (*DescribeOpsItemsOutput, error) -} - -var _ DescribeOpsItemsAPIClient = (*Client)(nil) - -// DescribeOpsItemsPaginatorOptions is the paginator options for DescribeOpsItems -type DescribeOpsItemsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeOpsItemsPaginator is a paginator for DescribeOpsItems -type DescribeOpsItemsPaginator struct { - options DescribeOpsItemsPaginatorOptions - client DescribeOpsItemsAPIClient - params *DescribeOpsItemsInput - nextToken *string - firstPage bool -} - -// NewDescribeOpsItemsPaginator returns a new DescribeOpsItemsPaginator -func NewDescribeOpsItemsPaginator(client DescribeOpsItemsAPIClient, params *DescribeOpsItemsInput, optFns ...func(*DescribeOpsItemsPaginatorOptions)) *DescribeOpsItemsPaginator { - if params == nil { - params = &DescribeOpsItemsInput{} - } - - options := DescribeOpsItemsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeOpsItemsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeOpsItemsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeOpsItems page. -func (p *DescribeOpsItemsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeOpsItemsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeOpsItems(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeOpsItems(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeOpsItems", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeParameters.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeParameters.go deleted file mode 100644 index 9da5680..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeParameters.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Get information about a parameter. Request results are returned on a -// best-effort basis. If you specify MaxResults in the request, the response -// includes information up to the limit specified. The number of items returned, -// however, can be between zero and the value of MaxResults . If the service -// reaches an internal limit while processing the results, it stops the operation -// and returns the matching values up to that point and a NextToken . You can -// specify the NextToken in a subsequent call to get the next set of results. If -// you change the KMS key alias for the KMS key used to encrypt a parameter, then -// you must also update the key alias the parameter uses to reference KMS. -// Otherwise, DescribeParameters retrieves whatever the original key alias was -// referencing. -func (c *Client) DescribeParameters(ctx context.Context, params *DescribeParametersInput, optFns ...func(*Options)) (*DescribeParametersOutput, error) { - if params == nil { - params = &DescribeParametersInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeParameters", params, optFns, c.addOperationDescribeParametersMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeParametersOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeParametersInput struct { - - // This data type is deprecated. Instead, use ParameterFilters . - Filters []types.ParametersFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // Filters to limit the request results. - ParameterFilters []types.ParameterStringFilter - - noSmithyDocumentSerde -} - -type DescribeParametersOutput struct { - - // The token to use when requesting the next set of items. - NextToken *string - - // Parameters returned by the request. - Parameters []types.ParameterMetadata - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeParametersMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeParameters{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeParameters{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeParameters"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeParametersValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeParameters(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeParametersAPIClient is a client that implements the DescribeParameters -// operation. -type DescribeParametersAPIClient interface { - DescribeParameters(context.Context, *DescribeParametersInput, ...func(*Options)) (*DescribeParametersOutput, error) -} - -var _ DescribeParametersAPIClient = (*Client)(nil) - -// DescribeParametersPaginatorOptions is the paginator options for -// DescribeParameters -type DescribeParametersPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeParametersPaginator is a paginator for DescribeParameters -type DescribeParametersPaginator struct { - options DescribeParametersPaginatorOptions - client DescribeParametersAPIClient - params *DescribeParametersInput - nextToken *string - firstPage bool -} - -// NewDescribeParametersPaginator returns a new DescribeParametersPaginator -func NewDescribeParametersPaginator(client DescribeParametersAPIClient, params *DescribeParametersInput, optFns ...func(*DescribeParametersPaginatorOptions)) *DescribeParametersPaginator { - if params == nil { - params = &DescribeParametersInput{} - } - - options := DescribeParametersPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeParametersPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeParametersPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeParameters page. -func (p *DescribeParametersPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeParametersOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeParameters(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeParameters(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeParameters", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchBaselines.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchBaselines.go deleted file mode 100644 index 089dd36..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchBaselines.go +++ /dev/null @@ -1,238 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the patch baselines in your Amazon Web Services account. -func (c *Client) DescribePatchBaselines(ctx context.Context, params *DescribePatchBaselinesInput, optFns ...func(*Options)) (*DescribePatchBaselinesOutput, error) { - if params == nil { - params = &DescribePatchBaselinesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribePatchBaselines", params, optFns, c.addOperationDescribePatchBaselinesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribePatchBaselinesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribePatchBaselinesInput struct { - - // Each element in the array is a structure containing a key-value pair. Supported - // keys for DescribePatchBaselines include the following: - // - NAME_PREFIX Sample values: AWS- | My- - // - OWNER Sample values: AWS | Self - // - OPERATING_SYSTEM Sample values: AMAZON_LINUX | SUSE | WINDOWS - Filters []types.PatchOrchestratorFilter - - // The maximum number of patch baselines to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribePatchBaselinesOutput struct { - - // An array of PatchBaselineIdentity elements. - BaselineIdentities []types.PatchBaselineIdentity - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribePatchBaselinesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribePatchBaselines{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribePatchBaselines{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribePatchBaselines"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePatchBaselines(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribePatchBaselinesAPIClient is a client that implements the -// DescribePatchBaselines operation. -type DescribePatchBaselinesAPIClient interface { - DescribePatchBaselines(context.Context, *DescribePatchBaselinesInput, ...func(*Options)) (*DescribePatchBaselinesOutput, error) -} - -var _ DescribePatchBaselinesAPIClient = (*Client)(nil) - -// DescribePatchBaselinesPaginatorOptions is the paginator options for -// DescribePatchBaselines -type DescribePatchBaselinesPaginatorOptions struct { - // The maximum number of patch baselines to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribePatchBaselinesPaginator is a paginator for DescribePatchBaselines -type DescribePatchBaselinesPaginator struct { - options DescribePatchBaselinesPaginatorOptions - client DescribePatchBaselinesAPIClient - params *DescribePatchBaselinesInput - nextToken *string - firstPage bool -} - -// NewDescribePatchBaselinesPaginator returns a new DescribePatchBaselinesPaginator -func NewDescribePatchBaselinesPaginator(client DescribePatchBaselinesAPIClient, params *DescribePatchBaselinesInput, optFns ...func(*DescribePatchBaselinesPaginatorOptions)) *DescribePatchBaselinesPaginator { - if params == nil { - params = &DescribePatchBaselinesInput{} - } - - options := DescribePatchBaselinesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribePatchBaselinesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribePatchBaselinesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribePatchBaselines page. -func (p *DescribePatchBaselinesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribePatchBaselinesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribePatchBaselines(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribePatchBaselines(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribePatchBaselines", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroupState.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroupState.go deleted file mode 100644 index 80b1615..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroupState.go +++ /dev/null @@ -1,189 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns high-level aggregated patch compliance state information for a patch -// group. -func (c *Client) DescribePatchGroupState(ctx context.Context, params *DescribePatchGroupStateInput, optFns ...func(*Options)) (*DescribePatchGroupStateOutput, error) { - if params == nil { - params = &DescribePatchGroupStateInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribePatchGroupState", params, optFns, c.addOperationDescribePatchGroupStateMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribePatchGroupStateOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribePatchGroupStateInput struct { - - // The name of the patch group whose patch snapshot should be retrieved. - // - // This member is required. - PatchGroup *string - - noSmithyDocumentSerde -} - -type DescribePatchGroupStateOutput struct { - - // The number of managed nodes in the patch group. - Instances int32 - - // The number of managed nodes where patches that are specified as Critical for - // compliance reporting in the patch baseline aren't installed. These patches might - // be missing, have failed installation, were rejected, or were installed but - // awaiting a required managed node reboot. The status of these managed nodes is - // NON_COMPLIANT . - InstancesWithCriticalNonCompliantPatches *int32 - - // The number of managed nodes with patches from the patch baseline that failed to - // install. - InstancesWithFailedPatches int32 - - // The number of managed nodes with patches installed that aren't defined in the - // patch baseline. - InstancesWithInstalledOtherPatches int32 - - // The number of managed nodes with installed patches. - InstancesWithInstalledPatches int32 - - // The number of managed nodes with patches installed by Patch Manager that - // haven't been rebooted after the patch installation. The status of these managed - // nodes is NON_COMPLIANT . - InstancesWithInstalledPendingRebootPatches *int32 - - // The number of managed nodes with patches installed that are specified in a - // RejectedPatches list. Patches with a status of INSTALLED_REJECTED were - // typically installed before they were added to a RejectedPatches list. If - // ALLOW_AS_DEPENDENCY is the specified option for RejectedPatchesAction , the - // value of InstancesWithInstalledRejectedPatches will always be 0 (zero). - InstancesWithInstalledRejectedPatches *int32 - - // The number of managed nodes with missing patches from the patch baseline. - InstancesWithMissingPatches int32 - - // The number of managed nodes with patches that aren't applicable. - InstancesWithNotApplicablePatches int32 - - // The number of managed nodes with patches installed that are specified as other - // than Critical or Security but aren't compliant with the patch baseline. The - // status of these managed nodes is NON_COMPLIANT . - InstancesWithOtherNonCompliantPatches *int32 - - // The number of managed nodes where patches that are specified as Security in a - // patch advisory aren't installed. These patches might be missing, have failed - // installation, were rejected, or were installed but awaiting a required managed - // node reboot. The status of these managed nodes is NON_COMPLIANT . - InstancesWithSecurityNonCompliantPatches *int32 - - // The number of managed nodes with NotApplicable patches beyond the supported - // limit, which aren't reported by name to Inventory. Inventory is a capability of - // Amazon Web Services Systems Manager. - InstancesWithUnreportedNotApplicablePatches *int32 - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribePatchGroupStateMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribePatchGroupState{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribePatchGroupState{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribePatchGroupState"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribePatchGroupStateValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePatchGroupState(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDescribePatchGroupState(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribePatchGroupState", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroups.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroups.go deleted file mode 100644 index fca09c5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchGroups.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists all patch groups that have been registered with patch baselines. -func (c *Client) DescribePatchGroups(ctx context.Context, params *DescribePatchGroupsInput, optFns ...func(*Options)) (*DescribePatchGroupsOutput, error) { - if params == nil { - params = &DescribePatchGroupsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribePatchGroups", params, optFns, c.addOperationDescribePatchGroupsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribePatchGroupsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribePatchGroupsInput struct { - - // Each element in the array is a structure containing a key-value pair. Supported - // keys for DescribePatchGroups include the following: - // - NAME_PREFIX Sample values: AWS- | My- . - // - OPERATING_SYSTEM Sample values: AMAZON_LINUX | SUSE | WINDOWS - Filters []types.PatchOrchestratorFilter - - // The maximum number of patch groups to return (per page). - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribePatchGroupsOutput struct { - - // Each entry in the array contains: - // - PatchGroup : string (between 1 and 256 characters. Regex: - // ^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$) - // - PatchBaselineIdentity : A PatchBaselineIdentity element. - Mappings []types.PatchGroupPatchBaselineMapping - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribePatchGroupsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribePatchGroups{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribePatchGroups{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribePatchGroups"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePatchGroups(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribePatchGroupsAPIClient is a client that implements the -// DescribePatchGroups operation. -type DescribePatchGroupsAPIClient interface { - DescribePatchGroups(context.Context, *DescribePatchGroupsInput, ...func(*Options)) (*DescribePatchGroupsOutput, error) -} - -var _ DescribePatchGroupsAPIClient = (*Client)(nil) - -// DescribePatchGroupsPaginatorOptions is the paginator options for -// DescribePatchGroups -type DescribePatchGroupsPaginatorOptions struct { - // The maximum number of patch groups to return (per page). - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribePatchGroupsPaginator is a paginator for DescribePatchGroups -type DescribePatchGroupsPaginator struct { - options DescribePatchGroupsPaginatorOptions - client DescribePatchGroupsAPIClient - params *DescribePatchGroupsInput - nextToken *string - firstPage bool -} - -// NewDescribePatchGroupsPaginator returns a new DescribePatchGroupsPaginator -func NewDescribePatchGroupsPaginator(client DescribePatchGroupsAPIClient, params *DescribePatchGroupsInput, optFns ...func(*DescribePatchGroupsPaginatorOptions)) *DescribePatchGroupsPaginator { - if params == nil { - params = &DescribePatchGroupsInput{} - } - - options := DescribePatchGroupsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribePatchGroupsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribePatchGroupsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribePatchGroups page. -func (p *DescribePatchGroupsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribePatchGroupsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribePatchGroups(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribePatchGroups(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribePatchGroups", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchProperties.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchProperties.go deleted file mode 100644 index c2f7446..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribePatchProperties.go +++ /dev/null @@ -1,265 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the properties of available patches organized by product, product family, -// classification, severity, and other properties of available patches. You can use -// the reported properties in the filters you specify in requests for operations -// such as CreatePatchBaseline , UpdatePatchBaseline , DescribeAvailablePatches , -// and DescribePatchBaselines . The following section lists the properties that can -// be used in filters for each major operating system type: AMAZON_LINUX Valid -// properties: PRODUCT | CLASSIFICATION | SEVERITY AMAZON_LINUX_2 Valid -// properties: PRODUCT | CLASSIFICATION | SEVERITY CENTOS Valid properties: PRODUCT -// | CLASSIFICATION | SEVERITY DEBIAN Valid properties: PRODUCT | PRIORITY MACOS -// Valid properties: PRODUCT | CLASSIFICATION ORACLE_LINUX Valid properties: -// PRODUCT | CLASSIFICATION | SEVERITY REDHAT_ENTERPRISE_LINUX Valid properties: -// PRODUCT | CLASSIFICATION | SEVERITY SUSE Valid properties: PRODUCT | -// CLASSIFICATION | SEVERITY UBUNTU Valid properties: PRODUCT | PRIORITY WINDOWS -// Valid properties: PRODUCT | PRODUCT_FAMILY | CLASSIFICATION | MSRC_SEVERITY -func (c *Client) DescribePatchProperties(ctx context.Context, params *DescribePatchPropertiesInput, optFns ...func(*Options)) (*DescribePatchPropertiesOutput, error) { - if params == nil { - params = &DescribePatchPropertiesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribePatchProperties", params, optFns, c.addOperationDescribePatchPropertiesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribePatchPropertiesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribePatchPropertiesInput struct { - - // The operating system type for which to list patches. - // - // This member is required. - OperatingSystem types.OperatingSystem - - // The patch property for which you want to view patch details. - // - // This member is required. - Property types.PatchProperty - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // Indicates whether to list patches for the Windows operating system or for - // applications released by Microsoft. Not applicable for the Linux or macOS - // operating systems. - PatchSet types.PatchSet - - noSmithyDocumentSerde -} - -type DescribePatchPropertiesOutput struct { - - // The token for the next set of items to return. (You use this token in the next - // call.) - NextToken *string - - // A list of the properties for patches matching the filter request parameters. - Properties []map[string]string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribePatchPropertiesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribePatchProperties{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribePatchProperties{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribePatchProperties"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribePatchPropertiesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePatchProperties(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribePatchPropertiesAPIClient is a client that implements the -// DescribePatchProperties operation. -type DescribePatchPropertiesAPIClient interface { - DescribePatchProperties(context.Context, *DescribePatchPropertiesInput, ...func(*Options)) (*DescribePatchPropertiesOutput, error) -} - -var _ DescribePatchPropertiesAPIClient = (*Client)(nil) - -// DescribePatchPropertiesPaginatorOptions is the paginator options for -// DescribePatchProperties -type DescribePatchPropertiesPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribePatchPropertiesPaginator is a paginator for DescribePatchProperties -type DescribePatchPropertiesPaginator struct { - options DescribePatchPropertiesPaginatorOptions - client DescribePatchPropertiesAPIClient - params *DescribePatchPropertiesInput - nextToken *string - firstPage bool -} - -// NewDescribePatchPropertiesPaginator returns a new -// DescribePatchPropertiesPaginator -func NewDescribePatchPropertiesPaginator(client DescribePatchPropertiesAPIClient, params *DescribePatchPropertiesInput, optFns ...func(*DescribePatchPropertiesPaginatorOptions)) *DescribePatchPropertiesPaginator { - if params == nil { - params = &DescribePatchPropertiesInput{} - } - - options := DescribePatchPropertiesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribePatchPropertiesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribePatchPropertiesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribePatchProperties page. -func (p *DescribePatchPropertiesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribePatchPropertiesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribePatchProperties(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribePatchProperties(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribePatchProperties", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeSessions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeSessions.go deleted file mode 100644 index cb3d1fc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DescribeSessions.go +++ /dev/null @@ -1,244 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves a list of all active sessions (both connected and disconnected) or -// terminated sessions from the past 30 days. -func (c *Client) DescribeSessions(ctx context.Context, params *DescribeSessionsInput, optFns ...func(*Options)) (*DescribeSessionsOutput, error) { - if params == nil { - params = &DescribeSessionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DescribeSessions", params, optFns, c.addOperationDescribeSessionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DescribeSessionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DescribeSessionsInput struct { - - // The session status to retrieve a list of sessions for. For example, "Active". - // - // This member is required. - State types.SessionState - - // One or more filters to limit the type of sessions returned by the request. - Filters []types.SessionFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type DescribeSessionsOutput struct { - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // A list of sessions meeting the request parameters. - Sessions []types.Session - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDescribeSessionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeSessions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeSessions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeSessions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDescribeSessionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeSessions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// DescribeSessionsAPIClient is a client that implements the DescribeSessions -// operation. -type DescribeSessionsAPIClient interface { - DescribeSessions(context.Context, *DescribeSessionsInput, ...func(*Options)) (*DescribeSessionsOutput, error) -} - -var _ DescribeSessionsAPIClient = (*Client)(nil) - -// DescribeSessionsPaginatorOptions is the paginator options for DescribeSessions -type DescribeSessionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// DescribeSessionsPaginator is a paginator for DescribeSessions -type DescribeSessionsPaginator struct { - options DescribeSessionsPaginatorOptions - client DescribeSessionsAPIClient - params *DescribeSessionsInput - nextToken *string - firstPage bool -} - -// NewDescribeSessionsPaginator returns a new DescribeSessionsPaginator -func NewDescribeSessionsPaginator(client DescribeSessionsAPIClient, params *DescribeSessionsInput, optFns ...func(*DescribeSessionsPaginatorOptions)) *DescribeSessionsPaginator { - if params == nil { - params = &DescribeSessionsInput{} - } - - options := DescribeSessionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &DescribeSessionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *DescribeSessionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next DescribeSessions page. -func (p *DescribeSessionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeSessionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.DescribeSessions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opDescribeSessions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DescribeSessions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DisassociateOpsItemRelatedItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DisassociateOpsItemRelatedItem.go deleted file mode 100644 index 7c32e8f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_DisassociateOpsItemRelatedItem.go +++ /dev/null @@ -1,141 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Deletes the association between an OpsItem and a related item. For example, -// this API operation can delete an Incident Manager incident from an OpsItem. -// Incident Manager is a capability of Amazon Web Services Systems Manager. -func (c *Client) DisassociateOpsItemRelatedItem(ctx context.Context, params *DisassociateOpsItemRelatedItemInput, optFns ...func(*Options)) (*DisassociateOpsItemRelatedItemOutput, error) { - if params == nil { - params = &DisassociateOpsItemRelatedItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DisassociateOpsItemRelatedItem", params, optFns, c.addOperationDisassociateOpsItemRelatedItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DisassociateOpsItemRelatedItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DisassociateOpsItemRelatedItemInput struct { - - // The ID of the association for which you want to delete an association between - // the OpsItem and a related item. - // - // This member is required. - AssociationId *string - - // The ID of the OpsItem for which you want to delete an association between the - // OpsItem and a related item. - // - // This member is required. - OpsItemId *string - - noSmithyDocumentSerde -} - -type DisassociateOpsItemRelatedItemOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDisassociateOpsItemRelatedItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpDisassociateOpsItemRelatedItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDisassociateOpsItemRelatedItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DisassociateOpsItemRelatedItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpDisassociateOpsItemRelatedItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDisassociateOpsItemRelatedItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDisassociateOpsItemRelatedItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DisassociateOpsItemRelatedItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetAutomationExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetAutomationExecution.go deleted file mode 100644 index cc3a61b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetAutomationExecution.go +++ /dev/null @@ -1,139 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Get detailed information about a particular Automation execution. -func (c *Client) GetAutomationExecution(ctx context.Context, params *GetAutomationExecutionInput, optFns ...func(*Options)) (*GetAutomationExecutionOutput, error) { - if params == nil { - params = &GetAutomationExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetAutomationExecution", params, optFns, c.addOperationGetAutomationExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetAutomationExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetAutomationExecutionInput struct { - - // The unique identifier for an existing automation execution to examine. The - // execution ID is returned by StartAutomationExecution when the execution of an - // Automation runbook is initiated. - // - // This member is required. - AutomationExecutionId *string - - noSmithyDocumentSerde -} - -type GetAutomationExecutionOutput struct { - - // Detailed information about the current state of an automation execution. - AutomationExecution *types.AutomationExecution - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetAutomationExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetAutomationExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetAutomationExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetAutomationExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetAutomationExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAutomationExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetAutomationExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetAutomationExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCalendarState.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCalendarState.go deleted file mode 100644 index 11b1f04..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCalendarState.go +++ /dev/null @@ -1,168 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Gets the state of a Amazon Web Services Systems Manager change calendar at the -// current time or a specified time. If you specify a time, GetCalendarState -// returns the state of the calendar at that specific time, and returns the next -// time that the change calendar state will transition. If you don't specify a -// time, GetCalendarState uses the current time. Change Calendar entries have two -// possible states: OPEN or CLOSED . If you specify more than one calendar in a -// request, the command returns the status of OPEN only if all calendars in the -// request are open. If one or more calendars in the request are closed, the status -// returned is CLOSED . For more information about Change Calendar, a capability of -// Amazon Web Services Systems Manager, see Amazon Web Services Systems Manager -// Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) GetCalendarState(ctx context.Context, params *GetCalendarStateInput, optFns ...func(*Options)) (*GetCalendarStateOutput, error) { - if params == nil { - params = &GetCalendarStateInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetCalendarState", params, optFns, c.addOperationGetCalendarStateMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetCalendarStateOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetCalendarStateInput struct { - - // The names or Amazon Resource Names (ARNs) of the Systems Manager documents (SSM - // documents) that represent the calendar entries for which you want to get the - // state. - // - // This member is required. - CalendarNames []string - - // (Optional) The specific time for which you want to get calendar state - // information, in ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601) format. If - // you don't specify a value or AtTime , the current time is used. - AtTime *string - - noSmithyDocumentSerde -} - -type GetCalendarStateOutput struct { - - // The time, as an ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601) string, that - // you specified in your command. If you don't specify a time, GetCalendarState - // uses the current time. - AtTime *string - - // The time, as an ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601) string, that - // the calendar state will change. If the current calendar state is OPEN , - // NextTransitionTime indicates when the calendar state changes to CLOSED , and - // vice-versa. - NextTransitionTime *string - - // The state of the calendar. An OPEN calendar indicates that actions are allowed - // to proceed, and a CLOSED calendar indicates that actions aren't allowed to - // proceed. - State types.CalendarState - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetCalendarStateMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetCalendarState{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetCalendarState{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetCalendarState"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetCalendarStateValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetCalendarState(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetCalendarState(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetCalendarState", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCommandInvocation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCommandInvocation.go deleted file mode 100644 index 05abba8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetCommandInvocation.go +++ /dev/null @@ -1,565 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "errors" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" - smithywaiter "github.com/aws/smithy-go/waiter" - "github.com/jmespath/go-jmespath" - "time" -) - -// Returns detailed information about command execution for an invocation or -// plugin. GetCommandInvocation only gives the execution status of a plugin in a -// document. To get the command execution status on a specific managed node, use -// ListCommandInvocations . To get the command execution status across managed -// nodes, use ListCommands . -func (c *Client) GetCommandInvocation(ctx context.Context, params *GetCommandInvocationInput, optFns ...func(*Options)) (*GetCommandInvocationOutput, error) { - if params == nil { - params = &GetCommandInvocationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetCommandInvocation", params, optFns, c.addOperationGetCommandInvocationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetCommandInvocationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetCommandInvocationInput struct { - - // (Required) The parent command ID of the invocation plugin. - // - // This member is required. - CommandId *string - - // (Required) The ID of the managed node targeted by the command. A managed node - // can be an Amazon Elastic Compute Cloud (Amazon EC2) instance, edge device, and - // on-premises server or VM in your hybrid environment that is configured for - // Amazon Web Services Systems Manager. - // - // This member is required. - InstanceId *string - - // The name of the step for which you want detailed results. If the document - // contains only one step, you can omit the name and details for that step. If the - // document contains more than one step, you must specify the name of the step for - // which you want to view details. Be sure to specify the name of the step, not the - // name of a plugin like aws:RunShellScript . To find the PluginName , check the - // document content and find the name of the step you want details for. - // Alternatively, use ListCommandInvocations with the CommandId and Details - // parameters. The PluginName is the Name attribute of the CommandPlugin object in - // the CommandPlugins list. - PluginName *string - - noSmithyDocumentSerde -} - -type GetCommandInvocationOutput struct { - - // Amazon CloudWatch Logs information where Systems Manager sent the command - // output. - CloudWatchOutputConfig *types.CloudWatchOutputConfig - - // The parent command ID of the invocation plugin. - CommandId *string - - // The comment text for the command. - Comment *string - - // The name of the document that was run. For example, AWS-RunShellScript . - DocumentName *string - - // The Systems Manager document (SSM document) version used in the request. - DocumentVersion *string - - // Duration since ExecutionStartDateTime . - ExecutionElapsedTime *string - - // The date and time the plugin finished running. Date and time are written in ISO - // 8601 format. For example, June 7, 2017 is represented as 2017-06-7. The - // following sample Amazon Web Services CLI command uses the InvokedAfter filter. - // aws ssm list-commands --filters key=InvokedAfter,value=2017-06-07T00:00:00Z If - // the plugin hasn't started to run, the string is empty. - ExecutionEndDateTime *string - - // The date and time the plugin started running. Date and time are written in ISO - // 8601 format. For example, June 7, 2017 is represented as 2017-06-7. The - // following sample Amazon Web Services CLI command uses the InvokedBefore filter. - // aws ssm list-commands --filters key=InvokedBefore,value=2017-06-07T00:00:00Z If - // the plugin hasn't started to run, the string is empty. - ExecutionStartDateTime *string - - // The ID of the managed node targeted by the command. A managed node can be an - // Amazon Elastic Compute Cloud (Amazon EC2) instance, edge device, or on-premises - // server or VM in your hybrid environment that is configured for Amazon Web - // Services Systems Manager. - InstanceId *string - - // The name of the plugin, or step name, for which details are reported. For - // example, aws:RunShellScript is a plugin. - PluginName *string - - // The error level response code for the plugin script. If the response code is -1 - // , then the command hasn't started running on the managed node, or it wasn't - // received by the node. - ResponseCode int32 - - // The first 8,000 characters written by the plugin to stderr . If the command - // hasn't finished running, then this string is empty. - StandardErrorContent *string - - // The URL for the complete text written by the plugin to stderr . If the command - // hasn't finished running, then this string is empty. - StandardErrorUrl *string - - // The first 24,000 characters written by the plugin to stdout . If the command - // hasn't finished running, if ExecutionStatus is neither Succeeded nor Failed, - // then this string is empty. - StandardOutputContent *string - - // The URL for the complete text written by the plugin to stdout in Amazon Simple - // Storage Service (Amazon S3). If an S3 bucket wasn't specified, then this string - // is empty. - StandardOutputUrl *string - - // The status of this invocation plugin. This status can be different than - // StatusDetails . - Status types.CommandInvocationStatus - - // A detailed status of the command execution for an invocation. StatusDetails - // includes more information than Status because it includes states resulting from - // error and concurrency control parameters. StatusDetails can show different - // results than Status . For more information about these statuses, see - // Understanding command statuses (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitor-commands.html) - // in the Amazon Web Services Systems Manager User Guide. StatusDetails can be one - // of the following values: - // - Pending: The command hasn't been sent to the managed node. - // - In Progress: The command has been sent to the managed node but hasn't - // reached a terminal state. - // - Delayed: The system attempted to send the command to the target, but the - // target wasn't available. The managed node might not be available because of - // network issues, because the node was stopped, or for similar reasons. The system - // will try to send the command again. - // - Success: The command or plugin ran successfully. This is a terminal state. - // - Delivery Timed Out: The command wasn't delivered to the managed node before - // the delivery timeout expired. Delivery timeouts don't count against the parent - // command's MaxErrors limit, but they do contribute to whether the parent - // command status is Success or Incomplete. This is a terminal state. - // - Execution Timed Out: The command started to run on the managed node, but - // the execution wasn't complete before the timeout expired. Execution timeouts - // count against the MaxErrors limit of the parent command. This is a terminal - // state. - // - Failed: The command wasn't run successfully on the managed node. For a - // plugin, this indicates that the result code wasn't zero. For a command - // invocation, this indicates that the result code for one or more plugins wasn't - // zero. Invocation failures count against the MaxErrors limit of the parent - // command. This is a terminal state. - // - Cancelled: The command was terminated before it was completed. This is a - // terminal state. - // - Undeliverable: The command can't be delivered to the managed node. The node - // might not exist or might not be responding. Undeliverable invocations don't - // count against the parent command's MaxErrors limit and don't contribute to - // whether the parent command status is Success or Incomplete. This is a terminal - // state. - // - Terminated: The parent command exceeded its MaxErrors limit and subsequent - // command invocations were canceled by the system. This is a terminal state. - StatusDetails *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetCommandInvocationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetCommandInvocation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetCommandInvocation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetCommandInvocation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetCommandInvocationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetCommandInvocation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetCommandInvocationAPIClient is a client that implements the -// GetCommandInvocation operation. -type GetCommandInvocationAPIClient interface { - GetCommandInvocation(context.Context, *GetCommandInvocationInput, ...func(*Options)) (*GetCommandInvocationOutput, error) -} - -var _ GetCommandInvocationAPIClient = (*Client)(nil) - -// CommandExecutedWaiterOptions are waiter options for CommandExecutedWaiter -type CommandExecutedWaiterOptions struct { - - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // MinDelay is the minimum amount of time to delay between retries. If unset, - // CommandExecutedWaiter will use default minimum delay of 5 seconds. Note that - // MinDelay must resolve to a value lesser than or equal to the MaxDelay. - MinDelay time.Duration - - // MaxDelay is the maximum amount of time to delay between retries. If unset or - // set to zero, CommandExecutedWaiter will use default max delay of 120 seconds. - // Note that MaxDelay must resolve to value greater than or equal to the MinDelay. - MaxDelay time.Duration - - // LogWaitAttempts is used to enable logging for waiter retry attempts - LogWaitAttempts bool - - // Retryable is function that can be used to override the service defined - // waiter-behavior based on operation output, or returned error. This function is - // used by the waiter to decide if a state is retryable or a terminal state. By - // default service-modeled logic will populate this option. This option can thus be - // used to define a custom waiter state with fall-back to service-modeled waiter - // state mutators.The function returns an error in case of a failure state. In case - // of retry state, this function returns a bool value of true and nil error, while - // in case of success it returns a bool value of false and nil error. - Retryable func(context.Context, *GetCommandInvocationInput, *GetCommandInvocationOutput, error) (bool, error) -} - -// CommandExecutedWaiter defines the waiters for CommandExecuted -type CommandExecutedWaiter struct { - client GetCommandInvocationAPIClient - - options CommandExecutedWaiterOptions -} - -// NewCommandExecutedWaiter constructs a CommandExecutedWaiter. -func NewCommandExecutedWaiter(client GetCommandInvocationAPIClient, optFns ...func(*CommandExecutedWaiterOptions)) *CommandExecutedWaiter { - options := CommandExecutedWaiterOptions{} - options.MinDelay = 5 * time.Second - options.MaxDelay = 120 * time.Second - options.Retryable = commandExecutedStateRetryable - - for _, fn := range optFns { - fn(&options) - } - return &CommandExecutedWaiter{ - client: client, - options: options, - } -} - -// Wait calls the waiter function for CommandExecuted waiter. The maxWaitDur is -// the maximum wait duration the waiter will wait. The maxWaitDur is required and -// must be greater than zero. -func (w *CommandExecutedWaiter) Wait(ctx context.Context, params *GetCommandInvocationInput, maxWaitDur time.Duration, optFns ...func(*CommandExecutedWaiterOptions)) error { - _, err := w.WaitForOutput(ctx, params, maxWaitDur, optFns...) - return err -} - -// WaitForOutput calls the waiter function for CommandExecuted waiter and returns -// the output of the successful operation. The maxWaitDur is the maximum wait -// duration the waiter will wait. The maxWaitDur is required and must be greater -// than zero. -func (w *CommandExecutedWaiter) WaitForOutput(ctx context.Context, params *GetCommandInvocationInput, maxWaitDur time.Duration, optFns ...func(*CommandExecutedWaiterOptions)) (*GetCommandInvocationOutput, error) { - if maxWaitDur <= 0 { - return nil, fmt.Errorf("maximum wait time for waiter must be greater than zero") - } - - options := w.options - for _, fn := range optFns { - fn(&options) - } - - if options.MaxDelay <= 0 { - options.MaxDelay = 120 * time.Second - } - - if options.MinDelay > options.MaxDelay { - return nil, fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) - } - - ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) - defer cancelFn() - - logger := smithywaiter.Logger{} - remainingTime := maxWaitDur - - var attempt int64 - for { - - attempt++ - apiOptions := options.APIOptions - start := time.Now() - - if options.LogWaitAttempts { - logger.Attempt = attempt - apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) - apiOptions = append(apiOptions, logger.AddLogger) - } - - out, err := w.client.GetCommandInvocation(ctx, params, func(o *Options) { - o.APIOptions = append(o.APIOptions, apiOptions...) - }) - - retryable, err := options.Retryable(ctx, params, out, err) - if err != nil { - return nil, err - } - if !retryable { - return out, nil - } - - remainingTime -= time.Since(start) - if remainingTime < options.MinDelay || remainingTime <= 0 { - break - } - - // compute exponential backoff between waiter retries - delay, err := smithywaiter.ComputeDelay( - attempt, options.MinDelay, options.MaxDelay, remainingTime, - ) - if err != nil { - return nil, fmt.Errorf("error computing waiter delay, %w", err) - } - - remainingTime -= delay - // sleep for the delay amount before invoking a request - if err := smithytime.SleepWithContext(ctx, delay); err != nil { - return nil, fmt.Errorf("request cancelled while waiting, %w", err) - } - } - return nil, fmt.Errorf("exceeded max wait time for CommandExecuted waiter") -} - -func commandExecutedStateRetryable(ctx context.Context, input *GetCommandInvocationInput, output *GetCommandInvocationOutput, err error) (bool, error) { - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Pending" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return true, nil - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "InProgress" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return true, nil - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Delayed" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return true, nil - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Success" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return false, nil - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Cancelled" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return false, fmt.Errorf("waiter state transitioned to Failure") - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "TimedOut" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return false, fmt.Errorf("waiter state transitioned to Failure") - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Failed" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return false, fmt.Errorf("waiter state transitioned to Failure") - } - } - - if err == nil { - pathValue, err := jmespath.Search("Status", output) - if err != nil { - return false, fmt.Errorf("error evaluating waiter state: %w", err) - } - - expectedValue := "Cancelling" - value, ok := pathValue.(types.CommandInvocationStatus) - if !ok { - return false, fmt.Errorf("waiter comparator expected types.CommandInvocationStatus value, got %T", pathValue) - } - - if string(value) == expectedValue { - return false, fmt.Errorf("waiter state transitioned to Failure") - } - } - - if err != nil { - var errorType *types.InvocationDoesNotExist - if errors.As(err, &errorType) { - return true, nil - } - } - - return true, nil -} - -func newServiceMetadataMiddleware_opGetCommandInvocation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetCommandInvocation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetConnectionStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetConnectionStatus.go deleted file mode 100644 index 60e562d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetConnectionStatus.go +++ /dev/null @@ -1,142 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the Session Manager connection status for a managed node to determine -// whether it is running and ready to receive Session Manager connections. -func (c *Client) GetConnectionStatus(ctx context.Context, params *GetConnectionStatusInput, optFns ...func(*Options)) (*GetConnectionStatusOutput, error) { - if params == nil { - params = &GetConnectionStatusInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetConnectionStatus", params, optFns, c.addOperationGetConnectionStatusMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetConnectionStatusOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetConnectionStatusInput struct { - - // The managed node ID. - // - // This member is required. - Target *string - - noSmithyDocumentSerde -} - -type GetConnectionStatusOutput struct { - - // The status of the connection to the managed node. For example, 'Connected' or - // 'Not Connected'. - Status types.ConnectionStatus - - // The ID of the managed node to check connection status. - Target *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetConnectionStatusMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetConnectionStatus{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetConnectionStatus{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetConnectionStatus"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetConnectionStatusValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetConnectionStatus(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetConnectionStatus(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetConnectionStatus", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDefaultPatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDefaultPatchBaseline.go deleted file mode 100644 index 753e899..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDefaultPatchBaseline.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the default patch baseline. Amazon Web Services Systems Manager -// supports creating multiple default patch baselines. For example, you can create -// a default patch baseline for each operating system. If you don't specify an -// operating system value, the default patch baseline for Windows is returned. -func (c *Client) GetDefaultPatchBaseline(ctx context.Context, params *GetDefaultPatchBaselineInput, optFns ...func(*Options)) (*GetDefaultPatchBaselineOutput, error) { - if params == nil { - params = &GetDefaultPatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetDefaultPatchBaseline", params, optFns, c.addOperationGetDefaultPatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetDefaultPatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetDefaultPatchBaselineInput struct { - - // Returns the default patch baseline for the specified operating system. - OperatingSystem types.OperatingSystem - - noSmithyDocumentSerde -} - -type GetDefaultPatchBaselineOutput struct { - - // The ID of the default patch baseline. - BaselineId *string - - // The operating system for the returned patch baseline. - OperatingSystem types.OperatingSystem - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetDefaultPatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetDefaultPatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetDefaultPatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetDefaultPatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDefaultPatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetDefaultPatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetDefaultPatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDeployablePatchSnapshotForInstance.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDeployablePatchSnapshotForInstance.go deleted file mode 100644 index 862b41d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDeployablePatchSnapshotForInstance.go +++ /dev/null @@ -1,165 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the current snapshot for the patch baseline the managed node uses. -// This API is primarily used by the AWS-RunPatchBaseline Systems Manager document -// (SSM document). If you run the command locally, such as with the Command Line -// Interface (CLI), the system attempts to use your local Amazon Web Services -// credentials and the operation fails. To avoid this, you can run the command in -// the Amazon Web Services Systems Manager console. Use Run Command, a capability -// of Amazon Web Services Systems Manager, with an SSM document that enables you to -// target a managed node with a script or command. For example, run the command -// using the AWS-RunShellScript document or the AWS-RunPowerShellScript document. -func (c *Client) GetDeployablePatchSnapshotForInstance(ctx context.Context, params *GetDeployablePatchSnapshotForInstanceInput, optFns ...func(*Options)) (*GetDeployablePatchSnapshotForInstanceOutput, error) { - if params == nil { - params = &GetDeployablePatchSnapshotForInstanceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetDeployablePatchSnapshotForInstance", params, optFns, c.addOperationGetDeployablePatchSnapshotForInstanceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetDeployablePatchSnapshotForInstanceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetDeployablePatchSnapshotForInstanceInput struct { - - // The ID of the managed node for which the appropriate patch snapshot should be - // retrieved. - // - // This member is required. - InstanceId *string - - // The snapshot ID provided by the user when running AWS-RunPatchBaseline . - // - // This member is required. - SnapshotId *string - - // Defines the basic information about a patch baseline override. - BaselineOverride *types.BaselineOverride - - noSmithyDocumentSerde -} - -type GetDeployablePatchSnapshotForInstanceOutput struct { - - // The managed node ID. - InstanceId *string - - // Returns the specific operating system (for example Windows Server 2012 or - // Amazon Linux 2015.09) on the managed node for the specified patch snapshot. - Product *string - - // A pre-signed Amazon Simple Storage Service (Amazon S3) URL that can be used to - // download the patch snapshot. - SnapshotDownloadUrl *string - - // The user-defined snapshot ID. - SnapshotId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetDeployablePatchSnapshotForInstanceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetDeployablePatchSnapshotForInstance{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetDeployablePatchSnapshotForInstance{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetDeployablePatchSnapshotForInstance"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetDeployablePatchSnapshotForInstanceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDeployablePatchSnapshotForInstance(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetDeployablePatchSnapshotForInstance(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetDeployablePatchSnapshotForInstance", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDocument.go deleted file mode 100644 index 9aa1641..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetDocument.go +++ /dev/null @@ -1,202 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Gets the contents of the specified Amazon Web Services Systems Manager document -// (SSM document). -func (c *Client) GetDocument(ctx context.Context, params *GetDocumentInput, optFns ...func(*Options)) (*GetDocumentOutput, error) { - if params == nil { - params = &GetDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetDocument", params, optFns, c.addOperationGetDocumentMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetDocumentInput struct { - - // The name of the SSM document. - // - // This member is required. - Name *string - - // Returns the document in the specified format. The document format can be either - // JSON or YAML. JSON is the default format. - DocumentFormat types.DocumentFormat - - // The document version for which you want information. - DocumentVersion *string - - // An optional field specifying the version of the artifact associated with the - // document. For example, "Release 12, Update 6". This value is unique across all - // versions of a document and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -type GetDocumentOutput struct { - - // A description of the document attachments, including names, locations, sizes, - // and so on. - AttachmentsContent []types.AttachmentContent - - // The contents of the SSM document. - Content *string - - // The date the SSM document was created. - CreatedDate *time.Time - - // The friendly name of the SSM document. This value can differ for each version - // of the document. If you want to update this value, see UpdateDocument . - DisplayName *string - - // The document format, either JSON or YAML. - DocumentFormat types.DocumentFormat - - // The document type. - DocumentType types.DocumentType - - // The document version. - DocumentVersion *string - - // The name of the SSM document. - Name *string - - // A list of SSM documents required by a document. For example, an - // ApplicationConfiguration document requires an ApplicationConfigurationSchema - // document. - Requires []types.DocumentRequires - - // The current review status of a new custom Systems Manager document (SSM - // document) created by a member of your organization, or of the latest version of - // an existing SSM document. Only one version of an SSM document can be in the - // APPROVED state at a time. When a new version is approved, the status of the - // previous version changes to REJECTED. Only one version of an SSM document can be - // in review, or PENDING, at a time. - ReviewStatus types.ReviewStatus - - // The status of the SSM document, such as Creating , Active , Updating , Failed , - // and Deleting . - Status types.DocumentStatus - - // A message returned by Amazon Web Services Systems Manager that explains the - // Status value. For example, a Failed status might be explained by the - // StatusInformation message, "The specified S3 bucket doesn't exist. Verify that - // the URL of the S3 bucket is correct." - StatusInformation *string - - // The version of the artifact associated with the document. For example, "Release - // 12, Update 6". This value is unique across all versions of a document, and can't - // be changed. - VersionName *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetDocumentMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetDocument{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetDocument{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetDocument"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetDocumentValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDocument(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetDocument(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetDocument", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventory.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventory.go deleted file mode 100644 index a84b17d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventory.go +++ /dev/null @@ -1,247 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Query inventory information. This includes managed node status, such as Stopped -// or Terminated . -func (c *Client) GetInventory(ctx context.Context, params *GetInventoryInput, optFns ...func(*Options)) (*GetInventoryOutput, error) { - if params == nil { - params = &GetInventoryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetInventory", params, optFns, c.addOperationGetInventoryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetInventoryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetInventoryInput struct { - - // Returns counts of inventory types based on one or more expressions. For - // example, if you aggregate by using an expression that uses the - // AWS:InstanceInformation.PlatformType type, you can see a count of how many - // Windows and Linux managed nodes exist in your inventoried fleet. - Aggregators []types.InventoryAggregator - - // One or more filters. Use a filter to return a more specific list of results. - Filters []types.InventoryFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // The list of inventory item types to return. - ResultAttributes []types.ResultAttribute - - noSmithyDocumentSerde -} - -type GetInventoryOutput struct { - - // Collection of inventory entities such as a collection of managed node inventory. - Entities []types.InventoryResultEntity - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetInventoryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetInventory{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetInventory{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetInventory"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetInventoryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetInventory(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetInventoryAPIClient is a client that implements the GetInventory operation. -type GetInventoryAPIClient interface { - GetInventory(context.Context, *GetInventoryInput, ...func(*Options)) (*GetInventoryOutput, error) -} - -var _ GetInventoryAPIClient = (*Client)(nil) - -// GetInventoryPaginatorOptions is the paginator options for GetInventory -type GetInventoryPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetInventoryPaginator is a paginator for GetInventory -type GetInventoryPaginator struct { - options GetInventoryPaginatorOptions - client GetInventoryAPIClient - params *GetInventoryInput - nextToken *string - firstPage bool -} - -// NewGetInventoryPaginator returns a new GetInventoryPaginator -func NewGetInventoryPaginator(client GetInventoryAPIClient, params *GetInventoryInput, optFns ...func(*GetInventoryPaginatorOptions)) *GetInventoryPaginator { - if params == nil { - params = &GetInventoryInput{} - } - - options := GetInventoryPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetInventoryPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetInventoryPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetInventory page. -func (p *GetInventoryPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetInventoryOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetInventory(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetInventory(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetInventory", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventorySchema.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventorySchema.go deleted file mode 100644 index 9d422bd..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetInventorySchema.go +++ /dev/null @@ -1,245 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Return a list of inventory type names for the account, or return a list of -// attribute names for a specific Inventory item type. -func (c *Client) GetInventorySchema(ctx context.Context, params *GetInventorySchemaInput, optFns ...func(*Options)) (*GetInventorySchemaOutput, error) { - if params == nil { - params = &GetInventorySchemaInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetInventorySchema", params, optFns, c.addOperationGetInventorySchemaMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetInventorySchemaOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetInventorySchemaInput struct { - - // Returns inventory schemas that support aggregation. For example, this call - // returns the AWS:InstanceInformation type, because it supports aggregation based - // on the PlatformName , PlatformType , and PlatformVersion attributes. - Aggregator bool - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // Returns the sub-type schema for a specified inventory type. - SubType *bool - - // The type of inventory item to return. - TypeName *string - - noSmithyDocumentSerde -} - -type GetInventorySchemaOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Inventory schemas returned by the request. - Schemas []types.InventoryItemSchema - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetInventorySchemaMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetInventorySchema{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetInventorySchema{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetInventorySchema"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetInventorySchema(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetInventorySchemaAPIClient is a client that implements the GetInventorySchema -// operation. -type GetInventorySchemaAPIClient interface { - GetInventorySchema(context.Context, *GetInventorySchemaInput, ...func(*Options)) (*GetInventorySchemaOutput, error) -} - -var _ GetInventorySchemaAPIClient = (*Client)(nil) - -// GetInventorySchemaPaginatorOptions is the paginator options for -// GetInventorySchema -type GetInventorySchemaPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetInventorySchemaPaginator is a paginator for GetInventorySchema -type GetInventorySchemaPaginator struct { - options GetInventorySchemaPaginatorOptions - client GetInventorySchemaAPIClient - params *GetInventorySchemaInput - nextToken *string - firstPage bool -} - -// NewGetInventorySchemaPaginator returns a new GetInventorySchemaPaginator -func NewGetInventorySchemaPaginator(client GetInventorySchemaAPIClient, params *GetInventorySchemaInput, optFns ...func(*GetInventorySchemaPaginatorOptions)) *GetInventorySchemaPaginator { - if params == nil { - params = &GetInventorySchemaInput{} - } - - options := GetInventorySchemaPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetInventorySchemaPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetInventorySchemaPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetInventorySchema page. -func (p *GetInventorySchemaPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetInventorySchemaOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetInventorySchema(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetInventorySchema(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetInventorySchema", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindow.go deleted file mode 100644 index 2475014..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindow.go +++ /dev/null @@ -1,190 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Retrieves a maintenance window. -func (c *Client) GetMaintenanceWindow(ctx context.Context, params *GetMaintenanceWindowInput, optFns ...func(*Options)) (*GetMaintenanceWindowOutput, error) { - if params == nil { - params = &GetMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMaintenanceWindow", params, optFns, c.addOperationGetMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetMaintenanceWindowInput struct { - - // The ID of the maintenance window for which you want to retrieve information. - // - // This member is required. - WindowId *string - - noSmithyDocumentSerde -} - -type GetMaintenanceWindowOutput struct { - - // Whether targets must be registered with the maintenance window before tasks can - // be defined for those targets. - AllowUnassociatedTargets bool - - // The date the maintenance window was created. - CreatedDate *time.Time - - // The number of hours before the end of the maintenance window that Amazon Web - // Services Systems Manager stops scheduling new tasks for execution. - Cutoff int32 - - // The description of the maintenance window. - Description *string - - // The duration of the maintenance window in hours. - Duration *int32 - - // Indicates whether the maintenance window is enabled. - Enabled bool - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become inactive. The maintenance window won't run after this - // specified time. - EndDate *string - - // The date the maintenance window was last modified. - ModifiedDate *time.Time - - // The name of the maintenance window. - Name *string - - // The next time the maintenance window will actually run, taking into account any - // specified times for the maintenance window to become active or inactive. - NextExecutionTime *string - - // The schedule of the maintenance window in the form of a cron or rate expression. - Schedule *string - - // The number of days to wait to run a maintenance window after the scheduled cron - // expression date and time. - ScheduleOffset *int32 - - // The time zone that the scheduled maintenance window executions are based on, in - // Internet Assigned Numbers Authority (IANA) format. For example: - // "America/Los_Angeles", "UTC", or "Asia/Seoul". For more information, see the - // Time Zone Database (https://www.iana.org/time-zones) on the IANA website. - ScheduleTimezone *string - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become active. The maintenance window won't run before this - // specified time. - StartDate *string - - // The ID of the created maintenance window. - WindowId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecution.go deleted file mode 100644 index 9c46cf8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecution.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Retrieves details about a specific a maintenance window execution. -func (c *Client) GetMaintenanceWindowExecution(ctx context.Context, params *GetMaintenanceWindowExecutionInput, optFns ...func(*Options)) (*GetMaintenanceWindowExecutionOutput, error) { - if params == nil { - params = &GetMaintenanceWindowExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMaintenanceWindowExecution", params, optFns, c.addOperationGetMaintenanceWindowExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetMaintenanceWindowExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetMaintenanceWindowExecutionInput struct { - - // The ID of the maintenance window execution that includes the task. - // - // This member is required. - WindowExecutionId *string - - noSmithyDocumentSerde -} - -type GetMaintenanceWindowExecutionOutput struct { - - // The time the maintenance window finished running. - EndTime *time.Time - - // The time the maintenance window started running. - StartTime *time.Time - - // The status of the maintenance window execution. - Status types.MaintenanceWindowExecutionStatus - - // The details explaining the status. Not available for all status values. - StatusDetails *string - - // The ID of the task executions from the maintenance window execution. - TaskIds []string - - // The ID of the maintenance window execution. - WindowExecutionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetMaintenanceWindowExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetMaintenanceWindowExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetMaintenanceWindowExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetMaintenanceWindowExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetMaintenanceWindowExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetMaintenanceWindowExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetMaintenanceWindowExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetMaintenanceWindowExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTask.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTask.go deleted file mode 100644 index c7ffe97..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTask.go +++ /dev/null @@ -1,197 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Retrieves the details about a specific task run as part of a maintenance window -// execution. -func (c *Client) GetMaintenanceWindowExecutionTask(ctx context.Context, params *GetMaintenanceWindowExecutionTaskInput, optFns ...func(*Options)) (*GetMaintenanceWindowExecutionTaskOutput, error) { - if params == nil { - params = &GetMaintenanceWindowExecutionTaskInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMaintenanceWindowExecutionTask", params, optFns, c.addOperationGetMaintenanceWindowExecutionTaskMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetMaintenanceWindowExecutionTaskOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetMaintenanceWindowExecutionTaskInput struct { - - // The ID of the specific task execution in the maintenance window task that - // should be retrieved. - // - // This member is required. - TaskId *string - - // The ID of the maintenance window execution that includes the task. - // - // This member is required. - WindowExecutionId *string - - noSmithyDocumentSerde -} - -type GetMaintenanceWindowExecutionTaskOutput struct { - - // The details for the CloudWatch alarm you applied to your maintenance window - // task. - AlarmConfiguration *types.AlarmConfiguration - - // The time the task execution completed. - EndTime *time.Time - - // The defined maximum number of task executions that could be run in parallel. - MaxConcurrency *string - - // The defined maximum number of task execution errors allowed before scheduling - // of the task execution would have been stopped. - MaxErrors *string - - // The priority of the task. - Priority int32 - - // The role that was assumed when running the task. - ServiceRole *string - - // The time the task execution started. - StartTime *time.Time - - // The status of the task. - Status types.MaintenanceWindowExecutionStatus - - // The details explaining the status. Not available for all status values. - StatusDetails *string - - // The Amazon Resource Name (ARN) of the task that ran. - TaskArn *string - - // The ID of the specific task execution in the maintenance window task that was - // retrieved. - TaskExecutionId *string - - // The parameters passed to the task when it was run. TaskParameters has been - // deprecated. To specify parameters to pass to a task when it runs, instead use - // the Parameters option in the TaskInvocationParameters structure. For - // information about how Systems Manager handles these options for the supported - // maintenance window task types, see MaintenanceWindowTaskInvocationParameters . - // The map has the following format: - // - Key : string, between 1 and 255 characters - // - Value : an array of strings, each between 1 and 255 characters - TaskParameters []map[string]types.MaintenanceWindowTaskParameterValueExpression - - // The CloudWatch alarms that were invoked by the maintenance window task. - TriggeredAlarms []types.AlarmStateInformation - - // The type of task that was run. - Type types.MaintenanceWindowTaskType - - // The ID of the maintenance window execution that includes the task. - WindowExecutionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetMaintenanceWindowExecutionTaskMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTask{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTask{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetMaintenanceWindowExecutionTask"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetMaintenanceWindowExecutionTaskValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetMaintenanceWindowExecutionTask(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetMaintenanceWindowExecutionTask(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetMaintenanceWindowExecutionTask", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTaskInvocation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTaskInvocation.go deleted file mode 100644 index a1d96e4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowExecutionTaskInvocation.go +++ /dev/null @@ -1,185 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Retrieves information about a specific task running on a specific target. -func (c *Client) GetMaintenanceWindowExecutionTaskInvocation(ctx context.Context, params *GetMaintenanceWindowExecutionTaskInvocationInput, optFns ...func(*Options)) (*GetMaintenanceWindowExecutionTaskInvocationOutput, error) { - if params == nil { - params = &GetMaintenanceWindowExecutionTaskInvocationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMaintenanceWindowExecutionTaskInvocation", params, optFns, c.addOperationGetMaintenanceWindowExecutionTaskInvocationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetMaintenanceWindowExecutionTaskInvocationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetMaintenanceWindowExecutionTaskInvocationInput struct { - - // The invocation ID to retrieve. - // - // This member is required. - InvocationId *string - - // The ID of the specific task in the maintenance window task that should be - // retrieved. - // - // This member is required. - TaskId *string - - // The ID of the maintenance window execution for which the task is a part. - // - // This member is required. - WindowExecutionId *string - - noSmithyDocumentSerde -} - -type GetMaintenanceWindowExecutionTaskInvocationOutput struct { - - // The time that the task finished running on the target. - EndTime *time.Time - - // The execution ID. - ExecutionId *string - - // The invocation ID. - InvocationId *string - - // User-provided value to be included in any Amazon CloudWatch Events or Amazon - // EventBridge events raised while running tasks for these targets in this - // maintenance window. - OwnerInformation *string - - // The parameters used at the time that the task ran. - Parameters *string - - // The time that the task started running on the target. - StartTime *time.Time - - // The task status for an invocation. - Status types.MaintenanceWindowExecutionStatus - - // The details explaining the status. Details are only available for certain - // status values. - StatusDetails *string - - // The task execution ID. - TaskExecutionId *string - - // Retrieves the task type for a maintenance window. - TaskType types.MaintenanceWindowTaskType - - // The maintenance window execution ID. - WindowExecutionId *string - - // The maintenance window target ID. - WindowTargetId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetMaintenanceWindowExecutionTaskInvocationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTaskInvocation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTaskInvocation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetMaintenanceWindowExecutionTaskInvocation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetMaintenanceWindowExecutionTaskInvocationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetMaintenanceWindowExecutionTaskInvocation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetMaintenanceWindowExecutionTaskInvocation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetMaintenanceWindowExecutionTaskInvocation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowTask.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowTask.go deleted file mode 100644 index 12e5c11..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetMaintenanceWindowTask.go +++ /dev/null @@ -1,222 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the details of a maintenance window task. For maintenance window -// tasks without a specified target, you can't supply values for --max-errors and -// --max-concurrency . Instead, the system inserts a placeholder value of 1 , which -// may be reported in the response to this command. These values don't affect the -// running of your task and can be ignored. To retrieve a list of tasks in a -// maintenance window, instead use the DescribeMaintenanceWindowTasks command. -func (c *Client) GetMaintenanceWindowTask(ctx context.Context, params *GetMaintenanceWindowTaskInput, optFns ...func(*Options)) (*GetMaintenanceWindowTaskOutput, error) { - if params == nil { - params = &GetMaintenanceWindowTaskInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMaintenanceWindowTask", params, optFns, c.addOperationGetMaintenanceWindowTaskMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetMaintenanceWindowTaskOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetMaintenanceWindowTaskInput struct { - - // The maintenance window ID that includes the task to retrieve. - // - // This member is required. - WindowId *string - - // The maintenance window task ID to retrieve. - // - // This member is required. - WindowTaskId *string - - noSmithyDocumentSerde -} - -type GetMaintenanceWindowTaskOutput struct { - - // The details for the CloudWatch alarm you applied to your maintenance window - // task. - AlarmConfiguration *types.AlarmConfiguration - - // The action to take on tasks when the maintenance window cutoff time is reached. - // CONTINUE_TASK means that tasks continue to run. For Automation, Lambda, Step - // Functions tasks, CANCEL_TASK means that currently running task invocations - // continue, but no new task invocations are started. For Run Command tasks, - // CANCEL_TASK means the system attempts to stop the task by sending a - // CancelCommand operation. - CutoffBehavior types.MaintenanceWindowTaskCutoffBehavior - - // The retrieved task description. - Description *string - - // The location in Amazon Simple Storage Service (Amazon S3) where the task - // results are logged. LoggingInfo has been deprecated. To specify an Amazon - // Simple Storage Service (Amazon S3) bucket to contain logs, instead use the - // OutputS3BucketName and OutputS3KeyPrefix options in the TaskInvocationParameters - // structure. For information about how Amazon Web Services Systems Manager handles - // these options for the supported maintenance window task types, see - // MaintenanceWindowTaskInvocationParameters . - LoggingInfo *types.LoggingInfo - - // The maximum number of targets allowed to run this task in parallel. For - // maintenance window tasks without a target specified, you can't supply a value - // for this option. Instead, the system inserts a placeholder value of 1 , which - // may be reported in the response to this command. This value doesn't affect the - // running of your task and can be ignored. - MaxConcurrency *string - - // The maximum number of errors allowed before the task stops being scheduled. For - // maintenance window tasks without a target specified, you can't supply a value - // for this option. Instead, the system inserts a placeholder value of 1 , which - // may be reported in the response to this command. This value doesn't affect the - // running of your task and can be ignored. - MaxErrors *string - - // The retrieved task name. - Name *string - - // The priority of the task when it runs. The lower the number, the higher the - // priority. Tasks that have the same priority are scheduled in parallel. - Priority int32 - - // The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) - // service role to use to publish Amazon Simple Notification Service (Amazon SNS) - // notifications for maintenance window Run Command tasks. - ServiceRoleArn *string - - // The targets where the task should run. - Targets []types.Target - - // The resource that the task used during execution. For RUN_COMMAND and AUTOMATION - // task types, the value of TaskArn is the SSM document name/ARN. For LAMBDA - // tasks, the value is the function name/ARN. For STEP_FUNCTIONS tasks, the value - // is the state machine ARN. - TaskArn *string - - // The parameters to pass to the task when it runs. - TaskInvocationParameters *types.MaintenanceWindowTaskInvocationParameters - - // The parameters to pass to the task when it runs. TaskParameters has been - // deprecated. To specify parameters to pass to a task when it runs, instead use - // the Parameters option in the TaskInvocationParameters structure. For - // information about how Systems Manager handles these options for the supported - // maintenance window task types, see MaintenanceWindowTaskInvocationParameters . - TaskParameters map[string]types.MaintenanceWindowTaskParameterValueExpression - - // The type of task to run. - TaskType types.MaintenanceWindowTaskType - - // The retrieved maintenance window ID. - WindowId *string - - // The retrieved maintenance window task ID. - WindowTaskId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetMaintenanceWindowTaskMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetMaintenanceWindowTask{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetMaintenanceWindowTask{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetMaintenanceWindowTask"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetMaintenanceWindowTaskValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetMaintenanceWindowTask(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetMaintenanceWindowTask(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetMaintenanceWindowTask", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsItem.go deleted file mode 100644 index dbb5ed7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsItem.go +++ /dev/null @@ -1,148 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Get information about an OpsItem by using the ID. You must have permission in -// Identity and Access Management (IAM) to view information about an OpsItem. For -// more information, see Set up OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setup.html) -// in the Amazon Web Services Systems Manager User Guide. Operations engineers and -// IT professionals use Amazon Web Services Systems Manager OpsCenter to view, -// investigate, and remediate operational issues impacting the performance and -// health of their Amazon Web Services resources. For more information, see -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) GetOpsItem(ctx context.Context, params *GetOpsItemInput, optFns ...func(*Options)) (*GetOpsItemOutput, error) { - if params == nil { - params = &GetOpsItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetOpsItem", params, optFns, c.addOperationGetOpsItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetOpsItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetOpsItemInput struct { - - // The ID of the OpsItem that you want to get. - // - // This member is required. - OpsItemId *string - - // The OpsItem Amazon Resource Name (ARN). - OpsItemArn *string - - noSmithyDocumentSerde -} - -type GetOpsItemOutput struct { - - // The OpsItem. - OpsItem *types.OpsItem - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetOpsItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetOpsItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetOpsItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetOpsItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetOpsItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetOpsItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetOpsItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetOpsItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsMetadata.go deleted file mode 100644 index 5a5f22a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsMetadata.go +++ /dev/null @@ -1,151 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// View operational metadata related to an application in Application Manager. -func (c *Client) GetOpsMetadata(ctx context.Context, params *GetOpsMetadataInput, optFns ...func(*Options)) (*GetOpsMetadataOutput, error) { - if params == nil { - params = &GetOpsMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetOpsMetadata", params, optFns, c.addOperationGetOpsMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetOpsMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetOpsMetadataInput struct { - - // The Amazon Resource Name (ARN) of an OpsMetadata Object to view. - // - // This member is required. - OpsMetadataArn *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type GetOpsMetadataOutput struct { - - // OpsMetadata for an Application Manager application. - Metadata map[string]types.MetadataValue - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // The resource ID of the Application Manager application. - ResourceId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetOpsMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetOpsMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetOpsMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetOpsMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetOpsMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetOpsMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetOpsMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetOpsMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsSummary.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsSummary.go deleted file mode 100644 index 6055903..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetOpsSummary.go +++ /dev/null @@ -1,250 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// View a summary of operations metadata (OpsData) based on specified filters and -// aggregators. OpsData can include information about Amazon Web Services Systems -// Manager OpsCenter operational workitems (OpsItems) as well as information about -// any Amazon Web Services resource or service configured to report OpsData to -// Amazon Web Services Systems Manager Explorer. -func (c *Client) GetOpsSummary(ctx context.Context, params *GetOpsSummaryInput, optFns ...func(*Options)) (*GetOpsSummaryOutput, error) { - if params == nil { - params = &GetOpsSummaryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetOpsSummary", params, optFns, c.addOperationGetOpsSummaryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetOpsSummaryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetOpsSummaryInput struct { - - // Optional aggregators that return counts of OpsData based on one or more - // expressions. - Aggregators []types.OpsAggregator - - // Optional filters used to scope down the returned OpsData. - Filters []types.OpsFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - // The OpsData data type to return. - ResultAttributes []types.OpsResultAttribute - - // Specify the name of a resource data sync to get. - SyncName *string - - noSmithyDocumentSerde -} - -type GetOpsSummaryOutput struct { - - // The list of aggregated details and filtered OpsData. - Entities []types.OpsEntity - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetOpsSummaryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetOpsSummary{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetOpsSummary{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetOpsSummary"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetOpsSummaryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetOpsSummary(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetOpsSummaryAPIClient is a client that implements the GetOpsSummary operation. -type GetOpsSummaryAPIClient interface { - GetOpsSummary(context.Context, *GetOpsSummaryInput, ...func(*Options)) (*GetOpsSummaryOutput, error) -} - -var _ GetOpsSummaryAPIClient = (*Client)(nil) - -// GetOpsSummaryPaginatorOptions is the paginator options for GetOpsSummary -type GetOpsSummaryPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetOpsSummaryPaginator is a paginator for GetOpsSummary -type GetOpsSummaryPaginator struct { - options GetOpsSummaryPaginatorOptions - client GetOpsSummaryAPIClient - params *GetOpsSummaryInput - nextToken *string - firstPage bool -} - -// NewGetOpsSummaryPaginator returns a new GetOpsSummaryPaginator -func NewGetOpsSummaryPaginator(client GetOpsSummaryAPIClient, params *GetOpsSummaryInput, optFns ...func(*GetOpsSummaryPaginatorOptions)) *GetOpsSummaryPaginator { - if params == nil { - params = &GetOpsSummaryInput{} - } - - options := GetOpsSummaryPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetOpsSummaryPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetOpsSummaryPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetOpsSummary page. -func (p *GetOpsSummaryPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetOpsSummaryOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetOpsSummary(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetOpsSummary(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetOpsSummary", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameter.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameter.go deleted file mode 100644 index 75aaa16..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameter.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Get information about a single parameter by specifying the parameter name. To -// get information about more than one parameter at a time, use the GetParameters -// operation. -func (c *Client) GetParameter(ctx context.Context, params *GetParameterInput, optFns ...func(*Options)) (*GetParameterOutput, error) { - if params == nil { - params = &GetParameterInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetParameter", params, optFns, c.addOperationGetParameterMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetParameterOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetParameterInput struct { - - // The name of the parameter you want to query. To query by parameter label, use - // "Name": "name:label" . To query by parameter version, use "Name": "name:version" - // . - // - // This member is required. - Name *string - - // Return decrypted values for secure string parameters. This flag is ignored for - // String and StringList parameter types. - WithDecryption *bool - - noSmithyDocumentSerde -} - -type GetParameterOutput struct { - - // Information about a parameter. - Parameter *types.Parameter - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetParameterMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetParameter{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetParameter{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetParameter"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetParameterValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetParameter(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetParameter(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetParameter", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameterHistory.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameterHistory.go deleted file mode 100644 index cd99f0c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameterHistory.go +++ /dev/null @@ -1,248 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the history of all changes to a parameter. If you change the KMS key -// alias for the KMS key used to encrypt a parameter, then you must also update the -// key alias the parameter uses to reference KMS. Otherwise, GetParameterHistory -// retrieves whatever the original key alias was referencing. -func (c *Client) GetParameterHistory(ctx context.Context, params *GetParameterHistoryInput, optFns ...func(*Options)) (*GetParameterHistoryOutput, error) { - if params == nil { - params = &GetParameterHistoryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetParameterHistory", params, optFns, c.addOperationGetParameterHistoryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetParameterHistoryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetParameterHistoryInput struct { - - // The name of the parameter for which you want to review history. - // - // This member is required. - Name *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // Return decrypted values for secure string parameters. This flag is ignored for - // String and StringList parameter types. - WithDecryption *bool - - noSmithyDocumentSerde -} - -type GetParameterHistoryOutput struct { - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // A list of parameters returned by the request. - Parameters []types.ParameterHistory - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetParameterHistoryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetParameterHistory{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetParameterHistory{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetParameterHistory"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetParameterHistoryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetParameterHistory(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetParameterHistoryAPIClient is a client that implements the -// GetParameterHistory operation. -type GetParameterHistoryAPIClient interface { - GetParameterHistory(context.Context, *GetParameterHistoryInput, ...func(*Options)) (*GetParameterHistoryOutput, error) -} - -var _ GetParameterHistoryAPIClient = (*Client)(nil) - -// GetParameterHistoryPaginatorOptions is the paginator options for -// GetParameterHistory -type GetParameterHistoryPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetParameterHistoryPaginator is a paginator for GetParameterHistory -type GetParameterHistoryPaginator struct { - options GetParameterHistoryPaginatorOptions - client GetParameterHistoryAPIClient - params *GetParameterHistoryInput - nextToken *string - firstPage bool -} - -// NewGetParameterHistoryPaginator returns a new GetParameterHistoryPaginator -func NewGetParameterHistoryPaginator(client GetParameterHistoryAPIClient, params *GetParameterHistoryInput, optFns ...func(*GetParameterHistoryPaginatorOptions)) *GetParameterHistoryPaginator { - if params == nil { - params = &GetParameterHistoryInput{} - } - - options := GetParameterHistoryPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetParameterHistoryPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetParameterHistoryPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetParameterHistory page. -func (p *GetParameterHistoryPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetParameterHistoryOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetParameterHistory(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetParameterHistory(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetParameterHistory", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameters.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameters.go deleted file mode 100644 index 7fabdaf..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParameters.go +++ /dev/null @@ -1,149 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Get information about one or more parameters by specifying multiple parameter -// names. To get information about a single parameter, you can use the GetParameter -// operation instead. -func (c *Client) GetParameters(ctx context.Context, params *GetParametersInput, optFns ...func(*Options)) (*GetParametersOutput, error) { - if params == nil { - params = &GetParametersInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetParameters", params, optFns, c.addOperationGetParametersMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetParametersOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetParametersInput struct { - - // Names of the parameters for which you want to query information. To query by - // parameter label, use "Name": "name:label" . To query by parameter version, use - // "Name": "name:version" . - // - // This member is required. - Names []string - - // Return decrypted secure string value. Return decrypted values for secure string - // parameters. This flag is ignored for String and StringList parameter types. - WithDecryption *bool - - noSmithyDocumentSerde -} - -type GetParametersOutput struct { - - // A list of parameters that aren't formatted correctly or don't run during an - // execution. - InvalidParameters []string - - // A list of details for a parameter. - Parameters []types.Parameter - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetParametersMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetParameters{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetParameters{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetParameters"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetParametersValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetParameters(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetParameters(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetParameters", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParametersByPath.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParametersByPath.go deleted file mode 100644 index 50c4400..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetParametersByPath.go +++ /dev/null @@ -1,268 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieve information about one or more parameters in a specific hierarchy. -// Request results are returned on a best-effort basis. If you specify MaxResults -// in the request, the response includes information up to the limit specified. The -// number of items returned, however, can be between zero and the value of -// MaxResults . If the service reaches an internal limit while processing the -// results, it stops the operation and returns the matching values up to that point -// and a NextToken . You can specify the NextToken in a subsequent call to get the -// next set of results. -func (c *Client) GetParametersByPath(ctx context.Context, params *GetParametersByPathInput, optFns ...func(*Options)) (*GetParametersByPathOutput, error) { - if params == nil { - params = &GetParametersByPathInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetParametersByPath", params, optFns, c.addOperationGetParametersByPathMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetParametersByPathOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetParametersByPathInput struct { - - // The hierarchy for the parameter. Hierarchies start with a forward slash (/). - // The hierarchy is the parameter name except the last part of the parameter. For - // the API call to succeed, the last part of the parameter name can't be in the - // path. A parameter name hierarchy can have a maximum of 15 levels. Here is an - // example of a hierarchy: /Finance/Prod/IAD/WinServ2016/license33 - // - // This member is required. - Path *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - // Filters to limit the request results. The following Key values are supported - // for GetParametersByPath : Type , KeyId , and Label . The following Key values - // aren't supported for GetParametersByPath : tag , DataType , Name , Path , and - // Tier . - ParameterFilters []types.ParameterStringFilter - - // Retrieve all parameters within a hierarchy. If a user has access to a path, - // then the user can access all levels of that path. For example, if a user has - // permission to access path /a , then the user can also access /a/b . Even if a - // user has explicitly been denied access in IAM for parameter /a/b , they can - // still call the GetParametersByPath API operation recursively for /a and view - // /a/b . - Recursive *bool - - // Retrieve all parameters in a hierarchy with their value decrypted. - WithDecryption *bool - - noSmithyDocumentSerde -} - -type GetParametersByPathOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A list of parameters found in the specified hierarchy. - Parameters []types.Parameter - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetParametersByPathMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetParametersByPath{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetParametersByPath{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetParametersByPath"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetParametersByPathValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetParametersByPath(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetParametersByPathAPIClient is a client that implements the -// GetParametersByPath operation. -type GetParametersByPathAPIClient interface { - GetParametersByPath(context.Context, *GetParametersByPathInput, ...func(*Options)) (*GetParametersByPathOutput, error) -} - -var _ GetParametersByPathAPIClient = (*Client)(nil) - -// GetParametersByPathPaginatorOptions is the paginator options for -// GetParametersByPath -type GetParametersByPathPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetParametersByPathPaginator is a paginator for GetParametersByPath -type GetParametersByPathPaginator struct { - options GetParametersByPathPaginatorOptions - client GetParametersByPathAPIClient - params *GetParametersByPathInput - nextToken *string - firstPage bool -} - -// NewGetParametersByPathPaginator returns a new GetParametersByPathPaginator -func NewGetParametersByPathPaginator(client GetParametersByPathAPIClient, params *GetParametersByPathInput, optFns ...func(*GetParametersByPathPaginatorOptions)) *GetParametersByPathPaginator { - if params == nil { - params = &GetParametersByPathInput{} - } - - options := GetParametersByPathPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetParametersByPathPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetParametersByPathPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetParametersByPath page. -func (p *GetParametersByPathPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetParametersByPathOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetParametersByPath(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetParametersByPath(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetParametersByPath", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaseline.go deleted file mode 100644 index 667c52c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaseline.go +++ /dev/null @@ -1,192 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Retrieves information about a patch baseline. -func (c *Client) GetPatchBaseline(ctx context.Context, params *GetPatchBaselineInput, optFns ...func(*Options)) (*GetPatchBaselineOutput, error) { - if params == nil { - params = &GetPatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetPatchBaseline", params, optFns, c.addOperationGetPatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetPatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetPatchBaselineInput struct { - - // The ID of the patch baseline to retrieve. To retrieve information about an - // Amazon Web Services managed patch baseline, specify the full Amazon Resource - // Name (ARN) of the baseline. For example, for the baseline - // AWS-AmazonLinuxDefaultPatchBaseline , specify - // arn:aws:ssm:us-east-2:733109147000:patchbaseline/pb-0e392de35e7c563b7 instead of - // pb-0e392de35e7c563b7 . - // - // This member is required. - BaselineId *string - - noSmithyDocumentSerde -} - -type GetPatchBaselineOutput struct { - - // A set of rules used to include patches in the baseline. - ApprovalRules *types.PatchRuleGroup - - // A list of explicitly approved patches for the baseline. - ApprovedPatches []string - - // Returns the specified compliance severity level for approved patches in the - // patch baseline. - ApprovedPatchesComplianceLevel types.PatchComplianceLevel - - // Indicates whether the list of approved patches includes non-security updates - // that should be applied to the managed nodes. The default value is false . - // Applies to Linux managed nodes only. - ApprovedPatchesEnableNonSecurity *bool - - // The ID of the retrieved patch baseline. - BaselineId *string - - // The date the patch baseline was created. - CreatedDate *time.Time - - // A description of the patch baseline. - Description *string - - // A set of global filters used to exclude patches from the baseline. - GlobalFilters *types.PatchFilterGroup - - // The date the patch baseline was last modified. - ModifiedDate *time.Time - - // The name of the patch baseline. - Name *string - - // Returns the operating system specified for the patch baseline. - OperatingSystem types.OperatingSystem - - // Patch groups included in the patch baseline. - PatchGroups []string - - // A list of explicitly rejected patches for the baseline. - RejectedPatches []string - - // The action specified to take on patches included in the RejectedPatches list. A - // patch can be allowed only if it is a dependency of another package, or blocked - // entirely along with packages that include it as a dependency. - RejectedPatchesAction types.PatchAction - - // Information about the patches to use to update the managed nodes, including - // target operating systems and source repositories. Applies to Linux managed nodes - // only. - Sources []types.PatchSource - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetPatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetPatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetPatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetPatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetPatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetPatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetPatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetPatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaselineForPatchGroup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaselineForPatchGroup.go deleted file mode 100644 index e78f168..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetPatchBaselineForPatchGroup.go +++ /dev/null @@ -1,147 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves the patch baseline that should be used for the specified patch group. -func (c *Client) GetPatchBaselineForPatchGroup(ctx context.Context, params *GetPatchBaselineForPatchGroupInput, optFns ...func(*Options)) (*GetPatchBaselineForPatchGroupOutput, error) { - if params == nil { - params = &GetPatchBaselineForPatchGroupInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetPatchBaselineForPatchGroup", params, optFns, c.addOperationGetPatchBaselineForPatchGroupMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetPatchBaselineForPatchGroupOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetPatchBaselineForPatchGroupInput struct { - - // The name of the patch group whose patch baseline should be retrieved. - // - // This member is required. - PatchGroup *string - - // Returns the operating system rule specified for patch groups using the patch - // baseline. - OperatingSystem types.OperatingSystem - - noSmithyDocumentSerde -} - -type GetPatchBaselineForPatchGroupOutput struct { - - // The ID of the patch baseline that should be used for the patch group. - BaselineId *string - - // The operating system rule specified for patch groups using the patch baseline. - OperatingSystem types.OperatingSystem - - // The name of the patch group. - PatchGroup *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetPatchBaselineForPatchGroupMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetPatchBaselineForPatchGroup"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetPatchBaselineForPatchGroupValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetPatchBaselineForPatchGroup(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetPatchBaselineForPatchGroup(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetPatchBaselineForPatchGroup", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetResourcePolicies.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetResourcePolicies.go deleted file mode 100644 index aead927..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetResourcePolicies.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns an array of the Policy object. -func (c *Client) GetResourcePolicies(ctx context.Context, params *GetResourcePoliciesInput, optFns ...func(*Options)) (*GetResourcePoliciesOutput, error) { - if params == nil { - params = &GetResourcePoliciesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetResourcePolicies", params, optFns, c.addOperationGetResourcePoliciesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetResourcePoliciesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetResourcePoliciesInput struct { - - // Amazon Resource Name (ARN) of the resource to which the policies are attached. - // - // This member is required. - ResourceArn *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type GetResourcePoliciesOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // An array of the Policy object. - Policies []types.GetResourcePoliciesResponseEntry - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetResourcePoliciesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetResourcePolicies{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetResourcePolicies{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetResourcePolicies"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetResourcePoliciesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetResourcePolicies(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// GetResourcePoliciesAPIClient is a client that implements the -// GetResourcePolicies operation. -type GetResourcePoliciesAPIClient interface { - GetResourcePolicies(context.Context, *GetResourcePoliciesInput, ...func(*Options)) (*GetResourcePoliciesOutput, error) -} - -var _ GetResourcePoliciesAPIClient = (*Client)(nil) - -// GetResourcePoliciesPaginatorOptions is the paginator options for -// GetResourcePolicies -type GetResourcePoliciesPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// GetResourcePoliciesPaginator is a paginator for GetResourcePolicies -type GetResourcePoliciesPaginator struct { - options GetResourcePoliciesPaginatorOptions - client GetResourcePoliciesAPIClient - params *GetResourcePoliciesInput - nextToken *string - firstPage bool -} - -// NewGetResourcePoliciesPaginator returns a new GetResourcePoliciesPaginator -func NewGetResourcePoliciesPaginator(client GetResourcePoliciesAPIClient, params *GetResourcePoliciesInput, optFns ...func(*GetResourcePoliciesPaginatorOptions)) *GetResourcePoliciesPaginator { - if params == nil { - params = &GetResourcePoliciesInput{} - } - - options := GetResourcePoliciesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &GetResourcePoliciesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *GetResourcePoliciesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next GetResourcePolicies page. -func (p *GetResourcePoliciesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*GetResourcePoliciesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.GetResourcePolicies(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opGetResourcePolicies(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetResourcePolicies", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetServiceSetting.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetServiceSetting.go deleted file mode 100644 index 3f8ec2d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_GetServiceSetting.go +++ /dev/null @@ -1,161 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ServiceSetting is an account-level setting for an Amazon Web Services service. -// This setting defines how a user interacts with or uses a service or a feature of -// a service. For example, if an Amazon Web Services service charges money to the -// account based on feature or service usage, then the Amazon Web Services service -// team might create a default setting of false . This means the user can't use -// this feature unless they change the setting to true and intentionally opt in -// for a paid feature. Services map a SettingId object to a setting value. Amazon -// Web Services services teams define the default value for a SettingId . You can't -// create a new SettingId , but you can overwrite the default value if you have the -// ssm:UpdateServiceSetting permission for the setting. Use the -// UpdateServiceSetting API operation to change the default setting. Or use the -// ResetServiceSetting to change the value back to the original value defined by -// the Amazon Web Services service team. Query the current service setting for the -// Amazon Web Services account. -func (c *Client) GetServiceSetting(ctx context.Context, params *GetServiceSettingInput, optFns ...func(*Options)) (*GetServiceSettingOutput, error) { - if params == nil { - params = &GetServiceSettingInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetServiceSetting", params, optFns, c.addOperationGetServiceSettingMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetServiceSettingOutput) - out.ResultMetadata = metadata - return out, nil -} - -// The request body of the GetServiceSetting API operation. -type GetServiceSettingInput struct { - - // The ID of the service setting to get. The setting ID can be one of the - // following. - // - /ssm/managed-instance/default-ec2-instance-management-role - // - /ssm/automation/customer-script-log-destination - // - /ssm/automation/customer-script-log-group-name - // - /ssm/documents/console/public-sharing-permission - // - /ssm/managed-instance/activation-tier - // - /ssm/opsinsights/opscenter - // - /ssm/parameter-store/default-parameter-tier - // - /ssm/parameter-store/high-throughput-enabled - // - // This member is required. - SettingId *string - - noSmithyDocumentSerde -} - -// The query result body of the GetServiceSetting API operation. -type GetServiceSettingOutput struct { - - // The query result of the current service setting. - ServiceSetting *types.ServiceSetting - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetServiceSettingMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetServiceSetting{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpGetServiceSetting{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetServiceSetting"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpGetServiceSettingValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetServiceSetting(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetServiceSetting(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetServiceSetting", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_LabelParameterVersion.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_LabelParameterVersion.go deleted file mode 100644 index 32a9c5a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_LabelParameterVersion.go +++ /dev/null @@ -1,170 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// A parameter label is a user-defined alias to help you manage different versions -// of a parameter. When you modify a parameter, Amazon Web Services Systems Manager -// automatically saves a new version and increments the version number by one. A -// label can help you remember the purpose of a parameter when there are multiple -// versions. Parameter labels have the following requirements and restrictions. -// - A version of a parameter can have a maximum of 10 labels. -// - You can't attach the same label to different versions of the same -// parameter. For example, if version 1 has the label Production, then you can't -// attach Production to version 2. -// - You can move a label from one version of a parameter to another. -// - You can't create a label when you create a new parameter. You must attach a -// label to a specific version of a parameter. -// - If you no longer want to use a parameter label, then you can either delete -// it or move it to a different version of a parameter. -// - A label can have a maximum of 100 characters. -// - Labels can contain letters (case sensitive), numbers, periods (.), hyphens -// (-), or underscores (_). -// - Labels can't begin with a number, " aws " or " ssm " (not case sensitive). -// If a label fails to meet these requirements, then the label isn't associated -// with a parameter and the system displays it in the list of InvalidLabels. -func (c *Client) LabelParameterVersion(ctx context.Context, params *LabelParameterVersionInput, optFns ...func(*Options)) (*LabelParameterVersionOutput, error) { - if params == nil { - params = &LabelParameterVersionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "LabelParameterVersion", params, optFns, c.addOperationLabelParameterVersionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*LabelParameterVersionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type LabelParameterVersionInput struct { - - // One or more labels to attach to the specified parameter version. - // - // This member is required. - Labels []string - - // The parameter name on which you want to attach one or more labels. - // - // This member is required. - Name *string - - // The specific version of the parameter on which you want to attach one or more - // labels. If no version is specified, the system attaches the label to the latest - // version. - ParameterVersion *int64 - - noSmithyDocumentSerde -} - -type LabelParameterVersionOutput struct { - - // The label doesn't meet the requirements. For information about parameter label - // requirements, see Labeling parameters (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-labels.html) - // in the Amazon Web Services Systems Manager User Guide. - InvalidLabels []string - - // The version of the parameter that has been labeled. - ParameterVersion int64 - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationLabelParameterVersionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpLabelParameterVersion{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpLabelParameterVersion{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "LabelParameterVersion"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpLabelParameterVersionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opLabelParameterVersion(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opLabelParameterVersion(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "LabelParameterVersion", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociationVersions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociationVersions.go deleted file mode 100644 index 4ab028e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociationVersions.go +++ /dev/null @@ -1,242 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Retrieves all versions of an association for a specific association ID. -func (c *Client) ListAssociationVersions(ctx context.Context, params *ListAssociationVersionsInput, optFns ...func(*Options)) (*ListAssociationVersionsOutput, error) { - if params == nil { - params = &ListAssociationVersionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListAssociationVersions", params, optFns, c.addOperationListAssociationVersionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListAssociationVersionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListAssociationVersionsInput struct { - - // The association ID for which you want to view all versions. - // - // This member is required. - AssociationId *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type ListAssociationVersionsOutput struct { - - // Information about all versions of the association for the specified association - // ID. - AssociationVersions []types.AssociationVersionInfo - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListAssociationVersionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListAssociationVersions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListAssociationVersions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListAssociationVersions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListAssociationVersionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListAssociationVersions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListAssociationVersionsAPIClient is a client that implements the -// ListAssociationVersions operation. -type ListAssociationVersionsAPIClient interface { - ListAssociationVersions(context.Context, *ListAssociationVersionsInput, ...func(*Options)) (*ListAssociationVersionsOutput, error) -} - -var _ ListAssociationVersionsAPIClient = (*Client)(nil) - -// ListAssociationVersionsPaginatorOptions is the paginator options for -// ListAssociationVersions -type ListAssociationVersionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListAssociationVersionsPaginator is a paginator for ListAssociationVersions -type ListAssociationVersionsPaginator struct { - options ListAssociationVersionsPaginatorOptions - client ListAssociationVersionsAPIClient - params *ListAssociationVersionsInput - nextToken *string - firstPage bool -} - -// NewListAssociationVersionsPaginator returns a new -// ListAssociationVersionsPaginator -func NewListAssociationVersionsPaginator(client ListAssociationVersionsAPIClient, params *ListAssociationVersionsInput, optFns ...func(*ListAssociationVersionsPaginatorOptions)) *ListAssociationVersionsPaginator { - if params == nil { - params = &ListAssociationVersionsInput{} - } - - options := ListAssociationVersionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListAssociationVersionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListAssociationVersionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListAssociationVersions page. -func (p *ListAssociationVersionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListAssociationVersionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListAssociationVersions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListAssociationVersions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListAssociationVersions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociations.go deleted file mode 100644 index e9224d6..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListAssociations.go +++ /dev/null @@ -1,245 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns all State Manager associations in the current Amazon Web Services -// account and Amazon Web Services Region. You can limit the results to a specific -// State Manager association document or managed node by specifying a filter. State -// Manager is a capability of Amazon Web Services Systems Manager. -func (c *Client) ListAssociations(ctx context.Context, params *ListAssociationsInput, optFns ...func(*Options)) (*ListAssociationsOutput, error) { - if params == nil { - params = &ListAssociationsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListAssociations", params, optFns, c.addOperationListAssociationsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListAssociationsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListAssociationsInput struct { - - // One or more filters. Use a filter to return a more specific list of results. - // Filtering associations using the InstanceID attribute only returns legacy - // associations created using the InstanceID attribute. Associations targeting the - // managed node that are part of the Target Attributes ResourceGroup or Tags - // aren't returned. - AssociationFilterList []types.AssociationFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListAssociationsOutput struct { - - // The associations. - Associations []types.Association - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListAssociationsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListAssociations{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListAssociations{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListAssociations"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListAssociationsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListAssociations(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListAssociationsAPIClient is a client that implements the ListAssociations -// operation. -type ListAssociationsAPIClient interface { - ListAssociations(context.Context, *ListAssociationsInput, ...func(*Options)) (*ListAssociationsOutput, error) -} - -var _ ListAssociationsAPIClient = (*Client)(nil) - -// ListAssociationsPaginatorOptions is the paginator options for ListAssociations -type ListAssociationsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListAssociationsPaginator is a paginator for ListAssociations -type ListAssociationsPaginator struct { - options ListAssociationsPaginatorOptions - client ListAssociationsAPIClient - params *ListAssociationsInput - nextToken *string - firstPage bool -} - -// NewListAssociationsPaginator returns a new ListAssociationsPaginator -func NewListAssociationsPaginator(client ListAssociationsAPIClient, params *ListAssociationsInput, optFns ...func(*ListAssociationsPaginatorOptions)) *ListAssociationsPaginator { - if params == nil { - params = &ListAssociationsInput{} - } - - options := ListAssociationsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListAssociationsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListAssociationsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListAssociations page. -func (p *ListAssociationsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListAssociationsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListAssociations(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListAssociations(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListAssociations", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommandInvocations.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommandInvocations.go deleted file mode 100644 index 26d062d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommandInvocations.go +++ /dev/null @@ -1,256 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// An invocation is copy of a command sent to a specific managed node. A command -// can apply to one or more managed nodes. A command invocation applies to one -// managed node. For example, if a user runs SendCommand against three managed -// nodes, then a command invocation is created for each requested managed node ID. -// ListCommandInvocations provide status about command execution. -func (c *Client) ListCommandInvocations(ctx context.Context, params *ListCommandInvocationsInput, optFns ...func(*Options)) (*ListCommandInvocationsOutput, error) { - if params == nil { - params = &ListCommandInvocationsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListCommandInvocations", params, optFns, c.addOperationListCommandInvocationsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListCommandInvocationsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListCommandInvocationsInput struct { - - // (Optional) The invocations for a specific command ID. - CommandId *string - - // (Optional) If set this returns the response of the command executions and any - // command output. The default value is false . - Details bool - - // (Optional) One or more filters. Use a filter to return a more specific list of - // results. - Filters []types.CommandFilter - - // (Optional) The command execution details for a specific managed node ID. - InstanceId *string - - // (Optional) The maximum number of items to return for this call. The call also - // returns a token that you can specify in a subsequent call to get the next set of - // results. - MaxResults *int32 - - // (Optional) The token for the next set of items to return. (You received this - // token from a previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListCommandInvocationsOutput struct { - - // (Optional) A list of all invocations. - CommandInvocations []types.CommandInvocation - - // (Optional) The token for the next set of items to return. (You received this - // token from a previous call.) - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListCommandInvocationsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListCommandInvocations{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListCommandInvocations{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListCommandInvocations"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListCommandInvocationsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListCommandInvocations(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListCommandInvocationsAPIClient is a client that implements the -// ListCommandInvocations operation. -type ListCommandInvocationsAPIClient interface { - ListCommandInvocations(context.Context, *ListCommandInvocationsInput, ...func(*Options)) (*ListCommandInvocationsOutput, error) -} - -var _ ListCommandInvocationsAPIClient = (*Client)(nil) - -// ListCommandInvocationsPaginatorOptions is the paginator options for -// ListCommandInvocations -type ListCommandInvocationsPaginatorOptions struct { - // (Optional) The maximum number of items to return for this call. The call also - // returns a token that you can specify in a subsequent call to get the next set of - // results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListCommandInvocationsPaginator is a paginator for ListCommandInvocations -type ListCommandInvocationsPaginator struct { - options ListCommandInvocationsPaginatorOptions - client ListCommandInvocationsAPIClient - params *ListCommandInvocationsInput - nextToken *string - firstPage bool -} - -// NewListCommandInvocationsPaginator returns a new ListCommandInvocationsPaginator -func NewListCommandInvocationsPaginator(client ListCommandInvocationsAPIClient, params *ListCommandInvocationsInput, optFns ...func(*ListCommandInvocationsPaginatorOptions)) *ListCommandInvocationsPaginator { - if params == nil { - params = &ListCommandInvocationsInput{} - } - - options := ListCommandInvocationsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListCommandInvocationsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListCommandInvocationsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListCommandInvocations page. -func (p *ListCommandInvocationsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListCommandInvocationsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListCommandInvocations(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListCommandInvocations(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListCommandInvocations", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommands.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommands.go deleted file mode 100644 index 78af404..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListCommands.go +++ /dev/null @@ -1,248 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists the commands requested by users of the Amazon Web Services account. -func (c *Client) ListCommands(ctx context.Context, params *ListCommandsInput, optFns ...func(*Options)) (*ListCommandsOutput, error) { - if params == nil { - params = &ListCommandsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListCommands", params, optFns, c.addOperationListCommandsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListCommandsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListCommandsInput struct { - - // (Optional) If provided, lists only the specified command. - CommandId *string - - // (Optional) One or more filters. Use a filter to return a more specific list of - // results. - Filters []types.CommandFilter - - // (Optional) Lists commands issued against this managed node ID. You can't - // specify a managed node ID in the same command that you specify Status = Pending - // . This is because the command hasn't reached the managed node yet. - InstanceId *string - - // (Optional) The maximum number of items to return for this call. The call also - // returns a token that you can specify in a subsequent call to get the next set of - // results. - MaxResults *int32 - - // (Optional) The token for the next set of items to return. (You received this - // token from a previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListCommandsOutput struct { - - // (Optional) The list of commands requested by the user. - Commands []types.Command - - // (Optional) The token for the next set of items to return. (You received this - // token from a previous call.) - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListCommandsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListCommands{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListCommands{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListCommands"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListCommandsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListCommands(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListCommandsAPIClient is a client that implements the ListCommands operation. -type ListCommandsAPIClient interface { - ListCommands(context.Context, *ListCommandsInput, ...func(*Options)) (*ListCommandsOutput, error) -} - -var _ ListCommandsAPIClient = (*Client)(nil) - -// ListCommandsPaginatorOptions is the paginator options for ListCommands -type ListCommandsPaginatorOptions struct { - // (Optional) The maximum number of items to return for this call. The call also - // returns a token that you can specify in a subsequent call to get the next set of - // results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListCommandsPaginator is a paginator for ListCommands -type ListCommandsPaginator struct { - options ListCommandsPaginatorOptions - client ListCommandsAPIClient - params *ListCommandsInput - nextToken *string - firstPage bool -} - -// NewListCommandsPaginator returns a new ListCommandsPaginator -func NewListCommandsPaginator(client ListCommandsAPIClient, params *ListCommandsInput, optFns ...func(*ListCommandsPaginatorOptions)) *ListCommandsPaginator { - if params == nil { - params = &ListCommandsInput{} - } - - options := ListCommandsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListCommandsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListCommandsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListCommands page. -func (p *ListCommandsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListCommandsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListCommands(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListCommands(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListCommands", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceItems.go deleted file mode 100644 index c0daf81..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceItems.go +++ /dev/null @@ -1,247 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// For a specified resource ID, this API operation returns a list of compliance -// statuses for different resource types. Currently, you can only specify one -// resource ID per call. List results depend on the criteria specified in the -// filter. -func (c *Client) ListComplianceItems(ctx context.Context, params *ListComplianceItemsInput, optFns ...func(*Options)) (*ListComplianceItemsOutput, error) { - if params == nil { - params = &ListComplianceItemsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListComplianceItems", params, optFns, c.addOperationListComplianceItemsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListComplianceItemsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListComplianceItemsInput struct { - - // One or more compliance filters. Use a filter to return a more specific list of - // results. - Filters []types.ComplianceStringFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - // The ID for the resources from which to get compliance information. Currently, - // you can only specify one resource ID. - ResourceIds []string - - // The type of resource from which to get compliance information. Currently, the - // only supported resource type is ManagedInstance . - ResourceTypes []string - - noSmithyDocumentSerde -} - -type ListComplianceItemsOutput struct { - - // A list of compliance information for the specified resource ID. - ComplianceItems []types.ComplianceItem - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListComplianceItemsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListComplianceItems{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListComplianceItems{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListComplianceItems"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListComplianceItems(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListComplianceItemsAPIClient is a client that implements the -// ListComplianceItems operation. -type ListComplianceItemsAPIClient interface { - ListComplianceItems(context.Context, *ListComplianceItemsInput, ...func(*Options)) (*ListComplianceItemsOutput, error) -} - -var _ ListComplianceItemsAPIClient = (*Client)(nil) - -// ListComplianceItemsPaginatorOptions is the paginator options for -// ListComplianceItems -type ListComplianceItemsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListComplianceItemsPaginator is a paginator for ListComplianceItems -type ListComplianceItemsPaginator struct { - options ListComplianceItemsPaginatorOptions - client ListComplianceItemsAPIClient - params *ListComplianceItemsInput - nextToken *string - firstPage bool -} - -// NewListComplianceItemsPaginator returns a new ListComplianceItemsPaginator -func NewListComplianceItemsPaginator(client ListComplianceItemsAPIClient, params *ListComplianceItemsInput, optFns ...func(*ListComplianceItemsPaginatorOptions)) *ListComplianceItemsPaginator { - if params == nil { - params = &ListComplianceItemsInput{} - } - - options := ListComplianceItemsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListComplianceItemsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListComplianceItemsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListComplianceItems page. -func (p *ListComplianceItemsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListComplianceItemsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListComplianceItems(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListComplianceItems(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListComplianceItems", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceSummaries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceSummaries.go deleted file mode 100644 index c302842..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListComplianceSummaries.go +++ /dev/null @@ -1,244 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a summary count of compliant and non-compliant resources for a -// compliance type. For example, this call can return State Manager associations, -// patches, or custom compliance types according to the filter criteria that you -// specify. -func (c *Client) ListComplianceSummaries(ctx context.Context, params *ListComplianceSummariesInput, optFns ...func(*Options)) (*ListComplianceSummariesOutput, error) { - if params == nil { - params = &ListComplianceSummariesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListComplianceSummaries", params, optFns, c.addOperationListComplianceSummariesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListComplianceSummariesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListComplianceSummariesInput struct { - - // One or more compliance or inventory filters. Use a filter to return a more - // specific list of results. - Filters []types.ComplianceStringFilter - - // The maximum number of items to return for this call. Currently, you can specify - // null or 50. The call also returns a token that you can specify in a subsequent - // call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type ListComplianceSummariesOutput struct { - - // A list of compliant and non-compliant summary counts based on compliance types. - // For example, this call returns State Manager associations, patches, or custom - // compliance types according to the filter criteria that you specified. - ComplianceSummaryItems []types.ComplianceSummaryItem - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListComplianceSummariesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListComplianceSummaries{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListComplianceSummaries{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListComplianceSummaries"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListComplianceSummaries(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListComplianceSummariesAPIClient is a client that implements the -// ListComplianceSummaries operation. -type ListComplianceSummariesAPIClient interface { - ListComplianceSummaries(context.Context, *ListComplianceSummariesInput, ...func(*Options)) (*ListComplianceSummariesOutput, error) -} - -var _ ListComplianceSummariesAPIClient = (*Client)(nil) - -// ListComplianceSummariesPaginatorOptions is the paginator options for -// ListComplianceSummaries -type ListComplianceSummariesPaginatorOptions struct { - // The maximum number of items to return for this call. Currently, you can specify - // null or 50. The call also returns a token that you can specify in a subsequent - // call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListComplianceSummariesPaginator is a paginator for ListComplianceSummaries -type ListComplianceSummariesPaginator struct { - options ListComplianceSummariesPaginatorOptions - client ListComplianceSummariesAPIClient - params *ListComplianceSummariesInput - nextToken *string - firstPage bool -} - -// NewListComplianceSummariesPaginator returns a new -// ListComplianceSummariesPaginator -func NewListComplianceSummariesPaginator(client ListComplianceSummariesAPIClient, params *ListComplianceSummariesInput, optFns ...func(*ListComplianceSummariesPaginatorOptions)) *ListComplianceSummariesPaginator { - if params == nil { - params = &ListComplianceSummariesInput{} - } - - options := ListComplianceSummariesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListComplianceSummariesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListComplianceSummariesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListComplianceSummaries page. -func (p *ListComplianceSummariesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListComplianceSummariesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListComplianceSummaries(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListComplianceSummaries(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListComplianceSummaries", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentMetadataHistory.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentMetadataHistory.go deleted file mode 100644 index 75303eb..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentMetadataHistory.go +++ /dev/null @@ -1,169 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Information about approval reviews for a version of a change template in Change -// Manager. -func (c *Client) ListDocumentMetadataHistory(ctx context.Context, params *ListDocumentMetadataHistoryInput, optFns ...func(*Options)) (*ListDocumentMetadataHistoryOutput, error) { - if params == nil { - params = &ListDocumentMetadataHistoryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListDocumentMetadataHistory", params, optFns, c.addOperationListDocumentMetadataHistoryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListDocumentMetadataHistoryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListDocumentMetadataHistoryInput struct { - - // The type of data for which details are being requested. Currently, the only - // supported value is DocumentReviews . - // - // This member is required. - Metadata types.DocumentMetadataEnum - - // The name of the change template. - // - // This member is required. - Name *string - - // The version of the change template. - DocumentVersion *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListDocumentMetadataHistoryOutput struct { - - // The user ID of the person in the organization who requested the review of the - // change template. - Author *string - - // The version of the change template. - DocumentVersion *string - - // Information about the response to the change template approval request. - Metadata *types.DocumentMetadataResponseInfo - - // The name of the change template. - Name *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListDocumentMetadataHistoryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListDocumentMetadataHistory{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListDocumentMetadataHistory{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListDocumentMetadataHistory"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListDocumentMetadataHistoryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListDocumentMetadataHistory(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opListDocumentMetadataHistory(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListDocumentMetadataHistory", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentVersions.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentVersions.go deleted file mode 100644 index 72afe4f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocumentVersions.go +++ /dev/null @@ -1,241 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// List all versions for a document. -func (c *Client) ListDocumentVersions(ctx context.Context, params *ListDocumentVersionsInput, optFns ...func(*Options)) (*ListDocumentVersionsOutput, error) { - if params == nil { - params = &ListDocumentVersionsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListDocumentVersions", params, optFns, c.addOperationListDocumentVersionsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListDocumentVersionsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListDocumentVersionsInput struct { - - // The name of the document. You can specify an Amazon Resource Name (ARN). - // - // This member is required. - Name *string - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListDocumentVersionsOutput struct { - - // The document versions. - DocumentVersions []types.DocumentVersionInfo - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListDocumentVersionsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListDocumentVersions{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListDocumentVersions{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListDocumentVersions"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListDocumentVersionsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListDocumentVersions(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListDocumentVersionsAPIClient is a client that implements the -// ListDocumentVersions operation. -type ListDocumentVersionsAPIClient interface { - ListDocumentVersions(context.Context, *ListDocumentVersionsInput, ...func(*Options)) (*ListDocumentVersionsOutput, error) -} - -var _ ListDocumentVersionsAPIClient = (*Client)(nil) - -// ListDocumentVersionsPaginatorOptions is the paginator options for -// ListDocumentVersions -type ListDocumentVersionsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListDocumentVersionsPaginator is a paginator for ListDocumentVersions -type ListDocumentVersionsPaginator struct { - options ListDocumentVersionsPaginatorOptions - client ListDocumentVersionsAPIClient - params *ListDocumentVersionsInput - nextToken *string - firstPage bool -} - -// NewListDocumentVersionsPaginator returns a new ListDocumentVersionsPaginator -func NewListDocumentVersionsPaginator(client ListDocumentVersionsAPIClient, params *ListDocumentVersionsInput, optFns ...func(*ListDocumentVersionsPaginatorOptions)) *ListDocumentVersionsPaginator { - if params == nil { - params = &ListDocumentVersionsInput{} - } - - options := ListDocumentVersionsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListDocumentVersionsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListDocumentVersionsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListDocumentVersions page. -func (p *ListDocumentVersionsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListDocumentVersionsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListDocumentVersions(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListDocumentVersions(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListDocumentVersions", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocuments.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocuments.go deleted file mode 100644 index 0d137fe..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListDocuments.go +++ /dev/null @@ -1,249 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns all Systems Manager (SSM) documents in the current Amazon Web Services -// account and Amazon Web Services Region. You can limit the results of this -// request by using a filter. -func (c *Client) ListDocuments(ctx context.Context, params *ListDocumentsInput, optFns ...func(*Options)) (*ListDocumentsOutput, error) { - if params == nil { - params = &ListDocumentsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListDocuments", params, optFns, c.addOperationListDocumentsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListDocumentsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListDocumentsInput struct { - - // This data type is deprecated. Instead, use Filters . - DocumentFilterList []types.DocumentFilter - - // One or more DocumentKeyValuesFilter objects. Use a filter to return a more - // specific list of results. For keys, you can specify one or more key-value pair - // tags that have been applied to a document. Other valid keys include Owner , Name - // , PlatformTypes , DocumentType , and TargetType . For example, to return - // documents you own use Key=Owner,Values=Self . To specify a custom key-value - // pair, use the format Key=tag:tagName,Values=valueName . This API operation only - // supports filtering documents by using a single tag key and one or more tag - // values. For example: Key=tag:tagName,Values=valueName1,valueName2 - Filters []types.DocumentKeyValuesFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListDocumentsOutput struct { - - // The names of the SSM documents. - DocumentIdentifiers []types.DocumentIdentifier - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListDocumentsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListDocuments{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListDocuments{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListDocuments"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListDocumentsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListDocuments(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListDocumentsAPIClient is a client that implements the ListDocuments operation. -type ListDocumentsAPIClient interface { - ListDocuments(context.Context, *ListDocumentsInput, ...func(*Options)) (*ListDocumentsOutput, error) -} - -var _ ListDocumentsAPIClient = (*Client)(nil) - -// ListDocumentsPaginatorOptions is the paginator options for ListDocuments -type ListDocumentsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListDocumentsPaginator is a paginator for ListDocuments -type ListDocumentsPaginator struct { - options ListDocumentsPaginatorOptions - client ListDocumentsAPIClient - params *ListDocumentsInput - nextToken *string - firstPage bool -} - -// NewListDocumentsPaginator returns a new ListDocumentsPaginator -func NewListDocumentsPaginator(client ListDocumentsAPIClient, params *ListDocumentsInput, optFns ...func(*ListDocumentsPaginatorOptions)) *ListDocumentsPaginator { - if params == nil { - params = &ListDocumentsInput{} - } - - options := ListDocumentsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListDocumentsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListDocumentsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListDocuments page. -func (p *ListDocumentsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListDocumentsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListDocuments(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListDocuments(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListDocuments", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListInventoryEntries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListInventoryEntries.go deleted file mode 100644 index 8589e48..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListInventoryEntries.go +++ /dev/null @@ -1,169 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// A list of inventory items returned by the request. -func (c *Client) ListInventoryEntries(ctx context.Context, params *ListInventoryEntriesInput, optFns ...func(*Options)) (*ListInventoryEntriesOutput, error) { - if params == nil { - params = &ListInventoryEntriesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListInventoryEntries", params, optFns, c.addOperationListInventoryEntriesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListInventoryEntriesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListInventoryEntriesInput struct { - - // The managed node ID for which you want inventory information. - // - // This member is required. - InstanceId *string - - // The type of inventory item for which you want information. - // - // This member is required. - TypeName *string - - // One or more filters. Use a filter to return a more specific list of results. - Filters []types.InventoryFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - noSmithyDocumentSerde -} - -type ListInventoryEntriesOutput struct { - - // The time that inventory information was collected for the managed node(s). - CaptureTime *string - - // A list of inventory items on the managed node(s). - Entries []map[string]string - - // The managed node ID targeted by the request to query inventory information. - InstanceId *string - - // The token to use when requesting the next set of items. If there are no - // additional items to return, the string is empty. - NextToken *string - - // The inventory schema version used by the managed node(s). - SchemaVersion *string - - // The type of inventory item returned by the request. - TypeName *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListInventoryEntriesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListInventoryEntries{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListInventoryEntries{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListInventoryEntries"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListInventoryEntriesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListInventoryEntries(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opListInventoryEntries(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListInventoryEntries", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemEvents.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemEvents.go deleted file mode 100644 index ee55b62..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemEvents.go +++ /dev/null @@ -1,240 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a list of all OpsItem events in the current Amazon Web Services Region -// and Amazon Web Services account. You can limit the results to events associated -// with specific OpsItems by specifying a filter. -func (c *Client) ListOpsItemEvents(ctx context.Context, params *ListOpsItemEventsInput, optFns ...func(*Options)) (*ListOpsItemEventsOutput, error) { - if params == nil { - params = &ListOpsItemEventsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListOpsItemEvents", params, optFns, c.addOperationListOpsItemEventsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListOpsItemEventsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListOpsItemEventsInput struct { - - // One or more OpsItem filters. Use a filter to return a more specific list of - // results. - Filters []types.OpsItemEventFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type ListOpsItemEventsOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A list of event information for the specified OpsItems. - Summaries []types.OpsItemEventSummary - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListOpsItemEventsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListOpsItemEvents{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListOpsItemEvents{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListOpsItemEvents"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListOpsItemEventsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListOpsItemEvents(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListOpsItemEventsAPIClient is a client that implements the ListOpsItemEvents -// operation. -type ListOpsItemEventsAPIClient interface { - ListOpsItemEvents(context.Context, *ListOpsItemEventsInput, ...func(*Options)) (*ListOpsItemEventsOutput, error) -} - -var _ ListOpsItemEventsAPIClient = (*Client)(nil) - -// ListOpsItemEventsPaginatorOptions is the paginator options for ListOpsItemEvents -type ListOpsItemEventsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListOpsItemEventsPaginator is a paginator for ListOpsItemEvents -type ListOpsItemEventsPaginator struct { - options ListOpsItemEventsPaginatorOptions - client ListOpsItemEventsAPIClient - params *ListOpsItemEventsInput - nextToken *string - firstPage bool -} - -// NewListOpsItemEventsPaginator returns a new ListOpsItemEventsPaginator -func NewListOpsItemEventsPaginator(client ListOpsItemEventsAPIClient, params *ListOpsItemEventsInput, optFns ...func(*ListOpsItemEventsPaginatorOptions)) *ListOpsItemEventsPaginator { - if params == nil { - params = &ListOpsItemEventsInput{} - } - - options := ListOpsItemEventsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListOpsItemEventsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListOpsItemEventsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListOpsItemEvents page. -func (p *ListOpsItemEventsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListOpsItemEventsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListOpsItemEvents(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListOpsItemEvents(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListOpsItemEvents", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemRelatedItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemRelatedItems.go deleted file mode 100644 index 4c3819e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsItemRelatedItems.go +++ /dev/null @@ -1,245 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists all related-item resources associated with a Systems Manager OpsCenter -// OpsItem. OpsCenter is a capability of Amazon Web Services Systems Manager. -func (c *Client) ListOpsItemRelatedItems(ctx context.Context, params *ListOpsItemRelatedItemsInput, optFns ...func(*Options)) (*ListOpsItemRelatedItemsOutput, error) { - if params == nil { - params = &ListOpsItemRelatedItemsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListOpsItemRelatedItems", params, optFns, c.addOperationListOpsItemRelatedItemsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListOpsItemRelatedItemsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListOpsItemRelatedItemsInput struct { - - // One or more OpsItem filters. Use a filter to return a more specific list of - // results. - Filters []types.OpsItemRelatedItemsFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // The token for the next set of items to return. (You received this token from a - // previous call.) - NextToken *string - - // The ID of the OpsItem for which you want to list all related-item resources. - OpsItemId *string - - noSmithyDocumentSerde -} - -type ListOpsItemRelatedItemsOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A list of related-item resources for the specified OpsItem. - Summaries []types.OpsItemRelatedItemSummary - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListOpsItemRelatedItemsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListOpsItemRelatedItems{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListOpsItemRelatedItems{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListOpsItemRelatedItems"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListOpsItemRelatedItemsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListOpsItemRelatedItems(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListOpsItemRelatedItemsAPIClient is a client that implements the -// ListOpsItemRelatedItems operation. -type ListOpsItemRelatedItemsAPIClient interface { - ListOpsItemRelatedItems(context.Context, *ListOpsItemRelatedItemsInput, ...func(*Options)) (*ListOpsItemRelatedItemsOutput, error) -} - -var _ ListOpsItemRelatedItemsAPIClient = (*Client)(nil) - -// ListOpsItemRelatedItemsPaginatorOptions is the paginator options for -// ListOpsItemRelatedItems -type ListOpsItemRelatedItemsPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListOpsItemRelatedItemsPaginator is a paginator for ListOpsItemRelatedItems -type ListOpsItemRelatedItemsPaginator struct { - options ListOpsItemRelatedItemsPaginatorOptions - client ListOpsItemRelatedItemsAPIClient - params *ListOpsItemRelatedItemsInput - nextToken *string - firstPage bool -} - -// NewListOpsItemRelatedItemsPaginator returns a new -// ListOpsItemRelatedItemsPaginator -func NewListOpsItemRelatedItemsPaginator(client ListOpsItemRelatedItemsAPIClient, params *ListOpsItemRelatedItemsInput, optFns ...func(*ListOpsItemRelatedItemsPaginatorOptions)) *ListOpsItemRelatedItemsPaginator { - if params == nil { - params = &ListOpsItemRelatedItemsInput{} - } - - options := ListOpsItemRelatedItemsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListOpsItemRelatedItemsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListOpsItemRelatedItemsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListOpsItemRelatedItems page. -func (p *ListOpsItemRelatedItemsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListOpsItemRelatedItemsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListOpsItemRelatedItems(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListOpsItemRelatedItems(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListOpsItemRelatedItems", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsMetadata.go deleted file mode 100644 index 944fba3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListOpsMetadata.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Amazon Web Services Systems Manager calls this API operation when displaying -// all Application Manager OpsMetadata objects or blobs. -func (c *Client) ListOpsMetadata(ctx context.Context, params *ListOpsMetadataInput, optFns ...func(*Options)) (*ListOpsMetadataOutput, error) { - if params == nil { - params = &ListOpsMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListOpsMetadata", params, optFns, c.addOperationListOpsMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListOpsMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListOpsMetadataInput struct { - - // One or more filters to limit the number of OpsMetadata objects returned by the - // call. - Filters []types.OpsMetadataFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type ListOpsMetadataOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // Returns a list of OpsMetadata objects. - OpsMetadataList []types.OpsMetadata - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListOpsMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListOpsMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListOpsMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListOpsMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListOpsMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListOpsMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListOpsMetadataAPIClient is a client that implements the ListOpsMetadata -// operation. -type ListOpsMetadataAPIClient interface { - ListOpsMetadata(context.Context, *ListOpsMetadataInput, ...func(*Options)) (*ListOpsMetadataOutput, error) -} - -var _ ListOpsMetadataAPIClient = (*Client)(nil) - -// ListOpsMetadataPaginatorOptions is the paginator options for ListOpsMetadata -type ListOpsMetadataPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListOpsMetadataPaginator is a paginator for ListOpsMetadata -type ListOpsMetadataPaginator struct { - options ListOpsMetadataPaginatorOptions - client ListOpsMetadataAPIClient - params *ListOpsMetadataInput - nextToken *string - firstPage bool -} - -// NewListOpsMetadataPaginator returns a new ListOpsMetadataPaginator -func NewListOpsMetadataPaginator(client ListOpsMetadataAPIClient, params *ListOpsMetadataInput, optFns ...func(*ListOpsMetadataPaginatorOptions)) *ListOpsMetadataPaginator { - if params == nil { - params = &ListOpsMetadataInput{} - } - - options := ListOpsMetadataPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListOpsMetadataPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListOpsMetadataPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListOpsMetadata page. -func (p *ListOpsMetadataPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListOpsMetadataOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListOpsMetadata(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListOpsMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListOpsMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceComplianceSummaries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceComplianceSummaries.go deleted file mode 100644 index 7bae0aa..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceComplianceSummaries.go +++ /dev/null @@ -1,241 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a resource-level summary count. The summary includes information about -// compliant and non-compliant statuses and detailed compliance-item severity -// counts, according to the filter criteria you specify. -func (c *Client) ListResourceComplianceSummaries(ctx context.Context, params *ListResourceComplianceSummariesInput, optFns ...func(*Options)) (*ListResourceComplianceSummariesOutput, error) { - if params == nil { - params = &ListResourceComplianceSummariesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListResourceComplianceSummaries", params, optFns, c.addOperationListResourceComplianceSummariesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListResourceComplianceSummariesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListResourceComplianceSummariesInput struct { - - // One or more filters. Use a filter to return a more specific list of results. - Filters []types.ComplianceStringFilter - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - noSmithyDocumentSerde -} - -type ListResourceComplianceSummariesOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A summary count for specified or targeted managed nodes. Summary count includes - // information about compliant and non-compliant State Manager associations, patch - // status, or custom items according to the filter criteria that you specify. - ResourceComplianceSummaryItems []types.ResourceComplianceSummaryItem - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListResourceComplianceSummariesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListResourceComplianceSummaries{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListResourceComplianceSummaries{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListResourceComplianceSummaries"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListResourceComplianceSummaries(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListResourceComplianceSummariesAPIClient is a client that implements the -// ListResourceComplianceSummaries operation. -type ListResourceComplianceSummariesAPIClient interface { - ListResourceComplianceSummaries(context.Context, *ListResourceComplianceSummariesInput, ...func(*Options)) (*ListResourceComplianceSummariesOutput, error) -} - -var _ ListResourceComplianceSummariesAPIClient = (*Client)(nil) - -// ListResourceComplianceSummariesPaginatorOptions is the paginator options for -// ListResourceComplianceSummaries -type ListResourceComplianceSummariesPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListResourceComplianceSummariesPaginator is a paginator for -// ListResourceComplianceSummaries -type ListResourceComplianceSummariesPaginator struct { - options ListResourceComplianceSummariesPaginatorOptions - client ListResourceComplianceSummariesAPIClient - params *ListResourceComplianceSummariesInput - nextToken *string - firstPage bool -} - -// NewListResourceComplianceSummariesPaginator returns a new -// ListResourceComplianceSummariesPaginator -func NewListResourceComplianceSummariesPaginator(client ListResourceComplianceSummariesAPIClient, params *ListResourceComplianceSummariesInput, optFns ...func(*ListResourceComplianceSummariesPaginatorOptions)) *ListResourceComplianceSummariesPaginator { - if params == nil { - params = &ListResourceComplianceSummariesInput{} - } - - options := ListResourceComplianceSummariesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListResourceComplianceSummariesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListResourceComplianceSummariesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListResourceComplianceSummaries page. -func (p *ListResourceComplianceSummariesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListResourceComplianceSummariesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListResourceComplianceSummaries(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListResourceComplianceSummaries(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListResourceComplianceSummaries", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceDataSync.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceDataSync.go deleted file mode 100644 index 2009101..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListResourceDataSync.go +++ /dev/null @@ -1,246 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists your resource data sync configurations. Includes information about the -// last time a sync attempted to start, the last sync status, and the last time a -// sync successfully completed. The number of sync configurations might be too -// large to return using a single call to ListResourceDataSync . You can limit the -// number of sync configurations returned by using the MaxResults parameter. To -// determine whether there are more sync configurations to list, check the value of -// NextToken in the output. If there are more sync configurations to list, you can -// request them by specifying the NextToken returned in the call to the parameter -// of a subsequent call. -func (c *Client) ListResourceDataSync(ctx context.Context, params *ListResourceDataSyncInput, optFns ...func(*Options)) (*ListResourceDataSyncOutput, error) { - if params == nil { - params = &ListResourceDataSyncInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListResourceDataSync", params, optFns, c.addOperationListResourceDataSyncMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListResourceDataSyncOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListResourceDataSyncInput struct { - - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - MaxResults *int32 - - // A token to start the list. Use this token to get the next set of results. - NextToken *string - - // View a list of resource data syncs according to the sync type. Specify - // SyncToDestination to view resource data syncs that synchronize data to an Amazon - // S3 bucket. Specify SyncFromSource to view resource data syncs from - // Organizations or from multiple Amazon Web Services Regions. - SyncType *string - - noSmithyDocumentSerde -} - -type ListResourceDataSyncOutput struct { - - // The token for the next set of items to return. Use this token to get the next - // set of results. - NextToken *string - - // A list of your current resource data sync configurations and their statuses. - ResourceDataSyncItems []types.ResourceDataSyncItem - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListResourceDataSyncMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListResourceDataSync{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListResourceDataSync{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListResourceDataSync"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListResourceDataSync(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -// ListResourceDataSyncAPIClient is a client that implements the -// ListResourceDataSync operation. -type ListResourceDataSyncAPIClient interface { - ListResourceDataSync(context.Context, *ListResourceDataSyncInput, ...func(*Options)) (*ListResourceDataSyncOutput, error) -} - -var _ ListResourceDataSyncAPIClient = (*Client)(nil) - -// ListResourceDataSyncPaginatorOptions is the paginator options for -// ListResourceDataSync -type ListResourceDataSyncPaginatorOptions struct { - // The maximum number of items to return for this call. The call also returns a - // token that you can specify in a subsequent call to get the next set of results. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListResourceDataSyncPaginator is a paginator for ListResourceDataSync -type ListResourceDataSyncPaginator struct { - options ListResourceDataSyncPaginatorOptions - client ListResourceDataSyncAPIClient - params *ListResourceDataSyncInput - nextToken *string - firstPage bool -} - -// NewListResourceDataSyncPaginator returns a new ListResourceDataSyncPaginator -func NewListResourceDataSyncPaginator(client ListResourceDataSyncAPIClient, params *ListResourceDataSyncInput, optFns ...func(*ListResourceDataSyncPaginatorOptions)) *ListResourceDataSyncPaginator { - if params == nil { - params = &ListResourceDataSyncInput{} - } - - options := ListResourceDataSyncPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListResourceDataSyncPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListResourceDataSyncPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListResourceDataSync page. -func (p *ListResourceDataSyncPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListResourceDataSyncOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - result, err := p.client.ListResourceDataSync(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -func newServiceMetadataMiddleware_opListResourceDataSync(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListResourceDataSync", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListTagsForResource.go deleted file mode 100644 index 06e7a52..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ListTagsForResource.go +++ /dev/null @@ -1,143 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a list of the tags assigned to the specified resource. For information -// about the ID format for each supported resource type, see AddTagsToResource . -func (c *Client) ListTagsForResource(ctx context.Context, params *ListTagsForResourceInput, optFns ...func(*Options)) (*ListTagsForResourceOutput, error) { - if params == nil { - params = &ListTagsForResourceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListTagsForResource", params, optFns, c.addOperationListTagsForResourceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListTagsForResourceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListTagsForResourceInput struct { - - // The resource ID for which you want to see a list of tags. - // - // This member is required. - ResourceId *string - - // Returns a list of tags for a specific resource type. - // - // This member is required. - ResourceType types.ResourceTypeForTagging - - noSmithyDocumentSerde -} - -type ListTagsForResourceOutput struct { - - // A list of tags. - TagList []types.Tag - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpListTagsForResource{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpListTagsForResource{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListTagsForResource"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListTagsForResource(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opListTagsForResource(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListTagsForResource", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ModifyDocumentPermission.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ModifyDocumentPermission.go deleted file mode 100644 index cf28685..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ModifyDocumentPermission.go +++ /dev/null @@ -1,155 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Shares a Amazon Web Services Systems Manager document (SSM document)publicly or -// privately. If you share a document privately, you must specify the Amazon Web -// Services user IDs for those people who can use the document. If you share a -// document publicly, you must specify All as the account ID. -func (c *Client) ModifyDocumentPermission(ctx context.Context, params *ModifyDocumentPermissionInput, optFns ...func(*Options)) (*ModifyDocumentPermissionOutput, error) { - if params == nil { - params = &ModifyDocumentPermissionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ModifyDocumentPermission", params, optFns, c.addOperationModifyDocumentPermissionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ModifyDocumentPermissionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ModifyDocumentPermissionInput struct { - - // The name of the document that you want to share. - // - // This member is required. - Name *string - - // The permission type for the document. The permission type can be Share. - // - // This member is required. - PermissionType types.DocumentPermissionType - - // The Amazon Web Services users that should have access to the document. The - // account IDs can either be a group of account IDs or All. - AccountIdsToAdd []string - - // The Amazon Web Services users that should no longer have access to the - // document. The Amazon Web Services user can either be a group of account IDs or - // All. This action has a higher priority than AccountIdsToAdd. If you specify an - // ID to add and the same ID to remove, the system removes access to the document. - AccountIdsToRemove []string - - // (Optional) The version of the document to share. If it isn't specified, the - // system choose the Default version to share. - SharedDocumentVersion *string - - noSmithyDocumentSerde -} - -type ModifyDocumentPermissionOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationModifyDocumentPermissionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpModifyDocumentPermission{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpModifyDocumentPermission{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ModifyDocumentPermission"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpModifyDocumentPermissionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opModifyDocumentPermission(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opModifyDocumentPermission(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ModifyDocumentPermission", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutComplianceItems.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutComplianceItems.go deleted file mode 100644 index 7432492..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutComplianceItems.go +++ /dev/null @@ -1,197 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Registers a compliance type and other compliance details on a designated -// resource. This operation lets you register custom compliance details with a -// resource. This call overwrites existing compliance information on the resource, -// so you must provide a full list of compliance items each time that you send the -// request. ComplianceType can be one of the following: -// - ExecutionId: The execution ID when the patch, association, or custom -// compliance item was applied. -// - ExecutionType: Specify patch, association, or Custom: string . -// - ExecutionTime. The time the patch, association, or custom compliance item -// was applied to the managed node. -// - Id: The patch, association, or custom compliance ID. -// - Title: A title. -// - Status: The status of the compliance item. For example, approved for -// patches, or Failed for associations. -// - Severity: A patch severity. For example, Critical . -// - DocumentName: An SSM document name. For example, AWS-RunPatchBaseline . -// - DocumentVersion: An SSM document version number. For example, 4. -// - Classification: A patch classification. For example, security updates . -// - PatchBaselineId: A patch baseline ID. -// - PatchSeverity: A patch severity. For example, Critical . -// - PatchState: A patch state. For example, InstancesWithFailedPatches . -// - PatchGroup: The name of a patch group. -// - InstalledTime: The time the association, patch, or custom compliance item -// was applied to the resource. Specify the time by using the following format: -// yyyy-MM-dd'T'HH:mm:ss'Z' -func (c *Client) PutComplianceItems(ctx context.Context, params *PutComplianceItemsInput, optFns ...func(*Options)) (*PutComplianceItemsOutput, error) { - if params == nil { - params = &PutComplianceItemsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "PutComplianceItems", params, optFns, c.addOperationPutComplianceItemsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*PutComplianceItemsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type PutComplianceItemsInput struct { - - // Specify the compliance type. For example, specify Association (for a State - // Manager association), Patch, or Custom: string . - // - // This member is required. - ComplianceType *string - - // A summary of the call execution that includes an execution ID, the type of - // execution (for example, Command ), and the date/time of the execution using a - // datetime object that is saved in the following format: yyyy-MM-dd'T'HH:mm:ss'Z'. - // - // This member is required. - ExecutionSummary *types.ComplianceExecutionSummary - - // Information about the compliance as defined by the resource type. For example, - // for a patch compliance type, Items includes information about the - // PatchSeverity, Classification, and so on. - // - // This member is required. - Items []types.ComplianceItemEntry - - // Specify an ID for this resource. For a managed node, this is the node ID. - // - // This member is required. - ResourceId *string - - // Specify the type of resource. ManagedInstance is currently the only supported - // resource type. - // - // This member is required. - ResourceType *string - - // MD5 or SHA-256 content hash. The content hash is used to determine if existing - // information should be overwritten or ignored. If the content hashes match, the - // request to put compliance information is ignored. - ItemContentHash *string - - // The mode for uploading compliance items. You can specify COMPLETE or PARTIAL . - // In COMPLETE mode, the system overwrites all existing compliance information for - // the resource. You must provide a full list of compliance items each time you - // send the request. In PARTIAL mode, the system overwrites compliance information - // for a specific association. The association must be configured with - // SyncCompliance set to MANUAL . By default, all requests use COMPLETE mode. This - // attribute is only valid for association compliance. - UploadType types.ComplianceUploadType - - noSmithyDocumentSerde -} - -type PutComplianceItemsOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationPutComplianceItemsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutComplianceItems{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpPutComplianceItems{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "PutComplianceItems"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpPutComplianceItemsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutComplianceItems(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opPutComplianceItems(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "PutComplianceItems", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutInventory.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutInventory.go deleted file mode 100644 index b4ef83b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutInventory.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Bulk update custom inventory items on one or more managed nodes. The request -// adds an inventory item, if it doesn't already exist, or updates an inventory -// item, if it does exist. -func (c *Client) PutInventory(ctx context.Context, params *PutInventoryInput, optFns ...func(*Options)) (*PutInventoryOutput, error) { - if params == nil { - params = &PutInventoryInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "PutInventory", params, optFns, c.addOperationPutInventoryMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*PutInventoryOutput) - out.ResultMetadata = metadata - return out, nil -} - -type PutInventoryInput struct { - - // An managed node ID where you want to add or update inventory items. - // - // This member is required. - InstanceId *string - - // The inventory items that you want to add or update on managed nodes. - // - // This member is required. - Items []types.InventoryItem - - noSmithyDocumentSerde -} - -type PutInventoryOutput struct { - - // Information about the request. - Message *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationPutInventoryMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutInventory{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpPutInventory{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "PutInventory"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpPutInventoryValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutInventory(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opPutInventory(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "PutInventory", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutParameter.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutParameter.go deleted file mode 100644 index e56044b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutParameter.go +++ /dev/null @@ -1,308 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Add a parameter to the system. -func (c *Client) PutParameter(ctx context.Context, params *PutParameterInput, optFns ...func(*Options)) (*PutParameterOutput, error) { - if params == nil { - params = &PutParameterInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "PutParameter", params, optFns, c.addOperationPutParameterMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*PutParameterOutput) - out.ResultMetadata = metadata - return out, nil -} - -type PutParameterInput struct { - - // The fully qualified name of the parameter that you want to add to the system. - // The fully qualified name includes the complete hierarchy of the parameter path - // and name. For parameters in a hierarchy, you must include a leading forward - // slash character (/) when you create or reference a parameter. For example: - // /Dev/DBServer/MySQL/db-string13 Naming Constraints: - // - Parameter names are case sensitive. - // - A parameter name must be unique within an Amazon Web Services Region - // - A parameter name can't be prefixed with " aws " or " ssm " - // (case-insensitive). - // - Parameter names can include only the following symbols and letters: - // a-zA-Z0-9_.- In addition, the slash character ( / ) is used to delineate - // hierarchies in parameter names. For example: - // /Dev/Production/East/Project-ABC/MyParameter - // - A parameter name can't include spaces. - // - Parameter hierarchies are limited to a maximum depth of fifteen levels. - // For additional information about valid values for parameter names, see Creating - // Systems Manager parameters (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-su-create.html) - // in the Amazon Web Services Systems Manager User Guide. The maximum length - // constraint of 2048 characters listed below includes 1037 characters reserved for - // internal use by Systems Manager. The maximum length for a parameter name that - // you create is 1011 characters. This includes the characters in the ARN that - // precede the name you specify, such as - // arn:aws:ssm:us-east-2:111122223333:parameter/ . - // - // This member is required. - Name *string - - // The parameter value that you want to add to the system. Standard parameters - // have a value limit of 4 KB. Advanced parameters have a value limit of 8 KB. - // Parameters can't be referenced or nested in the values of other parameters. You - // can't include {{}} or {{ssm:parameter-name}} in a parameter value. - // - // This member is required. - Value *string - - // A regular expression used to validate the parameter value. For example, for - // String types with values restricted to numbers, you can specify the following: - // AllowedPattern=^\d+$ - AllowedPattern *string - - // The data type for a String parameter. Supported data types include plain text - // and Amazon Machine Image (AMI) IDs. The following data type values are - // supported. - // - text - // - aws:ec2:image - // - aws:ssm:integration - // When you create a String parameter and specify aws:ec2:image , Amazon Web - // Services Systems Manager validates the parameter value is in the required - // format, such as ami-12345abcdeEXAMPLE , and that the specified AMI is available - // in your Amazon Web Services account. If the action is successful, the service - // sends back an HTTP 200 response which indicates a successful PutParameter call - // for all cases except for data type aws:ec2:image . If you call PutParameter - // with aws:ec2:image data type, a successful HTTP 200 response does not guarantee - // that your parameter was successfully created or updated. The aws:ec2:image - // value is validated asynchronously, and the PutParameter call returns before the - // validation is complete. If you submit an invalid AMI value, the PutParameter - // operation will return success, but the asynchronous validation will fail and the - // parameter will not be created or updated. To monitor whether your aws:ec2:image - // parameters are created successfully, see Setting up notifications or trigger - // actions based on Parameter Store events (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-cwe.html) - // . For more information about AMI format validation , see Native parameter - // support for Amazon Machine Image (AMI) IDs (https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-ec2-aliases.html) - // . - DataType *string - - // Information about the parameter that you want to add to the system. Optional - // but recommended. Don't enter personally identifiable information in this field. - Description *string - - // The Key Management Service (KMS) ID that you want to use to encrypt a - // parameter. Use a custom key for better security. Required for parameters that - // use the SecureString data type. If you don't specify a key ID, the system uses - // the default key associated with your Amazon Web Services account which is not as - // secure as using a custom key. - // - To use a custom KMS key, choose the SecureString data type with the Key ID - // parameter. - KeyId *string - - // Overwrite an existing parameter. The default value is false . - Overwrite *bool - - // One or more policies to apply to a parameter. This operation takes a JSON - // array. Parameter Store, a capability of Amazon Web Services Systems Manager - // supports the following policy types: Expiration: This policy deletes the - // parameter after it expires. When you create the policy, you specify the - // expiration date. You can update the expiration date and time by updating the - // policy. Updating the parameter doesn't affect the expiration date and time. When - // the expiration time is reached, Parameter Store deletes the parameter. - // ExpirationNotification: This policy initiates an event in Amazon CloudWatch - // Events that notifies you about the expiration. By using this policy, you can - // receive notification before or after the expiration time is reached, in units of - // days or hours. NoChangeNotification: This policy initiates a CloudWatch Events - // event if a parameter hasn't been modified for a specified period of time. This - // policy type is useful when, for example, a secret needs to be changed within a - // period of time, but it hasn't been changed. All existing policies are preserved - // until you send new policies or an empty policy. For more information about - // parameter policies, see Assigning parameter policies (https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-policies.html) - // . - Policies *string - - // Optional metadata that you assign to a resource. Tags enable you to categorize - // a resource in different ways, such as by purpose, owner, or environment. For - // example, you might want to tag a Systems Manager parameter to identify the type - // of resource to which it applies, the environment, or the type of configuration - // data referenced by the parameter. In this case, you could specify the following - // key-value pairs: - // - Key=Resource,Value=S3bucket - // - Key=OS,Value=Windows - // - Key=ParameterType,Value=LicenseKey - // To add tags to an existing Systems Manager parameter, use the AddTagsToResource - // operation. - Tags []types.Tag - - // The parameter tier to assign to a parameter. Parameter Store offers a standard - // tier and an advanced tier for parameters. Standard parameters have a content - // size limit of 4 KB and can't be configured to use parameter policies. You can - // create a maximum of 10,000 standard parameters for each Region in an Amazon Web - // Services account. Standard parameters are offered at no additional cost. - // Advanced parameters have a content size limit of 8 KB and can be configured to - // use parameter policies. You can create a maximum of 100,000 advanced parameters - // for each Region in an Amazon Web Services account. Advanced parameters incur a - // charge. For more information, see Standard and advanced parameter tiers (https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-advanced-parameters.html) - // in the Amazon Web Services Systems Manager User Guide. You can change a standard - // parameter to an advanced parameter any time. But you can't revert an advanced - // parameter to a standard parameter. Reverting an advanced parameter to a standard - // parameter would result in data loss because the system would truncate the size - // of the parameter from 8 KB to 4 KB. Reverting would also remove any policies - // attached to the parameter. Lastly, advanced parameters use a different form of - // encryption than standard parameters. If you no longer need an advanced - // parameter, or if you no longer want to incur charges for an advanced parameter, - // you must delete it and recreate it as a new standard parameter. Using the - // Default Tier Configuration In PutParameter requests, you can specify the tier - // to create the parameter in. Whenever you specify a tier in the request, - // Parameter Store creates or updates the parameter according to that request. - // However, if you don't specify a tier in a request, Parameter Store assigns the - // tier based on the current Parameter Store default tier configuration. The - // default tier when you begin using Parameter Store is the standard-parameter - // tier. If you use the advanced-parameter tier, you can specify one of the - // following as the default: - // - Advanced: With this option, Parameter Store evaluates all requests as - // advanced parameters. - // - Intelligent-Tiering: With this option, Parameter Store evaluates each - // request to determine if the parameter is standard or advanced. If the request - // doesn't include any options that require an advanced parameter, the parameter is - // created in the standard-parameter tier. If one or more options requiring an - // advanced parameter are included in the request, Parameter Store create a - // parameter in the advanced-parameter tier. This approach helps control your - // parameter-related costs by always creating standard parameters unless an - // advanced parameter is necessary. - // Options that require an advanced parameter include the following: - // - The content size of the parameter is more than 4 KB. - // - The parameter uses a parameter policy. - // - More than 10,000 parameters already exist in your Amazon Web Services - // account in the current Amazon Web Services Region. - // For more information about configuring the default tier option, see Specifying - // a default parameter tier (https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-default-tier.html) - // in the Amazon Web Services Systems Manager User Guide. - Tier types.ParameterTier - - // The type of parameter that you want to add to the system. SecureString isn't - // currently supported for CloudFormation templates. Items in a StringList must be - // separated by a comma (,). You can't use other punctuation or special character - // to escape items in the list. If you have a parameter value that requires a - // comma, then use the String data type. Specifying a parameter type isn't - // required when updating a parameter. You must specify a parameter type when - // creating a parameter. - Type types.ParameterType - - noSmithyDocumentSerde -} - -type PutParameterOutput struct { - - // The tier assigned to the parameter. - Tier types.ParameterTier - - // The new version number of a parameter. If you edit a parameter value, Parameter - // Store automatically creates a new version and assigns this new version a unique - // ID. You can reference a parameter version ID in API operations or in Systems - // Manager documents (SSM documents). By default, if you don't specify a specific - // version, the system returns the latest parameter value when a parameter is - // called. - Version int64 - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationPutParameterMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutParameter{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpPutParameter{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "PutParameter"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpPutParameterValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutParameter(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opPutParameter(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "PutParameter", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutResourcePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutResourcePolicy.go deleted file mode 100644 index 0ca5a2a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_PutResourcePolicy.go +++ /dev/null @@ -1,157 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates or updates a Systems Manager resource policy. A resource policy helps -// you to define the IAM entity (for example, an Amazon Web Services account) that -// can manage your Systems Manager resources. Currently, OpsItemGroup is the only -// resource that supports Systems Manager resource policies. The resource policy -// for OpsItemGroup enables Amazon Web Services accounts to view and interact with -// OpsCenter operational work items (OpsItems). -func (c *Client) PutResourcePolicy(ctx context.Context, params *PutResourcePolicyInput, optFns ...func(*Options)) (*PutResourcePolicyOutput, error) { - if params == nil { - params = &PutResourcePolicyInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "PutResourcePolicy", params, optFns, c.addOperationPutResourcePolicyMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*PutResourcePolicyOutput) - out.ResultMetadata = metadata - return out, nil -} - -type PutResourcePolicyInput struct { - - // A policy you want to associate with a resource. - // - // This member is required. - Policy *string - - // Amazon Resource Name (ARN) of the resource to which you want to attach a policy. - // - // This member is required. - ResourceArn *string - - // ID of the current policy version. The hash helps to prevent a situation where - // multiple users attempt to overwrite a policy. You must provide this hash when - // updating or deleting a policy. - PolicyHash *string - - // The policy ID. - PolicyId *string - - noSmithyDocumentSerde -} - -type PutResourcePolicyOutput struct { - - // ID of the current policy version. - PolicyHash *string - - // The policy ID. To update a policy, you must specify PolicyId and PolicyHash . - PolicyId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationPutResourcePolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutResourcePolicy{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpPutResourcePolicy{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "PutResourcePolicy"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpPutResourcePolicyValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutResourcePolicy(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opPutResourcePolicy(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "PutResourcePolicy", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterDefaultPatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterDefaultPatchBaseline.go deleted file mode 100644 index 6139a66..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterDefaultPatchBaseline.go +++ /dev/null @@ -1,141 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Defines the default patch baseline for the relevant operating system. To reset -// the Amazon Web Services-predefined patch baseline as the default, specify the -// full patch baseline Amazon Resource Name (ARN) as the baseline ID value. For -// example, for CentOS, specify -// arn:aws:ssm:us-east-2:733109147000:patchbaseline/pb-0574b43a65ea646ed instead of -// pb-0574b43a65ea646ed . -func (c *Client) RegisterDefaultPatchBaseline(ctx context.Context, params *RegisterDefaultPatchBaselineInput, optFns ...func(*Options)) (*RegisterDefaultPatchBaselineOutput, error) { - if params == nil { - params = &RegisterDefaultPatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RegisterDefaultPatchBaseline", params, optFns, c.addOperationRegisterDefaultPatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RegisterDefaultPatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RegisterDefaultPatchBaselineInput struct { - - // The ID of the patch baseline that should be the default patch baseline. - // - // This member is required. - BaselineId *string - - noSmithyDocumentSerde -} - -type RegisterDefaultPatchBaselineOutput struct { - - // The ID of the default patch baseline. - BaselineId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRegisterDefaultPatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpRegisterDefaultPatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpRegisterDefaultPatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterDefaultPatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpRegisterDefaultPatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterDefaultPatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opRegisterDefaultPatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RegisterDefaultPatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterPatchBaselineForPatchGroup.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterPatchBaselineForPatchGroup.go deleted file mode 100644 index bd808be..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterPatchBaselineForPatchGroup.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Registers a patch baseline for a patch group. -func (c *Client) RegisterPatchBaselineForPatchGroup(ctx context.Context, params *RegisterPatchBaselineForPatchGroupInput, optFns ...func(*Options)) (*RegisterPatchBaselineForPatchGroupOutput, error) { - if params == nil { - params = &RegisterPatchBaselineForPatchGroupInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RegisterPatchBaselineForPatchGroup", params, optFns, c.addOperationRegisterPatchBaselineForPatchGroupMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RegisterPatchBaselineForPatchGroupOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RegisterPatchBaselineForPatchGroupInput struct { - - // The ID of the patch baseline to register with the patch group. - // - // This member is required. - BaselineId *string - - // The name of the patch group to be registered with the patch baseline. - // - // This member is required. - PatchGroup *string - - noSmithyDocumentSerde -} - -type RegisterPatchBaselineForPatchGroupOutput struct { - - // The ID of the patch baseline the patch group was registered with. - BaselineId *string - - // The name of the patch group registered with the patch baseline. - PatchGroup *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRegisterPatchBaselineForPatchGroupMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpRegisterPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpRegisterPatchBaselineForPatchGroup{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterPatchBaselineForPatchGroup"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpRegisterPatchBaselineForPatchGroupValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterPatchBaselineForPatchGroup(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opRegisterPatchBaselineForPatchGroup(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RegisterPatchBaselineForPatchGroup", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTargetWithMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTargetWithMaintenanceWindow.go deleted file mode 100644 index 33b680b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTargetWithMaintenanceWindow.go +++ /dev/null @@ -1,213 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Registers a target with a maintenance window. -func (c *Client) RegisterTargetWithMaintenanceWindow(ctx context.Context, params *RegisterTargetWithMaintenanceWindowInput, optFns ...func(*Options)) (*RegisterTargetWithMaintenanceWindowOutput, error) { - if params == nil { - params = &RegisterTargetWithMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RegisterTargetWithMaintenanceWindow", params, optFns, c.addOperationRegisterTargetWithMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RegisterTargetWithMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RegisterTargetWithMaintenanceWindowInput struct { - - // The type of target being registered with the maintenance window. - // - // This member is required. - ResourceType types.MaintenanceWindowResourceType - - // The targets to register with the maintenance window. In other words, the - // managed nodes to run commands on when the maintenance window runs. If a single - // maintenance window task is registered with multiple targets, its task - // invocations occur sequentially and not in parallel. If your task must run on - // multiple targets at the same time, register a task for each target individually - // and assign each task the same priority level. You can specify targets using - // managed node IDs, resource group names, or tags that have been applied to - // managed nodes. Example 1: Specify managed node IDs Key=InstanceIds,Values=,, - // Example 2: Use tag key-pairs applied to managed nodes Key=tag:,Values=, Example - // 3: Use tag-keys applied to managed nodes Key=tag-key,Values=, Example 4: Use - // resource group names Key=resource-groups:Name,Values= Example 5: Use filters - // for resource group types Key=resource-groups:ResourceTypeFilters,Values=, For - // Key=resource-groups:ResourceTypeFilters , specify resource types in the - // following format - // Key=resource-groups:ResourceTypeFilters,Values=AWS::EC2::INSTANCE,AWS::EC2::VPC - // For more information about these examples formats, including the best use case - // for each one, see Examples: Register targets with a maintenance window (https://docs.aws.amazon.com/systems-manager/latest/userguide/mw-cli-tutorial-targets-examples.html) - // in the Amazon Web Services Systems Manager User Guide. - // - // This member is required. - Targets []types.Target - - // The ID of the maintenance window the target should be registered with. - // - // This member is required. - WindowId *string - - // User-provided idempotency token. - ClientToken *string - - // An optional description for the target. - Description *string - - // An optional name for the target. - Name *string - - // User-provided value that will be included in any Amazon CloudWatch Events - // events raised while running tasks for these targets in this maintenance window. - OwnerInformation *string - - noSmithyDocumentSerde -} - -type RegisterTargetWithMaintenanceWindowOutput struct { - - // The ID of the target definition in this maintenance window. - WindowTargetId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRegisterTargetWithMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpRegisterTargetWithMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpRegisterTargetWithMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterTargetWithMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addIdempotencyToken_opRegisterTargetWithMaintenanceWindowMiddleware(stack, options); err != nil { - return err - } - if err = addOpRegisterTargetWithMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterTargetWithMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -type idempotencyToken_initializeOpRegisterTargetWithMaintenanceWindow struct { - tokenProvider IdempotencyTokenProvider -} - -func (*idempotencyToken_initializeOpRegisterTargetWithMaintenanceWindow) ID() string { - return "OperationIdempotencyTokenAutoFill" -} - -func (m *idempotencyToken_initializeOpRegisterTargetWithMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.tokenProvider == nil { - return next.HandleInitialize(ctx, in) - } - - input, ok := in.Parameters.(*RegisterTargetWithMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("expected middleware input to be of type *RegisterTargetWithMaintenanceWindowInput ") - } - - if input.ClientToken == nil { - t, err := m.tokenProvider.GetIdempotencyToken() - if err != nil { - return out, metadata, err - } - input.ClientToken = &t - } - return next.HandleInitialize(ctx, in) -} -func addIdempotencyToken_opRegisterTargetWithMaintenanceWindowMiddleware(stack *middleware.Stack, cfg Options) error { - return stack.Initialize.Add(&idempotencyToken_initializeOpRegisterTargetWithMaintenanceWindow{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before) -} - -func newServiceMetadataMiddleware_opRegisterTargetWithMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RegisterTargetWithMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTaskWithMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTaskWithMaintenanceWindow.go deleted file mode 100644 index 21a3cb6..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RegisterTaskWithMaintenanceWindow.go +++ /dev/null @@ -1,277 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Adds a new task to a maintenance window. -func (c *Client) RegisterTaskWithMaintenanceWindow(ctx context.Context, params *RegisterTaskWithMaintenanceWindowInput, optFns ...func(*Options)) (*RegisterTaskWithMaintenanceWindowOutput, error) { - if params == nil { - params = &RegisterTaskWithMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RegisterTaskWithMaintenanceWindow", params, optFns, c.addOperationRegisterTaskWithMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RegisterTaskWithMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RegisterTaskWithMaintenanceWindowInput struct { - - // The ARN of the task to run. - // - // This member is required. - TaskArn *string - - // The type of task being registered. - // - // This member is required. - TaskType types.MaintenanceWindowTaskType - - // The ID of the maintenance window the task should be added to. - // - // This member is required. - WindowId *string - - // The CloudWatch alarm you want to apply to your maintenance window task. - AlarmConfiguration *types.AlarmConfiguration - - // User-provided idempotency token. - ClientToken *string - - // Indicates whether tasks should continue to run after the cutoff time specified - // in the maintenance windows is reached. - // - CONTINUE_TASK : When the cutoff time is reached, any tasks that are running - // continue. The default value. - // - CANCEL_TASK : - // - For Automation, Lambda, Step Functions tasks: When the cutoff time is - // reached, any task invocations that are already running continue, but no new task - // invocations are started. - // - For Run Command tasks: When the cutoff time is reached, the system sends a - // CancelCommand operation that attempts to cancel the command associated with - // the task. However, there is no guarantee that the command will be terminated and - // the underlying process stopped. The status for tasks that are not completed - // is TIMED_OUT . - CutoffBehavior types.MaintenanceWindowTaskCutoffBehavior - - // An optional description for the task. - Description *string - - // A structure containing information about an Amazon Simple Storage Service - // (Amazon S3) bucket to write managed node-level logs to. LoggingInfo has been - // deprecated. To specify an Amazon Simple Storage Service (Amazon S3) bucket to - // contain logs, instead use the OutputS3BucketName and OutputS3KeyPrefix options - // in the TaskInvocationParameters structure. For information about how Amazon Web - // Services Systems Manager handles these options for the supported maintenance - // window task types, see MaintenanceWindowTaskInvocationParameters . - LoggingInfo *types.LoggingInfo - - // The maximum number of targets this task can be run for, in parallel. Although - // this element is listed as "Required: No", a value can be omitted only when you - // are registering or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxConcurrency *string - - // The maximum number of errors allowed before this task stops being scheduled. - // Although this element is listed as "Required: No", a value can be omitted only - // when you are registering or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxErrors *string - - // An optional name for the task. - Name *string - - // The priority of the task in the maintenance window, the lower the number the - // higher the priority. Tasks in a maintenance window are scheduled in priority - // order with tasks that have the same priority scheduled in parallel. - Priority *int32 - - // The Amazon Resource Name (ARN) of the IAM service role for Amazon Web Services - // Systems Manager to assume when running a maintenance window task. If you do not - // specify a service role ARN, Systems Manager uses your account's service-linked - // role. If no service-linked role for Systems Manager exists in your account, it - // is created when you run RegisterTaskWithMaintenanceWindow . For more - // information, see the following topics in the in the Amazon Web Services Systems - // Manager User Guide: - // - Using service-linked roles for Systems Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/using-service-linked-roles.html#slr-permissions) - // - Should I use a service-linked role or a custom service role to run - // maintenance window tasks? (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-maintenance-permissions.html#maintenance-window-tasks-service-role) - ServiceRoleArn *string - - // The targets (either managed nodes or maintenance window targets). One or more - // targets must be specified for maintenance window Run Command-type tasks. - // Depending on the task, targets are optional for other maintenance window task - // types (Automation, Lambda, and Step Functions). For more information about - // running tasks that don't specify targets, see Registering maintenance window - // tasks without targets (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // in the Amazon Web Services Systems Manager User Guide. Specify managed nodes - // using the following format: Key=InstanceIds,Values=, Specify maintenance window - // targets using the following format: Key=WindowTargetIds,Values=, - Targets []types.Target - - // The parameters that the task should use during execution. Populate only the - // fields that match the task type. All other fields should be empty. - TaskInvocationParameters *types.MaintenanceWindowTaskInvocationParameters - - // The parameters that should be passed to the task when it is run. TaskParameters - // has been deprecated. To specify parameters to pass to a task when it runs, - // instead use the Parameters option in the TaskInvocationParameters structure. - // For information about how Systems Manager handles these options for the - // supported maintenance window task types, see - // MaintenanceWindowTaskInvocationParameters . - TaskParameters map[string]types.MaintenanceWindowTaskParameterValueExpression - - noSmithyDocumentSerde -} - -type RegisterTaskWithMaintenanceWindowOutput struct { - - // The ID of the task in the maintenance window. - WindowTaskId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRegisterTaskWithMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpRegisterTaskWithMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpRegisterTaskWithMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterTaskWithMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addIdempotencyToken_opRegisterTaskWithMaintenanceWindowMiddleware(stack, options); err != nil { - return err - } - if err = addOpRegisterTaskWithMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterTaskWithMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -type idempotencyToken_initializeOpRegisterTaskWithMaintenanceWindow struct { - tokenProvider IdempotencyTokenProvider -} - -func (*idempotencyToken_initializeOpRegisterTaskWithMaintenanceWindow) ID() string { - return "OperationIdempotencyTokenAutoFill" -} - -func (m *idempotencyToken_initializeOpRegisterTaskWithMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.tokenProvider == nil { - return next.HandleInitialize(ctx, in) - } - - input, ok := in.Parameters.(*RegisterTaskWithMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("expected middleware input to be of type *RegisterTaskWithMaintenanceWindowInput ") - } - - if input.ClientToken == nil { - t, err := m.tokenProvider.GetIdempotencyToken() - if err != nil { - return out, metadata, err - } - input.ClientToken = &t - } - return next.HandleInitialize(ctx, in) -} -func addIdempotencyToken_opRegisterTaskWithMaintenanceWindowMiddleware(stack *middleware.Stack, cfg Options) error { - return stack.Initialize.Add(&idempotencyToken_initializeOpRegisterTaskWithMaintenanceWindow{tokenProvider: cfg.IdempotencyTokenProvider}, middleware.Before) -} - -func newServiceMetadataMiddleware_opRegisterTaskWithMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RegisterTaskWithMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RemoveTagsFromResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RemoveTagsFromResource.go deleted file mode 100644 index f35351e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_RemoveTagsFromResource.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes tag keys from the specified resource. -func (c *Client) RemoveTagsFromResource(ctx context.Context, params *RemoveTagsFromResourceInput, optFns ...func(*Options)) (*RemoveTagsFromResourceOutput, error) { - if params == nil { - params = &RemoveTagsFromResourceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RemoveTagsFromResource", params, optFns, c.addOperationRemoveTagsFromResourceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RemoveTagsFromResourceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RemoveTagsFromResourceInput struct { - - // The ID of the resource from which you want to remove tags. For example: - // ManagedInstance: mi-012345abcde MaintenanceWindow: mw-012345abcde Automation : - // example-c160-4567-8519-012345abcde PatchBaseline: pb-012345abcde OpsMetadata - // object: ResourceID for tagging is created from the Amazon Resource Name (ARN) - // for the object. Specifically, ResourceID is created from the strings that come - // after the word opsmetadata in the ARN. For example, an OpsMetadata object with - // an ARN of - // arn:aws:ssm:us-east-2:1234567890:opsmetadata/aws/ssm/MyGroup/appmanager has a - // ResourceID of either aws/ssm/MyGroup/appmanager or /aws/ssm/MyGroup/appmanager . - // For the Document and Parameter values, use the name of the resource. The - // ManagedInstance type for this API operation is only for on-premises managed - // nodes. Specify the name of the managed node in the following format: - // mi-ID_number. For example, mi-1a2b3c4d5e6f. - // - // This member is required. - ResourceId *string - - // The type of resource from which you want to remove a tag. The ManagedInstance - // type for this API operation is only for on-premises managed nodes. Specify the - // name of the managed node in the following format: mi-ID_number . For example, - // mi-1a2b3c4d5e6f . - // - // This member is required. - ResourceType types.ResourceTypeForTagging - - // Tag keys that you want to remove from the specified resource. - // - // This member is required. - TagKeys []string - - noSmithyDocumentSerde -} - -type RemoveTagsFromResourceOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRemoveTagsFromResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpRemoveTagsFromResource{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpRemoveTagsFromResource{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RemoveTagsFromResource"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpRemoveTagsFromResourceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRemoveTagsFromResource(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opRemoveTagsFromResource(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RemoveTagsFromResource", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResetServiceSetting.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResetServiceSetting.go deleted file mode 100644 index fef61e3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResetServiceSetting.go +++ /dev/null @@ -1,162 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ServiceSetting is an account-level setting for an Amazon Web Services service. -// This setting defines how a user interacts with or uses a service or a feature of -// a service. For example, if an Amazon Web Services service charges money to the -// account based on feature or service usage, then the Amazon Web Services service -// team might create a default setting of "false". This means the user can't use -// this feature unless they change the setting to "true" and intentionally opt in -// for a paid feature. Services map a SettingId object to a setting value. Amazon -// Web Services services teams define the default value for a SettingId . You can't -// create a new SettingId , but you can overwrite the default value if you have the -// ssm:UpdateServiceSetting permission for the setting. Use the GetServiceSetting -// API operation to view the current value. Use the UpdateServiceSetting API -// operation to change the default setting. Reset the service setting for the -// account to the default value as provisioned by the Amazon Web Services service -// team. -func (c *Client) ResetServiceSetting(ctx context.Context, params *ResetServiceSettingInput, optFns ...func(*Options)) (*ResetServiceSettingOutput, error) { - if params == nil { - params = &ResetServiceSettingInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ResetServiceSetting", params, optFns, c.addOperationResetServiceSettingMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ResetServiceSettingOutput) - out.ResultMetadata = metadata - return out, nil -} - -// The request body of the ResetServiceSetting API operation. -type ResetServiceSettingInput struct { - - // The Amazon Resource Name (ARN) of the service setting to reset. The setting ID - // can be one of the following. - // - /ssm/managed-instance/default-ec2-instance-management-role - // - /ssm/automation/customer-script-log-destination - // - /ssm/automation/customer-script-log-group-name - // - /ssm/documents/console/public-sharing-permission - // - /ssm/managed-instance/activation-tier - // - /ssm/opsinsights/opscenter - // - /ssm/parameter-store/default-parameter-tier - // - /ssm/parameter-store/high-throughput-enabled - // - // This member is required. - SettingId *string - - noSmithyDocumentSerde -} - -// The result body of the ResetServiceSetting API operation. -type ResetServiceSettingOutput struct { - - // The current, effective service setting after calling the ResetServiceSetting - // API operation. - ServiceSetting *types.ServiceSetting - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationResetServiceSettingMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpResetServiceSetting{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpResetServiceSetting{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ResetServiceSetting"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpResetServiceSettingValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opResetServiceSetting(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opResetServiceSetting(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ResetServiceSetting", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResumeSession.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResumeSession.go deleted file mode 100644 index 731f79e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_ResumeSession.go +++ /dev/null @@ -1,155 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Reconnects a session to a managed node after it has been disconnected. -// Connections can be resumed for disconnected sessions, but not terminated -// sessions. This command is primarily for use by client machines to automatically -// reconnect during intermittent network issues. It isn't intended for any other -// use. -func (c *Client) ResumeSession(ctx context.Context, params *ResumeSessionInput, optFns ...func(*Options)) (*ResumeSessionOutput, error) { - if params == nil { - params = &ResumeSessionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ResumeSession", params, optFns, c.addOperationResumeSessionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ResumeSessionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ResumeSessionInput struct { - - // The ID of the disconnected session to resume. - // - // This member is required. - SessionId *string - - noSmithyDocumentSerde -} - -type ResumeSessionOutput struct { - - // The ID of the session. - SessionId *string - - // A URL back to SSM Agent on the managed node that the Session Manager client - // uses to send commands and receive output from the managed node. Format: - // wss://ssmmessages.region.amazonaws.com/v1/data-channel/session-id?stream=(input|output) - // . region represents the Region identifier for an Amazon Web Services Region - // supported by Amazon Web Services Systems Manager, such as us-east-2 for the US - // East (Ohio) Region. For a list of supported region values, see the Region column - // in Systems Manager service endpoints (https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) - // in the Amazon Web Services General Reference. session-id represents the ID of a - // Session Manager session, such as 1a2b3c4dEXAMPLE . - StreamUrl *string - - // An encrypted token value containing session and caller information. Used to - // authenticate the connection to the managed node. - TokenValue *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationResumeSessionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpResumeSession{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpResumeSession{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ResumeSession"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpResumeSessionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opResumeSession(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opResumeSession(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ResumeSession", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendAutomationSignal.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendAutomationSignal.go deleted file mode 100644 index 94933a3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendAutomationSignal.go +++ /dev/null @@ -1,150 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Sends a signal to an Automation execution to change the current behavior or -// status of the execution. -func (c *Client) SendAutomationSignal(ctx context.Context, params *SendAutomationSignalInput, optFns ...func(*Options)) (*SendAutomationSignalOutput, error) { - if params == nil { - params = &SendAutomationSignalInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "SendAutomationSignal", params, optFns, c.addOperationSendAutomationSignalMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*SendAutomationSignalOutput) - out.ResultMetadata = metadata - return out, nil -} - -type SendAutomationSignalInput struct { - - // The unique identifier for an existing Automation execution that you want to - // send the signal to. - // - // This member is required. - AutomationExecutionId *string - - // The type of signal to send to an Automation execution. - // - // This member is required. - SignalType types.SignalType - - // The data sent with the signal. The data schema depends on the type of signal - // used in the request. For Approve and Reject signal types, the payload is an - // optional comment that you can send with the signal type. For example: - // Comment="Looks good" For StartStep and Resume signal types, you must send the - // name of the Automation step to start or resume as the payload. For example: - // StepName="step1" For the StopStep signal type, you must send the step execution - // ID as the payload. For example: - // StepExecutionId="97fff367-fc5a-4299-aed8-0123456789ab" - Payload map[string][]string - - noSmithyDocumentSerde -} - -type SendAutomationSignalOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationSendAutomationSignalMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpSendAutomationSignal{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpSendAutomationSignal{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "SendAutomationSignal"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpSendAutomationSignalValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSendAutomationSignal(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opSendAutomationSignal(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "SendAutomationSignal", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendCommand.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendCommand.go deleted file mode 100644 index 76be45f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_SendCommand.go +++ /dev/null @@ -1,238 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Runs commands on one or more managed nodes. -func (c *Client) SendCommand(ctx context.Context, params *SendCommandInput, optFns ...func(*Options)) (*SendCommandOutput, error) { - if params == nil { - params = &SendCommandInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "SendCommand", params, optFns, c.addOperationSendCommandMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*SendCommandOutput) - out.ResultMetadata = metadata - return out, nil -} - -type SendCommandInput struct { - - // The name of the Amazon Web Services Systems Manager document (SSM document) to - // run. This can be a public document or a custom document. To run a shared - // document belonging to another account, specify the document Amazon Resource Name - // (ARN). For more information about how to use shared documents, see Using shared - // SSM documents (https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-using-shared.html) - // in the Amazon Web Services Systems Manager User Guide. If you specify a document - // name or ARN that hasn't been shared with your account, you receive an - // InvalidDocument error. - // - // This member is required. - DocumentName *string - - // The CloudWatch alarm you want to apply to your command. - AlarmConfiguration *types.AlarmConfiguration - - // Enables Amazon Web Services Systems Manager to send Run Command output to - // Amazon CloudWatch Logs. Run Command is a capability of Amazon Web Services - // Systems Manager. - CloudWatchOutputConfig *types.CloudWatchOutputConfig - - // User-specified information about the command, such as a brief description of - // what the command should do. - Comment *string - - // The Sha256 or Sha1 hash created by the system when the document was created. - // Sha1 hashes have been deprecated. - DocumentHash *string - - // Sha256 or Sha1. Sha1 hashes have been deprecated. - DocumentHashType types.DocumentHashType - - // The SSM document version to use in the request. You can specify $DEFAULT, - // $LATEST, or a specific version number. If you run commands by using the Command - // Line Interface (Amazon Web Services CLI), then you must escape the first two - // options by using a backslash. If you specify a version number, then you don't - // need to use the backslash. For example: --document-version "\$DEFAULT" - // --document-version "\$LATEST" --document-version "3" - DocumentVersion *string - - // The IDs of the managed nodes where the command should run. Specifying managed - // node IDs is most useful when you are targeting a limited number of managed - // nodes, though you can specify up to 50 IDs. To target a larger number of managed - // nodes, or if you prefer not to list individual node IDs, we recommend using the - // Targets option instead. Using Targets , which accepts tag key-value pairs to - // identify the managed nodes to send commands to, you can a send command to tens, - // hundreds, or thousands of nodes at once. For more information about how to use - // targets, see Using targets and rate controls to send commands to a fleet (https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-multiple.html) - // in the Amazon Web Services Systems Manager User Guide. - InstanceIds []string - - // (Optional) The maximum number of managed nodes that are allowed to run the - // command at the same time. You can specify a number such as 10 or a percentage - // such as 10%. The default value is 50 . For more information about how to use - // MaxConcurrency , see Using concurrency controls (https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-multiple.html#send-commands-velocity) - // in the Amazon Web Services Systems Manager User Guide. - MaxConcurrency *string - - // The maximum number of errors allowed without the command failing. When the - // command fails one more time beyond the value of MaxErrors , the systems stops - // sending the command to additional targets. You can specify a number like 10 or a - // percentage like 10%. The default value is 0 . For more information about how to - // use MaxErrors , see Using error controls (https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-multiple.html#send-commands-maxerrors) - // in the Amazon Web Services Systems Manager User Guide. - MaxErrors *string - - // Configurations for sending notifications. - NotificationConfig *types.NotificationConfig - - // The name of the S3 bucket where command execution responses should be stored. - OutputS3BucketName *string - - // The directory structure within the S3 bucket where the responses should be - // stored. - OutputS3KeyPrefix *string - - // (Deprecated) You can no longer specify this parameter. The system ignores it. - // Instead, Systems Manager automatically determines the Amazon Web Services Region - // of the S3 bucket. - OutputS3Region *string - - // The required and optional parameters specified in the document being run. - Parameters map[string][]string - - // The ARN of the Identity and Access Management (IAM) service role to use to - // publish Amazon Simple Notification Service (Amazon SNS) notifications for Run - // Command commands. This role must provide the sns:Publish permission for your - // notification topic. For information about creating and using this service role, - // see Monitoring Systems Manager status changes using Amazon SNS notifications (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitoring-sns-notifications.html) - // in the Amazon Web Services Systems Manager User Guide. - ServiceRoleArn *string - - // An array of search criteria that targets managed nodes using a Key,Value - // combination that you specify. Specifying targets is most useful when you want to - // send a command to a large number of managed nodes at once. Using Targets , which - // accepts tag key-value pairs to identify managed nodes, you can send a command to - // tens, hundreds, or thousands of nodes at once. To send a command to a smaller - // number of managed nodes, you can use the InstanceIds option instead. For more - // information about how to use targets, see Sending commands to a fleet (https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-multiple.html) - // in the Amazon Web Services Systems Manager User Guide. - Targets []types.Target - - // If this time is reached and the command hasn't already started running, it - // won't run. - TimeoutSeconds *int32 - - noSmithyDocumentSerde -} - -type SendCommandOutput struct { - - // The request as it was received by Systems Manager. Also provides the command ID - // which can be used future references to this request. - Command *types.Command - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationSendCommandMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpSendCommand{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpSendCommand{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "SendCommand"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpSendCommandValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSendCommand(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opSendCommand(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "SendCommand", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAssociationsOnce.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAssociationsOnce.go deleted file mode 100644 index b1346fc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAssociationsOnce.go +++ /dev/null @@ -1,133 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Runs an association immediately and only one time. This operation can be -// helpful when troubleshooting associations. -func (c *Client) StartAssociationsOnce(ctx context.Context, params *StartAssociationsOnceInput, optFns ...func(*Options)) (*StartAssociationsOnceOutput, error) { - if params == nil { - params = &StartAssociationsOnceInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StartAssociationsOnce", params, optFns, c.addOperationStartAssociationsOnceMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StartAssociationsOnceOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StartAssociationsOnceInput struct { - - // The association IDs that you want to run immediately and only one time. - // - // This member is required. - AssociationIds []string - - noSmithyDocumentSerde -} - -type StartAssociationsOnceOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStartAssociationsOnceMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartAssociationsOnce{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStartAssociationsOnce{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StartAssociationsOnce"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpStartAssociationsOnceValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartAssociationsOnce(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStartAssociationsOnce(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StartAssociationsOnce", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAutomationExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAutomationExecution.go deleted file mode 100644 index fcdb677..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartAutomationExecution.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Initiates execution of an Automation runbook. -func (c *Client) StartAutomationExecution(ctx context.Context, params *StartAutomationExecutionInput, optFns ...func(*Options)) (*StartAutomationExecutionOutput, error) { - if params == nil { - params = &StartAutomationExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StartAutomationExecution", params, optFns, c.addOperationStartAutomationExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StartAutomationExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StartAutomationExecutionInput struct { - - // The name of the SSM document to run. This can be a public document or a custom - // document. To run a shared document belonging to another account, specify the - // document ARN. For more information about how to use shared documents, see Using - // shared SSM documents (https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-using-shared.html) - // in the Amazon Web Services Systems Manager User Guide. - // - // This member is required. - DocumentName *string - - // The CloudWatch alarm you want to apply to your automation. - AlarmConfiguration *types.AlarmConfiguration - - // User-provided idempotency token. The token must be unique, is case insensitive, - // enforces the UUID format, and can't be reused. - ClientToken *string - - // The version of the Automation runbook to use for this execution. - DocumentVersion *string - - // The maximum number of targets allowed to run this task in parallel. You can - // specify a number, such as 10, or a percentage, such as 10%. The default value is - // 10 . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops running the - // automation on additional targets. You can specify either an absolute number of - // errors, for example 10, or a percentage of the target set, for example 10%. If - // you specify 3, for example, the system stops running the automation when the - // fourth error is received. If you specify 0, then the system stops running the - // automation on additional targets after the first error result is returned. If - // you run an automation on 50 resources and set max-errors to 10%, then the system - // stops running the automation on additional targets when the sixth error is - // received. Executions that are already running an automation when max-errors is - // reached are allowed to complete, but some of these executions may fail as well. - // If you need to ensure that there won't be more than max-errors failed - // executions, set max-concurrency to 1 so the executions proceed one at a time. - MaxErrors *string - - // The execution mode of the automation. Valid modes include the following: Auto - // and Interactive. The default mode is Auto. - Mode types.ExecutionMode - - // A key-value map of execution parameters, which match the declared parameters in - // the Automation runbook. - Parameters map[string][]string - - // Optional metadata that you assign to a resource. You can specify a maximum of - // five tags for an automation. Tags enable you to categorize a resource in - // different ways, such as by purpose, owner, or environment. For example, you - // might want to tag an automation to identify an environment or operating system. - // In this case, you could specify the following key-value pairs: - // - Key=environment,Value=test - // - Key=OS,Value=Windows - // To add tags to an existing automation, use the AddTagsToResource operation. - Tags []types.Tag - - // A location is a combination of Amazon Web Services Regions and/or Amazon Web - // Services accounts where you want to run the automation. Use this operation to - // start an automation in multiple Amazon Web Services Regions and multiple Amazon - // Web Services accounts. For more information, see Running Automation workflows - // in multiple Amazon Web Services Regions and Amazon Web Services accounts (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-automation-multiple-accounts-and-regions.html) - // in the Amazon Web Services Systems Manager User Guide. - TargetLocations []types.TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The name of the parameter used as the target resource for the rate-controlled - // execution. Required if you specify targets. - TargetParameterName *string - - // A key-value mapping to target resources. Required if you specify - // TargetParameterName. - Targets []types.Target - - noSmithyDocumentSerde -} - -type StartAutomationExecutionOutput struct { - - // The unique ID of a newly scheduled automation execution. - AutomationExecutionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStartAutomationExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartAutomationExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStartAutomationExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StartAutomationExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpStartAutomationExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartAutomationExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStartAutomationExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StartAutomationExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartChangeRequestExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartChangeRequestExecution.go deleted file mode 100644 index 556361e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartChangeRequestExecution.go +++ /dev/null @@ -1,197 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Creates a change request for Change Manager. The Automation runbooks specified -// in the change request run only after all required approvals for the change -// request have been received. -func (c *Client) StartChangeRequestExecution(ctx context.Context, params *StartChangeRequestExecutionInput, optFns ...func(*Options)) (*StartChangeRequestExecutionOutput, error) { - if params == nil { - params = &StartChangeRequestExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StartChangeRequestExecution", params, optFns, c.addOperationStartChangeRequestExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StartChangeRequestExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StartChangeRequestExecutionInput struct { - - // The name of the change template document to run during the runbook workflow. - // - // This member is required. - DocumentName *string - - // Information about the Automation runbooks that are run during the runbook - // workflow. The Automation runbooks specified for the runbook workflow can't run - // until all required approvals for the change request have been received. - // - // This member is required. - Runbooks []types.Runbook - - // Indicates whether the change request can be approved automatically without the - // need for manual approvals. If AutoApprovable is enabled in a change template, - // then setting AutoApprove to true in StartChangeRequestExecution creates a - // change request that bypasses approver review. Change Calendar restrictions are - // not bypassed in this scenario. If the state of an associated calendar is CLOSED - // , change freeze approvers must still grant permission for this change request to - // run. If they don't, the change won't be processed until the calendar state is - // again OPEN . - AutoApprove bool - - // User-provided details about the change. If no details are provided, content - // specified in the Template information section of the associated change template - // is added. - ChangeDetails *string - - // The name of the change request associated with the runbook workflow to be run. - ChangeRequestName *string - - // The user-provided idempotency token. The token must be unique, is case - // insensitive, enforces the UUID format, and can't be reused. - ClientToken *string - - // The version of the change template document to run during the runbook workflow. - DocumentVersion *string - - // A key-value map of parameters that match the declared parameters in the change - // template document. - Parameters map[string][]string - - // The time that the requester expects the runbook workflow related to the change - // request to complete. The time is an estimate only that the requester provides - // for reviewers. - ScheduledEndTime *time.Time - - // The date and time specified in the change request to run the Automation - // runbooks. The Automation runbooks specified for the runbook workflow can't run - // until all required approvals for the change request have been received. - ScheduledTime *time.Time - - // Optional metadata that you assign to a resource. You can specify a maximum of - // five tags for a change request. Tags enable you to categorize a resource in - // different ways, such as by purpose, owner, or environment. For example, you - // might want to tag a change request to identify an environment or target Amazon - // Web Services Region. In this case, you could specify the following key-value - // pairs: - // - Key=Environment,Value=Production - // - Key=Region,Value=us-east-2 - Tags []types.Tag - - noSmithyDocumentSerde -} - -type StartChangeRequestExecutionOutput struct { - - // The unique ID of a runbook workflow operation. (A runbook workflow is a type of - // Automation operation.) - AutomationExecutionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStartChangeRequestExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartChangeRequestExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStartChangeRequestExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StartChangeRequestExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpStartChangeRequestExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartChangeRequestExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStartChangeRequestExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StartChangeRequestExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartSession.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartSession.go deleted file mode 100644 index 0fbe804..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StartSession.go +++ /dev/null @@ -1,180 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Initiates a connection to a target (for example, a managed node) for a Session -// Manager session. Returns a URL and token that can be used to open a WebSocket -// connection for sending input and receiving outputs. Amazon Web Services CLI -// usage: start-session is an interactive command that requires the Session -// Manager plugin to be installed on the client machine making the call. For -// information, see Install the Session Manager plugin for the Amazon Web Services -// CLI (https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html) -// in the Amazon Web Services Systems Manager User Guide. Amazon Web Services Tools -// for PowerShell usage: Start-SSMSession isn't currently supported by Amazon Web -// Services Tools for PowerShell on Windows local machines. -func (c *Client) StartSession(ctx context.Context, params *StartSessionInput, optFns ...func(*Options)) (*StartSessionOutput, error) { - if params == nil { - params = &StartSessionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StartSession", params, optFns, c.addOperationStartSessionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StartSessionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StartSessionInput struct { - - // The managed node to connect to for the session. - // - // This member is required. - Target *string - - // The name of the SSM document you want to use to define the type of session, - // input parameters, or preferences for the session. For example, - // SSM-SessionManagerRunShell . You can call the GetDocument API to verify the - // document exists before attempting to start a session. If no document name is - // provided, a shell to the managed node is launched by default. For more - // information, see Start a session (https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html) - // in the Amazon Web Services Systems Manager User Guide. - DocumentName *string - - // The values you want to specify for the parameters defined in the Session - // document. - Parameters map[string][]string - - // The reason for connecting to the instance. This value is included in the - // details for the Amazon CloudWatch Events event created when you start the - // session. - Reason *string - - noSmithyDocumentSerde -} - -type StartSessionOutput struct { - - // The ID of the session. - SessionId *string - - // A URL back to SSM Agent on the managed node that the Session Manager client - // uses to send commands and receive output from the node. Format: - // wss://ssmmessages.region.amazonaws.com/v1/data-channel/session-id?stream=(input|output) - // region represents the Region identifier for an Amazon Web Services Region - // supported by Amazon Web Services Systems Manager, such as us-east-2 for the US - // East (Ohio) Region. For a list of supported region values, see the Region column - // in Systems Manager service endpoints (https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region) - // in the Amazon Web Services General Reference. session-id represents the ID of a - // Session Manager session, such as 1a2b3c4dEXAMPLE . - StreamUrl *string - - // An encrypted token value containing session and caller information. This token - // is used to authenticate the connection to the managed node, and is valid only - // long enough to ensure the connection is successful. Never share your session's - // token. - TokenValue *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStartSessionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartSession{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStartSession{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StartSession"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpStartSessionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartSession(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStartSession(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StartSession", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StopAutomationExecution.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StopAutomationExecution.go deleted file mode 100644 index cb2928c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_StopAutomationExecution.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Stop an Automation that is currently running. -func (c *Client) StopAutomationExecution(ctx context.Context, params *StopAutomationExecutionInput, optFns ...func(*Options)) (*StopAutomationExecutionOutput, error) { - if params == nil { - params = &StopAutomationExecutionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StopAutomationExecution", params, optFns, c.addOperationStopAutomationExecutionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StopAutomationExecutionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StopAutomationExecutionInput struct { - - // The execution ID of the Automation to stop. - // - // This member is required. - AutomationExecutionId *string - - // The stop request type. Valid types include the following: Cancel and Complete. - // The default type is Cancel. - Type types.StopType - - noSmithyDocumentSerde -} - -type StopAutomationExecutionOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStopAutomationExecutionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpStopAutomationExecution{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpStopAutomationExecution{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StopAutomationExecution"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpStopAutomationExecutionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStopAutomationExecution(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStopAutomationExecution(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StopAutomationExecution", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_TerminateSession.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_TerminateSession.go deleted file mode 100644 index f1dbd68..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_TerminateSession.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Permanently ends a session and closes the data connection between the Session -// Manager client and SSM Agent on the managed node. A terminated session can't be -// resumed. -func (c *Client) TerminateSession(ctx context.Context, params *TerminateSessionInput, optFns ...func(*Options)) (*TerminateSessionOutput, error) { - if params == nil { - params = &TerminateSessionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "TerminateSession", params, optFns, c.addOperationTerminateSessionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*TerminateSessionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type TerminateSessionInput struct { - - // The ID of the session to terminate. - // - // This member is required. - SessionId *string - - noSmithyDocumentSerde -} - -type TerminateSessionOutput struct { - - // The ID of the session that has been terminated. - SessionId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationTerminateSessionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpTerminateSession{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpTerminateSession{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "TerminateSession"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpTerminateSessionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opTerminateSession(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opTerminateSession(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "TerminateSession", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UnlabelParameterVersion.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UnlabelParameterVersion.go deleted file mode 100644 index f45c3ff..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UnlabelParameterVersion.go +++ /dev/null @@ -1,150 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Remove a label or labels from a parameter. -func (c *Client) UnlabelParameterVersion(ctx context.Context, params *UnlabelParameterVersionInput, optFns ...func(*Options)) (*UnlabelParameterVersionOutput, error) { - if params == nil { - params = &UnlabelParameterVersionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UnlabelParameterVersion", params, optFns, c.addOperationUnlabelParameterVersionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UnlabelParameterVersionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UnlabelParameterVersionInput struct { - - // One or more labels to delete from the specified parameter version. - // - // This member is required. - Labels []string - - // The name of the parameter from which you want to delete one or more labels. - // - // This member is required. - Name *string - - // The specific version of the parameter which you want to delete one or more - // labels from. If it isn't present, the call will fail. - // - // This member is required. - ParameterVersion *int64 - - noSmithyDocumentSerde -} - -type UnlabelParameterVersionOutput struct { - - // The labels that aren't attached to the given parameter version. - InvalidLabels []string - - // A list of all labels deleted from the parameter. - RemovedLabels []string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUnlabelParameterVersionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUnlabelParameterVersion{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUnlabelParameterVersion{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UnlabelParameterVersion"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUnlabelParameterVersionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUnlabelParameterVersion(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUnlabelParameterVersion(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UnlabelParameterVersion", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociation.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociation.go deleted file mode 100644 index d72a698..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociation.go +++ /dev/null @@ -1,290 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Updates an association. You can update the association name and version, the -// document version, schedule, parameters, and Amazon Simple Storage Service -// (Amazon S3) output. When you call UpdateAssociation , the system removes all -// optional parameters from the request and overwrites the association with null -// values for those parameters. This is by design. You must specify all optional -// parameters in the call, even if you are not changing the parameters. This -// includes the Name parameter. Before calling this API action, we recommend that -// you call the DescribeAssociation API operation and make a note of all optional -// parameters required for your UpdateAssociation call. In order to call this API -// operation, a user, group, or role must be granted permission to call the -// DescribeAssociation API operation. If you don't have permission to call -// DescribeAssociation , then you receive the following error: An error occurred -// (AccessDeniedException) when calling the UpdateAssociation operation: User: -// isn't authorized to perform: ssm:DescribeAssociation on resource: When you -// update an association, the association immediately runs against the specified -// targets. You can add the ApplyOnlyAtCronInterval parameter to run the -// association during the next schedule run. -func (c *Client) UpdateAssociation(ctx context.Context, params *UpdateAssociationInput, optFns ...func(*Options)) (*UpdateAssociationOutput, error) { - if params == nil { - params = &UpdateAssociationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateAssociation", params, optFns, c.addOperationUpdateAssociationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateAssociationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateAssociationInput struct { - - // The ID of the association you want to update. - // - // This member is required. - AssociationId *string - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - AlarmConfiguration *types.AlarmConfiguration - - // By default, when you update an association, the system runs it immediately - // after it is updated and then according to the schedule you specified. Specify - // this option if you don't want an association to run immediately after you update - // it. This parameter isn't supported for rate expressions. If you chose this - // option when you created an association and later you edit that association or - // you make changes to the SSM document on which that association is based (by - // using the Documents page in the console), State Manager applies the association - // at the next specified cron interval. For example, if you chose the Latest - // version of an SSM document when you created an association and you edit the - // association by choosing a different document version on the Documents page, - // State Manager applies the association at the next specified cron interval if you - // previously selected this option. If this option wasn't selected, State Manager - // immediately runs the association. You can reset this option. To do so, specify - // the no-apply-only-at-cron-interval parameter when you update the association - // from the command line. This parameter forces the association to run immediately - // after updating it and according to the interval specified. - ApplyOnlyAtCronInterval bool - - // The name of the association that you want to update. - AssociationName *string - - // This parameter is provided for concurrency control purposes. You must specify - // the latest association version in the service. If you want to ensure that this - // request succeeds, either specify $LATEST , or omit this parameter. - AssociationVersion *string - - // Choose the parameter that will define how your automation will branch out. This - // target is required for associations that use an Automation runbook and target - // resources by using rate controls. Automation is a capability of Amazon Web - // Services Systems Manager. - AutomationTargetParameterName *string - - // The names or Amazon Resource Names (ARNs) of the Change Calendar type documents - // you want to gate your associations under. The associations only run when that - // change calendar is open. For more information, see Amazon Web Services Systems - // Manager Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar) - // . - CalendarNames []string - - // The severity level to assign to the association. - ComplianceSeverity types.AssociationComplianceSeverity - - // The document version you want update for the association. State Manager doesn't - // support running associations that use a new version of a document if that - // document is shared from another account. State Manager always runs the default - // version of a document if shared from another account, even though the Systems - // Manager console shows that a new version was processed. If you want to run an - // association using a new version of a document shared form another account, you - // must set the document version to default . - DocumentVersion *string - - // The maximum number of targets allowed to run the association at the same time. - // You can specify a number, for example 10, or a percentage of the target set, for - // example 10%. The default value is 100%, which means all targets run the - // association at the same time. If a new managed node starts and attempts to run - // an association while Systems Manager is running MaxConcurrency associations, - // the association is allowed to run. During the next association interval, the new - // managed node will process its association within the limit specified for - // MaxConcurrency . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops sending requests - // to run the association on additional targets. You can specify either an absolute - // number of errors, for example 10, or a percentage of the target set, for example - // 10%. If you specify 3, for example, the system stops sending requests when the - // fourth error is received. If you specify 0, then the system stops sending - // requests after the first error is returned. If you run an association on 50 - // managed nodes and set MaxError to 10%, then the system stops sending the - // request when the sixth error is received. Executions that are already running an - // association when MaxErrors is reached are allowed to complete, but some of - // these executions may fail as well. If you need to ensure that there won't be - // more than max-errors failed executions, set MaxConcurrency to 1 so that - // executions proceed one at a time. - MaxErrors *string - - // The name of the SSM Command document or Automation runbook that contains the - // configuration information for the managed node. You can specify Amazon Web - // Services-predefined documents, documents you created, or a document that is - // shared with you from another account. For Systems Manager document (SSM - // document) that are shared with you from other Amazon Web Services accounts, you - // must specify the complete SSM document ARN, in the following format: - // arn:aws:ssm:region:account-id:document/document-name For example: - // arn:aws:ssm:us-east-2:12345678912:document/My-Shared-Document For Amazon Web - // Services-predefined documents and SSM documents you created in your account, you - // only need to specify the document name. For example, AWS-ApplyPatchBaseline or - // My-Document . - Name *string - - // An S3 bucket where you want to store the results of this request. - OutputLocation *types.InstanceAssociationOutputLocation - - // The parameters you want to update for the association. If you create a - // parameter using Parameter Store, a capability of Amazon Web Services Systems - // Manager, you can reference the parameter using {{ssm:parameter-name}} . - Parameters map[string][]string - - // The cron expression used to schedule the association that you want to update. - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. For - // example, if you specified a cron schedule of cron(0 0 ? * THU#2 *) , you could - // specify an offset of 3 to run the association each Sunday after the second - // Thursday of the month. For more information about cron schedules for - // associations, see Reference: Cron and rate expressions for Systems Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/reference-cron-and-rate-expressions.html) - // in the Amazon Web Services Systems Manager User Guide. To use offsets, you must - // specify the ApplyOnlyAtCronInterval parameter. This option tells the system not - // to run an association immediately after you create it. - ScheduleOffset *int32 - - // The mode for generating association compliance. You can specify AUTO or MANUAL . - // In AUTO mode, the system uses the status of the association execution to - // determine the compliance status. If the association execution runs successfully, - // then the association is COMPLIANT . If the association execution doesn't run - // successfully, the association is NON-COMPLIANT . In MANUAL mode, you must - // specify the AssociationId as a parameter for the PutComplianceItems API - // operation. In this case, compliance data isn't managed by State Manager, a - // capability of Amazon Web Services Systems Manager. It is managed by your direct - // call to the PutComplianceItems API operation. By default, all associations use - // AUTO mode. - SyncCompliance types.AssociationSyncCompliance - - // A location is a combination of Amazon Web Services Regions and Amazon Web - // Services accounts where you want to run the association. Use this action to - // update an association in multiple Regions and multiple accounts. - TargetLocations []types.TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The targets of the association. - Targets []types.Target - - noSmithyDocumentSerde -} - -type UpdateAssociationOutput struct { - - // The description of the association that was updated. - AssociationDescription *types.AssociationDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateAssociation{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateAssociation{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateAssociation"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateAssociationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateAssociation(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateAssociation(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateAssociation", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociationStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociationStatus.go deleted file mode 100644 index 6030e69..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateAssociationStatus.go +++ /dev/null @@ -1,151 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Updates the status of the Amazon Web Services Systems Manager document (SSM -// document) associated with the specified managed node. UpdateAssociationStatus -// is primarily used by the Amazon Web Services Systems Manager Agent (SSM Agent) -// to report status updates about your associations and is only used for -// associations created with the InstanceId legacy parameter. -func (c *Client) UpdateAssociationStatus(ctx context.Context, params *UpdateAssociationStatusInput, optFns ...func(*Options)) (*UpdateAssociationStatusOutput, error) { - if params == nil { - params = &UpdateAssociationStatusInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateAssociationStatus", params, optFns, c.addOperationUpdateAssociationStatusMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateAssociationStatusOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateAssociationStatusInput struct { - - // The association status. - // - // This member is required. - AssociationStatus *types.AssociationStatus - - // The managed node ID. - // - // This member is required. - InstanceId *string - - // The name of the SSM document. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -type UpdateAssociationStatusOutput struct { - - // Information about the association. - AssociationDescription *types.AssociationDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateAssociationStatusMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateAssociationStatus{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateAssociationStatus{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateAssociationStatus"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateAssociationStatusValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateAssociationStatus(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateAssociationStatus(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateAssociationStatus", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocument.go deleted file mode 100644 index e240848..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocument.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Updates one or more values for an SSM document. -func (c *Client) UpdateDocument(ctx context.Context, params *UpdateDocumentInput, optFns ...func(*Options)) (*UpdateDocumentOutput, error) { - if params == nil { - params = &UpdateDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateDocument", params, optFns, c.addOperationUpdateDocumentMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateDocumentInput struct { - - // A valid JSON or YAML string. - // - // This member is required. - Content *string - - // The name of the SSM document that you want to update. - // - // This member is required. - Name *string - - // A list of key-value pairs that describe attachments to a version of a document. - Attachments []types.AttachmentsSource - - // The friendly name of the SSM document that you want to update. This value can - // differ for each version of the document. If you don't specify a value for this - // parameter in your request, the existing value is applied to the new document - // version. - DisplayName *string - - // Specify the document format for the new document version. Systems Manager - // supports JSON and YAML documents. JSON is the default format. - DocumentFormat types.DocumentFormat - - // The version of the document that you want to update. Currently, Systems Manager - // supports updating only the latest version of the document. You can specify the - // version number of the latest version or use the $LATEST variable. If you change - // a document version for a State Manager association, Systems Manager immediately - // runs the association unless you previously specifed the - // apply-only-at-cron-interval parameter. - DocumentVersion *string - - // Specify a new target type for the document. - TargetType *string - - // An optional field specifying the version of the artifact you are updating with - // the document. For example, "Release 12, Update 6". This value is unique across - // all versions of a document, and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -type UpdateDocumentOutput struct { - - // A description of the document that was updated. - DocumentDescription *types.DocumentDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateDocumentMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateDocument{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateDocument{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateDocument"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateDocumentValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateDocument(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateDocument(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateDocument", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentDefaultVersion.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentDefaultVersion.go deleted file mode 100644 index e395516..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentDefaultVersion.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Set the default version of a document. If you change a document version for a -// State Manager association, Systems Manager immediately runs the association -// unless you previously specifed the apply-only-at-cron-interval parameter. -func (c *Client) UpdateDocumentDefaultVersion(ctx context.Context, params *UpdateDocumentDefaultVersionInput, optFns ...func(*Options)) (*UpdateDocumentDefaultVersionOutput, error) { - if params == nil { - params = &UpdateDocumentDefaultVersionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateDocumentDefaultVersion", params, optFns, c.addOperationUpdateDocumentDefaultVersionMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateDocumentDefaultVersionOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateDocumentDefaultVersionInput struct { - - // The version of a custom document that you want to set as the default version. - // - // This member is required. - DocumentVersion *string - - // The name of a custom document that you want to set as the default version. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -type UpdateDocumentDefaultVersionOutput struct { - - // The description of a custom document that you want to set as the default - // version. - Description *types.DocumentDefaultVersionDescription - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateDocumentDefaultVersionMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateDocumentDefaultVersion{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateDocumentDefaultVersion{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateDocumentDefaultVersion"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateDocumentDefaultVersionValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateDocumentDefaultVersion(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateDocumentDefaultVersion(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateDocumentDefaultVersion", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentMetadata.go deleted file mode 100644 index 8d82e9a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateDocumentMetadata.go +++ /dev/null @@ -1,142 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Updates information related to approval reviews for a specific version of a -// change template in Change Manager. -func (c *Client) UpdateDocumentMetadata(ctx context.Context, params *UpdateDocumentMetadataInput, optFns ...func(*Options)) (*UpdateDocumentMetadataOutput, error) { - if params == nil { - params = &UpdateDocumentMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateDocumentMetadata", params, optFns, c.addOperationUpdateDocumentMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateDocumentMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateDocumentMetadataInput struct { - - // The change template review details to update. - // - // This member is required. - DocumentReviews *types.DocumentReviews - - // The name of the change template for which a version's metadata is to be updated. - // - // This member is required. - Name *string - - // The version of a change template in which to update approval metadata. - DocumentVersion *string - - noSmithyDocumentSerde -} - -type UpdateDocumentMetadataOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateDocumentMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateDocumentMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateDocumentMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateDocumentMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateDocumentMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateDocumentMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateDocumentMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateDocumentMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindow.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindow.go deleted file mode 100644 index 4be08b3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindow.go +++ /dev/null @@ -1,236 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Updates an existing maintenance window. Only specified parameters are modified. -// The value you specify for Duration determines the specific end time for the -// maintenance window based on the time it begins. No maintenance window tasks are -// permitted to start after the resulting endtime minus the number of hours you -// specify for Cutoff . For example, if the maintenance window starts at 3 PM, the -// duration is three hours, and the value you specify for Cutoff is one hour, no -// maintenance window tasks can start after 5 PM. -func (c *Client) UpdateMaintenanceWindow(ctx context.Context, params *UpdateMaintenanceWindowInput, optFns ...func(*Options)) (*UpdateMaintenanceWindowOutput, error) { - if params == nil { - params = &UpdateMaintenanceWindowInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateMaintenanceWindow", params, optFns, c.addOperationUpdateMaintenanceWindowMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateMaintenanceWindowOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateMaintenanceWindowInput struct { - - // The ID of the maintenance window to update. - // - // This member is required. - WindowId *string - - // Whether targets must be registered with the maintenance window before tasks can - // be defined for those targets. - AllowUnassociatedTargets *bool - - // The number of hours before the end of the maintenance window that Amazon Web - // Services Systems Manager stops scheduling new tasks for execution. - Cutoff *int32 - - // An optional description for the update request. - Description *string - - // The duration of the maintenance window in hours. - Duration *int32 - - // Whether the maintenance window is enabled. - Enabled *bool - - // The date and time, in ISO-8601 Extended format, for when you want the - // maintenance window to become inactive. EndDate allows you to set a date and - // time in the future when the maintenance window will no longer run. - EndDate *string - - // The name of the maintenance window. - Name *string - - // If True , then all fields that are required by the CreateMaintenanceWindow - // operation are also required for this API request. Optional fields that aren't - // specified are set to null. - Replace *bool - - // The schedule of the maintenance window in the form of a cron or rate expression. - Schedule *string - - // The number of days to wait after the date and time specified by a cron - // expression before running the maintenance window. For example, the following - // cron expression schedules a maintenance window to run the third Tuesday of every - // month at 11:30 PM. cron(30 23 ? * TUE#3 *) If the schedule offset is 2 , the - // maintenance window won't run until two days later. - ScheduleOffset *int32 - - // The time zone that the scheduled maintenance window executions are based on, in - // Internet Assigned Numbers Authority (IANA) format. For example: - // "America/Los_Angeles", "UTC", or "Asia/Seoul". For more information, see the - // Time Zone Database (https://www.iana.org/time-zones) on the IANA website. - ScheduleTimezone *string - - // The date and time, in ISO-8601 Extended format, for when you want the - // maintenance window to become active. StartDate allows you to delay activation - // of the maintenance window until the specified future date. - StartDate *string - - noSmithyDocumentSerde -} - -type UpdateMaintenanceWindowOutput struct { - - // Whether targets must be registered with the maintenance window before tasks can - // be defined for those targets. - AllowUnassociatedTargets bool - - // The number of hours before the end of the maintenance window that Amazon Web - // Services Systems Manager stops scheduling new tasks for execution. - Cutoff int32 - - // An optional description of the update. - Description *string - - // The duration of the maintenance window in hours. - Duration *int32 - - // Whether the maintenance window is enabled. - Enabled bool - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become inactive. The maintenance window won't run after this - // specified time. - EndDate *string - - // The name of the maintenance window. - Name *string - - // The schedule of the maintenance window in the form of a cron or rate expression. - Schedule *string - - // The number of days to wait to run a maintenance window after the scheduled cron - // expression date and time. - ScheduleOffset *int32 - - // The time zone that the scheduled maintenance window executions are based on, in - // Internet Assigned Numbers Authority (IANA) format. For example: - // "America/Los_Angeles", "UTC", or "Asia/Seoul". For more information, see the - // Time Zone Database (https://www.iana.org/time-zones) on the IANA website. - ScheduleTimezone *string - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become active. The maintenance window won't run before this - // specified time. - StartDate *string - - // The ID of the created maintenance window. - WindowId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateMaintenanceWindowMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateMaintenanceWindow{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateMaintenanceWindow"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateMaintenanceWindowValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateMaintenanceWindow(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateMaintenanceWindow(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateMaintenanceWindow", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTarget.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTarget.go deleted file mode 100644 index 48a366a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTarget.go +++ /dev/null @@ -1,185 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Modifies the target of an existing maintenance window. You can change the -// following: -// - Name -// - Description -// - Owner -// - IDs for an ID target -// - Tags for a Tag target -// - From any supported tag type to another. The three supported tag types are -// ID target, Tag target, and resource group. For more information, see Target . -// -// If a parameter is null, then the corresponding field isn't modified. -func (c *Client) UpdateMaintenanceWindowTarget(ctx context.Context, params *UpdateMaintenanceWindowTargetInput, optFns ...func(*Options)) (*UpdateMaintenanceWindowTargetOutput, error) { - if params == nil { - params = &UpdateMaintenanceWindowTargetInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateMaintenanceWindowTarget", params, optFns, c.addOperationUpdateMaintenanceWindowTargetMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateMaintenanceWindowTargetOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateMaintenanceWindowTargetInput struct { - - // The maintenance window ID with which to modify the target. - // - // This member is required. - WindowId *string - - // The target ID to modify. - // - // This member is required. - WindowTargetId *string - - // An optional description for the update. - Description *string - - // A name for the update. - Name *string - - // User-provided value that will be included in any Amazon CloudWatch Events - // events raised while running tasks for these targets in this maintenance window. - OwnerInformation *string - - // If True , then all fields that are required by the - // RegisterTargetWithMaintenanceWindow operation are also required for this API - // request. Optional fields that aren't specified are set to null. - Replace *bool - - // The targets to add or replace. - Targets []types.Target - - noSmithyDocumentSerde -} - -type UpdateMaintenanceWindowTargetOutput struct { - - // The updated description. - Description *string - - // The updated name. - Name *string - - // The updated owner. - OwnerInformation *string - - // The updated targets. - Targets []types.Target - - // The maintenance window ID specified in the update request. - WindowId *string - - // The target ID specified in the update request. - WindowTargetId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateMaintenanceWindowTargetMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateMaintenanceWindowTarget{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateMaintenanceWindowTarget{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateMaintenanceWindowTarget"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateMaintenanceWindowTargetValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateMaintenanceWindowTarget(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateMaintenanceWindowTarget(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateMaintenanceWindowTarget", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTask.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTask.go deleted file mode 100644 index 07abf52..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateMaintenanceWindowTask.go +++ /dev/null @@ -1,332 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Modifies a task assigned to a maintenance window. You can't change the task -// type, but you can change the following values: -// - TaskARN . For example, you can change a RUN_COMMAND task from -// AWS-RunPowerShellScript to AWS-RunShellScript . -// - ServiceRoleArn -// - TaskInvocationParameters -// - Priority -// - MaxConcurrency -// - MaxErrors -// -// One or more targets must be specified for maintenance window Run Command-type -// tasks. Depending on the task, targets are optional for other maintenance window -// task types (Automation, Lambda, and Step Functions). For more information about -// running tasks that don't specify targets, see Registering maintenance window -// tasks without targets (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) -// in the Amazon Web Services Systems Manager User Guide. If the value for a -// parameter in UpdateMaintenanceWindowTask is null, then the corresponding field -// isn't modified. If you set Replace to true, then all fields required by the -// RegisterTaskWithMaintenanceWindow operation are required for this request. -// Optional fields that aren't specified are set to null. When you update a -// maintenance window task that has options specified in TaskInvocationParameters , -// you must provide again all the TaskInvocationParameters values that you want to -// retain. The values you don't specify again are removed. For example, suppose -// that when you registered a Run Command task, you specified -// TaskInvocationParameters values for Comment , NotificationConfig , and -// OutputS3BucketName . If you update the maintenance window task and specify only -// a different OutputS3BucketName value, the values for Comment and -// NotificationConfig are removed. -func (c *Client) UpdateMaintenanceWindowTask(ctx context.Context, params *UpdateMaintenanceWindowTaskInput, optFns ...func(*Options)) (*UpdateMaintenanceWindowTaskOutput, error) { - if params == nil { - params = &UpdateMaintenanceWindowTaskInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateMaintenanceWindowTask", params, optFns, c.addOperationUpdateMaintenanceWindowTaskMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateMaintenanceWindowTaskOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateMaintenanceWindowTaskInput struct { - - // The maintenance window ID that contains the task to modify. - // - // This member is required. - WindowId *string - - // The task ID to modify. - // - // This member is required. - WindowTaskId *string - - // The CloudWatch alarm you want to apply to your maintenance window task. - AlarmConfiguration *types.AlarmConfiguration - - // Indicates whether tasks should continue to run after the cutoff time specified - // in the maintenance windows is reached. - // - CONTINUE_TASK : When the cutoff time is reached, any tasks that are running - // continue. The default value. - // - CANCEL_TASK : - // - For Automation, Lambda, Step Functions tasks: When the cutoff time is - // reached, any task invocations that are already running continue, but no new task - // invocations are started. - // - For Run Command tasks: When the cutoff time is reached, the system sends a - // CancelCommand operation that attempts to cancel the command associated with - // the task. However, there is no guarantee that the command will be terminated and - // the underlying process stopped. The status for tasks that are not completed - // is TIMED_OUT . - CutoffBehavior types.MaintenanceWindowTaskCutoffBehavior - - // The new task description to specify. - Description *string - - // The new logging location in Amazon S3 to specify. LoggingInfo has been - // deprecated. To specify an Amazon Simple Storage Service (Amazon S3) bucket to - // contain logs, instead use the OutputS3BucketName and OutputS3KeyPrefix options - // in the TaskInvocationParameters structure. For information about how Amazon Web - // Services Systems Manager handles these options for the supported maintenance - // window task types, see MaintenanceWindowTaskInvocationParameters . - LoggingInfo *types.LoggingInfo - - // The new MaxConcurrency value you want to specify. MaxConcurrency is the number - // of targets that are allowed to run this task, in parallel. Although this element - // is listed as "Required: No", a value can be omitted only when you are - // registering or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxConcurrency *string - - // The new MaxErrors value to specify. MaxErrors is the maximum number of errors - // that are allowed before the task stops being scheduled. Although this element is - // listed as "Required: No", a value can be omitted only when you are registering - // or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxErrors *string - - // The new task name to specify. - Name *string - - // The new task priority to specify. The lower the number, the higher the - // priority. Tasks that have the same priority are scheduled in parallel. - Priority *int32 - - // If True, then all fields that are required by the - // RegisterTaskWithMaintenanceWindow operation are also required for this API - // request. Optional fields that aren't specified are set to null. - Replace *bool - - // The Amazon Resource Name (ARN) of the IAM service role for Amazon Web Services - // Systems Manager to assume when running a maintenance window task. If you do not - // specify a service role ARN, Systems Manager uses your account's service-linked - // role. If no service-linked role for Systems Manager exists in your account, it - // is created when you run RegisterTaskWithMaintenanceWindow . For more - // information, see the following topics in the in the Amazon Web Services Systems - // Manager User Guide: - // - Using service-linked roles for Systems Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/using-service-linked-roles.html#slr-permissions) - // - Should I use a service-linked role or a custom service role to run - // maintenance window tasks? (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-maintenance-permissions.html#maintenance-window-tasks-service-role) - ServiceRoleArn *string - - // The targets (either managed nodes or tags) to modify. Managed nodes are - // specified using the format Key=instanceids,Values=instanceID_1,instanceID_2 . - // Tags are specified using the format Key=tag_name,Values=tag_value . One or more - // targets must be specified for maintenance window Run Command-type tasks. - // Depending on the task, targets are optional for other maintenance window task - // types (Automation, Lambda, and Step Functions). For more information about - // running tasks that don't specify targets, see Registering maintenance window - // tasks without targets (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // in the Amazon Web Services Systems Manager User Guide. - Targets []types.Target - - // The task ARN to modify. - TaskArn *string - - // The parameters that the task should use during execution. Populate only the - // fields that match the task type. All other fields should be empty. When you - // update a maintenance window task that has options specified in - // TaskInvocationParameters , you must provide again all the - // TaskInvocationParameters values that you want to retain. The values you don't - // specify again are removed. For example, suppose that when you registered a Run - // Command task, you specified TaskInvocationParameters values for Comment , - // NotificationConfig , and OutputS3BucketName . If you update the maintenance - // window task and specify only a different OutputS3BucketName value, the values - // for Comment and NotificationConfig are removed. - TaskInvocationParameters *types.MaintenanceWindowTaskInvocationParameters - - // The parameters to modify. TaskParameters has been deprecated. To specify - // parameters to pass to a task when it runs, instead use the Parameters option in - // the TaskInvocationParameters structure. For information about how Systems - // Manager handles these options for the supported maintenance window task types, - // see MaintenanceWindowTaskInvocationParameters . The map has the following - // format: Key: string, between 1 and 255 characters Value: an array of strings, - // each string is between 1 and 255 characters - TaskParameters map[string]types.MaintenanceWindowTaskParameterValueExpression - - noSmithyDocumentSerde -} - -type UpdateMaintenanceWindowTaskOutput struct { - - // The details for the CloudWatch alarm you applied to your maintenance window - // task. - AlarmConfiguration *types.AlarmConfiguration - - // The specification for whether tasks should continue to run after the cutoff - // time specified in the maintenance windows is reached. - CutoffBehavior types.MaintenanceWindowTaskCutoffBehavior - - // The updated task description. - Description *string - - // The updated logging information in Amazon S3. LoggingInfo has been deprecated. - // To specify an Amazon Simple Storage Service (Amazon S3) bucket to contain logs, - // instead use the OutputS3BucketName and OutputS3KeyPrefix options in the - // TaskInvocationParameters structure. For information about how Amazon Web - // Services Systems Manager handles these options for the supported maintenance - // window task types, see MaintenanceWindowTaskInvocationParameters . - LoggingInfo *types.LoggingInfo - - // The updated MaxConcurrency value. - MaxConcurrency *string - - // The updated MaxErrors value. - MaxErrors *string - - // The updated task name. - Name *string - - // The updated priority value. - Priority int32 - - // The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) - // service role to use to publish Amazon Simple Notification Service (Amazon SNS) - // notifications for maintenance window Run Command tasks. - ServiceRoleArn *string - - // The updated target values. - Targets []types.Target - - // The updated task ARN value. - TaskArn *string - - // The updated parameter values. - TaskInvocationParameters *types.MaintenanceWindowTaskInvocationParameters - - // The updated parameter values. TaskParameters has been deprecated. To specify - // parameters to pass to a task when it runs, instead use the Parameters option in - // the TaskInvocationParameters structure. For information about how Systems - // Manager handles these options for the supported maintenance window task types, - // see MaintenanceWindowTaskInvocationParameters . - TaskParameters map[string]types.MaintenanceWindowTaskParameterValueExpression - - // The ID of the maintenance window that was updated. - WindowId *string - - // The task ID of the maintenance window that was updated. - WindowTaskId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateMaintenanceWindowTaskMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateMaintenanceWindowTask{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateMaintenanceWindowTask{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateMaintenanceWindowTask"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateMaintenanceWindowTaskValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateMaintenanceWindowTask(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateMaintenanceWindowTask(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateMaintenanceWindowTask", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateManagedInstanceRole.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateManagedInstanceRole.go deleted file mode 100644 index 9cd1965..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateManagedInstanceRole.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Changes the Identity and Access Management (IAM) role that is assigned to the -// on-premises server, edge device, or virtual machines (VM). IAM roles are first -// assigned to these hybrid nodes during the activation process. For more -// information, see CreateActivation . -func (c *Client) UpdateManagedInstanceRole(ctx context.Context, params *UpdateManagedInstanceRoleInput, optFns ...func(*Options)) (*UpdateManagedInstanceRoleOutput, error) { - if params == nil { - params = &UpdateManagedInstanceRoleInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateManagedInstanceRole", params, optFns, c.addOperationUpdateManagedInstanceRoleMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateManagedInstanceRoleOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateManagedInstanceRoleInput struct { - - // The name of the Identity and Access Management (IAM) role that you want to - // assign to the managed node. This IAM role must provide AssumeRole permissions - // for the Amazon Web Services Systems Manager service principal ssm.amazonaws.com - // . For more information, see Create an IAM service role for a hybrid environment (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-service-role.html) - // in the Amazon Web Services Systems Manager User Guide. You can't specify an IAM - // service-linked role for this parameter. You must create a unique role. - // - // This member is required. - IamRole *string - - // The ID of the managed node where you want to update the role. - // - // This member is required. - InstanceId *string - - noSmithyDocumentSerde -} - -type UpdateManagedInstanceRoleOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateManagedInstanceRoleMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateManagedInstanceRole{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateManagedInstanceRole{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateManagedInstanceRole"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateManagedInstanceRoleValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateManagedInstanceRole(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateManagedInstanceRole(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateManagedInstanceRole", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsItem.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsItem.go deleted file mode 100644 index 6203ad2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsItem.go +++ /dev/null @@ -1,215 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Edit or change an OpsItem. You must have permission in Identity and Access -// Management (IAM) to update an OpsItem. For more information, see Set up -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-setup.html) -// in the Amazon Web Services Systems Manager User Guide. Operations engineers and -// IT professionals use Amazon Web Services Systems Manager OpsCenter to view, -// investigate, and remediate operational issues impacting the performance and -// health of their Amazon Web Services resources. For more information, see -// OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter.html) -// in the Amazon Web Services Systems Manager User Guide. -func (c *Client) UpdateOpsItem(ctx context.Context, params *UpdateOpsItemInput, optFns ...func(*Options)) (*UpdateOpsItemOutput, error) { - if params == nil { - params = &UpdateOpsItemInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateOpsItem", params, optFns, c.addOperationUpdateOpsItemMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateOpsItemOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateOpsItemInput struct { - - // The ID of the OpsItem. - // - // This member is required. - OpsItemId *string - - // The time a runbook workflow ended. Currently reported only for the OpsItem type - // /aws/changerequest . - ActualEndTime *time.Time - - // The time a runbook workflow started. Currently reported only for the OpsItem - // type /aws/changerequest . - ActualStartTime *time.Time - - // Specify a new category for an OpsItem. - Category *string - - // User-defined text that contains information about the OpsItem, in Markdown - // format. - Description *string - - // The Amazon Resource Name (ARN) of an SNS topic where notifications are sent - // when this OpsItem is edited or changed. - Notifications []types.OpsItemNotification - - // Add new keys or edit existing key-value pairs of the OperationalData map in the - // OpsItem object. Operational data is custom data that provides useful reference - // details about the OpsItem. For example, you can specify log files, error - // strings, license keys, troubleshooting tips, or other relevant data. You enter - // operational data as key-value pairs. The key has a maximum length of 128 - // characters. The value has a maximum size of 20 KB. Operational data keys can't - // begin with the following: amazon , aws , amzn , ssm , /amazon , /aws , /amzn , - // /ssm . You can choose to make the data searchable by other users in the account - // or you can restrict search access. Searchable data means that all users with - // access to the OpsItem Overview page (as provided by the DescribeOpsItems API - // operation) can view and search on the specified data. Operational data that - // isn't searchable is only viewable by users who have access to the OpsItem (as - // provided by the GetOpsItem API operation). Use the /aws/resources key in - // OperationalData to specify a related resource in the request. Use the - // /aws/automations key in OperationalData to associate an Automation runbook with - // the OpsItem. To view Amazon Web Services CLI example commands that use these - // keys, see Creating OpsItems manually (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-manually-create-OpsItems.html) - // in the Amazon Web Services Systems Manager User Guide. - OperationalData map[string]types.OpsItemDataValue - - // Keys that you want to remove from the OperationalData map. - OperationalDataToDelete []string - - // The OpsItem Amazon Resource Name (ARN). - OpsItemArn *string - - // The time specified in a change request for a runbook workflow to end. Currently - // supported only for the OpsItem type /aws/changerequest . - PlannedEndTime *time.Time - - // The time specified in a change request for a runbook workflow to start. - // Currently supported only for the OpsItem type /aws/changerequest . - PlannedStartTime *time.Time - - // The importance of this OpsItem in relation to other OpsItems in the system. - Priority *int32 - - // One or more OpsItems that share something in common with the current OpsItems. - // For example, related OpsItems can include OpsItems with similar error messages, - // impacted resources, or statuses for the impacted resource. - RelatedOpsItems []types.RelatedOpsItem - - // Specify a new severity for an OpsItem. - Severity *string - - // The OpsItem status. Status can be Open , In Progress , or Resolved . For more - // information, see Editing OpsItem details (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-working-with-OpsItems-editing-details.html) - // in the Amazon Web Services Systems Manager User Guide. - Status types.OpsItemStatus - - // A short heading that describes the nature of the OpsItem and the impacted - // resource. - Title *string - - noSmithyDocumentSerde -} - -type UpdateOpsItemOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateOpsItemMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateOpsItem{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateOpsItem{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateOpsItem"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateOpsItemValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateOpsItem(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateOpsItem(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateOpsItem", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsMetadata.go deleted file mode 100644 index 2ce5ccd..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateOpsMetadata.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Amazon Web Services Systems Manager calls this API operation when you edit -// OpsMetadata in Application Manager. -func (c *Client) UpdateOpsMetadata(ctx context.Context, params *UpdateOpsMetadataInput, optFns ...func(*Options)) (*UpdateOpsMetadataOutput, error) { - if params == nil { - params = &UpdateOpsMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateOpsMetadata", params, optFns, c.addOperationUpdateOpsMetadataMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateOpsMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateOpsMetadataInput struct { - - // The Amazon Resource Name (ARN) of the OpsMetadata Object to update. - // - // This member is required. - OpsMetadataArn *string - - // The metadata keys to delete from the OpsMetadata object. - KeysToDelete []string - - // Metadata to add to an OpsMetadata object. - MetadataToUpdate map[string]types.MetadataValue - - noSmithyDocumentSerde -} - -type UpdateOpsMetadataOutput struct { - - // The Amazon Resource Name (ARN) of the OpsMetadata Object that was updated. - OpsMetadataArn *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateOpsMetadataMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateOpsMetadata{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateOpsMetadata{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateOpsMetadata"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateOpsMetadataValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateOpsMetadata(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateOpsMetadata(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateOpsMetadata", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdatePatchBaseline.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdatePatchBaseline.go deleted file mode 100644 index 656174a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdatePatchBaseline.go +++ /dev/null @@ -1,241 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Modifies an existing patch baseline. Fields not specified in the request are -// left unchanged. For information about valid key-value pairs in PatchFilters for -// each supported operating system type, see PatchFilter . -func (c *Client) UpdatePatchBaseline(ctx context.Context, params *UpdatePatchBaselineInput, optFns ...func(*Options)) (*UpdatePatchBaselineOutput, error) { - if params == nil { - params = &UpdatePatchBaselineInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdatePatchBaseline", params, optFns, c.addOperationUpdatePatchBaselineMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdatePatchBaselineOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdatePatchBaselineInput struct { - - // The ID of the patch baseline to update. - // - // This member is required. - BaselineId *string - - // A set of rules used to include patches in the baseline. - ApprovalRules *types.PatchRuleGroup - - // A list of explicitly approved patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - ApprovedPatches []string - - // Assigns a new compliance severity level to an existing patch baseline. - ApprovedPatchesComplianceLevel types.PatchComplianceLevel - - // Indicates whether the list of approved patches includes non-security updates - // that should be applied to the managed nodes. The default value is false . - // Applies to Linux managed nodes only. - ApprovedPatchesEnableNonSecurity *bool - - // A description of the patch baseline. - Description *string - - // A set of global filters used to include patches in the baseline. - GlobalFilters *types.PatchFilterGroup - - // The name of the patch baseline. - Name *string - - // A list of explicitly rejected patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - RejectedPatches []string - - // The action for Patch Manager to take on patches included in the RejectedPackages - // list. - // - ALLOW_AS_DEPENDENCY : A package in the Rejected patches list is installed - // only if it is a dependency of another package. It is considered compliant with - // the patch baseline, and its status is reported as InstalledOther . This is the - // default action if no option is specified. - // - BLOCK : Packages in the RejectedPatches list, and packages that include them - // as dependencies, aren't installed under any circumstances. If a package was - // installed before it was added to the Rejected patches list, it is considered - // non-compliant with the patch baseline, and its status is reported as - // InstalledRejected . - RejectedPatchesAction types.PatchAction - - // If True, then all fields that are required by the CreatePatchBaseline operation - // are also required for this API request. Optional fields that aren't specified - // are set to null. - Replace *bool - - // Information about the patches to use to update the managed nodes, including - // target operating systems and source repositories. Applies to Linux managed nodes - // only. - Sources []types.PatchSource - - noSmithyDocumentSerde -} - -type UpdatePatchBaselineOutput struct { - - // A set of rules used to include patches in the baseline. - ApprovalRules *types.PatchRuleGroup - - // A list of explicitly approved patches for the baseline. - ApprovedPatches []string - - // The compliance severity level assigned to the patch baseline after the update - // completed. - ApprovedPatchesComplianceLevel types.PatchComplianceLevel - - // Indicates whether the list of approved patches includes non-security updates - // that should be applied to the managed nodes. The default value is false . - // Applies to Linux managed nodes only. - ApprovedPatchesEnableNonSecurity *bool - - // The ID of the deleted patch baseline. - BaselineId *string - - // The date when the patch baseline was created. - CreatedDate *time.Time - - // A description of the patch baseline. - Description *string - - // A set of global filters used to exclude patches from the baseline. - GlobalFilters *types.PatchFilterGroup - - // The date when the patch baseline was last modified. - ModifiedDate *time.Time - - // The name of the patch baseline. - Name *string - - // The operating system rule used by the updated patch baseline. - OperatingSystem types.OperatingSystem - - // A list of explicitly rejected patches for the baseline. - RejectedPatches []string - - // The action specified to take on patches included in the RejectedPatches list. A - // patch can be allowed only if it is a dependency of another package, or blocked - // entirely along with packages that include it as a dependency. - RejectedPatchesAction types.PatchAction - - // Information about the patches to use to update the managed nodes, including - // target operating systems and source repositories. Applies to Linux managed nodes - // only. - Sources []types.PatchSource - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdatePatchBaselineMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdatePatchBaseline{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdatePatchBaseline{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdatePatchBaseline"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdatePatchBaselineValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdatePatchBaseline(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdatePatchBaseline(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdatePatchBaseline", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateResourceDataSync.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateResourceDataSync.go deleted file mode 100644 index a741220..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateResourceDataSync.go +++ /dev/null @@ -1,150 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Update a resource data sync. After you create a resource data sync for a -// Region, you can't change the account options for that sync. For example, if you -// create a sync in the us-east-2 (Ohio) Region and you choose the Include only -// the current account option, you can't edit that sync later and choose the -// Include all accounts from my Organizations configuration option. Instead, you -// must delete the first resource data sync, and create a new one. This API -// operation only supports a resource data sync that was created with a -// SyncFromSource SyncType . -func (c *Client) UpdateResourceDataSync(ctx context.Context, params *UpdateResourceDataSyncInput, optFns ...func(*Options)) (*UpdateResourceDataSyncOutput, error) { - if params == nil { - params = &UpdateResourceDataSyncInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateResourceDataSync", params, optFns, c.addOperationUpdateResourceDataSyncMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateResourceDataSyncOutput) - out.ResultMetadata = metadata - return out, nil -} - -type UpdateResourceDataSyncInput struct { - - // The name of the resource data sync you want to update. - // - // This member is required. - SyncName *string - - // Specify information about the data sources to synchronize. - // - // This member is required. - SyncSource *types.ResourceDataSyncSource - - // The type of resource data sync. The supported SyncType is SyncFromSource. - // - // This member is required. - SyncType *string - - noSmithyDocumentSerde -} - -type UpdateResourceDataSyncOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateResourceDataSyncMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateResourceDataSync{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateResourceDataSync{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateResourceDataSync"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateResourceDataSyncValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateResourceDataSync(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateResourceDataSync(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateResourceDataSync", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateServiceSetting.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateServiceSetting.go deleted file mode 100644 index 75e4928..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/api_op_UpdateServiceSetting.go +++ /dev/null @@ -1,178 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ServiceSetting is an account-level setting for an Amazon Web Services service. -// This setting defines how a user interacts with or uses a service or a feature of -// a service. For example, if an Amazon Web Services service charges money to the -// account based on feature or service usage, then the Amazon Web Services service -// team might create a default setting of "false". This means the user can't use -// this feature unless they change the setting to "true" and intentionally opt in -// for a paid feature. Services map a SettingId object to a setting value. Amazon -// Web Services services teams define the default value for a SettingId . You can't -// create a new SettingId , but you can overwrite the default value if you have the -// ssm:UpdateServiceSetting permission for the setting. Use the GetServiceSetting -// API operation to view the current value. Or, use the ResetServiceSetting to -// change the value back to the original value defined by the Amazon Web Services -// service team. Update the service setting for the account. -func (c *Client) UpdateServiceSetting(ctx context.Context, params *UpdateServiceSettingInput, optFns ...func(*Options)) (*UpdateServiceSettingOutput, error) { - if params == nil { - params = &UpdateServiceSettingInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "UpdateServiceSetting", params, optFns, c.addOperationUpdateServiceSettingMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*UpdateServiceSettingOutput) - out.ResultMetadata = metadata - return out, nil -} - -// The request body of the UpdateServiceSetting API operation. -type UpdateServiceSettingInput struct { - - // The Amazon Resource Name (ARN) of the service setting to update. For example, - // arn:aws:ssm:us-east-1:111122223333:servicesetting/ssm/parameter-store/high-throughput-enabled - // . The setting ID can be one of the following. - // - /ssm/managed-instance/default-ec2-instance-management-role - // - /ssm/automation/customer-script-log-destination - // - /ssm/automation/customer-script-log-group-name - // - /ssm/documents/console/public-sharing-permission - // - /ssm/managed-instance/activation-tier - // - /ssm/opsinsights/opscenter - // - /ssm/parameter-store/default-parameter-tier - // - /ssm/parameter-store/high-throughput-enabled - // Permissions to update the - // /ssm/managed-instance/default-ec2-instance-management-role setting should only - // be provided to administrators. Implement least privilege access when allowing - // individuals to configure or modify the Default Host Management Configuration. - // - // This member is required. - SettingId *string - - // The new value to specify for the service setting. The following list specifies - // the available values for each setting. - // - For /ssm/managed-instance/default-ec2-instance-management-role , enter the - // name of an IAM role. - // - For /ssm/automation/customer-script-log-destination , enter CloudWatch . - // - For /ssm/automation/customer-script-log-group-name , enter the name of an - // Amazon CloudWatch Logs log group. - // - For /ssm/documents/console/public-sharing-permission , enter Enable or - // Disable . - // - For /ssm/managed-instance/activation-tier , enter standard or advanced . - // - For /ssm/opsinsights/opscenter , enter Enabled or Disabled . - // - For /ssm/parameter-store/default-parameter-tier , enter Standard , Advanced - // , or Intelligent-Tiering - // - For /ssm/parameter-store/high-throughput-enabled , enter true or false . - // - // This member is required. - SettingValue *string - - noSmithyDocumentSerde -} - -// The result body of the UpdateServiceSetting API operation. -type UpdateServiceSettingOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationUpdateServiceSettingMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateServiceSetting{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateServiceSetting{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateServiceSetting"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { - return err - } - if err = addRetryMiddlewares(stack, options); err != nil { - return err - } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { - return err - } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addOpUpdateServiceSettingValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateServiceSetting(options.Region), middleware.Before); err != nil { - return err - } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opUpdateServiceSetting(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "UpdateServiceSetting", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/auth.go deleted file mode 100644 index bad85d0..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/auth.go +++ /dev/null @@ -1,284 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -func bindAuthParamsRegion(params *AuthResolverParameters, _ interface{}, options Options) { - params.Region = options.Region -} - -type setLegacyContextSigningOptionsMiddleware struct { -} - -func (*setLegacyContextSigningOptionsMiddleware) ID() string { - return "setLegacyContextSigningOptions" -} - -func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - schemeID := rscheme.Scheme.SchemeID() - - if sn := awsmiddleware.GetSigningName(ctx); sn != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) - } - } - - if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) - } - } - - return next.HandleFinalize(ctx, in) -} - -func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) -} - -type withAnonymous struct { - resolver AuthSchemeResolver -} - -var _ AuthSchemeResolver = (*withAnonymous)(nil) - -func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - opts, err := v.resolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return nil, err - } - - opts = append(opts, &smithyauth.Option{ - SchemeID: smithyauth.SchemeIDAnonymous, - }) - return opts, nil -} - -func wrapWithAnonymousAuth(options *Options) { - if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { - return - } - - options.AuthSchemeResolver = &withAnonymous{ - resolver: options.AuthSchemeResolver, - } -} - -// AuthResolverParameters contains the set of inputs necessary for auth scheme -// resolution. -type AuthResolverParameters struct { - // The name of the operation being invoked. - Operation string - - // The region in which the operation is being invoked. - Region string -} - -func bindAuthResolverParams(operation string, input interface{}, options Options) *AuthResolverParameters { - params := &AuthResolverParameters{ - Operation: operation, - } - - bindAuthParamsRegion(params, input, options) - - return params -} - -// AuthSchemeResolver returns a set of possible authentication options for an -// operation. -type AuthSchemeResolver interface { - ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) -} - -type defaultAuthSchemeResolver struct{} - -var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) - -func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - if overrides, ok := operationAuthOptions[params.Operation]; ok { - return overrides(params), nil - } - return serviceAuthOptions(params), nil -} - -var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{} - -func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - { - SchemeID: smithyauth.SchemeIDSigV4, - SignerProperties: func() smithy.Properties { - var props smithy.Properties - smithyhttp.SetSigV4SigningName(&props, "ssm") - smithyhttp.SetSigV4SigningRegion(&props, params.Region) - return props - }(), - }, - } -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - params := bindAuthResolverParams(m.operation, getOperationInput(ctx), m.options) - options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) - } - - scheme, ok := m.selectScheme(options) - if !ok { - return out, metadata, fmt.Errorf("could not select an auth scheme") - } - - ctx = setResolvedAuthScheme(ctx, scheme) - return next.HandleFinalize(ctx, in) -} - -func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { - if option.SchemeID == smithyauth.SchemeIDAnonymous { - return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true - } - - for _, scheme := range m.options.AuthSchemes { - if scheme.SchemeID() != option.SchemeID { - continue - } - - if scheme.IdentityResolver(m.options) != nil { - return newResolvedAuthScheme(scheme, option), true - } - } - } - - return nil, false -} - -type resolvedAuthSchemeKey struct{} - -type resolvedAuthScheme struct { - Scheme smithyhttp.AuthScheme - IdentityProperties smithy.Properties - SignerProperties smithy.Properties -} - -func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { - return &resolvedAuthScheme{ - Scheme: scheme, - IdentityProperties: option.IdentityProperties, - SignerProperties: option.SignerProperties, - } -} - -func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { - return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) -} - -func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { - v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) - return v -} - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - resolver := rscheme.Scheme.IdentityResolver(m.options) - if resolver == nil { - return out, metadata, fmt.Errorf("no identity resolver") - } - - identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties) - if err != nil { - return out, metadata, fmt.Errorf("get identity: %w", err) - } - - ctx = setIdentity(ctx, identity) - return next.HandleFinalize(ctx, in) -} - -type identityKey struct{} - -func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { - return middleware.WithStackValue(ctx, identityKey{}, identity) -} - -func getIdentity(ctx context.Context) smithyauth.Identity { - v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) - return v -} - -type signRequestMiddleware struct { -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - identity := getIdentity(ctx) - if identity == nil { - return out, metadata, fmt.Errorf("no identity") - } - - signer := rscheme.Scheme.Signer() - if signer == nil { - return out, metadata, fmt.Errorf("no signer") - } - - if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil { - return out, metadata, fmt.Errorf("sign request: %w", err) - } - - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/deserializers.go deleted file mode 100644 index 048cc31..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/deserializers.go +++ /dev/null @@ -1,48904 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "bytes" - "context" - "encoding/base64" - "encoding/json" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - smithy "github.com/aws/smithy-go" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" - "io" - "strings" -) - -type awsAwsjson11_deserializeOpAddTagsToResource struct { -} - -func (*awsAwsjson11_deserializeOpAddTagsToResource) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpAddTagsToResource) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorAddTagsToResource(response, &metadata) - } - output := &AddTagsToResourceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentAddTagsToResourceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorAddTagsToResource(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("InvalidResourceType", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceType(response, errorBody) - - case strings.EqualFold("TooManyTagsError", errorCode): - return awsAwsjson11_deserializeErrorTooManyTagsError(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpAssociateOpsItemRelatedItem struct { -} - -func (*awsAwsjson11_deserializeOpAssociateOpsItemRelatedItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpAssociateOpsItemRelatedItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorAssociateOpsItemRelatedItem(response, &metadata) - } - output := &AssociateOpsItemRelatedItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentAssociateOpsItemRelatedItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorAssociateOpsItemRelatedItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemConflictException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemConflictException(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - case strings.EqualFold("OpsItemLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemLimitExceededException(response, errorBody) - - case strings.EqualFold("OpsItemNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemNotFoundException(response, errorBody) - - case strings.EqualFold("OpsItemRelatedItemAlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemRelatedItemAlreadyExistsException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCancelCommand struct { -} - -func (*awsAwsjson11_deserializeOpCancelCommand) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCancelCommand) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCancelCommand(response, &metadata) - } - output := &CancelCommandOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCancelCommandOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCancelCommand(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DuplicateInstanceId", errorCode): - return awsAwsjson11_deserializeErrorDuplicateInstanceId(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidCommandId", errorCode): - return awsAwsjson11_deserializeErrorInvalidCommandId(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCancelMaintenanceWindowExecution struct { -} - -func (*awsAwsjson11_deserializeOpCancelMaintenanceWindowExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCancelMaintenanceWindowExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCancelMaintenanceWindowExecution(response, &metadata) - } - output := &CancelMaintenanceWindowExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCancelMaintenanceWindowExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCancelMaintenanceWindowExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateActivation struct { -} - -func (*awsAwsjson11_deserializeOpCreateActivation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateActivation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateActivation(response, &metadata) - } - output := &CreateActivationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateActivationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateActivation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidParameters", errorCode): - return awsAwsjson11_deserializeErrorInvalidParameters(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateAssociation struct { -} - -func (*awsAwsjson11_deserializeOpCreateAssociation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateAssociation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateAssociation(response, &metadata) - } - output := &CreateAssociationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateAssociationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateAssociation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationAlreadyExists", errorCode): - return awsAwsjson11_deserializeErrorAssociationAlreadyExists(response, errorBody) - - case strings.EqualFold("AssociationLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorAssociationLimitExceeded(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidOutputLocation", errorCode): - return awsAwsjson11_deserializeErrorInvalidOutputLocation(response, errorBody) - - case strings.EqualFold("InvalidParameters", errorCode): - return awsAwsjson11_deserializeErrorInvalidParameters(response, errorBody) - - case strings.EqualFold("InvalidSchedule", errorCode): - return awsAwsjson11_deserializeErrorInvalidSchedule(response, errorBody) - - case strings.EqualFold("InvalidTag", errorCode): - return awsAwsjson11_deserializeErrorInvalidTag(response, errorBody) - - case strings.EqualFold("InvalidTarget", errorCode): - return awsAwsjson11_deserializeErrorInvalidTarget(response, errorBody) - - case strings.EqualFold("InvalidTargetMaps", errorCode): - return awsAwsjson11_deserializeErrorInvalidTargetMaps(response, errorBody) - - case strings.EqualFold("UnsupportedPlatformType", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedPlatformType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateAssociationBatch struct { -} - -func (*awsAwsjson11_deserializeOpCreateAssociationBatch) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateAssociationBatch) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateAssociationBatch(response, &metadata) - } - output := &CreateAssociationBatchOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateAssociationBatchOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateAssociationBatch(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorAssociationLimitExceeded(response, errorBody) - - case strings.EqualFold("DuplicateInstanceId", errorCode): - return awsAwsjson11_deserializeErrorDuplicateInstanceId(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidOutputLocation", errorCode): - return awsAwsjson11_deserializeErrorInvalidOutputLocation(response, errorBody) - - case strings.EqualFold("InvalidParameters", errorCode): - return awsAwsjson11_deserializeErrorInvalidParameters(response, errorBody) - - case strings.EqualFold("InvalidSchedule", errorCode): - return awsAwsjson11_deserializeErrorInvalidSchedule(response, errorBody) - - case strings.EqualFold("InvalidTarget", errorCode): - return awsAwsjson11_deserializeErrorInvalidTarget(response, errorBody) - - case strings.EqualFold("InvalidTargetMaps", errorCode): - return awsAwsjson11_deserializeErrorInvalidTargetMaps(response, errorBody) - - case strings.EqualFold("UnsupportedPlatformType", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedPlatformType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateDocument struct { -} - -func (*awsAwsjson11_deserializeOpCreateDocument) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateDocument) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateDocument(response, &metadata) - } - output := &CreateDocumentOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateDocumentOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateDocument(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DocumentAlreadyExists", errorCode): - return awsAwsjson11_deserializeErrorDocumentAlreadyExists(response, errorBody) - - case strings.EqualFold("DocumentLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorDocumentLimitExceeded(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocumentContent", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentContent(response, errorBody) - - case strings.EqualFold("InvalidDocumentSchemaVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentSchemaVersion(response, errorBody) - - case strings.EqualFold("MaxDocumentSizeExceeded", errorCode): - return awsAwsjson11_deserializeErrorMaxDocumentSizeExceeded(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpCreateMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateMaintenanceWindow(response, &metadata) - } - output := &CreateMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateOpsItem struct { -} - -func (*awsAwsjson11_deserializeOpCreateOpsItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateOpsItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateOpsItem(response, &metadata) - } - output := &CreateOpsItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateOpsItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateOpsItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemAccessDeniedException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemAccessDeniedException(response, errorBody) - - case strings.EqualFold("OpsItemAlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemAlreadyExistsException(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - case strings.EqualFold("OpsItemLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateOpsMetadata struct { -} - -func (*awsAwsjson11_deserializeOpCreateOpsMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateOpsMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateOpsMetadata(response, &metadata) - } - output := &CreateOpsMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateOpsMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateOpsMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsMetadataAlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataAlreadyExistsException(response, errorBody) - - case strings.EqualFold("OpsMetadataInvalidArgumentException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response, errorBody) - - case strings.EqualFold("OpsMetadataLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataLimitExceededException(response, errorBody) - - case strings.EqualFold("OpsMetadataTooManyUpdatesException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataTooManyUpdatesException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreatePatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpCreatePatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreatePatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreatePatchBaseline(response, &metadata) - } - output := &CreatePatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreatePatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreatePatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpCreateResourceDataSync struct { -} - -func (*awsAwsjson11_deserializeOpCreateResourceDataSync) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpCreateResourceDataSync) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorCreateResourceDataSync(response, &metadata) - } - output := &CreateResourceDataSyncOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentCreateResourceDataSyncOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorCreateResourceDataSync(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceDataSyncAlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncAlreadyExistsException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncCountExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncCountExceededException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncInvalidConfigurationException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncInvalidConfigurationException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteActivation struct { -} - -func (*awsAwsjson11_deserializeOpDeleteActivation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteActivation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteActivation(response, &metadata) - } - output := &DeleteActivationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteActivationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteActivation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidActivation", errorCode): - return awsAwsjson11_deserializeErrorInvalidActivation(response, errorBody) - - case strings.EqualFold("InvalidActivationId", errorCode): - return awsAwsjson11_deserializeErrorInvalidActivationId(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteAssociation struct { -} - -func (*awsAwsjson11_deserializeOpDeleteAssociation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteAssociation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteAssociation(response, &metadata) - } - output := &DeleteAssociationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteAssociationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteAssociation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteDocument struct { -} - -func (*awsAwsjson11_deserializeOpDeleteDocument) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteDocument) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteDocument(response, &metadata) - } - output := &DeleteDocumentOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteDocumentOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteDocument(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociatedInstances", errorCode): - return awsAwsjson11_deserializeErrorAssociatedInstances(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentOperation", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentOperation(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteInventory struct { -} - -func (*awsAwsjson11_deserializeOpDeleteInventory) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteInventory) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteInventory(response, &metadata) - } - output := &DeleteInventoryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteInventoryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteInventory(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDeleteInventoryParametersException", errorCode): - return awsAwsjson11_deserializeErrorInvalidDeleteInventoryParametersException(response, errorBody) - - case strings.EqualFold("InvalidInventoryRequestException", errorCode): - return awsAwsjson11_deserializeErrorInvalidInventoryRequestException(response, errorBody) - - case strings.EqualFold("InvalidOptionException", errorCode): - return awsAwsjson11_deserializeErrorInvalidOptionException(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpDeleteMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteMaintenanceWindow(response, &metadata) - } - output := &DeleteMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteOpsItem struct { -} - -func (*awsAwsjson11_deserializeOpDeleteOpsItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteOpsItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteOpsItem(response, &metadata) - } - output := &DeleteOpsItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteOpsItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteOpsItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteOpsMetadata struct { -} - -func (*awsAwsjson11_deserializeOpDeleteOpsMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteOpsMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteOpsMetadata(response, &metadata) - } - output := &DeleteOpsMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteOpsMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteOpsMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsMetadataInvalidArgumentException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response, errorBody) - - case strings.EqualFold("OpsMetadataNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteParameter struct { -} - -func (*awsAwsjson11_deserializeOpDeleteParameter) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteParameter) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteParameter(response, &metadata) - } - output := &DeleteParameterOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteParameterOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteParameter(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ParameterNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterNotFound(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteParameters struct { -} - -func (*awsAwsjson11_deserializeOpDeleteParameters) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteParameters) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteParameters(response, &metadata) - } - output := &DeleteParametersOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteParametersOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteParameters(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeletePatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpDeletePatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeletePatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeletePatchBaseline(response, &metadata) - } - output := &DeletePatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeletePatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeletePatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceInUseException", errorCode): - return awsAwsjson11_deserializeErrorResourceInUseException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteResourceDataSync struct { -} - -func (*awsAwsjson11_deserializeOpDeleteResourceDataSync) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteResourceDataSync) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteResourceDataSync(response, &metadata) - } - output := &DeleteResourceDataSyncOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteResourceDataSyncOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteResourceDataSync(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceDataSyncInvalidConfigurationException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncInvalidConfigurationException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeleteResourcePolicy struct { -} - -func (*awsAwsjson11_deserializeOpDeleteResourcePolicy) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeleteResourcePolicy) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeleteResourcePolicy(response, &metadata) - } - output := &DeleteResourcePolicyOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeleteResourcePolicyOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeleteResourcePolicy(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourcePolicyConflictException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyConflictException(response, errorBody) - - case strings.EqualFold("ResourcePolicyInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyInvalidParameterException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeregisterManagedInstance struct { -} - -func (*awsAwsjson11_deserializeOpDeregisterManagedInstance) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeregisterManagedInstance) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeregisterManagedInstance(response, &metadata) - } - output := &DeregisterManagedInstanceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeregisterManagedInstanceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeregisterManagedInstance(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeregisterPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_deserializeOpDeregisterPatchBaselineForPatchGroup) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeregisterPatchBaselineForPatchGroup) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeregisterPatchBaselineForPatchGroup(response, &metadata) - } - output := &DeregisterPatchBaselineForPatchGroupOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeregisterPatchBaselineForPatchGroupOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeregisterPatchBaselineForPatchGroup(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeregisterTargetFromMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpDeregisterTargetFromMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeregisterTargetFromMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeregisterTargetFromMaintenanceWindow(response, &metadata) - } - output := &DeregisterTargetFromMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeregisterTargetFromMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeregisterTargetFromMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("TargetInUseException", errorCode): - return awsAwsjson11_deserializeErrorTargetInUseException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDeregisterTaskFromMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpDeregisterTaskFromMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDeregisterTaskFromMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDeregisterTaskFromMaintenanceWindow(response, &metadata) - } - output := &DeregisterTaskFromMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDeregisterTaskFromMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDeregisterTaskFromMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeActivations struct { -} - -func (*awsAwsjson11_deserializeOpDescribeActivations) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeActivations) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeActivations(response, &metadata) - } - output := &DescribeActivationsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeActivationsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeActivations(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAssociation struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAssociation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAssociation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAssociation(response, &metadata) - } - output := &DescribeAssociationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAssociationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAssociation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAssociationVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidAssociationVersion(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAssociationExecutions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAssociationExecutions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAssociationExecutions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAssociationExecutions(response, &metadata) - } - output := &DescribeAssociationExecutionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAssociationExecutionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAssociationExecutions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAssociationExecutionTargets struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAssociationExecutionTargets) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAssociationExecutionTargets) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAssociationExecutionTargets(response, &metadata) - } - output := &DescribeAssociationExecutionTargetsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAssociationExecutionTargetsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAssociationExecutionTargets(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("AssociationExecutionDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationExecutionDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAutomationExecutions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAutomationExecutions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAutomationExecutions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAutomationExecutions(response, &metadata) - } - output := &DescribeAutomationExecutionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAutomationExecutionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAutomationExecutions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidFilterValue", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterValue(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAutomationStepExecutions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAutomationStepExecutions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAutomationStepExecutions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAutomationStepExecutions(response, &metadata) - } - output := &DescribeAutomationStepExecutionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAutomationStepExecutionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAutomationStepExecutions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationExecutionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionNotFoundException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidFilterValue", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterValue(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeAvailablePatches struct { -} - -func (*awsAwsjson11_deserializeOpDescribeAvailablePatches) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeAvailablePatches) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeAvailablePatches(response, &metadata) - } - output := &DescribeAvailablePatchesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeAvailablePatchesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeAvailablePatches(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeDocument struct { -} - -func (*awsAwsjson11_deserializeOpDescribeDocument) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeDocument) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeDocument(response, &metadata) - } - output := &DescribeDocumentOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeDocumentOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeDocument(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeDocumentPermission struct { -} - -func (*awsAwsjson11_deserializeOpDescribeDocumentPermission) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeDocumentPermission) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeDocumentPermission(response, &metadata) - } - output := &DescribeDocumentPermissionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeDocumentPermissionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeDocumentPermission(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentOperation", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentOperation(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidPermissionType", errorCode): - return awsAwsjson11_deserializeErrorInvalidPermissionType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeEffectiveInstanceAssociations struct { -} - -func (*awsAwsjson11_deserializeOpDescribeEffectiveInstanceAssociations) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeEffectiveInstanceAssociations) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeEffectiveInstanceAssociations(response, &metadata) - } - output := &DescribeEffectiveInstanceAssociationsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeEffectiveInstanceAssociationsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeEffectiveInstanceAssociations(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeEffectivePatchesForPatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpDescribeEffectivePatchesForPatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeEffectivePatchesForPatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeEffectivePatchesForPatchBaseline(response, &metadata) - } - output := &DescribeEffectivePatchesForPatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeEffectivePatchesForPatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeEffectivePatchesForPatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("UnsupportedOperatingSystem", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedOperatingSystem(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInstanceAssociationsStatus struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInstanceAssociationsStatus) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInstanceAssociationsStatus) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInstanceAssociationsStatus(response, &metadata) - } - output := &DescribeInstanceAssociationsStatusOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInstanceAssociationsStatusOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInstanceAssociationsStatus(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInstanceInformation struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInstanceInformation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInstanceInformation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInstanceInformation(response, &metadata) - } - output := &DescribeInstanceInformationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInstanceInformationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInstanceInformation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidInstanceInformationFilterValue", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceInformationFilterValue(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInstancePatches struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInstancePatches) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInstancePatches) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInstancePatches(response, &metadata) - } - output := &DescribeInstancePatchesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInstancePatchesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInstancePatches(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInstancePatchStates struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInstancePatchStates) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInstancePatchStates) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInstancePatchStates(response, &metadata) - } - output := &DescribeInstancePatchStatesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInstancePatchStatesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInstancePatchStates(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInstancePatchStatesForPatchGroup struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInstancePatchStatesForPatchGroup) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInstancePatchStatesForPatchGroup) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInstancePatchStatesForPatchGroup(response, &metadata) - } - output := &DescribeInstancePatchStatesForPatchGroupOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInstancePatchStatesForPatchGroupOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInstancePatchStatesForPatchGroup(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeInventoryDeletions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeInventoryDeletions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeInventoryDeletions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeInventoryDeletions(response, &metadata) - } - output := &DescribeInventoryDeletionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeInventoryDeletionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeInventoryDeletions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDeletionIdException", errorCode): - return awsAwsjson11_deserializeErrorInvalidDeletionIdException(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutions(response, &metadata) - } - output := &DescribeMaintenanceWindowExecutionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTaskInvocations struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTaskInvocations) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTaskInvocations) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutionTaskInvocations(response, &metadata) - } - output := &DescribeMaintenanceWindowExecutionTaskInvocationsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionTaskInvocationsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutionTaskInvocations(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTasks struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTasks) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowExecutionTasks) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutionTasks(response, &metadata) - } - output := &DescribeMaintenanceWindowExecutionTasksOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionTasksOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowExecutionTasks(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindows struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindows) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindows) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindows(response, &metadata) - } - output := &DescribeMaintenanceWindowsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindows(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowSchedule struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowSchedule) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowSchedule) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowSchedule(response, &metadata) - } - output := &DescribeMaintenanceWindowScheduleOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowScheduleOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowSchedule(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowsForTarget struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowsForTarget) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowsForTarget) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowsForTarget(response, &metadata) - } - output := &DescribeMaintenanceWindowsForTargetOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowsForTargetOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowsForTarget(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowTargets struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowTargets) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowTargets) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowTargets(response, &metadata) - } - output := &DescribeMaintenanceWindowTargetsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowTargetsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowTargets(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeMaintenanceWindowTasks struct { -} - -func (*awsAwsjson11_deserializeOpDescribeMaintenanceWindowTasks) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeMaintenanceWindowTasks) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowTasks(response, &metadata) - } - output := &DescribeMaintenanceWindowTasksOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowTasksOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeMaintenanceWindowTasks(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeOpsItems struct { -} - -func (*awsAwsjson11_deserializeOpDescribeOpsItems) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeOpsItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeOpsItems(response, &metadata) - } - output := &DescribeOpsItemsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeOpsItemsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeOpsItems(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeParameters struct { -} - -func (*awsAwsjson11_deserializeOpDescribeParameters) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeParameters) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeParameters(response, &metadata) - } - output := &DescribeParametersOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeParametersOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeParameters(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidFilterOption", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterOption(response, errorBody) - - case strings.EqualFold("InvalidFilterValue", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterValue(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribePatchBaselines struct { -} - -func (*awsAwsjson11_deserializeOpDescribePatchBaselines) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribePatchBaselines) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribePatchBaselines(response, &metadata) - } - output := &DescribePatchBaselinesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribePatchBaselinesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribePatchBaselines(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribePatchGroups struct { -} - -func (*awsAwsjson11_deserializeOpDescribePatchGroups) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribePatchGroups) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribePatchGroups(response, &metadata) - } - output := &DescribePatchGroupsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribePatchGroupsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribePatchGroups(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribePatchGroupState struct { -} - -func (*awsAwsjson11_deserializeOpDescribePatchGroupState) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribePatchGroupState) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribePatchGroupState(response, &metadata) - } - output := &DescribePatchGroupStateOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribePatchGroupStateOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribePatchGroupState(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribePatchProperties struct { -} - -func (*awsAwsjson11_deserializeOpDescribePatchProperties) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribePatchProperties) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribePatchProperties(response, &metadata) - } - output := &DescribePatchPropertiesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribePatchPropertiesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribePatchProperties(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDescribeSessions struct { -} - -func (*awsAwsjson11_deserializeOpDescribeSessions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDescribeSessions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDescribeSessions(response, &metadata) - } - output := &DescribeSessionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDescribeSessionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDescribeSessions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpDisassociateOpsItemRelatedItem struct { -} - -func (*awsAwsjson11_deserializeOpDisassociateOpsItemRelatedItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpDisassociateOpsItemRelatedItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorDisassociateOpsItemRelatedItem(response, &metadata) - } - output := &DisassociateOpsItemRelatedItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentDisassociateOpsItemRelatedItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorDisassociateOpsItemRelatedItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemConflictException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemConflictException(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - case strings.EqualFold("OpsItemNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemNotFoundException(response, errorBody) - - case strings.EqualFold("OpsItemRelatedItemAssociationNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemRelatedItemAssociationNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetAutomationExecution struct { -} - -func (*awsAwsjson11_deserializeOpGetAutomationExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetAutomationExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetAutomationExecution(response, &metadata) - } - output := &GetAutomationExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetAutomationExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetAutomationExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationExecutionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionNotFoundException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetCalendarState struct { -} - -func (*awsAwsjson11_deserializeOpGetCalendarState) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetCalendarState) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetCalendarState(response, &metadata) - } - output := &GetCalendarStateOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetCalendarStateOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetCalendarState(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentType", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentType(response, errorBody) - - case strings.EqualFold("UnsupportedCalendarException", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedCalendarException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetCommandInvocation struct { -} - -func (*awsAwsjson11_deserializeOpGetCommandInvocation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetCommandInvocation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetCommandInvocation(response, &metadata) - } - output := &GetCommandInvocationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetCommandInvocationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetCommandInvocation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidCommandId", errorCode): - return awsAwsjson11_deserializeErrorInvalidCommandId(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidPluginName", errorCode): - return awsAwsjson11_deserializeErrorInvalidPluginName(response, errorBody) - - case strings.EqualFold("InvocationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorInvocationDoesNotExist(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetConnectionStatus struct { -} - -func (*awsAwsjson11_deserializeOpGetConnectionStatus) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetConnectionStatus) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetConnectionStatus(response, &metadata) - } - output := &GetConnectionStatusOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetConnectionStatusOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetConnectionStatus(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetDefaultPatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpGetDefaultPatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetDefaultPatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetDefaultPatchBaseline(response, &metadata) - } - output := &GetDefaultPatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetDefaultPatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetDefaultPatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetDeployablePatchSnapshotForInstance struct { -} - -func (*awsAwsjson11_deserializeOpGetDeployablePatchSnapshotForInstance) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetDeployablePatchSnapshotForInstance) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetDeployablePatchSnapshotForInstance(response, &metadata) - } - output := &GetDeployablePatchSnapshotForInstanceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetDeployablePatchSnapshotForInstanceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetDeployablePatchSnapshotForInstance(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("UnsupportedFeatureRequiredException", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedFeatureRequiredException(response, errorBody) - - case strings.EqualFold("UnsupportedOperatingSystem", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedOperatingSystem(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetDocument struct { -} - -func (*awsAwsjson11_deserializeOpGetDocument) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetDocument) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetDocument(response, &metadata) - } - output := &GetDocumentOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetDocumentOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetDocument(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetInventory struct { -} - -func (*awsAwsjson11_deserializeOpGetInventory) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetInventory) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetInventory(response, &metadata) - } - output := &GetInventoryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetInventoryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetInventory(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAggregatorException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAggregatorException(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidInventoryGroupException", errorCode): - return awsAwsjson11_deserializeErrorInvalidInventoryGroupException(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidResultAttributeException", errorCode): - return awsAwsjson11_deserializeErrorInvalidResultAttributeException(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetInventorySchema struct { -} - -func (*awsAwsjson11_deserializeOpGetInventorySchema) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetInventorySchema) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetInventorySchema(response, &metadata) - } - output := &GetInventorySchemaOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetInventorySchemaOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetInventorySchema(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpGetMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetMaintenanceWindow(response, &metadata) - } - output := &GetMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetMaintenanceWindowExecution struct { -} - -func (*awsAwsjson11_deserializeOpGetMaintenanceWindowExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetMaintenanceWindowExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecution(response, &metadata) - } - output := &GetMaintenanceWindowExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTask struct { -} - -func (*awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTask) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTask) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecutionTask(response, &metadata) - } - output := &GetMaintenanceWindowExecutionTaskOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionTaskOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecutionTask(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTaskInvocation struct { -} - -func (*awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTaskInvocation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetMaintenanceWindowExecutionTaskInvocation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecutionTaskInvocation(response, &metadata) - } - output := &GetMaintenanceWindowExecutionTaskInvocationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionTaskInvocationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetMaintenanceWindowExecutionTaskInvocation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetMaintenanceWindowTask struct { -} - -func (*awsAwsjson11_deserializeOpGetMaintenanceWindowTask) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetMaintenanceWindowTask) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetMaintenanceWindowTask(response, &metadata) - } - output := &GetMaintenanceWindowTaskOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowTaskOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetMaintenanceWindowTask(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetOpsItem struct { -} - -func (*awsAwsjson11_deserializeOpGetOpsItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetOpsItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetOpsItem(response, &metadata) - } - output := &GetOpsItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetOpsItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetOpsItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemAccessDeniedException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemAccessDeniedException(response, errorBody) - - case strings.EqualFold("OpsItemNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetOpsMetadata struct { -} - -func (*awsAwsjson11_deserializeOpGetOpsMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetOpsMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetOpsMetadata(response, &metadata) - } - output := &GetOpsMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetOpsMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetOpsMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsMetadataInvalidArgumentException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response, errorBody) - - case strings.EqualFold("OpsMetadataNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetOpsSummary struct { -} - -func (*awsAwsjson11_deserializeOpGetOpsSummary) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetOpsSummary) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetOpsSummary(response, &metadata) - } - output := &GetOpsSummaryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetOpsSummaryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetOpsSummary(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAggregatorException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAggregatorException(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetParameter struct { -} - -func (*awsAwsjson11_deserializeOpGetParameter) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetParameter) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetParameter(response, &metadata) - } - output := &GetParameterOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetParameterOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetParameter(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidKeyId", errorCode): - return awsAwsjson11_deserializeErrorInvalidKeyId(response, errorBody) - - case strings.EqualFold("ParameterNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterNotFound(response, errorBody) - - case strings.EqualFold("ParameterVersionNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterVersionNotFound(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetParameterHistory struct { -} - -func (*awsAwsjson11_deserializeOpGetParameterHistory) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetParameterHistory) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetParameterHistory(response, &metadata) - } - output := &GetParameterHistoryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetParameterHistoryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetParameterHistory(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidKeyId", errorCode): - return awsAwsjson11_deserializeErrorInvalidKeyId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("ParameterNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterNotFound(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetParameters struct { -} - -func (*awsAwsjson11_deserializeOpGetParameters) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetParameters) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetParameters(response, &metadata) - } - output := &GetParametersOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetParametersOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetParameters(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidKeyId", errorCode): - return awsAwsjson11_deserializeErrorInvalidKeyId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetParametersByPath struct { -} - -func (*awsAwsjson11_deserializeOpGetParametersByPath) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetParametersByPath) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetParametersByPath(response, &metadata) - } - output := &GetParametersByPathOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetParametersByPathOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetParametersByPath(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidFilterOption", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterOption(response, errorBody) - - case strings.EqualFold("InvalidFilterValue", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterValue(response, errorBody) - - case strings.EqualFold("InvalidKeyId", errorCode): - return awsAwsjson11_deserializeErrorInvalidKeyId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetPatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpGetPatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetPatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetPatchBaseline(response, &metadata) - } - output := &GetPatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetPatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetPatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_deserializeOpGetPatchBaselineForPatchGroup) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetPatchBaselineForPatchGroup) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetPatchBaselineForPatchGroup(response, &metadata) - } - output := &GetPatchBaselineForPatchGroupOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetPatchBaselineForPatchGroupOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetPatchBaselineForPatchGroup(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetResourcePolicies struct { -} - -func (*awsAwsjson11_deserializeOpGetResourcePolicies) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetResourcePolicies) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetResourcePolicies(response, &metadata) - } - output := &GetResourcePoliciesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetResourcePoliciesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetResourcePolicies(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourcePolicyInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyInvalidParameterException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpGetServiceSetting struct { -} - -func (*awsAwsjson11_deserializeOpGetServiceSetting) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpGetServiceSetting) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorGetServiceSetting(response, &metadata) - } - output := &GetServiceSettingOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentGetServiceSettingOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorGetServiceSetting(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ServiceSettingNotFound", errorCode): - return awsAwsjson11_deserializeErrorServiceSettingNotFound(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpLabelParameterVersion struct { -} - -func (*awsAwsjson11_deserializeOpLabelParameterVersion) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpLabelParameterVersion) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorLabelParameterVersion(response, &metadata) - } - output := &LabelParameterVersionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentLabelParameterVersionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorLabelParameterVersion(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ParameterNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterNotFound(response, errorBody) - - case strings.EqualFold("ParameterVersionLabelLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorParameterVersionLabelLimitExceeded(response, errorBody) - - case strings.EqualFold("ParameterVersionNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterVersionNotFound(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListAssociations struct { -} - -func (*awsAwsjson11_deserializeOpListAssociations) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListAssociations) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListAssociations(response, &metadata) - } - output := &ListAssociationsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListAssociationsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListAssociations(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListAssociationVersions struct { -} - -func (*awsAwsjson11_deserializeOpListAssociationVersions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListAssociationVersions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListAssociationVersions(response, &metadata) - } - output := &ListAssociationVersionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListAssociationVersionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListAssociationVersions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListCommandInvocations struct { -} - -func (*awsAwsjson11_deserializeOpListCommandInvocations) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListCommandInvocations) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListCommandInvocations(response, &metadata) - } - output := &ListCommandInvocationsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListCommandInvocationsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListCommandInvocations(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidCommandId", errorCode): - return awsAwsjson11_deserializeErrorInvalidCommandId(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListCommands struct { -} - -func (*awsAwsjson11_deserializeOpListCommands) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListCommands) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListCommands(response, &metadata) - } - output := &ListCommandsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListCommandsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListCommands(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidCommandId", errorCode): - return awsAwsjson11_deserializeErrorInvalidCommandId(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListComplianceItems struct { -} - -func (*awsAwsjson11_deserializeOpListComplianceItems) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListComplianceItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListComplianceItems(response, &metadata) - } - output := &ListComplianceItemsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListComplianceItemsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListComplianceItems(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("InvalidResourceType", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListComplianceSummaries struct { -} - -func (*awsAwsjson11_deserializeOpListComplianceSummaries) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListComplianceSummaries) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListComplianceSummaries(response, &metadata) - } - output := &ListComplianceSummariesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListComplianceSummariesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListComplianceSummaries(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListDocumentMetadataHistory struct { -} - -func (*awsAwsjson11_deserializeOpListDocumentMetadataHistory) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListDocumentMetadataHistory) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListDocumentMetadataHistory(response, &metadata) - } - output := &ListDocumentMetadataHistoryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListDocumentMetadataHistoryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListDocumentMetadataHistory(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListDocuments struct { -} - -func (*awsAwsjson11_deserializeOpListDocuments) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListDocuments) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListDocuments(response, &metadata) - } - output := &ListDocumentsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListDocumentsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListDocuments(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilterKey", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilterKey(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListDocumentVersions struct { -} - -func (*awsAwsjson11_deserializeOpListDocumentVersions) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListDocumentVersions) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListDocumentVersions(response, &metadata) - } - output := &ListDocumentVersionsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListDocumentVersionsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListDocumentVersions(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListInventoryEntries struct { -} - -func (*awsAwsjson11_deserializeOpListInventoryEntries) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListInventoryEntries) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListInventoryEntries(response, &metadata) - } - output := &ListInventoryEntriesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListInventoryEntriesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListInventoryEntries(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListOpsItemEvents struct { -} - -func (*awsAwsjson11_deserializeOpListOpsItemEvents) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListOpsItemEvents) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListOpsItemEvents(response, &metadata) - } - output := &ListOpsItemEventsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListOpsItemEventsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListOpsItemEvents(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - case strings.EqualFold("OpsItemLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemLimitExceededException(response, errorBody) - - case strings.EqualFold("OpsItemNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListOpsItemRelatedItems struct { -} - -func (*awsAwsjson11_deserializeOpListOpsItemRelatedItems) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListOpsItemRelatedItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListOpsItemRelatedItems(response, &metadata) - } - output := &ListOpsItemRelatedItemsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListOpsItemRelatedItemsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListOpsItemRelatedItems(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListOpsMetadata struct { -} - -func (*awsAwsjson11_deserializeOpListOpsMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListOpsMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListOpsMetadata(response, &metadata) - } - output := &ListOpsMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListOpsMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListOpsMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsMetadataInvalidArgumentException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListResourceComplianceSummaries struct { -} - -func (*awsAwsjson11_deserializeOpListResourceComplianceSummaries) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListResourceComplianceSummaries) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListResourceComplianceSummaries(response, &metadata) - } - output := &ListResourceComplianceSummariesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListResourceComplianceSummariesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListResourceComplianceSummaries(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidFilter", errorCode): - return awsAwsjson11_deserializeErrorInvalidFilter(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListResourceDataSync struct { -} - -func (*awsAwsjson11_deserializeOpListResourceDataSync) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListResourceDataSync) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListResourceDataSync(response, &metadata) - } - output := &ListResourceDataSyncOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListResourceDataSyncOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListResourceDataSync(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidNextToken", errorCode): - return awsAwsjson11_deserializeErrorInvalidNextToken(response, errorBody) - - case strings.EqualFold("ResourceDataSyncInvalidConfigurationException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncInvalidConfigurationException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpListTagsForResource struct { -} - -func (*awsAwsjson11_deserializeOpListTagsForResource) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpListTagsForResource) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorListTagsForResource(response, &metadata) - } - output := &ListTagsForResourceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentListTagsForResourceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("InvalidResourceType", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpModifyDocumentPermission struct { -} - -func (*awsAwsjson11_deserializeOpModifyDocumentPermission) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpModifyDocumentPermission) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorModifyDocumentPermission(response, &metadata) - } - output := &ModifyDocumentPermissionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentModifyDocumentPermissionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorModifyDocumentPermission(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DocumentLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorDocumentLimitExceeded(response, errorBody) - - case strings.EqualFold("DocumentPermissionLimit", errorCode): - return awsAwsjson11_deserializeErrorDocumentPermissionLimit(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidPermissionType", errorCode): - return awsAwsjson11_deserializeErrorInvalidPermissionType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpPutComplianceItems struct { -} - -func (*awsAwsjson11_deserializeOpPutComplianceItems) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpPutComplianceItems) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorPutComplianceItems(response, &metadata) - } - output := &PutComplianceItemsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentPutComplianceItemsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorPutComplianceItems(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("ComplianceTypeCountLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorComplianceTypeCountLimitExceededException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidItemContentException", errorCode): - return awsAwsjson11_deserializeErrorInvalidItemContentException(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("InvalidResourceType", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceType(response, errorBody) - - case strings.EqualFold("ItemSizeLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorItemSizeLimitExceededException(response, errorBody) - - case strings.EqualFold("TotalSizeLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorTotalSizeLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpPutInventory struct { -} - -func (*awsAwsjson11_deserializeOpPutInventory) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpPutInventory) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorPutInventory(response, &metadata) - } - output := &PutInventoryOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentPutInventoryOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorPutInventory(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("CustomSchemaCountLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorCustomSchemaCountLimitExceededException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidInventoryItemContextException", errorCode): - return awsAwsjson11_deserializeErrorInvalidInventoryItemContextException(response, errorBody) - - case strings.EqualFold("InvalidItemContentException", errorCode): - return awsAwsjson11_deserializeErrorInvalidItemContentException(response, errorBody) - - case strings.EqualFold("InvalidTypeNameException", errorCode): - return awsAwsjson11_deserializeErrorInvalidTypeNameException(response, errorBody) - - case strings.EqualFold("ItemContentMismatchException", errorCode): - return awsAwsjson11_deserializeErrorItemContentMismatchException(response, errorBody) - - case strings.EqualFold("ItemSizeLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorItemSizeLimitExceededException(response, errorBody) - - case strings.EqualFold("SubTypeCountLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorSubTypeCountLimitExceededException(response, errorBody) - - case strings.EqualFold("TotalSizeLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorTotalSizeLimitExceededException(response, errorBody) - - case strings.EqualFold("UnsupportedInventoryItemContextException", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedInventoryItemContextException(response, errorBody) - - case strings.EqualFold("UnsupportedInventorySchemaVersionException", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedInventorySchemaVersionException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpPutParameter struct { -} - -func (*awsAwsjson11_deserializeOpPutParameter) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpPutParameter) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorPutParameter(response, &metadata) - } - output := &PutParameterOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentPutParameterOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorPutParameter(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("HierarchyLevelLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorHierarchyLevelLimitExceededException(response, errorBody) - - case strings.EqualFold("HierarchyTypeMismatchException", errorCode): - return awsAwsjson11_deserializeErrorHierarchyTypeMismatchException(response, errorBody) - - case strings.EqualFold("IncompatiblePolicyException", errorCode): - return awsAwsjson11_deserializeErrorIncompatiblePolicyException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAllowedPatternException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAllowedPatternException(response, errorBody) - - case strings.EqualFold("InvalidKeyId", errorCode): - return awsAwsjson11_deserializeErrorInvalidKeyId(response, errorBody) - - case strings.EqualFold("InvalidPolicyAttributeException", errorCode): - return awsAwsjson11_deserializeErrorInvalidPolicyAttributeException(response, errorBody) - - case strings.EqualFold("InvalidPolicyTypeException", errorCode): - return awsAwsjson11_deserializeErrorInvalidPolicyTypeException(response, errorBody) - - case strings.EqualFold("ParameterAlreadyExists", errorCode): - return awsAwsjson11_deserializeErrorParameterAlreadyExists(response, errorBody) - - case strings.EqualFold("ParameterLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorParameterLimitExceeded(response, errorBody) - - case strings.EqualFold("ParameterMaxVersionLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorParameterMaxVersionLimitExceeded(response, errorBody) - - case strings.EqualFold("ParameterPatternMismatchException", errorCode): - return awsAwsjson11_deserializeErrorParameterPatternMismatchException(response, errorBody) - - case strings.EqualFold("PoliciesLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorPoliciesLimitExceededException(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - case strings.EqualFold("UnsupportedParameterType", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedParameterType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpPutResourcePolicy struct { -} - -func (*awsAwsjson11_deserializeOpPutResourcePolicy) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpPutResourcePolicy) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorPutResourcePolicy(response, &metadata) - } - output := &PutResourcePolicyOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentPutResourcePolicyOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorPutResourcePolicy(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourcePolicyConflictException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyConflictException(response, errorBody) - - case strings.EqualFold("ResourcePolicyInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyInvalidParameterException(response, errorBody) - - case strings.EqualFold("ResourcePolicyLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourcePolicyLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpRegisterDefaultPatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpRegisterDefaultPatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpRegisterDefaultPatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorRegisterDefaultPatchBaseline(response, &metadata) - } - output := &RegisterDefaultPatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentRegisterDefaultPatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorRegisterDefaultPatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpRegisterPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_deserializeOpRegisterPatchBaselineForPatchGroup) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpRegisterPatchBaselineForPatchGroup) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorRegisterPatchBaselineForPatchGroup(response, &metadata) - } - output := &RegisterPatchBaselineForPatchGroupOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentRegisterPatchBaselineForPatchGroupOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorRegisterPatchBaselineForPatchGroup(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorAlreadyExistsException(response, errorBody) - - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("ResourceLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpRegisterTargetWithMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpRegisterTargetWithMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpRegisterTargetWithMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorRegisterTargetWithMaintenanceWindow(response, &metadata) - } - output := &RegisterTargetWithMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentRegisterTargetWithMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorRegisterTargetWithMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpRegisterTaskWithMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpRegisterTaskWithMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpRegisterTaskWithMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorRegisterTaskWithMaintenanceWindow(response, &metadata) - } - output := &RegisterTaskWithMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentRegisterTaskWithMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorRegisterTaskWithMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("FeatureNotAvailableException", errorCode): - return awsAwsjson11_deserializeErrorFeatureNotAvailableException(response, errorBody) - - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorResourceLimitExceededException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpRemoveTagsFromResource struct { -} - -func (*awsAwsjson11_deserializeOpRemoveTagsFromResource) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpRemoveTagsFromResource) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorRemoveTagsFromResource(response, &metadata) - } - output := &RemoveTagsFromResourceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentRemoveTagsFromResourceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorRemoveTagsFromResource(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidResourceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceId(response, errorBody) - - case strings.EqualFold("InvalidResourceType", errorCode): - return awsAwsjson11_deserializeErrorInvalidResourceType(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpResetServiceSetting struct { -} - -func (*awsAwsjson11_deserializeOpResetServiceSetting) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpResetServiceSetting) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorResetServiceSetting(response, &metadata) - } - output := &ResetServiceSettingOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentResetServiceSettingOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorResetServiceSetting(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ServiceSettingNotFound", errorCode): - return awsAwsjson11_deserializeErrorServiceSettingNotFound(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpResumeSession struct { -} - -func (*awsAwsjson11_deserializeOpResumeSession) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpResumeSession) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorResumeSession(response, &metadata) - } - output := &ResumeSessionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentResumeSessionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorResumeSession(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpSendAutomationSignal struct { -} - -func (*awsAwsjson11_deserializeOpSendAutomationSignal) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpSendAutomationSignal) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorSendAutomationSignal(response, &metadata) - } - output := &SendAutomationSignalOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentSendAutomationSignalOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorSendAutomationSignal(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationExecutionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionNotFoundException(response, errorBody) - - case strings.EqualFold("AutomationStepNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationStepNotFoundException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAutomationSignalException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAutomationSignalException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpSendCommand struct { -} - -func (*awsAwsjson11_deserializeOpSendCommand) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpSendCommand) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorSendCommand(response, &metadata) - } - output := &SendCommandOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentSendCommandOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorSendCommand(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DuplicateInstanceId", errorCode): - return awsAwsjson11_deserializeErrorDuplicateInstanceId(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("InvalidNotificationConfig", errorCode): - return awsAwsjson11_deserializeErrorInvalidNotificationConfig(response, errorBody) - - case strings.EqualFold("InvalidOutputFolder", errorCode): - return awsAwsjson11_deserializeErrorInvalidOutputFolder(response, errorBody) - - case strings.EqualFold("InvalidParameters", errorCode): - return awsAwsjson11_deserializeErrorInvalidParameters(response, errorBody) - - case strings.EqualFold("InvalidRole", errorCode): - return awsAwsjson11_deserializeErrorInvalidRole(response, errorBody) - - case strings.EqualFold("MaxDocumentSizeExceeded", errorCode): - return awsAwsjson11_deserializeErrorMaxDocumentSizeExceeded(response, errorBody) - - case strings.EqualFold("UnsupportedPlatformType", errorCode): - return awsAwsjson11_deserializeErrorUnsupportedPlatformType(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpStartAssociationsOnce struct { -} - -func (*awsAwsjson11_deserializeOpStartAssociationsOnce) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpStartAssociationsOnce) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorStartAssociationsOnce(response, &metadata) - } - output := &StartAssociationsOnceOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentStartAssociationsOnceOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorStartAssociationsOnce(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InvalidAssociation", errorCode): - return awsAwsjson11_deserializeErrorInvalidAssociation(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpStartAutomationExecution struct { -} - -func (*awsAwsjson11_deserializeOpStartAutomationExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpStartAutomationExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorStartAutomationExecution(response, &metadata) - } - output := &StartAutomationExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentStartAutomationExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorStartAutomationExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationDefinitionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationDefinitionNotFoundException(response, errorBody) - - case strings.EqualFold("AutomationDefinitionVersionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationDefinitionVersionNotFoundException(response, errorBody) - - case strings.EqualFold("AutomationExecutionLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionLimitExceededException(response, errorBody) - - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAutomationExecutionParametersException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAutomationExecutionParametersException(response, errorBody) - - case strings.EqualFold("InvalidTarget", errorCode): - return awsAwsjson11_deserializeErrorInvalidTarget(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpStartChangeRequestExecution struct { -} - -func (*awsAwsjson11_deserializeOpStartChangeRequestExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpStartChangeRequestExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorStartChangeRequestExecution(response, &metadata) - } - output := &StartChangeRequestExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentStartChangeRequestExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorStartChangeRequestExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationDefinitionNotApprovedException", errorCode): - return awsAwsjson11_deserializeErrorAutomationDefinitionNotApprovedException(response, errorBody) - - case strings.EqualFold("AutomationDefinitionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationDefinitionNotFoundException(response, errorBody) - - case strings.EqualFold("AutomationDefinitionVersionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationDefinitionVersionNotFoundException(response, errorBody) - - case strings.EqualFold("AutomationExecutionLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionLimitExceededException(response, errorBody) - - case strings.EqualFold("IdempotentParameterMismatch", errorCode): - return awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAutomationExecutionParametersException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAutomationExecutionParametersException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpStartSession struct { -} - -func (*awsAwsjson11_deserializeOpStartSession) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpStartSession) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorStartSession(response, &metadata) - } - output := &StartSessionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentStartSessionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorStartSession(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("TargetNotConnected", errorCode): - return awsAwsjson11_deserializeErrorTargetNotConnected(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpStopAutomationExecution struct { -} - -func (*awsAwsjson11_deserializeOpStopAutomationExecution) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpStopAutomationExecution) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorStopAutomationExecution(response, &metadata) - } - output := &StopAutomationExecutionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentStopAutomationExecutionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorStopAutomationExecution(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AutomationExecutionNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorAutomationExecutionNotFoundException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAutomationStatusUpdateException", errorCode): - return awsAwsjson11_deserializeErrorInvalidAutomationStatusUpdateException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpTerminateSession struct { -} - -func (*awsAwsjson11_deserializeOpTerminateSession) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpTerminateSession) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorTerminateSession(response, &metadata) - } - output := &TerminateSessionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentTerminateSessionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorTerminateSession(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUnlabelParameterVersion struct { -} - -func (*awsAwsjson11_deserializeOpUnlabelParameterVersion) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUnlabelParameterVersion) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUnlabelParameterVersion(response, &metadata) - } - output := &UnlabelParameterVersionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUnlabelParameterVersionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUnlabelParameterVersion(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ParameterNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterNotFound(response, errorBody) - - case strings.EqualFold("ParameterVersionNotFound", errorCode): - return awsAwsjson11_deserializeErrorParameterVersionNotFound(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateAssociation struct { -} - -func (*awsAwsjson11_deserializeOpUpdateAssociation) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateAssociation) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateAssociation(response, &metadata) - } - output := &UpdateAssociationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateAssociationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateAssociation(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("AssociationVersionLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorAssociationVersionLimitExceeded(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidAssociationVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidAssociationVersion(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("InvalidOutputLocation", errorCode): - return awsAwsjson11_deserializeErrorInvalidOutputLocation(response, errorBody) - - case strings.EqualFold("InvalidParameters", errorCode): - return awsAwsjson11_deserializeErrorInvalidParameters(response, errorBody) - - case strings.EqualFold("InvalidSchedule", errorCode): - return awsAwsjson11_deserializeErrorInvalidSchedule(response, errorBody) - - case strings.EqualFold("InvalidTarget", errorCode): - return awsAwsjson11_deserializeErrorInvalidTarget(response, errorBody) - - case strings.EqualFold("InvalidTargetMaps", errorCode): - return awsAwsjson11_deserializeErrorInvalidTargetMaps(response, errorBody) - - case strings.EqualFold("InvalidUpdate", errorCode): - return awsAwsjson11_deserializeErrorInvalidUpdate(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateAssociationStatus struct { -} - -func (*awsAwsjson11_deserializeOpUpdateAssociationStatus) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateAssociationStatus) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateAssociationStatus(response, &metadata) - } - output := &UpdateAssociationStatusOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateAssociationStatusOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateAssociationStatus(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AssociationDoesNotExist", errorCode): - return awsAwsjson11_deserializeErrorAssociationDoesNotExist(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - case strings.EqualFold("StatusUnchanged", errorCode): - return awsAwsjson11_deserializeErrorStatusUnchanged(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateDocument struct { -} - -func (*awsAwsjson11_deserializeOpUpdateDocument) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateDocument) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateDocument(response, &metadata) - } - output := &UpdateDocumentOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateDocumentOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateDocument(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DocumentVersionLimitExceeded", errorCode): - return awsAwsjson11_deserializeErrorDocumentVersionLimitExceeded(response, errorBody) - - case strings.EqualFold("DuplicateDocumentContent", errorCode): - return awsAwsjson11_deserializeErrorDuplicateDocumentContent(response, errorBody) - - case strings.EqualFold("DuplicateDocumentVersionName", errorCode): - return awsAwsjson11_deserializeErrorDuplicateDocumentVersionName(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentContent", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentContent(response, errorBody) - - case strings.EqualFold("InvalidDocumentOperation", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentOperation(response, errorBody) - - case strings.EqualFold("InvalidDocumentSchemaVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentSchemaVersion(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - case strings.EqualFold("MaxDocumentSizeExceeded", errorCode): - return awsAwsjson11_deserializeErrorMaxDocumentSizeExceeded(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateDocumentDefaultVersion struct { -} - -func (*awsAwsjson11_deserializeOpUpdateDocumentDefaultVersion) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateDocumentDefaultVersion) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateDocumentDefaultVersion(response, &metadata) - } - output := &UpdateDocumentDefaultVersionOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateDocumentDefaultVersionOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateDocumentDefaultVersion(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentSchemaVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentSchemaVersion(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateDocumentMetadata struct { -} - -func (*awsAwsjson11_deserializeOpUpdateDocumentMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateDocumentMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateDocumentMetadata(response, &metadata) - } - output := &UpdateDocumentMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateDocumentMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateDocumentMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidDocument", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocument(response, errorBody) - - case strings.EqualFold("InvalidDocumentOperation", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentOperation(response, errorBody) - - case strings.EqualFold("InvalidDocumentVersion", errorCode): - return awsAwsjson11_deserializeErrorInvalidDocumentVersion(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateMaintenanceWindow struct { -} - -func (*awsAwsjson11_deserializeOpUpdateMaintenanceWindow) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateMaintenanceWindow) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindow(response, &metadata) - } - output := &UpdateMaintenanceWindowOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindow(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateMaintenanceWindowTarget struct { -} - -func (*awsAwsjson11_deserializeOpUpdateMaintenanceWindowTarget) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateMaintenanceWindowTarget) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindowTarget(response, &metadata) - } - output := &UpdateMaintenanceWindowTargetOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowTargetOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindowTarget(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateMaintenanceWindowTask struct { -} - -func (*awsAwsjson11_deserializeOpUpdateMaintenanceWindowTask) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateMaintenanceWindowTask) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindowTask(response, &metadata) - } - output := &UpdateMaintenanceWindowTaskOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowTaskOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateMaintenanceWindowTask(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateManagedInstanceRole struct { -} - -func (*awsAwsjson11_deserializeOpUpdateManagedInstanceRole) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateManagedInstanceRole) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateManagedInstanceRole(response, &metadata) - } - output := &UpdateManagedInstanceRoleOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateManagedInstanceRoleOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateManagedInstanceRole(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("InvalidInstanceId", errorCode): - return awsAwsjson11_deserializeErrorInvalidInstanceId(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateOpsItem struct { -} - -func (*awsAwsjson11_deserializeOpUpdateOpsItem) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateOpsItem) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateOpsItem(response, &metadata) - } - output := &UpdateOpsItemOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateOpsItemOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateOpsItem(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsItemAccessDeniedException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemAccessDeniedException(response, errorBody) - - case strings.EqualFold("OpsItemAlreadyExistsException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemAlreadyExistsException(response, errorBody) - - case strings.EqualFold("OpsItemConflictException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemConflictException(response, errorBody) - - case strings.EqualFold("OpsItemInvalidParameterException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response, errorBody) - - case strings.EqualFold("OpsItemLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemLimitExceededException(response, errorBody) - - case strings.EqualFold("OpsItemNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsItemNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateOpsMetadata struct { -} - -func (*awsAwsjson11_deserializeOpUpdateOpsMetadata) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateOpsMetadata) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateOpsMetadata(response, &metadata) - } - output := &UpdateOpsMetadataOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateOpsMetadataOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateOpsMetadata(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("OpsMetadataInvalidArgumentException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response, errorBody) - - case strings.EqualFold("OpsMetadataKeyLimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataKeyLimitExceededException(response, errorBody) - - case strings.EqualFold("OpsMetadataNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataNotFoundException(response, errorBody) - - case strings.EqualFold("OpsMetadataTooManyUpdatesException", errorCode): - return awsAwsjson11_deserializeErrorOpsMetadataTooManyUpdatesException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdatePatchBaseline struct { -} - -func (*awsAwsjson11_deserializeOpUpdatePatchBaseline) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdatePatchBaseline) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdatePatchBaseline(response, &metadata) - } - output := &UpdatePatchBaselineOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdatePatchBaselineOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdatePatchBaseline(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("DoesNotExistException", errorCode): - return awsAwsjson11_deserializeErrorDoesNotExistException(response, errorBody) - - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateResourceDataSync struct { -} - -func (*awsAwsjson11_deserializeOpUpdateResourceDataSync) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateResourceDataSync) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateResourceDataSync(response, &metadata) - } - output := &UpdateResourceDataSyncOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateResourceDataSyncOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateResourceDataSync(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ResourceDataSyncConflictException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncConflictException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncInvalidConfigurationException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncInvalidConfigurationException(response, errorBody) - - case strings.EqualFold("ResourceDataSyncNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorResourceDataSyncNotFoundException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsjson11_deserializeOpUpdateServiceSetting struct { -} - -func (*awsAwsjson11_deserializeOpUpdateServiceSetting) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsjson11_deserializeOpUpdateServiceSetting) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUpdateServiceSetting(response, &metadata) - } - output := &UpdateServiceSettingOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsAwsjson11_deserializeOpDocumentUpdateServiceSettingOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsjson11_deserializeOpErrorUpdateServiceSetting(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerError", errorCode): - return awsAwsjson11_deserializeErrorInternalServerError(response, errorBody) - - case strings.EqualFold("ServiceSettingNotFound", errorCode): - return awsAwsjson11_deserializeErrorServiceSettingNotFound(response, errorBody) - - case strings.EqualFold("TooManyUpdates", errorCode): - return awsAwsjson11_deserializeErrorTooManyUpdates(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsAwsjson11_deserializeErrorAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentAlreadyExistsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociatedInstances(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociatedInstances{} - err := awsAwsjson11_deserializeDocumentAssociatedInstances(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociationAlreadyExists(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociationAlreadyExists{} - err := awsAwsjson11_deserializeDocumentAssociationAlreadyExists(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociationDoesNotExist(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociationDoesNotExist{} - err := awsAwsjson11_deserializeDocumentAssociationDoesNotExist(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociationExecutionDoesNotExist(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociationExecutionDoesNotExist{} - err := awsAwsjson11_deserializeDocumentAssociationExecutionDoesNotExist(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociationLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociationLimitExceeded{} - err := awsAwsjson11_deserializeDocumentAssociationLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAssociationVersionLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AssociationVersionLimitExceeded{} - err := awsAwsjson11_deserializeDocumentAssociationVersionLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationDefinitionNotApprovedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationDefinitionNotApprovedException{} - err := awsAwsjson11_deserializeDocumentAutomationDefinitionNotApprovedException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationDefinitionNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationDefinitionNotFoundException{} - err := awsAwsjson11_deserializeDocumentAutomationDefinitionNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationDefinitionVersionNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationDefinitionVersionNotFoundException{} - err := awsAwsjson11_deserializeDocumentAutomationDefinitionVersionNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationExecutionLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationExecutionLimitExceededException{} - err := awsAwsjson11_deserializeDocumentAutomationExecutionLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationExecutionNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationExecutionNotFoundException{} - err := awsAwsjson11_deserializeDocumentAutomationExecutionNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorAutomationStepNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.AutomationStepNotFoundException{} - err := awsAwsjson11_deserializeDocumentAutomationStepNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorComplianceTypeCountLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ComplianceTypeCountLimitExceededException{} - err := awsAwsjson11_deserializeDocumentComplianceTypeCountLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorCustomSchemaCountLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.CustomSchemaCountLimitExceededException{} - err := awsAwsjson11_deserializeDocumentCustomSchemaCountLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDocumentAlreadyExists(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DocumentAlreadyExists{} - err := awsAwsjson11_deserializeDocumentDocumentAlreadyExists(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDocumentLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DocumentLimitExceeded{} - err := awsAwsjson11_deserializeDocumentDocumentLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDocumentPermissionLimit(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DocumentPermissionLimit{} - err := awsAwsjson11_deserializeDocumentDocumentPermissionLimit(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDocumentVersionLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DocumentVersionLimitExceeded{} - err := awsAwsjson11_deserializeDocumentDocumentVersionLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDoesNotExistException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DoesNotExistException{} - err := awsAwsjson11_deserializeDocumentDoesNotExistException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDuplicateDocumentContent(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DuplicateDocumentContent{} - err := awsAwsjson11_deserializeDocumentDuplicateDocumentContent(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDuplicateDocumentVersionName(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DuplicateDocumentVersionName{} - err := awsAwsjson11_deserializeDocumentDuplicateDocumentVersionName(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorDuplicateInstanceId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.DuplicateInstanceId{} - err := awsAwsjson11_deserializeDocumentDuplicateInstanceId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorFeatureNotAvailableException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.FeatureNotAvailableException{} - err := awsAwsjson11_deserializeDocumentFeatureNotAvailableException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorHierarchyLevelLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.HierarchyLevelLimitExceededException{} - err := awsAwsjson11_deserializeDocumentHierarchyLevelLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorHierarchyTypeMismatchException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.HierarchyTypeMismatchException{} - err := awsAwsjson11_deserializeDocumentHierarchyTypeMismatchException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorIdempotentParameterMismatch(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.IdempotentParameterMismatch{} - err := awsAwsjson11_deserializeDocumentIdempotentParameterMismatch(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorIncompatiblePolicyException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.IncompatiblePolicyException{} - err := awsAwsjson11_deserializeDocumentIncompatiblePolicyException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInternalServerError(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InternalServerError{} - err := awsAwsjson11_deserializeDocumentInternalServerError(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidActivation(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidActivation{} - err := awsAwsjson11_deserializeDocumentInvalidActivation(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidActivationId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidActivationId{} - err := awsAwsjson11_deserializeDocumentInvalidActivationId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAggregatorException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAggregatorException{} - err := awsAwsjson11_deserializeDocumentInvalidAggregatorException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAllowedPatternException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAllowedPatternException{} - err := awsAwsjson11_deserializeDocumentInvalidAllowedPatternException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAssociation(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAssociation{} - err := awsAwsjson11_deserializeDocumentInvalidAssociation(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAssociationVersion(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAssociationVersion{} - err := awsAwsjson11_deserializeDocumentInvalidAssociationVersion(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAutomationExecutionParametersException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAutomationExecutionParametersException{} - err := awsAwsjson11_deserializeDocumentInvalidAutomationExecutionParametersException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAutomationSignalException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAutomationSignalException{} - err := awsAwsjson11_deserializeDocumentInvalidAutomationSignalException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidAutomationStatusUpdateException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidAutomationStatusUpdateException{} - err := awsAwsjson11_deserializeDocumentInvalidAutomationStatusUpdateException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidCommandId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidCommandId{} - err := awsAwsjson11_deserializeDocumentInvalidCommandId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDeleteInventoryParametersException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDeleteInventoryParametersException{} - err := awsAwsjson11_deserializeDocumentInvalidDeleteInventoryParametersException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDeletionIdException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDeletionIdException{} - err := awsAwsjson11_deserializeDocumentInvalidDeletionIdException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocument(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocument{} - err := awsAwsjson11_deserializeDocumentInvalidDocument(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocumentContent(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocumentContent{} - err := awsAwsjson11_deserializeDocumentInvalidDocumentContent(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocumentOperation(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocumentOperation{} - err := awsAwsjson11_deserializeDocumentInvalidDocumentOperation(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocumentSchemaVersion(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocumentSchemaVersion{} - err := awsAwsjson11_deserializeDocumentInvalidDocumentSchemaVersion(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocumentType(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocumentType{} - err := awsAwsjson11_deserializeDocumentInvalidDocumentType(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidDocumentVersion(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidDocumentVersion{} - err := awsAwsjson11_deserializeDocumentInvalidDocumentVersion(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidFilter(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidFilter{} - err := awsAwsjson11_deserializeDocumentInvalidFilter(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidFilterKey(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidFilterKey{} - err := awsAwsjson11_deserializeDocumentInvalidFilterKey(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidFilterOption(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidFilterOption{} - err := awsAwsjson11_deserializeDocumentInvalidFilterOption(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidFilterValue(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidFilterValue{} - err := awsAwsjson11_deserializeDocumentInvalidFilterValue(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidInstanceId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidInstanceId{} - err := awsAwsjson11_deserializeDocumentInvalidInstanceId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidInstanceInformationFilterValue(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidInstanceInformationFilterValue{} - err := awsAwsjson11_deserializeDocumentInvalidInstanceInformationFilterValue(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidInventoryGroupException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidInventoryGroupException{} - err := awsAwsjson11_deserializeDocumentInvalidInventoryGroupException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidInventoryItemContextException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidInventoryItemContextException{} - err := awsAwsjson11_deserializeDocumentInvalidInventoryItemContextException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidInventoryRequestException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidInventoryRequestException{} - err := awsAwsjson11_deserializeDocumentInvalidInventoryRequestException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidItemContentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidItemContentException{} - err := awsAwsjson11_deserializeDocumentInvalidItemContentException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidKeyId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidKeyId{} - err := awsAwsjson11_deserializeDocumentInvalidKeyId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidNextToken(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidNextToken{} - err := awsAwsjson11_deserializeDocumentInvalidNextToken(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidNotificationConfig(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidNotificationConfig{} - err := awsAwsjson11_deserializeDocumentInvalidNotificationConfig(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidOptionException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidOptionException{} - err := awsAwsjson11_deserializeDocumentInvalidOptionException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidOutputFolder(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidOutputFolder{} - err := awsAwsjson11_deserializeDocumentInvalidOutputFolder(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidOutputLocation(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidOutputLocation{} - err := awsAwsjson11_deserializeDocumentInvalidOutputLocation(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidParameters(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidParameters{} - err := awsAwsjson11_deserializeDocumentInvalidParameters(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidPermissionType(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidPermissionType{} - err := awsAwsjson11_deserializeDocumentInvalidPermissionType(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidPluginName(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidPluginName{} - err := awsAwsjson11_deserializeDocumentInvalidPluginName(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidPolicyAttributeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidPolicyAttributeException{} - err := awsAwsjson11_deserializeDocumentInvalidPolicyAttributeException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidPolicyTypeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidPolicyTypeException{} - err := awsAwsjson11_deserializeDocumentInvalidPolicyTypeException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidResourceId(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidResourceId{} - err := awsAwsjson11_deserializeDocumentInvalidResourceId(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidResourceType(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidResourceType{} - err := awsAwsjson11_deserializeDocumentInvalidResourceType(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidResultAttributeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidResultAttributeException{} - err := awsAwsjson11_deserializeDocumentInvalidResultAttributeException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidRole(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidRole{} - err := awsAwsjson11_deserializeDocumentInvalidRole(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidSchedule(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidSchedule{} - err := awsAwsjson11_deserializeDocumentInvalidSchedule(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidTag(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidTag{} - err := awsAwsjson11_deserializeDocumentInvalidTag(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidTarget(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidTarget{} - err := awsAwsjson11_deserializeDocumentInvalidTarget(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidTargetMaps(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidTargetMaps{} - err := awsAwsjson11_deserializeDocumentInvalidTargetMaps(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidTypeNameException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidTypeNameException{} - err := awsAwsjson11_deserializeDocumentInvalidTypeNameException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvalidUpdate(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvalidUpdate{} - err := awsAwsjson11_deserializeDocumentInvalidUpdate(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorInvocationDoesNotExist(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.InvocationDoesNotExist{} - err := awsAwsjson11_deserializeDocumentInvocationDoesNotExist(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorItemContentMismatchException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ItemContentMismatchException{} - err := awsAwsjson11_deserializeDocumentItemContentMismatchException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorItemSizeLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ItemSizeLimitExceededException{} - err := awsAwsjson11_deserializeDocumentItemSizeLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorMaxDocumentSizeExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.MaxDocumentSizeExceeded{} - err := awsAwsjson11_deserializeDocumentMaxDocumentSizeExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemAccessDeniedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemAccessDeniedException{} - err := awsAwsjson11_deserializeDocumentOpsItemAccessDeniedException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentOpsItemAlreadyExistsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemConflictException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemConflictException{} - err := awsAwsjson11_deserializeDocumentOpsItemConflictException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemInvalidParameterException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemInvalidParameterException{} - err := awsAwsjson11_deserializeDocumentOpsItemInvalidParameterException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemLimitExceededException{} - err := awsAwsjson11_deserializeDocumentOpsItemLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemNotFoundException{} - err := awsAwsjson11_deserializeDocumentOpsItemNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemRelatedItemAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemRelatedItemAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentOpsItemRelatedItemAlreadyExistsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsItemRelatedItemAssociationNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsItemRelatedItemAssociationNotFoundException{} - err := awsAwsjson11_deserializeDocumentOpsItemRelatedItemAssociationNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataAlreadyExistsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataInvalidArgumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataInvalidArgumentException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataInvalidArgumentException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataKeyLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataKeyLimitExceededException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataKeyLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataLimitExceededException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataNotFoundException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorOpsMetadataTooManyUpdatesException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.OpsMetadataTooManyUpdatesException{} - err := awsAwsjson11_deserializeDocumentOpsMetadataTooManyUpdatesException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterAlreadyExists(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterAlreadyExists{} - err := awsAwsjson11_deserializeDocumentParameterAlreadyExists(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterLimitExceeded{} - err := awsAwsjson11_deserializeDocumentParameterLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterMaxVersionLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterMaxVersionLimitExceeded{} - err := awsAwsjson11_deserializeDocumentParameterMaxVersionLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterNotFound(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterNotFound{} - err := awsAwsjson11_deserializeDocumentParameterNotFound(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterPatternMismatchException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterPatternMismatchException{} - err := awsAwsjson11_deserializeDocumentParameterPatternMismatchException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterVersionLabelLimitExceeded(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterVersionLabelLimitExceeded{} - err := awsAwsjson11_deserializeDocumentParameterVersionLabelLimitExceeded(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorParameterVersionNotFound(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ParameterVersionNotFound{} - err := awsAwsjson11_deserializeDocumentParameterVersionNotFound(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorPoliciesLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.PoliciesLimitExceededException{} - err := awsAwsjson11_deserializeDocumentPoliciesLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceDataSyncAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceDataSyncAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentResourceDataSyncAlreadyExistsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceDataSyncConflictException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceDataSyncConflictException{} - err := awsAwsjson11_deserializeDocumentResourceDataSyncConflictException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceDataSyncCountExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceDataSyncCountExceededException{} - err := awsAwsjson11_deserializeDocumentResourceDataSyncCountExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceDataSyncInvalidConfigurationException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceDataSyncInvalidConfigurationException{} - err := awsAwsjson11_deserializeDocumentResourceDataSyncInvalidConfigurationException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceDataSyncNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceDataSyncNotFoundException{} - err := awsAwsjson11_deserializeDocumentResourceDataSyncNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceInUseException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceInUseException{} - err := awsAwsjson11_deserializeDocumentResourceInUseException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourceLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourceLimitExceededException{} - err := awsAwsjson11_deserializeDocumentResourceLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourcePolicyConflictException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourcePolicyConflictException{} - err := awsAwsjson11_deserializeDocumentResourcePolicyConflictException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourcePolicyInvalidParameterException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourcePolicyInvalidParameterException{} - err := awsAwsjson11_deserializeDocumentResourcePolicyInvalidParameterException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorResourcePolicyLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ResourcePolicyLimitExceededException{} - err := awsAwsjson11_deserializeDocumentResourcePolicyLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorServiceSettingNotFound(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.ServiceSettingNotFound{} - err := awsAwsjson11_deserializeDocumentServiceSettingNotFound(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorStatusUnchanged(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.StatusUnchanged{} - err := awsAwsjson11_deserializeDocumentStatusUnchanged(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorSubTypeCountLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.SubTypeCountLimitExceededException{} - err := awsAwsjson11_deserializeDocumentSubTypeCountLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorTargetInUseException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.TargetInUseException{} - err := awsAwsjson11_deserializeDocumentTargetInUseException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorTargetNotConnected(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.TargetNotConnected{} - err := awsAwsjson11_deserializeDocumentTargetNotConnected(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorTooManyTagsError(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.TooManyTagsError{} - err := awsAwsjson11_deserializeDocumentTooManyTagsError(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorTooManyUpdates(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.TooManyUpdates{} - err := awsAwsjson11_deserializeDocumentTooManyUpdates(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorTotalSizeLimitExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.TotalSizeLimitExceededException{} - err := awsAwsjson11_deserializeDocumentTotalSizeLimitExceededException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedCalendarException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedCalendarException{} - err := awsAwsjson11_deserializeDocumentUnsupportedCalendarException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedFeatureRequiredException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedFeatureRequiredException{} - err := awsAwsjson11_deserializeDocumentUnsupportedFeatureRequiredException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedInventoryItemContextException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedInventoryItemContextException{} - err := awsAwsjson11_deserializeDocumentUnsupportedInventoryItemContextException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedInventorySchemaVersionException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedInventorySchemaVersionException{} - err := awsAwsjson11_deserializeDocumentUnsupportedInventorySchemaVersionException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedOperatingSystem(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedOperatingSystem{} - err := awsAwsjson11_deserializeDocumentUnsupportedOperatingSystem(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedParameterType(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedParameterType{} - err := awsAwsjson11_deserializeDocumentUnsupportedParameterType(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeErrorUnsupportedPlatformType(response *smithyhttp.Response, errorBody *bytes.Reader) error { - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - output := &types.UnsupportedPlatformType{} - err := awsAwsjson11_deserializeDocumentUnsupportedPlatformType(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - return output -} - -func awsAwsjson11_deserializeDocumentAccountIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccountId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAccounts(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Account to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAccountSharingInfo(v **types.AccountSharingInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AccountSharingInfo - if *v == nil { - sv = &types.AccountSharingInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AccountId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccountId to be of type string, got %T instead", value) - } - sv.AccountId = ptr.String(jtv) - } - - case "SharedDocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SharedDocumentVersion to be of type string, got %T instead", value) - } - sv.SharedDocumentVersion = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAccountSharingInfoList(v *[]types.AccountSharingInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AccountSharingInfo - if *v == nil { - cv = []types.AccountSharingInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AccountSharingInfo - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAccountSharingInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentActivation(v **types.Activation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Activation - if *v == nil { - sv = &types.Activation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActivationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ActivationId to be of type string, got %T instead", value) - } - sv.ActivationId = ptr.String(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected CreatedDate to be a JSON Number, got %T instead", value) - - } - } - - case "DefaultInstanceName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DefaultInstanceName to be of type string, got %T instead", value) - } - sv.DefaultInstanceName = ptr.String(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ActivationDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "ExpirationDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExpirationDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected ExpirationDate to be a JSON Number, got %T instead", value) - - } - } - - case "Expired": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.Expired = jtv - } - - case "IamRole": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected IamRole to be of type string, got %T instead", value) - } - sv.IamRole = ptr.String(jtv) - } - - case "RegistrationLimit": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected RegistrationLimit to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.RegistrationLimit = ptr.Int32(int32(i64)) - } - - case "RegistrationsCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected RegistrationsCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.RegistrationsCount = ptr.Int32(int32(i64)) - } - - case "Tags": - if err := awsAwsjson11_deserializeDocumentTagList(&sv.Tags, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentActivationList(v *[]types.Activation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Activation - if *v == nil { - cv = []types.Activation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Activation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentActivation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAlarm(v **types.Alarm, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Alarm - if *v == nil { - sv = &types.Alarm{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AlarmName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAlarmConfiguration(v **types.AlarmConfiguration, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AlarmConfiguration - if *v == nil { - sv = &types.AlarmConfiguration{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Alarms": - if err := awsAwsjson11_deserializeDocumentAlarmList(&sv.Alarms, value); err != nil { - return err - } - - case "IgnorePollAlarmFailure": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.IgnorePollAlarmFailure = jtv - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAlarmList(v *[]types.Alarm, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Alarm - if *v == nil { - cv = []types.Alarm{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Alarm - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAlarm(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAlarmStateInformation(v **types.AlarmStateInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AlarmStateInformation - if *v == nil { - sv = &types.AlarmStateInformation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AlarmName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "State": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ExternalAlarmState to be of type string, got %T instead", value) - } - sv.State = types.ExternalAlarmState(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAlarmStateInformationList(v *[]types.AlarmStateInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AlarmStateInformation - if *v == nil { - cv = []types.AlarmStateInformation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AlarmStateInformation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAlarmStateInformation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAlreadyExistsException(v **types.AlreadyExistsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AlreadyExistsException - if *v == nil { - sv = &types.AlreadyExistsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociatedInstances(v **types.AssociatedInstances, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociatedInstances - if *v == nil { - sv = &types.AssociatedInstances{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociation(v **types.Association, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Association - if *v == nil { - sv = &types.Association{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationName to be of type string, got %T instead", value) - } - sv.AssociationName = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "LastExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Overview": - if err := awsAwsjson11_deserializeDocumentAssociationOverview(&sv.Overview, value); err != nil { - return err - } - - case "ScheduleExpression": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ScheduleExpression to be of type string, got %T instead", value) - } - sv.ScheduleExpression = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ScheduleOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationAlreadyExists(v **types.AssociationAlreadyExists, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationAlreadyExists - if *v == nil { - sv = &types.AssociationAlreadyExists{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationDescription(v **types.AssociationDescription, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationDescription - if *v == nil { - sv = &types.AssociationDescription{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "ApplyOnlyAtCronInterval": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected ApplyOnlyAtCronInterval to be of type *bool, got %T instead", value) - } - sv.ApplyOnlyAtCronInterval = jtv - } - - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationName to be of type string, got %T instead", value) - } - sv.AssociationName = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "AutomationTargetParameterName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationTargetParameterName to be of type string, got %T instead", value) - } - sv.AutomationTargetParameterName = ptr.String(jtv) - } - - case "CalendarNames": - if err := awsAwsjson11_deserializeDocumentCalendarNameOrARNList(&sv.CalendarNames, value); err != nil { - return err - } - - case "ComplianceSeverity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationComplianceSeverity to be of type string, got %T instead", value) - } - sv.ComplianceSeverity = types.AssociationComplianceSeverity(jtv) - } - - case "Date": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.Date = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "LastExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastSuccessfulExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastSuccessfulExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastUpdateAssociationDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastUpdateAssociationDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OutputLocation": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationOutputLocation(&sv.OutputLocation, value); err != nil { - return err - } - - case "Overview": - if err := awsAwsjson11_deserializeDocumentAssociationOverview(&sv.Overview, value); err != nil { - return err - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameters(&sv.Parameters, value); err != nil { - return err - } - - case "ScheduleExpression": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ScheduleExpression to be of type string, got %T instead", value) - } - sv.ScheduleExpression = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ScheduleOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "Status": - if err := awsAwsjson11_deserializeDocumentAssociationStatus(&sv.Status, value); err != nil { - return err - } - - case "SyncCompliance": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationSyncCompliance to be of type string, got %T instead", value) - } - sv.SyncCompliance = types.AssociationSyncCompliance(jtv) - } - - case "TargetLocations": - if err := awsAwsjson11_deserializeDocumentTargetLocations(&sv.TargetLocations, value); err != nil { - return err - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationDescriptionList(v *[]types.AssociationDescription, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AssociationDescription - if *v == nil { - cv = []types.AssociationDescription{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AssociationDescription - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAssociationDescription(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationDoesNotExist(v **types.AssociationDoesNotExist, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationDoesNotExist - if *v == nil { - sv = &types.AssociationDoesNotExist{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationExecution(v **types.AssociationExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationExecution - if *v == nil { - sv = &types.AssociationExecution{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "CreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DetailedStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.DetailedStatus = ptr.String(jtv) - } - - case "ExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationExecutionId to be of type string, got %T instead", value) - } - sv.ExecutionId = ptr.String(jtv) - } - - case "LastExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ResourceCountByStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceCountByStatus to be of type string, got %T instead", value) - } - sv.ResourceCountByStatus = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.Status = ptr.String(jtv) - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationExecutionDoesNotExist(v **types.AssociationExecutionDoesNotExist, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationExecutionDoesNotExist - if *v == nil { - sv = &types.AssociationExecutionDoesNotExist{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationExecutionsList(v *[]types.AssociationExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AssociationExecution - if *v == nil { - cv = []types.AssociationExecution{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AssociationExecution - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAssociationExecution(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationExecutionTarget(v **types.AssociationExecutionTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationExecutionTarget - if *v == nil { - sv = &types.AssociationExecutionTarget{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "DetailedStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.DetailedStatus = ptr.String(jtv) - } - - case "ExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationExecutionId to be of type string, got %T instead", value) - } - sv.ExecutionId = ptr.String(jtv) - } - - case "LastExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "OutputSource": - if err := awsAwsjson11_deserializeDocumentOutputSource(&sv.OutputSource, value); err != nil { - return err - } - - case "ResourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationResourceId to be of type string, got %T instead", value) - } - sv.ResourceId = ptr.String(jtv) - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.Status = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationExecutionTargetsList(v *[]types.AssociationExecutionTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AssociationExecutionTarget - if *v == nil { - cv = []types.AssociationExecutionTarget{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AssociationExecutionTarget - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAssociationExecutionTarget(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationLimitExceeded(v **types.AssociationLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationLimitExceeded - if *v == nil { - sv = &types.AssociationLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationList(v *[]types.Association, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Association - if *v == nil { - cv = []types.Association{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Association - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAssociation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationOverview(v **types.AssociationOverview, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationOverview - if *v == nil { - sv = &types.AssociationOverview{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationStatusAggregatedCount": - if err := awsAwsjson11_deserializeDocumentAssociationStatusAggregatedCount(&sv.AssociationStatusAggregatedCount, value); err != nil { - return err - } - - case "DetailedStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.DetailedStatus = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.Status = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationStatus(v **types.AssociationStatus, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationStatus - if *v == nil { - sv = &types.AssociationStatus{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AdditionalInfo": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusAdditionalInfo to be of type string, got %T instead", value) - } - sv.AdditionalInfo = ptr.String(jtv) - } - - case "Date": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.Date = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusMessage to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationStatusName to be of type string, got %T instead", value) - } - sv.Name = types.AssociationStatusName(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationStatusAggregatedCount(v *map[string]int32, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]int32 - if *v == nil { - mv = map[string]int32{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal int32 - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstanceCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - parsedVal = int32(i64) - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationVersionInfo(v **types.AssociationVersionInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationVersionInfo - if *v == nil { - sv = &types.AssociationVersionInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApplyOnlyAtCronInterval": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected ApplyOnlyAtCronInterval to be of type *bool, got %T instead", value) - } - sv.ApplyOnlyAtCronInterval = jtv - } - - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationName to be of type string, got %T instead", value) - } - sv.AssociationName = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "CalendarNames": - if err := awsAwsjson11_deserializeDocumentCalendarNameOrARNList(&sv.CalendarNames, value); err != nil { - return err - } - - case "ComplianceSeverity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationComplianceSeverity to be of type string, got %T instead", value) - } - sv.ComplianceSeverity = types.AssociationComplianceSeverity(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OutputLocation": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationOutputLocation(&sv.OutputLocation, value); err != nil { - return err - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameters(&sv.Parameters, value); err != nil { - return err - } - - case "ScheduleExpression": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ScheduleExpression to be of type string, got %T instead", value) - } - sv.ScheduleExpression = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ScheduleOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "SyncCompliance": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationSyncCompliance to be of type string, got %T instead", value) - } - sv.SyncCompliance = types.AssociationSyncCompliance(jtv) - } - - case "TargetLocations": - if err := awsAwsjson11_deserializeDocumentTargetLocations(&sv.TargetLocations, value); err != nil { - return err - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationVersionLimitExceeded(v **types.AssociationVersionLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AssociationVersionLimitExceeded - if *v == nil { - sv = &types.AssociationVersionLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAssociationVersionList(v *[]types.AssociationVersionInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AssociationVersionInfo - if *v == nil { - cv = []types.AssociationVersionInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AssociationVersionInfo - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAssociationVersionInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAttachmentContent(v **types.AttachmentContent, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AttachmentContent - if *v == nil { - sv = &types.AttachmentContent{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Hash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttachmentHash to be of type string, got %T instead", value) - } - sv.Hash = ptr.String(jtv) - } - - case "HashType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttachmentHashType to be of type string, got %T instead", value) - } - sv.HashType = types.AttachmentHashType(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttachmentName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Size": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ContentLength to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Size = i64 - } - - case "Url": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttachmentUrl to be of type string, got %T instead", value) - } - sv.Url = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAttachmentContentList(v *[]types.AttachmentContent, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AttachmentContent - if *v == nil { - cv = []types.AttachmentContent{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AttachmentContent - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAttachmentContent(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAttachmentInformation(v **types.AttachmentInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AttachmentInformation - if *v == nil { - sv = &types.AttachmentInformation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttachmentName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAttachmentInformationList(v *[]types.AttachmentInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AttachmentInformation - if *v == nil { - cv = []types.AttachmentInformation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AttachmentInformation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAttachmentInformation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationDefinitionNotApprovedException(v **types.AutomationDefinitionNotApprovedException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationDefinitionNotApprovedException - if *v == nil { - sv = &types.AutomationDefinitionNotApprovedException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationDefinitionNotFoundException(v **types.AutomationDefinitionNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationDefinitionNotFoundException - if *v == nil { - sv = &types.AutomationDefinitionNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationDefinitionVersionNotFoundException(v **types.AutomationDefinitionVersionNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationDefinitionVersionNotFoundException - if *v == nil { - sv = &types.AutomationDefinitionVersionNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationExecution(v **types.AutomationExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationExecution - if *v == nil { - sv = &types.AutomationExecution{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.AutomationExecutionId = ptr.String(jtv) - } - - case "AutomationExecutionStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionStatus to be of type string, got %T instead", value) - } - sv.AutomationExecutionStatus = types.AutomationExecutionStatus(jtv) - } - - case "AutomationSubtype": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationSubtype to be of type string, got %T instead", value) - } - sv.AutomationSubtype = types.AutomationSubtype(jtv) - } - - case "ChangeRequestName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ChangeRequestName to be of type string, got %T instead", value) - } - sv.ChangeRequestName = ptr.String(jtv) - } - - case "CurrentAction": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CurrentAction = ptr.String(jtv) - } - - case "CurrentStepName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CurrentStepName = ptr.String(jtv) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "ExecutedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.ExecutedBy = ptr.String(jtv) - } - - case "ExecutionEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "FailureMessage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.FailureMessage = ptr.String(jtv) - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Mode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ExecutionMode to be of type string, got %T instead", value) - } - sv.Mode = types.ExecutionMode(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "Outputs": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Outputs, value); err != nil { - return err - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Parameters, value); err != nil { - return err - } - - case "ParentAutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.ParentAutomationExecutionId = ptr.String(jtv) - } - - case "ProgressCounters": - if err := awsAwsjson11_deserializeDocumentProgressCounters(&sv.ProgressCounters, value); err != nil { - return err - } - - case "ResolvedTargets": - if err := awsAwsjson11_deserializeDocumentResolvedTargets(&sv.ResolvedTargets, value); err != nil { - return err - } - - case "Runbooks": - if err := awsAwsjson11_deserializeDocumentRunbooks(&sv.Runbooks, value); err != nil { - return err - } - - case "ScheduledTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ScheduledTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "StepExecutions": - if err := awsAwsjson11_deserializeDocumentStepExecutionList(&sv.StepExecutions, value); err != nil { - return err - } - - case "StepExecutionsTruncated": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.StepExecutionsTruncated = jtv - } - - case "Target": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Target = ptr.String(jtv) - } - - case "TargetLocations": - if err := awsAwsjson11_deserializeDocumentTargetLocations(&sv.TargetLocations, value); err != nil { - return err - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "TargetParameterName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationParameterKey to be of type string, got %T instead", value) - } - sv.TargetParameterName = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - case "Variables": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Variables, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationExecutionLimitExceededException(v **types.AutomationExecutionLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationExecutionLimitExceededException - if *v == nil { - sv = &types.AutomationExecutionLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationExecutionMetadata(v **types.AutomationExecutionMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationExecutionMetadata - if *v == nil { - sv = &types.AutomationExecutionMetadata{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.AutomationExecutionId = ptr.String(jtv) - } - - case "AutomationExecutionStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionStatus to be of type string, got %T instead", value) - } - sv.AutomationExecutionStatus = types.AutomationExecutionStatus(jtv) - } - - case "AutomationSubtype": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationSubtype to be of type string, got %T instead", value) - } - sv.AutomationSubtype = types.AutomationSubtype(jtv) - } - - case "AutomationType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationType to be of type string, got %T instead", value) - } - sv.AutomationType = types.AutomationType(jtv) - } - - case "ChangeRequestName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ChangeRequestName to be of type string, got %T instead", value) - } - sv.ChangeRequestName = ptr.String(jtv) - } - - case "CurrentAction": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CurrentAction = ptr.String(jtv) - } - - case "CurrentStepName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CurrentStepName = ptr.String(jtv) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "ExecutedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.ExecutedBy = ptr.String(jtv) - } - - case "ExecutionEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "FailureMessage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.FailureMessage = ptr.String(jtv) - } - - case "LogFile": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LogFile = ptr.String(jtv) - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Mode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ExecutionMode to be of type string, got %T instead", value) - } - sv.Mode = types.ExecutionMode(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "Outputs": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Outputs, value); err != nil { - return err - } - - case "ParentAutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.ParentAutomationExecutionId = ptr.String(jtv) - } - - case "ResolvedTargets": - if err := awsAwsjson11_deserializeDocumentResolvedTargets(&sv.ResolvedTargets, value); err != nil { - return err - } - - case "Runbooks": - if err := awsAwsjson11_deserializeDocumentRunbooks(&sv.Runbooks, value); err != nil { - return err - } - - case "ScheduledTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ScheduledTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Target": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Target = ptr.String(jtv) - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "TargetParameterName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationParameterKey to be of type string, got %T instead", value) - } - sv.TargetParameterName = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationExecutionMetadataList(v *[]types.AutomationExecutionMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AutomationExecutionMetadata - if *v == nil { - cv = []types.AutomationExecutionMetadata{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AutomationExecutionMetadata - destAddr := &col - if err := awsAwsjson11_deserializeDocumentAutomationExecutionMetadata(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationExecutionNotFoundException(v **types.AutomationExecutionNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationExecutionNotFoundException - if *v == nil { - sv = &types.AutomationExecutionNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationParameterMap(v *map[string][]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string][]string - if *v == nil { - mv = map[string][]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal []string - mapVar := parsedVal - if err := awsAwsjson11_deserializeDocumentAutomationParameterValueList(&mapVar, value); err != nil { - return err - } - parsedVal = mapVar - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationParameterValueList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationParameterValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentAutomationStepNotFoundException(v **types.AutomationStepNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AutomationStepNotFoundException - if *v == nil { - sv = &types.AutomationStepNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCalendarNameOrARNList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CalendarNameOrARN to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentCategoryEnumList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Category to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentCategoryList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Category to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentCloudWatchOutputConfig(v **types.CloudWatchOutputConfig, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CloudWatchOutputConfig - if *v == nil { - sv = &types.CloudWatchOutputConfig{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CloudWatchLogGroupName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CloudWatchLogGroupName to be of type string, got %T instead", value) - } - sv.CloudWatchLogGroupName = ptr.String(jtv) - } - - case "CloudWatchOutputEnabled": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected CloudWatchOutputEnabled to be of type *bool, got %T instead", value) - } - sv.CloudWatchOutputEnabled = jtv - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCommand(v **types.Command, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Command - if *v == nil { - sv = &types.Command{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "CloudWatchOutputConfig": - if err := awsAwsjson11_deserializeDocumentCloudWatchOutputConfig(&sv.CloudWatchOutputConfig, value); err != nil { - return err - } - - case "CommandId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandId to be of type string, got %T instead", value) - } - sv.CommandId = ptr.String(jtv) - } - - case "Comment": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Comment to be of type string, got %T instead", value) - } - sv.Comment = ptr.String(jtv) - } - - case "CompletedCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected CompletedCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.CompletedCount = int32(i64) - } - - case "DeliveryTimedOutCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected DeliveryTimedOutCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.DeliveryTimedOutCount = int32(i64) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "ErrorCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ErrorCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ErrorCount = int32(i64) - } - - case "ExpiresAfter": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExpiresAfter = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "InstanceIds": - if err := awsAwsjson11_deserializeDocumentInstanceIdList(&sv.InstanceIds, value); err != nil { - return err - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "NotificationConfig": - if err := awsAwsjson11_deserializeDocumentNotificationConfig(&sv.NotificationConfig, value); err != nil { - return err - } - - case "OutputS3BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3BucketName to be of type string, got %T instead", value) - } - sv.OutputS3BucketName = ptr.String(jtv) - } - - case "OutputS3KeyPrefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3KeyPrefix to be of type string, got %T instead", value) - } - sv.OutputS3KeyPrefix = ptr.String(jtv) - } - - case "OutputS3Region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3Region to be of type string, got %T instead", value) - } - sv.OutputS3Region = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameters(&sv.Parameters, value); err != nil { - return err - } - - case "RequestedDateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.RequestedDateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ServiceRole": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRole = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandStatus to be of type string, got %T instead", value) - } - sv.Status = types.CommandStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TargetCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected TargetCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TargetCount = int32(i64) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TimeoutSeconds": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected TimeoutSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TimeoutSeconds = ptr.Int32(int32(i64)) - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCommandInvocation(v **types.CommandInvocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CommandInvocation - if *v == nil { - sv = &types.CommandInvocation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CloudWatchOutputConfig": - if err := awsAwsjson11_deserializeDocumentCloudWatchOutputConfig(&sv.CloudWatchOutputConfig, value); err != nil { - return err - } - - case "CommandId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandId to be of type string, got %T instead", value) - } - sv.CommandId = ptr.String(jtv) - } - - case "CommandPlugins": - if err := awsAwsjson11_deserializeDocumentCommandPluginList(&sv.CommandPlugins, value); err != nil { - return err - } - - case "Comment": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Comment to be of type string, got %T instead", value) - } - sv.Comment = ptr.String(jtv) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "InstanceName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceTagName to be of type string, got %T instead", value) - } - sv.InstanceName = ptr.String(jtv) - } - - case "NotificationConfig": - if err := awsAwsjson11_deserializeDocumentNotificationConfig(&sv.NotificationConfig, value); err != nil { - return err - } - - case "RequestedDateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.RequestedDateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ServiceRole": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRole = ptr.String(jtv) - } - - case "StandardErrorUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardErrorUrl = ptr.String(jtv) - } - - case "StandardOutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardOutputUrl = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandInvocationStatus to be of type string, got %T instead", value) - } - sv.Status = types.CommandInvocationStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TraceOutput": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InvocationTraceOutput to be of type string, got %T instead", value) - } - sv.TraceOutput = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCommandInvocationList(v *[]types.CommandInvocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.CommandInvocation - if *v == nil { - cv = []types.CommandInvocation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.CommandInvocation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentCommandInvocation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentCommandList(v *[]types.Command, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Command - if *v == nil { - cv = []types.Command{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Command - destAddr := &col - if err := awsAwsjson11_deserializeDocumentCommand(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentCommandPlugin(v **types.CommandPlugin, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CommandPlugin - if *v == nil { - sv = &types.CommandPlugin{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandPluginName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Output": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandPluginOutput to be of type string, got %T instead", value) - } - sv.Output = ptr.String(jtv) - } - - case "OutputS3BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3BucketName to be of type string, got %T instead", value) - } - sv.OutputS3BucketName = ptr.String(jtv) - } - - case "OutputS3KeyPrefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3KeyPrefix to be of type string, got %T instead", value) - } - sv.OutputS3KeyPrefix = ptr.String(jtv) - } - - case "OutputS3Region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3Region to be of type string, got %T instead", value) - } - sv.OutputS3Region = ptr.String(jtv) - } - - case "ResponseCode": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ResponseCode to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ResponseCode = int32(i64) - } - - case "ResponseFinishDateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ResponseFinishDateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ResponseStartDateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ResponseStartDateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "StandardErrorUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardErrorUrl = ptr.String(jtv) - } - - case "StandardOutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardOutputUrl = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandPluginStatus to be of type string, got %T instead", value) - } - sv.Status = types.CommandPluginStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCommandPluginList(v *[]types.CommandPlugin, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.CommandPlugin - if *v == nil { - cv = []types.CommandPlugin{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.CommandPlugin - destAddr := &col - if err := awsAwsjson11_deserializeDocumentCommandPlugin(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceExecutionSummary(v **types.ComplianceExecutionSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ComplianceExecutionSummary - if *v == nil { - sv = &types.ComplianceExecutionSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceExecutionId to be of type string, got %T instead", value) - } - sv.ExecutionId = ptr.String(jtv) - } - - case "ExecutionTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceExecutionType to be of type string, got %T instead", value) - } - sv.ExecutionType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceItem(v **types.ComplianceItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ComplianceItem - if *v == nil { - sv = &types.ComplianceItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ComplianceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceTypeName to be of type string, got %T instead", value) - } - sv.ComplianceType = ptr.String(jtv) - } - - case "Details": - if err := awsAwsjson11_deserializeDocumentComplianceItemDetails(&sv.Details, value); err != nil { - return err - } - - case "ExecutionSummary": - if err := awsAwsjson11_deserializeDocumentComplianceExecutionSummary(&sv.ExecutionSummary, value); err != nil { - return err - } - - case "Id": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceItemId to be of type string, got %T instead", value) - } - sv.Id = ptr.String(jtv) - } - - case "ResourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceResourceId to be of type string, got %T instead", value) - } - sv.ResourceId = ptr.String(jtv) - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = ptr.String(jtv) - } - - case "Severity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceSeverity to be of type string, got %T instead", value) - } - sv.Severity = types.ComplianceSeverity(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceStatus to be of type string, got %T instead", value) - } - sv.Status = types.ComplianceStatus(jtv) - } - - case "Title": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceItemTitle to be of type string, got %T instead", value) - } - sv.Title = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceItemDetails(v *map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]string - if *v == nil { - mv = map[string]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttributeValue to be of type string, got %T instead", value) - } - parsedVal = jtv - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceItemList(v *[]types.ComplianceItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ComplianceItem - if *v == nil { - cv = []types.ComplianceItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ComplianceItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentComplianceItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceSummaryItem(v **types.ComplianceSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ComplianceSummaryItem - if *v == nil { - sv = &types.ComplianceSummaryItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ComplianceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceTypeName to be of type string, got %T instead", value) - } - sv.ComplianceType = ptr.String(jtv) - } - - case "CompliantSummary": - if err := awsAwsjson11_deserializeDocumentCompliantSummary(&sv.CompliantSummary, value); err != nil { - return err - } - - case "NonCompliantSummary": - if err := awsAwsjson11_deserializeDocumentNonCompliantSummary(&sv.NonCompliantSummary, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceSummaryItemList(v *[]types.ComplianceSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ComplianceSummaryItem - if *v == nil { - cv = []types.ComplianceSummaryItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ComplianceSummaryItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentComplianceSummaryItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentComplianceTypeCountLimitExceededException(v **types.ComplianceTypeCountLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ComplianceTypeCountLimitExceededException - if *v == nil { - sv = &types.ComplianceTypeCountLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCompliantSummary(v **types.CompliantSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CompliantSummary - if *v == nil { - sv = &types.CompliantSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CompliantCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.CompliantCount = int32(i64) - } - - case "SeveritySummary": - if err := awsAwsjson11_deserializeDocumentSeveritySummary(&sv.SeveritySummary, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCreateAssociationBatchRequestEntry(v **types.CreateAssociationBatchRequestEntry, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CreateAssociationBatchRequestEntry - if *v == nil { - sv = &types.CreateAssociationBatchRequestEntry{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "ApplyOnlyAtCronInterval": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected ApplyOnlyAtCronInterval to be of type *bool, got %T instead", value) - } - sv.ApplyOnlyAtCronInterval = jtv - } - - case "AssociationName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationName to be of type string, got %T instead", value) - } - sv.AssociationName = ptr.String(jtv) - } - - case "AutomationTargetParameterName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationTargetParameterName to be of type string, got %T instead", value) - } - sv.AutomationTargetParameterName = ptr.String(jtv) - } - - case "CalendarNames": - if err := awsAwsjson11_deserializeDocumentCalendarNameOrARNList(&sv.CalendarNames, value); err != nil { - return err - } - - case "ComplianceSeverity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationComplianceSeverity to be of type string, got %T instead", value) - } - sv.ComplianceSeverity = types.AssociationComplianceSeverity(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OutputLocation": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationOutputLocation(&sv.OutputLocation, value); err != nil { - return err - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameters(&sv.Parameters, value); err != nil { - return err - } - - case "ScheduleExpression": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ScheduleExpression to be of type string, got %T instead", value) - } - sv.ScheduleExpression = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ScheduleOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "SyncCompliance": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationSyncCompliance to be of type string, got %T instead", value) - } - sv.SyncCompliance = types.AssociationSyncCompliance(jtv) - } - - case "TargetLocations": - if err := awsAwsjson11_deserializeDocumentTargetLocations(&sv.TargetLocations, value); err != nil { - return err - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentCustomSchemaCountLimitExceededException(v **types.CustomSchemaCountLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.CustomSchemaCountLimitExceededException - if *v == nil { - sv = &types.CustomSchemaCountLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentAlreadyExists(v **types.DocumentAlreadyExists, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentAlreadyExists - if *v == nil { - sv = &types.DocumentAlreadyExists{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentDefaultVersionDescription(v **types.DocumentDefaultVersionDescription, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentDefaultVersionDescription - if *v == nil { - sv = &types.DocumentDefaultVersionDescription{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DefaultVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DefaultVersion = ptr.String(jtv) - } - - case "DefaultVersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.DefaultVersionName = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentDescription(v **types.DocumentDescription, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentDescription - if *v == nil { - sv = &types.DocumentDescription{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApprovedVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.ApprovedVersion = ptr.String(jtv) - } - - case "AttachmentsInformation": - if err := awsAwsjson11_deserializeDocumentAttachmentInformationList(&sv.AttachmentsInformation, value); err != nil { - return err - } - - case "Author": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentAuthor to be of type string, got %T instead", value) - } - sv.Author = ptr.String(jtv) - } - - case "Category": - if err := awsAwsjson11_deserializeDocumentCategoryList(&sv.Category, value); err != nil { - return err - } - - case "CategoryEnum": - if err := awsAwsjson11_deserializeDocumentCategoryEnumList(&sv.CategoryEnum, value); err != nil { - return err - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DefaultVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DefaultVersion = ptr.String(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DescriptionInDocument to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "DisplayName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentDisplayName to be of type string, got %T instead", value) - } - sv.DisplayName = ptr.String(jtv) - } - - case "DocumentFormat": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentFormat to be of type string, got %T instead", value) - } - sv.DocumentFormat = types.DocumentFormat(jtv) - } - - case "DocumentType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentType to be of type string, got %T instead", value) - } - sv.DocumentType = types.DocumentType(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "Hash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentHash to be of type string, got %T instead", value) - } - sv.Hash = ptr.String(jtv) - } - - case "HashType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentHashType to be of type string, got %T instead", value) - } - sv.HashType = types.DocumentHashType(jtv) - } - - case "LatestVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.LatestVersion = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Owner": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentOwner to be of type string, got %T instead", value) - } - sv.Owner = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentDocumentParameterList(&sv.Parameters, value); err != nil { - return err - } - - case "PendingReviewVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.PendingReviewVersion = ptr.String(jtv) - } - - case "PlatformTypes": - if err := awsAwsjson11_deserializeDocumentPlatformTypeList(&sv.PlatformTypes, value); err != nil { - return err - } - - case "Requires": - if err := awsAwsjson11_deserializeDocumentDocumentRequiresList(&sv.Requires, value); err != nil { - return err - } - - case "ReviewInformation": - if err := awsAwsjson11_deserializeDocumentReviewInformationList(&sv.ReviewInformation, value); err != nil { - return err - } - - case "ReviewStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.ReviewStatus = types.ReviewStatus(jtv) - } - - case "SchemaVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentSchemaVersion to be of type string, got %T instead", value) - } - sv.SchemaVersion = ptr.String(jtv) - } - - case "Sha1": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentSha1 to be of type string, got %T instead", value) - } - sv.Sha1 = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatus to be of type string, got %T instead", value) - } - sv.Status = types.DocumentStatus(jtv) - } - - case "StatusInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatusInformation to be of type string, got %T instead", value) - } - sv.StatusInformation = ptr.String(jtv) - } - - case "Tags": - if err := awsAwsjson11_deserializeDocumentTagList(&sv.Tags, value); err != nil { - return err - } - - case "TargetType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TargetType to be of type string, got %T instead", value) - } - sv.TargetType = ptr.String(jtv) - } - - case "VersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.VersionName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentIdentifier(v **types.DocumentIdentifier, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentIdentifier - if *v == nil { - sv = &types.DocumentIdentifier{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Author": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentAuthor to be of type string, got %T instead", value) - } - sv.Author = ptr.String(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DisplayName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentDisplayName to be of type string, got %T instead", value) - } - sv.DisplayName = ptr.String(jtv) - } - - case "DocumentFormat": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentFormat to be of type string, got %T instead", value) - } - sv.DocumentFormat = types.DocumentFormat(jtv) - } - - case "DocumentType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentType to be of type string, got %T instead", value) - } - sv.DocumentType = types.DocumentType(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Owner": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentOwner to be of type string, got %T instead", value) - } - sv.Owner = ptr.String(jtv) - } - - case "PlatformTypes": - if err := awsAwsjson11_deserializeDocumentPlatformTypeList(&sv.PlatformTypes, value); err != nil { - return err - } - - case "Requires": - if err := awsAwsjson11_deserializeDocumentDocumentRequiresList(&sv.Requires, value); err != nil { - return err - } - - case "ReviewStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.ReviewStatus = types.ReviewStatus(jtv) - } - - case "SchemaVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentSchemaVersion to be of type string, got %T instead", value) - } - sv.SchemaVersion = ptr.String(jtv) - } - - case "Tags": - if err := awsAwsjson11_deserializeDocumentTagList(&sv.Tags, value); err != nil { - return err - } - - case "TargetType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TargetType to be of type string, got %T instead", value) - } - sv.TargetType = ptr.String(jtv) - } - - case "VersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.VersionName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentIdentifierList(v *[]types.DocumentIdentifier, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentIdentifier - if *v == nil { - cv = []types.DocumentIdentifier{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentIdentifier - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentIdentifier(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentLimitExceeded(v **types.DocumentLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentLimitExceeded - if *v == nil { - sv = &types.DocumentLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentMetadataResponseInfo(v **types.DocumentMetadataResponseInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentMetadataResponseInfo - if *v == nil { - sv = &types.DocumentMetadataResponseInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ReviewerResponse": - if err := awsAwsjson11_deserializeDocumentDocumentReviewerResponseList(&sv.ReviewerResponse, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentParameter(v **types.DocumentParameter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentParameter - if *v == nil { - sv = &types.DocumentParameter{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DefaultValue": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentParameterDefaultValue to be of type string, got %T instead", value) - } - sv.DefaultValue = ptr.String(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentParameterDescrption to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentParameterName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentParameterType to be of type string, got %T instead", value) - } - sv.Type = types.DocumentParameterType(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentParameterList(v *[]types.DocumentParameter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentParameter - if *v == nil { - cv = []types.DocumentParameter{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentParameter - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentParameter(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentPermissionLimit(v **types.DocumentPermissionLimit, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentPermissionLimit - if *v == nil { - sv = &types.DocumentPermissionLimit{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentRequires(v **types.DocumentRequires, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentRequires - if *v == nil { - sv = &types.DocumentRequires{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "RequireType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected RequireType to be of type string, got %T instead", value) - } - sv.RequireType = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.Version = ptr.String(jtv) - } - - case "VersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.VersionName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentRequiresList(v *[]types.DocumentRequires, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentRequires - if *v == nil { - cv = []types.DocumentRequires{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentRequires - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentRequires(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentReviewCommentList(v *[]types.DocumentReviewCommentSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentReviewCommentSource - if *v == nil { - cv = []types.DocumentReviewCommentSource{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentReviewCommentSource - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentReviewCommentSource(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentReviewCommentSource(v **types.DocumentReviewCommentSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentReviewCommentSource - if *v == nil { - sv = &types.DocumentReviewCommentSource{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Content": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentReviewComment to be of type string, got %T instead", value) - } - sv.Content = ptr.String(jtv) - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentReviewCommentType to be of type string, got %T instead", value) - } - sv.Type = types.DocumentReviewCommentType(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentReviewerResponseList(v *[]types.DocumentReviewerResponseSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentReviewerResponseSource - if *v == nil { - cv = []types.DocumentReviewerResponseSource{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentReviewerResponseSource - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentReviewerResponseSource(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentReviewerResponseSource(v **types.DocumentReviewerResponseSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentReviewerResponseSource - if *v == nil { - sv = &types.DocumentReviewerResponseSource{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Comment": - if err := awsAwsjson11_deserializeDocumentDocumentReviewCommentList(&sv.Comment, value); err != nil { - return err - } - - case "CreateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Reviewer": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Reviewer to be of type string, got %T instead", value) - } - sv.Reviewer = ptr.String(jtv) - } - - case "ReviewStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.ReviewStatus = types.ReviewStatus(jtv) - } - - case "UpdatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.UpdatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentVersionInfo(v **types.DocumentVersionInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentVersionInfo - if *v == nil { - sv = &types.DocumentVersionInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DisplayName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentDisplayName to be of type string, got %T instead", value) - } - sv.DisplayName = ptr.String(jtv) - } - - case "DocumentFormat": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentFormat to be of type string, got %T instead", value) - } - sv.DocumentFormat = types.DocumentFormat(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "IsDefaultVersion": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.IsDefaultVersion = jtv - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "ReviewStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.ReviewStatus = types.ReviewStatus(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatus to be of type string, got %T instead", value) - } - sv.Status = types.DocumentStatus(jtv) - } - - case "StatusInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatusInformation to be of type string, got %T instead", value) - } - sv.StatusInformation = ptr.String(jtv) - } - - case "VersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.VersionName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentVersionLimitExceeded(v **types.DocumentVersionLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DocumentVersionLimitExceeded - if *v == nil { - sv = &types.DocumentVersionLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDocumentVersionList(v *[]types.DocumentVersionInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.DocumentVersionInfo - if *v == nil { - cv = []types.DocumentVersionInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.DocumentVersionInfo - destAddr := &col - if err := awsAwsjson11_deserializeDocumentDocumentVersionInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentDoesNotExistException(v **types.DoesNotExistException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DoesNotExistException - if *v == nil { - sv = &types.DoesNotExistException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDuplicateDocumentContent(v **types.DuplicateDocumentContent, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DuplicateDocumentContent - if *v == nil { - sv = &types.DuplicateDocumentContent{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDuplicateDocumentVersionName(v **types.DuplicateDocumentVersionName, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DuplicateDocumentVersionName - if *v == nil { - sv = &types.DuplicateDocumentVersionName{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentDuplicateInstanceId(v **types.DuplicateInstanceId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.DuplicateInstanceId - if *v == nil { - sv = &types.DuplicateInstanceId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentEffectivePatch(v **types.EffectivePatch, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.EffectivePatch - if *v == nil { - sv = &types.EffectivePatch{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Patch": - if err := awsAwsjson11_deserializeDocumentPatch(&sv.Patch, value); err != nil { - return err - } - - case "PatchStatus": - if err := awsAwsjson11_deserializeDocumentPatchStatus(&sv.PatchStatus, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentEffectivePatchList(v *[]types.EffectivePatch, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.EffectivePatch - if *v == nil { - cv = []types.EffectivePatch{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.EffectivePatch - destAddr := &col - if err := awsAwsjson11_deserializeDocumentEffectivePatch(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentFailedCreateAssociation(v **types.FailedCreateAssociation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.FailedCreateAssociation - if *v == nil { - sv = &types.FailedCreateAssociation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Entry": - if err := awsAwsjson11_deserializeDocumentCreateAssociationBatchRequestEntry(&sv.Entry, value); err != nil { - return err - } - - case "Fault": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Fault to be of type string, got %T instead", value) - } - sv.Fault = types.Fault(jtv) - } - - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BatchErrorMessage to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentFailedCreateAssociationList(v *[]types.FailedCreateAssociation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.FailedCreateAssociation - if *v == nil { - cv = []types.FailedCreateAssociation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.FailedCreateAssociation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentFailedCreateAssociation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentFailureDetails(v **types.FailureDetails, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.FailureDetails - if *v == nil { - sv = &types.FailureDetails{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Details": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Details, value); err != nil { - return err - } - - case "FailureStage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.FailureStage = ptr.String(jtv) - } - - case "FailureType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.FailureType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentFeatureNotAvailableException(v **types.FeatureNotAvailableException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.FeatureNotAvailableException - if *v == nil { - sv = &types.FeatureNotAvailableException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentGetResourcePoliciesResponseEntries(v *[]types.GetResourcePoliciesResponseEntry, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.GetResourcePoliciesResponseEntry - if *v == nil { - cv = []types.GetResourcePoliciesResponseEntry{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.GetResourcePoliciesResponseEntry - destAddr := &col - if err := awsAwsjson11_deserializeDocumentGetResourcePoliciesResponseEntry(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentGetResourcePoliciesResponseEntry(v **types.GetResourcePoliciesResponseEntry, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.GetResourcePoliciesResponseEntry - if *v == nil { - sv = &types.GetResourcePoliciesResponseEntry{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Policy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Policy to be of type string, got %T instead", value) - } - sv.Policy = ptr.String(jtv) - } - - case "PolicyHash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PolicyHash to be of type string, got %T instead", value) - } - sv.PolicyHash = ptr.String(jtv) - } - - case "PolicyId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PolicyId to be of type string, got %T instead", value) - } - sv.PolicyId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentHierarchyLevelLimitExceededException(v **types.HierarchyLevelLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.HierarchyLevelLimitExceededException - if *v == nil { - sv = &types.HierarchyLevelLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentHierarchyTypeMismatchException(v **types.HierarchyTypeMismatchException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.HierarchyTypeMismatchException - if *v == nil { - sv = &types.HierarchyTypeMismatchException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentIdempotentParameterMismatch(v **types.IdempotentParameterMismatch, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.IdempotentParameterMismatch - if *v == nil { - sv = &types.IdempotentParameterMismatch{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentIncompatiblePolicyException(v **types.IncompatiblePolicyException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.IncompatiblePolicyException - if *v == nil { - sv = &types.IncompatiblePolicyException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAggregatedAssociationOverview(v **types.InstanceAggregatedAssociationOverview, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceAggregatedAssociationOverview - if *v == nil { - sv = &types.InstanceAggregatedAssociationOverview{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DetailedStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.DetailedStatus = ptr.String(jtv) - } - - case "InstanceAssociationStatusAggregatedCount": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationStatusAggregatedCount(&sv.InstanceAssociationStatusAggregatedCount, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociation(v **types.InstanceAssociation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceAssociation - if *v == nil { - sv = &types.InstanceAssociation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "Content": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentContent to be of type string, got %T instead", value) - } - sv.Content = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationList(v *[]types.InstanceAssociation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InstanceAssociation - if *v == nil { - cv = []types.InstanceAssociation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InstanceAssociation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInstanceAssociation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationOutputLocation(v **types.InstanceAssociationOutputLocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceAssociationOutputLocation - if *v == nil { - sv = &types.InstanceAssociationOutputLocation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "S3Location": - if err := awsAwsjson11_deserializeDocumentS3OutputLocation(&sv.S3Location, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationOutputUrl(v **types.InstanceAssociationOutputUrl, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceAssociationOutputUrl - if *v == nil { - sv = &types.InstanceAssociationOutputUrl{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "S3OutputUrl": - if err := awsAwsjson11_deserializeDocumentS3OutputUrl(&sv.S3OutputUrl, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationStatusAggregatedCount(v *map[string]int32, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]int32 - if *v == nil { - mv = map[string]int32{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal int32 - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstanceCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - parsedVal = int32(i64) - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationStatusInfo(v **types.InstanceAssociationStatusInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceAssociationStatusInfo - if *v == nil { - sv = &types.InstanceAssociationStatusInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationName to be of type string, got %T instead", value) - } - sv.AssociationName = ptr.String(jtv) - } - - case "AssociationVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AssociationVersion to be of type string, got %T instead", value) - } - sv.AssociationVersion = ptr.String(jtv) - } - - case "DetailedStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.DetailedStatus = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "ErrorCode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AgentErrorCode to be of type string, got %T instead", value) - } - sv.ErrorCode = ptr.String(jtv) - } - - case "ExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionSummary": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceAssociationExecutionSummary to be of type string, got %T instead", value) - } - sv.ExecutionSummary = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OutputUrl": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationOutputUrl(&sv.OutputUrl, value); err != nil { - return err - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.Status = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceAssociationStatusInfos(v *[]types.InstanceAssociationStatusInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InstanceAssociationStatusInfo - if *v == nil { - cv = []types.InstanceAssociationStatusInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InstanceAssociationStatusInfo - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInstanceAssociationStatusInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceInformation(v **types.InstanceInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstanceInformation - if *v == nil { - sv = &types.InstanceInformation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActivationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ActivationId to be of type string, got %T instead", value) - } - sv.ActivationId = ptr.String(jtv) - } - - case "AgentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Version to be of type string, got %T instead", value) - } - sv.AgentVersion = ptr.String(jtv) - } - - case "AssociationOverview": - if err := awsAwsjson11_deserializeDocumentInstanceAggregatedAssociationOverview(&sv.AssociationOverview, value); err != nil { - return err - } - - case "AssociationStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusName to be of type string, got %T instead", value) - } - sv.AssociationStatus = ptr.String(jtv) - } - - case "ComputerName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComputerName to be of type string, got %T instead", value) - } - sv.ComputerName = ptr.String(jtv) - } - - case "IamRole": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected IamRole to be of type string, got %T instead", value) - } - sv.IamRole = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "IPAddress": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected IPAddress to be of type string, got %T instead", value) - } - sv.IPAddress = ptr.String(jtv) - } - - case "IsLatestVersion": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.IsLatestVersion = ptr.Bool(jtv) - } - - case "LastAssociationExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastAssociationExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastPingDateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastPingDateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastSuccessfulAssociationExecutionDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastSuccessfulAssociationExecutionDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "PingStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PingStatus to be of type string, got %T instead", value) - } - sv.PingStatus = types.PingStatus(jtv) - } - - case "PlatformName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.PlatformName = ptr.String(jtv) - } - - case "PlatformType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PlatformType to be of type string, got %T instead", value) - } - sv.PlatformType = types.PlatformType(jtv) - } - - case "PlatformVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.PlatformVersion = ptr.String(jtv) - } - - case "RegistrationDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.RegistrationDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = types.ResourceType(jtv) - } - - case "SourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SourceId to be of type string, got %T instead", value) - } - sv.SourceId = ptr.String(jtv) - } - - case "SourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SourceType to be of type string, got %T instead", value) - } - sv.SourceType = types.SourceType(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstanceInformationList(v *[]types.InstanceInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InstanceInformation - if *v == nil { - cv = []types.InstanceInformation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InstanceInformation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInstanceInformation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInstancePatchState(v **types.InstancePatchState, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InstancePatchState - if *v == nil { - sv = &types.InstancePatchState{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "CriticalNonCompliantCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchCriticalNonCompliantCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.CriticalNonCompliantCount = ptr.Int32(int32(i64)) - } - - case "FailedCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchFailedCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.FailedCount = int32(i64) - } - - case "InstalledCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchInstalledCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstalledCount = int32(i64) - } - - case "InstalledOtherCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchInstalledOtherCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstalledOtherCount = int32(i64) - } - - case "InstalledPendingRebootCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchInstalledPendingRebootCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstalledPendingRebootCount = ptr.Int32(int32(i64)) - } - - case "InstalledRejectedCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchInstalledRejectedCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstalledRejectedCount = ptr.Int32(int32(i64)) - } - - case "InstallOverrideList": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstallOverrideList to be of type string, got %T instead", value) - } - sv.InstallOverrideList = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "LastNoRebootInstallOperationTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastNoRebootInstallOperationTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "MissingCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchMissingCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.MissingCount = int32(i64) - } - - case "NotApplicableCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchNotApplicableCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.NotApplicableCount = int32(i64) - } - - case "Operation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchOperationType to be of type string, got %T instead", value) - } - sv.Operation = types.PatchOperationType(jtv) - } - - case "OperationEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.OperationEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "OperationStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.OperationStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "OtherNonCompliantCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchOtherNonCompliantCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.OtherNonCompliantCount = ptr.Int32(int32(i64)) - } - - case "OwnerInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OwnerInformation to be of type string, got %T instead", value) - } - sv.OwnerInformation = ptr.String(jtv) - } - - case "PatchGroup": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - sv.PatchGroup = ptr.String(jtv) - } - - case "RebootOption": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected RebootOption to be of type string, got %T instead", value) - } - sv.RebootOption = types.RebootOption(jtv) - } - - case "SecurityNonCompliantCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchSecurityNonCompliantCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.SecurityNonCompliantCount = ptr.Int32(int32(i64)) - } - - case "SnapshotId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SnapshotId to be of type string, got %T instead", value) - } - sv.SnapshotId = ptr.String(jtv) - } - - case "UnreportedNotApplicableCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchUnreportedNotApplicableCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.UnreportedNotApplicableCount = ptr.Int32(int32(i64)) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInstancePatchStateList(v *[]types.InstancePatchState, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InstancePatchState - if *v == nil { - cv = []types.InstancePatchState{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InstancePatchState - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInstancePatchState(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInstancePatchStatesList(v *[]types.InstancePatchState, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InstancePatchState - if *v == nil { - cv = []types.InstancePatchState{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InstancePatchState - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInstancePatchState(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInternalServerError(v **types.InternalServerError, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InternalServerError - if *v == nil { - sv = &types.InternalServerError{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidActivation(v **types.InvalidActivation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidActivation - if *v == nil { - sv = &types.InvalidActivation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidActivationId(v **types.InvalidActivationId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidActivationId - if *v == nil { - sv = &types.InvalidActivationId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAggregatorException(v **types.InvalidAggregatorException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAggregatorException - if *v == nil { - sv = &types.InvalidAggregatorException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAllowedPatternException(v **types.InvalidAllowedPatternException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAllowedPatternException - if *v == nil { - sv = &types.InvalidAllowedPatternException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAssociation(v **types.InvalidAssociation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAssociation - if *v == nil { - sv = &types.InvalidAssociation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAssociationVersion(v **types.InvalidAssociationVersion, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAssociationVersion - if *v == nil { - sv = &types.InvalidAssociationVersion{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAutomationExecutionParametersException(v **types.InvalidAutomationExecutionParametersException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAutomationExecutionParametersException - if *v == nil { - sv = &types.InvalidAutomationExecutionParametersException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAutomationSignalException(v **types.InvalidAutomationSignalException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAutomationSignalException - if *v == nil { - sv = &types.InvalidAutomationSignalException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidAutomationStatusUpdateException(v **types.InvalidAutomationStatusUpdateException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidAutomationStatusUpdateException - if *v == nil { - sv = &types.InvalidAutomationStatusUpdateException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidCommandId(v **types.InvalidCommandId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidCommandId - if *v == nil { - sv = &types.InvalidCommandId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDeleteInventoryParametersException(v **types.InvalidDeleteInventoryParametersException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDeleteInventoryParametersException - if *v == nil { - sv = &types.InvalidDeleteInventoryParametersException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDeletionIdException(v **types.InvalidDeletionIdException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDeletionIdException - if *v == nil { - sv = &types.InvalidDeletionIdException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocument(v **types.InvalidDocument, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocument - if *v == nil { - sv = &types.InvalidDocument{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocumentContent(v **types.InvalidDocumentContent, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocumentContent - if *v == nil { - sv = &types.InvalidDocumentContent{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocumentOperation(v **types.InvalidDocumentOperation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocumentOperation - if *v == nil { - sv = &types.InvalidDocumentOperation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocumentSchemaVersion(v **types.InvalidDocumentSchemaVersion, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocumentSchemaVersion - if *v == nil { - sv = &types.InvalidDocumentSchemaVersion{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocumentType(v **types.InvalidDocumentType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocumentType - if *v == nil { - sv = &types.InvalidDocumentType{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidDocumentVersion(v **types.InvalidDocumentVersion, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidDocumentVersion - if *v == nil { - sv = &types.InvalidDocumentVersion{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidFilter(v **types.InvalidFilter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidFilter - if *v == nil { - sv = &types.InvalidFilter{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidFilterKey(v **types.InvalidFilterKey, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidFilterKey - if *v == nil { - sv = &types.InvalidFilterKey{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidFilterOption(v **types.InvalidFilterOption, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidFilterOption - if *v == nil { - sv = &types.InvalidFilterOption{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidFilterValue(v **types.InvalidFilterValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidFilterValue - if *v == nil { - sv = &types.InvalidFilterValue{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidInstanceId(v **types.InvalidInstanceId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidInstanceId - if *v == nil { - sv = &types.InvalidInstanceId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidInstanceInformationFilterValue(v **types.InvalidInstanceInformationFilterValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidInstanceInformationFilterValue - if *v == nil { - sv = &types.InvalidInstanceInformationFilterValue{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidInventoryGroupException(v **types.InvalidInventoryGroupException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidInventoryGroupException - if *v == nil { - sv = &types.InvalidInventoryGroupException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidInventoryItemContextException(v **types.InvalidInventoryItemContextException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidInventoryItemContextException - if *v == nil { - sv = &types.InvalidInventoryItemContextException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidInventoryRequestException(v **types.InvalidInventoryRequestException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidInventoryRequestException - if *v == nil { - sv = &types.InvalidInventoryRequestException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidItemContentException(v **types.InvalidItemContentException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidItemContentException - if *v == nil { - sv = &types.InvalidItemContentException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidKeyId(v **types.InvalidKeyId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidKeyId - if *v == nil { - sv = &types.InvalidKeyId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidNextToken(v **types.InvalidNextToken, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidNextToken - if *v == nil { - sv = &types.InvalidNextToken{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidNotificationConfig(v **types.InvalidNotificationConfig, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidNotificationConfig - if *v == nil { - sv = &types.InvalidNotificationConfig{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidOptionException(v **types.InvalidOptionException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidOptionException - if *v == nil { - sv = &types.InvalidOptionException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidOutputFolder(v **types.InvalidOutputFolder, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidOutputFolder - if *v == nil { - sv = &types.InvalidOutputFolder{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidOutputLocation(v **types.InvalidOutputLocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidOutputLocation - if *v == nil { - sv = &types.InvalidOutputLocation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidParameters(v **types.InvalidParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidParameters - if *v == nil { - sv = &types.InvalidParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidPermissionType(v **types.InvalidPermissionType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidPermissionType - if *v == nil { - sv = &types.InvalidPermissionType{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidPluginName(v **types.InvalidPluginName, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidPluginName - if *v == nil { - sv = &types.InvalidPluginName{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidPolicyAttributeException(v **types.InvalidPolicyAttributeException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidPolicyAttributeException - if *v == nil { - sv = &types.InvalidPolicyAttributeException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidPolicyTypeException(v **types.InvalidPolicyTypeException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidPolicyTypeException - if *v == nil { - sv = &types.InvalidPolicyTypeException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidResourceId(v **types.InvalidResourceId, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidResourceId - if *v == nil { - sv = &types.InvalidResourceId{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidResourceType(v **types.InvalidResourceType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidResourceType - if *v == nil { - sv = &types.InvalidResourceType{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidResultAttributeException(v **types.InvalidResultAttributeException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidResultAttributeException - if *v == nil { - sv = &types.InvalidResultAttributeException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidRole(v **types.InvalidRole, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidRole - if *v == nil { - sv = &types.InvalidRole{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidSchedule(v **types.InvalidSchedule, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidSchedule - if *v == nil { - sv = &types.InvalidSchedule{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidTag(v **types.InvalidTag, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidTag - if *v == nil { - sv = &types.InvalidTag{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidTarget(v **types.InvalidTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidTarget - if *v == nil { - sv = &types.InvalidTarget{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidTargetMaps(v **types.InvalidTargetMaps, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidTargetMaps - if *v == nil { - sv = &types.InvalidTargetMaps{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidTypeNameException(v **types.InvalidTypeNameException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidTypeNameException - if *v == nil { - sv = &types.InvalidTypeNameException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInvalidUpdate(v **types.InvalidUpdate, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidUpdate - if *v == nil { - sv = &types.InvalidUpdate{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryDeletionsList(v *[]types.InventoryDeletionStatusItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InventoryDeletionStatusItem - if *v == nil { - cv = []types.InventoryDeletionStatusItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InventoryDeletionStatusItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInventoryDeletionStatusItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryDeletionStatusItem(v **types.InventoryDeletionStatusItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryDeletionStatusItem - if *v == nil { - sv = &types.InventoryDeletionStatusItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DeletionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected UUID to be of type string, got %T instead", value) - } - sv.DeletionId = ptr.String(jtv) - } - - case "DeletionStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.DeletionStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected InventoryDeletionStartTime to be a JSON Number, got %T instead", value) - - } - } - - case "DeletionSummary": - if err := awsAwsjson11_deserializeDocumentInventoryDeletionSummary(&sv.DeletionSummary, value); err != nil { - return err - } - - case "LastStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryDeletionStatus to be of type string, got %T instead", value) - } - sv.LastStatus = types.InventoryDeletionStatus(jtv) - } - - case "LastStatusMessage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryDeletionLastStatusMessage to be of type string, got %T instead", value) - } - sv.LastStatusMessage = ptr.String(jtv) - } - - case "LastStatusUpdateTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastStatusUpdateTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected InventoryDeletionLastStatusUpdateTime to be a JSON Number, got %T instead", value) - - } - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryDeletionSummary(v **types.InventoryDeletionSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryDeletionSummary - if *v == nil { - sv = &types.InventoryDeletionSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "RemainingCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected RemainingCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.RemainingCount = int32(i64) - } - - case "SummaryItems": - if err := awsAwsjson11_deserializeDocumentInventoryDeletionSummaryItems(&sv.SummaryItems, value); err != nil { - return err - } - - case "TotalCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected TotalCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TotalCount = int32(i64) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryDeletionSummaryItem(v **types.InventoryDeletionSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryDeletionSummaryItem - if *v == nil { - sv = &types.InventoryDeletionSummaryItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Count": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ResourceCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Count = int32(i64) - } - - case "RemainingCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected RemainingCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.RemainingCount = int32(i64) - } - - case "Version": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemSchemaVersion to be of type string, got %T instead", value) - } - sv.Version = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryDeletionSummaryItems(v *[]types.InventoryDeletionSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InventoryDeletionSummaryItem - if *v == nil { - cv = []types.InventoryDeletionSummaryItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InventoryDeletionSummaryItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInventoryDeletionSummaryItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemAttribute(v **types.InventoryItemAttribute, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryItemAttribute - if *v == nil { - sv = &types.InventoryItemAttribute{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DataType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryAttributeDataType to be of type string, got %T instead", value) - } - sv.DataType = types.InventoryAttributeDataType(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemAttributeName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemAttributeList(v *[]types.InventoryItemAttribute, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InventoryItemAttribute - if *v == nil { - cv = []types.InventoryItemAttribute{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InventoryItemAttribute - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInventoryItemAttribute(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemEntry(v *map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]string - if *v == nil { - mv = map[string]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttributeValue to be of type string, got %T instead", value) - } - parsedVal = jtv - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemEntryList(v *[]map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []map[string]string - if *v == nil { - cv = []map[string]string{} - } else { - cv = *v - } - - for _, value := range shape { - var col map[string]string - if err := awsAwsjson11_deserializeDocumentInventoryItemEntry(&col, value); err != nil { - return err - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemSchema(v **types.InventoryItemSchema, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryItemSchema - if *v == nil { - sv = &types.InventoryItemSchema{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Attributes": - if err := awsAwsjson11_deserializeDocumentInventoryItemAttributeList(&sv.Attributes, value); err != nil { - return err - } - - case "DisplayName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryTypeDisplayName to be of type string, got %T instead", value) - } - sv.DisplayName = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemSchemaVersion to be of type string, got %T instead", value) - } - sv.Version = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryItemSchemaResultList(v *[]types.InventoryItemSchema, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InventoryItemSchema - if *v == nil { - cv = []types.InventoryItemSchema{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InventoryItemSchema - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInventoryItemSchema(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryResultEntity(v **types.InventoryResultEntity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryResultEntity - if *v == nil { - sv = &types.InventoryResultEntity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Data": - if err := awsAwsjson11_deserializeDocumentInventoryResultItemMap(&sv.Data, value); err != nil { - return err - } - - case "Id": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryResultEntityId to be of type string, got %T instead", value) - } - sv.Id = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryResultEntityList(v *[]types.InventoryResultEntity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.InventoryResultEntity - if *v == nil { - cv = []types.InventoryResultEntity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.InventoryResultEntity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentInventoryResultEntity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryResultItem(v **types.InventoryResultItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InventoryResultItem - if *v == nil { - sv = &types.InventoryResultItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CaptureTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemCaptureTime to be of type string, got %T instead", value) - } - sv.CaptureTime = ptr.String(jtv) - } - - case "Content": - if err := awsAwsjson11_deserializeDocumentInventoryItemEntryList(&sv.Content, value); err != nil { - return err - } - - case "ContentHash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemContentHash to be of type string, got %T instead", value) - } - sv.ContentHash = ptr.String(jtv) - } - - case "SchemaVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemSchemaVersion to be of type string, got %T instead", value) - } - sv.SchemaVersion = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentInventoryResultItemMap(v *map[string]types.InventoryResultItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]types.InventoryResultItem - if *v == nil { - mv = map[string]types.InventoryResultItem{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal types.InventoryResultItem - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson11_deserializeDocumentInventoryResultItem(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentInvocationDoesNotExist(v **types.InvocationDoesNotExist, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvocationDoesNotExist - if *v == nil { - sv = &types.InvocationDoesNotExist{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentItemContentMismatchException(v **types.ItemContentMismatchException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ItemContentMismatchException - if *v == nil { - sv = &types.ItemContentMismatchException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentItemSizeLimitExceededException(v **types.ItemSizeLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ItemSizeLimitExceededException - if *v == nil { - sv = &types.ItemSizeLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentLoggingInfo(v **types.LoggingInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.LoggingInfo - if *v == nil { - sv = &types.LoggingInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "S3BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3BucketName to be of type string, got %T instead", value) - } - sv.S3BucketName = ptr.String(jtv) - } - - case "S3KeyPrefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3KeyPrefix to be of type string, got %T instead", value) - } - sv.S3KeyPrefix = ptr.String(jtv) - } - - case "S3Region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3Region to be of type string, got %T instead", value) - } - sv.S3Region = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowAutomationParameters(v **types.MaintenanceWindowAutomationParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowAutomationParameters - if *v == nil { - sv = &types.MaintenanceWindowAutomationParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Parameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecution(v **types.MaintenanceWindowExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowExecution - if *v == nil { - sv = &types.MaintenanceWindowExecution{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionList(v *[]types.MaintenanceWindowExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowExecution - if *v == nil { - cv = []types.MaintenanceWindowExecution{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowExecution - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecution(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdentity(v **types.MaintenanceWindowExecutionTaskIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowExecutionTaskIdentity - if *v == nil { - sv = &types.MaintenanceWindowExecutionTaskIdentity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TaskArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskArn to be of type string, got %T instead", value) - } - sv.TaskArn = ptr.String(jtv) - } - - case "TaskExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskId to be of type string, got %T instead", value) - } - sv.TaskExecutionId = ptr.String(jtv) - } - - case "TaskType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.TaskType = types.MaintenanceWindowTaskType(jtv) - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdentityList(v *[]types.MaintenanceWindowExecutionTaskIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowExecutionTaskIdentity - if *v == nil { - cv = []types.MaintenanceWindowExecutionTaskIdentity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowExecutionTaskIdentity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdentity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskInvocationIdentity(v **types.MaintenanceWindowExecutionTaskInvocationIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowExecutionTaskInvocationIdentity - if *v == nil { - sv = &types.MaintenanceWindowExecutionTaskInvocationIdentity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskExecutionId to be of type string, got %T instead", value) - } - sv.ExecutionId = ptr.String(jtv) - } - - case "InvocationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskInvocationId to be of type string, got %T instead", value) - } - sv.InvocationId = ptr.String(jtv) - } - - case "OwnerInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OwnerInformation to be of type string, got %T instead", value) - } - sv.OwnerInformation = ptr.String(jtv) - } - - case "Parameters": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskInvocationParameters to be of type string, got %T instead", value) - } - sv.Parameters = ptr.String(jtv) - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TaskExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskId to be of type string, got %T instead", value) - } - sv.TaskExecutionId = ptr.String(jtv) - } - - case "TaskType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.TaskType = types.MaintenanceWindowTaskType(jtv) - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskInvocationIdentityList(v *[]types.MaintenanceWindowExecutionTaskInvocationIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowExecutionTaskInvocationIdentity - if *v == nil { - cv = []types.MaintenanceWindowExecutionTaskInvocationIdentity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowExecutionTaskInvocationIdentity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskInvocationIdentity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowIdentity(v **types.MaintenanceWindowIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowIdentity - if *v == nil { - sv = &types.MaintenanceWindowIdentity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Cutoff": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowCutoff to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Cutoff = int32(i64) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Duration": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDurationHours to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Duration = ptr.Int32(int32(i64)) - } - - case "Enabled": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected MaintenanceWindowEnabled to be of type *bool, got %T instead", value) - } - sv.Enabled = jtv - } - - case "EndDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.EndDate = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "NextExecutionTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.NextExecutionTime = ptr.String(jtv) - } - - case "Schedule": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowSchedule to be of type string, got %T instead", value) - } - sv.Schedule = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "ScheduleTimezone": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTimezone to be of type string, got %T instead", value) - } - sv.ScheduleTimezone = ptr.String(jtv) - } - - case "StartDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.StartDate = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowIdentityForTarget(v **types.MaintenanceWindowIdentityForTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowIdentityForTarget - if *v == nil { - sv = &types.MaintenanceWindowIdentityForTarget{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowIdentityList(v *[]types.MaintenanceWindowIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowIdentity - if *v == nil { - cv = []types.MaintenanceWindowIdentity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowIdentity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowIdentity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowLambdaParameters(v **types.MaintenanceWindowLambdaParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowLambdaParameters - if *v == nil { - sv = &types.MaintenanceWindowLambdaParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ClientContext": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowLambdaClientContext to be of type string, got %T instead", value) - } - sv.ClientContext = ptr.String(jtv) - } - - case "Payload": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowLambdaPayload to be []byte, got %T instead", value) - } - dv, err := base64.StdEncoding.DecodeString(jtv) - if err != nil { - return fmt.Errorf("failed to base64 decode MaintenanceWindowLambdaPayload, %w", err) - } - sv.Payload = dv - } - - case "Qualifier": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowLambdaQualifier to be of type string, got %T instead", value) - } - sv.Qualifier = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowRunCommandParameters(v **types.MaintenanceWindowRunCommandParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowRunCommandParameters - if *v == nil { - sv = &types.MaintenanceWindowRunCommandParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CloudWatchOutputConfig": - if err := awsAwsjson11_deserializeDocumentCloudWatchOutputConfig(&sv.CloudWatchOutputConfig, value); err != nil { - return err - } - - case "Comment": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Comment to be of type string, got %T instead", value) - } - sv.Comment = ptr.String(jtv) - } - - case "DocumentHash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentHash to be of type string, got %T instead", value) - } - sv.DocumentHash = ptr.String(jtv) - } - - case "DocumentHashType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentHashType to be of type string, got %T instead", value) - } - sv.DocumentHashType = types.DocumentHashType(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "NotificationConfig": - if err := awsAwsjson11_deserializeDocumentNotificationConfig(&sv.NotificationConfig, value); err != nil { - return err - } - - case "OutputS3BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3BucketName to be of type string, got %T instead", value) - } - sv.OutputS3BucketName = ptr.String(jtv) - } - - case "OutputS3KeyPrefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3KeyPrefix to be of type string, got %T instead", value) - } - sv.OutputS3KeyPrefix = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameters(&sv.Parameters, value); err != nil { - return err - } - - case "ServiceRoleArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRoleArn = ptr.String(jtv) - } - - case "TimeoutSeconds": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected TimeoutSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TimeoutSeconds = ptr.Int32(int32(i64)) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowsForTargetList(v *[]types.MaintenanceWindowIdentityForTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowIdentityForTarget - if *v == nil { - cv = []types.MaintenanceWindowIdentityForTarget{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowIdentityForTarget - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowIdentityForTarget(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowStepFunctionsParameters(v **types.MaintenanceWindowStepFunctionsParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowStepFunctionsParameters - if *v == nil { - sv = &types.MaintenanceWindowStepFunctionsParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Input": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStepFunctionsInput to be of type string, got %T instead", value) - } - sv.Input = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStepFunctionsName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTarget(v **types.MaintenanceWindowTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowTarget - if *v == nil { - sv = &types.MaintenanceWindowTarget{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OwnerInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OwnerInformation to be of type string, got %T instead", value) - } - sv.OwnerInformation = ptr.String(jtv) - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = types.MaintenanceWindowResourceType(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTargetList(v *[]types.MaintenanceWindowTarget, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowTarget - if *v == nil { - cv = []types.MaintenanceWindowTarget{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowTarget - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTarget(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTask(v **types.MaintenanceWindowTask, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowTask - if *v == nil { - sv = &types.MaintenanceWindowTask{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "CutoffBehavior": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskCutoffBehavior to be of type string, got %T instead", value) - } - sv.CutoffBehavior = types.MaintenanceWindowTaskCutoffBehavior(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "LoggingInfo": - if err := awsAwsjson11_deserializeDocumentLoggingInfo(&sv.LoggingInfo, value); err != nil { - return err - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = int32(i64) - } - - case "ServiceRoleArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRoleArn = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TaskArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskArn to be of type string, got %T instead", value) - } - sv.TaskArn = ptr.String(jtv) - } - - case "TaskParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameters(&sv.TaskParameters, value); err != nil { - return err - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.Type = types.MaintenanceWindowTaskType(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTaskId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskId to be of type string, got %T instead", value) - } - sv.WindowTaskId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskInvocationParameters(v **types.MaintenanceWindowTaskInvocationParameters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowTaskInvocationParameters - if *v == nil { - sv = &types.MaintenanceWindowTaskInvocationParameters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Automation": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowAutomationParameters(&sv.Automation, value); err != nil { - return err - } - - case "Lambda": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowLambdaParameters(&sv.Lambda, value); err != nil { - return err - } - - case "RunCommand": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowRunCommandParameters(&sv.RunCommand, value); err != nil { - return err - } - - case "StepFunctions": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowStepFunctionsParameters(&sv.StepFunctions, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskList(v *[]types.MaintenanceWindowTask, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.MaintenanceWindowTask - if *v == nil { - cv = []types.MaintenanceWindowTask{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.MaintenanceWindowTask - destAddr := &col - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTask(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameters(v *map[string]types.MaintenanceWindowTaskParameterValueExpression, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]types.MaintenanceWindowTaskParameterValueExpression - if *v == nil { - mv = map[string]types.MaintenanceWindowTaskParameterValueExpression{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal types.MaintenanceWindowTaskParameterValueExpression - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameterValueExpression(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParametersList(v *[]map[string]types.MaintenanceWindowTaskParameterValueExpression, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []map[string]types.MaintenanceWindowTaskParameterValueExpression - if *v == nil { - cv = []map[string]types.MaintenanceWindowTaskParameterValueExpression{} - } else { - cv = *v - } - - for _, value := range shape { - var col map[string]types.MaintenanceWindowTaskParameterValueExpression - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameters(&col, value); err != nil { - return err - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameterValueExpression(v **types.MaintenanceWindowTaskParameterValueExpression, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaintenanceWindowTaskParameterValueExpression - if *v == nil { - sv = &types.MaintenanceWindowTaskParameterValueExpression{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Values": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameterValueList(&sv.Values, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameterValueList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskParameterValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentMaxDocumentSizeExceeded(v **types.MaxDocumentSizeExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MaxDocumentSizeExceeded - if *v == nil { - sv = &types.MaxDocumentSizeExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentMetadataMap(v *map[string]types.MetadataValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]types.MetadataValue - if *v == nil { - mv = map[string]types.MetadataValue{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal types.MetadataValue - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson11_deserializeDocumentMetadataValue(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentMetadataValue(v **types.MetadataValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.MetadataValue - if *v == nil { - sv = &types.MetadataValue{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Value": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MetadataValueString to be of type string, got %T instead", value) - } - sv.Value = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentNonCompliantSummary(v **types.NonCompliantSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.NonCompliantSummary - if *v == nil { - sv = &types.NonCompliantSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NonCompliantCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.NonCompliantCount = int32(i64) - } - - case "SeveritySummary": - if err := awsAwsjson11_deserializeDocumentSeveritySummary(&sv.SeveritySummary, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentNormalStringMap(v *map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]string - if *v == nil { - mv = map[string]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - parsedVal = jtv - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentNotificationConfig(v **types.NotificationConfig, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.NotificationConfig - if *v == nil { - sv = &types.NotificationConfig{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NotificationArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NotificationArn to be of type string, got %T instead", value) - } - sv.NotificationArn = ptr.String(jtv) - } - - case "NotificationEvents": - if err := awsAwsjson11_deserializeDocumentNotificationEventList(&sv.NotificationEvents, value); err != nil { - return err - } - - case "NotificationType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NotificationType to be of type string, got %T instead", value) - } - sv.NotificationType = types.NotificationType(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentNotificationEventList(v *[]types.NotificationEvent, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.NotificationEvent - if *v == nil { - cv = []types.NotificationEvent{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.NotificationEvent - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NotificationEvent to be of type string, got %T instead", value) - } - col = types.NotificationEvent(jtv) - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntity(v **types.OpsEntity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsEntity - if *v == nil { - sv = &types.OpsEntity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Data": - if err := awsAwsjson11_deserializeDocumentOpsEntityItemMap(&sv.Data, value); err != nil { - return err - } - - case "Id": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsEntityId to be of type string, got %T instead", value) - } - sv.Id = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntityItem(v **types.OpsEntityItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsEntityItem - if *v == nil { - sv = &types.OpsEntityItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CaptureTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsEntityItemCaptureTime to be of type string, got %T instead", value) - } - sv.CaptureTime = ptr.String(jtv) - } - - case "Content": - if err := awsAwsjson11_deserializeDocumentOpsEntityItemEntryList(&sv.Content, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntityItemEntry(v *map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]string - if *v == nil { - mv = map[string]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttributeValue to be of type string, got %T instead", value) - } - parsedVal = jtv - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntityItemEntryList(v *[]map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []map[string]string - if *v == nil { - cv = []map[string]string{} - } else { - cv = *v - } - - for _, value := range shape { - var col map[string]string - if err := awsAwsjson11_deserializeDocumentOpsEntityItemEntry(&col, value); err != nil { - return err - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntityItemMap(v *map[string]types.OpsEntityItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]types.OpsEntityItem - if *v == nil { - mv = map[string]types.OpsEntityItem{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal types.OpsEntityItem - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson11_deserializeDocumentOpsEntityItem(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsEntityList(v *[]types.OpsEntity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsEntity - if *v == nil { - cv = []types.OpsEntity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsEntity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsEntity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItem(v **types.OpsItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItem - if *v == nil { - sv = &types.OpsItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActualEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ActualEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ActualStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ActualStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Category": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemCategory to be of type string, got %T instead", value) - } - sv.Category = ptr.String(jtv) - } - - case "CreatedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CreatedBy = ptr.String(jtv) - } - - case "CreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "LastModifiedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedBy = ptr.String(jtv) - } - - case "LastModifiedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Notifications": - if err := awsAwsjson11_deserializeDocumentOpsItemNotifications(&sv.Notifications, value); err != nil { - return err - } - - case "OperationalData": - if err := awsAwsjson11_deserializeDocumentOpsItemOperationalData(&sv.OperationalData, value); err != nil { - return err - } - - case "OpsItemArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemArn to be of type string, got %T instead", value) - } - sv.OpsItemArn = ptr.String(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemId to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "OpsItemType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemType to be of type string, got %T instead", value) - } - sv.OpsItemType = ptr.String(jtv) - } - - case "PlannedEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.PlannedEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "PlannedStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.PlannedStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected OpsItemPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = ptr.Int32(int32(i64)) - } - - case "RelatedOpsItems": - if err := awsAwsjson11_deserializeDocumentRelatedOpsItems(&sv.RelatedOpsItems, value); err != nil { - return err - } - - case "Severity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemSeverity to be of type string, got %T instead", value) - } - sv.Severity = ptr.String(jtv) - } - - case "Source": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemSource to be of type string, got %T instead", value) - } - sv.Source = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemStatus to be of type string, got %T instead", value) - } - sv.Status = types.OpsItemStatus(jtv) - } - - case "Title": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemTitle to be of type string, got %T instead", value) - } - sv.Title = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Version = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemAccessDeniedException(v **types.OpsItemAccessDeniedException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemAccessDeniedException - if *v == nil { - sv = &types.OpsItemAccessDeniedException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemAlreadyExistsException(v **types.OpsItemAlreadyExistsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemAlreadyExistsException - if *v == nil { - sv = &types.OpsItemAlreadyExistsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemConflictException(v **types.OpsItemConflictException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemConflictException - if *v == nil { - sv = &types.OpsItemConflictException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemDataValue(v **types.OpsItemDataValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemDataValue - if *v == nil { - sv = &types.OpsItemDataValue{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemDataType to be of type string, got %T instead", value) - } - sv.Type = types.OpsItemDataType(jtv) - } - - case "Value": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemDataValueString to be of type string, got %T instead", value) - } - sv.Value = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemEventSummaries(v *[]types.OpsItemEventSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsItemEventSummary - if *v == nil { - cv = []types.OpsItemEventSummary{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsItemEventSummary - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsItemEventSummary(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemEventSummary(v **types.OpsItemEventSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemEventSummary - if *v == nil { - sv = &types.OpsItemEventSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CreatedBy": - if err := awsAwsjson11_deserializeDocumentOpsItemIdentity(&sv.CreatedBy, value); err != nil { - return err - } - - case "CreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Detail": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Detail = ptr.String(jtv) - } - - case "DetailType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.DetailType = ptr.String(jtv) - } - - case "EventId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.EventId = ptr.String(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "Source": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Source = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemIdentity(v **types.OpsItemIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemIdentity - if *v == nil { - sv = &types.OpsItemIdentity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Arn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Arn = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemInvalidParameterException(v **types.OpsItemInvalidParameterException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemInvalidParameterException - if *v == nil { - sv = &types.OpsItemInvalidParameterException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "ParameterNames": - if err := awsAwsjson11_deserializeDocumentOpsItemParameterNamesList(&sv.ParameterNames, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemLimitExceededException(v **types.OpsItemLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemLimitExceededException - if *v == nil { - sv = &types.OpsItemLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Limit": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Limit = int32(i64) - } - - case "LimitType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LimitType = ptr.String(jtv) - } - - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "ResourceTypes": - if err := awsAwsjson11_deserializeDocumentOpsItemParameterNamesList(&sv.ResourceTypes, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemNotFoundException(v **types.OpsItemNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemNotFoundException - if *v == nil { - sv = &types.OpsItemNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemNotification(v **types.OpsItemNotification, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemNotification - if *v == nil { - sv = &types.OpsItemNotification{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Arn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Arn = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemNotifications(v *[]types.OpsItemNotification, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsItemNotification - if *v == nil { - cv = []types.OpsItemNotification{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsItemNotification - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsItemNotification(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemOperationalData(v *map[string]types.OpsItemDataValue, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]types.OpsItemDataValue - if *v == nil { - mv = map[string]types.OpsItemDataValue{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal types.OpsItemDataValue - mapVar := parsedVal - destAddr := &mapVar - if err := awsAwsjson11_deserializeDocumentOpsItemDataValue(&destAddr, value); err != nil { - return err - } - parsedVal = *destAddr - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemParameterNamesList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemRelatedItemAlreadyExistsException(v **types.OpsItemRelatedItemAlreadyExistsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemRelatedItemAlreadyExistsException - if *v == nil { - sv = &types.OpsItemRelatedItemAlreadyExistsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemId to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "ResourceUri": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationResourceUri to be of type string, got %T instead", value) - } - sv.ResourceUri = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemRelatedItemAssociationNotFoundException(v **types.OpsItemRelatedItemAssociationNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemRelatedItemAssociationNotFoundException - if *v == nil { - sv = &types.OpsItemRelatedItemAssociationNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemRelatedItemSummaries(v *[]types.OpsItemRelatedItemSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsItemRelatedItemSummary - if *v == nil { - cv = []types.OpsItemRelatedItemSummary{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsItemRelatedItemSummary - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsItemRelatedItemSummary(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemRelatedItemSummary(v **types.OpsItemRelatedItemSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemRelatedItemSummary - if *v == nil { - sv = &types.OpsItemRelatedItemSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - case "AssociationType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationType to be of type string, got %T instead", value) - } - sv.AssociationType = ptr.String(jtv) - } - - case "CreatedBy": - if err := awsAwsjson11_deserializeDocumentOpsItemIdentity(&sv.CreatedBy, value); err != nil { - return err - } - - case "CreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedBy": - if err := awsAwsjson11_deserializeDocumentOpsItemIdentity(&sv.LastModifiedBy, value); err != nil { - return err - } - - case "LastModifiedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemId to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = ptr.String(jtv) - } - - case "ResourceUri": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationResourceUri to be of type string, got %T instead", value) - } - sv.ResourceUri = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemSummaries(v *[]types.OpsItemSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsItemSummary - if *v == nil { - cv = []types.OpsItemSummary{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsItemSummary - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsItemSummary(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsItemSummary(v **types.OpsItemSummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsItemSummary - if *v == nil { - sv = &types.OpsItemSummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActualEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ActualEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ActualStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ActualStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Category": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemCategory to be of type string, got %T instead", value) - } - sv.Category = ptr.String(jtv) - } - - case "CreatedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.CreatedBy = ptr.String(jtv) - } - - case "CreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedBy": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedBy = ptr.String(jtv) - } - - case "LastModifiedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "OperationalData": - if err := awsAwsjson11_deserializeDocumentOpsItemOperationalData(&sv.OperationalData, value); err != nil { - return err - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemId to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - case "OpsItemType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemType to be of type string, got %T instead", value) - } - sv.OpsItemType = ptr.String(jtv) - } - - case "PlannedEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.PlannedEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "PlannedStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.PlannedStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected OpsItemPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = ptr.Int32(int32(i64)) - } - - case "Severity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemSeverity to be of type string, got %T instead", value) - } - sv.Severity = ptr.String(jtv) - } - - case "Source": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemSource to be of type string, got %T instead", value) - } - sv.Source = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemStatus to be of type string, got %T instead", value) - } - sv.Status = types.OpsItemStatus(jtv) - } - - case "Title": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemTitle to be of type string, got %T instead", value) - } - sv.Title = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadata(v **types.OpsMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadata - if *v == nil { - sv = &types.OpsMetadata{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CreationDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreationDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedUser": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedUser = ptr.String(jtv) - } - - case "OpsMetadataArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsMetadataArn to be of type string, got %T instead", value) - } - sv.OpsMetadataArn = ptr.String(jtv) - } - - case "ResourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsMetadataResourceId to be of type string, got %T instead", value) - } - sv.ResourceId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataAlreadyExistsException(v **types.OpsMetadataAlreadyExistsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataAlreadyExistsException - if *v == nil { - sv = &types.OpsMetadataAlreadyExistsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataInvalidArgumentException(v **types.OpsMetadataInvalidArgumentException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataInvalidArgumentException - if *v == nil { - sv = &types.OpsMetadataInvalidArgumentException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataKeyLimitExceededException(v **types.OpsMetadataKeyLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataKeyLimitExceededException - if *v == nil { - sv = &types.OpsMetadataKeyLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataLimitExceededException(v **types.OpsMetadataLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataLimitExceededException - if *v == nil { - sv = &types.OpsMetadataLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataList(v *[]types.OpsMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.OpsMetadata - if *v == nil { - cv = []types.OpsMetadata{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.OpsMetadata - destAddr := &col - if err := awsAwsjson11_deserializeDocumentOpsMetadata(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataNotFoundException(v **types.OpsMetadataNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataNotFoundException - if *v == nil { - sv = &types.OpsMetadataNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOpsMetadataTooManyUpdatesException(v **types.OpsMetadataTooManyUpdatesException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OpsMetadataTooManyUpdatesException - if *v == nil { - sv = &types.OpsMetadataTooManyUpdatesException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentOutputSource(v **types.OutputSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.OutputSource - if *v == nil { - sv = &types.OutputSource{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OutputSourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OutputSourceId to be of type string, got %T instead", value) - } - sv.OutputSourceId = ptr.String(jtv) - } - - case "OutputSourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OutputSourceType to be of type string, got %T instead", value) - } - sv.OutputSourceType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameter(v **types.Parameter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Parameter - if *v == nil { - sv = &types.Parameter{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ARN": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.ARN = ptr.String(jtv) - } - - case "DataType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterDataType to be of type string, got %T instead", value) - } - sv.DataType = ptr.String(jtv) - } - - case "LastModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Selector": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterSelector to be of type string, got %T instead", value) - } - sv.Selector = ptr.String(jtv) - } - - case "SourceResult": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.SourceResult = ptr.String(jtv) - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterType to be of type string, got %T instead", value) - } - sv.Type = types.ParameterType(jtv) - } - - case "Value": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterValue to be of type string, got %T instead", value) - } - sv.Value = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PSParameterVersion to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Version = i64 - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterAlreadyExists(v **types.ParameterAlreadyExists, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterAlreadyExists - if *v == nil { - sv = &types.ParameterAlreadyExists{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterHistory(v **types.ParameterHistory, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterHistory - if *v == nil { - sv = &types.ParameterHistory{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AllowedPattern": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AllowedPattern to be of type string, got %T instead", value) - } - sv.AllowedPattern = ptr.String(jtv) - } - - case "DataType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterDataType to be of type string, got %T instead", value) - } - sv.DataType = ptr.String(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "KeyId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterKeyId to be of type string, got %T instead", value) - } - sv.KeyId = ptr.String(jtv) - } - - case "Labels": - if err := awsAwsjson11_deserializeDocumentParameterLabelList(&sv.Labels, value); err != nil { - return err - } - - case "LastModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedUser": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedUser = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Policies": - if err := awsAwsjson11_deserializeDocumentParameterPolicyList(&sv.Policies, value); err != nil { - return err - } - - case "Tier": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterTier to be of type string, got %T instead", value) - } - sv.Tier = types.ParameterTier(jtv) - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterType to be of type string, got %T instead", value) - } - sv.Type = types.ParameterType(jtv) - } - - case "Value": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterValue to be of type string, got %T instead", value) - } - sv.Value = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PSParameterVersion to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Version = i64 - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterHistoryList(v *[]types.ParameterHistory, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ParameterHistory - if *v == nil { - cv = []types.ParameterHistory{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ParameterHistory - destAddr := &col - if err := awsAwsjson11_deserializeDocumentParameterHistory(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterInlinePolicy(v **types.ParameterInlinePolicy, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterInlinePolicy - if *v == nil { - sv = &types.ParameterInlinePolicy{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "PolicyStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.PolicyStatus = ptr.String(jtv) - } - - case "PolicyText": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.PolicyText = ptr.String(jtv) - } - - case "PolicyType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.PolicyType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterLabelList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterLabel to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterLimitExceeded(v **types.ParameterLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterLimitExceeded - if *v == nil { - sv = &types.ParameterLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterList(v *[]types.Parameter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Parameter - if *v == nil { - cv = []types.Parameter{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Parameter - destAddr := &col - if err := awsAwsjson11_deserializeDocumentParameter(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterMaxVersionLimitExceeded(v **types.ParameterMaxVersionLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterMaxVersionLimitExceeded - if *v == nil { - sv = &types.ParameterMaxVersionLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterMetadata(v **types.ParameterMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterMetadata - if *v == nil { - sv = &types.ParameterMetadata{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AllowedPattern": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AllowedPattern to be of type string, got %T instead", value) - } - sv.AllowedPattern = ptr.String(jtv) - } - - case "DataType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterDataType to be of type string, got %T instead", value) - } - sv.DataType = ptr.String(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "KeyId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterKeyId to be of type string, got %T instead", value) - } - sv.KeyId = ptr.String(jtv) - } - - case "LastModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedUser": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedUser = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Policies": - if err := awsAwsjson11_deserializeDocumentParameterPolicyList(&sv.Policies, value); err != nil { - return err - } - - case "Tier": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterTier to be of type string, got %T instead", value) - } - sv.Tier = types.ParameterTier(jtv) - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterType to be of type string, got %T instead", value) - } - sv.Type = types.ParameterType(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PSParameterVersion to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Version = i64 - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterMetadataList(v *[]types.ParameterMetadata, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ParameterMetadata - if *v == nil { - cv = []types.ParameterMetadata{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ParameterMetadata - destAddr := &col - if err := awsAwsjson11_deserializeDocumentParameterMetadata(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterNameList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PSParameterName to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterNotFound(v **types.ParameterNotFound, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterNotFound - if *v == nil { - sv = &types.ParameterNotFound{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterPatternMismatchException(v **types.ParameterPatternMismatchException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterPatternMismatchException - if *v == nil { - sv = &types.ParameterPatternMismatchException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterPolicyList(v *[]types.ParameterInlinePolicy, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ParameterInlinePolicy - if *v == nil { - cv = []types.ParameterInlinePolicy{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ParameterInlinePolicy - destAddr := &col - if err := awsAwsjson11_deserializeDocumentParameterInlinePolicy(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameters(v *map[string][]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string][]string - if *v == nil { - mv = map[string][]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal []string - mapVar := parsedVal - if err := awsAwsjson11_deserializeDocumentParameterValueList(&mapVar, value); err != nil { - return err - } - parsedVal = mapVar - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterValueList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterVersionLabelLimitExceeded(v **types.ParameterVersionLabelLimitExceeded, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterVersionLabelLimitExceeded - if *v == nil { - sv = &types.ParameterVersionLabelLimitExceeded{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParameterVersionNotFound(v **types.ParameterVersionNotFound, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParameterVersionNotFound - if *v == nil { - sv = &types.ParameterVersionNotFound{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentParentStepDetails(v **types.ParentStepDetails, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ParentStepDetails - if *v == nil { - sv = &types.ParentStepDetails{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Action": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationActionName to be of type string, got %T instead", value) - } - sv.Action = ptr.String(jtv) - } - - case "Iteration": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Iteration = ptr.Int32(int32(i64)) - } - - case "IteratorValue": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.IteratorValue = ptr.String(jtv) - } - - case "StepExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.StepExecutionId = ptr.String(jtv) - } - - case "StepName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.StepName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatch(v **types.Patch, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Patch - if *v == nil { - sv = &types.Patch{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AdvisoryIds": - if err := awsAwsjson11_deserializeDocumentPatchAdvisoryIdList(&sv.AdvisoryIds, value); err != nil { - return err - } - - case "Arch": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchArch to be of type string, got %T instead", value) - } - sv.Arch = ptr.String(jtv) - } - - case "BugzillaIds": - if err := awsAwsjson11_deserializeDocumentPatchBugzillaIdList(&sv.BugzillaIds, value); err != nil { - return err - } - - case "Classification": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchClassification to be of type string, got %T instead", value) - } - sv.Classification = ptr.String(jtv) - } - - case "ContentUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchContentUrl to be of type string, got %T instead", value) - } - sv.ContentUrl = ptr.String(jtv) - } - - case "CVEIds": - if err := awsAwsjson11_deserializeDocumentPatchCVEIdList(&sv.CVEIds, value); err != nil { - return err - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Epoch": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PatchEpoch to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Epoch = int32(i64) - } - - case "Id": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchId to be of type string, got %T instead", value) - } - sv.Id = ptr.String(jtv) - } - - case "KbNumber": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchKbNumber to be of type string, got %T instead", value) - } - sv.KbNumber = ptr.String(jtv) - } - - case "Language": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchLanguage to be of type string, got %T instead", value) - } - sv.Language = ptr.String(jtv) - } - - case "MsrcNumber": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchMsrcNumber to be of type string, got %T instead", value) - } - sv.MsrcNumber = ptr.String(jtv) - } - - case "MsrcSeverity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchMsrcSeverity to be of type string, got %T instead", value) - } - sv.MsrcSeverity = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Product": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchProduct to be of type string, got %T instead", value) - } - sv.Product = ptr.String(jtv) - } - - case "ProductFamily": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchProductFamily to be of type string, got %T instead", value) - } - sv.ProductFamily = ptr.String(jtv) - } - - case "Release": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchRelease to be of type string, got %T instead", value) - } - sv.Release = ptr.String(jtv) - } - - case "ReleaseDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ReleaseDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Repository": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchRepository to be of type string, got %T instead", value) - } - sv.Repository = ptr.String(jtv) - } - - case "Severity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchSeverity to be of type string, got %T instead", value) - } - sv.Severity = ptr.String(jtv) - } - - case "Title": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchTitle to be of type string, got %T instead", value) - } - sv.Title = ptr.String(jtv) - } - - case "Vendor": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchVendor to be of type string, got %T instead", value) - } - sv.Vendor = ptr.String(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchVersion to be of type string, got %T instead", value) - } - sv.Version = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchAdvisoryIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchAdvisoryId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchBaselineIdentity(v **types.PatchBaselineIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchBaselineIdentity - if *v == nil { - sv = &types.PatchBaselineIdentity{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineDescription": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineDescription to be of type string, got %T instead", value) - } - sv.BaselineDescription = ptr.String(jtv) - } - - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "BaselineName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineName to be of type string, got %T instead", value) - } - sv.BaselineName = ptr.String(jtv) - } - - case "DefaultBaseline": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected DefaultBaseline to be of type *bool, got %T instead", value) - } - sv.DefaultBaseline = jtv - } - - case "OperatingSystem": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OperatingSystem to be of type string, got %T instead", value) - } - sv.OperatingSystem = types.OperatingSystem(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchBaselineIdentityList(v *[]types.PatchBaselineIdentity, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchBaselineIdentity - if *v == nil { - cv = []types.PatchBaselineIdentity{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchBaselineIdentity - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchBaselineIdentity(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchBugzillaIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchBugzillaId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchComplianceData(v **types.PatchComplianceData, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchComplianceData - if *v == nil { - sv = &types.PatchComplianceData{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Classification": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchClassification to be of type string, got %T instead", value) - } - sv.Classification = ptr.String(jtv) - } - - case "CVEIds": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchCVEIds to be of type string, got %T instead", value) - } - sv.CVEIds = ptr.String(jtv) - } - - case "InstalledTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.InstalledTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "KBId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchKbNumber to be of type string, got %T instead", value) - } - sv.KBId = ptr.String(jtv) - } - - case "Severity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchSeverity to be of type string, got %T instead", value) - } - sv.Severity = ptr.String(jtv) - } - - case "State": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchComplianceDataState to be of type string, got %T instead", value) - } - sv.State = types.PatchComplianceDataState(jtv) - } - - case "Title": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchTitle to be of type string, got %T instead", value) - } - sv.Title = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchComplianceDataList(v *[]types.PatchComplianceData, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchComplianceData - if *v == nil { - cv = []types.PatchComplianceData{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchComplianceData - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchComplianceData(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchCVEIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchCVEId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchFilter(v **types.PatchFilter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchFilter - if *v == nil { - sv = &types.PatchFilter{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Key": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchFilterKey to be of type string, got %T instead", value) - } - sv.Key = types.PatchFilterKey(jtv) - } - - case "Values": - if err := awsAwsjson11_deserializeDocumentPatchFilterValueList(&sv.Values, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchFilterGroup(v **types.PatchFilterGroup, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchFilterGroup - if *v == nil { - sv = &types.PatchFilterGroup{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "PatchFilters": - if err := awsAwsjson11_deserializeDocumentPatchFilterList(&sv.PatchFilters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchFilterList(v *[]types.PatchFilter, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchFilter - if *v == nil { - cv = []types.PatchFilter{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchFilter - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchFilter(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchFilterValueList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchFilterValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchGroupList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchGroupPatchBaselineMapping(v **types.PatchGroupPatchBaselineMapping, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchGroupPatchBaselineMapping - if *v == nil { - sv = &types.PatchGroupPatchBaselineMapping{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineIdentity": - if err := awsAwsjson11_deserializeDocumentPatchBaselineIdentity(&sv.BaselineIdentity, value); err != nil { - return err - } - - case "PatchGroup": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - sv.PatchGroup = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchGroupPatchBaselineMappingList(v *[]types.PatchGroupPatchBaselineMapping, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchGroupPatchBaselineMapping - if *v == nil { - cv = []types.PatchGroupPatchBaselineMapping{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchGroupPatchBaselineMapping - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchGroupPatchBaselineMapping(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchIdList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchId to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchList(v *[]types.Patch, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Patch - if *v == nil { - cv = []types.Patch{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Patch - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatch(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchPropertiesList(v *[]map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []map[string]string - if *v == nil { - cv = []map[string]string{} - } else { - cv = *v - } - - for _, value := range shape { - var col map[string]string - if err := awsAwsjson11_deserializeDocumentPatchPropertyEntry(&col, value); err != nil { - return err - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchPropertyEntry(v *map[string]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string]string - if *v == nil { - mv = map[string]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AttributeValue to be of type string, got %T instead", value) - } - parsedVal = jtv - } - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchRule(v **types.PatchRule, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchRule - if *v == nil { - sv = &types.PatchRule{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApproveAfterDays": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ApproveAfterDays to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ApproveAfterDays = ptr.Int32(int32(i64)) - } - - case "ApproveUntilDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchStringDateTime to be of type string, got %T instead", value) - } - sv.ApproveUntilDate = ptr.String(jtv) - } - - case "ComplianceLevel": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchComplianceLevel to be of type string, got %T instead", value) - } - sv.ComplianceLevel = types.PatchComplianceLevel(jtv) - } - - case "EnableNonSecurity": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.EnableNonSecurity = ptr.Bool(jtv) - } - - case "PatchFilterGroup": - if err := awsAwsjson11_deserializeDocumentPatchFilterGroup(&sv.PatchFilterGroup, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchRuleGroup(v **types.PatchRuleGroup, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchRuleGroup - if *v == nil { - sv = &types.PatchRuleGroup{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "PatchRules": - if err := awsAwsjson11_deserializeDocumentPatchRuleList(&sv.PatchRules, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchRuleList(v *[]types.PatchRule, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchRule - if *v == nil { - cv = []types.PatchRule{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchRule - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchRule(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchSource(v **types.PatchSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchSource - if *v == nil { - sv = &types.PatchSource{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Configuration": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchSourceConfiguration to be of type string, got %T instead", value) - } - sv.Configuration = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchSourceName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Products": - if err := awsAwsjson11_deserializeDocumentPatchSourceProductList(&sv.Products, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchSourceList(v *[]types.PatchSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PatchSource - if *v == nil { - cv = []types.PatchSource{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PatchSource - destAddr := &col - if err := awsAwsjson11_deserializeDocumentPatchSource(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchSourceProductList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchSourceProduct to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPatchStatus(v **types.PatchStatus, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PatchStatus - if *v == nil { - sv = &types.PatchStatus{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApprovalDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ApprovalDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ComplianceLevel": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchComplianceLevel to be of type string, got %T instead", value) - } - sv.ComplianceLevel = types.PatchComplianceLevel(jtv) - } - - case "DeploymentStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchDeploymentStatus to be of type string, got %T instead", value) - } - sv.DeploymentStatus = types.PatchDeploymentStatus(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentPlatformTypeList(v *[]types.PlatformType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.PlatformType - if *v == nil { - cv = []types.PlatformType{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.PlatformType - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PlatformType to be of type string, got %T instead", value) - } - col = types.PlatformType(jtv) - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentPoliciesLimitExceededException(v **types.PoliciesLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.PoliciesLimitExceededException - if *v == nil { - sv = &types.PoliciesLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentProgressCounters(v **types.ProgressCounters, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ProgressCounters - if *v == nil { - sv = &types.ProgressCounters{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CancelledSteps": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.CancelledSteps = int32(i64) - } - - case "FailedSteps": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.FailedSteps = int32(i64) - } - - case "SuccessSteps": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.SuccessSteps = int32(i64) - } - - case "TimedOutSteps": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TimedOutSteps = int32(i64) - } - - case "TotalSteps": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TotalSteps = int32(i64) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentRegions(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Region to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentRelatedOpsItem(v **types.RelatedOpsItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.RelatedOpsItem - if *v == nil { - sv = &types.RelatedOpsItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentRelatedOpsItems(v *[]types.RelatedOpsItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.RelatedOpsItem - if *v == nil { - cv = []types.RelatedOpsItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.RelatedOpsItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentRelatedOpsItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentResolvedTargets(v **types.ResolvedTargets, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResolvedTargets - if *v == nil { - sv = &types.ResolvedTargets{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ParameterValues": - if err := awsAwsjson11_deserializeDocumentTargetParameterList(&sv.ParameterValues, value); err != nil { - return err - } - - case "Truncated": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.Truncated = jtv - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceComplianceSummaryItem(v **types.ResourceComplianceSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceComplianceSummaryItem - if *v == nil { - sv = &types.ResourceComplianceSummaryItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ComplianceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceTypeName to be of type string, got %T instead", value) - } - sv.ComplianceType = ptr.String(jtv) - } - - case "CompliantSummary": - if err := awsAwsjson11_deserializeDocumentCompliantSummary(&sv.CompliantSummary, value); err != nil { - return err - } - - case "ExecutionSummary": - if err := awsAwsjson11_deserializeDocumentComplianceExecutionSummary(&sv.ExecutionSummary, value); err != nil { - return err - } - - case "NonCompliantSummary": - if err := awsAwsjson11_deserializeDocumentNonCompliantSummary(&sv.NonCompliantSummary, value); err != nil { - return err - } - - case "OverallSeverity": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceSeverity to be of type string, got %T instead", value) - } - sv.OverallSeverity = types.ComplianceSeverity(jtv) - } - - case "ResourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceResourceId to be of type string, got %T instead", value) - } - sv.ResourceId = ptr.String(jtv) - } - - case "ResourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceResourceType to be of type string, got %T instead", value) - } - sv.ResourceType = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ComplianceStatus to be of type string, got %T instead", value) - } - sv.Status = types.ComplianceStatus(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceComplianceSummaryItemList(v *[]types.ResourceComplianceSummaryItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ResourceComplianceSummaryItem - if *v == nil { - cv = []types.ResourceComplianceSummaryItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ResourceComplianceSummaryItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentResourceComplianceSummaryItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncAlreadyExistsException(v **types.ResourceDataSyncAlreadyExistsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncAlreadyExistsException - if *v == nil { - sv = &types.ResourceDataSyncAlreadyExistsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "SyncName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncName to be of type string, got %T instead", value) - } - sv.SyncName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncAwsOrganizationsSource(v **types.ResourceDataSyncAwsOrganizationsSource, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncAwsOrganizationsSource - if *v == nil { - sv = &types.ResourceDataSyncAwsOrganizationsSource{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OrganizationalUnits": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncOrganizationalUnitList(&sv.OrganizationalUnits, value); err != nil { - return err - } - - case "OrganizationSourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncOrganizationSourceType to be of type string, got %T instead", value) - } - sv.OrganizationSourceType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncConflictException(v **types.ResourceDataSyncConflictException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncConflictException - if *v == nil { - sv = &types.ResourceDataSyncConflictException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncCountExceededException(v **types.ResourceDataSyncCountExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncCountExceededException - if *v == nil { - sv = &types.ResourceDataSyncCountExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncDestinationDataSharing(v **types.ResourceDataSyncDestinationDataSharing, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncDestinationDataSharing - if *v == nil { - sv = &types.ResourceDataSyncDestinationDataSharing{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DestinationDataSharingType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncDestinationDataSharingType to be of type string, got %T instead", value) - } - sv.DestinationDataSharingType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncInvalidConfigurationException(v **types.ResourceDataSyncInvalidConfigurationException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncInvalidConfigurationException - if *v == nil { - sv = &types.ResourceDataSyncInvalidConfigurationException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncItem(v **types.ResourceDataSyncItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncItem - if *v == nil { - sv = &types.ResourceDataSyncItem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "LastStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected LastResourceDataSyncStatus to be of type string, got %T instead", value) - } - sv.LastStatus = types.LastResourceDataSyncStatus(jtv) - } - - case "LastSuccessfulSyncTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastSuccessfulSyncTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected LastSuccessfulResourceDataSyncTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastSyncStatusMessage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected LastResourceDataSyncMessage to be of type string, got %T instead", value) - } - sv.LastSyncStatusMessage = ptr.String(jtv) - } - - case "LastSyncTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastSyncTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected LastResourceDataSyncTime to be a JSON Number, got %T instead", value) - - } - } - - case "S3Destination": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncS3Destination(&sv.S3Destination, value); err != nil { - return err - } - - case "SyncCreatedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.SyncCreatedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected ResourceDataSyncCreatedTime to be a JSON Number, got %T instead", value) - - } - } - - case "SyncLastModifiedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.SyncLastModifiedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected ResourceDataSyncLastModifiedTime to be a JSON Number, got %T instead", value) - - } - } - - case "SyncName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncName to be of type string, got %T instead", value) - } - sv.SyncName = ptr.String(jtv) - } - - case "SyncSource": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncSourceWithState(&sv.SyncSource, value); err != nil { - return err - } - - case "SyncType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncType to be of type string, got %T instead", value) - } - sv.SyncType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncItemList(v *[]types.ResourceDataSyncItem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ResourceDataSyncItem - if *v == nil { - cv = []types.ResourceDataSyncItem{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ResourceDataSyncItem - destAddr := &col - if err := awsAwsjson11_deserializeDocumentResourceDataSyncItem(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncNotFoundException(v **types.ResourceDataSyncNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncNotFoundException - if *v == nil { - sv = &types.ResourceDataSyncNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "SyncName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncName to be of type string, got %T instead", value) - } - sv.SyncName = ptr.String(jtv) - } - - case "SyncType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncType to be of type string, got %T instead", value) - } - sv.SyncType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncOrganizationalUnit(v **types.ResourceDataSyncOrganizationalUnit, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncOrganizationalUnit - if *v == nil { - sv = &types.ResourceDataSyncOrganizationalUnit{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OrganizationalUnitId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncOrganizationalUnitId to be of type string, got %T instead", value) - } - sv.OrganizationalUnitId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncOrganizationalUnitList(v *[]types.ResourceDataSyncOrganizationalUnit, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ResourceDataSyncOrganizationalUnit - if *v == nil { - cv = []types.ResourceDataSyncOrganizationalUnit{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ResourceDataSyncOrganizationalUnit - destAddr := &col - if err := awsAwsjson11_deserializeDocumentResourceDataSyncOrganizationalUnit(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncS3Destination(v **types.ResourceDataSyncS3Destination, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncS3Destination - if *v == nil { - sv = &types.ResourceDataSyncS3Destination{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AWSKMSKeyARN": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncAWSKMSKeyARN to be of type string, got %T instead", value) - } - sv.AWSKMSKeyARN = ptr.String(jtv) - } - - case "BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncS3BucketName to be of type string, got %T instead", value) - } - sv.BucketName = ptr.String(jtv) - } - - case "DestinationDataSharing": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncDestinationDataSharing(&sv.DestinationDataSharing, value); err != nil { - return err - } - - case "Prefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncS3Prefix to be of type string, got %T instead", value) - } - sv.Prefix = ptr.String(jtv) - } - - case "Region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncS3Region to be of type string, got %T instead", value) - } - sv.Region = ptr.String(jtv) - } - - case "SyncFormat": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncS3Format to be of type string, got %T instead", value) - } - sv.SyncFormat = types.ResourceDataSyncS3Format(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncSourceRegionList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncSourceRegion to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceDataSyncSourceWithState(v **types.ResourceDataSyncSourceWithState, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceDataSyncSourceWithState - if *v == nil { - sv = &types.ResourceDataSyncSourceWithState{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AwsOrganizationsSource": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncAwsOrganizationsSource(&sv.AwsOrganizationsSource, value); err != nil { - return err - } - - case "EnableAllOpsDataSources": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected ResourceDataSyncEnableAllOpsDataSources to be of type *bool, got %T instead", value) - } - sv.EnableAllOpsDataSources = jtv - } - - case "IncludeFutureRegions": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected ResourceDataSyncIncludeFutureRegions to be of type *bool, got %T instead", value) - } - sv.IncludeFutureRegions = jtv - } - - case "SourceRegions": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncSourceRegionList(&sv.SourceRegions, value); err != nil { - return err - } - - case "SourceType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncSourceType to be of type string, got %T instead", value) - } - sv.SourceType = ptr.String(jtv) - } - - case "State": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ResourceDataSyncState to be of type string, got %T instead", value) - } - sv.State = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceInUseException(v **types.ResourceInUseException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceInUseException - if *v == nil { - sv = &types.ResourceInUseException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourceLimitExceededException(v **types.ResourceLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceLimitExceededException - if *v == nil { - sv = &types.ResourceLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourcePolicyConflictException(v **types.ResourcePolicyConflictException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourcePolicyConflictException - if *v == nil { - sv = &types.ResourcePolicyConflictException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourcePolicyInvalidParameterException(v **types.ResourcePolicyInvalidParameterException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourcePolicyInvalidParameterException - if *v == nil { - sv = &types.ResourcePolicyInvalidParameterException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "ParameterNames": - if err := awsAwsjson11_deserializeDocumentResourcePolicyParameterNamesList(&sv.ParameterNames, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourcePolicyLimitExceededException(v **types.ResourcePolicyLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourcePolicyLimitExceededException - if *v == nil { - sv = &types.ResourcePolicyLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Limit": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Limit = int32(i64) - } - - case "LimitType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LimitType = ptr.String(jtv) - } - - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentResourcePolicyParameterNamesList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentReviewInformation(v **types.ReviewInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ReviewInformation - if *v == nil { - sv = &types.ReviewInformation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ReviewedTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ReviewedTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Reviewer": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Reviewer to be of type string, got %T instead", value) - } - sv.Reviewer = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.Status = types.ReviewStatus(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentReviewInformationList(v *[]types.ReviewInformation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ReviewInformation - if *v == nil { - cv = []types.ReviewInformation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ReviewInformation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentReviewInformation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentRunbook(v **types.Runbook, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Runbook - if *v == nil { - sv = &types.Runbook{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Parameters, value); err != nil { - return err - } - - case "TargetLocations": - if err := awsAwsjson11_deserializeDocumentTargetLocations(&sv.TargetLocations, value); err != nil { - return err - } - - case "TargetMaps": - if err := awsAwsjson11_deserializeDocumentTargetMaps(&sv.TargetMaps, value); err != nil { - return err - } - - case "TargetParameterName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationParameterKey to be of type string, got %T instead", value) - } - sv.TargetParameterName = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentRunbooks(v *[]types.Runbook, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Runbook - if *v == nil { - cv = []types.Runbook{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Runbook - destAddr := &col - if err := awsAwsjson11_deserializeDocumentRunbook(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentS3OutputLocation(v **types.S3OutputLocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.S3OutputLocation - if *v == nil { - sv = &types.S3OutputLocation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OutputS3BucketName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3BucketName to be of type string, got %T instead", value) - } - sv.OutputS3BucketName = ptr.String(jtv) - } - - case "OutputS3KeyPrefix": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3KeyPrefix to be of type string, got %T instead", value) - } - sv.OutputS3KeyPrefix = ptr.String(jtv) - } - - case "OutputS3Region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected S3Region to be of type string, got %T instead", value) - } - sv.OutputS3Region = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentS3OutputUrl(v **types.S3OutputUrl, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.S3OutputUrl - if *v == nil { - sv = &types.S3OutputUrl{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.OutputUrl = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentScheduledWindowExecution(v **types.ScheduledWindowExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ScheduledWindowExecution - if *v == nil { - sv = &types.ScheduledWindowExecution{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ExecutionTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.ExecutionTime = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentScheduledWindowExecutionList(v *[]types.ScheduledWindowExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.ScheduledWindowExecution - if *v == nil { - cv = []types.ScheduledWindowExecution{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.ScheduledWindowExecution - destAddr := &col - if err := awsAwsjson11_deserializeDocumentScheduledWindowExecution(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentServiceSetting(v **types.ServiceSetting, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ServiceSetting - if *v == nil { - sv = &types.ServiceSetting{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ARN": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.ARN = ptr.String(jtv) - } - - case "LastModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.LastModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "LastModifiedUser": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.LastModifiedUser = ptr.String(jtv) - } - - case "SettingId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceSettingId to be of type string, got %T instead", value) - } - sv.SettingId = ptr.String(jtv) - } - - case "SettingValue": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceSettingValue to be of type string, got %T instead", value) - } - sv.SettingValue = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Status = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentServiceSettingNotFound(v **types.ServiceSettingNotFound, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ServiceSettingNotFound - if *v == nil { - sv = &types.ServiceSettingNotFound{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentSession(v **types.Session, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Session - if *v == nil { - sv = &types.Session{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Details": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionDetails to be of type string, got %T instead", value) - } - sv.Details = ptr.String(jtv) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "EndDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "MaxSessionDuration": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxSessionDuration to be of type string, got %T instead", value) - } - sv.MaxSessionDuration = ptr.String(jtv) - } - - case "OutputUrl": - if err := awsAwsjson11_deserializeDocumentSessionManagerOutputUrl(&sv.OutputUrl, value); err != nil { - return err - } - - case "Owner": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionOwner to be of type string, got %T instead", value) - } - sv.Owner = ptr.String(jtv) - } - - case "Reason": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionReason to be of type string, got %T instead", value) - } - sv.Reason = ptr.String(jtv) - } - - case "SessionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionId to be of type string, got %T instead", value) - } - sv.SessionId = ptr.String(jtv) - } - - case "StartDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionStatus to be of type string, got %T instead", value) - } - sv.Status = types.SessionStatus(jtv) - } - - case "Target": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionTarget to be of type string, got %T instead", value) - } - sv.Target = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentSessionList(v *[]types.Session, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Session - if *v == nil { - cv = []types.Session{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Session - destAddr := &col - if err := awsAwsjson11_deserializeDocumentSession(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentSessionManagerOutputUrl(v **types.SessionManagerOutputUrl, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.SessionManagerOutputUrl - if *v == nil { - sv = &types.SessionManagerOutputUrl{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CloudWatchOutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionManagerCloudWatchOutputUrl to be of type string, got %T instead", value) - } - sv.CloudWatchOutputUrl = ptr.String(jtv) - } - - case "S3OutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionManagerS3OutputUrl to be of type string, got %T instead", value) - } - sv.S3OutputUrl = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentSeveritySummary(v **types.SeveritySummary, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.SeveritySummary - if *v == nil { - sv = &types.SeveritySummary{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CriticalCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.CriticalCount = int32(i64) - } - - case "HighCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.HighCount = int32(i64) - } - - case "InformationalCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InformationalCount = int32(i64) - } - - case "LowCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.LowCount = int32(i64) - } - - case "MediumCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.MediumCount = int32(i64) - } - - case "UnspecifiedCount": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ComplianceSummaryCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.UnspecifiedCount = int32(i64) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentStatusUnchanged(v **types.StatusUnchanged, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.StatusUnchanged - if *v == nil { - sv = &types.StatusUnchanged{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentStepExecution(v **types.StepExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.StepExecution - if *v == nil { - sv = &types.StepExecution{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Action": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationActionName to be of type string, got %T instead", value) - } - sv.Action = ptr.String(jtv) - } - - case "ExecutionEndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionEndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionStartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ExecutionStartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "FailureDetails": - if err := awsAwsjson11_deserializeDocumentFailureDetails(&sv.FailureDetails, value); err != nil { - return err - } - - case "FailureMessage": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.FailureMessage = ptr.String(jtv) - } - - case "Inputs": - if err := awsAwsjson11_deserializeDocumentNormalStringMap(&sv.Inputs, value); err != nil { - return err - } - - case "IsCritical": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.IsCritical = ptr.Bool(jtv) - } - - case "IsEnd": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.IsEnd = ptr.Bool(jtv) - } - - case "MaxAttempts": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.MaxAttempts = ptr.Int32(int32(i64)) - } - - case "NextStep": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.NextStep = ptr.String(jtv) - } - - case "OnFailure": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OnFailure = ptr.String(jtv) - } - - case "Outputs": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.Outputs, value); err != nil { - return err - } - - case "OverriddenParameters": - if err := awsAwsjson11_deserializeDocumentAutomationParameterMap(&sv.OverriddenParameters, value); err != nil { - return err - } - - case "ParentStepDetails": - if err := awsAwsjson11_deserializeDocumentParentStepDetails(&sv.ParentStepDetails, value); err != nil { - return err - } - - case "Response": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Response = ptr.String(jtv) - } - - case "ResponseCode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.ResponseCode = ptr.String(jtv) - } - - case "StepExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.StepExecutionId = ptr.String(jtv) - } - - case "StepName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.StepName = ptr.String(jtv) - } - - case "StepStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionStatus to be of type string, got %T instead", value) - } - sv.StepStatus = types.AutomationExecutionStatus(jtv) - } - - case "TargetLocation": - if err := awsAwsjson11_deserializeDocumentTargetLocation(&sv.TargetLocation, value); err != nil { - return err - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TimeoutSeconds": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Long to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.TimeoutSeconds = ptr.Int64(i64) - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - case "ValidNextSteps": - if err := awsAwsjson11_deserializeDocumentValidNextStepList(&sv.ValidNextSteps, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentStepExecutionList(v *[]types.StepExecution, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.StepExecution - if *v == nil { - cv = []types.StepExecution{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.StepExecution - destAddr := &col - if err := awsAwsjson11_deserializeDocumentStepExecution(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentSubTypeCountLimitExceededException(v **types.SubTypeCountLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.SubTypeCountLimitExceededException - if *v == nil { - sv = &types.SubTypeCountLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTag(v **types.Tag, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Tag - if *v == nil { - sv = &types.Tag{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Key": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TagKey to be of type string, got %T instead", value) - } - sv.Key = ptr.String(jtv) - } - - case "Value": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TagValue to be of type string, got %T instead", value) - } - sv.Value = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTagList(v *[]types.Tag, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Tag - if *v == nil { - cv = []types.Tag{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Tag - destAddr := &col - if err := awsAwsjson11_deserializeDocumentTag(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTarget(v **types.Target, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.Target - if *v == nil { - sv = &types.Target{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Key": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TargetKey to be of type string, got %T instead", value) - } - sv.Key = ptr.String(jtv) - } - - case "Values": - if err := awsAwsjson11_deserializeDocumentTargetValues(&sv.Values, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetInUseException(v **types.TargetInUseException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TargetInUseException - if *v == nil { - sv = &types.TargetInUseException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetLocation(v **types.TargetLocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TargetLocation - if *v == nil { - sv = &types.TargetLocation{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Accounts": - if err := awsAwsjson11_deserializeDocumentAccounts(&sv.Accounts, value); err != nil { - return err - } - - case "ExecutionRoleName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ExecutionRoleName to be of type string, got %T instead", value) - } - sv.ExecutionRoleName = ptr.String(jtv) - } - - case "Regions": - if err := awsAwsjson11_deserializeDocumentRegions(&sv.Regions, value); err != nil { - return err - } - - case "TargetLocationAlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.TargetLocationAlarmConfiguration, value); err != nil { - return err - } - - case "TargetLocationMaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.TargetLocationMaxConcurrency = ptr.String(jtv) - } - - case "TargetLocationMaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.TargetLocationMaxErrors = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetLocations(v *[]types.TargetLocation, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.TargetLocation - if *v == nil { - cv = []types.TargetLocation{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.TargetLocation - destAddr := &col - if err := awsAwsjson11_deserializeDocumentTargetLocation(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetMap(v *map[string][]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var mv map[string][]string - if *v == nil { - mv = map[string][]string{} - } else { - mv = *v - } - - for key, value := range shape { - var parsedVal []string - mapVar := parsedVal - if err := awsAwsjson11_deserializeDocumentTargetMapValueList(&mapVar, value); err != nil { - return err - } - parsedVal = mapVar - mv[key] = parsedVal - - } - *v = mv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetMaps(v *[]map[string][]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []map[string][]string - if *v == nil { - cv = []map[string][]string{} - } else { - cv = *v - } - - for _, value := range shape { - var col map[string][]string - if err := awsAwsjson11_deserializeDocumentTargetMap(&col, value); err != nil { - return err - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetMapValueList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TargetMapValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetNotConnected(v **types.TargetNotConnected, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TargetNotConnected - if *v == nil { - sv = &types.TargetNotConnected{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetParameterList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTargets(v *[]types.Target, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.Target - if *v == nil { - cv = []types.Target{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.Target - destAddr := &col - if err := awsAwsjson11_deserializeDocumentTarget(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTargetValues(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TargetValue to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeDocumentTooManyTagsError(v **types.TooManyTagsError, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TooManyTagsError - if *v == nil { - sv = &types.TooManyTagsError{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTooManyUpdates(v **types.TooManyUpdates, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TooManyUpdates - if *v == nil { - sv = &types.TooManyUpdates{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentTotalSizeLimitExceededException(v **types.TotalSizeLimitExceededException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TotalSizeLimitExceededException - if *v == nil { - sv = &types.TotalSizeLimitExceededException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedCalendarException(v **types.UnsupportedCalendarException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedCalendarException - if *v == nil { - sv = &types.UnsupportedCalendarException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedFeatureRequiredException(v **types.UnsupportedFeatureRequiredException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedFeatureRequiredException - if *v == nil { - sv = &types.UnsupportedFeatureRequiredException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedInventoryItemContextException(v **types.UnsupportedInventoryItemContextException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedInventoryItemContextException - if *v == nil { - sv = &types.UnsupportedInventoryItemContextException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedInventorySchemaVersionException(v **types.UnsupportedInventorySchemaVersionException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedInventorySchemaVersionException - if *v == nil { - sv = &types.UnsupportedInventorySchemaVersionException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedOperatingSystem(v **types.UnsupportedOperatingSystem, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedOperatingSystem - if *v == nil { - sv = &types.UnsupportedOperatingSystem{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedParameterType(v **types.UnsupportedParameterType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedParameterType - if *v == nil { - sv = &types.UnsupportedParameterType{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentUnsupportedPlatformType(v **types.UnsupportedPlatformType, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedPlatformType - if *v == nil { - sv = &types.UnsupportedPlatformType{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeDocumentValidNextStepList(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ValidNextStep to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsAwsjson11_deserializeOpDocumentAddTagsToResourceOutput(v **AddTagsToResourceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *AddTagsToResourceOutput - if *v == nil { - sv = &AddTagsToResourceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentAssociateOpsItemRelatedItemOutput(v **AssociateOpsItemRelatedItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *AssociateOpsItemRelatedItemOutput - if *v == nil { - sv = &AssociateOpsItemRelatedItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemRelatedItemAssociationId to be of type string, got %T instead", value) - } - sv.AssociationId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCancelCommandOutput(v **CancelCommandOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CancelCommandOutput - if *v == nil { - sv = &CancelCommandOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCancelMaintenanceWindowExecutionOutput(v **CancelMaintenanceWindowExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CancelMaintenanceWindowExecutionOutput - if *v == nil { - sv = &CancelMaintenanceWindowExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateActivationOutput(v **CreateActivationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateActivationOutput - if *v == nil { - sv = &CreateActivationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActivationCode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ActivationCode to be of type string, got %T instead", value) - } - sv.ActivationCode = ptr.String(jtv) - } - - case "ActivationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ActivationId to be of type string, got %T instead", value) - } - sv.ActivationId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateAssociationBatchOutput(v **CreateAssociationBatchOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateAssociationBatchOutput - if *v == nil { - sv = &CreateAssociationBatchOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Failed": - if err := awsAwsjson11_deserializeDocumentFailedCreateAssociationList(&sv.Failed, value); err != nil { - return err - } - - case "Successful": - if err := awsAwsjson11_deserializeDocumentAssociationDescriptionList(&sv.Successful, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateAssociationOutput(v **CreateAssociationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateAssociationOutput - if *v == nil { - sv = &CreateAssociationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationDescription": - if err := awsAwsjson11_deserializeDocumentAssociationDescription(&sv.AssociationDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateDocumentOutput(v **CreateDocumentOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateDocumentOutput - if *v == nil { - sv = &CreateDocumentOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentDescription": - if err := awsAwsjson11_deserializeDocumentDocumentDescription(&sv.DocumentDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateMaintenanceWindowOutput(v **CreateMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateMaintenanceWindowOutput - if *v == nil { - sv = &CreateMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateOpsItemOutput(v **CreateOpsItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateOpsItemOutput - if *v == nil { - sv = &CreateOpsItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OpsItemArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsItemArn to be of type string, got %T instead", value) - } - sv.OpsItemArn = ptr.String(jtv) - } - - case "OpsItemId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.OpsItemId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateOpsMetadataOutput(v **CreateOpsMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateOpsMetadataOutput - if *v == nil { - sv = &CreateOpsMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OpsMetadataArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsMetadataArn to be of type string, got %T instead", value) - } - sv.OpsMetadataArn = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreatePatchBaselineOutput(v **CreatePatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreatePatchBaselineOutput - if *v == nil { - sv = &CreatePatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentCreateResourceDataSyncOutput(v **CreateResourceDataSyncOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateResourceDataSyncOutput - if *v == nil { - sv = &CreateResourceDataSyncOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteActivationOutput(v **DeleteActivationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteActivationOutput - if *v == nil { - sv = &DeleteActivationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteAssociationOutput(v **DeleteAssociationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteAssociationOutput - if *v == nil { - sv = &DeleteAssociationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteDocumentOutput(v **DeleteDocumentOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteDocumentOutput - if *v == nil { - sv = &DeleteDocumentOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteInventoryOutput(v **DeleteInventoryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteInventoryOutput - if *v == nil { - sv = &DeleteInventoryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DeletionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected UUID to be of type string, got %T instead", value) - } - sv.DeletionId = ptr.String(jtv) - } - - case "DeletionSummary": - if err := awsAwsjson11_deserializeDocumentInventoryDeletionSummary(&sv.DeletionSummary, value); err != nil { - return err - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteMaintenanceWindowOutput(v **DeleteMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteMaintenanceWindowOutput - if *v == nil { - sv = &DeleteMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteOpsItemOutput(v **DeleteOpsItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteOpsItemOutput - if *v == nil { - sv = &DeleteOpsItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteOpsMetadataOutput(v **DeleteOpsMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteOpsMetadataOutput - if *v == nil { - sv = &DeleteOpsMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteParameterOutput(v **DeleteParameterOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteParameterOutput - if *v == nil { - sv = &DeleteParameterOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteParametersOutput(v **DeleteParametersOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteParametersOutput - if *v == nil { - sv = &DeleteParametersOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DeletedParameters": - if err := awsAwsjson11_deserializeDocumentParameterNameList(&sv.DeletedParameters, value); err != nil { - return err - } - - case "InvalidParameters": - if err := awsAwsjson11_deserializeDocumentParameterNameList(&sv.InvalidParameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeletePatchBaselineOutput(v **DeletePatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeletePatchBaselineOutput - if *v == nil { - sv = &DeletePatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteResourceDataSyncOutput(v **DeleteResourceDataSyncOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteResourceDataSyncOutput - if *v == nil { - sv = &DeleteResourceDataSyncOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeleteResourcePolicyOutput(v **DeleteResourcePolicyOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeleteResourcePolicyOutput - if *v == nil { - sv = &DeleteResourcePolicyOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeregisterManagedInstanceOutput(v **DeregisterManagedInstanceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeregisterManagedInstanceOutput - if *v == nil { - sv = &DeregisterManagedInstanceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeregisterPatchBaselineForPatchGroupOutput(v **DeregisterPatchBaselineForPatchGroupOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeregisterPatchBaselineForPatchGroupOutput - if *v == nil { - sv = &DeregisterPatchBaselineForPatchGroupOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "PatchGroup": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - sv.PatchGroup = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeregisterTargetFromMaintenanceWindowOutput(v **DeregisterTargetFromMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeregisterTargetFromMaintenanceWindowOutput - if *v == nil { - sv = &DeregisterTargetFromMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDeregisterTaskFromMaintenanceWindowOutput(v **DeregisterTaskFromMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DeregisterTaskFromMaintenanceWindowOutput - if *v == nil { - sv = &DeregisterTaskFromMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTaskId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskId to be of type string, got %T instead", value) - } - sv.WindowTaskId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeActivationsOutput(v **DescribeActivationsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeActivationsOutput - if *v == nil { - sv = &DescribeActivationsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ActivationList": - if err := awsAwsjson11_deserializeDocumentActivationList(&sv.ActivationList, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAssociationExecutionsOutput(v **DescribeAssociationExecutionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAssociationExecutionsOutput - if *v == nil { - sv = &DescribeAssociationExecutionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationExecutions": - if err := awsAwsjson11_deserializeDocumentAssociationExecutionsList(&sv.AssociationExecutions, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAssociationExecutionTargetsOutput(v **DescribeAssociationExecutionTargetsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAssociationExecutionTargetsOutput - if *v == nil { - sv = &DescribeAssociationExecutionTargetsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationExecutionTargets": - if err := awsAwsjson11_deserializeDocumentAssociationExecutionTargetsList(&sv.AssociationExecutionTargets, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAssociationOutput(v **DescribeAssociationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAssociationOutput - if *v == nil { - sv = &DescribeAssociationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationDescription": - if err := awsAwsjson11_deserializeDocumentAssociationDescription(&sv.AssociationDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAutomationExecutionsOutput(v **DescribeAutomationExecutionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAutomationExecutionsOutput - if *v == nil { - sv = &DescribeAutomationExecutionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AutomationExecutionMetadataList": - if err := awsAwsjson11_deserializeDocumentAutomationExecutionMetadataList(&sv.AutomationExecutionMetadataList, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAutomationStepExecutionsOutput(v **DescribeAutomationStepExecutionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAutomationStepExecutionsOutput - if *v == nil { - sv = &DescribeAutomationStepExecutionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "StepExecutions": - if err := awsAwsjson11_deserializeDocumentStepExecutionList(&sv.StepExecutions, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeAvailablePatchesOutput(v **DescribeAvailablePatchesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeAvailablePatchesOutput - if *v == nil { - sv = &DescribeAvailablePatchesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Patches": - if err := awsAwsjson11_deserializeDocumentPatchList(&sv.Patches, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeDocumentOutput(v **DescribeDocumentOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeDocumentOutput - if *v == nil { - sv = &DescribeDocumentOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Document": - if err := awsAwsjson11_deserializeDocumentDocumentDescription(&sv.Document, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeDocumentPermissionOutput(v **DescribeDocumentPermissionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeDocumentPermissionOutput - if *v == nil { - sv = &DescribeDocumentPermissionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AccountIds": - if err := awsAwsjson11_deserializeDocumentAccountIdList(&sv.AccountIds, value); err != nil { - return err - } - - case "AccountSharingInfoList": - if err := awsAwsjson11_deserializeDocumentAccountSharingInfoList(&sv.AccountSharingInfoList, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeEffectiveInstanceAssociationsOutput(v **DescribeEffectiveInstanceAssociationsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeEffectiveInstanceAssociationsOutput - if *v == nil { - sv = &DescribeEffectiveInstanceAssociationsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Associations": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationList(&sv.Associations, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeEffectivePatchesForPatchBaselineOutput(v **DescribeEffectivePatchesForPatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeEffectivePatchesForPatchBaselineOutput - if *v == nil { - sv = &DescribeEffectivePatchesForPatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "EffectivePatches": - if err := awsAwsjson11_deserializeDocumentEffectivePatchList(&sv.EffectivePatches, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInstanceAssociationsStatusOutput(v **DescribeInstanceAssociationsStatusOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInstanceAssociationsStatusOutput - if *v == nil { - sv = &DescribeInstanceAssociationsStatusOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InstanceAssociationStatusInfos": - if err := awsAwsjson11_deserializeDocumentInstanceAssociationStatusInfos(&sv.InstanceAssociationStatusInfos, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInstanceInformationOutput(v **DescribeInstanceInformationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInstanceInformationOutput - if *v == nil { - sv = &DescribeInstanceInformationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InstanceInformationList": - if err := awsAwsjson11_deserializeDocumentInstanceInformationList(&sv.InstanceInformationList, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInstancePatchesOutput(v **DescribeInstancePatchesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInstancePatchesOutput - if *v == nil { - sv = &DescribeInstancePatchesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Patches": - if err := awsAwsjson11_deserializeDocumentPatchComplianceDataList(&sv.Patches, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInstancePatchStatesForPatchGroupOutput(v **DescribeInstancePatchStatesForPatchGroupOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInstancePatchStatesForPatchGroupOutput - if *v == nil { - sv = &DescribeInstancePatchStatesForPatchGroupOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InstancePatchStates": - if err := awsAwsjson11_deserializeDocumentInstancePatchStatesList(&sv.InstancePatchStates, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInstancePatchStatesOutput(v **DescribeInstancePatchStatesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInstancePatchStatesOutput - if *v == nil { - sv = &DescribeInstancePatchStatesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InstancePatchStates": - if err := awsAwsjson11_deserializeDocumentInstancePatchStateList(&sv.InstancePatchStates, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeInventoryDeletionsOutput(v **DescribeInventoryDeletionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeInventoryDeletionsOutput - if *v == nil { - sv = &DescribeInventoryDeletionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InventoryDeletions": - if err := awsAwsjson11_deserializeDocumentInventoryDeletionsList(&sv.InventoryDeletions, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionsOutput(v **DescribeMaintenanceWindowExecutionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowExecutionsOutput - if *v == nil { - sv = &DescribeMaintenanceWindowExecutionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "WindowExecutions": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionList(&sv.WindowExecutions, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionTaskInvocationsOutput(v **DescribeMaintenanceWindowExecutionTaskInvocationsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowExecutionTaskInvocationsOutput - if *v == nil { - sv = &DescribeMaintenanceWindowExecutionTaskInvocationsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "WindowExecutionTaskInvocationIdentities": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskInvocationIdentityList(&sv.WindowExecutionTaskInvocationIdentities, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowExecutionTasksOutput(v **DescribeMaintenanceWindowExecutionTasksOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowExecutionTasksOutput - if *v == nil { - sv = &DescribeMaintenanceWindowExecutionTasksOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "WindowExecutionTaskIdentities": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdentityList(&sv.WindowExecutionTaskIdentities, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowScheduleOutput(v **DescribeMaintenanceWindowScheduleOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowScheduleOutput - if *v == nil { - sv = &DescribeMaintenanceWindowScheduleOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "ScheduledWindowExecutions": - if err := awsAwsjson11_deserializeDocumentScheduledWindowExecutionList(&sv.ScheduledWindowExecutions, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowsForTargetOutput(v **DescribeMaintenanceWindowsForTargetOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowsForTargetOutput - if *v == nil { - sv = &DescribeMaintenanceWindowsForTargetOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "WindowIdentities": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowsForTargetList(&sv.WindowIdentities, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowsOutput(v **DescribeMaintenanceWindowsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowsOutput - if *v == nil { - sv = &DescribeMaintenanceWindowsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "WindowIdentities": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowIdentityList(&sv.WindowIdentities, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowTargetsOutput(v **DescribeMaintenanceWindowTargetsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowTargetsOutput - if *v == nil { - sv = &DescribeMaintenanceWindowTargetsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTargetList(&sv.Targets, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeMaintenanceWindowTasksOutput(v **DescribeMaintenanceWindowTasksOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeMaintenanceWindowTasksOutput - if *v == nil { - sv = &DescribeMaintenanceWindowTasksOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Tasks": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskList(&sv.Tasks, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeOpsItemsOutput(v **DescribeOpsItemsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeOpsItemsOutput - if *v == nil { - sv = &DescribeOpsItemsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "OpsItemSummaries": - if err := awsAwsjson11_deserializeDocumentOpsItemSummaries(&sv.OpsItemSummaries, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeParametersOutput(v **DescribeParametersOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeParametersOutput - if *v == nil { - sv = &DescribeParametersOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameterMetadataList(&sv.Parameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribePatchBaselinesOutput(v **DescribePatchBaselinesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribePatchBaselinesOutput - if *v == nil { - sv = &DescribePatchBaselinesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineIdentities": - if err := awsAwsjson11_deserializeDocumentPatchBaselineIdentityList(&sv.BaselineIdentities, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribePatchGroupsOutput(v **DescribePatchGroupsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribePatchGroupsOutput - if *v == nil { - sv = &DescribePatchGroupsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Mappings": - if err := awsAwsjson11_deserializeDocumentPatchGroupPatchBaselineMappingList(&sv.Mappings, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribePatchGroupStateOutput(v **DescribePatchGroupStateOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribePatchGroupStateOutput - if *v == nil { - sv = &DescribePatchGroupStateOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Instances": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Instances = int32(i64) - } - - case "InstancesWithCriticalNonCompliantPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstancesCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithCriticalNonCompliantPatches = ptr.Int32(int32(i64)) - } - - case "InstancesWithFailedPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithFailedPatches = int32(i64) - } - - case "InstancesWithInstalledOtherPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithInstalledOtherPatches = int32(i64) - } - - case "InstancesWithInstalledPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithInstalledPatches = int32(i64) - } - - case "InstancesWithInstalledPendingRebootPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstancesCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithInstalledPendingRebootPatches = ptr.Int32(int32(i64)) - } - - case "InstancesWithInstalledRejectedPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstancesCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithInstalledRejectedPatches = ptr.Int32(int32(i64)) - } - - case "InstancesWithMissingPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithMissingPatches = int32(i64) - } - - case "InstancesWithNotApplicablePatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithNotApplicablePatches = int32(i64) - } - - case "InstancesWithOtherNonCompliantPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstancesCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithOtherNonCompliantPatches = ptr.Int32(int32(i64)) - } - - case "InstancesWithSecurityNonCompliantPatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected InstancesCount to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithSecurityNonCompliantPatches = ptr.Int32(int32(i64)) - } - - case "InstancesWithUnreportedNotApplicablePatches": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected Integer to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.InstancesWithUnreportedNotApplicablePatches = ptr.Int32(int32(i64)) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribePatchPropertiesOutput(v **DescribePatchPropertiesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribePatchPropertiesOutput - if *v == nil { - sv = &DescribePatchPropertiesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Properties": - if err := awsAwsjson11_deserializeDocumentPatchPropertiesList(&sv.Properties, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDescribeSessionsOutput(v **DescribeSessionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DescribeSessionsOutput - if *v == nil { - sv = &DescribeSessionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Sessions": - if err := awsAwsjson11_deserializeDocumentSessionList(&sv.Sessions, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentDisassociateOpsItemRelatedItemOutput(v **DisassociateOpsItemRelatedItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *DisassociateOpsItemRelatedItemOutput - if *v == nil { - sv = &DisassociateOpsItemRelatedItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetAutomationExecutionOutput(v **GetAutomationExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetAutomationExecutionOutput - if *v == nil { - sv = &GetAutomationExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AutomationExecution": - if err := awsAwsjson11_deserializeDocumentAutomationExecution(&sv.AutomationExecution, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetCalendarStateOutput(v **GetCalendarStateOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetCalendarStateOutput - if *v == nil { - sv = &GetCalendarStateOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AtTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ISO8601String to be of type string, got %T instead", value) - } - sv.AtTime = ptr.String(jtv) - } - - case "NextTransitionTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ISO8601String to be of type string, got %T instead", value) - } - sv.NextTransitionTime = ptr.String(jtv) - } - - case "State": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CalendarState to be of type string, got %T instead", value) - } - sv.State = types.CalendarState(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetCommandInvocationOutput(v **GetCommandInvocationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetCommandInvocationOutput - if *v == nil { - sv = &GetCommandInvocationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CloudWatchOutputConfig": - if err := awsAwsjson11_deserializeDocumentCloudWatchOutputConfig(&sv.CloudWatchOutputConfig, value); err != nil { - return err - } - - case "CommandId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandId to be of type string, got %T instead", value) - } - sv.CommandId = ptr.String(jtv) - } - - case "Comment": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Comment to be of type string, got %T instead", value) - } - sv.Comment = ptr.String(jtv) - } - - case "DocumentName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.DocumentName = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "ExecutionElapsedTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StringDateTime to be of type string, got %T instead", value) - } - sv.ExecutionElapsedTime = ptr.String(jtv) - } - - case "ExecutionEndDateTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StringDateTime to be of type string, got %T instead", value) - } - sv.ExecutionEndDateTime = ptr.String(jtv) - } - - case "ExecutionStartDateTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StringDateTime to be of type string, got %T instead", value) - } - sv.ExecutionStartDateTime = ptr.String(jtv) - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "PluginName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandPluginName to be of type string, got %T instead", value) - } - sv.PluginName = ptr.String(jtv) - } - - case "ResponseCode": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ResponseCode to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ResponseCode = int32(i64) - } - - case "StandardErrorContent": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StandardErrorContent to be of type string, got %T instead", value) - } - sv.StandardErrorContent = ptr.String(jtv) - } - - case "StandardErrorUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardErrorUrl = ptr.String(jtv) - } - - case "StandardOutputContent": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StandardOutputContent to be of type string, got %T instead", value) - } - sv.StandardOutputContent = ptr.String(jtv) - } - - case "StandardOutputUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Url to be of type string, got %T instead", value) - } - sv.StandardOutputUrl = ptr.String(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected CommandInvocationStatus to be of type string, got %T instead", value) - } - sv.Status = types.CommandInvocationStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetConnectionStatusOutput(v **GetConnectionStatusOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetConnectionStatusOutput - if *v == nil { - sv = &GetConnectionStatusOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ConnectionStatus to be of type string, got %T instead", value) - } - sv.Status = types.ConnectionStatus(jtv) - } - - case "Target": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionTarget to be of type string, got %T instead", value) - } - sv.Target = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetDefaultPatchBaselineOutput(v **GetDefaultPatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetDefaultPatchBaselineOutput - if *v == nil { - sv = &GetDefaultPatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "OperatingSystem": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OperatingSystem to be of type string, got %T instead", value) - } - sv.OperatingSystem = types.OperatingSystem(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetDeployablePatchSnapshotForInstanceOutput(v **GetDeployablePatchSnapshotForInstanceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetDeployablePatchSnapshotForInstanceOutput - if *v == nil { - sv = &GetDeployablePatchSnapshotForInstanceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "Product": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Product to be of type string, got %T instead", value) - } - sv.Product = ptr.String(jtv) - } - - case "SnapshotDownloadUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SnapshotDownloadUrl to be of type string, got %T instead", value) - } - sv.SnapshotDownloadUrl = ptr.String(jtv) - } - - case "SnapshotId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SnapshotId to be of type string, got %T instead", value) - } - sv.SnapshotId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetDocumentOutput(v **GetDocumentOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetDocumentOutput - if *v == nil { - sv = &GetDocumentOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AttachmentsContent": - if err := awsAwsjson11_deserializeDocumentAttachmentContentList(&sv.AttachmentsContent, value); err != nil { - return err - } - - case "Content": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentContent to be of type string, got %T instead", value) - } - sv.Content = ptr.String(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "DisplayName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentDisplayName to be of type string, got %T instead", value) - } - sv.DisplayName = ptr.String(jtv) - } - - case "DocumentFormat": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentFormat to be of type string, got %T instead", value) - } - sv.DocumentFormat = types.DocumentFormat(jtv) - } - - case "DocumentType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentType to be of type string, got %T instead", value) - } - sv.DocumentType = types.DocumentType(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentARN to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Requires": - if err := awsAwsjson11_deserializeDocumentDocumentRequiresList(&sv.Requires, value); err != nil { - return err - } - - case "ReviewStatus": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ReviewStatus to be of type string, got %T instead", value) - } - sv.ReviewStatus = types.ReviewStatus(jtv) - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatus to be of type string, got %T instead", value) - } - sv.Status = types.DocumentStatus(jtv) - } - - case "StatusInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentStatusInformation to be of type string, got %T instead", value) - } - sv.StatusInformation = ptr.String(jtv) - } - - case "VersionName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersionName to be of type string, got %T instead", value) - } - sv.VersionName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetInventoryOutput(v **GetInventoryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetInventoryOutput - if *v == nil { - sv = &GetInventoryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Entities": - if err := awsAwsjson11_deserializeDocumentInventoryResultEntityList(&sv.Entities, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetInventorySchemaOutput(v **GetInventorySchemaOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetInventorySchemaOutput - if *v == nil { - sv = &GetInventorySchemaOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Schemas": - if err := awsAwsjson11_deserializeDocumentInventoryItemSchemaResultList(&sv.Schemas, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionOutput(v **GetMaintenanceWindowExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetMaintenanceWindowExecutionOutput - if *v == nil { - sv = &GetMaintenanceWindowExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TaskIds": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowExecutionTaskIdList(&sv.TaskIds, value); err != nil { - return err - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionTaskInvocationOutput(v **GetMaintenanceWindowExecutionTaskInvocationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetMaintenanceWindowExecutionTaskInvocationOutput - if *v == nil { - sv = &GetMaintenanceWindowExecutionTaskInvocationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "ExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskExecutionId to be of type string, got %T instead", value) - } - sv.ExecutionId = ptr.String(jtv) - } - - case "InvocationId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskInvocationId to be of type string, got %T instead", value) - } - sv.InvocationId = ptr.String(jtv) - } - - case "OwnerInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OwnerInformation to be of type string, got %T instead", value) - } - sv.OwnerInformation = ptr.String(jtv) - } - - case "Parameters": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskInvocationParameters to be of type string, got %T instead", value) - } - sv.Parameters = ptr.String(jtv) - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TaskExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskId to be of type string, got %T instead", value) - } - sv.TaskExecutionId = ptr.String(jtv) - } - - case "TaskType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.TaskType = types.MaintenanceWindowTaskType(jtv) - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowExecutionTaskOutput(v **GetMaintenanceWindowExecutionTaskOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetMaintenanceWindowExecutionTaskOutput - if *v == nil { - sv = &GetMaintenanceWindowExecutionTaskOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "EndTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.EndTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = int32(i64) - } - - case "ServiceRole": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRole = ptr.String(jtv) - } - - case "StartTime": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.StartTime = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Status": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatus to be of type string, got %T instead", value) - } - sv.Status = types.MaintenanceWindowExecutionStatus(jtv) - } - - case "StatusDetails": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionStatusDetails to be of type string, got %T instead", value) - } - sv.StatusDetails = ptr.String(jtv) - } - - case "TaskArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskArn to be of type string, got %T instead", value) - } - sv.TaskArn = ptr.String(jtv) - } - - case "TaskExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionTaskId to be of type string, got %T instead", value) - } - sv.TaskExecutionId = ptr.String(jtv) - } - - case "TaskParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParametersList(&sv.TaskParameters, value); err != nil { - return err - } - - case "TriggeredAlarms": - if err := awsAwsjson11_deserializeDocumentAlarmStateInformationList(&sv.TriggeredAlarms, value); err != nil { - return err - } - - case "Type": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.Type = types.MaintenanceWindowTaskType(jtv) - } - - case "WindowExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowExecutionId to be of type string, got %T instead", value) - } - sv.WindowExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowOutput(v **GetMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetMaintenanceWindowOutput - if *v == nil { - sv = &GetMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AllowUnassociatedTargets": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected MaintenanceWindowAllowUnassociatedTargets to be of type *bool, got %T instead", value) - } - sv.AllowUnassociatedTargets = jtv - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Cutoff": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowCutoff to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Cutoff = int32(i64) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Duration": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDurationHours to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Duration = ptr.Int32(int32(i64)) - } - - case "Enabled": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected MaintenanceWindowEnabled to be of type *bool, got %T instead", value) - } - sv.Enabled = jtv - } - - case "EndDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.EndDate = ptr.String(jtv) - } - - case "ModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "NextExecutionTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.NextExecutionTime = ptr.String(jtv) - } - - case "Schedule": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowSchedule to be of type string, got %T instead", value) - } - sv.Schedule = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "ScheduleTimezone": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTimezone to be of type string, got %T instead", value) - } - sv.ScheduleTimezone = ptr.String(jtv) - } - - case "StartDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.StartDate = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetMaintenanceWindowTaskOutput(v **GetMaintenanceWindowTaskOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetMaintenanceWindowTaskOutput - if *v == nil { - sv = &GetMaintenanceWindowTaskOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "CutoffBehavior": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskCutoffBehavior to be of type string, got %T instead", value) - } - sv.CutoffBehavior = types.MaintenanceWindowTaskCutoffBehavior(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "LoggingInfo": - if err := awsAwsjson11_deserializeDocumentLoggingInfo(&sv.LoggingInfo, value); err != nil { - return err - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = int32(i64) - } - - case "ServiceRoleArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRoleArn = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TaskArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskArn to be of type string, got %T instead", value) - } - sv.TaskArn = ptr.String(jtv) - } - - case "TaskInvocationParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskInvocationParameters(&sv.TaskInvocationParameters, value); err != nil { - return err - } - - case "TaskParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameters(&sv.TaskParameters, value); err != nil { - return err - } - - case "TaskType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskType to be of type string, got %T instead", value) - } - sv.TaskType = types.MaintenanceWindowTaskType(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTaskId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskId to be of type string, got %T instead", value) - } - sv.WindowTaskId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetOpsItemOutput(v **GetOpsItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetOpsItemOutput - if *v == nil { - sv = &GetOpsItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OpsItem": - if err := awsAwsjson11_deserializeDocumentOpsItem(&sv.OpsItem, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetOpsMetadataOutput(v **GetOpsMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetOpsMetadataOutput - if *v == nil { - sv = &GetOpsMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Metadata": - if err := awsAwsjson11_deserializeDocumentMetadataMap(&sv.Metadata, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "ResourceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsMetadataResourceId to be of type string, got %T instead", value) - } - sv.ResourceId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetOpsSummaryOutput(v **GetOpsSummaryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetOpsSummaryOutput - if *v == nil { - sv = &GetOpsSummaryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Entities": - if err := awsAwsjson11_deserializeDocumentOpsEntityList(&sv.Entities, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetParameterHistoryOutput(v **GetParameterHistoryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetParameterHistoryOutput - if *v == nil { - sv = &GetParameterHistoryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameterHistoryList(&sv.Parameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetParameterOutput(v **GetParameterOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetParameterOutput - if *v == nil { - sv = &GetParameterOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Parameter": - if err := awsAwsjson11_deserializeDocumentParameter(&sv.Parameter, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetParametersByPathOutput(v **GetParametersByPathOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetParametersByPathOutput - if *v == nil { - sv = &GetParametersByPathOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameterList(&sv.Parameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetParametersOutput(v **GetParametersOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetParametersOutput - if *v == nil { - sv = &GetParametersOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InvalidParameters": - if err := awsAwsjson11_deserializeDocumentParameterNameList(&sv.InvalidParameters, value); err != nil { - return err - } - - case "Parameters": - if err := awsAwsjson11_deserializeDocumentParameterList(&sv.Parameters, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetPatchBaselineForPatchGroupOutput(v **GetPatchBaselineForPatchGroupOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetPatchBaselineForPatchGroupOutput - if *v == nil { - sv = &GetPatchBaselineForPatchGroupOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "OperatingSystem": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OperatingSystem to be of type string, got %T instead", value) - } - sv.OperatingSystem = types.OperatingSystem(jtv) - } - - case "PatchGroup": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - sv.PatchGroup = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetPatchBaselineOutput(v **GetPatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetPatchBaselineOutput - if *v == nil { - sv = &GetPatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApprovalRules": - if err := awsAwsjson11_deserializeDocumentPatchRuleGroup(&sv.ApprovalRules, value); err != nil { - return err - } - - case "ApprovedPatches": - if err := awsAwsjson11_deserializeDocumentPatchIdList(&sv.ApprovedPatches, value); err != nil { - return err - } - - case "ApprovedPatchesComplianceLevel": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchComplianceLevel to be of type string, got %T instead", value) - } - sv.ApprovedPatchesComplianceLevel = types.PatchComplianceLevel(jtv) - } - - case "ApprovedPatchesEnableNonSecurity": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.ApprovedPatchesEnableNonSecurity = ptr.Bool(jtv) - } - - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "GlobalFilters": - if err := awsAwsjson11_deserializeDocumentPatchFilterGroup(&sv.GlobalFilters, value); err != nil { - return err - } - - case "ModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OperatingSystem": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OperatingSystem to be of type string, got %T instead", value) - } - sv.OperatingSystem = types.OperatingSystem(jtv) - } - - case "PatchGroups": - if err := awsAwsjson11_deserializeDocumentPatchGroupList(&sv.PatchGroups, value); err != nil { - return err - } - - case "RejectedPatches": - if err := awsAwsjson11_deserializeDocumentPatchIdList(&sv.RejectedPatches, value); err != nil { - return err - } - - case "RejectedPatchesAction": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchAction to be of type string, got %T instead", value) - } - sv.RejectedPatchesAction = types.PatchAction(jtv) - } - - case "Sources": - if err := awsAwsjson11_deserializeDocumentPatchSourceList(&sv.Sources, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetResourcePoliciesOutput(v **GetResourcePoliciesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetResourcePoliciesOutput - if *v == nil { - sv = &GetResourcePoliciesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Policies": - if err := awsAwsjson11_deserializeDocumentGetResourcePoliciesResponseEntries(&sv.Policies, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentGetServiceSettingOutput(v **GetServiceSettingOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetServiceSettingOutput - if *v == nil { - sv = &GetServiceSettingOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ServiceSetting": - if err := awsAwsjson11_deserializeDocumentServiceSetting(&sv.ServiceSetting, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentLabelParameterVersionOutput(v **LabelParameterVersionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *LabelParameterVersionOutput - if *v == nil { - sv = &LabelParameterVersionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InvalidLabels": - if err := awsAwsjson11_deserializeDocumentParameterLabelList(&sv.InvalidLabels, value); err != nil { - return err - } - - case "ParameterVersion": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PSParameterVersion to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ParameterVersion = i64 - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListAssociationsOutput(v **ListAssociationsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListAssociationsOutput - if *v == nil { - sv = &ListAssociationsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Associations": - if err := awsAwsjson11_deserializeDocumentAssociationList(&sv.Associations, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListAssociationVersionsOutput(v **ListAssociationVersionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListAssociationVersionsOutput - if *v == nil { - sv = &ListAssociationVersionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationVersions": - if err := awsAwsjson11_deserializeDocumentAssociationVersionList(&sv.AssociationVersions, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListCommandInvocationsOutput(v **ListCommandInvocationsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListCommandInvocationsOutput - if *v == nil { - sv = &ListCommandInvocationsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CommandInvocations": - if err := awsAwsjson11_deserializeDocumentCommandInvocationList(&sv.CommandInvocations, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListCommandsOutput(v **ListCommandsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListCommandsOutput - if *v == nil { - sv = &ListCommandsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Commands": - if err := awsAwsjson11_deserializeDocumentCommandList(&sv.Commands, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListComplianceItemsOutput(v **ListComplianceItemsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListComplianceItemsOutput - if *v == nil { - sv = &ListComplianceItemsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ComplianceItems": - if err := awsAwsjson11_deserializeDocumentComplianceItemList(&sv.ComplianceItems, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListComplianceSummariesOutput(v **ListComplianceSummariesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListComplianceSummariesOutput - if *v == nil { - sv = &ListComplianceSummariesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ComplianceSummaryItems": - if err := awsAwsjson11_deserializeDocumentComplianceSummaryItemList(&sv.ComplianceSummaryItems, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListDocumentMetadataHistoryOutput(v **ListDocumentMetadataHistoryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListDocumentMetadataHistoryOutput - if *v == nil { - sv = &ListDocumentMetadataHistoryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Author": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentAuthor to be of type string, got %T instead", value) - } - sv.Author = ptr.String(jtv) - } - - case "DocumentVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentVersion to be of type string, got %T instead", value) - } - sv.DocumentVersion = ptr.String(jtv) - } - - case "Metadata": - if err := awsAwsjson11_deserializeDocumentDocumentMetadataResponseInfo(&sv.Metadata, value); err != nil { - return err - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DocumentName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListDocumentsOutput(v **ListDocumentsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListDocumentsOutput - if *v == nil { - sv = &ListDocumentsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentIdentifiers": - if err := awsAwsjson11_deserializeDocumentDocumentIdentifierList(&sv.DocumentIdentifiers, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListDocumentVersionsOutput(v **ListDocumentVersionsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListDocumentVersionsOutput - if *v == nil { - sv = &ListDocumentVersionsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentVersions": - if err := awsAwsjson11_deserializeDocumentDocumentVersionList(&sv.DocumentVersions, value); err != nil { - return err - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListInventoryEntriesOutput(v **ListInventoryEntriesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListInventoryEntriesOutput - if *v == nil { - sv = &ListInventoryEntriesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "CaptureTime": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemCaptureTime to be of type string, got %T instead", value) - } - sv.CaptureTime = ptr.String(jtv) - } - - case "Entries": - if err := awsAwsjson11_deserializeDocumentInventoryItemEntryList(&sv.Entries, value); err != nil { - return err - } - - case "InstanceId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InstanceId to be of type string, got %T instead", value) - } - sv.InstanceId = ptr.String(jtv) - } - - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "SchemaVersion": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemSchemaVersion to be of type string, got %T instead", value) - } - sv.SchemaVersion = ptr.String(jtv) - } - - case "TypeName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected InventoryItemTypeName to be of type string, got %T instead", value) - } - sv.TypeName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListOpsItemEventsOutput(v **ListOpsItemEventsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListOpsItemEventsOutput - if *v == nil { - sv = &ListOpsItemEventsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Summaries": - if err := awsAwsjson11_deserializeDocumentOpsItemEventSummaries(&sv.Summaries, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListOpsItemRelatedItemsOutput(v **ListOpsItemRelatedItemsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListOpsItemRelatedItemsOutput - if *v == nil { - sv = &ListOpsItemRelatedItemsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected String to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "Summaries": - if err := awsAwsjson11_deserializeDocumentOpsItemRelatedItemSummaries(&sv.Summaries, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListOpsMetadataOutput(v **ListOpsMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListOpsMetadataOutput - if *v == nil { - sv = &ListOpsMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "OpsMetadataList": - if err := awsAwsjson11_deserializeDocumentOpsMetadataList(&sv.OpsMetadataList, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListResourceComplianceSummariesOutput(v **ListResourceComplianceSummariesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListResourceComplianceSummariesOutput - if *v == nil { - sv = &ListResourceComplianceSummariesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "ResourceComplianceSummaryItems": - if err := awsAwsjson11_deserializeDocumentResourceComplianceSummaryItemList(&sv.ResourceComplianceSummaryItems, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListResourceDataSyncOutput(v **ListResourceDataSyncOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListResourceDataSyncOutput - if *v == nil { - sv = &ListResourceDataSyncOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "NextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextToken to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "ResourceDataSyncItems": - if err := awsAwsjson11_deserializeDocumentResourceDataSyncItemList(&sv.ResourceDataSyncItems, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentListTagsForResourceOutput(v **ListTagsForResourceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListTagsForResourceOutput - if *v == nil { - sv = &ListTagsForResourceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "TagList": - if err := awsAwsjson11_deserializeDocumentTagList(&sv.TagList, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentModifyDocumentPermissionOutput(v **ModifyDocumentPermissionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ModifyDocumentPermissionOutput - if *v == nil { - sv = &ModifyDocumentPermissionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentPutComplianceItemsOutput(v **PutComplianceItemsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *PutComplianceItemsOutput - if *v == nil { - sv = &PutComplianceItemsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentPutInventoryOutput(v **PutInventoryOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *PutInventoryOutput - if *v == nil { - sv = &PutInventoryOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PutInventoryMessage to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentPutParameterOutput(v **PutParameterOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *PutParameterOutput - if *v == nil { - sv = &PutParameterOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Tier": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ParameterTier to be of type string, got %T instead", value) - } - sv.Tier = types.ParameterTier(jtv) - } - - case "Version": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected PSParameterVersion to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Version = i64 - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentPutResourcePolicyOutput(v **PutResourcePolicyOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *PutResourcePolicyOutput - if *v == nil { - sv = &PutResourcePolicyOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "PolicyHash": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PolicyHash to be of type string, got %T instead", value) - } - sv.PolicyHash = ptr.String(jtv) - } - - case "PolicyId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PolicyId to be of type string, got %T instead", value) - } - sv.PolicyId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentRegisterDefaultPatchBaselineOutput(v **RegisterDefaultPatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RegisterDefaultPatchBaselineOutput - if *v == nil { - sv = &RegisterDefaultPatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentRegisterPatchBaselineForPatchGroupOutput(v **RegisterPatchBaselineForPatchGroupOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RegisterPatchBaselineForPatchGroupOutput - if *v == nil { - sv = &RegisterPatchBaselineForPatchGroupOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "PatchGroup": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchGroup to be of type string, got %T instead", value) - } - sv.PatchGroup = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentRegisterTargetWithMaintenanceWindowOutput(v **RegisterTargetWithMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RegisterTargetWithMaintenanceWindowOutput - if *v == nil { - sv = &RegisterTargetWithMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentRegisterTaskWithMaintenanceWindowOutput(v **RegisterTaskWithMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RegisterTaskWithMaintenanceWindowOutput - if *v == nil { - sv = &RegisterTaskWithMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "WindowTaskId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskId to be of type string, got %T instead", value) - } - sv.WindowTaskId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentRemoveTagsFromResourceOutput(v **RemoveTagsFromResourceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RemoveTagsFromResourceOutput - if *v == nil { - sv = &RemoveTagsFromResourceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentResetServiceSettingOutput(v **ResetServiceSettingOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ResetServiceSettingOutput - if *v == nil { - sv = &ResetServiceSettingOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ServiceSetting": - if err := awsAwsjson11_deserializeDocumentServiceSetting(&sv.ServiceSetting, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentResumeSessionOutput(v **ResumeSessionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ResumeSessionOutput - if *v == nil { - sv = &ResumeSessionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "SessionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionId to be of type string, got %T instead", value) - } - sv.SessionId = ptr.String(jtv) - } - - case "StreamUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StreamUrl to be of type string, got %T instead", value) - } - sv.StreamUrl = ptr.String(jtv) - } - - case "TokenValue": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TokenValue to be of type string, got %T instead", value) - } - sv.TokenValue = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentSendAutomationSignalOutput(v **SendAutomationSignalOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *SendAutomationSignalOutput - if *v == nil { - sv = &SendAutomationSignalOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentSendCommandOutput(v **SendCommandOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *SendCommandOutput - if *v == nil { - sv = &SendCommandOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Command": - if err := awsAwsjson11_deserializeDocumentCommand(&sv.Command, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentStartAssociationsOnceOutput(v **StartAssociationsOnceOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StartAssociationsOnceOutput - if *v == nil { - sv = &StartAssociationsOnceOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentStartAutomationExecutionOutput(v **StartAutomationExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StartAutomationExecutionOutput - if *v == nil { - sv = &StartAutomationExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.AutomationExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentStartChangeRequestExecutionOutput(v **StartChangeRequestExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StartChangeRequestExecutionOutput - if *v == nil { - sv = &StartChangeRequestExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AutomationExecutionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AutomationExecutionId to be of type string, got %T instead", value) - } - sv.AutomationExecutionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentStartSessionOutput(v **StartSessionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StartSessionOutput - if *v == nil { - sv = &StartSessionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "SessionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionId to be of type string, got %T instead", value) - } - sv.SessionId = ptr.String(jtv) - } - - case "StreamUrl": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected StreamUrl to be of type string, got %T instead", value) - } - sv.StreamUrl = ptr.String(jtv) - } - - case "TokenValue": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TokenValue to be of type string, got %T instead", value) - } - sv.TokenValue = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentStopAutomationExecutionOutput(v **StopAutomationExecutionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StopAutomationExecutionOutput - if *v == nil { - sv = &StopAutomationExecutionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentTerminateSessionOutput(v **TerminateSessionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *TerminateSessionOutput - if *v == nil { - sv = &TerminateSessionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "SessionId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionId to be of type string, got %T instead", value) - } - sv.SessionId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUnlabelParameterVersionOutput(v **UnlabelParameterVersionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UnlabelParameterVersionOutput - if *v == nil { - sv = &UnlabelParameterVersionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "InvalidLabels": - if err := awsAwsjson11_deserializeDocumentParameterLabelList(&sv.InvalidLabels, value); err != nil { - return err - } - - case "RemovedLabels": - if err := awsAwsjson11_deserializeDocumentParameterLabelList(&sv.RemovedLabels, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateAssociationOutput(v **UpdateAssociationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateAssociationOutput - if *v == nil { - sv = &UpdateAssociationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationDescription": - if err := awsAwsjson11_deserializeDocumentAssociationDescription(&sv.AssociationDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateAssociationStatusOutput(v **UpdateAssociationStatusOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateAssociationStatusOutput - if *v == nil { - sv = &UpdateAssociationStatusOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AssociationDescription": - if err := awsAwsjson11_deserializeDocumentAssociationDescription(&sv.AssociationDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateDocumentDefaultVersionOutput(v **UpdateDocumentDefaultVersionOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateDocumentDefaultVersionOutput - if *v == nil { - sv = &UpdateDocumentDefaultVersionOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Description": - if err := awsAwsjson11_deserializeDocumentDocumentDefaultVersionDescription(&sv.Description, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateDocumentMetadataOutput(v **UpdateDocumentMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateDocumentMetadataOutput - if *v == nil { - sv = &UpdateDocumentMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateDocumentOutput(v **UpdateDocumentOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateDocumentOutput - if *v == nil { - sv = &UpdateDocumentOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "DocumentDescription": - if err := awsAwsjson11_deserializeDocumentDocumentDescription(&sv.DocumentDescription, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowOutput(v **UpdateMaintenanceWindowOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateMaintenanceWindowOutput - if *v == nil { - sv = &UpdateMaintenanceWindowOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AllowUnassociatedTargets": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected MaintenanceWindowAllowUnassociatedTargets to be of type *bool, got %T instead", value) - } - sv.AllowUnassociatedTargets = jtv - } - - case "Cutoff": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowCutoff to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Cutoff = int32(i64) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Duration": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDurationHours to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Duration = ptr.Int32(int32(i64)) - } - - case "Enabled": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected MaintenanceWindowEnabled to be of type *bool, got %T instead", value) - } - sv.Enabled = jtv - } - - case "EndDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.EndDate = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Schedule": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowSchedule to be of type string, got %T instead", value) - } - sv.Schedule = ptr.String(jtv) - } - - case "ScheduleOffset": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowOffset to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ScheduleOffset = ptr.Int32(int32(i64)) - } - - case "ScheduleTimezone": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTimezone to be of type string, got %T instead", value) - } - sv.ScheduleTimezone = ptr.String(jtv) - } - - case "StartDate": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowStringDateTime to be of type string, got %T instead", value) - } - sv.StartDate = ptr.String(jtv) - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowTargetOutput(v **UpdateMaintenanceWindowTargetOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateMaintenanceWindowTargetOutput - if *v == nil { - sv = &UpdateMaintenanceWindowTargetOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OwnerInformation": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OwnerInformation to be of type string, got %T instead", value) - } - sv.OwnerInformation = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTargetId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTargetId to be of type string, got %T instead", value) - } - sv.WindowTargetId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateMaintenanceWindowTaskOutput(v **UpdateMaintenanceWindowTaskOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateMaintenanceWindowTaskOutput - if *v == nil { - sv = &UpdateMaintenanceWindowTaskOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "AlarmConfiguration": - if err := awsAwsjson11_deserializeDocumentAlarmConfiguration(&sv.AlarmConfiguration, value); err != nil { - return err - } - - case "CutoffBehavior": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskCutoffBehavior to be of type string, got %T instead", value) - } - sv.CutoffBehavior = types.MaintenanceWindowTaskCutoffBehavior(jtv) - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "LoggingInfo": - if err := awsAwsjson11_deserializeDocumentLoggingInfo(&sv.LoggingInfo, value); err != nil { - return err - } - - case "MaxConcurrency": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxConcurrency to be of type string, got %T instead", value) - } - sv.MaxConcurrency = ptr.String(jtv) - } - - case "MaxErrors": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaxErrors to be of type string, got %T instead", value) - } - sv.MaxErrors = ptr.String(jtv) - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "Priority": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskPriority to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Priority = int32(i64) - } - - case "ServiceRoleArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ServiceRole to be of type string, got %T instead", value) - } - sv.ServiceRoleArn = ptr.String(jtv) - } - - case "Targets": - if err := awsAwsjson11_deserializeDocumentTargets(&sv.Targets, value); err != nil { - return err - } - - case "TaskArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskArn to be of type string, got %T instead", value) - } - sv.TaskArn = ptr.String(jtv) - } - - case "TaskInvocationParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskInvocationParameters(&sv.TaskInvocationParameters, value); err != nil { - return err - } - - case "TaskParameters": - if err := awsAwsjson11_deserializeDocumentMaintenanceWindowTaskParameters(&sv.TaskParameters, value); err != nil { - return err - } - - case "WindowId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowId to be of type string, got %T instead", value) - } - sv.WindowId = ptr.String(jtv) - } - - case "WindowTaskId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected MaintenanceWindowTaskId to be of type string, got %T instead", value) - } - sv.WindowTaskId = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateManagedInstanceRoleOutput(v **UpdateManagedInstanceRoleOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateManagedInstanceRoleOutput - if *v == nil { - sv = &UpdateManagedInstanceRoleOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateOpsItemOutput(v **UpdateOpsItemOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateOpsItemOutput - if *v == nil { - sv = &UpdateOpsItemOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateOpsMetadataOutput(v **UpdateOpsMetadataOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateOpsMetadataOutput - if *v == nil { - sv = &UpdateOpsMetadataOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "OpsMetadataArn": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OpsMetadataArn to be of type string, got %T instead", value) - } - sv.OpsMetadataArn = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdatePatchBaselineOutput(v **UpdatePatchBaselineOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdatePatchBaselineOutput - if *v == nil { - sv = &UpdatePatchBaselineOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "ApprovalRules": - if err := awsAwsjson11_deserializeDocumentPatchRuleGroup(&sv.ApprovalRules, value); err != nil { - return err - } - - case "ApprovedPatches": - if err := awsAwsjson11_deserializeDocumentPatchIdList(&sv.ApprovedPatches, value); err != nil { - return err - } - - case "ApprovedPatchesComplianceLevel": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchComplianceLevel to be of type string, got %T instead", value) - } - sv.ApprovedPatchesComplianceLevel = types.PatchComplianceLevel(jtv) - } - - case "ApprovedPatchesEnableNonSecurity": - if value != nil { - jtv, ok := value.(bool) - if !ok { - return fmt.Errorf("expected Boolean to be of type *bool, got %T instead", value) - } - sv.ApprovedPatchesEnableNonSecurity = ptr.Bool(jtv) - } - - case "BaselineId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineId to be of type string, got %T instead", value) - } - sv.BaselineId = ptr.String(jtv) - } - - case "CreatedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.CreatedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineDescription to be of type string, got %T instead", value) - } - sv.Description = ptr.String(jtv) - } - - case "GlobalFilters": - if err := awsAwsjson11_deserializeDocumentPatchFilterGroup(&sv.GlobalFilters, value); err != nil { - return err - } - - case "ModifiedDate": - if value != nil { - switch jtv := value.(type) { - case json.Number: - f64, err := jtv.Float64() - if err != nil { - return err - } - sv.ModifiedDate = ptr.Time(smithytime.ParseEpochSeconds(f64)) - - default: - return fmt.Errorf("expected DateTime to be a JSON Number, got %T instead", value) - - } - } - - case "Name": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected BaselineName to be of type string, got %T instead", value) - } - sv.Name = ptr.String(jtv) - } - - case "OperatingSystem": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected OperatingSystem to be of type string, got %T instead", value) - } - sv.OperatingSystem = types.OperatingSystem(jtv) - } - - case "RejectedPatches": - if err := awsAwsjson11_deserializeDocumentPatchIdList(&sv.RejectedPatches, value); err != nil { - return err - } - - case "RejectedPatchesAction": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected PatchAction to be of type string, got %T instead", value) - } - sv.RejectedPatchesAction = types.PatchAction(jtv) - } - - case "Sources": - if err := awsAwsjson11_deserializeDocumentPatchSourceList(&sv.Sources, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateResourceDataSyncOutput(v **UpdateResourceDataSyncOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateResourceDataSyncOutput - if *v == nil { - sv = &UpdateResourceDataSyncOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsAwsjson11_deserializeOpDocumentUpdateServiceSettingOutput(v **UpdateServiceSettingOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *UpdateServiceSettingOutput - if *v == nil { - sv = &UpdateServiceSettingOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - default: - _, _ = key, value - - } - } - *v = sv - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/doc.go deleted file mode 100644 index e546b70..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/doc.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -// Package ssm provides the API client, operations, and parameter types for Amazon -// Simple Systems Manager (SSM). -// -// Amazon Web Services Systems Manager is the operations hub for your Amazon Web -// Services applications and resources and a secure end-to-end management solution -// for hybrid cloud environments that enables safe and secure operations at scale. -// This reference is intended to be used with the Amazon Web Services Systems -// Manager User Guide (https://docs.aws.amazon.com/systems-manager/latest/userguide/) -// . To get started, see Setting up Amazon Web Services Systems Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up.html) -// . Related resources -// - For information about each of the capabilities that comprise Systems -// Manager, see Systems Manager capabilities (https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html#systems-manager-capabilities) -// in the Amazon Web Services Systems Manager User Guide. -// - For details about predefined runbooks for Automation, a capability of -// Amazon Web Services Systems Manager, see the Systems Manager Automation -// runbook reference (https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-runbook-reference.html) -// . -// - For information about AppConfig, a capability of Systems Manager, see the -// AppConfig User Guide (https://docs.aws.amazon.com/appconfig/latest/userguide/) -// and the AppConfig API Reference (https://docs.aws.amazon.com/appconfig/2019-10-09/APIReference/) -// . -// - For information about Incident Manager, a capability of Systems Manager, -// see the Systems Manager Incident Manager User Guide (https://docs.aws.amazon.com/incident-manager/latest/userguide/) -// and the Systems Manager Incident Manager API Reference (https://docs.aws.amazon.com/incident-manager/latest/APIReference/) -// . -package ssm diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/endpoints.go deleted file mode 100644 index 4cd4e2f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/endpoints.go +++ /dev/null @@ -1,528 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - "github.com/aws/aws-sdk-go-v2/internal/endpoints" - "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" - internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssm/internal/endpoints" - smithyauth "github.com/aws/smithy-go/auth" - smithyendpoints "github.com/aws/smithy-go/endpoints" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" - "net/url" - "os" - "strings" -) - -// EndpointResolverOptions is the service endpoint resolver options -type EndpointResolverOptions = internalendpoints.Options - -// EndpointResolver interface for resolving service endpoints. -type EndpointResolver interface { - ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error) -} - -var _ EndpointResolver = &internalendpoints.Resolver{} - -// NewDefaultEndpointResolver constructs a new service endpoint resolver -func NewDefaultEndpointResolver() *internalendpoints.Resolver { - return internalendpoints.New() -} - -// EndpointResolverFunc is a helper utility that wraps a function so it satisfies -// the EndpointResolver interface. This is useful when you want to add additional -// endpoint resolving logic, or stub out specific endpoints with custom values. -type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error) - -func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return fn(region, options) -} - -// EndpointResolverFromURL returns an EndpointResolver configured using the -// provided endpoint url. By default, the resolved endpoint resolver uses the -// client region as signing region, and the endpoint source is set to -// EndpointSourceCustom.You can provide functional options to configure endpoint -// values for the resolved endpoint. -func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver { - e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom} - for _, fn := range optFns { - fn(&e) - } - - return EndpointResolverFunc( - func(region string, options EndpointResolverOptions) (aws.Endpoint, error) { - if len(e.SigningRegion) == 0 { - e.SigningRegion = region - } - return e, nil - }, - ) -} - -type ResolveEndpoint struct { - Resolver EndpointResolver - Options EndpointResolverOptions -} - -func (*ResolveEndpoint) ID() string { - return "ResolveEndpoint" -} - -func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleSerialize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.Resolver == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - eo := m.Options - eo.Logger = middleware.GetLogger(ctx) - - var endpoint aws.Endpoint - endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) - if err != nil { - nf := (&aws.EndpointNotFoundError{}) - if errors.As(err, &nf) { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) - return next.HandleSerialize(ctx, in) - } - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - req.URL, err = url.Parse(endpoint.URL) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) - } - - if len(awsmiddleware.GetSigningName(ctx)) == 0 { - signingName := endpoint.SigningName - if len(signingName) == 0 { - signingName = "ssm" - } - ctx = awsmiddleware.SetSigningName(ctx, signingName) - } - ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source) - ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable) - ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion) - ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID) - return next.HandleSerialize(ctx, in) -} -func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error { - return stack.Serialize.Insert(&ResolveEndpoint{ - Resolver: o.EndpointResolver, - Options: o.EndpointOptions, - }, "OperationSerializer", middleware.Before) -} - -func removeResolveEndpointMiddleware(stack *middleware.Stack) error { - _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID()) - return err -} - -type wrappedEndpointResolver struct { - awsResolver aws.EndpointResolverWithOptions -} - -func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return w.awsResolver.ResolveEndpoint(ServiceID, region, options) -} - -type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) - -func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) { - return a(service, region) -} - -var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) - -// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, -// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked -// via its middleware. -// -// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { - var resolver aws.EndpointResolverWithOptions - - if awsResolverWithOptions != nil { - resolver = awsResolverWithOptions - } else if awsResolver != nil { - resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint) - } - - return &wrappedEndpointResolver{ - awsResolver: resolver, - } -} - -func finalizeClientEndpointResolverOptions(options *Options) { - options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage() - - if len(options.EndpointOptions.ResolvedRegion) == 0 { - const fipsInfix = "-fips-" - const fipsPrefix = "fips-" - const fipsSuffix = "-fips" - - if strings.Contains(options.Region, fipsInfix) || - strings.Contains(options.Region, fipsPrefix) || - strings.Contains(options.Region, fipsSuffix) { - options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( - options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") - options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled - } - } - -} - -func resolveEndpointResolverV2(options *Options) { - if options.EndpointResolverV2 == nil { - options.EndpointResolverV2 = NewDefaultEndpointResolverV2() - } -} - -func resolveBaseEndpoint(cfg aws.Config, o *Options) { - if cfg.BaseEndpoint != nil { - o.BaseEndpoint = cfg.BaseEndpoint - } - - _, g := os.LookupEnv("AWS_ENDPOINT_URL") - _, s := os.LookupEnv("AWS_ENDPOINT_URL_SSM") - - if g && !s { - return - } - - value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "SSM", cfg.ConfigSources) - if found && err == nil { - o.BaseEndpoint = &value - } -} - -// EndpointParameters provides the parameters that influence how endpoints are -// resolved. -type EndpointParameters struct { - // The AWS region used to dispatch the request. - // - // Parameter is - // required. - // - // AWS::Region - Region *string - - // When true, use the dual-stack endpoint. If the configured endpoint does not - // support dual-stack, dispatching the request MAY return an error. - // - // Defaults to - // false if no value is provided. - // - // AWS::UseDualStack - UseDualStack *bool - - // When true, send this request to the FIPS-compliant regional endpoint. If the - // configured endpoint does not have a FIPS compliant endpoint, dispatching the - // request will return an error. - // - // Defaults to false if no value is - // provided. - // - // AWS::UseFIPS - UseFIPS *bool - - // Override the endpoint used to send this request - // - // Parameter is - // required. - // - // SDK::Endpoint - Endpoint *string -} - -// ValidateRequired validates required parameters are set. -func (p EndpointParameters) ValidateRequired() error { - if p.UseDualStack == nil { - return fmt.Errorf("parameter UseDualStack is required") - } - - if p.UseFIPS == nil { - return fmt.Errorf("parameter UseFIPS is required") - } - - return nil -} - -// WithDefaults returns a shallow copy of EndpointParameterswith default values -// applied to members where applicable. -func (p EndpointParameters) WithDefaults() EndpointParameters { - if p.UseDualStack == nil { - p.UseDualStack = ptr.Bool(false) - } - - if p.UseFIPS == nil { - p.UseFIPS = ptr.Bool(false) - } - return p -} - -// EndpointResolverV2 provides the interface for resolving service endpoints. -type EndpointResolverV2 interface { - // ResolveEndpoint attempts to resolve the endpoint with the provided options, - // returning the endpoint if found. Otherwise an error is returned. - ResolveEndpoint(ctx context.Context, params EndpointParameters) ( - smithyendpoints.Endpoint, error, - ) -} - -// resolver provides the implementation for resolving endpoints. -type resolver struct{} - -func NewDefaultEndpointResolverV2() EndpointResolverV2 { - return &resolver{} -} - -// ResolveEndpoint attempts to resolve the endpoint with the provided options, -// returning the endpoint if found. Otherwise an error is returned. -func (r *resolver) ResolveEndpoint( - ctx context.Context, params EndpointParameters, -) ( - endpoint smithyendpoints.Endpoint, err error, -) { - params = params.WithDefaults() - if err = params.ValidateRequired(); err != nil { - return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) - } - _UseDualStack := *params.UseDualStack - _UseFIPS := *params.UseFIPS - - if exprVal := params.Endpoint; exprVal != nil { - _Endpoint := *exprVal - _ = _Endpoint - if _UseFIPS == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") - } - if _UseDualStack == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") - } - uriString := _Endpoint - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - if exprVal := params.Region; exprVal != nil { - _Region := *exprVal - _ = _Region - if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { - _PartitionResult := *exprVal - _ = _PartitionResult - if _UseFIPS == true { - if _UseDualStack == true { - if true == _PartitionResult.SupportsFIPS { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://ssm-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") - } - } - if _UseFIPS == true { - if _PartitionResult.SupportsFIPS == true { - if _PartitionResult.Name == "aws-us-gov" { - uriString := func() string { - var out strings.Builder - out.WriteString("https://ssm.") - out.WriteString(_Region) - out.WriteString(".amazonaws.com") - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://ssm-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - } - if _UseDualStack == true { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://ssm.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://ssm.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") -} - -type endpointParamsBinder interface { - bindEndpointParams(*EndpointParameters) -} - -func bindEndpointParams(input interface{}, options Options) *EndpointParameters { - params := &EndpointParameters{} - - params.Region = aws.String(endpoints.MapFIPSRegion(options.Region)) - params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) - params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) - params.Endpoint = options.BaseEndpoint - - if b, ok := input.(endpointParamsBinder); ok { - b.bindEndpointParams(params) - } - - return params -} - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleFinalize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.options.EndpointResolverV2 == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - params := bindEndpointParams(getOperationInput(ctx), m.options) - endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) - if err != nil { - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - if endpt.URI.RawPath == "" && req.URL.RawPath != "" { - endpt.URI.RawPath = endpt.URI.Path - } - req.URL.Scheme = endpt.URI.Scheme - req.URL.Host = endpt.URI.Host - req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) - req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) - for k := range endpt.Headers { - req.Header.Set(k, endpt.Headers.Get(k)) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) - for _, o := range opts { - rscheme.SignerProperties.SetAll(&o.SignerProperties) - } - - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/generated.json deleted file mode 100644 index b9f761a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/generated.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "dependencies": { - "github.com/aws/aws-sdk-go-v2": "v1.4.0", - "github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000", - "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000", - "github.com/aws/smithy-go": "v1.4.0", - "github.com/google/go-cmp": "v0.5.4", - "github.com/jmespath/go-jmespath": "v0.4.0" - }, - "files": [ - "api_client.go", - "api_client_test.go", - "api_op_AddTagsToResource.go", - "api_op_AssociateOpsItemRelatedItem.go", - "api_op_CancelCommand.go", - "api_op_CancelMaintenanceWindowExecution.go", - "api_op_CreateActivation.go", - "api_op_CreateAssociation.go", - "api_op_CreateAssociationBatch.go", - "api_op_CreateDocument.go", - "api_op_CreateMaintenanceWindow.go", - "api_op_CreateOpsItem.go", - "api_op_CreateOpsMetadata.go", - "api_op_CreatePatchBaseline.go", - "api_op_CreateResourceDataSync.go", - "api_op_DeleteActivation.go", - "api_op_DeleteAssociation.go", - "api_op_DeleteDocument.go", - "api_op_DeleteInventory.go", - "api_op_DeleteMaintenanceWindow.go", - "api_op_DeleteOpsItem.go", - "api_op_DeleteOpsMetadata.go", - "api_op_DeleteParameter.go", - "api_op_DeleteParameters.go", - "api_op_DeletePatchBaseline.go", - "api_op_DeleteResourceDataSync.go", - "api_op_DeleteResourcePolicy.go", - "api_op_DeregisterManagedInstance.go", - "api_op_DeregisterPatchBaselineForPatchGroup.go", - "api_op_DeregisterTargetFromMaintenanceWindow.go", - "api_op_DeregisterTaskFromMaintenanceWindow.go", - "api_op_DescribeActivations.go", - "api_op_DescribeAssociation.go", - "api_op_DescribeAssociationExecutionTargets.go", - "api_op_DescribeAssociationExecutions.go", - "api_op_DescribeAutomationExecutions.go", - "api_op_DescribeAutomationStepExecutions.go", - "api_op_DescribeAvailablePatches.go", - "api_op_DescribeDocument.go", - "api_op_DescribeDocumentPermission.go", - "api_op_DescribeEffectiveInstanceAssociations.go", - "api_op_DescribeEffectivePatchesForPatchBaseline.go", - "api_op_DescribeInstanceAssociationsStatus.go", - "api_op_DescribeInstanceInformation.go", - "api_op_DescribeInstancePatchStates.go", - "api_op_DescribeInstancePatchStatesForPatchGroup.go", - "api_op_DescribeInstancePatches.go", - "api_op_DescribeInventoryDeletions.go", - "api_op_DescribeMaintenanceWindowExecutionTaskInvocations.go", - "api_op_DescribeMaintenanceWindowExecutionTasks.go", - "api_op_DescribeMaintenanceWindowExecutions.go", - "api_op_DescribeMaintenanceWindowSchedule.go", - "api_op_DescribeMaintenanceWindowTargets.go", - "api_op_DescribeMaintenanceWindowTasks.go", - "api_op_DescribeMaintenanceWindows.go", - "api_op_DescribeMaintenanceWindowsForTarget.go", - "api_op_DescribeOpsItems.go", - "api_op_DescribeParameters.go", - "api_op_DescribePatchBaselines.go", - "api_op_DescribePatchGroupState.go", - "api_op_DescribePatchGroups.go", - "api_op_DescribePatchProperties.go", - "api_op_DescribeSessions.go", - "api_op_DisassociateOpsItemRelatedItem.go", - "api_op_GetAutomationExecution.go", - "api_op_GetCalendarState.go", - "api_op_GetCommandInvocation.go", - "api_op_GetConnectionStatus.go", - "api_op_GetDefaultPatchBaseline.go", - "api_op_GetDeployablePatchSnapshotForInstance.go", - "api_op_GetDocument.go", - "api_op_GetInventory.go", - "api_op_GetInventorySchema.go", - "api_op_GetMaintenanceWindow.go", - "api_op_GetMaintenanceWindowExecution.go", - "api_op_GetMaintenanceWindowExecutionTask.go", - "api_op_GetMaintenanceWindowExecutionTaskInvocation.go", - "api_op_GetMaintenanceWindowTask.go", - "api_op_GetOpsItem.go", - "api_op_GetOpsMetadata.go", - "api_op_GetOpsSummary.go", - "api_op_GetParameter.go", - "api_op_GetParameterHistory.go", - "api_op_GetParameters.go", - "api_op_GetParametersByPath.go", - "api_op_GetPatchBaseline.go", - "api_op_GetPatchBaselineForPatchGroup.go", - "api_op_GetResourcePolicies.go", - "api_op_GetServiceSetting.go", - "api_op_LabelParameterVersion.go", - "api_op_ListAssociationVersions.go", - "api_op_ListAssociations.go", - "api_op_ListCommandInvocations.go", - "api_op_ListCommands.go", - "api_op_ListComplianceItems.go", - "api_op_ListComplianceSummaries.go", - "api_op_ListDocumentMetadataHistory.go", - "api_op_ListDocumentVersions.go", - "api_op_ListDocuments.go", - "api_op_ListInventoryEntries.go", - "api_op_ListOpsItemEvents.go", - "api_op_ListOpsItemRelatedItems.go", - "api_op_ListOpsMetadata.go", - "api_op_ListResourceComplianceSummaries.go", - "api_op_ListResourceDataSync.go", - "api_op_ListTagsForResource.go", - "api_op_ModifyDocumentPermission.go", - "api_op_PutComplianceItems.go", - "api_op_PutInventory.go", - "api_op_PutParameter.go", - "api_op_PutResourcePolicy.go", - "api_op_RegisterDefaultPatchBaseline.go", - "api_op_RegisterPatchBaselineForPatchGroup.go", - "api_op_RegisterTargetWithMaintenanceWindow.go", - "api_op_RegisterTaskWithMaintenanceWindow.go", - "api_op_RemoveTagsFromResource.go", - "api_op_ResetServiceSetting.go", - "api_op_ResumeSession.go", - "api_op_SendAutomationSignal.go", - "api_op_SendCommand.go", - "api_op_StartAssociationsOnce.go", - "api_op_StartAutomationExecution.go", - "api_op_StartChangeRequestExecution.go", - "api_op_StartSession.go", - "api_op_StopAutomationExecution.go", - "api_op_TerminateSession.go", - "api_op_UnlabelParameterVersion.go", - "api_op_UpdateAssociation.go", - "api_op_UpdateAssociationStatus.go", - "api_op_UpdateDocument.go", - "api_op_UpdateDocumentDefaultVersion.go", - "api_op_UpdateDocumentMetadata.go", - "api_op_UpdateMaintenanceWindow.go", - "api_op_UpdateMaintenanceWindowTarget.go", - "api_op_UpdateMaintenanceWindowTask.go", - "api_op_UpdateManagedInstanceRole.go", - "api_op_UpdateOpsItem.go", - "api_op_UpdateOpsMetadata.go", - "api_op_UpdatePatchBaseline.go", - "api_op_UpdateResourceDataSync.go", - "api_op_UpdateServiceSetting.go", - "auth.go", - "deserializers.go", - "doc.go", - "endpoints.go", - "endpoints_config_test.go", - "endpoints_test.go", - "generated.json", - "internal/endpoints/endpoints.go", - "internal/endpoints/endpoints_test.go", - "options.go", - "protocol_test.go", - "serializers.go", - "types/enums.go", - "types/errors.go", - "types/types.go", - "validators.go" - ], - "go": "1.15", - "module": "github.com/aws/aws-sdk-go-v2/service/ssm", - "unstable": false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/go_module_metadata.go deleted file mode 100644 index 9b35f7a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package ssm - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.44.7" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/internal/endpoints/endpoints.go deleted file mode 100644 index 88f6325..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/internal/endpoints/endpoints.go +++ /dev/null @@ -1,534 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package endpoints - -import ( - "github.com/aws/aws-sdk-go-v2/aws" - endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2" - "github.com/aws/smithy-go/logging" - "regexp" -) - -// Options is the endpoint resolver configuration options -type Options struct { - // Logger is a logging implementation that log events should be sent to. - Logger logging.Logger - - // LogDeprecated indicates that deprecated endpoints should be logged to the - // provided logger. - LogDeprecated bool - - // ResolvedRegion is used to override the region to be resolved, rather then the - // using the value passed to the ResolveEndpoint method. This value is used by the - // SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative - // name. You must not set this value directly in your application. - ResolvedRegion string - - // DisableHTTPS informs the resolver to return an endpoint that does not use the - // HTTPS scheme. - DisableHTTPS bool - - // UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint. - UseDualStackEndpoint aws.DualStackEndpointState - - // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. - UseFIPSEndpoint aws.FIPSEndpointState -} - -func (o Options) GetResolvedRegion() string { - return o.ResolvedRegion -} - -func (o Options) GetDisableHTTPS() bool { - return o.DisableHTTPS -} - -func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState { - return o.UseDualStackEndpoint -} - -func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState { - return o.UseFIPSEndpoint -} - -func transformToSharedOptions(options Options) endpoints.Options { - return endpoints.Options{ - Logger: options.Logger, - LogDeprecated: options.LogDeprecated, - ResolvedRegion: options.ResolvedRegion, - DisableHTTPS: options.DisableHTTPS, - UseDualStackEndpoint: options.UseDualStackEndpoint, - UseFIPSEndpoint: options.UseFIPSEndpoint, - } -} - -// Resolver SSM endpoint resolver -type Resolver struct { - partitions endpoints.Partitions -} - -// ResolveEndpoint resolves the service endpoint for the given region and options -func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) { - if len(region) == 0 { - return endpoint, &aws.MissingRegionError{} - } - - opt := transformToSharedOptions(options) - return r.partitions.ResolveEndpoint(region, opt) -} - -// New returns a new Resolver -func New() *Resolver { - return &Resolver{ - partitions: defaultPartitions, - } -} - -var partitionRegexp = struct { - Aws *regexp.Regexp - AwsCn *regexp.Regexp - AwsIso *regexp.Regexp - AwsIsoB *regexp.Regexp - AwsIsoE *regexp.Regexp - AwsIsoF *regexp.Regexp - AwsUsGov *regexp.Regexp -}{ - - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), - AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), - AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), - AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), - AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), - AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), - AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), -} - -var defaultPartitions = endpoints.Partitions{ - { - ID: "aws", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "ssm.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "ssm-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.Aws, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "af-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-south-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-4", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ca-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ca-central-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.ca-central-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "ca-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ca-west-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.ca-west-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "eu-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-central-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-north-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-south-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "fips-ca-central-1", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.ca-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-central-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-ca-west-1", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.ca-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-west-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-us-east-1", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.us-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-us-east-2", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.us-east-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-2", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-us-west-1", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.us-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-us-west-2", - }: endpoints.Endpoint{ - Hostname: "ssm-fips.us-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-2", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "il-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "me-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "me-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "sa-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.us-east-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-east-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-2", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.us-east-2.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-west-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.us-west-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-west-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-west-2", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.us-west-2.amazonaws.com", - }, - }, - }, - { - ID: "aws-cn", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "ssm.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "ssm-fips.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsCn, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "cn-north-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "cn-northwest-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIso, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-iso-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-iso-west-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso-b", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoB, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-isob-east-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso-e", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoE, - IsRegionalized: true, - }, - { - ID: "aws-iso-f", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm-fips.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoF, - IsRegionalized: true, - }, - { - ID: "aws-us-gov", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "ssm.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "ssm-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "ssm.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsUsGov, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "fips-us-gov-east-1", - }: endpoints.Endpoint{ - Hostname: "ssm.us-gov-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-east-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "fips-us-gov-west-1", - }: endpoints.Endpoint{ - Hostname: "ssm.us-gov-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-west-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "us-gov-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-gov-east-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm.us-gov-east-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "ssm.us-gov-west-1.amazonaws.com", - }, - }, - }, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/options.go deleted file mode 100644 index 197dfd3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/options.go +++ /dev/null @@ -1,221 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" -) - -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // The optional application specific identifier appended to the User-Agent header. - AppID string - - // This endpoint will be given as input to an EndpointResolverV2. It is used for - // providing a custom base endpoint that is subject to modifications by the - // processing EndpointResolverV2. - BaseEndpoint *string - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - // - // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a - // value for this field will likely prevent you from using any endpoint-related - // service features released after the introduction of EndpointResolverV2 and - // BaseEndpoint. To migrate an EndpointResolver implementation that uses a custom - // endpoint, set the client option BaseEndpoint instead. - EndpointResolver EndpointResolver - - // Resolves the endpoint used for a particular service operation. This should be - // used over the deprecated EndpointResolver. - EndpointResolverV2 EndpointResolverV2 - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // Provides idempotency tokens values that will be automatically populated into - // idempotent API operations. - IdempotencyTokenProvider IdempotencyTokenProvider - - // The logger writer interface to write logging messages to. - Logger logging.Logger - - // The region to send requests to. (Required) - Region string - - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. If specified in an operation call's - // functional options with a value that is different than the constructed client's - // Options, the Client's Retryer will be wrapped to use the operation's specific - // RetryMaxAttempts value. - RetryMaxAttempts int - - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. When creating a new API Clients this - // member will only be used if the Retryer Options member is nil. This value will - // be ignored if Retryer is not nil. Currently does not support per operation call - // overrides, may in the future. - RetryMode aws.RetryMode - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. Currently does not support per operation call - // overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient - - // The auth scheme resolver which determines how to authenticate for each - // operation. - AuthSchemeResolver AuthSchemeResolver - - // The list of auth schemes supported by the client. - AuthSchemes []smithyhttp.AuthScheme -} - -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - - return to -} - -func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { - if schemeID == "aws.auth#sigv4" { - return getSigV4IdentityResolver(o) - } - if schemeID == "smithy.api#noAuth" { - return &smithyauth.AnonymousIdentityResolver{} - } - return nil -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) - } -} - -// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for -// this field will likely prevent you from using any endpoint-related service -// features released after the introduction of EndpointResolverV2 and BaseEndpoint. -// To migrate an EndpointResolver implementation that uses a custom endpoint, set -// the client option BaseEndpoint instead. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } -} - -// WithEndpointResolverV2 returns a functional option for setting the Client's -// EndpointResolverV2 option. -func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { - return func(o *Options) { - o.EndpointResolverV2 = v - } -} - -func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { - if o.Credentials != nil { - return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} - } - return nil -} - -// WithSigV4SigningName applies an override to the authentication workflow to -// use the given signing name for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing name from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningName(name string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), - middleware.Before, - ) - }) - } -} - -// WithSigV4SigningRegion applies an override to the authentication workflow to -// use the given signing region for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing region from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningRegion(region string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), - middleware.Before, - ) - }) - } -} - -func ignoreAnonymousAuth(options *Options) { - if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { - options.Credentials = nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/serializers.go deleted file mode 100644 index 9e3ab94..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/serializers.go +++ /dev/null @@ -1,14912 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "bytes" - "context" - "fmt" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/encoding/httpbinding" - smithyjson "github.com/aws/smithy-go/encoding/json" - "github.com/aws/smithy-go/middleware" - smithytime "github.com/aws/smithy-go/time" - smithyhttp "github.com/aws/smithy-go/transport/http" - "path" -) - -type awsAwsjson11_serializeOpAddTagsToResource struct { -} - -func (*awsAwsjson11_serializeOpAddTagsToResource) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpAddTagsToResource) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AddTagsToResourceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.AddTagsToResource") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentAddTagsToResourceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpAssociateOpsItemRelatedItem struct { -} - -func (*awsAwsjson11_serializeOpAssociateOpsItemRelatedItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpAssociateOpsItemRelatedItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AssociateOpsItemRelatedItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.AssociateOpsItemRelatedItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentAssociateOpsItemRelatedItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCancelCommand struct { -} - -func (*awsAwsjson11_serializeOpCancelCommand) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCancelCommand) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CancelCommandInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CancelCommand") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCancelCommandInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCancelMaintenanceWindowExecution struct { -} - -func (*awsAwsjson11_serializeOpCancelMaintenanceWindowExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCancelMaintenanceWindowExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CancelMaintenanceWindowExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CancelMaintenanceWindowExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCancelMaintenanceWindowExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateActivation struct { -} - -func (*awsAwsjson11_serializeOpCreateActivation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateActivation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateActivationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateActivation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateActivationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateAssociation struct { -} - -func (*awsAwsjson11_serializeOpCreateAssociation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateAssociation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateAssociationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateAssociation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateAssociationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateAssociationBatch struct { -} - -func (*awsAwsjson11_serializeOpCreateAssociationBatch) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateAssociationBatch) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateAssociationBatchInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateAssociationBatch") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateAssociationBatchInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateDocument struct { -} - -func (*awsAwsjson11_serializeOpCreateDocument) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateDocument) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateDocumentInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateDocument") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateDocumentInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpCreateMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateOpsItem struct { -} - -func (*awsAwsjson11_serializeOpCreateOpsItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateOpsItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateOpsItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateOpsItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateOpsItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateOpsMetadata struct { -} - -func (*awsAwsjson11_serializeOpCreateOpsMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateOpsMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateOpsMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateOpsMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateOpsMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreatePatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpCreatePatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreatePatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreatePatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreatePatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreatePatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpCreateResourceDataSync struct { -} - -func (*awsAwsjson11_serializeOpCreateResourceDataSync) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpCreateResourceDataSync) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateResourceDataSyncInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.CreateResourceDataSync") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentCreateResourceDataSyncInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteActivation struct { -} - -func (*awsAwsjson11_serializeOpDeleteActivation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteActivation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteActivationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteActivation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteActivationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteAssociation struct { -} - -func (*awsAwsjson11_serializeOpDeleteAssociation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteAssociation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteAssociationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteAssociation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteAssociationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteDocument struct { -} - -func (*awsAwsjson11_serializeOpDeleteDocument) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteDocument) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteDocumentInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteDocument") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteDocumentInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteInventory struct { -} - -func (*awsAwsjson11_serializeOpDeleteInventory) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteInventory) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteInventoryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteInventory") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteInventoryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpDeleteMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteOpsItem struct { -} - -func (*awsAwsjson11_serializeOpDeleteOpsItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteOpsItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteOpsItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteOpsItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteOpsItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteOpsMetadata struct { -} - -func (*awsAwsjson11_serializeOpDeleteOpsMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteOpsMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteOpsMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteOpsMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteOpsMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteParameter struct { -} - -func (*awsAwsjson11_serializeOpDeleteParameter) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteParameter) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteParameterInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteParameter") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteParameterInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteParameters struct { -} - -func (*awsAwsjson11_serializeOpDeleteParameters) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteParameters) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteParametersInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteParameters") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteParametersInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeletePatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpDeletePatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeletePatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeletePatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeletePatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeletePatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteResourceDataSync struct { -} - -func (*awsAwsjson11_serializeOpDeleteResourceDataSync) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteResourceDataSync) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteResourceDataSyncInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteResourceDataSync") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteResourceDataSyncInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeleteResourcePolicy struct { -} - -func (*awsAwsjson11_serializeOpDeleteResourcePolicy) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeleteResourcePolicy) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeleteResourcePolicyInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeleteResourcePolicy") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeleteResourcePolicyInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeregisterManagedInstance struct { -} - -func (*awsAwsjson11_serializeOpDeregisterManagedInstance) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeregisterManagedInstance) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeregisterManagedInstanceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeregisterManagedInstance") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeregisterManagedInstanceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeregisterPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_serializeOpDeregisterPatchBaselineForPatchGroup) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeregisterPatchBaselineForPatchGroup) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeregisterPatchBaselineForPatchGroupInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeregisterPatchBaselineForPatchGroup") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeregisterPatchBaselineForPatchGroupInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeregisterTargetFromMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpDeregisterTargetFromMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeregisterTargetFromMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeregisterTargetFromMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeregisterTargetFromMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeregisterTargetFromMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDeregisterTaskFromMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpDeregisterTaskFromMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDeregisterTaskFromMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DeregisterTaskFromMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DeregisterTaskFromMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDeregisterTaskFromMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeActivations struct { -} - -func (*awsAwsjson11_serializeOpDescribeActivations) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeActivations) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeActivationsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeActivations") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeActivationsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAssociation struct { -} - -func (*awsAwsjson11_serializeOpDescribeAssociation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAssociation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAssociationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAssociation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAssociationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAssociationExecutions struct { -} - -func (*awsAwsjson11_serializeOpDescribeAssociationExecutions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAssociationExecutions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAssociationExecutionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAssociationExecutions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAssociationExecutionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAssociationExecutionTargets struct { -} - -func (*awsAwsjson11_serializeOpDescribeAssociationExecutionTargets) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAssociationExecutionTargets) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAssociationExecutionTargetsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAssociationExecutionTargets") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAssociationExecutionTargetsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAutomationExecutions struct { -} - -func (*awsAwsjson11_serializeOpDescribeAutomationExecutions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAutomationExecutions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAutomationExecutionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAutomationExecutions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAutomationExecutionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAutomationStepExecutions struct { -} - -func (*awsAwsjson11_serializeOpDescribeAutomationStepExecutions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAutomationStepExecutions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAutomationStepExecutionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAutomationStepExecutions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAutomationStepExecutionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeAvailablePatches struct { -} - -func (*awsAwsjson11_serializeOpDescribeAvailablePatches) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeAvailablePatches) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeAvailablePatchesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeAvailablePatches") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeAvailablePatchesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeDocument struct { -} - -func (*awsAwsjson11_serializeOpDescribeDocument) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeDocument) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeDocumentInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeDocument") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeDocumentInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeDocumentPermission struct { -} - -func (*awsAwsjson11_serializeOpDescribeDocumentPermission) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeDocumentPermission) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeDocumentPermissionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeDocumentPermission") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeDocumentPermissionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeEffectiveInstanceAssociations struct { -} - -func (*awsAwsjson11_serializeOpDescribeEffectiveInstanceAssociations) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeEffectiveInstanceAssociations) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeEffectiveInstanceAssociationsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeEffectiveInstanceAssociations") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeEffectiveInstanceAssociationsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeEffectivePatchesForPatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpDescribeEffectivePatchesForPatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeEffectivePatchesForPatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeEffectivePatchesForPatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeEffectivePatchesForPatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeEffectivePatchesForPatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInstanceAssociationsStatus struct { -} - -func (*awsAwsjson11_serializeOpDescribeInstanceAssociationsStatus) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInstanceAssociationsStatus) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInstanceAssociationsStatusInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInstanceAssociationsStatus") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInstanceAssociationsStatusInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInstanceInformation struct { -} - -func (*awsAwsjson11_serializeOpDescribeInstanceInformation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInstanceInformation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInstanceInformationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInstanceInformation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInstanceInformationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInstancePatches struct { -} - -func (*awsAwsjson11_serializeOpDescribeInstancePatches) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInstancePatches) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInstancePatchesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInstancePatches") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInstancePatchesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInstancePatchStates struct { -} - -func (*awsAwsjson11_serializeOpDescribeInstancePatchStates) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInstancePatchStates) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInstancePatchStatesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInstancePatchStates") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInstancePatchStatesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInstancePatchStatesForPatchGroup struct { -} - -func (*awsAwsjson11_serializeOpDescribeInstancePatchStatesForPatchGroup) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInstancePatchStatesForPatchGroup) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInstancePatchStatesForPatchGroupInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInstancePatchStatesForPatchGroup") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInstancePatchStatesForPatchGroupInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeInventoryDeletions struct { -} - -func (*awsAwsjson11_serializeOpDescribeInventoryDeletions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeInventoryDeletions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeInventoryDeletionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeInventoryDeletions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeInventoryDeletionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutions struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowExecutions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTaskInvocations struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTaskInvocations) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTaskInvocations) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionTaskInvocationsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowExecutionTaskInvocations") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionTaskInvocationsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTasks struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTasks) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowExecutionTasks) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionTasksInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowExecutionTasks") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionTasksInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindows struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindows) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindows) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindows") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowSchedule struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowSchedule) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowSchedule) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowScheduleInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowSchedule") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowScheduleInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowsForTarget struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowsForTarget) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowsForTarget) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowsForTargetInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowsForTarget") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowsForTargetInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowTargets struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowTargets) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowTargets) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowTargetsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowTargets") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowTargetsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeMaintenanceWindowTasks struct { -} - -func (*awsAwsjson11_serializeOpDescribeMaintenanceWindowTasks) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeMaintenanceWindowTasks) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeMaintenanceWindowTasksInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeMaintenanceWindowTasks") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowTasksInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeOpsItems struct { -} - -func (*awsAwsjson11_serializeOpDescribeOpsItems) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeOpsItems) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeOpsItemsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeOpsItems") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeOpsItemsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeParameters struct { -} - -func (*awsAwsjson11_serializeOpDescribeParameters) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeParameters) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeParametersInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeParameters") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeParametersInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribePatchBaselines struct { -} - -func (*awsAwsjson11_serializeOpDescribePatchBaselines) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribePatchBaselines) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribePatchBaselinesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribePatchBaselines") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribePatchBaselinesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribePatchGroups struct { -} - -func (*awsAwsjson11_serializeOpDescribePatchGroups) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribePatchGroups) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribePatchGroupsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribePatchGroups") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribePatchGroupsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribePatchGroupState struct { -} - -func (*awsAwsjson11_serializeOpDescribePatchGroupState) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribePatchGroupState) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribePatchGroupStateInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribePatchGroupState") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribePatchGroupStateInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribePatchProperties struct { -} - -func (*awsAwsjson11_serializeOpDescribePatchProperties) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribePatchProperties) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribePatchPropertiesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribePatchProperties") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribePatchPropertiesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDescribeSessions struct { -} - -func (*awsAwsjson11_serializeOpDescribeSessions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDescribeSessions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DescribeSessionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DescribeSessions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDescribeSessionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpDisassociateOpsItemRelatedItem struct { -} - -func (*awsAwsjson11_serializeOpDisassociateOpsItemRelatedItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpDisassociateOpsItemRelatedItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DisassociateOpsItemRelatedItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.DisassociateOpsItemRelatedItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentDisassociateOpsItemRelatedItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetAutomationExecution struct { -} - -func (*awsAwsjson11_serializeOpGetAutomationExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetAutomationExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetAutomationExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetAutomationExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetAutomationExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetCalendarState struct { -} - -func (*awsAwsjson11_serializeOpGetCalendarState) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetCalendarState) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetCalendarStateInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetCalendarState") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetCalendarStateInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetCommandInvocation struct { -} - -func (*awsAwsjson11_serializeOpGetCommandInvocation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetCommandInvocation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetCommandInvocationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetCommandInvocation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetCommandInvocationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetConnectionStatus struct { -} - -func (*awsAwsjson11_serializeOpGetConnectionStatus) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetConnectionStatus) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetConnectionStatusInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetConnectionStatus") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetConnectionStatusInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetDefaultPatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpGetDefaultPatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetDefaultPatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetDefaultPatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetDefaultPatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetDefaultPatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetDeployablePatchSnapshotForInstance struct { -} - -func (*awsAwsjson11_serializeOpGetDeployablePatchSnapshotForInstance) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetDeployablePatchSnapshotForInstance) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetDeployablePatchSnapshotForInstanceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetDeployablePatchSnapshotForInstance") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetDeployablePatchSnapshotForInstanceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetDocument struct { -} - -func (*awsAwsjson11_serializeOpGetDocument) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetDocument) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetDocumentInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetDocument") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetDocumentInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetInventory struct { -} - -func (*awsAwsjson11_serializeOpGetInventory) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetInventory) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetInventoryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetInventory") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetInventoryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetInventorySchema struct { -} - -func (*awsAwsjson11_serializeOpGetInventorySchema) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetInventorySchema) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetInventorySchemaInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetInventorySchema") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetInventorySchemaInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpGetMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetMaintenanceWindowExecution struct { -} - -func (*awsAwsjson11_serializeOpGetMaintenanceWindowExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetMaintenanceWindowExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetMaintenanceWindowExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTask struct { -} - -func (*awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTask) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTask) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionTaskInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetMaintenanceWindowExecutionTask") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionTaskInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTaskInvocation struct { -} - -func (*awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTaskInvocation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetMaintenanceWindowExecutionTaskInvocation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionTaskInvocationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetMaintenanceWindowExecutionTaskInvocation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionTaskInvocationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetMaintenanceWindowTask struct { -} - -func (*awsAwsjson11_serializeOpGetMaintenanceWindowTask) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetMaintenanceWindowTask) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetMaintenanceWindowTaskInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetMaintenanceWindowTask") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetMaintenanceWindowTaskInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetOpsItem struct { -} - -func (*awsAwsjson11_serializeOpGetOpsItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetOpsItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetOpsItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetOpsItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetOpsItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetOpsMetadata struct { -} - -func (*awsAwsjson11_serializeOpGetOpsMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetOpsMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetOpsMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetOpsMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetOpsMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetOpsSummary struct { -} - -func (*awsAwsjson11_serializeOpGetOpsSummary) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetOpsSummary) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetOpsSummaryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetOpsSummary") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetOpsSummaryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetParameter struct { -} - -func (*awsAwsjson11_serializeOpGetParameter) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetParameter) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetParameterInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetParameter") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetParameterInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetParameterHistory struct { -} - -func (*awsAwsjson11_serializeOpGetParameterHistory) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetParameterHistory) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetParameterHistoryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetParameterHistory") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetParameterHistoryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetParameters struct { -} - -func (*awsAwsjson11_serializeOpGetParameters) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetParameters) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetParametersInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetParameters") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetParametersInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetParametersByPath struct { -} - -func (*awsAwsjson11_serializeOpGetParametersByPath) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetParametersByPath) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetParametersByPathInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetParametersByPath") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetParametersByPathInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetPatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpGetPatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetPatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetPatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetPatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetPatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_serializeOpGetPatchBaselineForPatchGroup) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetPatchBaselineForPatchGroup) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetPatchBaselineForPatchGroupInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetPatchBaselineForPatchGroup") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetPatchBaselineForPatchGroupInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetResourcePolicies struct { -} - -func (*awsAwsjson11_serializeOpGetResourcePolicies) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetResourcePolicies) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetResourcePoliciesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetResourcePolicies") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetResourcePoliciesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpGetServiceSetting struct { -} - -func (*awsAwsjson11_serializeOpGetServiceSetting) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpGetServiceSetting) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetServiceSettingInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.GetServiceSetting") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentGetServiceSettingInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpLabelParameterVersion struct { -} - -func (*awsAwsjson11_serializeOpLabelParameterVersion) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpLabelParameterVersion) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*LabelParameterVersionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.LabelParameterVersion") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentLabelParameterVersionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListAssociations struct { -} - -func (*awsAwsjson11_serializeOpListAssociations) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListAssociations) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListAssociationsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListAssociations") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListAssociationsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListAssociationVersions struct { -} - -func (*awsAwsjson11_serializeOpListAssociationVersions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListAssociationVersions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListAssociationVersionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListAssociationVersions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListAssociationVersionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListCommandInvocations struct { -} - -func (*awsAwsjson11_serializeOpListCommandInvocations) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListCommandInvocations) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListCommandInvocationsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListCommandInvocations") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListCommandInvocationsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListCommands struct { -} - -func (*awsAwsjson11_serializeOpListCommands) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListCommands) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListCommandsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListCommands") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListCommandsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListComplianceItems struct { -} - -func (*awsAwsjson11_serializeOpListComplianceItems) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListComplianceItems) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListComplianceItemsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListComplianceItems") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListComplianceItemsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListComplianceSummaries struct { -} - -func (*awsAwsjson11_serializeOpListComplianceSummaries) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListComplianceSummaries) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListComplianceSummariesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListComplianceSummaries") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListComplianceSummariesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListDocumentMetadataHistory struct { -} - -func (*awsAwsjson11_serializeOpListDocumentMetadataHistory) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListDocumentMetadataHistory) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListDocumentMetadataHistoryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListDocumentMetadataHistory") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListDocumentMetadataHistoryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListDocuments struct { -} - -func (*awsAwsjson11_serializeOpListDocuments) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListDocuments) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListDocumentsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListDocuments") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListDocumentsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListDocumentVersions struct { -} - -func (*awsAwsjson11_serializeOpListDocumentVersions) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListDocumentVersions) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListDocumentVersionsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListDocumentVersions") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListDocumentVersionsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListInventoryEntries struct { -} - -func (*awsAwsjson11_serializeOpListInventoryEntries) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListInventoryEntries) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListInventoryEntriesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListInventoryEntries") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListInventoryEntriesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListOpsItemEvents struct { -} - -func (*awsAwsjson11_serializeOpListOpsItemEvents) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListOpsItemEvents) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListOpsItemEventsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListOpsItemEvents") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListOpsItemEventsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListOpsItemRelatedItems struct { -} - -func (*awsAwsjson11_serializeOpListOpsItemRelatedItems) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListOpsItemRelatedItems) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListOpsItemRelatedItemsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListOpsItemRelatedItems") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListOpsItemRelatedItemsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListOpsMetadata struct { -} - -func (*awsAwsjson11_serializeOpListOpsMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListOpsMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListOpsMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListOpsMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListOpsMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListResourceComplianceSummaries struct { -} - -func (*awsAwsjson11_serializeOpListResourceComplianceSummaries) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListResourceComplianceSummaries) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListResourceComplianceSummariesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListResourceComplianceSummaries") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListResourceComplianceSummariesInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListResourceDataSync struct { -} - -func (*awsAwsjson11_serializeOpListResourceDataSync) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListResourceDataSync) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListResourceDataSyncInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListResourceDataSync") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListResourceDataSyncInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpListTagsForResource struct { -} - -func (*awsAwsjson11_serializeOpListTagsForResource) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpListTagsForResource) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListTagsForResourceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ListTagsForResource") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentListTagsForResourceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpModifyDocumentPermission struct { -} - -func (*awsAwsjson11_serializeOpModifyDocumentPermission) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpModifyDocumentPermission) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ModifyDocumentPermissionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ModifyDocumentPermission") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentModifyDocumentPermissionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpPutComplianceItems struct { -} - -func (*awsAwsjson11_serializeOpPutComplianceItems) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpPutComplianceItems) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*PutComplianceItemsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.PutComplianceItems") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentPutComplianceItemsInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpPutInventory struct { -} - -func (*awsAwsjson11_serializeOpPutInventory) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpPutInventory) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*PutInventoryInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.PutInventory") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentPutInventoryInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpPutParameter struct { -} - -func (*awsAwsjson11_serializeOpPutParameter) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpPutParameter) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*PutParameterInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.PutParameter") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentPutParameterInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpPutResourcePolicy struct { -} - -func (*awsAwsjson11_serializeOpPutResourcePolicy) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpPutResourcePolicy) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*PutResourcePolicyInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.PutResourcePolicy") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentPutResourcePolicyInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpRegisterDefaultPatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpRegisterDefaultPatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpRegisterDefaultPatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RegisterDefaultPatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.RegisterDefaultPatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentRegisterDefaultPatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpRegisterPatchBaselineForPatchGroup struct { -} - -func (*awsAwsjson11_serializeOpRegisterPatchBaselineForPatchGroup) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpRegisterPatchBaselineForPatchGroup) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RegisterPatchBaselineForPatchGroupInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.RegisterPatchBaselineForPatchGroup") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentRegisterPatchBaselineForPatchGroupInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpRegisterTargetWithMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpRegisterTargetWithMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpRegisterTargetWithMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RegisterTargetWithMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.RegisterTargetWithMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentRegisterTargetWithMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpRegisterTaskWithMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpRegisterTaskWithMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpRegisterTaskWithMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RegisterTaskWithMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.RegisterTaskWithMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentRegisterTaskWithMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpRemoveTagsFromResource struct { -} - -func (*awsAwsjson11_serializeOpRemoveTagsFromResource) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpRemoveTagsFromResource) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RemoveTagsFromResourceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.RemoveTagsFromResource") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentRemoveTagsFromResourceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpResetServiceSetting struct { -} - -func (*awsAwsjson11_serializeOpResetServiceSetting) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpResetServiceSetting) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ResetServiceSettingInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ResetServiceSetting") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentResetServiceSettingInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpResumeSession struct { -} - -func (*awsAwsjson11_serializeOpResumeSession) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpResumeSession) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ResumeSessionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.ResumeSession") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentResumeSessionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpSendAutomationSignal struct { -} - -func (*awsAwsjson11_serializeOpSendAutomationSignal) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpSendAutomationSignal) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*SendAutomationSignalInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.SendAutomationSignal") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentSendAutomationSignalInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpSendCommand struct { -} - -func (*awsAwsjson11_serializeOpSendCommand) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpSendCommand) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*SendCommandInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.SendCommand") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentSendCommandInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpStartAssociationsOnce struct { -} - -func (*awsAwsjson11_serializeOpStartAssociationsOnce) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpStartAssociationsOnce) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StartAssociationsOnceInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.StartAssociationsOnce") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentStartAssociationsOnceInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpStartAutomationExecution struct { -} - -func (*awsAwsjson11_serializeOpStartAutomationExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpStartAutomationExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StartAutomationExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.StartAutomationExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentStartAutomationExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpStartChangeRequestExecution struct { -} - -func (*awsAwsjson11_serializeOpStartChangeRequestExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpStartChangeRequestExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StartChangeRequestExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.StartChangeRequestExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentStartChangeRequestExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpStartSession struct { -} - -func (*awsAwsjson11_serializeOpStartSession) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpStartSession) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StartSessionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.StartSession") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentStartSessionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpStopAutomationExecution struct { -} - -func (*awsAwsjson11_serializeOpStopAutomationExecution) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpStopAutomationExecution) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StopAutomationExecutionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.StopAutomationExecution") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentStopAutomationExecutionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpTerminateSession struct { -} - -func (*awsAwsjson11_serializeOpTerminateSession) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpTerminateSession) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*TerminateSessionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.TerminateSession") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentTerminateSessionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUnlabelParameterVersion struct { -} - -func (*awsAwsjson11_serializeOpUnlabelParameterVersion) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUnlabelParameterVersion) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UnlabelParameterVersionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UnlabelParameterVersion") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUnlabelParameterVersionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateAssociation struct { -} - -func (*awsAwsjson11_serializeOpUpdateAssociation) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateAssociation) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateAssociationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateAssociation") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateAssociationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateAssociationStatus struct { -} - -func (*awsAwsjson11_serializeOpUpdateAssociationStatus) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateAssociationStatus) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateAssociationStatusInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateAssociationStatus") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateAssociationStatusInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateDocument struct { -} - -func (*awsAwsjson11_serializeOpUpdateDocument) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateDocument) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateDocumentInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateDocument") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateDocumentInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateDocumentDefaultVersion struct { -} - -func (*awsAwsjson11_serializeOpUpdateDocumentDefaultVersion) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateDocumentDefaultVersion) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateDocumentDefaultVersionInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateDocumentDefaultVersion") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateDocumentDefaultVersionInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateDocumentMetadata struct { -} - -func (*awsAwsjson11_serializeOpUpdateDocumentMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateDocumentMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateDocumentMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateDocumentMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateDocumentMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateMaintenanceWindow struct { -} - -func (*awsAwsjson11_serializeOpUpdateMaintenanceWindow) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateMaintenanceWindow) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateMaintenanceWindowInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateMaintenanceWindow") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateMaintenanceWindowTarget struct { -} - -func (*awsAwsjson11_serializeOpUpdateMaintenanceWindowTarget) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateMaintenanceWindowTarget) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateMaintenanceWindowTargetInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateMaintenanceWindowTarget") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowTargetInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateMaintenanceWindowTask struct { -} - -func (*awsAwsjson11_serializeOpUpdateMaintenanceWindowTask) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateMaintenanceWindowTask) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateMaintenanceWindowTaskInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateMaintenanceWindowTask") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowTaskInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateManagedInstanceRole struct { -} - -func (*awsAwsjson11_serializeOpUpdateManagedInstanceRole) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateManagedInstanceRole) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateManagedInstanceRoleInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateManagedInstanceRole") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateManagedInstanceRoleInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateOpsItem struct { -} - -func (*awsAwsjson11_serializeOpUpdateOpsItem) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateOpsItem) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateOpsItemInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateOpsItem") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateOpsItemInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateOpsMetadata struct { -} - -func (*awsAwsjson11_serializeOpUpdateOpsMetadata) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateOpsMetadata) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateOpsMetadataInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateOpsMetadata") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateOpsMetadataInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdatePatchBaseline struct { -} - -func (*awsAwsjson11_serializeOpUpdatePatchBaseline) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdatePatchBaseline) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdatePatchBaselineInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdatePatchBaseline") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdatePatchBaselineInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateResourceDataSync struct { -} - -func (*awsAwsjson11_serializeOpUpdateResourceDataSync) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateResourceDataSync) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateResourceDataSyncInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateResourceDataSync") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateResourceDataSyncInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} - -type awsAwsjson11_serializeOpUpdateServiceSetting struct { -} - -func (*awsAwsjson11_serializeOpUpdateServiceSetting) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsjson11_serializeOpUpdateServiceSetting) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*UpdateServiceSettingInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") - httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonSSM.UpdateServiceSetting") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsAwsjson11_serializeOpDocumentUpdateServiceSettingInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - return next.HandleSerialize(ctx, in) -} -func awsAwsjson11_serializeDocumentAccountIdList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentAccounts(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentAlarm(v *types.Alarm, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAlarmConfiguration(v *types.AlarmConfiguration, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Alarms != nil { - ok := object.Key("Alarms") - if err := awsAwsjson11_serializeDocumentAlarmList(v.Alarms, ok); err != nil { - return err - } - } - - if v.IgnorePollAlarmFailure { - ok := object.Key("IgnorePollAlarmFailure") - ok.Boolean(v.IgnorePollAlarmFailure) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAlarmList(v []types.Alarm, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAlarm(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAssociationExecutionFilter(v *types.AssociationExecutionFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAssociationExecutionFilterList(v []types.AssociationExecutionFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAssociationExecutionFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAssociationExecutionTargetsFilter(v *types.AssociationExecutionTargetsFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAssociationExecutionTargetsFilterList(v []types.AssociationExecutionTargetsFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAssociationExecutionTargetsFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAssociationFilter(v *types.AssociationFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("key") - ok.String(string(v.Key)) - } - - if v.Value != nil { - ok := object.Key("value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAssociationFilterList(v []types.AssociationFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAssociationFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAssociationIdList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentAssociationStatus(v *types.AssociationStatus, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AdditionalInfo != nil { - ok := object.Key("AdditionalInfo") - ok.String(*v.AdditionalInfo) - } - - if v.Date != nil { - ok := object.Key("Date") - ok.Double(smithytime.FormatEpochSeconds(*v.Date)) - } - - if v.Message != nil { - ok := object.Key("Message") - ok.String(*v.Message) - } - - if len(v.Name) > 0 { - ok := object.Key("Name") - ok.String(string(v.Name)) - } - - return nil -} - -func awsAwsjson11_serializeDocumentAttachmentsSource(v *types.AttachmentsSource, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentAttachmentsSourceValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentAttachmentsSourceList(v []types.AttachmentsSource, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAttachmentsSource(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAttachmentsSourceValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentAutomationExecutionFilter(v *types.AutomationExecutionFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentAutomationExecutionFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentAutomationExecutionFilterList(v []types.AutomationExecutionFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentAutomationExecutionFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAutomationExecutionFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentAutomationParameterMap(v map[string][]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - if vv := v[key]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentAutomationParameterValueList(v[key], om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentAutomationParameterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentBaselineOverride(v *types.BaselineOverride, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ApprovalRules != nil { - ok := object.Key("ApprovalRules") - if err := awsAwsjson11_serializeDocumentPatchRuleGroup(v.ApprovalRules, ok); err != nil { - return err - } - } - - if v.ApprovedPatches != nil { - ok := object.Key("ApprovedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.ApprovedPatches, ok); err != nil { - return err - } - } - - if len(v.ApprovedPatchesComplianceLevel) > 0 { - ok := object.Key("ApprovedPatchesComplianceLevel") - ok.String(string(v.ApprovedPatchesComplianceLevel)) - } - - if v.ApprovedPatchesEnableNonSecurity { - ok := object.Key("ApprovedPatchesEnableNonSecurity") - ok.Boolean(v.ApprovedPatchesEnableNonSecurity) - } - - if v.GlobalFilters != nil { - ok := object.Key("GlobalFilters") - if err := awsAwsjson11_serializeDocumentPatchFilterGroup(v.GlobalFilters, ok); err != nil { - return err - } - } - - if len(v.OperatingSystem) > 0 { - ok := object.Key("OperatingSystem") - ok.String(string(v.OperatingSystem)) - } - - if v.RejectedPatches != nil { - ok := object.Key("RejectedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.RejectedPatches, ok); err != nil { - return err - } - } - - if len(v.RejectedPatchesAction) > 0 { - ok := object.Key("RejectedPatchesAction") - ok.String(string(v.RejectedPatchesAction)) - } - - if v.Sources != nil { - ok := object.Key("Sources") - if err := awsAwsjson11_serializeDocumentPatchSourceList(v.Sources, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentCalendarNameOrARNList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentCloudWatchOutputConfig(v *types.CloudWatchOutputConfig, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CloudWatchLogGroupName != nil { - ok := object.Key("CloudWatchLogGroupName") - ok.String(*v.CloudWatchLogGroupName) - } - - if v.CloudWatchOutputEnabled { - ok := object.Key("CloudWatchOutputEnabled") - ok.Boolean(v.CloudWatchOutputEnabled) - } - - return nil -} - -func awsAwsjson11_serializeDocumentCommandFilter(v *types.CommandFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("key") - ok.String(string(v.Key)) - } - - if v.Value != nil { - ok := object.Key("value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentCommandFilterList(v []types.CommandFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentCommandFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceExecutionSummary(v *types.ComplianceExecutionSummary, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ExecutionId != nil { - ok := object.Key("ExecutionId") - ok.String(*v.ExecutionId) - } - - if v.ExecutionTime != nil { - ok := object.Key("ExecutionTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ExecutionTime)) - } - - if v.ExecutionType != nil { - ok := object.Key("ExecutionType") - ok.String(*v.ExecutionType) - } - - return nil -} - -func awsAwsjson11_serializeDocumentComplianceItemDetails(v map[string]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - om.String(v[key]) - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceItemEntry(v *types.ComplianceItemEntry, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Details != nil { - ok := object.Key("Details") - if err := awsAwsjson11_serializeDocumentComplianceItemDetails(v.Details, ok); err != nil { - return err - } - } - - if v.Id != nil { - ok := object.Key("Id") - ok.String(*v.Id) - } - - if len(v.Severity) > 0 { - ok := object.Key("Severity") - ok.String(string(v.Severity)) - } - - if len(v.Status) > 0 { - ok := object.Key("Status") - ok.String(string(v.Status)) - } - - if v.Title != nil { - ok := object.Key("Title") - ok.String(*v.Title) - } - - return nil -} - -func awsAwsjson11_serializeDocumentComplianceItemEntryList(v []types.ComplianceItemEntry, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentComplianceItemEntry(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceResourceIdList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceResourceTypeList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceStringFilter(v *types.ComplianceStringFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentComplianceStringFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentComplianceStringFilterList(v []types.ComplianceStringFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentComplianceStringFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentComplianceStringFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentCreateAssociationBatchRequestEntries(v []types.CreateAssociationBatchRequestEntry, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentCreateAssociationBatchRequestEntry(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentCreateAssociationBatchRequestEntry(v *types.CreateAssociationBatchRequestEntry, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.ApplyOnlyAtCronInterval { - ok := object.Key("ApplyOnlyAtCronInterval") - ok.Boolean(v.ApplyOnlyAtCronInterval) - } - - if v.AssociationName != nil { - ok := object.Key("AssociationName") - ok.String(*v.AssociationName) - } - - if v.AutomationTargetParameterName != nil { - ok := object.Key("AutomationTargetParameterName") - ok.String(*v.AutomationTargetParameterName) - } - - if v.CalendarNames != nil { - ok := object.Key("CalendarNames") - if err := awsAwsjson11_serializeDocumentCalendarNameOrARNList(v.CalendarNames, ok); err != nil { - return err - } - } - - if len(v.ComplianceSeverity) > 0 { - ok := object.Key("ComplianceSeverity") - ok.String(string(v.ComplianceSeverity)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.OutputLocation != nil { - ok := object.Key("OutputLocation") - if err := awsAwsjson11_serializeDocumentInstanceAssociationOutputLocation(v.OutputLocation, ok); err != nil { - return err - } - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.ScheduleExpression != nil { - ok := object.Key("ScheduleExpression") - ok.String(*v.ScheduleExpression) - } - - if v.ScheduleOffset != nil { - ok := object.Key("ScheduleOffset") - ok.Integer(*v.ScheduleOffset) - } - - if len(v.SyncCompliance) > 0 { - ok := object.Key("SyncCompliance") - ok.String(string(v.SyncCompliance)) - } - - if v.TargetLocations != nil { - ok := object.Key("TargetLocations") - if err := awsAwsjson11_serializeDocumentTargetLocations(v.TargetLocations, ok); err != nil { - return err - } - } - - if v.TargetMaps != nil { - ok := object.Key("TargetMaps") - if err := awsAwsjson11_serializeDocumentTargetMaps(v.TargetMaps, ok); err != nil { - return err - } - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentDescribeActivationsFilter(v *types.DescribeActivationsFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.FilterKey) > 0 { - ok := object.Key("FilterKey") - ok.String(string(v.FilterKey)) - } - - if v.FilterValues != nil { - ok := object.Key("FilterValues") - if err := awsAwsjson11_serializeDocumentStringList(v.FilterValues, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentDescribeActivationsFilterList(v []types.DescribeActivationsFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentDescribeActivationsFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentFilter(v *types.DocumentFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("key") - ok.String(string(v.Key)) - } - - if v.Value != nil { - ok := object.Key("value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentDocumentFilterList(v []types.DocumentFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentDocumentFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentKeyValuesFilter(v *types.DocumentKeyValuesFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentDocumentKeyValuesFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentDocumentKeyValuesFilterList(v []types.DocumentKeyValuesFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentDocumentKeyValuesFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentKeyValuesFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentRequires(v *types.DocumentRequires, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.RequireType != nil { - ok := object.Key("RequireType") - ok.String(*v.RequireType) - } - - if v.Version != nil { - ok := object.Key("Version") - ok.String(*v.Version) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeDocumentDocumentRequiresList(v []types.DocumentRequires, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentDocumentRequires(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentReviewCommentList(v []types.DocumentReviewCommentSource, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentDocumentReviewCommentSource(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentDocumentReviewCommentSource(v *types.DocumentReviewCommentSource, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Content != nil { - ok := object.Key("Content") - ok.String(*v.Content) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - return nil -} - -func awsAwsjson11_serializeDocumentDocumentReviews(v *types.DocumentReviews, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Action) > 0 { - ok := object.Key("Action") - ok.String(string(v.Action)) - } - - if v.Comment != nil { - ok := object.Key("Comment") - if err := awsAwsjson11_serializeDocumentDocumentReviewCommentList(v.Comment, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInstanceAssociationOutputLocation(v *types.InstanceAssociationOutputLocation, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.S3Location != nil { - ok := object.Key("S3Location") - if err := awsAwsjson11_serializeDocumentS3OutputLocation(v.S3Location, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInstanceIdList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInstanceInformationFilter(v *types.InstanceInformationFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("key") - ok.String(string(v.Key)) - } - - if v.ValueSet != nil { - ok := object.Key("valueSet") - if err := awsAwsjson11_serializeDocumentInstanceInformationFilterValueSet(v.ValueSet, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInstanceInformationFilterList(v []types.InstanceInformationFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInstanceInformationFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInstanceInformationFilterValueSet(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInstanceInformationStringFilter(v *types.InstanceInformationStringFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentInstanceInformationFilterValueSet(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInstanceInformationStringFilterList(v []types.InstanceInformationStringFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInstanceInformationStringFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInstancePatchStateFilter(v *types.InstancePatchStateFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentInstancePatchStateFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInstancePatchStateFilterList(v []types.InstancePatchStateFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInstancePatchStateFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInstancePatchStateFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryAggregator(v *types.InventoryAggregator, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Aggregators != nil { - ok := object.Key("Aggregators") - if err := awsAwsjson11_serializeDocumentInventoryAggregatorList(v.Aggregators, ok); err != nil { - return err - } - } - - if v.Expression != nil { - ok := object.Key("Expression") - ok.String(*v.Expression) - } - - if v.Groups != nil { - ok := object.Key("Groups") - if err := awsAwsjson11_serializeDocumentInventoryGroupList(v.Groups, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInventoryAggregatorList(v []types.InventoryAggregator, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInventoryAggregator(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryFilter(v *types.InventoryFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentInventoryFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentInventoryFilterList(v []types.InventoryFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInventoryFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryGroup(v *types.InventoryGroup, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentInventoryFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeDocumentInventoryGroupList(v []types.InventoryGroup, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInventoryGroup(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryItem(v *types.InventoryItem, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CaptureTime != nil { - ok := object.Key("CaptureTime") - ok.String(*v.CaptureTime) - } - - if v.Content != nil { - ok := object.Key("Content") - if err := awsAwsjson11_serializeDocumentInventoryItemEntryList(v.Content, ok); err != nil { - return err - } - } - - if v.ContentHash != nil { - ok := object.Key("ContentHash") - ok.String(*v.ContentHash) - } - - if v.Context != nil { - ok := object.Key("Context") - if err := awsAwsjson11_serializeDocumentInventoryItemContentContext(v.Context, ok); err != nil { - return err - } - } - - if v.SchemaVersion != nil { - ok := object.Key("SchemaVersion") - ok.String(*v.SchemaVersion) - } - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeDocumentInventoryItemContentContext(v map[string]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - om.String(v[key]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryItemEntry(v map[string]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - om.String(v[key]) - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryItemEntryList(v []map[string]string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if vv := v[i]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentInventoryItemEntry(v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentInventoryItemList(v []types.InventoryItem, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentInventoryItem(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentKeyList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentLoggingInfo(v *types.LoggingInfo, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.S3BucketName != nil { - ok := object.Key("S3BucketName") - ok.String(*v.S3BucketName) - } - - if v.S3KeyPrefix != nil { - ok := object.Key("S3KeyPrefix") - ok.String(*v.S3KeyPrefix) - } - - if v.S3Region != nil { - ok := object.Key("S3Region") - ok.String(*v.S3Region) - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowAutomationParameters(v *types.MaintenanceWindowAutomationParameters, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentAutomationParameterMap(v.Parameters, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowFilter(v *types.MaintenanceWindowFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v []types.MaintenanceWindowFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowLambdaParameters(v *types.MaintenanceWindowLambdaParameters, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientContext != nil { - ok := object.Key("ClientContext") - ok.String(*v.ClientContext) - } - - if v.Payload != nil { - ok := object.Key("Payload") - ok.Base64EncodeBytes(v.Payload) - } - - if v.Qualifier != nil { - ok := object.Key("Qualifier") - ok.String(*v.Qualifier) - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowRunCommandParameters(v *types.MaintenanceWindowRunCommandParameters, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CloudWatchOutputConfig != nil { - ok := object.Key("CloudWatchOutputConfig") - if err := awsAwsjson11_serializeDocumentCloudWatchOutputConfig(v.CloudWatchOutputConfig, ok); err != nil { - return err - } - } - - if v.Comment != nil { - ok := object.Key("Comment") - ok.String(*v.Comment) - } - - if v.DocumentHash != nil { - ok := object.Key("DocumentHash") - ok.String(*v.DocumentHash) - } - - if len(v.DocumentHashType) > 0 { - ok := object.Key("DocumentHashType") - ok.String(string(v.DocumentHashType)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.NotificationConfig != nil { - ok := object.Key("NotificationConfig") - if err := awsAwsjson11_serializeDocumentNotificationConfig(v.NotificationConfig, ok); err != nil { - return err - } - } - - if v.OutputS3BucketName != nil { - ok := object.Key("OutputS3BucketName") - ok.String(*v.OutputS3BucketName) - } - - if v.OutputS3KeyPrefix != nil { - ok := object.Key("OutputS3KeyPrefix") - ok.String(*v.OutputS3KeyPrefix) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.ServiceRoleArn != nil { - ok := object.Key("ServiceRoleArn") - ok.String(*v.ServiceRoleArn) - } - - if v.TimeoutSeconds != nil { - ok := object.Key("TimeoutSeconds") - ok.Integer(*v.TimeoutSeconds) - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowStepFunctionsParameters(v *types.MaintenanceWindowStepFunctionsParameters, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Input != nil { - ok := object.Key("Input") - ok.String(*v.Input) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowTaskInvocationParameters(v *types.MaintenanceWindowTaskInvocationParameters, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Automation != nil { - ok := object.Key("Automation") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowAutomationParameters(v.Automation, ok); err != nil { - return err - } - } - - if v.Lambda != nil { - ok := object.Key("Lambda") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowLambdaParameters(v.Lambda, ok); err != nil { - return err - } - } - - if v.RunCommand != nil { - ok := object.Key("RunCommand") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowRunCommandParameters(v.RunCommand, ok); err != nil { - return err - } - } - - if v.StepFunctions != nil { - ok := object.Key("StepFunctions") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowStepFunctionsParameters(v.StepFunctions, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameters(v map[string]types.MaintenanceWindowTaskParameterValueExpression, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - mapVar := v[key] - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameterValueExpression(&mapVar, om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameterValueExpression(v *types.MaintenanceWindowTaskParameterValueExpression, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentMetadataKeysToDeleteList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentMetadataMap(v map[string]types.MetadataValue, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - mapVar := v[key] - if err := awsAwsjson11_serializeDocumentMetadataValue(&mapVar, om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentMetadataValue(v *types.MetadataValue, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentNotificationConfig(v *types.NotificationConfig, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.NotificationArn != nil { - ok := object.Key("NotificationArn") - ok.String(*v.NotificationArn) - } - - if v.NotificationEvents != nil { - ok := object.Key("NotificationEvents") - if err := awsAwsjson11_serializeDocumentNotificationEventList(v.NotificationEvents, ok); err != nil { - return err - } - } - - if len(v.NotificationType) > 0 { - ok := object.Key("NotificationType") - ok.String(string(v.NotificationType)) - } - - return nil -} - -func awsAwsjson11_serializeDocumentNotificationEventList(v []types.NotificationEvent, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(string(v[i])) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsAggregator(v *types.OpsAggregator, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Aggregators != nil { - ok := object.Key("Aggregators") - if err := awsAwsjson11_serializeDocumentOpsAggregatorList(v.Aggregators, ok); err != nil { - return err - } - } - - if v.AggregatorType != nil { - ok := object.Key("AggregatorType") - ok.String(*v.AggregatorType) - } - - if v.AttributeName != nil { - ok := object.Key("AttributeName") - ok.String(*v.AttributeName) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentOpsFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsAggregatorValueMap(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsAggregatorList(v []types.OpsAggregator, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsAggregator(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsAggregatorValueMap(v map[string]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - om.String(v[key]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsFilter(v *types.OpsFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsFilterList(v []types.OpsFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemDataValue(v *types.OpsItemDataValue, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemEventFilter(v *types.OpsItemEventFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if len(v.Operator) > 0 { - ok := object.Key("Operator") - ok.String(string(v.Operator)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsItemEventFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemEventFilters(v []types.OpsItemEventFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsItemEventFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemEventFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemFilter(v *types.OpsItemFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if len(v.Operator) > 0 { - ok := object.Key("Operator") - ok.String(string(v.Operator)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsItemFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemFilters(v []types.OpsItemFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsItemFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemNotification(v *types.OpsItemNotification, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Arn != nil { - ok := object.Key("Arn") - ok.String(*v.Arn) - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemNotifications(v []types.OpsItemNotification, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsItemNotification(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemOperationalData(v map[string]types.OpsItemDataValue, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - mapVar := v[key] - if err := awsAwsjson11_serializeDocumentOpsItemDataValue(&mapVar, om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemOpsDataKeysList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilter(v *types.OpsItemRelatedItemsFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if len(v.Operator) > 0 { - ok := object.Key("Operator") - ok.String(string(v.Operator)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilters(v []types.OpsItemRelatedItemsFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsMetadataFilter(v *types.OpsMetadataFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentOpsMetadataFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsMetadataFilterList(v []types.OpsMetadataFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsMetadataFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsMetadataFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentOpsResultAttribute(v *types.OpsResultAttribute, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeDocumentOpsResultAttributeList(v []types.OpsResultAttribute, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentOpsResultAttribute(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentParameterLabelList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentParameterNameList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentParameters(v map[string][]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - if vv := v[key]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentParameterValueList(v[key], om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentParametersFilter(v *types.ParametersFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentParametersFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentParametersFilterList(v []types.ParametersFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentParametersFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentParametersFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentParameterStringFilter(v *types.ParameterStringFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Option != nil { - ok := object.Key("Option") - ok.String(*v.Option) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentParameterStringFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentParameterStringFilterList(v []types.ParameterStringFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentParameterStringFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentParameterStringFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentParameterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchFilter(v *types.PatchFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentPatchFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchFilterGroup(v *types.PatchFilterGroup, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.PatchFilters != nil { - ok := object.Key("PatchFilters") - if err := awsAwsjson11_serializeDocumentPatchFilterList(v.PatchFilters, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchFilterList(v []types.PatchFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentPatchFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchIdList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchOrchestratorFilter(v *types.PatchOrchestratorFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v []types.PatchOrchestratorFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchOrchestratorFilterValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchRule(v *types.PatchRule, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ApproveAfterDays != nil { - ok := object.Key("ApproveAfterDays") - ok.Integer(*v.ApproveAfterDays) - } - - if v.ApproveUntilDate != nil { - ok := object.Key("ApproveUntilDate") - ok.String(*v.ApproveUntilDate) - } - - if len(v.ComplianceLevel) > 0 { - ok := object.Key("ComplianceLevel") - ok.String(string(v.ComplianceLevel)) - } - - if v.EnableNonSecurity != nil { - ok := object.Key("EnableNonSecurity") - ok.Boolean(*v.EnableNonSecurity) - } - - if v.PatchFilterGroup != nil { - ok := object.Key("PatchFilterGroup") - if err := awsAwsjson11_serializeDocumentPatchFilterGroup(v.PatchFilterGroup, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchRuleGroup(v *types.PatchRuleGroup, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.PatchRules != nil { - ok := object.Key("PatchRules") - if err := awsAwsjson11_serializeDocumentPatchRuleList(v.PatchRules, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchRuleList(v []types.PatchRule, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentPatchRule(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchSource(v *types.PatchSource, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Configuration != nil { - ok := object.Key("Configuration") - ok.String(*v.Configuration) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Products != nil { - ok := object.Key("Products") - if err := awsAwsjson11_serializeDocumentPatchSourceProductList(v.Products, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentPatchSourceList(v []types.PatchSource, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentPatchSource(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentPatchSourceProductList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentRegions(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentRegistrationMetadataItem(v *types.RegistrationMetadataItem, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentRegistrationMetadataList(v []types.RegistrationMetadataItem, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentRegistrationMetadataItem(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentRelatedOpsItem(v *types.RelatedOpsItem, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - return nil -} - -func awsAwsjson11_serializeDocumentRelatedOpsItems(v []types.RelatedOpsItem, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentRelatedOpsItem(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncAwsOrganizationsSource(v *types.ResourceDataSyncAwsOrganizationsSource, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OrganizationalUnits != nil { - ok := object.Key("OrganizationalUnits") - if err := awsAwsjson11_serializeDocumentResourceDataSyncOrganizationalUnitList(v.OrganizationalUnits, ok); err != nil { - return err - } - } - - if v.OrganizationSourceType != nil { - ok := object.Key("OrganizationSourceType") - ok.String(*v.OrganizationSourceType) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncDestinationDataSharing(v *types.ResourceDataSyncDestinationDataSharing, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DestinationDataSharingType != nil { - ok := object.Key("DestinationDataSharingType") - ok.String(*v.DestinationDataSharingType) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncOrganizationalUnit(v *types.ResourceDataSyncOrganizationalUnit, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OrganizationalUnitId != nil { - ok := object.Key("OrganizationalUnitId") - ok.String(*v.OrganizationalUnitId) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncOrganizationalUnitList(v []types.ResourceDataSyncOrganizationalUnit, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentResourceDataSyncOrganizationalUnit(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncS3Destination(v *types.ResourceDataSyncS3Destination, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AWSKMSKeyARN != nil { - ok := object.Key("AWSKMSKeyARN") - ok.String(*v.AWSKMSKeyARN) - } - - if v.BucketName != nil { - ok := object.Key("BucketName") - ok.String(*v.BucketName) - } - - if v.DestinationDataSharing != nil { - ok := object.Key("DestinationDataSharing") - if err := awsAwsjson11_serializeDocumentResourceDataSyncDestinationDataSharing(v.DestinationDataSharing, ok); err != nil { - return err - } - } - - if v.Prefix != nil { - ok := object.Key("Prefix") - ok.String(*v.Prefix) - } - - if v.Region != nil { - ok := object.Key("Region") - ok.String(*v.Region) - } - - if len(v.SyncFormat) > 0 { - ok := object.Key("SyncFormat") - ok.String(string(v.SyncFormat)) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncSource(v *types.ResourceDataSyncSource, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AwsOrganizationsSource != nil { - ok := object.Key("AwsOrganizationsSource") - if err := awsAwsjson11_serializeDocumentResourceDataSyncAwsOrganizationsSource(v.AwsOrganizationsSource, ok); err != nil { - return err - } - } - - if v.EnableAllOpsDataSources { - ok := object.Key("EnableAllOpsDataSources") - ok.Boolean(v.EnableAllOpsDataSources) - } - - if v.IncludeFutureRegions { - ok := object.Key("IncludeFutureRegions") - ok.Boolean(v.IncludeFutureRegions) - } - - if v.SourceRegions != nil { - ok := object.Key("SourceRegions") - if err := awsAwsjson11_serializeDocumentResourceDataSyncSourceRegionList(v.SourceRegions, ok); err != nil { - return err - } - } - - if v.SourceType != nil { - ok := object.Key("SourceType") - ok.String(*v.SourceType) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResourceDataSyncSourceRegionList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentResultAttribute(v *types.ResultAttribute, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeDocumentResultAttributeList(v []types.ResultAttribute, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentResultAttribute(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentRunbook(v *types.Runbook, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentName != nil { - ok := object.Key("DocumentName") - ok.String(*v.DocumentName) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentAutomationParameterMap(v.Parameters, ok); err != nil { - return err - } - } - - if v.TargetLocations != nil { - ok := object.Key("TargetLocations") - if err := awsAwsjson11_serializeDocumentTargetLocations(v.TargetLocations, ok); err != nil { - return err - } - } - - if v.TargetMaps != nil { - ok := object.Key("TargetMaps") - if err := awsAwsjson11_serializeDocumentTargetMaps(v.TargetMaps, ok); err != nil { - return err - } - } - - if v.TargetParameterName != nil { - ok := object.Key("TargetParameterName") - ok.String(*v.TargetParameterName) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentRunbooks(v []types.Runbook, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentRunbook(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentS3OutputLocation(v *types.S3OutputLocation, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OutputS3BucketName != nil { - ok := object.Key("OutputS3BucketName") - ok.String(*v.OutputS3BucketName) - } - - if v.OutputS3KeyPrefix != nil { - ok := object.Key("OutputS3KeyPrefix") - ok.String(*v.OutputS3KeyPrefix) - } - - if v.OutputS3Region != nil { - ok := object.Key("OutputS3Region") - ok.String(*v.OutputS3Region) - } - - return nil -} - -func awsAwsjson11_serializeDocumentSessionFilter(v *types.SessionFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("key") - ok.String(string(v.Key)) - } - - if v.Value != nil { - ok := object.Key("value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentSessionFilterList(v []types.SessionFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentSessionFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentSessionManagerParameters(v map[string][]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - if vv := v[key]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentSessionManagerParameterValueList(v[key], om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentSessionManagerParameterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentStepExecutionFilter(v *types.StepExecutionFilter, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.Key) > 0 { - ok := object.Key("Key") - ok.String(string(v.Key)) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentStepExecutionFilterValueList(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentStepExecutionFilterList(v []types.StepExecutionFilter, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentStepExecutionFilter(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentStepExecutionFilterValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentStringList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentTag(v *types.Tag, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeDocumentTagList(v []types.Tag, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentTag(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentTarget(v *types.Target, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Key != nil { - ok := object.Key("Key") - ok.String(*v.Key) - } - - if v.Values != nil { - ok := object.Key("Values") - if err := awsAwsjson11_serializeDocumentTargetValues(v.Values, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeDocumentTargetLocation(v *types.TargetLocation, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Accounts != nil { - ok := object.Key("Accounts") - if err := awsAwsjson11_serializeDocumentAccounts(v.Accounts, ok); err != nil { - return err - } - } - - if v.ExecutionRoleName != nil { - ok := object.Key("ExecutionRoleName") - ok.String(*v.ExecutionRoleName) - } - - if v.Regions != nil { - ok := object.Key("Regions") - if err := awsAwsjson11_serializeDocumentRegions(v.Regions, ok); err != nil { - return err - } - } - - if v.TargetLocationAlarmConfiguration != nil { - ok := object.Key("TargetLocationAlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.TargetLocationAlarmConfiguration, ok); err != nil { - return err - } - } - - if v.TargetLocationMaxConcurrency != nil { - ok := object.Key("TargetLocationMaxConcurrency") - ok.String(*v.TargetLocationMaxConcurrency) - } - - if v.TargetLocationMaxErrors != nil { - ok := object.Key("TargetLocationMaxErrors") - ok.String(*v.TargetLocationMaxErrors) - } - - return nil -} - -func awsAwsjson11_serializeDocumentTargetLocations(v []types.TargetLocation, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentTargetLocation(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentTargetMap(v map[string][]string, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - for key := range v { - om := object.Key(key) - if vv := v[key]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentTargetMapValueList(v[key], om); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentTargetMaps(v []map[string][]string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if vv := v[i]; vv == nil { - continue - } - if err := awsAwsjson11_serializeDocumentTargetMap(v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentTargetMapValueList(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeDocumentTargets(v []types.Target, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - if err := awsAwsjson11_serializeDocumentTarget(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsjson11_serializeDocumentTargetValues(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsjson11_serializeOpDocumentAddTagsToResourceInput(v *AddTagsToResourceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ResourceId != nil { - ok := object.Key("ResourceId") - ok.String(*v.ResourceId) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentAssociateOpsItemRelatedItemInput(v *AssociateOpsItemRelatedItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationType != nil { - ok := object.Key("AssociationType") - ok.String(*v.AssociationType) - } - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - if v.ResourceType != nil { - ok := object.Key("ResourceType") - ok.String(*v.ResourceType) - } - - if v.ResourceUri != nil { - ok := object.Key("ResourceUri") - ok.String(*v.ResourceUri) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCancelCommandInput(v *CancelCommandInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CommandId != nil { - ok := object.Key("CommandId") - ok.String(*v.CommandId) - } - - if v.InstanceIds != nil { - ok := object.Key("InstanceIds") - if err := awsAwsjson11_serializeDocumentInstanceIdList(v.InstanceIds, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCancelMaintenanceWindowExecutionInput(v *CancelMaintenanceWindowExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateActivationInput(v *CreateActivationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DefaultInstanceName != nil { - ok := object.Key("DefaultInstanceName") - ok.String(*v.DefaultInstanceName) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.ExpirationDate != nil { - ok := object.Key("ExpirationDate") - ok.Double(smithytime.FormatEpochSeconds(*v.ExpirationDate)) - } - - if v.IamRole != nil { - ok := object.Key("IamRole") - ok.String(*v.IamRole) - } - - if v.RegistrationLimit != nil { - ok := object.Key("RegistrationLimit") - ok.Integer(*v.RegistrationLimit) - } - - if v.RegistrationMetadata != nil { - ok := object.Key("RegistrationMetadata") - if err := awsAwsjson11_serializeDocumentRegistrationMetadataList(v.RegistrationMetadata, ok); err != nil { - return err - } - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateAssociationBatchInput(v *CreateAssociationBatchInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Entries != nil { - ok := object.Key("Entries") - if err := awsAwsjson11_serializeDocumentCreateAssociationBatchRequestEntries(v.Entries, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateAssociationInput(v *CreateAssociationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.ApplyOnlyAtCronInterval { - ok := object.Key("ApplyOnlyAtCronInterval") - ok.Boolean(v.ApplyOnlyAtCronInterval) - } - - if v.AssociationName != nil { - ok := object.Key("AssociationName") - ok.String(*v.AssociationName) - } - - if v.AutomationTargetParameterName != nil { - ok := object.Key("AutomationTargetParameterName") - ok.String(*v.AutomationTargetParameterName) - } - - if v.CalendarNames != nil { - ok := object.Key("CalendarNames") - if err := awsAwsjson11_serializeDocumentCalendarNameOrARNList(v.CalendarNames, ok); err != nil { - return err - } - } - - if len(v.ComplianceSeverity) > 0 { - ok := object.Key("ComplianceSeverity") - ok.String(string(v.ComplianceSeverity)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.OutputLocation != nil { - ok := object.Key("OutputLocation") - if err := awsAwsjson11_serializeDocumentInstanceAssociationOutputLocation(v.OutputLocation, ok); err != nil { - return err - } - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.ScheduleExpression != nil { - ok := object.Key("ScheduleExpression") - ok.String(*v.ScheduleExpression) - } - - if v.ScheduleOffset != nil { - ok := object.Key("ScheduleOffset") - ok.Integer(*v.ScheduleOffset) - } - - if len(v.SyncCompliance) > 0 { - ok := object.Key("SyncCompliance") - ok.String(string(v.SyncCompliance)) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - if v.TargetLocations != nil { - ok := object.Key("TargetLocations") - if err := awsAwsjson11_serializeDocumentTargetLocations(v.TargetLocations, ok); err != nil { - return err - } - } - - if v.TargetMaps != nil { - ok := object.Key("TargetMaps") - if err := awsAwsjson11_serializeDocumentTargetMaps(v.TargetMaps, ok); err != nil { - return err - } - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateDocumentInput(v *CreateDocumentInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Attachments != nil { - ok := object.Key("Attachments") - if err := awsAwsjson11_serializeDocumentAttachmentsSourceList(v.Attachments, ok); err != nil { - return err - } - } - - if v.Content != nil { - ok := object.Key("Content") - ok.String(*v.Content) - } - - if v.DisplayName != nil { - ok := object.Key("DisplayName") - ok.String(*v.DisplayName) - } - - if len(v.DocumentFormat) > 0 { - ok := object.Key("DocumentFormat") - ok.String(string(v.DocumentFormat)) - } - - if len(v.DocumentType) > 0 { - ok := object.Key("DocumentType") - ok.String(string(v.DocumentType)) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Requires != nil { - ok := object.Key("Requires") - if err := awsAwsjson11_serializeDocumentDocumentRequiresList(v.Requires, ok); err != nil { - return err - } - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - if v.TargetType != nil { - ok := object.Key("TargetType") - ok.String(*v.TargetType) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateMaintenanceWindowInput(v *CreateMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - { - ok := object.Key("AllowUnassociatedTargets") - ok.Boolean(v.AllowUnassociatedTargets) - } - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - { - ok := object.Key("Cutoff") - ok.Integer(v.Cutoff) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Duration != nil { - ok := object.Key("Duration") - ok.Integer(*v.Duration) - } - - if v.EndDate != nil { - ok := object.Key("EndDate") - ok.String(*v.EndDate) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Schedule != nil { - ok := object.Key("Schedule") - ok.String(*v.Schedule) - } - - if v.ScheduleOffset != nil { - ok := object.Key("ScheduleOffset") - ok.Integer(*v.ScheduleOffset) - } - - if v.ScheduleTimezone != nil { - ok := object.Key("ScheduleTimezone") - ok.String(*v.ScheduleTimezone) - } - - if v.StartDate != nil { - ok := object.Key("StartDate") - ok.String(*v.StartDate) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateOpsItemInput(v *CreateOpsItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AccountId != nil { - ok := object.Key("AccountId") - ok.String(*v.AccountId) - } - - if v.ActualEndTime != nil { - ok := object.Key("ActualEndTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ActualEndTime)) - } - - if v.ActualStartTime != nil { - ok := object.Key("ActualStartTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ActualStartTime)) - } - - if v.Category != nil { - ok := object.Key("Category") - ok.String(*v.Category) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Notifications != nil { - ok := object.Key("Notifications") - if err := awsAwsjson11_serializeDocumentOpsItemNotifications(v.Notifications, ok); err != nil { - return err - } - } - - if v.OperationalData != nil { - ok := object.Key("OperationalData") - if err := awsAwsjson11_serializeDocumentOpsItemOperationalData(v.OperationalData, ok); err != nil { - return err - } - } - - if v.OpsItemType != nil { - ok := object.Key("OpsItemType") - ok.String(*v.OpsItemType) - } - - if v.PlannedEndTime != nil { - ok := object.Key("PlannedEndTime") - ok.Double(smithytime.FormatEpochSeconds(*v.PlannedEndTime)) - } - - if v.PlannedStartTime != nil { - ok := object.Key("PlannedStartTime") - ok.Double(smithytime.FormatEpochSeconds(*v.PlannedStartTime)) - } - - if v.Priority != nil { - ok := object.Key("Priority") - ok.Integer(*v.Priority) - } - - if v.RelatedOpsItems != nil { - ok := object.Key("RelatedOpsItems") - if err := awsAwsjson11_serializeDocumentRelatedOpsItems(v.RelatedOpsItems, ok); err != nil { - return err - } - } - - if v.Severity != nil { - ok := object.Key("Severity") - ok.String(*v.Severity) - } - - if v.Source != nil { - ok := object.Key("Source") - ok.String(*v.Source) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - if v.Title != nil { - ok := object.Key("Title") - ok.String(*v.Title) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateOpsMetadataInput(v *CreateOpsMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Metadata != nil { - ok := object.Key("Metadata") - if err := awsAwsjson11_serializeDocumentMetadataMap(v.Metadata, ok); err != nil { - return err - } - } - - if v.ResourceId != nil { - ok := object.Key("ResourceId") - ok.String(*v.ResourceId) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreatePatchBaselineInput(v *CreatePatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ApprovalRules != nil { - ok := object.Key("ApprovalRules") - if err := awsAwsjson11_serializeDocumentPatchRuleGroup(v.ApprovalRules, ok); err != nil { - return err - } - } - - if v.ApprovedPatches != nil { - ok := object.Key("ApprovedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.ApprovedPatches, ok); err != nil { - return err - } - } - - if len(v.ApprovedPatchesComplianceLevel) > 0 { - ok := object.Key("ApprovedPatchesComplianceLevel") - ok.String(string(v.ApprovedPatchesComplianceLevel)) - } - - if v.ApprovedPatchesEnableNonSecurity != nil { - ok := object.Key("ApprovedPatchesEnableNonSecurity") - ok.Boolean(*v.ApprovedPatchesEnableNonSecurity) - } - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.GlobalFilters != nil { - ok := object.Key("GlobalFilters") - if err := awsAwsjson11_serializeDocumentPatchFilterGroup(v.GlobalFilters, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if len(v.OperatingSystem) > 0 { - ok := object.Key("OperatingSystem") - ok.String(string(v.OperatingSystem)) - } - - if v.RejectedPatches != nil { - ok := object.Key("RejectedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.RejectedPatches, ok); err != nil { - return err - } - } - - if len(v.RejectedPatchesAction) > 0 { - ok := object.Key("RejectedPatchesAction") - ok.String(string(v.RejectedPatchesAction)) - } - - if v.Sources != nil { - ok := object.Key("Sources") - if err := awsAwsjson11_serializeDocumentPatchSourceList(v.Sources, ok); err != nil { - return err - } - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentCreateResourceDataSyncInput(v *CreateResourceDataSyncInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.S3Destination != nil { - ok := object.Key("S3Destination") - if err := awsAwsjson11_serializeDocumentResourceDataSyncS3Destination(v.S3Destination, ok); err != nil { - return err - } - } - - if v.SyncName != nil { - ok := object.Key("SyncName") - ok.String(*v.SyncName) - } - - if v.SyncSource != nil { - ok := object.Key("SyncSource") - if err := awsAwsjson11_serializeDocumentResourceDataSyncSource(v.SyncSource, ok); err != nil { - return err - } - } - - if v.SyncType != nil { - ok := object.Key("SyncType") - ok.String(*v.SyncType) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteActivationInput(v *DeleteActivationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ActivationId != nil { - ok := object.Key("ActivationId") - ok.String(*v.ActivationId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteAssociationInput(v *DeleteAssociationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteDocumentInput(v *DeleteDocumentInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Force { - ok := object.Key("Force") - ok.Boolean(v.Force) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteInventoryInput(v *DeleteInventoryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if v.DryRun { - ok := object.Key("DryRun") - ok.Boolean(v.DryRun) - } - - if len(v.SchemaDeleteOption) > 0 { - ok := object.Key("SchemaDeleteOption") - ok.String(string(v.SchemaDeleteOption)) - } - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteMaintenanceWindowInput(v *DeleteMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteOpsItemInput(v *DeleteOpsItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteOpsMetadataInput(v *DeleteOpsMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OpsMetadataArn != nil { - ok := object.Key("OpsMetadataArn") - ok.String(*v.OpsMetadataArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteParameterInput(v *DeleteParameterInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteParametersInput(v *DeleteParametersInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Names != nil { - ok := object.Key("Names") - if err := awsAwsjson11_serializeDocumentParameterNameList(v.Names, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeletePatchBaselineInput(v *DeletePatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteResourceDataSyncInput(v *DeleteResourceDataSyncInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SyncName != nil { - ok := object.Key("SyncName") - ok.String(*v.SyncName) - } - - if v.SyncType != nil { - ok := object.Key("SyncType") - ok.String(*v.SyncType) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeleteResourcePolicyInput(v *DeleteResourcePolicyInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.PolicyHash != nil { - ok := object.Key("PolicyHash") - ok.String(*v.PolicyHash) - } - - if v.PolicyId != nil { - ok := object.Key("PolicyId") - ok.String(*v.PolicyId) - } - - if v.ResourceArn != nil { - ok := object.Key("ResourceArn") - ok.String(*v.ResourceArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeregisterManagedInstanceInput(v *DeregisterManagedInstanceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeregisterPatchBaselineForPatchGroupInput(v *DeregisterPatchBaselineForPatchGroupInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - if v.PatchGroup != nil { - ok := object.Key("PatchGroup") - ok.String(*v.PatchGroup) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeregisterTargetFromMaintenanceWindowInput(v *DeregisterTargetFromMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Safe != nil { - ok := object.Key("Safe") - ok.Boolean(*v.Safe) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - if v.WindowTargetId != nil { - ok := object.Key("WindowTargetId") - ok.String(*v.WindowTargetId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDeregisterTaskFromMaintenanceWindowInput(v *DeregisterTaskFromMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - if v.WindowTaskId != nil { - ok := object.Key("WindowTaskId") - ok.String(*v.WindowTaskId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeActivationsInput(v *DescribeActivationsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentDescribeActivationsFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAssociationExecutionsInput(v *DescribeAssociationExecutionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentAssociationExecutionFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAssociationExecutionTargetsInput(v *DescribeAssociationExecutionTargetsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.ExecutionId != nil { - ok := object.Key("ExecutionId") - ok.String(*v.ExecutionId) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentAssociationExecutionTargetsFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAssociationInput(v *DescribeAssociationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.AssociationVersion != nil { - ok := object.Key("AssociationVersion") - ok.String(*v.AssociationVersion) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAutomationExecutionsInput(v *DescribeAutomationExecutionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentAutomationExecutionFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAutomationStepExecutionsInput(v *DescribeAutomationStepExecutionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AutomationExecutionId != nil { - ok := object.Key("AutomationExecutionId") - ok.String(*v.AutomationExecutionId) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentStepExecutionFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ReverseOrder != nil { - ok := object.Key("ReverseOrder") - ok.Boolean(*v.ReverseOrder) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeAvailablePatchesInput(v *DescribeAvailablePatchesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeDocumentInput(v *DescribeDocumentInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeDocumentPermissionInput(v *DescribeDocumentPermissionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if len(v.PermissionType) > 0 { - ok := object.Key("PermissionType") - ok.String(string(v.PermissionType)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeEffectiveInstanceAssociationsInput(v *DescribeEffectiveInstanceAssociationsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeEffectivePatchesForPatchBaselineInput(v *DescribeEffectivePatchesForPatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInstanceAssociationsStatusInput(v *DescribeInstanceAssociationsStatusInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInstanceInformationInput(v *DescribeInstanceInformationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentInstanceInformationStringFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.InstanceInformationFilterList != nil { - ok := object.Key("InstanceInformationFilterList") - if err := awsAwsjson11_serializeDocumentInstanceInformationFilterList(v.InstanceInformationFilterList, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInstancePatchesInput(v *DescribeInstancePatchesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInstancePatchStatesForPatchGroupInput(v *DescribeInstancePatchStatesForPatchGroupInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentInstancePatchStateFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.PatchGroup != nil { - ok := object.Key("PatchGroup") - ok.String(*v.PatchGroup) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInstancePatchStatesInput(v *DescribeInstancePatchStatesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InstanceIds != nil { - ok := object.Key("InstanceIds") - if err := awsAwsjson11_serializeDocumentInstanceIdList(v.InstanceIds, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeInventoryDeletionsInput(v *DescribeInventoryDeletionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DeletionId != nil { - ok := object.Key("DeletionId") - ok.String(*v.DeletionId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionsInput(v *DescribeMaintenanceWindowExecutionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionTaskInvocationsInput(v *DescribeMaintenanceWindowExecutionTaskInvocationsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.TaskId != nil { - ok := object.Key("TaskId") - ok.String(*v.TaskId) - } - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowExecutionTasksInput(v *DescribeMaintenanceWindowExecutionTasksInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowScheduleInput(v *DescribeMaintenanceWindowScheduleInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowsForTargetInput(v *DescribeMaintenanceWindowsForTargetInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowsInput(v *DescribeMaintenanceWindowsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowTargetsInput(v *DescribeMaintenanceWindowTargetsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeMaintenanceWindowTasksInput(v *DescribeMaintenanceWindowTasksInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeOpsItemsInput(v *DescribeOpsItemsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.OpsItemFilters != nil { - ok := object.Key("OpsItemFilters") - if err := awsAwsjson11_serializeDocumentOpsItemFilters(v.OpsItemFilters, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeParametersInput(v *DescribeParametersInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentParametersFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ParameterFilters != nil { - ok := object.Key("ParameterFilters") - if err := awsAwsjson11_serializeDocumentParameterStringFilterList(v.ParameterFilters, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribePatchBaselinesInput(v *DescribePatchBaselinesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribePatchGroupsInput(v *DescribePatchGroupsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentPatchOrchestratorFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribePatchGroupStateInput(v *DescribePatchGroupStateInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.PatchGroup != nil { - ok := object.Key("PatchGroup") - ok.String(*v.PatchGroup) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribePatchPropertiesInput(v *DescribePatchPropertiesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if len(v.OperatingSystem) > 0 { - ok := object.Key("OperatingSystem") - ok.String(string(v.OperatingSystem)) - } - - if len(v.PatchSet) > 0 { - ok := object.Key("PatchSet") - ok.String(string(v.PatchSet)) - } - - if len(v.Property) > 0 { - ok := object.Key("Property") - ok.String(string(v.Property)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDescribeSessionsInput(v *DescribeSessionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentSessionFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if len(v.State) > 0 { - ok := object.Key("State") - ok.String(string(v.State)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentDisassociateOpsItemRelatedItemInput(v *DisassociateOpsItemRelatedItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetAutomationExecutionInput(v *GetAutomationExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AutomationExecutionId != nil { - ok := object.Key("AutomationExecutionId") - ok.String(*v.AutomationExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetCalendarStateInput(v *GetCalendarStateInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AtTime != nil { - ok := object.Key("AtTime") - ok.String(*v.AtTime) - } - - if v.CalendarNames != nil { - ok := object.Key("CalendarNames") - if err := awsAwsjson11_serializeDocumentCalendarNameOrARNList(v.CalendarNames, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetCommandInvocationInput(v *GetCommandInvocationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CommandId != nil { - ok := object.Key("CommandId") - ok.String(*v.CommandId) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.PluginName != nil { - ok := object.Key("PluginName") - ok.String(*v.PluginName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetConnectionStatusInput(v *GetConnectionStatusInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Target != nil { - ok := object.Key("Target") - ok.String(*v.Target) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetDefaultPatchBaselineInput(v *GetDefaultPatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.OperatingSystem) > 0 { - ok := object.Key("OperatingSystem") - ok.String(string(v.OperatingSystem)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetDeployablePatchSnapshotForInstanceInput(v *GetDeployablePatchSnapshotForInstanceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineOverride != nil { - ok := object.Key("BaselineOverride") - if err := awsAwsjson11_serializeDocumentBaselineOverride(v.BaselineOverride, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.SnapshotId != nil { - ok := object.Key("SnapshotId") - ok.String(*v.SnapshotId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetDocumentInput(v *GetDocumentInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.DocumentFormat) > 0 { - ok := object.Key("DocumentFormat") - ok.String(string(v.DocumentFormat)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetInventoryInput(v *GetInventoryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Aggregators != nil { - ok := object.Key("Aggregators") - if err := awsAwsjson11_serializeDocumentInventoryAggregatorList(v.Aggregators, ok); err != nil { - return err - } - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentInventoryFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ResultAttributes != nil { - ok := object.Key("ResultAttributes") - if err := awsAwsjson11_serializeDocumentResultAttributeList(v.ResultAttributes, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetInventorySchemaInput(v *GetInventorySchemaInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Aggregator { - ok := object.Key("Aggregator") - ok.Boolean(v.Aggregator) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.SubType != nil { - ok := object.Key("SubType") - ok.Boolean(*v.SubType) - } - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionInput(v *GetMaintenanceWindowExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionTaskInput(v *GetMaintenanceWindowExecutionTaskInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.TaskId != nil { - ok := object.Key("TaskId") - ok.String(*v.TaskId) - } - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetMaintenanceWindowExecutionTaskInvocationInput(v *GetMaintenanceWindowExecutionTaskInvocationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InvocationId != nil { - ok := object.Key("InvocationId") - ok.String(*v.InvocationId) - } - - if v.TaskId != nil { - ok := object.Key("TaskId") - ok.String(*v.TaskId) - } - - if v.WindowExecutionId != nil { - ok := object.Key("WindowExecutionId") - ok.String(*v.WindowExecutionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetMaintenanceWindowInput(v *GetMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetMaintenanceWindowTaskInput(v *GetMaintenanceWindowTaskInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - if v.WindowTaskId != nil { - ok := object.Key("WindowTaskId") - ok.String(*v.WindowTaskId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetOpsItemInput(v *GetOpsItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.OpsItemArn != nil { - ok := object.Key("OpsItemArn") - ok.String(*v.OpsItemArn) - } - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetOpsMetadataInput(v *GetOpsMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.OpsMetadataArn != nil { - ok := object.Key("OpsMetadataArn") - ok.String(*v.OpsMetadataArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetOpsSummaryInput(v *GetOpsSummaryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Aggregators != nil { - ok := object.Key("Aggregators") - if err := awsAwsjson11_serializeDocumentOpsAggregatorList(v.Aggregators, ok); err != nil { - return err - } - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentOpsFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ResultAttributes != nil { - ok := object.Key("ResultAttributes") - if err := awsAwsjson11_serializeDocumentOpsResultAttributeList(v.ResultAttributes, ok); err != nil { - return err - } - } - - if v.SyncName != nil { - ok := object.Key("SyncName") - ok.String(*v.SyncName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetParameterHistoryInput(v *GetParameterHistoryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.WithDecryption != nil { - ok := object.Key("WithDecryption") - ok.Boolean(*v.WithDecryption) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetParameterInput(v *GetParameterInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.WithDecryption != nil { - ok := object.Key("WithDecryption") - ok.Boolean(*v.WithDecryption) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetParametersByPathInput(v *GetParametersByPathInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ParameterFilters != nil { - ok := object.Key("ParameterFilters") - if err := awsAwsjson11_serializeDocumentParameterStringFilterList(v.ParameterFilters, ok); err != nil { - return err - } - } - - if v.Path != nil { - ok := object.Key("Path") - ok.String(*v.Path) - } - - if v.Recursive != nil { - ok := object.Key("Recursive") - ok.Boolean(*v.Recursive) - } - - if v.WithDecryption != nil { - ok := object.Key("WithDecryption") - ok.Boolean(*v.WithDecryption) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetParametersInput(v *GetParametersInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Names != nil { - ok := object.Key("Names") - if err := awsAwsjson11_serializeDocumentParameterNameList(v.Names, ok); err != nil { - return err - } - } - - if v.WithDecryption != nil { - ok := object.Key("WithDecryption") - ok.Boolean(*v.WithDecryption) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetPatchBaselineForPatchGroupInput(v *GetPatchBaselineForPatchGroupInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if len(v.OperatingSystem) > 0 { - ok := object.Key("OperatingSystem") - ok.String(string(v.OperatingSystem)) - } - - if v.PatchGroup != nil { - ok := object.Key("PatchGroup") - ok.String(*v.PatchGroup) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetPatchBaselineInput(v *GetPatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetResourcePoliciesInput(v *GetResourcePoliciesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ResourceArn != nil { - ok := object.Key("ResourceArn") - ok.String(*v.ResourceArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentGetServiceSettingInput(v *GetServiceSettingInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SettingId != nil { - ok := object.Key("SettingId") - ok.String(*v.SettingId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentLabelParameterVersionInput(v *LabelParameterVersionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Labels != nil { - ok := object.Key("Labels") - if err := awsAwsjson11_serializeDocumentParameterLabelList(v.Labels, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.ParameterVersion != nil { - ok := object.Key("ParameterVersion") - ok.Long(*v.ParameterVersion) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListAssociationsInput(v *ListAssociationsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationFilterList != nil { - ok := object.Key("AssociationFilterList") - if err := awsAwsjson11_serializeDocumentAssociationFilterList(v.AssociationFilterList, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListAssociationVersionsInput(v *ListAssociationVersionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListCommandInvocationsInput(v *ListCommandInvocationsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CommandId != nil { - ok := object.Key("CommandId") - ok.String(*v.CommandId) - } - - if v.Details { - ok := object.Key("Details") - ok.Boolean(v.Details) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentCommandFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListCommandsInput(v *ListCommandsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.CommandId != nil { - ok := object.Key("CommandId") - ok.String(*v.CommandId) - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentCommandFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListComplianceItemsInput(v *ListComplianceItemsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentComplianceStringFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.ResourceIds != nil { - ok := object.Key("ResourceIds") - if err := awsAwsjson11_serializeDocumentComplianceResourceIdList(v.ResourceIds, ok); err != nil { - return err - } - } - - if v.ResourceTypes != nil { - ok := object.Key("ResourceTypes") - if err := awsAwsjson11_serializeDocumentComplianceResourceTypeList(v.ResourceTypes, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListComplianceSummariesInput(v *ListComplianceSummariesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentComplianceStringFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListDocumentMetadataHistoryInput(v *ListDocumentMetadataHistoryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if len(v.Metadata) > 0 { - ok := object.Key("Metadata") - ok.String(string(v.Metadata)) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListDocumentsInput(v *ListDocumentsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentFilterList != nil { - ok := object.Key("DocumentFilterList") - if err := awsAwsjson11_serializeDocumentDocumentFilterList(v.DocumentFilterList, ok); err != nil { - return err - } - } - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentDocumentKeyValuesFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListDocumentVersionsInput(v *ListDocumentVersionsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListInventoryEntriesInput(v *ListInventoryEntriesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentInventoryFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.TypeName != nil { - ok := object.Key("TypeName") - ok.String(*v.TypeName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListOpsItemEventsInput(v *ListOpsItemEventsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentOpsItemEventFilters(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListOpsItemRelatedItemsInput(v *ListOpsItemRelatedItemsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentOpsItemRelatedItemsFilters(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListOpsMetadataInput(v *ListOpsMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentOpsMetadataFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListResourceComplianceSummariesInput(v *ListResourceComplianceSummariesInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Filters != nil { - ok := object.Key("Filters") - if err := awsAwsjson11_serializeDocumentComplianceStringFilterList(v.Filters, ok); err != nil { - return err - } - } - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListResourceDataSyncInput(v *ListResourceDataSyncInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.MaxResults != nil { - ok := object.Key("MaxResults") - ok.Integer(*v.MaxResults) - } - - if v.NextToken != nil { - ok := object.Key("NextToken") - ok.String(*v.NextToken) - } - - if v.SyncType != nil { - ok := object.Key("SyncType") - ok.String(*v.SyncType) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentListTagsForResourceInput(v *ListTagsForResourceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ResourceId != nil { - ok := object.Key("ResourceId") - ok.String(*v.ResourceId) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentModifyDocumentPermissionInput(v *ModifyDocumentPermissionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AccountIdsToAdd != nil { - ok := object.Key("AccountIdsToAdd") - if err := awsAwsjson11_serializeDocumentAccountIdList(v.AccountIdsToAdd, ok); err != nil { - return err - } - } - - if v.AccountIdsToRemove != nil { - ok := object.Key("AccountIdsToRemove") - if err := awsAwsjson11_serializeDocumentAccountIdList(v.AccountIdsToRemove, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if len(v.PermissionType) > 0 { - ok := object.Key("PermissionType") - ok.String(string(v.PermissionType)) - } - - if v.SharedDocumentVersion != nil { - ok := object.Key("SharedDocumentVersion") - ok.String(*v.SharedDocumentVersion) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentPutComplianceItemsInput(v *PutComplianceItemsInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ComplianceType != nil { - ok := object.Key("ComplianceType") - ok.String(*v.ComplianceType) - } - - if v.ExecutionSummary != nil { - ok := object.Key("ExecutionSummary") - if err := awsAwsjson11_serializeDocumentComplianceExecutionSummary(v.ExecutionSummary, ok); err != nil { - return err - } - } - - if v.ItemContentHash != nil { - ok := object.Key("ItemContentHash") - ok.String(*v.ItemContentHash) - } - - if v.Items != nil { - ok := object.Key("Items") - if err := awsAwsjson11_serializeDocumentComplianceItemEntryList(v.Items, ok); err != nil { - return err - } - } - - if v.ResourceId != nil { - ok := object.Key("ResourceId") - ok.String(*v.ResourceId) - } - - if v.ResourceType != nil { - ok := object.Key("ResourceType") - ok.String(*v.ResourceType) - } - - if len(v.UploadType) > 0 { - ok := object.Key("UploadType") - ok.String(string(v.UploadType)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentPutInventoryInput(v *PutInventoryInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.Items != nil { - ok := object.Key("Items") - if err := awsAwsjson11_serializeDocumentInventoryItemList(v.Items, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentPutParameterInput(v *PutParameterInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AllowedPattern != nil { - ok := object.Key("AllowedPattern") - ok.String(*v.AllowedPattern) - } - - if v.DataType != nil { - ok := object.Key("DataType") - ok.String(*v.DataType) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.KeyId != nil { - ok := object.Key("KeyId") - ok.String(*v.KeyId) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Overwrite != nil { - ok := object.Key("Overwrite") - ok.Boolean(*v.Overwrite) - } - - if v.Policies != nil { - ok := object.Key("Policies") - ok.String(*v.Policies) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - if len(v.Tier) > 0 { - ok := object.Key("Tier") - ok.String(string(v.Tier)) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - if v.Value != nil { - ok := object.Key("Value") - ok.String(*v.Value) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentPutResourcePolicyInput(v *PutResourcePolicyInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Policy != nil { - ok := object.Key("Policy") - ok.String(*v.Policy) - } - - if v.PolicyHash != nil { - ok := object.Key("PolicyHash") - ok.String(*v.PolicyHash) - } - - if v.PolicyId != nil { - ok := object.Key("PolicyId") - ok.String(*v.PolicyId) - } - - if v.ResourceArn != nil { - ok := object.Key("ResourceArn") - ok.String(*v.ResourceArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentRegisterDefaultPatchBaselineInput(v *RegisterDefaultPatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentRegisterPatchBaselineForPatchGroupInput(v *RegisterPatchBaselineForPatchGroupInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - if v.PatchGroup != nil { - ok := object.Key("PatchGroup") - ok.String(*v.PatchGroup) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentRegisterTargetWithMaintenanceWindowInput(v *RegisterTargetWithMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.OwnerInformation != nil { - ok := object.Key("OwnerInformation") - ok.String(*v.OwnerInformation) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentRegisterTaskWithMaintenanceWindowInput(v *RegisterTaskWithMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if len(v.CutoffBehavior) > 0 { - ok := object.Key("CutoffBehavior") - ok.String(string(v.CutoffBehavior)) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.LoggingInfo != nil { - ok := object.Key("LoggingInfo") - if err := awsAwsjson11_serializeDocumentLoggingInfo(v.LoggingInfo, ok); err != nil { - return err - } - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Priority != nil { - ok := object.Key("Priority") - ok.Integer(*v.Priority) - } - - if v.ServiceRoleArn != nil { - ok := object.Key("ServiceRoleArn") - ok.String(*v.ServiceRoleArn) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.TaskArn != nil { - ok := object.Key("TaskArn") - ok.String(*v.TaskArn) - } - - if v.TaskInvocationParameters != nil { - ok := object.Key("TaskInvocationParameters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskInvocationParameters(v.TaskInvocationParameters, ok); err != nil { - return err - } - } - - if v.TaskParameters != nil { - ok := object.Key("TaskParameters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameters(v.TaskParameters, ok); err != nil { - return err - } - } - - if len(v.TaskType) > 0 { - ok := object.Key("TaskType") - ok.String(string(v.TaskType)) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentRemoveTagsFromResourceInput(v *RemoveTagsFromResourceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ResourceId != nil { - ok := object.Key("ResourceId") - ok.String(*v.ResourceId) - } - - if len(v.ResourceType) > 0 { - ok := object.Key("ResourceType") - ok.String(string(v.ResourceType)) - } - - if v.TagKeys != nil { - ok := object.Key("TagKeys") - if err := awsAwsjson11_serializeDocumentKeyList(v.TagKeys, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentResetServiceSettingInput(v *ResetServiceSettingInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SettingId != nil { - ok := object.Key("SettingId") - ok.String(*v.SettingId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentResumeSessionInput(v *ResumeSessionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SessionId != nil { - ok := object.Key("SessionId") - ok.String(*v.SessionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentSendAutomationSignalInput(v *SendAutomationSignalInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AutomationExecutionId != nil { - ok := object.Key("AutomationExecutionId") - ok.String(*v.AutomationExecutionId) - } - - if v.Payload != nil { - ok := object.Key("Payload") - if err := awsAwsjson11_serializeDocumentAutomationParameterMap(v.Payload, ok); err != nil { - return err - } - } - - if len(v.SignalType) > 0 { - ok := object.Key("SignalType") - ok.String(string(v.SignalType)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentSendCommandInput(v *SendCommandInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.CloudWatchOutputConfig != nil { - ok := object.Key("CloudWatchOutputConfig") - if err := awsAwsjson11_serializeDocumentCloudWatchOutputConfig(v.CloudWatchOutputConfig, ok); err != nil { - return err - } - } - - if v.Comment != nil { - ok := object.Key("Comment") - ok.String(*v.Comment) - } - - if v.DocumentHash != nil { - ok := object.Key("DocumentHash") - ok.String(*v.DocumentHash) - } - - if len(v.DocumentHashType) > 0 { - ok := object.Key("DocumentHashType") - ok.String(string(v.DocumentHashType)) - } - - if v.DocumentName != nil { - ok := object.Key("DocumentName") - ok.String(*v.DocumentName) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.InstanceIds != nil { - ok := object.Key("InstanceIds") - if err := awsAwsjson11_serializeDocumentInstanceIdList(v.InstanceIds, ok); err != nil { - return err - } - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.NotificationConfig != nil { - ok := object.Key("NotificationConfig") - if err := awsAwsjson11_serializeDocumentNotificationConfig(v.NotificationConfig, ok); err != nil { - return err - } - } - - if v.OutputS3BucketName != nil { - ok := object.Key("OutputS3BucketName") - ok.String(*v.OutputS3BucketName) - } - - if v.OutputS3KeyPrefix != nil { - ok := object.Key("OutputS3KeyPrefix") - ok.String(*v.OutputS3KeyPrefix) - } - - if v.OutputS3Region != nil { - ok := object.Key("OutputS3Region") - ok.String(*v.OutputS3Region) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.ServiceRoleArn != nil { - ok := object.Key("ServiceRoleArn") - ok.String(*v.ServiceRoleArn) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.TimeoutSeconds != nil { - ok := object.Key("TimeoutSeconds") - ok.Integer(*v.TimeoutSeconds) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentStartAssociationsOnceInput(v *StartAssociationsOnceInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationIds != nil { - ok := object.Key("AssociationIds") - if err := awsAwsjson11_serializeDocumentAssociationIdList(v.AssociationIds, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentStartAutomationExecutionInput(v *StartAutomationExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if v.DocumentName != nil { - ok := object.Key("DocumentName") - ok.String(*v.DocumentName) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if len(v.Mode) > 0 { - ok := object.Key("Mode") - ok.String(string(v.Mode)) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentAutomationParameterMap(v.Parameters, ok); err != nil { - return err - } - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - if v.TargetLocations != nil { - ok := object.Key("TargetLocations") - if err := awsAwsjson11_serializeDocumentTargetLocations(v.TargetLocations, ok); err != nil { - return err - } - } - - if v.TargetMaps != nil { - ok := object.Key("TargetMaps") - if err := awsAwsjson11_serializeDocumentTargetMaps(v.TargetMaps, ok); err != nil { - return err - } - } - - if v.TargetParameterName != nil { - ok := object.Key("TargetParameterName") - ok.String(*v.TargetParameterName) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentStartChangeRequestExecutionInput(v *StartChangeRequestExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AutoApprove { - ok := object.Key("AutoApprove") - ok.Boolean(v.AutoApprove) - } - - if v.ChangeDetails != nil { - ok := object.Key("ChangeDetails") - ok.String(*v.ChangeDetails) - } - - if v.ChangeRequestName != nil { - ok := object.Key("ChangeRequestName") - ok.String(*v.ChangeRequestName) - } - - if v.ClientToken != nil { - ok := object.Key("ClientToken") - ok.String(*v.ClientToken) - } - - if v.DocumentName != nil { - ok := object.Key("DocumentName") - ok.String(*v.DocumentName) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentAutomationParameterMap(v.Parameters, ok); err != nil { - return err - } - } - - if v.Runbooks != nil { - ok := object.Key("Runbooks") - if err := awsAwsjson11_serializeDocumentRunbooks(v.Runbooks, ok); err != nil { - return err - } - } - - if v.ScheduledEndTime != nil { - ok := object.Key("ScheduledEndTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ScheduledEndTime)) - } - - if v.ScheduledTime != nil { - ok := object.Key("ScheduledTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ScheduledTime)) - } - - if v.Tags != nil { - ok := object.Key("Tags") - if err := awsAwsjson11_serializeDocumentTagList(v.Tags, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentStartSessionInput(v *StartSessionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentName != nil { - ok := object.Key("DocumentName") - ok.String(*v.DocumentName) - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentSessionManagerParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.Reason != nil { - ok := object.Key("Reason") - ok.String(*v.Reason) - } - - if v.Target != nil { - ok := object.Key("Target") - ok.String(*v.Target) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentStopAutomationExecutionInput(v *StopAutomationExecutionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AutomationExecutionId != nil { - ok := object.Key("AutomationExecutionId") - ok.String(*v.AutomationExecutionId) - } - - if len(v.Type) > 0 { - ok := object.Key("Type") - ok.String(string(v.Type)) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentTerminateSessionInput(v *TerminateSessionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SessionId != nil { - ok := object.Key("SessionId") - ok.String(*v.SessionId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUnlabelParameterVersionInput(v *UnlabelParameterVersionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Labels != nil { - ok := object.Key("Labels") - if err := awsAwsjson11_serializeDocumentParameterLabelList(v.Labels, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.ParameterVersion != nil { - ok := object.Key("ParameterVersion") - ok.Long(*v.ParameterVersion) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateAssociationInput(v *UpdateAssociationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if v.ApplyOnlyAtCronInterval { - ok := object.Key("ApplyOnlyAtCronInterval") - ok.Boolean(v.ApplyOnlyAtCronInterval) - } - - if v.AssociationId != nil { - ok := object.Key("AssociationId") - ok.String(*v.AssociationId) - } - - if v.AssociationName != nil { - ok := object.Key("AssociationName") - ok.String(*v.AssociationName) - } - - if v.AssociationVersion != nil { - ok := object.Key("AssociationVersion") - ok.String(*v.AssociationVersion) - } - - if v.AutomationTargetParameterName != nil { - ok := object.Key("AutomationTargetParameterName") - ok.String(*v.AutomationTargetParameterName) - } - - if v.CalendarNames != nil { - ok := object.Key("CalendarNames") - if err := awsAwsjson11_serializeDocumentCalendarNameOrARNList(v.CalendarNames, ok); err != nil { - return err - } - } - - if len(v.ComplianceSeverity) > 0 { - ok := object.Key("ComplianceSeverity") - ok.String(string(v.ComplianceSeverity)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.OutputLocation != nil { - ok := object.Key("OutputLocation") - if err := awsAwsjson11_serializeDocumentInstanceAssociationOutputLocation(v.OutputLocation, ok); err != nil { - return err - } - } - - if v.Parameters != nil { - ok := object.Key("Parameters") - if err := awsAwsjson11_serializeDocumentParameters(v.Parameters, ok); err != nil { - return err - } - } - - if v.ScheduleExpression != nil { - ok := object.Key("ScheduleExpression") - ok.String(*v.ScheduleExpression) - } - - if v.ScheduleOffset != nil { - ok := object.Key("ScheduleOffset") - ok.Integer(*v.ScheduleOffset) - } - - if len(v.SyncCompliance) > 0 { - ok := object.Key("SyncCompliance") - ok.String(string(v.SyncCompliance)) - } - - if v.TargetLocations != nil { - ok := object.Key("TargetLocations") - if err := awsAwsjson11_serializeDocumentTargetLocations(v.TargetLocations, ok); err != nil { - return err - } - } - - if v.TargetMaps != nil { - ok := object.Key("TargetMaps") - if err := awsAwsjson11_serializeDocumentTargetMaps(v.TargetMaps, ok); err != nil { - return err - } - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateAssociationStatusInput(v *UpdateAssociationStatusInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AssociationStatus != nil { - ok := object.Key("AssociationStatus") - if err := awsAwsjson11_serializeDocumentAssociationStatus(v.AssociationStatus, ok); err != nil { - return err - } - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateDocumentDefaultVersionInput(v *UpdateDocumentDefaultVersionInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateDocumentInput(v *UpdateDocumentInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Attachments != nil { - ok := object.Key("Attachments") - if err := awsAwsjson11_serializeDocumentAttachmentsSourceList(v.Attachments, ok); err != nil { - return err - } - } - - if v.Content != nil { - ok := object.Key("Content") - ok.String(*v.Content) - } - - if v.DisplayName != nil { - ok := object.Key("DisplayName") - ok.String(*v.DisplayName) - } - - if len(v.DocumentFormat) > 0 { - ok := object.Key("DocumentFormat") - ok.String(string(v.DocumentFormat)) - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.TargetType != nil { - ok := object.Key("TargetType") - ok.String(*v.TargetType) - } - - if v.VersionName != nil { - ok := object.Key("VersionName") - ok.String(*v.VersionName) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateDocumentMetadataInput(v *UpdateDocumentMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.DocumentReviews != nil { - ok := object.Key("DocumentReviews") - if err := awsAwsjson11_serializeDocumentDocumentReviews(v.DocumentReviews, ok); err != nil { - return err - } - } - - if v.DocumentVersion != nil { - ok := object.Key("DocumentVersion") - ok.String(*v.DocumentVersion) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowInput(v *UpdateMaintenanceWindowInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AllowUnassociatedTargets != nil { - ok := object.Key("AllowUnassociatedTargets") - ok.Boolean(*v.AllowUnassociatedTargets) - } - - if v.Cutoff != nil { - ok := object.Key("Cutoff") - ok.Integer(*v.Cutoff) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Duration != nil { - ok := object.Key("Duration") - ok.Integer(*v.Duration) - } - - if v.Enabled != nil { - ok := object.Key("Enabled") - ok.Boolean(*v.Enabled) - } - - if v.EndDate != nil { - ok := object.Key("EndDate") - ok.String(*v.EndDate) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Replace != nil { - ok := object.Key("Replace") - ok.Boolean(*v.Replace) - } - - if v.Schedule != nil { - ok := object.Key("Schedule") - ok.String(*v.Schedule) - } - - if v.ScheduleOffset != nil { - ok := object.Key("ScheduleOffset") - ok.Integer(*v.ScheduleOffset) - } - - if v.ScheduleTimezone != nil { - ok := object.Key("ScheduleTimezone") - ok.String(*v.ScheduleTimezone) - } - - if v.StartDate != nil { - ok := object.Key("StartDate") - ok.String(*v.StartDate) - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowTargetInput(v *UpdateMaintenanceWindowTargetInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.OwnerInformation != nil { - ok := object.Key("OwnerInformation") - ok.String(*v.OwnerInformation) - } - - if v.Replace != nil { - ok := object.Key("Replace") - ok.Boolean(*v.Replace) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - if v.WindowTargetId != nil { - ok := object.Key("WindowTargetId") - ok.String(*v.WindowTargetId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateMaintenanceWindowTaskInput(v *UpdateMaintenanceWindowTaskInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.AlarmConfiguration != nil { - ok := object.Key("AlarmConfiguration") - if err := awsAwsjson11_serializeDocumentAlarmConfiguration(v.AlarmConfiguration, ok); err != nil { - return err - } - } - - if len(v.CutoffBehavior) > 0 { - ok := object.Key("CutoffBehavior") - ok.String(string(v.CutoffBehavior)) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.LoggingInfo != nil { - ok := object.Key("LoggingInfo") - if err := awsAwsjson11_serializeDocumentLoggingInfo(v.LoggingInfo, ok); err != nil { - return err - } - } - - if v.MaxConcurrency != nil { - ok := object.Key("MaxConcurrency") - ok.String(*v.MaxConcurrency) - } - - if v.MaxErrors != nil { - ok := object.Key("MaxErrors") - ok.String(*v.MaxErrors) - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.Priority != nil { - ok := object.Key("Priority") - ok.Integer(*v.Priority) - } - - if v.Replace != nil { - ok := object.Key("Replace") - ok.Boolean(*v.Replace) - } - - if v.ServiceRoleArn != nil { - ok := object.Key("ServiceRoleArn") - ok.String(*v.ServiceRoleArn) - } - - if v.Targets != nil { - ok := object.Key("Targets") - if err := awsAwsjson11_serializeDocumentTargets(v.Targets, ok); err != nil { - return err - } - } - - if v.TaskArn != nil { - ok := object.Key("TaskArn") - ok.String(*v.TaskArn) - } - - if v.TaskInvocationParameters != nil { - ok := object.Key("TaskInvocationParameters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskInvocationParameters(v.TaskInvocationParameters, ok); err != nil { - return err - } - } - - if v.TaskParameters != nil { - ok := object.Key("TaskParameters") - if err := awsAwsjson11_serializeDocumentMaintenanceWindowTaskParameters(v.TaskParameters, ok); err != nil { - return err - } - } - - if v.WindowId != nil { - ok := object.Key("WindowId") - ok.String(*v.WindowId) - } - - if v.WindowTaskId != nil { - ok := object.Key("WindowTaskId") - ok.String(*v.WindowTaskId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateManagedInstanceRoleInput(v *UpdateManagedInstanceRoleInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.IamRole != nil { - ok := object.Key("IamRole") - ok.String(*v.IamRole) - } - - if v.InstanceId != nil { - ok := object.Key("InstanceId") - ok.String(*v.InstanceId) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateOpsItemInput(v *UpdateOpsItemInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ActualEndTime != nil { - ok := object.Key("ActualEndTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ActualEndTime)) - } - - if v.ActualStartTime != nil { - ok := object.Key("ActualStartTime") - ok.Double(smithytime.FormatEpochSeconds(*v.ActualStartTime)) - } - - if v.Category != nil { - ok := object.Key("Category") - ok.String(*v.Category) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.Notifications != nil { - ok := object.Key("Notifications") - if err := awsAwsjson11_serializeDocumentOpsItemNotifications(v.Notifications, ok); err != nil { - return err - } - } - - if v.OperationalData != nil { - ok := object.Key("OperationalData") - if err := awsAwsjson11_serializeDocumentOpsItemOperationalData(v.OperationalData, ok); err != nil { - return err - } - } - - if v.OperationalDataToDelete != nil { - ok := object.Key("OperationalDataToDelete") - if err := awsAwsjson11_serializeDocumentOpsItemOpsDataKeysList(v.OperationalDataToDelete, ok); err != nil { - return err - } - } - - if v.OpsItemArn != nil { - ok := object.Key("OpsItemArn") - ok.String(*v.OpsItemArn) - } - - if v.OpsItemId != nil { - ok := object.Key("OpsItemId") - ok.String(*v.OpsItemId) - } - - if v.PlannedEndTime != nil { - ok := object.Key("PlannedEndTime") - ok.Double(smithytime.FormatEpochSeconds(*v.PlannedEndTime)) - } - - if v.PlannedStartTime != nil { - ok := object.Key("PlannedStartTime") - ok.Double(smithytime.FormatEpochSeconds(*v.PlannedStartTime)) - } - - if v.Priority != nil { - ok := object.Key("Priority") - ok.Integer(*v.Priority) - } - - if v.RelatedOpsItems != nil { - ok := object.Key("RelatedOpsItems") - if err := awsAwsjson11_serializeDocumentRelatedOpsItems(v.RelatedOpsItems, ok); err != nil { - return err - } - } - - if v.Severity != nil { - ok := object.Key("Severity") - ok.String(*v.Severity) - } - - if len(v.Status) > 0 { - ok := object.Key("Status") - ok.String(string(v.Status)) - } - - if v.Title != nil { - ok := object.Key("Title") - ok.String(*v.Title) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateOpsMetadataInput(v *UpdateOpsMetadataInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.KeysToDelete != nil { - ok := object.Key("KeysToDelete") - if err := awsAwsjson11_serializeDocumentMetadataKeysToDeleteList(v.KeysToDelete, ok); err != nil { - return err - } - } - - if v.MetadataToUpdate != nil { - ok := object.Key("MetadataToUpdate") - if err := awsAwsjson11_serializeDocumentMetadataMap(v.MetadataToUpdate, ok); err != nil { - return err - } - } - - if v.OpsMetadataArn != nil { - ok := object.Key("OpsMetadataArn") - ok.String(*v.OpsMetadataArn) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdatePatchBaselineInput(v *UpdatePatchBaselineInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ApprovalRules != nil { - ok := object.Key("ApprovalRules") - if err := awsAwsjson11_serializeDocumentPatchRuleGroup(v.ApprovalRules, ok); err != nil { - return err - } - } - - if v.ApprovedPatches != nil { - ok := object.Key("ApprovedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.ApprovedPatches, ok); err != nil { - return err - } - } - - if len(v.ApprovedPatchesComplianceLevel) > 0 { - ok := object.Key("ApprovedPatchesComplianceLevel") - ok.String(string(v.ApprovedPatchesComplianceLevel)) - } - - if v.ApprovedPatchesEnableNonSecurity != nil { - ok := object.Key("ApprovedPatchesEnableNonSecurity") - ok.Boolean(*v.ApprovedPatchesEnableNonSecurity) - } - - if v.BaselineId != nil { - ok := object.Key("BaselineId") - ok.String(*v.BaselineId) - } - - if v.Description != nil { - ok := object.Key("Description") - ok.String(*v.Description) - } - - if v.GlobalFilters != nil { - ok := object.Key("GlobalFilters") - if err := awsAwsjson11_serializeDocumentPatchFilterGroup(v.GlobalFilters, ok); err != nil { - return err - } - } - - if v.Name != nil { - ok := object.Key("Name") - ok.String(*v.Name) - } - - if v.RejectedPatches != nil { - ok := object.Key("RejectedPatches") - if err := awsAwsjson11_serializeDocumentPatchIdList(v.RejectedPatches, ok); err != nil { - return err - } - } - - if len(v.RejectedPatchesAction) > 0 { - ok := object.Key("RejectedPatchesAction") - ok.String(string(v.RejectedPatchesAction)) - } - - if v.Replace != nil { - ok := object.Key("Replace") - ok.Boolean(*v.Replace) - } - - if v.Sources != nil { - ok := object.Key("Sources") - if err := awsAwsjson11_serializeDocumentPatchSourceList(v.Sources, ok); err != nil { - return err - } - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateResourceDataSyncInput(v *UpdateResourceDataSyncInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SyncName != nil { - ok := object.Key("SyncName") - ok.String(*v.SyncName) - } - - if v.SyncSource != nil { - ok := object.Key("SyncSource") - if err := awsAwsjson11_serializeDocumentResourceDataSyncSource(v.SyncSource, ok); err != nil { - return err - } - } - - if v.SyncType != nil { - ok := object.Key("SyncType") - ok.String(*v.SyncType) - } - - return nil -} - -func awsAwsjson11_serializeOpDocumentUpdateServiceSettingInput(v *UpdateServiceSettingInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.SettingId != nil { - ok := object.Key("SettingId") - ok.String(*v.SettingId) - } - - if v.SettingValue != nil { - ok := object.Key("SettingValue") - ok.String(*v.SettingValue) - } - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/enums.go deleted file mode 100644 index bb6c67a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/enums.go +++ /dev/null @@ -1,2012 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -type AssociationComplianceSeverity string - -// Enum values for AssociationComplianceSeverity -const ( - AssociationComplianceSeverityCritical AssociationComplianceSeverity = "CRITICAL" - AssociationComplianceSeverityHigh AssociationComplianceSeverity = "HIGH" - AssociationComplianceSeverityMedium AssociationComplianceSeverity = "MEDIUM" - AssociationComplianceSeverityLow AssociationComplianceSeverity = "LOW" - AssociationComplianceSeverityUnspecified AssociationComplianceSeverity = "UNSPECIFIED" -) - -// Values returns all known values for AssociationComplianceSeverity. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (AssociationComplianceSeverity) Values() []AssociationComplianceSeverity { - return []AssociationComplianceSeverity{ - "CRITICAL", - "HIGH", - "MEDIUM", - "LOW", - "UNSPECIFIED", - } -} - -type AssociationExecutionFilterKey string - -// Enum values for AssociationExecutionFilterKey -const ( - AssociationExecutionFilterKeyExecutionId AssociationExecutionFilterKey = "ExecutionId" - AssociationExecutionFilterKeyStatus AssociationExecutionFilterKey = "Status" - AssociationExecutionFilterKeyCreatedTime AssociationExecutionFilterKey = "CreatedTime" -) - -// Values returns all known values for AssociationExecutionFilterKey. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (AssociationExecutionFilterKey) Values() []AssociationExecutionFilterKey { - return []AssociationExecutionFilterKey{ - "ExecutionId", - "Status", - "CreatedTime", - } -} - -type AssociationExecutionTargetsFilterKey string - -// Enum values for AssociationExecutionTargetsFilterKey -const ( - AssociationExecutionTargetsFilterKeyStatus AssociationExecutionTargetsFilterKey = "Status" - AssociationExecutionTargetsFilterKeyResourceId AssociationExecutionTargetsFilterKey = "ResourceId" - AssociationExecutionTargetsFilterKeyResourceType AssociationExecutionTargetsFilterKey = "ResourceType" -) - -// Values returns all known values for AssociationExecutionTargetsFilterKey. Note -// that this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (AssociationExecutionTargetsFilterKey) Values() []AssociationExecutionTargetsFilterKey { - return []AssociationExecutionTargetsFilterKey{ - "Status", - "ResourceId", - "ResourceType", - } -} - -type AssociationFilterKey string - -// Enum values for AssociationFilterKey -const ( - AssociationFilterKeyInstanceId AssociationFilterKey = "InstanceId" - AssociationFilterKeyName AssociationFilterKey = "Name" - AssociationFilterKeyAssociationId AssociationFilterKey = "AssociationId" - AssociationFilterKeyStatus AssociationFilterKey = "AssociationStatusName" - AssociationFilterKeyLastExecutedBefore AssociationFilterKey = "LastExecutedBefore" - AssociationFilterKeyLastExecutedAfter AssociationFilterKey = "LastExecutedAfter" - AssociationFilterKeyAssociationName AssociationFilterKey = "AssociationName" - AssociationFilterKeyResourceGroupName AssociationFilterKey = "ResourceGroupName" -) - -// Values returns all known values for AssociationFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AssociationFilterKey) Values() []AssociationFilterKey { - return []AssociationFilterKey{ - "InstanceId", - "Name", - "AssociationId", - "AssociationStatusName", - "LastExecutedBefore", - "LastExecutedAfter", - "AssociationName", - "ResourceGroupName", - } -} - -type AssociationFilterOperatorType string - -// Enum values for AssociationFilterOperatorType -const ( - AssociationFilterOperatorTypeEqual AssociationFilterOperatorType = "EQUAL" - AssociationFilterOperatorTypeLessThan AssociationFilterOperatorType = "LESS_THAN" - AssociationFilterOperatorTypeGreaterThan AssociationFilterOperatorType = "GREATER_THAN" -) - -// Values returns all known values for AssociationFilterOperatorType. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (AssociationFilterOperatorType) Values() []AssociationFilterOperatorType { - return []AssociationFilterOperatorType{ - "EQUAL", - "LESS_THAN", - "GREATER_THAN", - } -} - -type AssociationStatusName string - -// Enum values for AssociationStatusName -const ( - AssociationStatusNamePending AssociationStatusName = "Pending" - AssociationStatusNameSuccess AssociationStatusName = "Success" - AssociationStatusNameFailed AssociationStatusName = "Failed" -) - -// Values returns all known values for AssociationStatusName. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AssociationStatusName) Values() []AssociationStatusName { - return []AssociationStatusName{ - "Pending", - "Success", - "Failed", - } -} - -type AssociationSyncCompliance string - -// Enum values for AssociationSyncCompliance -const ( - AssociationSyncComplianceAuto AssociationSyncCompliance = "AUTO" - AssociationSyncComplianceManual AssociationSyncCompliance = "MANUAL" -) - -// Values returns all known values for AssociationSyncCompliance. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (AssociationSyncCompliance) Values() []AssociationSyncCompliance { - return []AssociationSyncCompliance{ - "AUTO", - "MANUAL", - } -} - -type AttachmentHashType string - -// Enum values for AttachmentHashType -const ( - AttachmentHashTypeSha256 AttachmentHashType = "Sha256" -) - -// Values returns all known values for AttachmentHashType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AttachmentHashType) Values() []AttachmentHashType { - return []AttachmentHashType{ - "Sha256", - } -} - -type AttachmentsSourceKey string - -// Enum values for AttachmentsSourceKey -const ( - AttachmentsSourceKeySourceUrl AttachmentsSourceKey = "SourceUrl" - AttachmentsSourceKeyS3FileUrl AttachmentsSourceKey = "S3FileUrl" - AttachmentsSourceKeyAttachmentReference AttachmentsSourceKey = "AttachmentReference" -) - -// Values returns all known values for AttachmentsSourceKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AttachmentsSourceKey) Values() []AttachmentsSourceKey { - return []AttachmentsSourceKey{ - "SourceUrl", - "S3FileUrl", - "AttachmentReference", - } -} - -type AutomationExecutionFilterKey string - -// Enum values for AutomationExecutionFilterKey -const ( - AutomationExecutionFilterKeyDocumentNamePrefix AutomationExecutionFilterKey = "DocumentNamePrefix" - AutomationExecutionFilterKeyExecutionStatus AutomationExecutionFilterKey = "ExecutionStatus" - AutomationExecutionFilterKeyExecutionId AutomationExecutionFilterKey = "ExecutionId" - AutomationExecutionFilterKeyParentExecutionId AutomationExecutionFilterKey = "ParentExecutionId" - AutomationExecutionFilterKeyCurrentAction AutomationExecutionFilterKey = "CurrentAction" - AutomationExecutionFilterKeyStartTimeBefore AutomationExecutionFilterKey = "StartTimeBefore" - AutomationExecutionFilterKeyStartTimeAfter AutomationExecutionFilterKey = "StartTimeAfter" - AutomationExecutionFilterKeyAutomationType AutomationExecutionFilterKey = "AutomationType" - AutomationExecutionFilterKeyTagKey AutomationExecutionFilterKey = "TagKey" - AutomationExecutionFilterKeyTargetResourceGroup AutomationExecutionFilterKey = "TargetResourceGroup" - AutomationExecutionFilterKeyAutomationSubtype AutomationExecutionFilterKey = "AutomationSubtype" - AutomationExecutionFilterKeyOpsItemId AutomationExecutionFilterKey = "OpsItemId" -) - -// Values returns all known values for AutomationExecutionFilterKey. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (AutomationExecutionFilterKey) Values() []AutomationExecutionFilterKey { - return []AutomationExecutionFilterKey{ - "DocumentNamePrefix", - "ExecutionStatus", - "ExecutionId", - "ParentExecutionId", - "CurrentAction", - "StartTimeBefore", - "StartTimeAfter", - "AutomationType", - "TagKey", - "TargetResourceGroup", - "AutomationSubtype", - "OpsItemId", - } -} - -type AutomationExecutionStatus string - -// Enum values for AutomationExecutionStatus -const ( - AutomationExecutionStatusPending AutomationExecutionStatus = "Pending" - AutomationExecutionStatusInprogress AutomationExecutionStatus = "InProgress" - AutomationExecutionStatusWaiting AutomationExecutionStatus = "Waiting" - AutomationExecutionStatusSuccess AutomationExecutionStatus = "Success" - AutomationExecutionStatusTimedout AutomationExecutionStatus = "TimedOut" - AutomationExecutionStatusCancelling AutomationExecutionStatus = "Cancelling" - AutomationExecutionStatusCancelled AutomationExecutionStatus = "Cancelled" - AutomationExecutionStatusFailed AutomationExecutionStatus = "Failed" - AutomationExecutionStatusPendingApproval AutomationExecutionStatus = "PendingApproval" - AutomationExecutionStatusApproved AutomationExecutionStatus = "Approved" - AutomationExecutionStatusRejected AutomationExecutionStatus = "Rejected" - AutomationExecutionStatusScheduled AutomationExecutionStatus = "Scheduled" - AutomationExecutionStatusRunbookInprogress AutomationExecutionStatus = "RunbookInProgress" - AutomationExecutionStatusPendingChangeCalendarOverride AutomationExecutionStatus = "PendingChangeCalendarOverride" - AutomationExecutionStatusChangeCalendarOverrideApproved AutomationExecutionStatus = "ChangeCalendarOverrideApproved" - AutomationExecutionStatusChangeCalendarOverrideRejected AutomationExecutionStatus = "ChangeCalendarOverrideRejected" - AutomationExecutionStatusCompletedWithSuccess AutomationExecutionStatus = "CompletedWithSuccess" - AutomationExecutionStatusCompletedWithFailure AutomationExecutionStatus = "CompletedWithFailure" - AutomationExecutionStatusExited AutomationExecutionStatus = "Exited" -) - -// Values returns all known values for AutomationExecutionStatus. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (AutomationExecutionStatus) Values() []AutomationExecutionStatus { - return []AutomationExecutionStatus{ - "Pending", - "InProgress", - "Waiting", - "Success", - "TimedOut", - "Cancelling", - "Cancelled", - "Failed", - "PendingApproval", - "Approved", - "Rejected", - "Scheduled", - "RunbookInProgress", - "PendingChangeCalendarOverride", - "ChangeCalendarOverrideApproved", - "ChangeCalendarOverrideRejected", - "CompletedWithSuccess", - "CompletedWithFailure", - "Exited", - } -} - -type AutomationSubtype string - -// Enum values for AutomationSubtype -const ( - AutomationSubtypeChangeRequest AutomationSubtype = "ChangeRequest" -) - -// Values returns all known values for AutomationSubtype. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AutomationSubtype) Values() []AutomationSubtype { - return []AutomationSubtype{ - "ChangeRequest", - } -} - -type AutomationType string - -// Enum values for AutomationType -const ( - AutomationTypeCrossAccount AutomationType = "CrossAccount" - AutomationTypeLocal AutomationType = "Local" -) - -// Values returns all known values for AutomationType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (AutomationType) Values() []AutomationType { - return []AutomationType{ - "CrossAccount", - "Local", - } -} - -type CalendarState string - -// Enum values for CalendarState -const ( - CalendarStateOpen CalendarState = "OPEN" - CalendarStateClosed CalendarState = "CLOSED" -) - -// Values returns all known values for CalendarState. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (CalendarState) Values() []CalendarState { - return []CalendarState{ - "OPEN", - "CLOSED", - } -} - -type CommandFilterKey string - -// Enum values for CommandFilterKey -const ( - CommandFilterKeyInvokedAfter CommandFilterKey = "InvokedAfter" - CommandFilterKeyInvokedBefore CommandFilterKey = "InvokedBefore" - CommandFilterKeyStatus CommandFilterKey = "Status" - CommandFilterKeyExecutionStage CommandFilterKey = "ExecutionStage" - CommandFilterKeyDocumentName CommandFilterKey = "DocumentName" -) - -// Values returns all known values for CommandFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (CommandFilterKey) Values() []CommandFilterKey { - return []CommandFilterKey{ - "InvokedAfter", - "InvokedBefore", - "Status", - "ExecutionStage", - "DocumentName", - } -} - -type CommandInvocationStatus string - -// Enum values for CommandInvocationStatus -const ( - CommandInvocationStatusPending CommandInvocationStatus = "Pending" - CommandInvocationStatusInProgress CommandInvocationStatus = "InProgress" - CommandInvocationStatusDelayed CommandInvocationStatus = "Delayed" - CommandInvocationStatusSuccess CommandInvocationStatus = "Success" - CommandInvocationStatusCancelled CommandInvocationStatus = "Cancelled" - CommandInvocationStatusTimedOut CommandInvocationStatus = "TimedOut" - CommandInvocationStatusFailed CommandInvocationStatus = "Failed" - CommandInvocationStatusCancelling CommandInvocationStatus = "Cancelling" -) - -// Values returns all known values for CommandInvocationStatus. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (CommandInvocationStatus) Values() []CommandInvocationStatus { - return []CommandInvocationStatus{ - "Pending", - "InProgress", - "Delayed", - "Success", - "Cancelled", - "TimedOut", - "Failed", - "Cancelling", - } -} - -type CommandPluginStatus string - -// Enum values for CommandPluginStatus -const ( - CommandPluginStatusPending CommandPluginStatus = "Pending" - CommandPluginStatusInProgress CommandPluginStatus = "InProgress" - CommandPluginStatusSuccess CommandPluginStatus = "Success" - CommandPluginStatusTimedOut CommandPluginStatus = "TimedOut" - CommandPluginStatusCancelled CommandPluginStatus = "Cancelled" - CommandPluginStatusFailed CommandPluginStatus = "Failed" -) - -// Values returns all known values for CommandPluginStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (CommandPluginStatus) Values() []CommandPluginStatus { - return []CommandPluginStatus{ - "Pending", - "InProgress", - "Success", - "TimedOut", - "Cancelled", - "Failed", - } -} - -type CommandStatus string - -// Enum values for CommandStatus -const ( - CommandStatusPending CommandStatus = "Pending" - CommandStatusInProgress CommandStatus = "InProgress" - CommandStatusSuccess CommandStatus = "Success" - CommandStatusCancelled CommandStatus = "Cancelled" - CommandStatusFailed CommandStatus = "Failed" - CommandStatusTimedOut CommandStatus = "TimedOut" - CommandStatusCancelling CommandStatus = "Cancelling" -) - -// Values returns all known values for CommandStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (CommandStatus) Values() []CommandStatus { - return []CommandStatus{ - "Pending", - "InProgress", - "Success", - "Cancelled", - "Failed", - "TimedOut", - "Cancelling", - } -} - -type ComplianceQueryOperatorType string - -// Enum values for ComplianceQueryOperatorType -const ( - ComplianceQueryOperatorTypeEqual ComplianceQueryOperatorType = "EQUAL" - ComplianceQueryOperatorTypeNotEqual ComplianceQueryOperatorType = "NOT_EQUAL" - ComplianceQueryOperatorTypeBeginWith ComplianceQueryOperatorType = "BEGIN_WITH" - ComplianceQueryOperatorTypeLessThan ComplianceQueryOperatorType = "LESS_THAN" - ComplianceQueryOperatorTypeGreaterThan ComplianceQueryOperatorType = "GREATER_THAN" -) - -// Values returns all known values for ComplianceQueryOperatorType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (ComplianceQueryOperatorType) Values() []ComplianceQueryOperatorType { - return []ComplianceQueryOperatorType{ - "EQUAL", - "NOT_EQUAL", - "BEGIN_WITH", - "LESS_THAN", - "GREATER_THAN", - } -} - -type ComplianceSeverity string - -// Enum values for ComplianceSeverity -const ( - ComplianceSeverityCritical ComplianceSeverity = "CRITICAL" - ComplianceSeverityHigh ComplianceSeverity = "HIGH" - ComplianceSeverityMedium ComplianceSeverity = "MEDIUM" - ComplianceSeverityLow ComplianceSeverity = "LOW" - ComplianceSeverityInformational ComplianceSeverity = "INFORMATIONAL" - ComplianceSeverityUnspecified ComplianceSeverity = "UNSPECIFIED" -) - -// Values returns all known values for ComplianceSeverity. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ComplianceSeverity) Values() []ComplianceSeverity { - return []ComplianceSeverity{ - "CRITICAL", - "HIGH", - "MEDIUM", - "LOW", - "INFORMATIONAL", - "UNSPECIFIED", - } -} - -type ComplianceStatus string - -// Enum values for ComplianceStatus -const ( - ComplianceStatusCompliant ComplianceStatus = "COMPLIANT" - ComplianceStatusNonCompliant ComplianceStatus = "NON_COMPLIANT" -) - -// Values returns all known values for ComplianceStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ComplianceStatus) Values() []ComplianceStatus { - return []ComplianceStatus{ - "COMPLIANT", - "NON_COMPLIANT", - } -} - -type ComplianceUploadType string - -// Enum values for ComplianceUploadType -const ( - ComplianceUploadTypeComplete ComplianceUploadType = "COMPLETE" - ComplianceUploadTypePartial ComplianceUploadType = "PARTIAL" -) - -// Values returns all known values for ComplianceUploadType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ComplianceUploadType) Values() []ComplianceUploadType { - return []ComplianceUploadType{ - "COMPLETE", - "PARTIAL", - } -} - -type ConnectionStatus string - -// Enum values for ConnectionStatus -const ( - ConnectionStatusConnected ConnectionStatus = "connected" - ConnectionStatusNotConnected ConnectionStatus = "notconnected" -) - -// Values returns all known values for ConnectionStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ConnectionStatus) Values() []ConnectionStatus { - return []ConnectionStatus{ - "connected", - "notconnected", - } -} - -type DescribeActivationsFilterKeys string - -// Enum values for DescribeActivationsFilterKeys -const ( - DescribeActivationsFilterKeysActivationIds DescribeActivationsFilterKeys = "ActivationIds" - DescribeActivationsFilterKeysDefaultInstanceName DescribeActivationsFilterKeys = "DefaultInstanceName" - DescribeActivationsFilterKeysIamRole DescribeActivationsFilterKeys = "IamRole" -) - -// Values returns all known values for DescribeActivationsFilterKeys. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (DescribeActivationsFilterKeys) Values() []DescribeActivationsFilterKeys { - return []DescribeActivationsFilterKeys{ - "ActivationIds", - "DefaultInstanceName", - "IamRole", - } -} - -type DocumentFilterKey string - -// Enum values for DocumentFilterKey -const ( - DocumentFilterKeyName DocumentFilterKey = "Name" - DocumentFilterKeyOwner DocumentFilterKey = "Owner" - DocumentFilterKeyPlatformTypes DocumentFilterKey = "PlatformTypes" - DocumentFilterKeyDocumentType DocumentFilterKey = "DocumentType" -) - -// Values returns all known values for DocumentFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentFilterKey) Values() []DocumentFilterKey { - return []DocumentFilterKey{ - "Name", - "Owner", - "PlatformTypes", - "DocumentType", - } -} - -type DocumentFormat string - -// Enum values for DocumentFormat -const ( - DocumentFormatYaml DocumentFormat = "YAML" - DocumentFormatJson DocumentFormat = "JSON" - DocumentFormatText DocumentFormat = "TEXT" -) - -// Values returns all known values for DocumentFormat. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentFormat) Values() []DocumentFormat { - return []DocumentFormat{ - "YAML", - "JSON", - "TEXT", - } -} - -type DocumentHashType string - -// Enum values for DocumentHashType -const ( - DocumentHashTypeSha256 DocumentHashType = "Sha256" - DocumentHashTypeSha1 DocumentHashType = "Sha1" -) - -// Values returns all known values for DocumentHashType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentHashType) Values() []DocumentHashType { - return []DocumentHashType{ - "Sha256", - "Sha1", - } -} - -type DocumentMetadataEnum string - -// Enum values for DocumentMetadataEnum -const ( - DocumentMetadataEnumDocumentReviews DocumentMetadataEnum = "DocumentReviews" -) - -// Values returns all known values for DocumentMetadataEnum. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentMetadataEnum) Values() []DocumentMetadataEnum { - return []DocumentMetadataEnum{ - "DocumentReviews", - } -} - -type DocumentParameterType string - -// Enum values for DocumentParameterType -const ( - DocumentParameterTypeString DocumentParameterType = "String" - DocumentParameterTypeStringList DocumentParameterType = "StringList" -) - -// Values returns all known values for DocumentParameterType. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentParameterType) Values() []DocumentParameterType { - return []DocumentParameterType{ - "String", - "StringList", - } -} - -type DocumentPermissionType string - -// Enum values for DocumentPermissionType -const ( - DocumentPermissionTypeShare DocumentPermissionType = "Share" -) - -// Values returns all known values for DocumentPermissionType. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentPermissionType) Values() []DocumentPermissionType { - return []DocumentPermissionType{ - "Share", - } -} - -type DocumentReviewAction string - -// Enum values for DocumentReviewAction -const ( - DocumentReviewActionSendForReview DocumentReviewAction = "SendForReview" - DocumentReviewActionUpdateReview DocumentReviewAction = "UpdateReview" - DocumentReviewActionApprove DocumentReviewAction = "Approve" - DocumentReviewActionReject DocumentReviewAction = "Reject" -) - -// Values returns all known values for DocumentReviewAction. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentReviewAction) Values() []DocumentReviewAction { - return []DocumentReviewAction{ - "SendForReview", - "UpdateReview", - "Approve", - "Reject", - } -} - -type DocumentReviewCommentType string - -// Enum values for DocumentReviewCommentType -const ( - DocumentReviewCommentTypeComment DocumentReviewCommentType = "Comment" -) - -// Values returns all known values for DocumentReviewCommentType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (DocumentReviewCommentType) Values() []DocumentReviewCommentType { - return []DocumentReviewCommentType{ - "Comment", - } -} - -type DocumentStatus string - -// Enum values for DocumentStatus -const ( - DocumentStatusCreating DocumentStatus = "Creating" - DocumentStatusActive DocumentStatus = "Active" - DocumentStatusUpdating DocumentStatus = "Updating" - DocumentStatusDeleting DocumentStatus = "Deleting" - DocumentStatusFailed DocumentStatus = "Failed" -) - -// Values returns all known values for DocumentStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentStatus) Values() []DocumentStatus { - return []DocumentStatus{ - "Creating", - "Active", - "Updating", - "Deleting", - "Failed", - } -} - -type DocumentType string - -// Enum values for DocumentType -const ( - DocumentTypeCommand DocumentType = "Command" - DocumentTypePolicy DocumentType = "Policy" - DocumentTypeAutomation DocumentType = "Automation" - DocumentTypeSession DocumentType = "Session" - DocumentTypePackage DocumentType = "Package" - DocumentTypeApplicationConfiguration DocumentType = "ApplicationConfiguration" - DocumentTypeApplicationConfigurationSchema DocumentType = "ApplicationConfigurationSchema" - DocumentTypeDeploymentStrategy DocumentType = "DeploymentStrategy" - DocumentTypeChangeCalendar DocumentType = "ChangeCalendar" - DocumentTypeChangeTemplate DocumentType = "Automation.ChangeTemplate" - DocumentTypeProblemAnalysis DocumentType = "ProblemAnalysis" - DocumentTypeProblemAnalysisTemplate DocumentType = "ProblemAnalysisTemplate" - DocumentTypeCloudFormation DocumentType = "CloudFormation" - DocumentTypeConformancePackTemplate DocumentType = "ConformancePackTemplate" - DocumentTypeQuickSetup DocumentType = "QuickSetup" -) - -// Values returns all known values for DocumentType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (DocumentType) Values() []DocumentType { - return []DocumentType{ - "Command", - "Policy", - "Automation", - "Session", - "Package", - "ApplicationConfiguration", - "ApplicationConfigurationSchema", - "DeploymentStrategy", - "ChangeCalendar", - "Automation.ChangeTemplate", - "ProblemAnalysis", - "ProblemAnalysisTemplate", - "CloudFormation", - "ConformancePackTemplate", - "QuickSetup", - } -} - -type ExecutionMode string - -// Enum values for ExecutionMode -const ( - ExecutionModeAuto ExecutionMode = "Auto" - ExecutionModeInteractive ExecutionMode = "Interactive" -) - -// Values returns all known values for ExecutionMode. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ExecutionMode) Values() []ExecutionMode { - return []ExecutionMode{ - "Auto", - "Interactive", - } -} - -type ExternalAlarmState string - -// Enum values for ExternalAlarmState -const ( - ExternalAlarmStateUnknown ExternalAlarmState = "UNKNOWN" - ExternalAlarmStateAlarm ExternalAlarmState = "ALARM" -) - -// Values returns all known values for ExternalAlarmState. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ExternalAlarmState) Values() []ExternalAlarmState { - return []ExternalAlarmState{ - "UNKNOWN", - "ALARM", - } -} - -type Fault string - -// Enum values for Fault -const ( - FaultClient Fault = "Client" - FaultServer Fault = "Server" - FaultUnknown Fault = "Unknown" -) - -// Values returns all known values for Fault. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. -func (Fault) Values() []Fault { - return []Fault{ - "Client", - "Server", - "Unknown", - } -} - -type InstanceInformationFilterKey string - -// Enum values for InstanceInformationFilterKey -const ( - InstanceInformationFilterKeyInstanceIds InstanceInformationFilterKey = "InstanceIds" - InstanceInformationFilterKeyAgentVersion InstanceInformationFilterKey = "AgentVersion" - InstanceInformationFilterKeyPingStatus InstanceInformationFilterKey = "PingStatus" - InstanceInformationFilterKeyPlatformTypes InstanceInformationFilterKey = "PlatformTypes" - InstanceInformationFilterKeyActivationIds InstanceInformationFilterKey = "ActivationIds" - InstanceInformationFilterKeyIamRole InstanceInformationFilterKey = "IamRole" - InstanceInformationFilterKeyResourceType InstanceInformationFilterKey = "ResourceType" - InstanceInformationFilterKeyAssociationStatus InstanceInformationFilterKey = "AssociationStatus" -) - -// Values returns all known values for InstanceInformationFilterKey. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (InstanceInformationFilterKey) Values() []InstanceInformationFilterKey { - return []InstanceInformationFilterKey{ - "InstanceIds", - "AgentVersion", - "PingStatus", - "PlatformTypes", - "ActivationIds", - "IamRole", - "ResourceType", - "AssociationStatus", - } -} - -type InstancePatchStateOperatorType string - -// Enum values for InstancePatchStateOperatorType -const ( - InstancePatchStateOperatorTypeEqual InstancePatchStateOperatorType = "Equal" - InstancePatchStateOperatorTypeNotEqual InstancePatchStateOperatorType = "NotEqual" - InstancePatchStateOperatorTypeLessThan InstancePatchStateOperatorType = "LessThan" - InstancePatchStateOperatorTypeGreaterThan InstancePatchStateOperatorType = "GreaterThan" -) - -// Values returns all known values for InstancePatchStateOperatorType. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (InstancePatchStateOperatorType) Values() []InstancePatchStateOperatorType { - return []InstancePatchStateOperatorType{ - "Equal", - "NotEqual", - "LessThan", - "GreaterThan", - } -} - -type InventoryAttributeDataType string - -// Enum values for InventoryAttributeDataType -const ( - InventoryAttributeDataTypeString InventoryAttributeDataType = "string" - InventoryAttributeDataTypeNumber InventoryAttributeDataType = "number" -) - -// Values returns all known values for InventoryAttributeDataType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (InventoryAttributeDataType) Values() []InventoryAttributeDataType { - return []InventoryAttributeDataType{ - "string", - "number", - } -} - -type InventoryDeletionStatus string - -// Enum values for InventoryDeletionStatus -const ( - InventoryDeletionStatusInProgress InventoryDeletionStatus = "InProgress" - InventoryDeletionStatusComplete InventoryDeletionStatus = "Complete" -) - -// Values returns all known values for InventoryDeletionStatus. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (InventoryDeletionStatus) Values() []InventoryDeletionStatus { - return []InventoryDeletionStatus{ - "InProgress", - "Complete", - } -} - -type InventoryQueryOperatorType string - -// Enum values for InventoryQueryOperatorType -const ( - InventoryQueryOperatorTypeEqual InventoryQueryOperatorType = "Equal" - InventoryQueryOperatorTypeNotEqual InventoryQueryOperatorType = "NotEqual" - InventoryQueryOperatorTypeBeginWith InventoryQueryOperatorType = "BeginWith" - InventoryQueryOperatorTypeLessThan InventoryQueryOperatorType = "LessThan" - InventoryQueryOperatorTypeGreaterThan InventoryQueryOperatorType = "GreaterThan" - InventoryQueryOperatorTypeExists InventoryQueryOperatorType = "Exists" -) - -// Values returns all known values for InventoryQueryOperatorType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (InventoryQueryOperatorType) Values() []InventoryQueryOperatorType { - return []InventoryQueryOperatorType{ - "Equal", - "NotEqual", - "BeginWith", - "LessThan", - "GreaterThan", - "Exists", - } -} - -type InventorySchemaDeleteOption string - -// Enum values for InventorySchemaDeleteOption -const ( - InventorySchemaDeleteOptionDisableSchema InventorySchemaDeleteOption = "DisableSchema" - InventorySchemaDeleteOptionDeleteSchema InventorySchemaDeleteOption = "DeleteSchema" -) - -// Values returns all known values for InventorySchemaDeleteOption. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (InventorySchemaDeleteOption) Values() []InventorySchemaDeleteOption { - return []InventorySchemaDeleteOption{ - "DisableSchema", - "DeleteSchema", - } -} - -type LastResourceDataSyncStatus string - -// Enum values for LastResourceDataSyncStatus -const ( - LastResourceDataSyncStatusSuccessful LastResourceDataSyncStatus = "Successful" - LastResourceDataSyncStatusFailed LastResourceDataSyncStatus = "Failed" - LastResourceDataSyncStatusInprogress LastResourceDataSyncStatus = "InProgress" -) - -// Values returns all known values for LastResourceDataSyncStatus. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (LastResourceDataSyncStatus) Values() []LastResourceDataSyncStatus { - return []LastResourceDataSyncStatus{ - "Successful", - "Failed", - "InProgress", - } -} - -type MaintenanceWindowExecutionStatus string - -// Enum values for MaintenanceWindowExecutionStatus -const ( - MaintenanceWindowExecutionStatusPending MaintenanceWindowExecutionStatus = "PENDING" - MaintenanceWindowExecutionStatusInProgress MaintenanceWindowExecutionStatus = "IN_PROGRESS" - MaintenanceWindowExecutionStatusSuccess MaintenanceWindowExecutionStatus = "SUCCESS" - MaintenanceWindowExecutionStatusFailed MaintenanceWindowExecutionStatus = "FAILED" - MaintenanceWindowExecutionStatusTimedOut MaintenanceWindowExecutionStatus = "TIMED_OUT" - MaintenanceWindowExecutionStatusCancelling MaintenanceWindowExecutionStatus = "CANCELLING" - MaintenanceWindowExecutionStatusCancelled MaintenanceWindowExecutionStatus = "CANCELLED" - MaintenanceWindowExecutionStatusSkippedOverlapping MaintenanceWindowExecutionStatus = "SKIPPED_OVERLAPPING" -) - -// Values returns all known values for MaintenanceWindowExecutionStatus. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (MaintenanceWindowExecutionStatus) Values() []MaintenanceWindowExecutionStatus { - return []MaintenanceWindowExecutionStatus{ - "PENDING", - "IN_PROGRESS", - "SUCCESS", - "FAILED", - "TIMED_OUT", - "CANCELLING", - "CANCELLED", - "SKIPPED_OVERLAPPING", - } -} - -type MaintenanceWindowResourceType string - -// Enum values for MaintenanceWindowResourceType -const ( - MaintenanceWindowResourceTypeInstance MaintenanceWindowResourceType = "INSTANCE" - MaintenanceWindowResourceTypeResourceGroup MaintenanceWindowResourceType = "RESOURCE_GROUP" -) - -// Values returns all known values for MaintenanceWindowResourceType. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (MaintenanceWindowResourceType) Values() []MaintenanceWindowResourceType { - return []MaintenanceWindowResourceType{ - "INSTANCE", - "RESOURCE_GROUP", - } -} - -type MaintenanceWindowTaskCutoffBehavior string - -// Enum values for MaintenanceWindowTaskCutoffBehavior -const ( - MaintenanceWindowTaskCutoffBehaviorContinueTask MaintenanceWindowTaskCutoffBehavior = "CONTINUE_TASK" - MaintenanceWindowTaskCutoffBehaviorCancelTask MaintenanceWindowTaskCutoffBehavior = "CANCEL_TASK" -) - -// Values returns all known values for MaintenanceWindowTaskCutoffBehavior. Note -// that this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (MaintenanceWindowTaskCutoffBehavior) Values() []MaintenanceWindowTaskCutoffBehavior { - return []MaintenanceWindowTaskCutoffBehavior{ - "CONTINUE_TASK", - "CANCEL_TASK", - } -} - -type MaintenanceWindowTaskType string - -// Enum values for MaintenanceWindowTaskType -const ( - MaintenanceWindowTaskTypeRunCommand MaintenanceWindowTaskType = "RUN_COMMAND" - MaintenanceWindowTaskTypeAutomation MaintenanceWindowTaskType = "AUTOMATION" - MaintenanceWindowTaskTypeStepFunctions MaintenanceWindowTaskType = "STEP_FUNCTIONS" - MaintenanceWindowTaskTypeLambda MaintenanceWindowTaskType = "LAMBDA" -) - -// Values returns all known values for MaintenanceWindowTaskType. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (MaintenanceWindowTaskType) Values() []MaintenanceWindowTaskType { - return []MaintenanceWindowTaskType{ - "RUN_COMMAND", - "AUTOMATION", - "STEP_FUNCTIONS", - "LAMBDA", - } -} - -type NotificationEvent string - -// Enum values for NotificationEvent -const ( - NotificationEventAll NotificationEvent = "All" - NotificationEventInProgress NotificationEvent = "InProgress" - NotificationEventSuccess NotificationEvent = "Success" - NotificationEventTimedOut NotificationEvent = "TimedOut" - NotificationEventCancelled NotificationEvent = "Cancelled" - NotificationEventFailed NotificationEvent = "Failed" -) - -// Values returns all known values for NotificationEvent. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (NotificationEvent) Values() []NotificationEvent { - return []NotificationEvent{ - "All", - "InProgress", - "Success", - "TimedOut", - "Cancelled", - "Failed", - } -} - -type NotificationType string - -// Enum values for NotificationType -const ( - NotificationTypeCommand NotificationType = "Command" - NotificationTypeInvocation NotificationType = "Invocation" -) - -// Values returns all known values for NotificationType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (NotificationType) Values() []NotificationType { - return []NotificationType{ - "Command", - "Invocation", - } -} - -type OperatingSystem string - -// Enum values for OperatingSystem -const ( - OperatingSystemWindows OperatingSystem = "WINDOWS" - OperatingSystemAmazonLinux OperatingSystem = "AMAZON_LINUX" - OperatingSystemAmazonLinux2 OperatingSystem = "AMAZON_LINUX_2" - OperatingSystemAmazonLinux2022 OperatingSystem = "AMAZON_LINUX_2022" - OperatingSystemUbuntu OperatingSystem = "UBUNTU" - OperatingSystemRedhatEnterpriseLinux OperatingSystem = "REDHAT_ENTERPRISE_LINUX" - OperatingSystemSuse OperatingSystem = "SUSE" - OperatingSystemCentOS OperatingSystem = "CENTOS" - OperatingSystemOracleLinux OperatingSystem = "ORACLE_LINUX" - OperatingSystemDebian OperatingSystem = "DEBIAN" - OperatingSystemMacOS OperatingSystem = "MACOS" - OperatingSystemRaspbian OperatingSystem = "RASPBIAN" - OperatingSystemRockyLinux OperatingSystem = "ROCKY_LINUX" - OperatingSystemAlmaLinux OperatingSystem = "ALMA_LINUX" - OperatingSystemAmazonLinux2023 OperatingSystem = "AMAZON_LINUX_2023" -) - -// Values returns all known values for OperatingSystem. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OperatingSystem) Values() []OperatingSystem { - return []OperatingSystem{ - "WINDOWS", - "AMAZON_LINUX", - "AMAZON_LINUX_2", - "AMAZON_LINUX_2022", - "UBUNTU", - "REDHAT_ENTERPRISE_LINUX", - "SUSE", - "CENTOS", - "ORACLE_LINUX", - "DEBIAN", - "MACOS", - "RASPBIAN", - "ROCKY_LINUX", - "ALMA_LINUX", - "AMAZON_LINUX_2023", - } -} - -type OpsFilterOperatorType string - -// Enum values for OpsFilterOperatorType -const ( - OpsFilterOperatorTypeEqual OpsFilterOperatorType = "Equal" - OpsFilterOperatorTypeNotEqual OpsFilterOperatorType = "NotEqual" - OpsFilterOperatorTypeBeginWith OpsFilterOperatorType = "BeginWith" - OpsFilterOperatorTypeLessThan OpsFilterOperatorType = "LessThan" - OpsFilterOperatorTypeGreaterThan OpsFilterOperatorType = "GreaterThan" - OpsFilterOperatorTypeExists OpsFilterOperatorType = "Exists" -) - -// Values returns all known values for OpsFilterOperatorType. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsFilterOperatorType) Values() []OpsFilterOperatorType { - return []OpsFilterOperatorType{ - "Equal", - "NotEqual", - "BeginWith", - "LessThan", - "GreaterThan", - "Exists", - } -} - -type OpsItemDataType string - -// Enum values for OpsItemDataType -const ( - OpsItemDataTypeSearchableString OpsItemDataType = "SearchableString" - OpsItemDataTypeString OpsItemDataType = "String" -) - -// Values returns all known values for OpsItemDataType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemDataType) Values() []OpsItemDataType { - return []OpsItemDataType{ - "SearchableString", - "String", - } -} - -type OpsItemEventFilterKey string - -// Enum values for OpsItemEventFilterKey -const ( - OpsItemEventFilterKeyOpsitemId OpsItemEventFilterKey = "OpsItemId" -) - -// Values returns all known values for OpsItemEventFilterKey. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemEventFilterKey) Values() []OpsItemEventFilterKey { - return []OpsItemEventFilterKey{ - "OpsItemId", - } -} - -type OpsItemEventFilterOperator string - -// Enum values for OpsItemEventFilterOperator -const ( - OpsItemEventFilterOperatorEqual OpsItemEventFilterOperator = "Equal" -) - -// Values returns all known values for OpsItemEventFilterOperator. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemEventFilterOperator) Values() []OpsItemEventFilterOperator { - return []OpsItemEventFilterOperator{ - "Equal", - } -} - -type OpsItemFilterKey string - -// Enum values for OpsItemFilterKey -const ( - OpsItemFilterKeyStatus OpsItemFilterKey = "Status" - OpsItemFilterKeyCreatedBy OpsItemFilterKey = "CreatedBy" - OpsItemFilterKeySource OpsItemFilterKey = "Source" - OpsItemFilterKeyPriority OpsItemFilterKey = "Priority" - OpsItemFilterKeyTitle OpsItemFilterKey = "Title" - OpsItemFilterKeyOpsitemId OpsItemFilterKey = "OpsItemId" - OpsItemFilterKeyCreatedTime OpsItemFilterKey = "CreatedTime" - OpsItemFilterKeyLastModifiedTime OpsItemFilterKey = "LastModifiedTime" - OpsItemFilterKeyActualStartTime OpsItemFilterKey = "ActualStartTime" - OpsItemFilterKeyActualEndTime OpsItemFilterKey = "ActualEndTime" - OpsItemFilterKeyPlannedStartTime OpsItemFilterKey = "PlannedStartTime" - OpsItemFilterKeyPlannedEndTime OpsItemFilterKey = "PlannedEndTime" - OpsItemFilterKeyOperationalData OpsItemFilterKey = "OperationalData" - OpsItemFilterKeyOperationalDataKey OpsItemFilterKey = "OperationalDataKey" - OpsItemFilterKeyOperationalDataValue OpsItemFilterKey = "OperationalDataValue" - OpsItemFilterKeyResourceId OpsItemFilterKey = "ResourceId" - OpsItemFilterKeyAutomationId OpsItemFilterKey = "AutomationId" - OpsItemFilterKeyCategory OpsItemFilterKey = "Category" - OpsItemFilterKeySeverity OpsItemFilterKey = "Severity" - OpsItemFilterKeyOpsitemType OpsItemFilterKey = "OpsItemType" - OpsItemFilterKeyChangeRequestRequesterArn OpsItemFilterKey = "ChangeRequestByRequesterArn" - OpsItemFilterKeyChangeRequestRequesterName OpsItemFilterKey = "ChangeRequestByRequesterName" - OpsItemFilterKeyChangeRequestApproverArn OpsItemFilterKey = "ChangeRequestByApproverArn" - OpsItemFilterKeyChangeRequestApproverName OpsItemFilterKey = "ChangeRequestByApproverName" - OpsItemFilterKeyChangeRequestTemplate OpsItemFilterKey = "ChangeRequestByTemplate" - OpsItemFilterKeyChangeRequestTargetsResourceGroup OpsItemFilterKey = "ChangeRequestByTargetsResourceGroup" - OpsItemFilterKeyInsightType OpsItemFilterKey = "InsightByType" - OpsItemFilterKeyAccountId OpsItemFilterKey = "AccountId" -) - -// Values returns all known values for OpsItemFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemFilterKey) Values() []OpsItemFilterKey { - return []OpsItemFilterKey{ - "Status", - "CreatedBy", - "Source", - "Priority", - "Title", - "OpsItemId", - "CreatedTime", - "LastModifiedTime", - "ActualStartTime", - "ActualEndTime", - "PlannedStartTime", - "PlannedEndTime", - "OperationalData", - "OperationalDataKey", - "OperationalDataValue", - "ResourceId", - "AutomationId", - "Category", - "Severity", - "OpsItemType", - "ChangeRequestByRequesterArn", - "ChangeRequestByRequesterName", - "ChangeRequestByApproverArn", - "ChangeRequestByApproverName", - "ChangeRequestByTemplate", - "ChangeRequestByTargetsResourceGroup", - "InsightByType", - "AccountId", - } -} - -type OpsItemFilterOperator string - -// Enum values for OpsItemFilterOperator -const ( - OpsItemFilterOperatorEqual OpsItemFilterOperator = "Equal" - OpsItemFilterOperatorContains OpsItemFilterOperator = "Contains" - OpsItemFilterOperatorGreaterThan OpsItemFilterOperator = "GreaterThan" - OpsItemFilterOperatorLessThan OpsItemFilterOperator = "LessThan" -) - -// Values returns all known values for OpsItemFilterOperator. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemFilterOperator) Values() []OpsItemFilterOperator { - return []OpsItemFilterOperator{ - "Equal", - "Contains", - "GreaterThan", - "LessThan", - } -} - -type OpsItemRelatedItemsFilterKey string - -// Enum values for OpsItemRelatedItemsFilterKey -const ( - OpsItemRelatedItemsFilterKeyResourceType OpsItemRelatedItemsFilterKey = "ResourceType" - OpsItemRelatedItemsFilterKeyAssociationId OpsItemRelatedItemsFilterKey = "AssociationId" - OpsItemRelatedItemsFilterKeyResourceUri OpsItemRelatedItemsFilterKey = "ResourceUri" -) - -// Values returns all known values for OpsItemRelatedItemsFilterKey. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (OpsItemRelatedItemsFilterKey) Values() []OpsItemRelatedItemsFilterKey { - return []OpsItemRelatedItemsFilterKey{ - "ResourceType", - "AssociationId", - "ResourceUri", - } -} - -type OpsItemRelatedItemsFilterOperator string - -// Enum values for OpsItemRelatedItemsFilterOperator -const ( - OpsItemRelatedItemsFilterOperatorEqual OpsItemRelatedItemsFilterOperator = "Equal" -) - -// Values returns all known values for OpsItemRelatedItemsFilterOperator. Note -// that this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (OpsItemRelatedItemsFilterOperator) Values() []OpsItemRelatedItemsFilterOperator { - return []OpsItemRelatedItemsFilterOperator{ - "Equal", - } -} - -type OpsItemStatus string - -// Enum values for OpsItemStatus -const ( - OpsItemStatusOpen OpsItemStatus = "Open" - OpsItemStatusInProgress OpsItemStatus = "InProgress" - OpsItemStatusResolved OpsItemStatus = "Resolved" - OpsItemStatusPending OpsItemStatus = "Pending" - OpsItemStatusTimedOut OpsItemStatus = "TimedOut" - OpsItemStatusCancelling OpsItemStatus = "Cancelling" - OpsItemStatusCancelled OpsItemStatus = "Cancelled" - OpsItemStatusFailed OpsItemStatus = "Failed" - OpsItemStatusCompletedWithSuccess OpsItemStatus = "CompletedWithSuccess" - OpsItemStatusCompletedWithFailure OpsItemStatus = "CompletedWithFailure" - OpsItemStatusScheduled OpsItemStatus = "Scheduled" - OpsItemStatusRunbookInProgress OpsItemStatus = "RunbookInProgress" - OpsItemStatusPendingChangeCalendarOverride OpsItemStatus = "PendingChangeCalendarOverride" - OpsItemStatusChangeCalendarOverrideApproved OpsItemStatus = "ChangeCalendarOverrideApproved" - OpsItemStatusChangeCalendarOverrideRejected OpsItemStatus = "ChangeCalendarOverrideRejected" - OpsItemStatusPendingApproval OpsItemStatus = "PendingApproval" - OpsItemStatusApproved OpsItemStatus = "Approved" - OpsItemStatusRejected OpsItemStatus = "Rejected" - OpsItemStatusClosed OpsItemStatus = "Closed" -) - -// Values returns all known values for OpsItemStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (OpsItemStatus) Values() []OpsItemStatus { - return []OpsItemStatus{ - "Open", - "InProgress", - "Resolved", - "Pending", - "TimedOut", - "Cancelling", - "Cancelled", - "Failed", - "CompletedWithSuccess", - "CompletedWithFailure", - "Scheduled", - "RunbookInProgress", - "PendingChangeCalendarOverride", - "ChangeCalendarOverrideApproved", - "ChangeCalendarOverrideRejected", - "PendingApproval", - "Approved", - "Rejected", - "Closed", - } -} - -type ParametersFilterKey string - -// Enum values for ParametersFilterKey -const ( - ParametersFilterKeyName ParametersFilterKey = "Name" - ParametersFilterKeyType ParametersFilterKey = "Type" - ParametersFilterKeyKeyId ParametersFilterKey = "KeyId" -) - -// Values returns all known values for ParametersFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ParametersFilterKey) Values() []ParametersFilterKey { - return []ParametersFilterKey{ - "Name", - "Type", - "KeyId", - } -} - -type ParameterTier string - -// Enum values for ParameterTier -const ( - ParameterTierStandard ParameterTier = "Standard" - ParameterTierAdvanced ParameterTier = "Advanced" - ParameterTierIntelligentTiering ParameterTier = "Intelligent-Tiering" -) - -// Values returns all known values for ParameterTier. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ParameterTier) Values() []ParameterTier { - return []ParameterTier{ - "Standard", - "Advanced", - "Intelligent-Tiering", - } -} - -type ParameterType string - -// Enum values for ParameterType -const ( - ParameterTypeString ParameterType = "String" - ParameterTypeStringList ParameterType = "StringList" - ParameterTypeSecureString ParameterType = "SecureString" -) - -// Values returns all known values for ParameterType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ParameterType) Values() []ParameterType { - return []ParameterType{ - "String", - "StringList", - "SecureString", - } -} - -type PatchAction string - -// Enum values for PatchAction -const ( - PatchActionAllowAsDependency PatchAction = "ALLOW_AS_DEPENDENCY" - PatchActionBlock PatchAction = "BLOCK" -) - -// Values returns all known values for PatchAction. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (PatchAction) Values() []PatchAction { - return []PatchAction{ - "ALLOW_AS_DEPENDENCY", - "BLOCK", - } -} - -type PatchComplianceDataState string - -// Enum values for PatchComplianceDataState -const ( - PatchComplianceDataStateInstalled PatchComplianceDataState = "INSTALLED" - PatchComplianceDataStateInstalledOther PatchComplianceDataState = "INSTALLED_OTHER" - PatchComplianceDataStateInstalledPendingReboot PatchComplianceDataState = "INSTALLED_PENDING_REBOOT" - PatchComplianceDataStateInstalledRejected PatchComplianceDataState = "INSTALLED_REJECTED" - PatchComplianceDataStateMissing PatchComplianceDataState = "MISSING" - PatchComplianceDataStateNotApplicable PatchComplianceDataState = "NOT_APPLICABLE" - PatchComplianceDataStateFailed PatchComplianceDataState = "FAILED" -) - -// Values returns all known values for PatchComplianceDataState. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (PatchComplianceDataState) Values() []PatchComplianceDataState { - return []PatchComplianceDataState{ - "INSTALLED", - "INSTALLED_OTHER", - "INSTALLED_PENDING_REBOOT", - "INSTALLED_REJECTED", - "MISSING", - "NOT_APPLICABLE", - "FAILED", - } -} - -type PatchComplianceLevel string - -// Enum values for PatchComplianceLevel -const ( - PatchComplianceLevelCritical PatchComplianceLevel = "CRITICAL" - PatchComplianceLevelHigh PatchComplianceLevel = "HIGH" - PatchComplianceLevelMedium PatchComplianceLevel = "MEDIUM" - PatchComplianceLevelLow PatchComplianceLevel = "LOW" - PatchComplianceLevelInformational PatchComplianceLevel = "INFORMATIONAL" - PatchComplianceLevelUnspecified PatchComplianceLevel = "UNSPECIFIED" -) - -// Values returns all known values for PatchComplianceLevel. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PatchComplianceLevel) Values() []PatchComplianceLevel { - return []PatchComplianceLevel{ - "CRITICAL", - "HIGH", - "MEDIUM", - "LOW", - "INFORMATIONAL", - "UNSPECIFIED", - } -} - -type PatchDeploymentStatus string - -// Enum values for PatchDeploymentStatus -const ( - PatchDeploymentStatusApproved PatchDeploymentStatus = "APPROVED" - PatchDeploymentStatusPendingApproval PatchDeploymentStatus = "PENDING_APPROVAL" - PatchDeploymentStatusExplicitApproved PatchDeploymentStatus = "EXPLICIT_APPROVED" - PatchDeploymentStatusExplicitRejected PatchDeploymentStatus = "EXPLICIT_REJECTED" -) - -// Values returns all known values for PatchDeploymentStatus. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PatchDeploymentStatus) Values() []PatchDeploymentStatus { - return []PatchDeploymentStatus{ - "APPROVED", - "PENDING_APPROVAL", - "EXPLICIT_APPROVED", - "EXPLICIT_REJECTED", - } -} - -type PatchFilterKey string - -// Enum values for PatchFilterKey -const ( - PatchFilterKeyArch PatchFilterKey = "ARCH" - PatchFilterKeyAdvisoryId PatchFilterKey = "ADVISORY_ID" - PatchFilterKeyBugzillaId PatchFilterKey = "BUGZILLA_ID" - PatchFilterKeyPatchSet PatchFilterKey = "PATCH_SET" - PatchFilterKeyProduct PatchFilterKey = "PRODUCT" - PatchFilterKeyProductFamily PatchFilterKey = "PRODUCT_FAMILY" - PatchFilterKeyClassification PatchFilterKey = "CLASSIFICATION" - PatchFilterKeyCVEId PatchFilterKey = "CVE_ID" - PatchFilterKeyEpoch PatchFilterKey = "EPOCH" - PatchFilterKeyMsrcSeverity PatchFilterKey = "MSRC_SEVERITY" - PatchFilterKeyName PatchFilterKey = "NAME" - PatchFilterKeyPatchId PatchFilterKey = "PATCH_ID" - PatchFilterKeySection PatchFilterKey = "SECTION" - PatchFilterKeyPriority PatchFilterKey = "PRIORITY" - PatchFilterKeyRepository PatchFilterKey = "REPOSITORY" - PatchFilterKeyRelease PatchFilterKey = "RELEASE" - PatchFilterKeySeverity PatchFilterKey = "SEVERITY" - PatchFilterKeySecurity PatchFilterKey = "SECURITY" - PatchFilterKeyVersion PatchFilterKey = "VERSION" -) - -// Values returns all known values for PatchFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PatchFilterKey) Values() []PatchFilterKey { - return []PatchFilterKey{ - "ARCH", - "ADVISORY_ID", - "BUGZILLA_ID", - "PATCH_SET", - "PRODUCT", - "PRODUCT_FAMILY", - "CLASSIFICATION", - "CVE_ID", - "EPOCH", - "MSRC_SEVERITY", - "NAME", - "PATCH_ID", - "SECTION", - "PRIORITY", - "REPOSITORY", - "RELEASE", - "SEVERITY", - "SECURITY", - "VERSION", - } -} - -type PatchOperationType string - -// Enum values for PatchOperationType -const ( - PatchOperationTypeScan PatchOperationType = "Scan" - PatchOperationTypeInstall PatchOperationType = "Install" -) - -// Values returns all known values for PatchOperationType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PatchOperationType) Values() []PatchOperationType { - return []PatchOperationType{ - "Scan", - "Install", - } -} - -type PatchProperty string - -// Enum values for PatchProperty -const ( - PatchPropertyProduct PatchProperty = "PRODUCT" - PatchPropertyPatchProductFamily PatchProperty = "PRODUCT_FAMILY" - PatchPropertyPatchClassification PatchProperty = "CLASSIFICATION" - PatchPropertyPatchMsrcSeverity PatchProperty = "MSRC_SEVERITY" - PatchPropertyPatchPriority PatchProperty = "PRIORITY" - PatchPropertyPatchSeverity PatchProperty = "SEVERITY" -) - -// Values returns all known values for PatchProperty. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PatchProperty) Values() []PatchProperty { - return []PatchProperty{ - "PRODUCT", - "PRODUCT_FAMILY", - "CLASSIFICATION", - "MSRC_SEVERITY", - "PRIORITY", - "SEVERITY", - } -} - -type PatchSet string - -// Enum values for PatchSet -const ( - PatchSetOs PatchSet = "OS" - PatchSetApplication PatchSet = "APPLICATION" -) - -// Values returns all known values for PatchSet. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. -func (PatchSet) Values() []PatchSet { - return []PatchSet{ - "OS", - "APPLICATION", - } -} - -type PingStatus string - -// Enum values for PingStatus -const ( - PingStatusOnline PingStatus = "Online" - PingStatusConnectionLost PingStatus = "ConnectionLost" - PingStatusInactive PingStatus = "Inactive" -) - -// Values returns all known values for PingStatus. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (PingStatus) Values() []PingStatus { - return []PingStatus{ - "Online", - "ConnectionLost", - "Inactive", - } -} - -type PlatformType string - -// Enum values for PlatformType -const ( - PlatformTypeWindows PlatformType = "Windows" - PlatformTypeLinux PlatformType = "Linux" - PlatformTypeMacos PlatformType = "MacOS" -) - -// Values returns all known values for PlatformType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (PlatformType) Values() []PlatformType { - return []PlatformType{ - "Windows", - "Linux", - "MacOS", - } -} - -type RebootOption string - -// Enum values for RebootOption -const ( - RebootOptionRebootIfNeeded RebootOption = "RebootIfNeeded" - RebootOptionNoReboot RebootOption = "NoReboot" -) - -// Values returns all known values for RebootOption. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (RebootOption) Values() []RebootOption { - return []RebootOption{ - "RebootIfNeeded", - "NoReboot", - } -} - -type ResourceDataSyncS3Format string - -// Enum values for ResourceDataSyncS3Format -const ( - ResourceDataSyncS3FormatJsonSerde ResourceDataSyncS3Format = "JsonSerDe" -) - -// Values returns all known values for ResourceDataSyncS3Format. Note that this -// can be expanded in the future, and so it is only as up to date as the client. -// The ordering of this slice is not guaranteed to be stable across updates. -func (ResourceDataSyncS3Format) Values() []ResourceDataSyncS3Format { - return []ResourceDataSyncS3Format{ - "JsonSerDe", - } -} - -type ResourceType string - -// Enum values for ResourceType -const ( - ResourceTypeManagedInstance ResourceType = "ManagedInstance" - ResourceTypeEc2Instance ResourceType = "EC2Instance" -) - -// Values returns all known values for ResourceType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ResourceType) Values() []ResourceType { - return []ResourceType{ - "ManagedInstance", - "EC2Instance", - } -} - -type ResourceTypeForTagging string - -// Enum values for ResourceTypeForTagging -const ( - ResourceTypeForTaggingDocument ResourceTypeForTagging = "Document" - ResourceTypeForTaggingManagedInstance ResourceTypeForTagging = "ManagedInstance" - ResourceTypeForTaggingMaintenanceWindow ResourceTypeForTagging = "MaintenanceWindow" - ResourceTypeForTaggingParameter ResourceTypeForTagging = "Parameter" - ResourceTypeForTaggingPatchBaseline ResourceTypeForTagging = "PatchBaseline" - ResourceTypeForTaggingOpsItem ResourceTypeForTagging = "OpsItem" - ResourceTypeForTaggingOpsmetadata ResourceTypeForTagging = "OpsMetadata" - ResourceTypeForTaggingAutomation ResourceTypeForTagging = "Automation" - ResourceTypeForTaggingAssociation ResourceTypeForTagging = "Association" -) - -// Values returns all known values for ResourceTypeForTagging. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ResourceTypeForTagging) Values() []ResourceTypeForTagging { - return []ResourceTypeForTagging{ - "Document", - "ManagedInstance", - "MaintenanceWindow", - "Parameter", - "PatchBaseline", - "OpsItem", - "OpsMetadata", - "Automation", - "Association", - } -} - -type ReviewStatus string - -// Enum values for ReviewStatus -const ( - ReviewStatusApproved ReviewStatus = "APPROVED" - ReviewStatusNotReviewed ReviewStatus = "NOT_REVIEWED" - ReviewStatusPending ReviewStatus = "PENDING" - ReviewStatusRejected ReviewStatus = "REJECTED" -) - -// Values returns all known values for ReviewStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ReviewStatus) Values() []ReviewStatus { - return []ReviewStatus{ - "APPROVED", - "NOT_REVIEWED", - "PENDING", - "REJECTED", - } -} - -type SessionFilterKey string - -// Enum values for SessionFilterKey -const ( - SessionFilterKeyInvokedAfter SessionFilterKey = "InvokedAfter" - SessionFilterKeyInvokedBefore SessionFilterKey = "InvokedBefore" - SessionFilterKeyTargetId SessionFilterKey = "Target" - SessionFilterKeyOwner SessionFilterKey = "Owner" - SessionFilterKeyStatus SessionFilterKey = "Status" - SessionFilterKeySessionId SessionFilterKey = "SessionId" -) - -// Values returns all known values for SessionFilterKey. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (SessionFilterKey) Values() []SessionFilterKey { - return []SessionFilterKey{ - "InvokedAfter", - "InvokedBefore", - "Target", - "Owner", - "Status", - "SessionId", - } -} - -type SessionState string - -// Enum values for SessionState -const ( - SessionStateActive SessionState = "Active" - SessionStateHistory SessionState = "History" -) - -// Values returns all known values for SessionState. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (SessionState) Values() []SessionState { - return []SessionState{ - "Active", - "History", - } -} - -type SessionStatus string - -// Enum values for SessionStatus -const ( - SessionStatusConnected SessionStatus = "Connected" - SessionStatusConnecting SessionStatus = "Connecting" - SessionStatusDisconnected SessionStatus = "Disconnected" - SessionStatusTerminated SessionStatus = "Terminated" - SessionStatusTerminating SessionStatus = "Terminating" - SessionStatusFailed SessionStatus = "Failed" -) - -// Values returns all known values for SessionStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (SessionStatus) Values() []SessionStatus { - return []SessionStatus{ - "Connected", - "Connecting", - "Disconnected", - "Terminated", - "Terminating", - "Failed", - } -} - -type SignalType string - -// Enum values for SignalType -const ( - SignalTypeApprove SignalType = "Approve" - SignalTypeReject SignalType = "Reject" - SignalTypeStartStep SignalType = "StartStep" - SignalTypeStopStep SignalType = "StopStep" - SignalTypeResume SignalType = "Resume" -) - -// Values returns all known values for SignalType. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (SignalType) Values() []SignalType { - return []SignalType{ - "Approve", - "Reject", - "StartStep", - "StopStep", - "Resume", - } -} - -type SourceType string - -// Enum values for SourceType -const ( - SourceTypeAwsEc2Instance SourceType = "AWS::EC2::Instance" - SourceTypeAwsIotThing SourceType = "AWS::IoT::Thing" - SourceTypeAwsSsmManagedinstance SourceType = "AWS::SSM::ManagedInstance" -) - -// Values returns all known values for SourceType. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (SourceType) Values() []SourceType { - return []SourceType{ - "AWS::EC2::Instance", - "AWS::IoT::Thing", - "AWS::SSM::ManagedInstance", - } -} - -type StepExecutionFilterKey string - -// Enum values for StepExecutionFilterKey -const ( - StepExecutionFilterKeyStartTimeBefore StepExecutionFilterKey = "StartTimeBefore" - StepExecutionFilterKeyStartTimeAfter StepExecutionFilterKey = "StartTimeAfter" - StepExecutionFilterKeyStepExecutionStatus StepExecutionFilterKey = "StepExecutionStatus" - StepExecutionFilterKeyStepExecutionId StepExecutionFilterKey = "StepExecutionId" - StepExecutionFilterKeyStepName StepExecutionFilterKey = "StepName" - StepExecutionFilterKeyAction StepExecutionFilterKey = "Action" - StepExecutionFilterKeyParentStepExecutionId StepExecutionFilterKey = "ParentStepExecutionId" - StepExecutionFilterKeyParentStepIteration StepExecutionFilterKey = "ParentStepIteration" - StepExecutionFilterKeyParentStepIteratorValue StepExecutionFilterKey = "ParentStepIteratorValue" -) - -// Values returns all known values for StepExecutionFilterKey. Note that this can -// be expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (StepExecutionFilterKey) Values() []StepExecutionFilterKey { - return []StepExecutionFilterKey{ - "StartTimeBefore", - "StartTimeAfter", - "StepExecutionStatus", - "StepExecutionId", - "StepName", - "Action", - "ParentStepExecutionId", - "ParentStepIteration", - "ParentStepIteratorValue", - } -} - -type StopType string - -// Enum values for StopType -const ( - StopTypeComplete StopType = "Complete" - StopTypeCancel StopType = "Cancel" -) - -// Values returns all known values for StopType. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. -func (StopType) Values() []StopType { - return []StopType{ - "Complete", - "Cancel", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/errors.go deleted file mode 100644 index 61ec235..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/errors.go +++ /dev/null @@ -1,3567 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - "fmt" - smithy "github.com/aws/smithy-go" -) - -// Error returned if an attempt is made to register a patch group with a patch -// baseline that is already registered with a different patch baseline. -type AlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *AlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You must disassociate a document from all managed nodes before you can delete -// it. -type AssociatedInstances struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociatedInstances) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociatedInstances) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociatedInstances) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociatedInstances" - } - return *e.ErrorCodeOverride -} -func (e *AssociatedInstances) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified association already exists. -type AssociationAlreadyExists struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociationAlreadyExists) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociationAlreadyExists) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociationAlreadyExists) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociationAlreadyExists" - } - return *e.ErrorCodeOverride -} -func (e *AssociationAlreadyExists) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified association doesn't exist. -type AssociationDoesNotExist struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociationDoesNotExist) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociationDoesNotExist) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociationDoesNotExist) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociationDoesNotExist" - } - return *e.ErrorCodeOverride -} -func (e *AssociationDoesNotExist) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified execution ID doesn't exist. Verify the ID number and try again. -type AssociationExecutionDoesNotExist struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociationExecutionDoesNotExist) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociationExecutionDoesNotExist) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociationExecutionDoesNotExist) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociationExecutionDoesNotExist" - } - return *e.ErrorCodeOverride -} -func (e *AssociationExecutionDoesNotExist) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You can have at most 2,000 active associations. -type AssociationLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociationLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociationLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociationLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociationLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *AssociationLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You have reached the maximum number versions allowed for an association. Each -// association has a limit of 1,000 versions. -type AssociationVersionLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AssociationVersionLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AssociationVersionLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AssociationVersionLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AssociationVersionLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *AssociationVersionLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the Change Manager change template used in the change request -// was rejected or is still in a pending state. -type AutomationDefinitionNotApprovedException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationDefinitionNotApprovedException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationDefinitionNotApprovedException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationDefinitionNotApprovedException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationDefinitionNotApprovedException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationDefinitionNotApprovedException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// An Automation runbook with the specified name couldn't be found. -type AutomationDefinitionNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationDefinitionNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationDefinitionNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationDefinitionNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationDefinitionNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationDefinitionNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// An Automation runbook with the specified name and version couldn't be found. -type AutomationDefinitionVersionNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationDefinitionVersionNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationDefinitionVersionNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationDefinitionVersionNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationDefinitionVersionNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationDefinitionVersionNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The number of simultaneously running Automation executions exceeded the -// allowable limit. -type AutomationExecutionLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationExecutionLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationExecutionLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationExecutionLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationExecutionLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationExecutionLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// There is no automation execution information for the requested automation -// execution ID. -type AutomationExecutionNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationExecutionNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationExecutionNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationExecutionNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationExecutionNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationExecutionNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified step name and execution ID don't exist. Verify the information -// and try again. -type AutomationStepNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *AutomationStepNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AutomationStepNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AutomationStepNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AutomationStepNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *AutomationStepNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You specified too many custom compliance types. You can specify a maximum of 10 -// different types. -type ComplianceTypeCountLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ComplianceTypeCountLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ComplianceTypeCountLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ComplianceTypeCountLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ComplianceTypeCountLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *ComplianceTypeCountLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// You have exceeded the limit for custom schemas. Delete one or more custom -// schemas and try again. -type CustomSchemaCountLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *CustomSchemaCountLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *CustomSchemaCountLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *CustomSchemaCountLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "CustomSchemaCountLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *CustomSchemaCountLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified document already exists. -type DocumentAlreadyExists struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DocumentAlreadyExists) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DocumentAlreadyExists) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DocumentAlreadyExists) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DocumentAlreadyExists" - } - return *e.ErrorCodeOverride -} -func (e *DocumentAlreadyExists) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You can have at most 500 active SSM documents. -type DocumentLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DocumentLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DocumentLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DocumentLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DocumentLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *DocumentLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The document can't be shared with more Amazon Web Services accounts. You can -// specify a maximum of 20 accounts per API operation to share a private document. -// By default, you can share a private document with a maximum of 1,000 accounts -// and publicly share up to five documents. If you need to increase the quota for -// privately or publicly shared Systems Manager documents, contact Amazon Web -// Services Support. -type DocumentPermissionLimit struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DocumentPermissionLimit) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DocumentPermissionLimit) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DocumentPermissionLimit) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DocumentPermissionLimit" - } - return *e.ErrorCodeOverride -} -func (e *DocumentPermissionLimit) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The document has too many versions. Delete one or more document versions and -// try again. -type DocumentVersionLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DocumentVersionLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DocumentVersionLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DocumentVersionLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DocumentVersionLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *DocumentVersionLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Error returned when the ID specified for a resource, such as a maintenance -// window or patch baseline, doesn't exist. For information about resource quotas -// in Amazon Web Services Systems Manager, see Systems Manager service quotas (https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) -// in the Amazon Web Services General Reference. -type DoesNotExistException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DoesNotExistException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DoesNotExistException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DoesNotExistException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DoesNotExistException" - } - return *e.ErrorCodeOverride -} -func (e *DoesNotExistException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The content of the association document matches another document. Change the -// content of the document and try again. -type DuplicateDocumentContent struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DuplicateDocumentContent) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DuplicateDocumentContent) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DuplicateDocumentContent) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DuplicateDocumentContent" - } - return *e.ErrorCodeOverride -} -func (e *DuplicateDocumentContent) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The version name has already been used in this document. Specify a different -// version name, and then try again. -type DuplicateDocumentVersionName struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DuplicateDocumentVersionName) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DuplicateDocumentVersionName) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DuplicateDocumentVersionName) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DuplicateDocumentVersionName" - } - return *e.ErrorCodeOverride -} -func (e *DuplicateDocumentVersionName) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You can't specify a managed node ID in more than one association. -type DuplicateInstanceId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *DuplicateInstanceId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *DuplicateInstanceId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *DuplicateInstanceId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "DuplicateInstanceId" - } - return *e.ErrorCodeOverride -} -func (e *DuplicateInstanceId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You attempted to register a LAMBDA or STEP_FUNCTIONS task in a region where the -// corresponding service isn't available. -type FeatureNotAvailableException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *FeatureNotAvailableException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *FeatureNotAvailableException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *FeatureNotAvailableException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "FeatureNotAvailableException" - } - return *e.ErrorCodeOverride -} -func (e *FeatureNotAvailableException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A hierarchy can have a maximum of 15 levels. For more information, see -// Requirements and constraints for parameter names (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-parameter-name-constraints.html) -// in the Amazon Web Services Systems Manager User Guide. -type HierarchyLevelLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *HierarchyLevelLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *HierarchyLevelLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *HierarchyLevelLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "HierarchyLevelLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *HierarchyLevelLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// Parameter Store doesn't support changing a parameter type in a hierarchy. For -// example, you can't change a parameter from a String type to a SecureString -// type. You must create a new, unique parameter. -type HierarchyTypeMismatchException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *HierarchyTypeMismatchException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *HierarchyTypeMismatchException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *HierarchyTypeMismatchException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "HierarchyTypeMismatchException" - } - return *e.ErrorCodeOverride -} -func (e *HierarchyTypeMismatchException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Error returned when an idempotent operation is retried and the parameters don't -// match the original call to the API with the same idempotency token. -type IdempotentParameterMismatch struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *IdempotentParameterMismatch) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *IdempotentParameterMismatch) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *IdempotentParameterMismatch) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "IdempotentParameterMismatch" - } - return *e.ErrorCodeOverride -} -func (e *IdempotentParameterMismatch) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// There is a conflict in the policies specified for this parameter. You can't, -// for example, specify two Expiration policies for a parameter. Review your -// policies, and try again. -type IncompatiblePolicyException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *IncompatiblePolicyException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *IncompatiblePolicyException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *IncompatiblePolicyException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "IncompatiblePolicyException" - } - return *e.ErrorCodeOverride -} -func (e *IncompatiblePolicyException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// An error occurred on the server side. -type InternalServerError struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InternalServerError) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InternalServerError) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InternalServerError) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InternalServerError" - } - return *e.ErrorCodeOverride -} -func (e *InternalServerError) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } - -// The activation isn't valid. The activation might have been deleted, or the -// ActivationId and the ActivationCode don't match. -type InvalidActivation struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidActivation) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidActivation) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidActivation) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidActivation" - } - return *e.ErrorCodeOverride -} -func (e *InvalidActivation) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The activation ID isn't valid. Verify the you entered the correct ActivationId -// or ActivationCode and try again. -type InvalidActivationId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidActivationId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidActivationId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidActivationId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidActivationId" - } - return *e.ErrorCodeOverride -} -func (e *InvalidActivationId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified aggregator isn't valid for inventory groups. Verify that the -// aggregator uses a valid inventory type such as AWS:Application or -// AWS:InstanceInformation . -type InvalidAggregatorException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAggregatorException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAggregatorException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAggregatorException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAggregatorException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAggregatorException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The request doesn't meet the regular expression requirement. -type InvalidAllowedPatternException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAllowedPatternException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAllowedPatternException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAllowedPatternException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAllowedPatternException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAllowedPatternException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The association isn't valid or doesn't exist. -type InvalidAssociation struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAssociation) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAssociation) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAssociation) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAssociation" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAssociation) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The version you specified isn't valid. Use ListAssociationVersions to view all -// versions of an association according to the association ID. Or, use the $LATEST -// parameter to view the latest version of the association. -type InvalidAssociationVersion struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAssociationVersion) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAssociationVersion) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAssociationVersion) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAssociationVersion" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAssociationVersion) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The supplied parameters for invoking the specified Automation runbook are -// incorrect. For example, they may not match the set of parameters permitted for -// the specified Automation document. -type InvalidAutomationExecutionParametersException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAutomationExecutionParametersException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAutomationExecutionParametersException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAutomationExecutionParametersException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAutomationExecutionParametersException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAutomationExecutionParametersException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The signal isn't valid for the current Automation execution. -type InvalidAutomationSignalException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAutomationSignalException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAutomationSignalException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAutomationSignalException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAutomationSignalException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAutomationSignalException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified update status operation isn't valid. -type InvalidAutomationStatusUpdateException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAutomationStatusUpdateException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAutomationStatusUpdateException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAutomationStatusUpdateException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAutomationStatusUpdateException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAutomationStatusUpdateException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified command ID isn't valid. Verify the ID and try again. -type InvalidCommandId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidCommandId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidCommandId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidCommandId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidCommandId" - } - return *e.ErrorCodeOverride -} -func (e *InvalidCommandId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// One or more of the parameters specified for the delete operation isn't valid. -// Verify all parameters and try again. -type InvalidDeleteInventoryParametersException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDeleteInventoryParametersException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDeleteInventoryParametersException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDeleteInventoryParametersException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDeleteInventoryParametersException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDeleteInventoryParametersException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The ID specified for the delete operation doesn't exist or isn't valid. Verify -// the ID and try again. -type InvalidDeletionIdException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDeletionIdException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDeletionIdException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDeletionIdException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDeletionIdException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDeletionIdException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified SSM document doesn't exist. -type InvalidDocument struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocument) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocument) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocument) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocument" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocument) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The content for the document isn't valid. -type InvalidDocumentContent struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocumentContent) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocumentContent) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocumentContent) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocumentContent" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocumentContent) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You attempted to delete a document while it is still shared. You must stop -// sharing the document before you can delete it. -type InvalidDocumentOperation struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocumentOperation) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocumentOperation) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocumentOperation) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocumentOperation" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocumentOperation) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The version of the document schema isn't supported. -type InvalidDocumentSchemaVersion struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocumentSchemaVersion) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocumentSchemaVersion) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocumentSchemaVersion) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocumentSchemaVersion" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocumentSchemaVersion) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The SSM document type isn't valid. Valid document types are described in the -// DocumentType property. -type InvalidDocumentType struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocumentType) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocumentType) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocumentType) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocumentType" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocumentType) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The document version isn't valid or doesn't exist. -type InvalidDocumentVersion struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidDocumentVersion) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidDocumentVersion) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidDocumentVersion) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidDocumentVersion" - } - return *e.ErrorCodeOverride -} -func (e *InvalidDocumentVersion) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The filter name isn't valid. Verify the you entered the correct name and try -// again. -type InvalidFilter struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidFilter) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidFilter) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidFilter) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidFilter" - } - return *e.ErrorCodeOverride -} -func (e *InvalidFilter) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified key isn't valid. -type InvalidFilterKey struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidFilterKey) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidFilterKey) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidFilterKey) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidFilterKey" - } - return *e.ErrorCodeOverride -} -func (e *InvalidFilterKey) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified filter option isn't valid. Valid options are Equals and -// BeginsWith. For Path filter, valid options are Recursive and OneLevel. -type InvalidFilterOption struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidFilterOption) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidFilterOption) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidFilterOption) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidFilterOption" - } - return *e.ErrorCodeOverride -} -func (e *InvalidFilterOption) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The filter value isn't valid. Verify the value and try again. -type InvalidFilterValue struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidFilterValue) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidFilterValue) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidFilterValue) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidFilterValue" - } - return *e.ErrorCodeOverride -} -func (e *InvalidFilterValue) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The following problems can cause this exception: -// - You don't have permission to access the managed node. -// - Amazon Web Services Systems Manager Agent(SSM Agent) isn't running. Verify -// that SSM Agent is running. -// - SSM Agent isn't registered with the SSM endpoint. Try reinstalling SSM -// Agent. -// - The managed node isn't in valid state. Valid states are: Running , Pending , -// Stopped , and Stopping . Invalid states are: Shutting-down and Terminated . -type InvalidInstanceId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidInstanceId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidInstanceId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidInstanceId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidInstanceId" - } - return *e.ErrorCodeOverride -} -func (e *InvalidInstanceId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified filter value isn't valid. -type InvalidInstanceInformationFilterValue struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidInstanceInformationFilterValue) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidInstanceInformationFilterValue) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidInstanceInformationFilterValue) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidInstanceInformationFilterValue" - } - return *e.ErrorCodeOverride -} -func (e *InvalidInstanceInformationFilterValue) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified inventory group isn't valid. -type InvalidInventoryGroupException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidInventoryGroupException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidInventoryGroupException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidInventoryGroupException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidInventoryGroupException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidInventoryGroupException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You specified invalid keys or values in the Context attribute for InventoryItem -// . Verify the keys and values, and try again. -type InvalidInventoryItemContextException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidInventoryItemContextException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidInventoryItemContextException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidInventoryItemContextException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidInventoryItemContextException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidInventoryItemContextException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The request isn't valid. -type InvalidInventoryRequestException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidInventoryRequestException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidInventoryRequestException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidInventoryRequestException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidInventoryRequestException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidInventoryRequestException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// One or more content items isn't valid. -type InvalidItemContentException struct { - Message *string - - ErrorCodeOverride *string - - TypeName *string - - noSmithyDocumentSerde -} - -func (e *InvalidItemContentException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidItemContentException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidItemContentException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidItemContentException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidItemContentException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The query key ID isn't valid. -type InvalidKeyId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidKeyId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidKeyId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidKeyId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidKeyId" - } - return *e.ErrorCodeOverride -} -func (e *InvalidKeyId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified token isn't valid. -type InvalidNextToken struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidNextToken) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidNextToken) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidNextToken) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidNextToken" - } - return *e.ErrorCodeOverride -} -func (e *InvalidNextToken) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// One or more configuration items isn't valid. Verify that a valid Amazon -// Resource Name (ARN) was provided for an Amazon Simple Notification Service -// topic. -type InvalidNotificationConfig struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidNotificationConfig) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidNotificationConfig) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidNotificationConfig) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidNotificationConfig" - } - return *e.ErrorCodeOverride -} -func (e *InvalidNotificationConfig) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The delete inventory option specified isn't valid. Verify the option and try -// again. -type InvalidOptionException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidOptionException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidOptionException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidOptionException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidOptionException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidOptionException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The S3 bucket doesn't exist. -type InvalidOutputFolder struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidOutputFolder) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidOutputFolder) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidOutputFolder) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidOutputFolder" - } - return *e.ErrorCodeOverride -} -func (e *InvalidOutputFolder) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The output location isn't valid or doesn't exist. -type InvalidOutputLocation struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidOutputLocation) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidOutputLocation) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidOutputLocation) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidOutputLocation" - } - return *e.ErrorCodeOverride -} -func (e *InvalidOutputLocation) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You must specify values for all required parameters in the Amazon Web Services -// Systems Manager document (SSM document). You can only supply values to -// parameters defined in the SSM document. -type InvalidParameters struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidParameters) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidParameters) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidParameters) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidParameters" - } - return *e.ErrorCodeOverride -} -func (e *InvalidParameters) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The permission type isn't supported. Share is the only supported permission -// type. -type InvalidPermissionType struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidPermissionType) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidPermissionType) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidPermissionType) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidPermissionType" - } - return *e.ErrorCodeOverride -} -func (e *InvalidPermissionType) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The plugin name isn't valid. -type InvalidPluginName struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidPluginName) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidPluginName) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidPluginName) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidPluginName" - } - return *e.ErrorCodeOverride -} -func (e *InvalidPluginName) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A policy attribute or its value is invalid. -type InvalidPolicyAttributeException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidPolicyAttributeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidPolicyAttributeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidPolicyAttributeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidPolicyAttributeException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidPolicyAttributeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The policy type isn't supported. Parameter Store supports the following policy -// types: Expiration, ExpirationNotification, and NoChangeNotification. -type InvalidPolicyTypeException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidPolicyTypeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidPolicyTypeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidPolicyTypeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidPolicyTypeException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidPolicyTypeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The resource ID isn't valid. Verify that you entered the correct ID and try -// again. -type InvalidResourceId struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidResourceId) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidResourceId) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidResourceId) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidResourceId" - } - return *e.ErrorCodeOverride -} -func (e *InvalidResourceId) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The resource type isn't valid. For example, if you are attempting to tag an EC2 -// instance, the instance must be a registered managed node. -type InvalidResourceType struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidResourceType) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidResourceType) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidResourceType) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidResourceType" - } - return *e.ErrorCodeOverride -} -func (e *InvalidResourceType) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified inventory item result attribute isn't valid. -type InvalidResultAttributeException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidResultAttributeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidResultAttributeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidResultAttributeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidResultAttributeException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidResultAttributeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The role name can't contain invalid characters. Also verify that you specified -// an IAM role for notifications that includes the required trust policy. For -// information about configuring the IAM role for Run Command notifications, see -// Configuring Amazon SNS Notifications for Run Command (https://docs.aws.amazon.com/systems-manager/latest/userguide/rc-sns-notifications.html) -// in the Amazon Web Services Systems Manager User Guide. -type InvalidRole struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidRole) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidRole) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidRole) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidRole" - } - return *e.ErrorCodeOverride -} -func (e *InvalidRole) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The schedule is invalid. Verify your cron or rate expression and try again. -type InvalidSchedule struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidSchedule) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidSchedule) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidSchedule) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidSchedule" - } - return *e.ErrorCodeOverride -} -func (e *InvalidSchedule) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified tag key or value isn't valid. -type InvalidTag struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidTag) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidTag) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidTag) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidTag" - } - return *e.ErrorCodeOverride -} -func (e *InvalidTag) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The target isn't valid or doesn't exist. It might not be configured for Systems -// Manager or you might not have permission to perform the operation. -type InvalidTarget struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidTarget) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidTarget) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidTarget) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidTarget" - } - return *e.ErrorCodeOverride -} -func (e *InvalidTarget) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// TargetMap parameter isn't valid. -type InvalidTargetMaps struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidTargetMaps) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidTargetMaps) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidTargetMaps) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidTargetMaps" - } - return *e.ErrorCodeOverride -} -func (e *InvalidTargetMaps) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The parameter type name isn't valid. -type InvalidTypeNameException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidTypeNameException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidTypeNameException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidTypeNameException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidTypeNameException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidTypeNameException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The update isn't valid. -type InvalidUpdate struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidUpdate) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidUpdate) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidUpdate) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidUpdate" - } - return *e.ErrorCodeOverride -} -func (e *InvalidUpdate) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The command ID and managed node ID you specified didn't match any invocations. -// Verify the command ID and the managed node ID and try again. -type InvocationDoesNotExist struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvocationDoesNotExist) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvocationDoesNotExist) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvocationDoesNotExist) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvocationDoesNotExist" - } - return *e.ErrorCodeOverride -} -func (e *InvocationDoesNotExist) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The inventory item has invalid content. -type ItemContentMismatchException struct { - Message *string - - ErrorCodeOverride *string - - TypeName *string - - noSmithyDocumentSerde -} - -func (e *ItemContentMismatchException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ItemContentMismatchException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ItemContentMismatchException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ItemContentMismatchException" - } - return *e.ErrorCodeOverride -} -func (e *ItemContentMismatchException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The inventory item size has exceeded the size limit. -type ItemSizeLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - TypeName *string - - noSmithyDocumentSerde -} - -func (e *ItemSizeLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ItemSizeLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ItemSizeLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ItemSizeLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *ItemSizeLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The size limit of a document is 64 KB. -type MaxDocumentSizeExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *MaxDocumentSizeExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *MaxDocumentSizeExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *MaxDocumentSizeExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "MaxDocumentSizeExceeded" - } - return *e.ErrorCodeOverride -} -func (e *MaxDocumentSizeExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You don't have permission to view OpsItems in the specified account. Verify -// that your account is configured either as a Systems Manager delegated -// administrator or that you are logged into the Organizations management account. -type OpsItemAccessDeniedException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsItemAccessDeniedException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemAccessDeniedException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemAccessDeniedException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemAccessDeniedException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemAccessDeniedException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The OpsItem already exists. -type OpsItemAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - OpsItemId *string - - noSmithyDocumentSerde -} - -func (e *OpsItemAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified OpsItem is in the process of being deleted. -type OpsItemConflictException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsItemConflictException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemConflictException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemConflictException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemConflictException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemConflictException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A specified parameter argument isn't valid. Verify the available arguments and -// try again. -type OpsItemInvalidParameterException struct { - Message *string - - ErrorCodeOverride *string - - ParameterNames []string - - noSmithyDocumentSerde -} - -func (e *OpsItemInvalidParameterException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemInvalidParameterException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemInvalidParameterException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemInvalidParameterException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemInvalidParameterException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The request caused OpsItems to exceed one or more quotas. -type OpsItemLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - ResourceTypes []string - Limit int32 - LimitType *string - - noSmithyDocumentSerde -} - -func (e *OpsItemLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified OpsItem ID doesn't exist. Verify the ID and try again. -type OpsItemNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsItemNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The Amazon Resource Name (ARN) is already associated with the OpsItem. -type OpsItemRelatedItemAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - ResourceUri *string - OpsItemId *string - - noSmithyDocumentSerde -} - -func (e *OpsItemRelatedItemAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemRelatedItemAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemRelatedItemAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemRelatedItemAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemRelatedItemAlreadyExistsException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The association wasn't found using the parameters you specified in the call. -// Verify the information and try again. -type OpsItemRelatedItemAssociationNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsItemRelatedItemAssociationNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsItemRelatedItemAssociationNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsItemRelatedItemAssociationNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsItemRelatedItemAssociationNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *OpsItemRelatedItemAssociationNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// An OpsMetadata object already exists for the selected resource. -type OpsMetadataAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// One of the arguments passed is invalid. -type OpsMetadataInvalidArgumentException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataInvalidArgumentException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataInvalidArgumentException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataInvalidArgumentException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataInvalidArgumentException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataInvalidArgumentException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The OpsMetadata object exceeds the maximum number of OpsMetadata keys that you -// can assign to an application in Application Manager. -type OpsMetadataKeyLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataKeyLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataKeyLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataKeyLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataKeyLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataKeyLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// Your account reached the maximum number of OpsMetadata objects allowed by -// Application Manager. The maximum is 200 OpsMetadata objects. Delete one or more -// OpsMetadata object and try again. -type OpsMetadataLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The OpsMetadata object doesn't exist. -type OpsMetadataNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The system is processing too many concurrent updates. Wait a few moments and -// try again. -type OpsMetadataTooManyUpdatesException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OpsMetadataTooManyUpdatesException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OpsMetadataTooManyUpdatesException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OpsMetadataTooManyUpdatesException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OpsMetadataTooManyUpdatesException" - } - return *e.ErrorCodeOverride -} -func (e *OpsMetadataTooManyUpdatesException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The parameter already exists. You can't create duplicate parameters. -type ParameterAlreadyExists struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterAlreadyExists) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterAlreadyExists) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterAlreadyExists) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterAlreadyExists" - } - return *e.ErrorCodeOverride -} -func (e *ParameterAlreadyExists) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You have exceeded the number of parameters for this Amazon Web Services -// account. Delete one or more parameters and try again. -type ParameterLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *ParameterLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Parameter Store retains the 100 most recently created versions of a parameter. -// After this number of versions has been created, Parameter Store deletes the -// oldest version when a new one is created. However, if the oldest version has a -// label attached to it, Parameter Store won't delete the version and instead -// presents this error message: An error occurred -// (ParameterMaxVersionLimitExceeded) when calling the PutParameter operation: You -// attempted to create a new version of parameter-name by calling the PutParameter -// API with the overwrite flag. Version version-number, the oldest version, can't -// be deleted because it has a label associated with it. Move the label to another -// version of the parameter, and try again. This safeguard is to prevent parameter -// versions with mission critical labels assigned to them from being deleted. To -// continue creating new parameters, first move the label from the oldest version -// of the parameter to a newer one for use in your operations. For information -// about moving parameter labels, see Move a parameter label (console) (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-labels.html#sysman-paramstore-labels-console-move) -// or Move a parameter label (CLI) (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-labels.html#sysman-paramstore-labels-cli-move) -// in the Amazon Web Services Systems Manager User Guide. -type ParameterMaxVersionLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterMaxVersionLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterMaxVersionLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterMaxVersionLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterMaxVersionLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *ParameterMaxVersionLimitExceeded) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The parameter couldn't be found. Verify the name and try again. -type ParameterNotFound struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterNotFound) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterNotFound) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterNotFound) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterNotFound" - } - return *e.ErrorCodeOverride -} -func (e *ParameterNotFound) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The parameter name isn't valid. -type ParameterPatternMismatchException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterPatternMismatchException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterPatternMismatchException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterPatternMismatchException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterPatternMismatchException" - } - return *e.ErrorCodeOverride -} -func (e *ParameterPatternMismatchException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A parameter version can have a maximum of ten labels. -type ParameterVersionLabelLimitExceeded struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterVersionLabelLimitExceeded) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterVersionLabelLimitExceeded) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterVersionLabelLimitExceeded) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterVersionLabelLimitExceeded" - } - return *e.ErrorCodeOverride -} -func (e *ParameterVersionLabelLimitExceeded) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified parameter version wasn't found. Verify the parameter name and -// version, and try again. -type ParameterVersionNotFound struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ParameterVersionNotFound) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ParameterVersionNotFound) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ParameterVersionNotFound) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ParameterVersionNotFound" - } - return *e.ErrorCodeOverride -} -func (e *ParameterVersionNotFound) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You specified more than the maximum number of allowed policies for the -// parameter. The maximum is 10. -type PoliciesLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *PoliciesLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *PoliciesLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *PoliciesLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "PoliciesLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *PoliciesLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A sync configuration with the same name already exists. -type ResourceDataSyncAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - SyncName *string - - noSmithyDocumentSerde -} - -func (e *ResourceDataSyncAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceDataSyncAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceDataSyncAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceDataSyncAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceDataSyncAlreadyExistsException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// Another UpdateResourceDataSync request is being processed. Wait a few minutes -// and try again. -type ResourceDataSyncConflictException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceDataSyncConflictException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceDataSyncConflictException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceDataSyncConflictException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceDataSyncConflictException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceDataSyncConflictException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// You have exceeded the allowed maximum sync configurations. -type ResourceDataSyncCountExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceDataSyncCountExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceDataSyncCountExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceDataSyncCountExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceDataSyncCountExceededException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceDataSyncCountExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified sync configuration is invalid. -type ResourceDataSyncInvalidConfigurationException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceDataSyncInvalidConfigurationException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceDataSyncInvalidConfigurationException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceDataSyncInvalidConfigurationException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceDataSyncInvalidConfigurationException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceDataSyncInvalidConfigurationException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified sync name wasn't found. -type ResourceDataSyncNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - SyncName *string - SyncType *string - - noSmithyDocumentSerde -} - -func (e *ResourceDataSyncNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceDataSyncNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceDataSyncNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceDataSyncNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceDataSyncNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Error returned if an attempt is made to delete a patch baseline that is -// registered for a patch group. -type ResourceInUseException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceInUseException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceInUseException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceInUseException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceInUseException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceInUseException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Error returned when the caller has exceeded the default resource quotas. For -// example, too many maintenance windows or patch baselines have been created. For -// information about resource quotas in Systems Manager, see Systems Manager -// service quotas (https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm) -// in the Amazon Web Services General Reference. -type ResourceLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The hash provided in the call doesn't match the stored hash. This exception is -// thrown when trying to update an obsolete policy version or when multiple -// requests to update a policy are sent. -type ResourcePolicyConflictException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourcePolicyConflictException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourcePolicyConflictException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourcePolicyConflictException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourcePolicyConflictException" - } - return *e.ErrorCodeOverride -} -func (e *ResourcePolicyConflictException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// One or more parameters specified for the call aren't valid. Verify the -// parameters and their values and try again. -type ResourcePolicyInvalidParameterException struct { - Message *string - - ErrorCodeOverride *string - - ParameterNames []string - - noSmithyDocumentSerde -} - -func (e *ResourcePolicyInvalidParameterException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourcePolicyInvalidParameterException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourcePolicyInvalidParameterException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourcePolicyInvalidParameterException" - } - return *e.ErrorCodeOverride -} -func (e *ResourcePolicyInvalidParameterException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The PutResourcePolicy API action enforces two limits. A policy can't be greater -// than 1024 bytes in size. And only one policy can be attached to OpsItemGroup . -// Verify these limits and try again. -type ResourcePolicyLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - Limit int32 - LimitType *string - - noSmithyDocumentSerde -} - -func (e *ResourcePolicyLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourcePolicyLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourcePolicyLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourcePolicyLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *ResourcePolicyLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The specified service setting wasn't found. Either the service name or the -// setting hasn't been provisioned by the Amazon Web Services service team. -type ServiceSettingNotFound struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ServiceSettingNotFound) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ServiceSettingNotFound) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ServiceSettingNotFound) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ServiceSettingNotFound" - } - return *e.ErrorCodeOverride -} -func (e *ServiceSettingNotFound) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The updated status is the same as the current status. -type StatusUnchanged struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *StatusUnchanged) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *StatusUnchanged) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *StatusUnchanged) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "StatusUnchanged" - } - return *e.ErrorCodeOverride -} -func (e *StatusUnchanged) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The sub-type count exceeded the limit for the inventory type. -type SubTypeCountLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *SubTypeCountLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *SubTypeCountLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *SubTypeCountLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "SubTypeCountLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *SubTypeCountLimitExceededException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// You specified the Safe option for the DeregisterTargetFromMaintenanceWindow -// operation, but the target is still referenced in a task. -type TargetInUseException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TargetInUseException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TargetInUseException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TargetInUseException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TargetInUseException" - } - return *e.ErrorCodeOverride -} -func (e *TargetInUseException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified target managed node for the session isn't fully configured for -// use with Session Manager. For more information, see Getting started with -// Session Manager (https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started.html) -// in the Amazon Web Services Systems Manager User Guide. This error is also -// returned if you attempt to start a session on a managed node that is located in -// a different account or Region -type TargetNotConnected struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TargetNotConnected) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TargetNotConnected) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TargetNotConnected) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TargetNotConnected" - } - return *e.ErrorCodeOverride -} -func (e *TargetNotConnected) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The Targets parameter includes too many tags. Remove one or more tags and try -// the command again. -type TooManyTagsError struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TooManyTagsError) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TooManyTagsError) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TooManyTagsError) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TooManyTagsError" - } - return *e.ErrorCodeOverride -} -func (e *TooManyTagsError) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// There are concurrent updates for a resource that supports one update at a time. -type TooManyUpdates struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TooManyUpdates) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TooManyUpdates) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TooManyUpdates) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TooManyUpdates" - } - return *e.ErrorCodeOverride -} -func (e *TooManyUpdates) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The size of inventory data has exceeded the total size limit for the resource. -type TotalSizeLimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TotalSizeLimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TotalSizeLimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TotalSizeLimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TotalSizeLimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *TotalSizeLimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The calendar entry contained in the specified SSM document isn't supported. -type UnsupportedCalendarException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedCalendarException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedCalendarException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedCalendarException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedCalendarException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedCalendarException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Patching for applications released by Microsoft is only available on EC2 -// instances and advanced instances. To patch applications released by Microsoft on -// on-premises servers and VMs, you must enable advanced instances. For more -// information, see Enabling the advanced-instances tier (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-managedinstances-advanced.html) -// in the Amazon Web Services Systems Manager User Guide. -type UnsupportedFeatureRequiredException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedFeatureRequiredException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedFeatureRequiredException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedFeatureRequiredException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedFeatureRequiredException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedFeatureRequiredException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The Context attribute that you specified for the InventoryItem isn't allowed -// for this inventory type. You can only use the Context attribute with inventory -// types like AWS:ComplianceItem . -type UnsupportedInventoryItemContextException struct { - Message *string - - ErrorCodeOverride *string - - TypeName *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedInventoryItemContextException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedInventoryItemContextException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedInventoryItemContextException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedInventoryItemContextException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedInventoryItemContextException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// Inventory item type schema version has to match supported versions in the -// service. Check output of GetInventorySchema to see the available schema version -// for each type. -type UnsupportedInventorySchemaVersionException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedInventorySchemaVersionException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedInventorySchemaVersionException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedInventorySchemaVersionException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedInventorySchemaVersionException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedInventorySchemaVersionException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The operating systems you specified isn't supported, or the operation isn't -// supported for the operating system. -type UnsupportedOperatingSystem struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedOperatingSystem) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedOperatingSystem) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedOperatingSystem) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedOperatingSystem" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedOperatingSystem) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The parameter type isn't supported. -type UnsupportedParameterType struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedParameterType) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedParameterType) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedParameterType) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedParameterType" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedParameterType) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The document doesn't support the platform type of the given managed node ID(s). -// For example, you sent an document for a Windows managed node to a Linux node. -type UnsupportedPlatformType struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedPlatformType) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedPlatformType) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedPlatformType) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedPlatformType" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedPlatformType) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/types.go deleted file mode 100644 index 6ea901a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/types/types.go +++ /dev/null @@ -1,5096 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - smithydocument "github.com/aws/smithy-go/document" - "time" -) - -// Information includes the Amazon Web Services account ID where the current -// document is shared and the version shared with that account. -type AccountSharingInfo struct { - - // The Amazon Web Services account ID where the current document is shared. - AccountId *string - - // The version of the current document shared with the account. - SharedDocumentVersion *string - - noSmithyDocumentSerde -} - -// An activation registers one or more on-premises servers or virtual machines -// (VMs) with Amazon Web Services so that you can configure those servers or VMs -// using Run Command. A server or VM that has been registered with Amazon Web -// Services Systems Manager is called a managed node. -type Activation struct { - - // The ID created by Systems Manager when you submitted the activation. - ActivationId *string - - // The date the activation was created. - CreatedDate *time.Time - - // A name for the managed node when it is created. - DefaultInstanceName *string - - // A user defined description of the activation. - Description *string - - // The date when this activation can no longer be used to register managed nodes. - ExpirationDate *time.Time - - // Whether or not the activation is expired. - Expired bool - - // The Identity and Access Management (IAM) role to assign to the managed node. - IamRole *string - - // The maximum number of managed nodes that can be registered using this - // activation. - RegistrationLimit *int32 - - // The number of managed nodes already registered with this activation. - RegistrationsCount *int32 - - // Tags assigned to the activation. - Tags []Tag - - noSmithyDocumentSerde -} - -// A CloudWatch alarm you apply to an automation or command. -type Alarm struct { - - // The name of your CloudWatch alarm. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -// The details for the CloudWatch alarm you want to apply to an automation or -// command. -type AlarmConfiguration struct { - - // The name of the CloudWatch alarm specified in the configuration. - // - // This member is required. - Alarms []Alarm - - // When this value is true, your automation or command continues to run in cases - // where we can’t retrieve alarm status information from CloudWatch. In cases where - // we successfully retrieve an alarm status of OK or INSUFFICIENT_DATA, the - // automation or command continues to run, regardless of this value. Default is - // false. - IgnorePollAlarmFailure bool - - noSmithyDocumentSerde -} - -// The details about the state of your CloudWatch alarm. -type AlarmStateInformation struct { - - // The name of your CloudWatch alarm. - // - // This member is required. - Name *string - - // The state of your CloudWatch alarm. - // - // This member is required. - State ExternalAlarmState - - noSmithyDocumentSerde -} - -// Describes an association of a Amazon Web Services Systems Manager document (SSM -// document) and a managed node. -type Association struct { - - // The ID created by the system when you create an association. An association is - // a binding between a document and a set of targets with a schedule. - AssociationId *string - - // The association name. - AssociationName *string - - // The association version. - AssociationVersion *string - - // The version of the document used in the association. If you change a document - // version for a State Manager association, Systems Manager immediately runs the - // association unless you previously specifed the apply-only-at-cron-interval - // parameter. State Manager doesn't support running associations that use a new - // version of a document if that document is shared from another account. State - // Manager always runs the default version of a document if shared from another - // account, even though the Systems Manager console shows that a new version was - // processed. If you want to run an association using a new version of a document - // shared form another account, you must set the document version to default . - DocumentVersion *string - - // The managed node ID. - InstanceId *string - - // The date on which the association was last run. - LastExecutionDate *time.Time - - // The name of the SSM document. - Name *string - - // Information about the association. - Overview *AssociationOverview - - // A cron expression that specifies a schedule when the association runs. The - // schedule runs in Coordinated Universal Time (UTC). - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. - ScheduleOffset *int32 - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The managed nodes targeted by the request to create an association. You can - // target all managed nodes in an Amazon Web Services account by specifying the - // InstanceIds key with a value of * . - Targets []Target - - noSmithyDocumentSerde -} - -// Describes the parameters for a document. -type AssociationDescription struct { - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - AlarmConfiguration *AlarmConfiguration - - // By default, when you create a new associations, the system runs it immediately - // after it is created and then according to the schedule you specified. Specify - // this option if you don't want an association to run immediately after you create - // it. This parameter isn't supported for rate expressions. - ApplyOnlyAtCronInterval bool - - // The association ID. - AssociationId *string - - // The association name. - AssociationName *string - - // The association version. - AssociationVersion *string - - // Choose the parameter that will define how your automation will branch out. This - // target is required for associations that use an Automation runbook and target - // resources by using rate controls. Automation is a capability of Amazon Web - // Services Systems Manager. - AutomationTargetParameterName *string - - // The names or Amazon Resource Names (ARNs) of the Change Calendar type documents - // your associations are gated under. The associations only run when that change - // calendar is open. For more information, see Amazon Web Services Systems Manager - // Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar) - // . - CalendarNames []string - - // The severity level that is assigned to the association. - ComplianceSeverity AssociationComplianceSeverity - - // The date when the association was made. - Date *time.Time - - // The document version. - DocumentVersion *string - - // The managed node ID. - InstanceId *string - - // The date on which the association was last run. - LastExecutionDate *time.Time - - // The last date on which the association was successfully run. - LastSuccessfulExecutionDate *time.Time - - // The date when the association was last updated. - LastUpdateAssociationDate *time.Time - - // The maximum number of targets allowed to run the association at the same time. - // You can specify a number, for example 10, or a percentage of the target set, for - // example 10%. The default value is 100%, which means all targets run the - // association at the same time. If a new managed node starts and attempts to run - // an association while Systems Manager is running MaxConcurrency associations, - // the association is allowed to run. During the next association interval, the new - // managed node will process its association within the limit specified for - // MaxConcurrency . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops sending requests - // to run the association on additional targets. You can specify either an absolute - // number of errors, for example 10, or a percentage of the target set, for example - // 10%. If you specify 3, for example, the system stops sending requests when the - // fourth error is received. If you specify 0, then the system stops sending - // requests after the first error is returned. If you run an association on 50 - // managed nodes and set MaxError to 10%, then the system stops sending the - // request when the sixth error is received. Executions that are already running an - // association when MaxErrors is reached are allowed to complete, but some of - // these executions may fail as well. If you need to ensure that there won't be - // more than max-errors failed executions, set MaxConcurrency to 1 so that - // executions proceed one at a time. - MaxErrors *string - - // The name of the SSM document. - Name *string - - // An S3 bucket where you want to store the output details of the request. - OutputLocation *InstanceAssociationOutputLocation - - // Information about the association. - Overview *AssociationOverview - - // A description of the parameters for a document. - Parameters map[string][]string - - // A cron expression that specifies a schedule when the association runs. - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. - ScheduleOffset *int32 - - // The association status. - Status *AssociationStatus - - // The mode for generating association compliance. You can specify AUTO or MANUAL . - // In AUTO mode, the system uses the status of the association execution to - // determine the compliance status. If the association execution runs successfully, - // then the association is COMPLIANT . If the association execution doesn't run - // successfully, the association is NON-COMPLIANT . In MANUAL mode, you must - // specify the AssociationId as a parameter for the PutComplianceItems API - // operation. In this case, compliance data isn't managed by State Manager, a - // capability of Amazon Web Services Systems Manager. It is managed by your direct - // call to the PutComplianceItems API operation. By default, all associations use - // AUTO mode. - SyncCompliance AssociationSyncCompliance - - // The combination of Amazon Web Services Regions and Amazon Web Services accounts - // where you want to run the association. - TargetLocations []TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The managed nodes targeted by the request. - Targets []Target - - // The CloudWatch alarm that was invoked during the association. - TriggeredAlarms []AlarmStateInformation - - noSmithyDocumentSerde -} - -// Includes information about the specified association. -type AssociationExecution struct { - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - AlarmConfiguration *AlarmConfiguration - - // The association ID. - AssociationId *string - - // The association version. - AssociationVersion *string - - // The time the execution started. - CreatedTime *time.Time - - // Detailed status information about the execution. - DetailedStatus *string - - // The execution ID for the association. - ExecutionId *string - - // The date of the last execution. - LastExecutionDate *time.Time - - // An aggregate status of the resources in the execution based on the status type. - ResourceCountByStatus *string - - // The status of the association execution. - Status *string - - // The CloudWatch alarms that were invoked by the association. - TriggeredAlarms []AlarmStateInformation - - noSmithyDocumentSerde -} - -// Filters used in the request. -type AssociationExecutionFilter struct { - - // The key value used in the request. - // - // This member is required. - Key AssociationExecutionFilterKey - - // The filter type specified in the request. - // - // This member is required. - Type AssociationFilterOperatorType - - // The value specified for the key. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Includes information about the specified association execution. -type AssociationExecutionTarget struct { - - // The association ID. - AssociationId *string - - // The association version. - AssociationVersion *string - - // Detailed information about the execution status. - DetailedStatus *string - - // The execution ID. - ExecutionId *string - - // The date of the last execution. - LastExecutionDate *time.Time - - // The location where the association details are saved. - OutputSource *OutputSource - - // The resource ID, for example, the managed node ID where the association ran. - ResourceId *string - - // The resource type, for example, EC2. - ResourceType *string - - // The association execution status. - Status *string - - noSmithyDocumentSerde -} - -// Filters for the association execution. -type AssociationExecutionTargetsFilter struct { - - // The key value used in the request. - // - // This member is required. - Key AssociationExecutionTargetsFilterKey - - // The value specified for the key. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Describes a filter. -type AssociationFilter struct { - - // The name of the filter. InstanceId has been deprecated. - // - // This member is required. - Key AssociationFilterKey - - // The filter value. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Information about the association. -type AssociationOverview struct { - - // Returns the number of targets for the association status. For example, if you - // created an association with two managed nodes, and one of them was successful, - // this would return the count of managed nodes by status. - AssociationStatusAggregatedCount map[string]int32 - - // A detailed status of the association. - DetailedStatus *string - - // The status of the association. Status can be: Pending, Success, or Failed. - Status *string - - noSmithyDocumentSerde -} - -// Describes an association status. -type AssociationStatus struct { - - // The date when the status changed. - // - // This member is required. - Date *time.Time - - // The reason for the status. - // - // This member is required. - Message *string - - // The status. - // - // This member is required. - Name AssociationStatusName - - // A user-defined string. - AdditionalInfo *string - - noSmithyDocumentSerde -} - -// Information about the association version. -type AssociationVersionInfo struct { - - // By default, when you create a new associations, the system runs it immediately - // after it is created and then according to the schedule you specified. Specify - // this option if you don't want an association to run immediately after you create - // it. This parameter isn't supported for rate expressions. - ApplyOnlyAtCronInterval bool - - // The ID created by the system when the association was created. - AssociationId *string - - // The name specified for the association version when the association version was - // created. - AssociationName *string - - // The association version. - AssociationVersion *string - - // The names or Amazon Resource Names (ARNs) of the Change Calendar type documents - // your associations are gated under. The associations for this version only run - // when that Change Calendar is open. For more information, see Amazon Web - // Services Systems Manager Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar) - // . - CalendarNames []string - - // The severity level that is assigned to the association. - ComplianceSeverity AssociationComplianceSeverity - - // The date the association version was created. - CreatedDate *time.Time - - // The version of an Amazon Web Services Systems Manager document (SSM document) - // used when the association version was created. - DocumentVersion *string - - // The maximum number of targets allowed to run the association at the same time. - // You can specify a number, for example 10, or a percentage of the target set, for - // example 10%. The default value is 100%, which means all targets run the - // association at the same time. If a new managed node starts and attempts to run - // an association while Systems Manager is running MaxConcurrency associations, - // the association is allowed to run. During the next association interval, the new - // managed node will process its association within the limit specified for - // MaxConcurrency . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops sending requests - // to run the association on additional targets. You can specify either an absolute - // number of errors, for example 10, or a percentage of the target set, for example - // 10%. If you specify 3, for example, the system stops sending requests when the - // fourth error is received. If you specify 0, then the system stops sending - // requests after the first error is returned. If you run an association on 50 - // managed nodes and set MaxError to 10%, then the system stops sending the - // request when the sixth error is received. Executions that are already running an - // association when MaxErrors is reached are allowed to complete, but some of - // these executions may fail as well. If you need to ensure that there won't be - // more than max-errors failed executions, set MaxConcurrency to 1 so that - // executions proceed one at a time. - MaxErrors *string - - // The name specified when the association was created. - Name *string - - // The location in Amazon S3 specified for the association when the association - // version was created. - OutputLocation *InstanceAssociationOutputLocation - - // Parameters specified when the association version was created. - Parameters map[string][]string - - // The cron or rate schedule specified for the association when the association - // version was created. - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. - ScheduleOffset *int32 - - // The mode for generating association compliance. You can specify AUTO or MANUAL . - // In AUTO mode, the system uses the status of the association execution to - // determine the compliance status. If the association execution runs successfully, - // then the association is COMPLIANT . If the association execution doesn't run - // successfully, the association is NON-COMPLIANT . In MANUAL mode, you must - // specify the AssociationId as a parameter for the PutComplianceItems API - // operation. In this case, compliance data isn't managed by State Manager, a - // capability of Amazon Web Services Systems Manager. It is managed by your direct - // call to the PutComplianceItems API operation. By default, all associations use - // AUTO mode. - SyncCompliance AssociationSyncCompliance - - // The combination of Amazon Web Services Regions and Amazon Web Services accounts - // where you wanted to run the association when this association version was - // created. - TargetLocations []TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The targets specified for the association when the association version was - // created. - Targets []Target - - noSmithyDocumentSerde -} - -// A structure that includes attributes that describe a document attachment. -type AttachmentContent struct { - - // The cryptographic hash value of the document content. - Hash *string - - // The hash algorithm used to calculate the hash value. - HashType AttachmentHashType - - // The name of an attachment. - Name *string - - // The size of an attachment in bytes. - Size int64 - - // The URL location of the attachment content. - Url *string - - noSmithyDocumentSerde -} - -// An attribute of an attachment, such as the attachment name. -type AttachmentInformation struct { - - // The name of the attachment. - Name *string - - noSmithyDocumentSerde -} - -// Identifying information about a document attachment, including the file name -// and a key-value pair that identifies the location of an attachment to a -// document. -type AttachmentsSource struct { - - // The key of a key-value pair that identifies the location of an attachment to a - // document. - Key AttachmentsSourceKey - - // The name of the document attachment file. - Name *string - - // The value of a key-value pair that identifies the location of an attachment to - // a document. The format for Value depends on the type of key you specify. - // - For the key SourceUrl, the value is an S3 bucket location. For example: - // "Values": [ "s3://doc-example-bucket/my-folder" ] - // - For the key S3FileUrl, the value is a file in an S3 bucket. For example: - // "Values": [ "s3://doc-example-bucket/my-folder/my-file.py" ] - // - For the key AttachmentReference, the value is constructed from the name of - // another SSM document in your account, a version number of that document, and a - // file attached to that document version that you want to reuse. For example: - // "Values": [ "MyOtherDocument/3/my-other-file.py" ] However, if the SSM - // document is shared with you from another account, the full SSM document ARN must - // be specified instead of the document name only. For example: "Values": [ - // "arn:aws:ssm:us-east-2:111122223333:document/OtherAccountDocument/3/their-file.py" - // ] - Values []string - - noSmithyDocumentSerde -} - -// Detailed information about the current state of an individual Automation -// execution. -type AutomationExecution struct { - - // The details for the CloudWatch alarm applied to your automation. - AlarmConfiguration *AlarmConfiguration - - // The ID of a State Manager association used in the Automation operation. - AssociationId *string - - // The execution ID. - AutomationExecutionId *string - - // The execution status of the Automation. - AutomationExecutionStatus AutomationExecutionStatus - - // The subtype of the Automation operation. Currently, the only supported value is - // ChangeRequest . - AutomationSubtype AutomationSubtype - - // The name of the Change Manager change request. - ChangeRequestName *string - - // The action of the step that is currently running. - CurrentAction *string - - // The name of the step that is currently running. - CurrentStepName *string - - // The name of the Automation runbook used during the execution. - DocumentName *string - - // The version of the document to use during execution. - DocumentVersion *string - - // The Amazon Resource Name (ARN) of the user who ran the automation. - ExecutedBy *string - - // The time the execution finished. - ExecutionEndTime *time.Time - - // The time the execution started. - ExecutionStartTime *time.Time - - // A message describing why an execution has failed, if the status is set to - // Failed. - FailureMessage *string - - // The MaxConcurrency value specified by the user when the execution started. - MaxConcurrency *string - - // The MaxErrors value specified by the user when the execution started. - MaxErrors *string - - // The automation execution mode. - Mode ExecutionMode - - // The ID of an OpsItem that is created to represent a Change Manager change - // request. - OpsItemId *string - - // The list of execution outputs as defined in the Automation runbook. - Outputs map[string][]string - - // The key-value map of execution parameters, which were supplied when calling - // StartAutomationExecution . - Parameters map[string][]string - - // The AutomationExecutionId of the parent automation. - ParentAutomationExecutionId *string - - // An aggregate of step execution statuses displayed in the Amazon Web Services - // Systems Manager console for a multi-Region and multi-account Automation - // execution. - ProgressCounters *ProgressCounters - - // A list of resolved targets in the rate control execution. - ResolvedTargets *ResolvedTargets - - // Information about the Automation runbooks that are run as part of a runbook - // workflow. The Automation runbooks specified for the runbook workflow can't run - // until all required approvals for the change request have been received. - Runbooks []Runbook - - // The date and time the Automation operation is scheduled to start. - ScheduledTime *time.Time - - // A list of details about the current state of all steps that comprise an - // execution. An Automation runbook contains a list of steps that are run in order. - StepExecutions []StepExecution - - // A boolean value that indicates if the response contains the full list of the - // Automation step executions. If true, use the DescribeAutomationStepExecutions - // API operation to get the full list of step executions. - StepExecutionsTruncated bool - - // The target of the execution. - Target *string - - // The combination of Amazon Web Services Regions and/or Amazon Web Services - // accounts where you want to run the Automation. - TargetLocations []TargetLocation - - // The specified key-value mapping of document parameters to target resources. - TargetMaps []map[string][]string - - // The parameter name. - TargetParameterName *string - - // The specified targets. - Targets []Target - - // The CloudWatch alarm that was invoked by the automation. - TriggeredAlarms []AlarmStateInformation - - // Variables defined for the automation. - Variables map[string][]string - - noSmithyDocumentSerde -} - -// A filter used to match specific automation executions. This is used to limit -// the scope of Automation execution information returned. -type AutomationExecutionFilter struct { - - // One or more keys to limit the results. - // - // This member is required. - Key AutomationExecutionFilterKey - - // The values used to limit the execution information associated with the filter's - // key. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Details about a specific Automation execution. -type AutomationExecutionMetadata struct { - - // The details for the CloudWatch alarm applied to your automation. - AlarmConfiguration *AlarmConfiguration - - // The ID of a State Manager association used in the Automation operation. - AssociationId *string - - // The execution ID. - AutomationExecutionId *string - - // The status of the execution. - AutomationExecutionStatus AutomationExecutionStatus - - // The subtype of the Automation operation. Currently, the only supported value is - // ChangeRequest . - AutomationSubtype AutomationSubtype - - // Use this filter with DescribeAutomationExecutions . Specify either Local or - // CrossAccount. CrossAccount is an Automation that runs in multiple Amazon Web - // Services Regions and Amazon Web Services accounts. For more information, see - // Running Automation workflows in multiple Amazon Web Services Regions and - // accounts (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-automation-multiple-accounts-and-regions.html) - // in the Amazon Web Services Systems Manager User Guide. - AutomationType AutomationType - - // The name of the Change Manager change request. - ChangeRequestName *string - - // The action of the step that is currently running. - CurrentAction *string - - // The name of the step that is currently running. - CurrentStepName *string - - // The name of the Automation runbook used during execution. - DocumentName *string - - // The document version used during the execution. - DocumentVersion *string - - // The IAM role ARN of the user who ran the automation. - ExecutedBy *string - - // The time the execution finished. This isn't populated if the execution is still - // in progress. - ExecutionEndTime *time.Time - - // The time the execution started. - ExecutionStartTime *time.Time - - // The list of execution outputs as defined in the Automation runbook. - FailureMessage *string - - // An S3 bucket where execution information is stored. - LogFile *string - - // The MaxConcurrency value specified by the user when starting the automation. - MaxConcurrency *string - - // The MaxErrors value specified by the user when starting the automation. - MaxErrors *string - - // The Automation execution mode. - Mode ExecutionMode - - // The ID of an OpsItem that is created to represent a Change Manager change - // request. - OpsItemId *string - - // The list of execution outputs as defined in the Automation runbook. - Outputs map[string][]string - - // The execution ID of the parent automation. - ParentAutomationExecutionId *string - - // A list of targets that resolved during the execution. - ResolvedTargets *ResolvedTargets - - // Information about the Automation runbooks that are run during a runbook - // workflow in Change Manager. The Automation runbooks specified for the runbook - // workflow can't run until all required approvals for the change request have been - // received. - Runbooks []Runbook - - // The date and time the Automation operation is scheduled to start. - ScheduledTime *time.Time - - // The list of execution outputs as defined in the Automation runbook. - Target *string - - // The specified key-value mapping of document parameters to target resources. - TargetMaps []map[string][]string - - // The list of execution outputs as defined in the Automation runbook. - TargetParameterName *string - - // The targets defined by the user when starting the automation. - Targets []Target - - // The CloudWatch alarm that was invoked by the automation. - TriggeredAlarms []AlarmStateInformation - - noSmithyDocumentSerde -} - -// Defines the basic information about a patch baseline override. -type BaselineOverride struct { - - // A set of rules defining the approval rules for a patch baseline. - ApprovalRules *PatchRuleGroup - - // A list of explicitly approved patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - ApprovedPatches []string - - // Defines the compliance level for approved patches. When an approved patch is - // reported as missing, this value describes the severity of the compliance - // violation. - ApprovedPatchesComplianceLevel PatchComplianceLevel - - // Indicates whether the list of approved patches includes non-security updates - // that should be applied to the managed nodes. The default value is false . - // Applies to Linux managed nodes only. - ApprovedPatchesEnableNonSecurity bool - - // A set of patch filters, typically used for approval rules. - GlobalFilters *PatchFilterGroup - - // The operating system rule used by the patch baseline override. - OperatingSystem OperatingSystem - - // A list of explicitly rejected patches for the baseline. For information about - // accepted formats for lists of approved patches and rejected patches, see About - // package name formats for approved and rejected patch lists (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-approved-rejected-package-name-formats.html) - // in the Amazon Web Services Systems Manager User Guide. - RejectedPatches []string - - // The action for Patch Manager to take on patches included in the RejectedPackages - // list. A patch can be allowed only if it is a dependency of another package, or - // blocked entirely along with packages that include it as a dependency. - RejectedPatchesAction PatchAction - - // Information about the patches to use to update the managed nodes, including - // target operating systems and source repositories. Applies to Linux managed nodes - // only. - Sources []PatchSource - - noSmithyDocumentSerde -} - -// Configuration options for sending command output to Amazon CloudWatch Logs. -type CloudWatchOutputConfig struct { - - // The name of the CloudWatch Logs log group where you want to send command - // output. If you don't specify a group name, Amazon Web Services Systems Manager - // automatically creates a log group for you. The log group uses the following - // naming format: aws/ssm/SystemsManagerDocumentName - CloudWatchLogGroupName *string - - // Enables Systems Manager to send command output to CloudWatch Logs. - CloudWatchOutputEnabled bool - - noSmithyDocumentSerde -} - -// Describes a command request. -type Command struct { - - // The details for the CloudWatch alarm applied to your command. - AlarmConfiguration *AlarmConfiguration - - // Amazon CloudWatch Logs information where you want Amazon Web Services Systems - // Manager to send the command output. - CloudWatchOutputConfig *CloudWatchOutputConfig - - // A unique identifier for this command. - CommandId *string - - // User-specified information about the command, such as a brief description of - // what the command should do. - Comment *string - - // The number of targets for which the command invocation reached a terminal - // state. Terminal states include the following: Success, Failed, Execution Timed - // Out, Delivery Timed Out, Cancelled, Terminated, or Undeliverable. - CompletedCount int32 - - // The number of targets for which the status is Delivery Timed Out. - DeliveryTimedOutCount int32 - - // The name of the document requested for execution. - DocumentName *string - - // The Systems Manager document (SSM document) version. - DocumentVersion *string - - // The number of targets for which the status is Failed or Execution Timed Out. - ErrorCount int32 - - // If a command expires, it changes status to DeliveryTimedOut for all invocations - // that have the status InProgress , Pending , or Delayed . ExpiresAfter is - // calculated based on the total timeout for the overall command. For more - // information, see Understanding command timeout values (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitor-commands.html?icmpid=docs_ec2_console#monitor-about-status-timeouts) - // in the Amazon Web Services Systems Manager User Guide. - ExpiresAfter *time.Time - - // The managed node IDs against which this command was requested. - InstanceIds []string - - // The maximum number of managed nodes that are allowed to run the command at the - // same time. You can specify a number of managed nodes, such as 10, or a - // percentage of nodes, such as 10%. The default value is 50. For more information - // about how to use MaxConcurrency , see Running commands using Systems Manager - // Run Command (https://docs.aws.amazon.com/systems-manager/latest/userguide/run-command.html) - // in the Amazon Web Services Systems Manager User Guide. - MaxConcurrency *string - - // The maximum number of errors allowed before the system stops sending the - // command to additional targets. You can specify a number of errors, such as 10, - // or a percentage or errors, such as 10%. The default value is 0 . For more - // information about how to use MaxErrors , see Running commands using Systems - // Manager Run Command (https://docs.aws.amazon.com/systems-manager/latest/userguide/run-command.html) - // in the Amazon Web Services Systems Manager User Guide. - MaxErrors *string - - // Configurations for sending notifications about command status changes. - NotificationConfig *NotificationConfig - - // The S3 bucket where the responses to the command executions should be stored. - // This was requested when issuing the command. - OutputS3BucketName *string - - // The S3 directory path inside the bucket where the responses to the command - // executions should be stored. This was requested when issuing the command. - OutputS3KeyPrefix *string - - // (Deprecated) You can no longer specify this parameter. The system ignores it. - // Instead, Systems Manager automatically determines the Amazon Web Services Region - // of the S3 bucket. - OutputS3Region *string - - // The parameter values to be inserted in the document when running the command. - Parameters map[string][]string - - // The date and time the command was requested. - RequestedDateTime *time.Time - - // The Identity and Access Management (IAM) service role that Run Command, a - // capability of Amazon Web Services Systems Manager, uses to act on your behalf - // when sending notifications about command status changes. - ServiceRole *string - - // The status of the command. - Status CommandStatus - - // A detailed status of the command execution. StatusDetails includes more - // information than Status because it includes states resulting from error and - // concurrency control parameters. StatusDetails can show different results than - // Status. For more information about these statuses, see Understanding command - // statuses (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitor-commands.html) - // in the Amazon Web Services Systems Manager User Guide. StatusDetails can be one - // of the following values: - // - Pending: The command hasn't been sent to any managed nodes. - // - In Progress: The command has been sent to at least one managed node but - // hasn't reached a final state on all managed nodes. - // - Success: The command successfully ran on all invocations. This is a - // terminal state. - // - Delivery Timed Out: The value of MaxErrors or more command invocations - // shows a status of Delivery Timed Out. This is a terminal state. - // - Execution Timed Out: The value of MaxErrors or more command invocations - // shows a status of Execution Timed Out. This is a terminal state. - // - Failed: The value of MaxErrors or more command invocations shows a status - // of Failed. This is a terminal state. - // - Incomplete: The command was attempted on all managed nodes and one or more - // invocations doesn't have a value of Success but not enough invocations failed - // for the status to be Failed. This is a terminal state. - // - Cancelled: The command was terminated before it was completed. This is a - // terminal state. - // - Rate Exceeded: The number of managed nodes targeted by the command exceeded - // the account limit for pending invocations. The system has canceled the command - // before running it on any managed node. This is a terminal state. - // - Delayed: The system attempted to send the command to the managed node but - // wasn't successful. The system retries again. - StatusDetails *string - - // The number of targets for the command. - TargetCount int32 - - // An array of search criteria that targets managed nodes using a Key,Value - // combination that you specify. Targets is required if you don't provide one or - // more managed node IDs in the call. - Targets []Target - - // The TimeoutSeconds value specified for a command. - TimeoutSeconds *int32 - - // The CloudWatch alarm that was invoked by the command. - TriggeredAlarms []AlarmStateInformation - - noSmithyDocumentSerde -} - -// Describes a command filter. A managed node ID can't be specified when a command -// status is Pending because the command hasn't run on the node yet. -type CommandFilter struct { - - // The name of the filter. The ExecutionStage filter can't be used with the - // ListCommandInvocations operation, only with ListCommands . - // - // This member is required. - Key CommandFilterKey - - // The filter value. Valid values for each filter key are as follows: - // - InvokedAfter: Specify a timestamp to limit your results. For example, - // specify 2021-07-07T00:00:00Z to see a list of command executions occurring - // July 7, 2021, and later. - // - InvokedBefore: Specify a timestamp to limit your results. For example, - // specify 2021-07-07T00:00:00Z to see a list of command executions from before - // July 7, 2021. - // - Status: Specify a valid command status to see a list of all command - // executions with that status. The status choices depend on the API you call. The - // status values you can specify for ListCommands are: - // - Pending - // - InProgress - // - Success - // - Cancelled - // - Failed - // - TimedOut (this includes both Delivery and Execution time outs) - // - AccessDenied - // - DeliveryTimedOut - // - ExecutionTimedOut - // - Incomplete - // - NoInstancesInTag - // - LimitExceeded The status values you can specify for ListCommandInvocations - // are: - // - Pending - // - InProgress - // - Delayed - // - Success - // - Cancelled - // - Failed - // - TimedOut (this includes both Delivery and Execution time outs) - // - AccessDenied - // - DeliveryTimedOut - // - ExecutionTimedOut - // - Undeliverable - // - InvalidPlatform - // - Terminated - // - DocumentName: Specify name of the Amazon Web Services Systems Manager - // document (SSM document) for which you want to see command execution results. For - // example, specify AWS-RunPatchBaseline to see command executions that used this - // SSM document to perform security patching operations on managed nodes. - // - ExecutionStage: Specify one of the following values ( ListCommands - // operations only): - // - Executing : Returns a list of command executions that are currently still - // running. - // - Complete : Returns a list of command executions that have already completed. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// An invocation is a copy of a command sent to a specific managed node. A command -// can apply to one or more managed nodes. A command invocation applies to one -// managed node. For example, if a user runs SendCommand against three managed -// nodes, then a command invocation is created for each requested managed node ID. -// A command invocation returns status and detail information about a command you -// ran. -type CommandInvocation struct { - - // Amazon CloudWatch Logs information where you want Amazon Web Services Systems - // Manager to send the command output. - CloudWatchOutputConfig *CloudWatchOutputConfig - - // The command against which this invocation was requested. - CommandId *string - - // Plugins processed by the command. - CommandPlugins []CommandPlugin - - // User-specified information about the command, such as a brief description of - // what the command should do. - Comment *string - - // The document name that was requested for execution. - DocumentName *string - - // The Systems Manager document (SSM document) version. - DocumentVersion *string - - // The managed node ID in which this invocation was requested. - InstanceId *string - - // The fully qualified host name of the managed node. - InstanceName *string - - // Configurations for sending notifications about command status changes on a per - // managed node basis. - NotificationConfig *NotificationConfig - - // The time and date the request was sent to this managed node. - RequestedDateTime *time.Time - - // The Identity and Access Management (IAM) service role that Run Command, a - // capability of Amazon Web Services Systems Manager, uses to act on your behalf - // when sending notifications about command status changes on a per managed node - // basis. - ServiceRole *string - - // The URL to the plugin's StdErr file in Amazon Simple Storage Service (Amazon - // S3), if the S3 bucket was defined for the parent command. For an invocation, - // StandardErrorUrl is populated if there is just one plugin defined for the - // command, and the S3 bucket was defined for the command. - StandardErrorUrl *string - - // The URL to the plugin's StdOut file in Amazon Simple Storage Service (Amazon - // S3), if the S3 bucket was defined for the parent command. For an invocation, - // StandardOutputUrl is populated if there is just one plugin defined for the - // command, and the S3 bucket was defined for the command. - StandardOutputUrl *string - - // Whether or not the invocation succeeded, failed, or is pending. - Status CommandInvocationStatus - - // A detailed status of the command execution for each invocation (each managed - // node targeted by the command). StatusDetails includes more information than - // Status because it includes states resulting from error and concurrency control - // parameters. StatusDetails can show different results than Status. For more - // information about these statuses, see Understanding command statuses (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitor-commands.html) - // in the Amazon Web Services Systems Manager User Guide. StatusDetails can be one - // of the following values: - // - Pending: The command hasn't been sent to the managed node. - // - In Progress: The command has been sent to the managed node but hasn't - // reached a terminal state. - // - Success: The execution of the command or plugin was successfully completed. - // This is a terminal state. - // - Delivery Timed Out: The command wasn't delivered to the managed node before - // the delivery timeout expired. Delivery timeouts don't count against the parent - // command's MaxErrors limit, but they do contribute to whether the parent - // command status is Success or Incomplete. This is a terminal state. - // - Execution Timed Out: Command execution started on the managed node, but the - // execution wasn't complete before the execution timeout expired. Execution - // timeouts count against the MaxErrors limit of the parent command. This is a - // terminal state. - // - Failed: The command wasn't successful on the managed node. For a plugin, - // this indicates that the result code wasn't zero. For a command invocation, this - // indicates that the result code for one or more plugins wasn't zero. Invocation - // failures count against the MaxErrors limit of the parent command. This is a - // terminal state. - // - Cancelled: The command was terminated before it was completed. This is a - // terminal state. - // - Undeliverable: The command can't be delivered to the managed node. The - // managed node might not exist or might not be responding. Undeliverable - // invocations don't count against the parent command's MaxErrors limit and don't - // contribute to whether the parent command status is Success or Incomplete. This - // is a terminal state. - // - Terminated: The parent command exceeded its MaxErrors limit and subsequent - // command invocations were canceled by the system. This is a terminal state. - // - Delayed: The system attempted to send the command to the managed node but - // wasn't successful. The system retries again. - StatusDetails *string - - // Gets the trace output sent by the agent. - TraceOutput *string - - noSmithyDocumentSerde -} - -// Describes plugin details. -type CommandPlugin struct { - - // The name of the plugin. Must be one of the following: aws:updateAgent , - // aws:domainjoin , aws:applications , aws:runPowerShellScript , aws:psmodule , - // aws:cloudWatch , aws:runShellScript , or aws:updateSSMAgent . - Name *string - - // Output of the plugin execution. - Output *string - - // The S3 bucket where the responses to the command executions should be stored. - // This was requested when issuing the command. For example, in the following - // response: - // doc-example-bucket/ab19cb99-a030-46dd-9dfc-8eSAMPLEPre-Fix/i-02573cafcfEXAMPLE/awsrunShellScript - // doc-example-bucket is the name of the S3 bucket; - // ab19cb99-a030-46dd-9dfc-8eSAMPLEPre-Fix is the name of the S3 prefix; - // i-02573cafcfEXAMPLE is the managed node ID; awsrunShellScript is the name of - // the plugin. - OutputS3BucketName *string - - // The S3 directory path inside the bucket where the responses to the command - // executions should be stored. This was requested when issuing the command. For - // example, in the following response: - // doc-example-bucket/ab19cb99-a030-46dd-9dfc-8eSAMPLEPre-Fix/i-02573cafcfEXAMPLE/awsrunShellScript - // doc-example-bucket is the name of the S3 bucket; - // ab19cb99-a030-46dd-9dfc-8eSAMPLEPre-Fix is the name of the S3 prefix; - // i-02573cafcfEXAMPLE is the managed node ID; awsrunShellScript is the name of - // the plugin. - OutputS3KeyPrefix *string - - // (Deprecated) You can no longer specify this parameter. The system ignores it. - // Instead, Amazon Web Services Systems Manager automatically determines the S3 - // bucket region. - OutputS3Region *string - - // A numeric response code generated after running the plugin. - ResponseCode int32 - - // The time the plugin stopped running. Could stop prematurely if, for example, a - // cancel command was sent. - ResponseFinishDateTime *time.Time - - // The time the plugin started running. - ResponseStartDateTime *time.Time - - // The URL for the complete text written by the plugin to stderr. If execution - // isn't yet complete, then this string is empty. - StandardErrorUrl *string - - // The URL for the complete text written by the plugin to stdout in Amazon S3. If - // the S3 bucket for the command wasn't specified, then this string is empty. - StandardOutputUrl *string - - // The status of this plugin. You can run a document with multiple plugins. - Status CommandPluginStatus - - // A detailed status of the plugin execution. StatusDetails includes more - // information than Status because it includes states resulting from error and - // concurrency control parameters. StatusDetails can show different results than - // Status. For more information about these statuses, see Understanding command - // statuses (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitor-commands.html) - // in the Amazon Web Services Systems Manager User Guide. StatusDetails can be one - // of the following values: - // - Pending: The command hasn't been sent to the managed node. - // - In Progress: The command has been sent to the managed node but hasn't - // reached a terminal state. - // - Success: The execution of the command or plugin was successfully completed. - // This is a terminal state. - // - Delivery Timed Out: The command wasn't delivered to the managed node before - // the delivery timeout expired. Delivery timeouts don't count against the parent - // command's MaxErrors limit, but they do contribute to whether the parent - // command status is Success or Incomplete. This is a terminal state. - // - Execution Timed Out: Command execution started on the managed node, but the - // execution wasn't complete before the execution timeout expired. Execution - // timeouts count against the MaxErrors limit of the parent command. This is a - // terminal state. - // - Failed: The command wasn't successful on the managed node. For a plugin, - // this indicates that the result code wasn't zero. For a command invocation, this - // indicates that the result code for one or more plugins wasn't zero. Invocation - // failures count against the MaxErrors limit of the parent command. This is a - // terminal state. - // - Cancelled: The command was terminated before it was completed. This is a - // terminal state. - // - Undeliverable: The command can't be delivered to the managed node. The - // managed node might not exist, or it might not be responding. Undeliverable - // invocations don't count against the parent command's MaxErrors limit, and they - // don't contribute to whether the parent command status is Success or Incomplete. - // This is a terminal state. - // - Terminated: The parent command exceeded its MaxErrors limit and subsequent - // command invocations were canceled by the system. This is a terminal state. - StatusDetails *string - - noSmithyDocumentSerde -} - -// A summary of the call execution that includes an execution ID, the type of -// execution (for example, Command ), and the date/time of the execution using a -// datetime object that is saved in the following format: yyyy-MM-dd'T'HH:mm:ss'Z'. -type ComplianceExecutionSummary struct { - - // The time the execution ran as a datetime object that is saved in the following - // format: yyyy-MM-dd'T'HH:mm:ss'Z'. - // - // This member is required. - ExecutionTime *time.Time - - // An ID created by the system when PutComplianceItems was called. For example, - // CommandID is a valid execution ID. You can use this ID in subsequent calls. - ExecutionId *string - - // The type of execution. For example, Command is a valid execution type. - ExecutionType *string - - noSmithyDocumentSerde -} - -// Information about the compliance as defined by the resource type. For example, -// for a patch resource type, Items includes information about the PatchSeverity, -// Classification, and so on. -type ComplianceItem struct { - - // The compliance type. For example, Association (for a State Manager - // association), Patch, or Custom: string are all valid compliance types. - ComplianceType *string - - // A "Key": "Value" tag combination for the compliance item. - Details map[string]string - - // A summary for the compliance item. The summary includes an execution ID, the - // execution type (for example, command), and the execution time. - ExecutionSummary *ComplianceExecutionSummary - - // An ID for the compliance item. For example, if the compliance item is a Windows - // patch, the ID could be the number of the KB article; for example: KB4010320. - Id *string - - // An ID for the resource. For a managed node, this is the node ID. - ResourceId *string - - // The type of resource. ManagedInstance is currently the only supported resource - // type. - ResourceType *string - - // The severity of the compliance status. Severity can be one of the following: - // Critical, High, Medium, Low, Informational, Unspecified. - Severity ComplianceSeverity - - // The status of the compliance item. An item is either COMPLIANT, NON_COMPLIANT, - // or an empty string (for Windows patches that aren't applicable). - Status ComplianceStatus - - // A title for the compliance item. For example, if the compliance item is a - // Windows patch, the title could be the title of the KB article for the patch; for - // example: Security Update for Active Directory Federation Services. - Title *string - - noSmithyDocumentSerde -} - -// Information about a compliance item. -type ComplianceItemEntry struct { - - // The severity of the compliance status. Severity can be one of the following: - // Critical, High, Medium, Low, Informational, Unspecified. - // - // This member is required. - Severity ComplianceSeverity - - // The status of the compliance item. An item is either COMPLIANT or NON_COMPLIANT. - // - // This member is required. - Status ComplianceStatus - - // A "Key": "Value" tag combination for the compliance item. - Details map[string]string - - // The compliance item ID. For example, if the compliance item is a Windows patch, - // the ID could be the number of the KB article. - Id *string - - // The title of the compliance item. For example, if the compliance item is a - // Windows patch, the title could be the title of the KB article for the patch; for - // example: Security Update for Active Directory Federation Services. - Title *string - - noSmithyDocumentSerde -} - -// One or more filters. Use a filter to return a more specific list of results. -type ComplianceStringFilter struct { - - // The name of the filter. - Key *string - - // The type of comparison that should be performed for the value: Equal, NotEqual, - // BeginWith, LessThan, or GreaterThan. - Type ComplianceQueryOperatorType - - // The value for which to search. - Values []string - - noSmithyDocumentSerde -} - -// A summary of compliance information by compliance type. -type ComplianceSummaryItem struct { - - // The type of compliance item. For example, the compliance type can be - // Association, Patch, or Custom:string. - ComplianceType *string - - // A list of COMPLIANT items for the specified compliance type. - CompliantSummary *CompliantSummary - - // A list of NON_COMPLIANT items for the specified compliance type. - NonCompliantSummary *NonCompliantSummary - - noSmithyDocumentSerde -} - -// A summary of resources that are compliant. The summary is organized according -// to the resource count for each compliance type. -type CompliantSummary struct { - - // The total number of resources that are compliant. - CompliantCount int32 - - // A summary of the compliance severity by compliance type. - SeveritySummary *SeveritySummary - - noSmithyDocumentSerde -} - -// Describes the association of a Amazon Web Services Systems Manager document -// (SSM document) and a managed node. -type CreateAssociationBatchRequestEntry struct { - - // The name of the SSM document that contains the configuration information for - // the managed node. You can specify Command or Automation runbooks. You can - // specify Amazon Web Services-predefined documents, documents you created, or a - // document that is shared with you from another account. For SSM documents that - // are shared with you from other Amazon Web Services accounts, you must specify - // the complete SSM document ARN, in the following format: - // arn:aws:ssm:region:account-id:document/document-name For example: - // arn:aws:ssm:us-east-2:12345678912:document/My-Shared-Document For Amazon Web - // Services-predefined documents and SSM documents you created in your account, you - // only need to specify the document name. For example, AWS-ApplyPatchBaseline or - // My-Document . - // - // This member is required. - Name *string - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - AlarmConfiguration *AlarmConfiguration - - // By default, when you create a new associations, the system runs it immediately - // after it is created and then according to the schedule you specified. Specify - // this option if you don't want an association to run immediately after you create - // it. This parameter isn't supported for rate expressions. - ApplyOnlyAtCronInterval bool - - // Specify a descriptive name for the association. - AssociationName *string - - // Specify the target for the association. This target is required for - // associations that use an Automation runbook and target resources by using rate - // controls. Automation is a capability of Amazon Web Services Systems Manager. - AutomationTargetParameterName *string - - // The names or Amazon Resource Names (ARNs) of the Change Calendar type documents - // your associations are gated under. The associations only run when that Change - // Calendar is open. For more information, see Amazon Web Services Systems Manager - // Change Calendar (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar) - // . - CalendarNames []string - - // The severity level to assign to the association. - ComplianceSeverity AssociationComplianceSeverity - - // The document version. - DocumentVersion *string - - // The managed node ID. InstanceId has been deprecated. To specify a managed node - // ID for an association, use the Targets parameter. Requests that include the - // parameter InstanceID with Systems Manager documents (SSM documents) that use - // schema version 2.0 or later will fail. In addition, if you use the parameter - // InstanceId , you can't use the parameters AssociationName , DocumentVersion , - // MaxErrors , MaxConcurrency , OutputLocation , or ScheduleExpression . To use - // these parameters, you must use the Targets parameter. - InstanceId *string - - // The maximum number of targets allowed to run the association at the same time. - // You can specify a number, for example 10, or a percentage of the target set, for - // example 10%. The default value is 100%, which means all targets run the - // association at the same time. If a new managed node starts and attempts to run - // an association while Systems Manager is running MaxConcurrency associations, - // the association is allowed to run. During the next association interval, the new - // managed node will process its association within the limit specified for - // MaxConcurrency . - MaxConcurrency *string - - // The number of errors that are allowed before the system stops sending requests - // to run the association on additional targets. You can specify either an absolute - // number of errors, for example 10, or a percentage of the target set, for example - // 10%. If you specify 3, for example, the system stops sending requests when the - // fourth error is received. If you specify 0, then the system stops sending - // requests after the first error is returned. If you run an association on 50 - // managed nodes and set MaxError to 10%, then the system stops sending the - // request when the sixth error is received. Executions that are already running an - // association when MaxErrors is reached are allowed to complete, but some of - // these executions may fail as well. If you need to ensure that there won't be - // more than max-errors failed executions, set MaxConcurrency to 1 so that - // executions proceed one at a time. - MaxErrors *string - - // An S3 bucket where you want to store the results of this request. - OutputLocation *InstanceAssociationOutputLocation - - // A description of the parameters for a document. - Parameters map[string][]string - - // A cron expression that specifies a schedule when the association runs. - ScheduleExpression *string - - // Number of days to wait after the scheduled day to run an association. - ScheduleOffset *int32 - - // The mode for generating association compliance. You can specify AUTO or MANUAL . - // In AUTO mode, the system uses the status of the association execution to - // determine the compliance status. If the association execution runs successfully, - // then the association is COMPLIANT . If the association execution doesn't run - // successfully, the association is NON-COMPLIANT . In MANUAL mode, you must - // specify the AssociationId as a parameter for the PutComplianceItems API - // operation. In this case, compliance data isn't managed by State Manager, a - // capability of Amazon Web Services Systems Manager. It is managed by your direct - // call to the PutComplianceItems API operation. By default, all associations use - // AUTO mode. - SyncCompliance AssociationSyncCompliance - - // Use this action to create an association in multiple Regions and multiple - // accounts. - TargetLocations []TargetLocation - - // A key-value mapping of document parameters to target resources. Both Targets - // and TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The managed nodes targeted by the request. - Targets []Target - - noSmithyDocumentSerde -} - -// Filter for the DescribeActivation API. -type DescribeActivationsFilter struct { - - // The name of the filter. - FilterKey DescribeActivationsFilterKeys - - // The filter values. - FilterValues []string - - noSmithyDocumentSerde -} - -// A default version of a document. -type DocumentDefaultVersionDescription struct { - - // The default version of the document. - DefaultVersion *string - - // The default version of the artifact associated with the document. - DefaultVersionName *string - - // The name of the document. - Name *string - - noSmithyDocumentSerde -} - -// Describes an Amazon Web Services Systems Manager document (SSM document). -type DocumentDescription struct { - - // The version of the document currently approved for use in the organization. - ApprovedVersion *string - - // Details about the document attachments, including names, locations, sizes, and - // so on. - AttachmentsInformation []AttachmentInformation - - // The user in your organization who created the document. - Author *string - - // The classification of a document to help you identify and categorize its use. - Category []string - - // The value that identifies a document's category. - CategoryEnum []string - - // The date when the document was created. - CreatedDate *time.Time - - // The default version. - DefaultVersion *string - - // A description of the document. - Description *string - - // The friendly name of the SSM document. This value can differ for each version - // of the document. If you want to update this value, see UpdateDocument . - DisplayName *string - - // The document format, either JSON or YAML. - DocumentFormat DocumentFormat - - // The type of document. - DocumentType DocumentType - - // The document version. - DocumentVersion *string - - // The Sha256 or Sha1 hash created by the system when the document was created. - // Sha1 hashes have been deprecated. - Hash *string - - // The hash type of the document. Valid values include Sha256 or Sha1 . Sha1 hashes - // have been deprecated. - HashType DocumentHashType - - // The latest version of the document. - LatestVersion *string - - // The name of the SSM document. - Name *string - - // The Amazon Web Services user that created the document. - Owner *string - - // A description of the parameters for a document. - Parameters []DocumentParameter - - // The version of the document that is currently under review. - PendingReviewVersion *string - - // The list of operating system (OS) platforms compatible with this SSM document. - PlatformTypes []PlatformType - - // A list of SSM documents required by a document. For example, an - // ApplicationConfiguration document requires an ApplicationConfigurationSchema - // document. - Requires []DocumentRequires - - // Details about the review of a document. - ReviewInformation []ReviewInformation - - // The current status of the review. - ReviewStatus ReviewStatus - - // The schema version. - SchemaVersion *string - - // The SHA1 hash of the document, which you can use for verification. - Sha1 *string - - // The status of the SSM document. - Status DocumentStatus - - // A message returned by Amazon Web Services Systems Manager that explains the - // Status value. For example, a Failed status might be explained by the - // StatusInformation message, "The specified S3 bucket doesn't exist. Verify that - // the URL of the S3 bucket is correct." - StatusInformation *string - - // The tags, or metadata, that have been applied to the document. - Tags []Tag - - // The target type which defines the kinds of resources the document can run on. - // For example, /AWS::EC2::Instance . For a list of valid resource types, see - // Amazon Web Services resource and property types reference (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) - // in the CloudFormation User Guide. - TargetType *string - - // The version of the artifact associated with the document. - VersionName *string - - noSmithyDocumentSerde -} - -// This data type is deprecated. Instead, use DocumentKeyValuesFilter . -type DocumentFilter struct { - - // The name of the filter. - // - // This member is required. - Key DocumentFilterKey - - // The value of the filter. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Describes the name of a SSM document. -type DocumentIdentifier struct { - - // The user in your organization who created the document. - Author *string - - // The date the SSM document was created. - CreatedDate *time.Time - - // An optional field where you can specify a friendly name for the SSM document. - // This value can differ for each version of the document. If you want to update - // this value, see UpdateDocument . - DisplayName *string - - // The document format, either JSON or YAML. - DocumentFormat DocumentFormat - - // The document type. - DocumentType DocumentType - - // The document version. - DocumentVersion *string - - // The name of the SSM document. - Name *string - - // The Amazon Web Services user that created the document. - Owner *string - - // The operating system platform. - PlatformTypes []PlatformType - - // A list of SSM documents required by a document. For example, an - // ApplicationConfiguration document requires an ApplicationConfigurationSchema - // document. - Requires []DocumentRequires - - // The current status of a document review. - ReviewStatus ReviewStatus - - // The schema version. - SchemaVersion *string - - // The tags, or metadata, that have been applied to the document. - Tags []Tag - - // The target type which defines the kinds of resources the document can run on. - // For example, /AWS::EC2::Instance . For a list of valid resource types, see - // Amazon Web Services resource and property types reference (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) - // in the CloudFormation User Guide. - TargetType *string - - // An optional field specifying the version of the artifact associated with the - // document. For example, "Release 12, Update 6". This value is unique across all - // versions of a document, and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -// One or more filters. Use a filter to return a more specific list of documents. -// For keys, you can specify one or more tags that have been applied to a document. -// You can also use Amazon Web Services-provided keys, some of which have specific -// allowed values. These keys and their associated values are as follows: -// DocumentType -// - ApplicationConfiguration -// - ApplicationConfigurationSchema -// - Automation -// - ChangeCalendar -// - Command -// - Package -// - Policy -// - Session -// -// Owner Note that only one Owner can be specified in a request. For example: -// Key=Owner,Values=Self . -// - Amazon -// - Private -// - Public -// - Self -// - ThirdParty -// -// PlatformTypes -// - Linux -// - Windows -// -// Name is another Amazon Web Services-provided key. If you use Name as a key, you -// can use a name prefix to return a list of documents. For example, in the Amazon -// Web Services CLI, to return a list of all documents that begin with Te , run the -// following command: aws ssm list-documents --filters Key=Name,Values=Te You can -// also use the TargetType Amazon Web Services-provided key. For a list of valid -// resource type values that can be used with this key, see Amazon Web Services -// resource and property types reference (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) -// in the CloudFormation User Guide. If you specify more than two keys, only -// documents that are identified by all the tags are returned in the results. If -// you specify more than two values for a key, documents that are identified by any -// of the values are returned in the results. To specify a custom key-value pair, -// use the format Key=tag:tagName,Values=valueName . For example, if you created a -// key called region and are using the Amazon Web Services CLI to call the -// list-documents command: aws ssm list-documents --filters -// Key=tag:region,Values=east,west Key=Owner,Values=Self -type DocumentKeyValuesFilter struct { - - // The name of the filter key. - Key *string - - // The value for the filter key. - Values []string - - noSmithyDocumentSerde -} - -// Details about the response to a document review request. -type DocumentMetadataResponseInfo struct { - - // Details about a reviewer's response to a document review request. - ReviewerResponse []DocumentReviewerResponseSource - - noSmithyDocumentSerde -} - -// Parameters specified in a Systems Manager document that run on the server when -// the command is run. -type DocumentParameter struct { - - // If specified, the default values for the parameters. Parameters without a - // default value are required. Parameters with a default value are optional. - DefaultValue *string - - // A description of what the parameter does, how to use it, the default value, and - // whether or not the parameter is optional. - Description *string - - // The name of the parameter. - Name *string - - // The type of parameter. The type can be either String or StringList. - Type DocumentParameterType - - noSmithyDocumentSerde -} - -// An SSM document required by the current document. -type DocumentRequires struct { - - // The name of the required SSM document. The name can be an Amazon Resource Name - // (ARN). - // - // This member is required. - Name *string - - // The document type of the required SSM document. - RequireType *string - - // The document version required by the current document. - Version *string - - // An optional field specifying the version of the artifact associated with the - // document. For example, "Release 12, Update 6". This value is unique across all - // versions of a document, and can't be changed. - VersionName *string - - noSmithyDocumentSerde -} - -// Information about comments added to a document review request. -type DocumentReviewCommentSource struct { - - // The content of a comment entered by a user who requests a review of a new - // document version, or who reviews the new version. - Content *string - - // The type of information added to a review request. Currently, only the value - // Comment is supported. - Type DocumentReviewCommentType - - noSmithyDocumentSerde -} - -// Information about a reviewer's response to a document review request. -type DocumentReviewerResponseSource struct { - - // The comment entered by a reviewer as part of their document review response. - Comment []DocumentReviewCommentSource - - // The date and time that a reviewer entered a response to a document review - // request. - CreateTime *time.Time - - // The current review status of a new custom SSM document created by a member of - // your organization, or of the latest version of an existing SSM document. Only - // one version of a document can be in the APPROVED state at a time. When a new - // version is approved, the status of the previous version changes to REJECTED. - // Only one version of a document can be in review, or PENDING, at a time. - ReviewStatus ReviewStatus - - // The user in your organization assigned to review a document request. - Reviewer *string - - // The date and time that a reviewer last updated a response to a document review - // request. - UpdatedTime *time.Time - - noSmithyDocumentSerde -} - -// Information about a document approval review. -type DocumentReviews struct { - - // The action to take on a document approval review request. - // - // This member is required. - Action DocumentReviewAction - - // A comment entered by a user in your organization about the document review - // request. - Comment []DocumentReviewCommentSource - - noSmithyDocumentSerde -} - -// Version information about the document. -type DocumentVersionInfo struct { - - // The date the document was created. - CreatedDate *time.Time - - // The friendly name of the SSM document. This value can differ for each version - // of the document. If you want to update this value, see UpdateDocument . - DisplayName *string - - // The document format, either JSON or YAML. - DocumentFormat DocumentFormat - - // The document version. - DocumentVersion *string - - // An identifier for the default version of the document. - IsDefaultVersion bool - - // The document name. - Name *string - - // The current status of the approval review for the latest version of the - // document. - ReviewStatus ReviewStatus - - // The status of the SSM document, such as Creating , Active , Failed , and - // Deleting . - Status DocumentStatus - - // A message returned by Amazon Web Services Systems Manager that explains the - // Status value. For example, a Failed status might be explained by the - // StatusInformation message, "The specified S3 bucket doesn't exist. Verify that - // the URL of the S3 bucket is correct." - StatusInformation *string - - // The version of the artifact associated with the document. For example, "Release - // 12, Update 6". This value is unique across all versions of a document, and can't - // be changed. - VersionName *string - - noSmithyDocumentSerde -} - -// The EffectivePatch structure defines metadata about a patch along with the -// approval state of the patch in a particular patch baseline. The approval state -// includes information about whether the patch is currently approved, due to be -// approved by a rule, explicitly approved, or explicitly rejected and the date the -// patch was or will be approved. -type EffectivePatch struct { - - // Provides metadata for a patch, including information such as the KB ID, - // severity, classification and a URL for where more information can be obtained - // about the patch. - Patch *Patch - - // The status of the patch in a patch baseline. This includes information about - // whether the patch is currently approved, due to be approved by a rule, - // explicitly approved, or explicitly rejected and the date the patch was or will - // be approved. - PatchStatus *PatchStatus - - noSmithyDocumentSerde -} - -// Describes a failed association. -type FailedCreateAssociation struct { - - // The association. - Entry *CreateAssociationBatchRequestEntry - - // The source of the failure. - Fault Fault - - // A description of the failure. - Message *string - - noSmithyDocumentSerde -} - -// Information about an Automation failure. -type FailureDetails struct { - - // Detailed information about the Automation step failure. - Details map[string][]string - - // The stage of the Automation execution when the failure occurred. The stages - // include the following: InputValidation, PreVerification, Invocation, - // PostVerification. - FailureStage *string - - // The type of Automation failure. Failure types include the following: Action, - // Permission, Throttling, Verification, Internal. - FailureType *string - - noSmithyDocumentSerde -} - -// A resource policy helps you to define the IAM entity (for example, an Amazon -// Web Services account) that can manage your Systems Manager resources. Currently, -// OpsItemGroup is the only resource that supports Systems Manager resource -// policies. The resource policy for OpsItemGroup enables Amazon Web Services -// accounts to view and interact with OpsCenter operational work items (OpsItems). -type GetResourcePoliciesResponseEntry struct { - - // A resource policy helps you to define the IAM entity (for example, an Amazon - // Web Services account) that can manage your Systems Manager resources. Currently, - // OpsItemGroup is the only resource that supports Systems Manager resource - // policies. The resource policy for OpsItemGroup enables Amazon Web Services - // accounts to view and interact with OpsCenter operational work items (OpsItems). - Policy *string - - // ID of the current policy version. The hash helps to prevent a situation where - // multiple users attempt to overwrite a policy. You must provide this hash when - // updating or deleting a policy. - PolicyHash *string - - // A policy ID. - PolicyId *string - - noSmithyDocumentSerde -} - -// Status information about the aggregated associations. -type InstanceAggregatedAssociationOverview struct { - - // Detailed status information about the aggregated associations. - DetailedStatus *string - - // The number of associations for the managed node(s). - InstanceAssociationStatusAggregatedCount map[string]int32 - - noSmithyDocumentSerde -} - -// One or more association documents on the managed node. -type InstanceAssociation struct { - - // The association ID. - AssociationId *string - - // Version information for the association on the managed node. - AssociationVersion *string - - // The content of the association document for the managed node(s). - Content *string - - // The managed node ID. - InstanceId *string - - noSmithyDocumentSerde -} - -// An S3 bucket where you want to store the results of this request. For the -// minimal permissions required to enable Amazon S3 output for an association, see -// Creating associations (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-state-assoc.html) -// in the Systems Manager User Guide. -type InstanceAssociationOutputLocation struct { - - // An S3 bucket where you want to store the results of this request. - S3Location *S3OutputLocation - - noSmithyDocumentSerde -} - -// The URL of S3 bucket where you want to store the results of this request. -type InstanceAssociationOutputUrl struct { - - // The URL of S3 bucket where you want to store the results of this request. - S3OutputUrl *S3OutputUrl - - noSmithyDocumentSerde -} - -// Status information about the association. -type InstanceAssociationStatusInfo struct { - - // The association ID. - AssociationId *string - - // The name of the association applied to the managed node. - AssociationName *string - - // The version of the association applied to the managed node. - AssociationVersion *string - - // Detailed status information about the association. - DetailedStatus *string - - // The association document versions. - DocumentVersion *string - - // An error code returned by the request to create the association. - ErrorCode *string - - // The date the association ran. - ExecutionDate *time.Time - - // Summary information about association execution. - ExecutionSummary *string - - // The managed node ID where the association was created. - InstanceId *string - - // The name of the association. - Name *string - - // A URL for an S3 bucket where you want to store the results of this request. - OutputUrl *InstanceAssociationOutputUrl - - // Status information about the association. - Status *string - - noSmithyDocumentSerde -} - -// Describes a filter for a specific list of managed nodes. -type InstanceInformation struct { - - // The activation ID created by Amazon Web Services Systems Manager when the - // server or virtual machine (VM) was registered. - ActivationId *string - - // The version of SSM Agent running on your Linux managed node. - AgentVersion *string - - // Information about the association. - AssociationOverview *InstanceAggregatedAssociationOverview - - // The status of the association. - AssociationStatus *string - - // The fully qualified host name of the managed node. - ComputerName *string - - // The IP address of the managed node. - IPAddress *string - - // The Identity and Access Management (IAM) role assigned to the on-premises - // Systems Manager managed node. This call doesn't return the IAM role for Amazon - // Elastic Compute Cloud (Amazon EC2) instances. To retrieve the IAM role for an - // EC2 instance, use the Amazon EC2 DescribeInstances operation. For information, - // see DescribeInstances (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html) - // in the Amazon EC2 API Reference or describe-instances (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html) - // in the Amazon Web Services CLI Command Reference. - IamRole *string - - // The managed node ID. - InstanceId *string - - // Indicates whether the latest version of SSM Agent is running on your Linux - // managed node. This field doesn't indicate whether or not the latest version is - // installed on Windows managed nodes, because some older versions of Windows - // Server use the EC2Config service to process Systems Manager requests. - IsLatestVersion *bool - - // The date the association was last run. - LastAssociationExecutionDate *time.Time - - // The date and time when the agent last pinged the Systems Manager service. - LastPingDateTime *time.Time - - // The last date the association was successfully run. - LastSuccessfulAssociationExecutionDate *time.Time - - // The name assigned to an on-premises server, edge device, or virtual machine - // (VM) when it is activated as a Systems Manager managed node. The name is - // specified as the DefaultInstanceName property using the CreateActivation - // command. It is applied to the managed node by specifying the Activation Code and - // Activation ID when you install SSM Agent on the node, as explained in Install - // SSM Agent for a hybrid environment (Linux) (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-managed-linux.html) - // and Install SSM Agent for a hybrid environment (Windows) (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-install-managed-win.html) - // . To retrieve the Name tag of an EC2 instance, use the Amazon EC2 - // DescribeInstances operation. For information, see DescribeInstances (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html) - // in the Amazon EC2 API Reference or describe-instances (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html) - // in the Amazon Web Services CLI Command Reference. - Name *string - - // Connection status of SSM Agent. The status Inactive has been deprecated and is - // no longer in use. - PingStatus PingStatus - - // The name of the operating system platform running on your managed node. - PlatformName *string - - // The operating system platform type. - PlatformType PlatformType - - // The version of the OS platform running on your managed node. - PlatformVersion *string - - // The date the server or VM was registered with Amazon Web Services as a managed - // node. - RegistrationDate *time.Time - - // The type of instance. Instances are either EC2 instances or managed instances. - ResourceType ResourceType - - // The ID of the source resource. For IoT Greengrass devices, SourceId is the - // Thing name. - SourceId *string - - // The type of the source resource. For IoT Greengrass devices, SourceType is - // AWS::IoT::Thing . - SourceType SourceType - - noSmithyDocumentSerde -} - -// Describes a filter for a specific list of managed nodes. You can filter node -// information by using tags. You specify tags by using a key-value mapping. Use -// this operation instead of the -// DescribeInstanceInformationRequest$InstanceInformationFilterList method. The -// InstanceInformationFilterList method is a legacy method and doesn't support tags. -type InstanceInformationFilter struct { - - // The name of the filter. - // - // This member is required. - Key InstanceInformationFilterKey - - // The filter values. - // - // This member is required. - ValueSet []string - - noSmithyDocumentSerde -} - -// The filters to describe or get information about your managed nodes. -type InstanceInformationStringFilter struct { - - // The filter key name to describe your managed nodes. Valid filter key values: - // ActivationIds | AgentVersion | AssociationStatus | IamRole | InstanceIds | - // PingStatus | PlatformTypes | ResourceType | SourceIds | SourceTypes | "tag-key" - // | "tag: {keyname} - // - Valid values for the AssociationStatus filter key: Success | Pending | - // Failed - // - Valid values for the PingStatus filter key: Online | ConnectionLost | - // Inactive (deprecated) - // - Valid values for the PlatformType filter key: Windows | Linux | MacOS - // - Valid values for the ResourceType filter key: EC2Instance | ManagedInstance - // - Valid values for the SourceType filter key: AWS::EC2::Instance | - // AWS::SSM::ManagedInstance | AWS::IoT::Thing - // - Valid tag examples: Key=tag-key,Values=Purpose | Key=tag:Purpose,Values=Test - // . - // - // This member is required. - Key *string - - // The filter values. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Defines the high-level patch compliance state for a managed node, providing -// information about the number of installed, missing, not applicable, and failed -// patches along with metadata about the operation when this information was -// gathered for the managed node. -type InstancePatchState struct { - - // The ID of the patch baseline used to patch the managed node. - // - // This member is required. - BaselineId *string - - // The ID of the managed node the high-level patch compliance information was - // collected for. - // - // This member is required. - InstanceId *string - - // The type of patching operation that was performed: or - // - SCAN assesses the patch compliance state. - // - INSTALL installs missing patches. - // - // This member is required. - Operation PatchOperationType - - // The time the most recent patching operation completed on the managed node. - // - // This member is required. - OperationEndTime *time.Time - - // The time the most recent patching operation was started on the managed node. - // - // This member is required. - OperationStartTime *time.Time - - // The name of the patch group the managed node belongs to. - // - // This member is required. - PatchGroup *string - - // The number of patches per node that are specified as Critical for compliance - // reporting in the patch baseline aren't installed. These patches might be - // missing, have failed installation, were rejected, or were installed but awaiting - // a required managed node reboot. The status of these managed nodes is - // NON_COMPLIANT . - CriticalNonCompliantCount *int32 - - // The number of patches from the patch baseline that were attempted to be - // installed during the last patching operation, but failed to install. - FailedCount int32 - - // An https URL or an Amazon Simple Storage Service (Amazon S3) path-style URL to - // a list of patches to be installed. This patch installation list, which you - // maintain in an S3 bucket in YAML format and specify in the SSM document - // AWS-RunPatchBaseline , overrides the patches specified by the default patch - // baseline. For more information about the InstallOverrideList parameter, see - // About the AWS-RunPatchBaseline (https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager-about-aws-runpatchbaseline.html) - // SSM document in the Amazon Web Services Systems Manager User Guide. - InstallOverrideList *string - - // The number of patches from the patch baseline that are installed on the managed - // node. - InstalledCount int32 - - // The number of patches not specified in the patch baseline that are installed on - // the managed node. - InstalledOtherCount int32 - - // The number of patches installed by Patch Manager since the last time the - // managed node was rebooted. - InstalledPendingRebootCount *int32 - - // The number of patches installed on a managed node that are specified in a - // RejectedPatches list. Patches with a status of InstalledRejected were typically - // installed before they were added to a RejectedPatches list. If - // ALLOW_AS_DEPENDENCY is the specified option for RejectedPatchesAction , the - // value of InstalledRejectedCount will always be 0 (zero). - InstalledRejectedCount *int32 - - // The time of the last attempt to patch the managed node with NoReboot specified - // as the reboot option. - LastNoRebootInstallOperationTime *time.Time - - // The number of patches from the patch baseline that are applicable for the - // managed node but aren't currently installed. - MissingCount int32 - - // The number of patches from the patch baseline that aren't applicable for the - // managed node and therefore aren't installed on the node. This number may be - // truncated if the list of patch names is very large. The number of patches beyond - // this limit are reported in UnreportedNotApplicableCount . - NotApplicableCount int32 - - // The number of patches per node that are specified as other than Critical or - // Security but aren't compliant with the patch baseline. The status of these - // managed nodes is NON_COMPLIANT . - OtherNonCompliantCount *int32 - - // Placeholder information. This field will always be empty in the current release - // of the service. - OwnerInformation *string - - // Indicates the reboot option specified in the patch baseline. Reboot options - // apply to Install operations only. Reboots aren't attempted for Patch Manager - // Scan operations. - // - RebootIfNeeded : Patch Manager tries to reboot the managed node if it - // installed any patches, or if any patches are detected with a status of - // InstalledPendingReboot . - // - NoReboot : Patch Manager attempts to install missing packages without trying - // to reboot the system. Patches installed with this option are assigned a status - // of InstalledPendingReboot . These patches might not be in effect until a - // reboot is performed. - RebootOption RebootOption - - // The number of patches per node that are specified as Security in a patch - // advisory aren't installed. These patches might be missing, have failed - // installation, were rejected, or were installed but awaiting a required managed - // node reboot. The status of these managed nodes is NON_COMPLIANT . - SecurityNonCompliantCount *int32 - - // The ID of the patch baseline snapshot used during the patching operation when - // this compliance data was collected. - SnapshotId *string - - // The number of patches beyond the supported limit of NotApplicableCount that - // aren't reported by name to Inventory. Inventory is a capability of Amazon Web - // Services Systems Manager. - UnreportedNotApplicableCount *int32 - - noSmithyDocumentSerde -} - -// Defines a filter used in DescribeInstancePatchStatesForPatchGroup to scope down -// the information returned by the API. Example: To filter for all managed nodes in -// a patch group having more than three patches with a FailedCount status, use the -// following for the filter: -// - Value for Key : FailedCount -// - Value for Type : GreaterThan -// - Value for Values : 3 -type InstancePatchStateFilter struct { - - // The key for the filter. Supported values include the following: - // - InstalledCount - // - InstalledOtherCount - // - InstalledPendingRebootCount - // - InstalledRejectedCount - // - MissingCount - // - FailedCount - // - UnreportedNotApplicableCount - // - NotApplicableCount - // - // This member is required. - Key *string - - // The type of comparison that should be performed for the value. - // - // This member is required. - Type InstancePatchStateOperatorType - - // The value for the filter. Must be an integer greater than or equal to 0. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Specifies the inventory type and attribute for the aggregation execution. -type InventoryAggregator struct { - - // Nested aggregators to further refine aggregation for an inventory type. - Aggregators []InventoryAggregator - - // The inventory type and attribute name for aggregation. - Expression *string - - // A user-defined set of one or more filters on which to aggregate inventory data. - // Groups return a count of resources that match and don't match the specified - // criteria. - Groups []InventoryGroup - - noSmithyDocumentSerde -} - -// Status information returned by the DeleteInventory operation. -type InventoryDeletionStatusItem struct { - - // The deletion ID returned by the DeleteInventory operation. - DeletionId *string - - // The UTC timestamp when the delete operation started. - DeletionStartTime *time.Time - - // Information about the delete operation. For more information about this - // summary, see Understanding the delete inventory summary (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-custom.html#sysman-inventory-delete) - // in the Amazon Web Services Systems Manager User Guide. - DeletionSummary *InventoryDeletionSummary - - // The status of the operation. Possible values are InProgress and Complete. - LastStatus InventoryDeletionStatus - - // Information about the status. - LastStatusMessage *string - - // The UTC timestamp of when the last status report. - LastStatusUpdateTime *time.Time - - // The name of the inventory data type. - TypeName *string - - noSmithyDocumentSerde -} - -// Information about the delete operation. -type InventoryDeletionSummary struct { - - // Remaining number of items to delete. - RemainingCount int32 - - // A list of counts and versions for deleted items. - SummaryItems []InventoryDeletionSummaryItem - - // The total number of items to delete. This count doesn't change during the - // delete operation. - TotalCount int32 - - noSmithyDocumentSerde -} - -// Either a count, remaining count, or a version number in a delete inventory -// summary. -type InventoryDeletionSummaryItem struct { - - // A count of the number of deleted items. - Count int32 - - // The remaining number of items to delete. - RemainingCount int32 - - // The inventory type version. - Version *string - - noSmithyDocumentSerde -} - -// One or more filters. Use a filter to return a more specific list of results. -type InventoryFilter struct { - - // The name of the filter key. - // - // This member is required. - Key *string - - // Inventory filter values. Example: inventory filter where managed node IDs are - // specified as values Key=AWS:InstanceInformation.InstanceId,Values= - // i-a12b3c4d5e6g, i-1a2b3c4d5e6,Type=Equal . - // - // This member is required. - Values []string - - // The type of filter. The Exists filter must be used with aggregators. For more - // information, see Aggregating inventory data (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-aggregate.html) - // in the Amazon Web Services Systems Manager User Guide. - Type InventoryQueryOperatorType - - noSmithyDocumentSerde -} - -// A user-defined set of one or more filters on which to aggregate inventory data. -// Groups return a count of resources that match and don't match the specified -// criteria. -type InventoryGroup struct { - - // Filters define the criteria for the group. The matchingCount field displays the - // number of resources that match the criteria. The notMatchingCount field - // displays the number of resources that don't match the criteria. - // - // This member is required. - Filters []InventoryFilter - - // The name of the group. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -// Information collected from managed nodes based on your inventory policy document -type InventoryItem struct { - - // The time the inventory information was collected. - // - // This member is required. - CaptureTime *string - - // The schema version for the inventory item. - // - // This member is required. - SchemaVersion *string - - // The name of the inventory type. Default inventory item type names start with AWS - // . Custom inventory type names will start with Custom. Default inventory item - // types include the following: AWS:AWSComponent , AWS:Application , - // AWS:InstanceInformation , AWS:Network , and AWS:WindowsUpdate . - // - // This member is required. - TypeName *string - - // The inventory data of the inventory type. - Content []map[string]string - - // MD5 hash of the inventory item type contents. The content hash is used to - // determine whether to update inventory information. The PutInventory API doesn't - // update the inventory item type contents if the MD5 hash hasn't changed since - // last update. - ContentHash *string - - // A map of associated properties for a specified inventory type. For example, - // with this attribute, you can specify the ExecutionId , ExecutionType , - // ComplianceType properties of the AWS:ComplianceItem type. - Context map[string]string - - noSmithyDocumentSerde -} - -// Attributes are the entries within the inventory item content. It contains name -// and value. -type InventoryItemAttribute struct { - - // The data type of the inventory item attribute. - // - // This member is required. - DataType InventoryAttributeDataType - - // Name of the inventory item attribute. - // - // This member is required. - Name *string - - noSmithyDocumentSerde -} - -// The inventory item schema definition. Users can use this to compose inventory -// query filters. -type InventoryItemSchema struct { - - // The schema attributes for inventory. This contains data type and attribute name. - // - // This member is required. - Attributes []InventoryItemAttribute - - // The name of the inventory type. Default inventory item type names start with - // Amazon Web Services. Custom inventory type names will start with Custom. Default - // inventory item types include the following: AWS:AWSComponent , AWS:Application , - // AWS:InstanceInformation , AWS:Network , and AWS:WindowsUpdate . - // - // This member is required. - TypeName *string - - // The alias name of the inventory type. The alias name is used for display - // purposes. - DisplayName *string - - // The schema version for the inventory item. - Version *string - - noSmithyDocumentSerde -} - -// Inventory query results. -type InventoryResultEntity struct { - - // The data section in the inventory result entity JSON. - Data map[string]InventoryResultItem - - // ID of the inventory result entity. For example, for managed node inventory the - // result will be the managed node ID. For EC2 instance inventory, the result will - // be the instance ID. - Id *string - - noSmithyDocumentSerde -} - -// The inventory result item. -type InventoryResultItem struct { - - // Contains all the inventory data of the item type. Results include attribute - // names and values. - // - // This member is required. - Content []map[string]string - - // The schema version for the inventory result item/ - // - // This member is required. - SchemaVersion *string - - // The name of the inventory result item type. - // - // This member is required. - TypeName *string - - // The time inventory item data was captured. - CaptureTime *string - - // MD5 hash of the inventory item type contents. The content hash is used to - // determine whether to update inventory information. The PutInventory API doesn't - // update the inventory item type contents if the MD5 hash hasn't changed since - // last update. - ContentHash *string - - noSmithyDocumentSerde -} - -// Information about an Amazon Simple Storage Service (Amazon S3) bucket to write -// managed node-level logs to. LoggingInfo has been deprecated. To specify an -// Amazon Simple Storage Service (Amazon S3) bucket to contain logs, instead use -// the OutputS3BucketName and OutputS3KeyPrefix options in the -// TaskInvocationParameters structure. For information about how Amazon Web -// Services Systems Manager handles these options for the supported maintenance -// window task types, see MaintenanceWindowTaskInvocationParameters . -type LoggingInfo struct { - - // The name of an S3 bucket where execution logs are stored. - // - // This member is required. - S3BucketName *string - - // The Amazon Web Services Region where the S3 bucket is located. - // - // This member is required. - S3Region *string - - // (Optional) The S3 bucket subfolder. - S3KeyPrefix *string - - noSmithyDocumentSerde -} - -// The parameters for an AUTOMATION task type. -type MaintenanceWindowAutomationParameters struct { - - // The version of an Automation runbook to use during task execution. - DocumentVersion *string - - // The parameters for the AUTOMATION task. For information about specifying and - // updating task parameters, see RegisterTaskWithMaintenanceWindow and - // UpdateMaintenanceWindowTask . LoggingInfo has been deprecated. To specify an - // Amazon Simple Storage Service (Amazon S3) bucket to contain logs, instead use - // the OutputS3BucketName and OutputS3KeyPrefix options in the - // TaskInvocationParameters structure. For information about how Amazon Web - // Services Systems Manager handles these options for the supported maintenance - // window task types, see MaintenanceWindowTaskInvocationParameters . - // TaskParameters has been deprecated. To specify parameters to pass to a task when - // it runs, instead use the Parameters option in the TaskInvocationParameters - // structure. For information about how Systems Manager handles these options for - // the supported maintenance window task types, see - // MaintenanceWindowTaskInvocationParameters . For AUTOMATION task types, Amazon - // Web Services Systems Manager ignores any values specified for these parameters. - Parameters map[string][]string - - noSmithyDocumentSerde -} - -// Describes the information about an execution of a maintenance window. -type MaintenanceWindowExecution struct { - - // The time the execution finished. - EndTime *time.Time - - // The time the execution started. - StartTime *time.Time - - // The status of the execution. - Status MaintenanceWindowExecutionStatus - - // The details explaining the status. Not available for all status values. - StatusDetails *string - - // The ID of the maintenance window execution. - WindowExecutionId *string - - // The ID of the maintenance window. - WindowId *string - - noSmithyDocumentSerde -} - -// Information about a task execution performed as part of a maintenance window -// execution. -type MaintenanceWindowExecutionTaskIdentity struct { - - // The details for the CloudWatch alarm applied to your maintenance window task. - AlarmConfiguration *AlarmConfiguration - - // The time the task execution finished. - EndTime *time.Time - - // The time the task execution started. - StartTime *time.Time - - // The status of the task execution. - Status MaintenanceWindowExecutionStatus - - // The details explaining the status of the task execution. Not available for all - // status values. - StatusDetails *string - - // The Amazon Resource Name (ARN) of the task that ran. - TaskArn *string - - // The ID of the specific task execution in the maintenance window execution. - TaskExecutionId *string - - // The type of task that ran. - TaskType MaintenanceWindowTaskType - - // The CloudWatch alarm that was invoked by the maintenance window task. - TriggeredAlarms []AlarmStateInformation - - // The ID of the maintenance window execution that ran the task. - WindowExecutionId *string - - noSmithyDocumentSerde -} - -// Describes the information about a task invocation for a particular target as -// part of a task execution performed as part of a maintenance window execution. -type MaintenanceWindowExecutionTaskInvocationIdentity struct { - - // The time the invocation finished. - EndTime *time.Time - - // The ID of the action performed in the service that actually handled the task - // invocation. If the task type is RUN_COMMAND , this value is the command ID. - ExecutionId *string - - // The ID of the task invocation. - InvocationId *string - - // User-provided value that was specified when the target was registered with the - // maintenance window. This was also included in any Amazon CloudWatch Events - // events raised during the task invocation. - OwnerInformation *string - - // The parameters that were provided for the invocation when it was run. - Parameters *string - - // The time the invocation started. - StartTime *time.Time - - // The status of the task invocation. - Status MaintenanceWindowExecutionStatus - - // The details explaining the status of the task invocation. Not available for all - // status values. - StatusDetails *string - - // The ID of the specific task execution in the maintenance window execution. - TaskExecutionId *string - - // The task type. - TaskType MaintenanceWindowTaskType - - // The ID of the maintenance window execution that ran the task. - WindowExecutionId *string - - // The ID of the target definition in this maintenance window the invocation was - // performed for. - WindowTargetId *string - - noSmithyDocumentSerde -} - -// Filter used in the request. Supported filter keys depend on the API operation -// that includes the filter. API operations that use MaintenanceWindowFilter> -// include the following: -// - DescribeMaintenanceWindowExecutions -// - DescribeMaintenanceWindowExecutionTaskInvocations -// - DescribeMaintenanceWindowExecutionTasks -// - DescribeMaintenanceWindows -// - DescribeMaintenanceWindowTargets -// - DescribeMaintenanceWindowTasks -type MaintenanceWindowFilter struct { - - // The name of the filter. - Key *string - - // The filter values. - Values []string - - noSmithyDocumentSerde -} - -// Information about the maintenance window. -type MaintenanceWindowIdentity struct { - - // The number of hours before the end of the maintenance window that Amazon Web - // Services Systems Manager stops scheduling new tasks for execution. - Cutoff int32 - - // A description of the maintenance window. - Description *string - - // The duration of the maintenance window in hours. - Duration *int32 - - // Indicates whether the maintenance window is enabled. - Enabled bool - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become inactive. - EndDate *string - - // The name of the maintenance window. - Name *string - - // The next time the maintenance window will actually run, taking into account any - // specified times for the maintenance window to become active or inactive. - NextExecutionTime *string - - // The schedule of the maintenance window in the form of a cron or rate expression. - Schedule *string - - // The number of days to wait to run a maintenance window after the scheduled cron - // expression date and time. - ScheduleOffset *int32 - - // The time zone that the scheduled maintenance window executions are based on, in - // Internet Assigned Numbers Authority (IANA) format. - ScheduleTimezone *string - - // The date and time, in ISO-8601 Extended format, for when the maintenance window - // is scheduled to become active. - StartDate *string - - // The ID of the maintenance window. - WindowId *string - - noSmithyDocumentSerde -} - -// The maintenance window to which the specified target belongs. -type MaintenanceWindowIdentityForTarget struct { - - // The name of the maintenance window. - Name *string - - // The ID of the maintenance window. - WindowId *string - - noSmithyDocumentSerde -} - -// The parameters for a LAMBDA task type. For information about specifying and -// updating task parameters, see RegisterTaskWithMaintenanceWindow and -// UpdateMaintenanceWindowTask . LoggingInfo has been deprecated. To specify an -// Amazon Simple Storage Service (Amazon S3) bucket to contain logs, instead use -// the OutputS3BucketName and OutputS3KeyPrefix options in the -// TaskInvocationParameters structure. For information about how Amazon Web -// Services Systems Manager handles these options for the supported maintenance -// window task types, see MaintenanceWindowTaskInvocationParameters . -// TaskParameters has been deprecated. To specify parameters to pass to a task when -// it runs, instead use the Parameters option in the TaskInvocationParameters -// structure. For information about how Systems Manager handles these options for -// the supported maintenance window task types, see -// MaintenanceWindowTaskInvocationParameters . For Lambda tasks, Systems Manager -// ignores any values specified for TaskParameters and LoggingInfo. -type MaintenanceWindowLambdaParameters struct { - - // Pass client-specific information to the Lambda function that you are invoking. - // You can then process the client information in your Lambda function as you - // choose through the context variable. - ClientContext *string - - // JSON to provide to your Lambda function as input. - Payload []byte - - // (Optional) Specify an Lambda function version or alias name. If you specify a - // function version, the operation uses the qualified function Amazon Resource Name - // (ARN) to invoke a specific Lambda function. If you specify an alias name, the - // operation uses the alias ARN to invoke the Lambda function version to which the - // alias points. - Qualifier *string - - noSmithyDocumentSerde -} - -// The parameters for a RUN_COMMAND task type. For information about specifying -// and updating task parameters, see RegisterTaskWithMaintenanceWindow and -// UpdateMaintenanceWindowTask . LoggingInfo has been deprecated. To specify an -// Amazon Simple Storage Service (Amazon S3) bucket to contain logs, instead use -// the OutputS3BucketName and OutputS3KeyPrefix options in the -// TaskInvocationParameters structure. For information about how Amazon Web -// Services Systems Manager handles these options for the supported maintenance -// window task types, see MaintenanceWindowTaskInvocationParameters . -// TaskParameters has been deprecated. To specify parameters to pass to a task when -// it runs, instead use the Parameters option in the TaskInvocationParameters -// structure. For information about how Systems Manager handles these options for -// the supported maintenance window task types, see -// MaintenanceWindowTaskInvocationParameters . For RUN_COMMAND tasks, Systems -// Manager uses specified values for TaskParameters and LoggingInfo only if no -// values are specified for TaskInvocationParameters . -type MaintenanceWindowRunCommandParameters struct { - - // Configuration options for sending command output to Amazon CloudWatch Logs. - CloudWatchOutputConfig *CloudWatchOutputConfig - - // Information about the commands to run. - Comment *string - - // The SHA-256 or SHA-1 hash created by the system when the document was created. - // SHA-1 hashes have been deprecated. - DocumentHash *string - - // SHA-256 or SHA-1. SHA-1 hashes have been deprecated. - DocumentHashType DocumentHashType - - // The Amazon Web Services Systems Manager document (SSM document) version to use - // in the request. You can specify $DEFAULT , $LATEST , or a specific version - // number. If you run commands by using the Amazon Web Services CLI, then you must - // escape the first two options by using a backslash. If you specify a version - // number, then you don't need to use the backslash. For example: - // --document-version "\$DEFAULT" - // --document-version "\$LATEST" - // - // --document-version "3" - DocumentVersion *string - - // Configurations for sending notifications about command status changes on a - // per-managed node basis. - NotificationConfig *NotificationConfig - - // The name of the Amazon Simple Storage Service (Amazon S3) bucket. - OutputS3BucketName *string - - // The S3 bucket subfolder. - OutputS3KeyPrefix *string - - // The parameters for the RUN_COMMAND task execution. - Parameters map[string][]string - - // The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) - // service role to use to publish Amazon Simple Notification Service (Amazon SNS) - // notifications for maintenance window Run Command tasks. - ServiceRoleArn *string - - // If this time is reached and the command hasn't already started running, it - // doesn't run. - TimeoutSeconds *int32 - - noSmithyDocumentSerde -} - -// The parameters for a STEP_FUNCTIONS task. For information about specifying and -// updating task parameters, see RegisterTaskWithMaintenanceWindow and -// UpdateMaintenanceWindowTask . LoggingInfo has been deprecated. To specify an -// Amazon Simple Storage Service (Amazon S3) bucket to contain logs, instead use -// the OutputS3BucketName and OutputS3KeyPrefix options in the -// TaskInvocationParameters structure. For information about how Amazon Web -// Services Systems Manager handles these options for the supported maintenance -// window task types, see MaintenanceWindowTaskInvocationParameters . -// TaskParameters has been deprecated. To specify parameters to pass to a task when -// it runs, instead use the Parameters option in the TaskInvocationParameters -// structure. For information about how Systems Manager handles these options for -// the supported maintenance window task types, see -// MaintenanceWindowTaskInvocationParameters . For Step Functions tasks, Systems -// Manager ignores any values specified for TaskParameters and LoggingInfo . -type MaintenanceWindowStepFunctionsParameters struct { - - // The inputs for the STEP_FUNCTIONS task. - Input *string - - // The name of the STEP_FUNCTIONS task. - Name *string - - noSmithyDocumentSerde -} - -// The target registered with the maintenance window. -type MaintenanceWindowTarget struct { - - // A description for the target. - Description *string - - // The name for the maintenance window target. - Name *string - - // A user-provided value that will be included in any Amazon CloudWatch Events - // events that are raised while running tasks for these targets in this maintenance - // window. - OwnerInformation *string - - // The type of target that is being registered with the maintenance window. - ResourceType MaintenanceWindowResourceType - - // The targets, either managed nodes or tags. Specify managed nodes using the - // following format: Key=instanceids,Values=, Tags are specified using the - // following format: Key=,Values= . - Targets []Target - - // The ID of the maintenance window to register the target with. - WindowId *string - - // The ID of the target. - WindowTargetId *string - - noSmithyDocumentSerde -} - -// Information about a task defined for a maintenance window. -type MaintenanceWindowTask struct { - - // The details for the CloudWatch alarm applied to your maintenance window task. - AlarmConfiguration *AlarmConfiguration - - // The specification for whether tasks should continue to run after the cutoff - // time specified in the maintenance windows is reached. - CutoffBehavior MaintenanceWindowTaskCutoffBehavior - - // A description of the task. - Description *string - - // Information about an S3 bucket to write task-level logs to. LoggingInfo has - // been deprecated. To specify an Amazon Simple Storage Service (Amazon S3) bucket - // to contain logs, instead use the OutputS3BucketName and OutputS3KeyPrefix - // options in the TaskInvocationParameters structure. For information about how - // Amazon Web Services Systems Manager handles these options for the supported - // maintenance window task types, see MaintenanceWindowTaskInvocationParameters . - LoggingInfo *LoggingInfo - - // The maximum number of targets this task can be run for, in parallel. Although - // this element is listed as "Required: No", a value can be omitted only when you - // are registering or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxConcurrency *string - - // The maximum number of errors allowed before this task stops being scheduled. - // Although this element is listed as "Required: No", a value can be omitted only - // when you are registering or updating a targetless task (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) - // You must provide a value in all other cases. For maintenance window tasks - // without a target specified, you can't supply a value for this option. Instead, - // the system inserts a placeholder value of 1 . This value doesn't affect the - // running of your task. - MaxErrors *string - - // The task name. - Name *string - - // The priority of the task in the maintenance window. The lower the number, the - // higher the priority. Tasks that have the same priority are scheduled in - // parallel. - Priority int32 - - // The Amazon Resource Name (ARN) of the Identity and Access Management (IAM) - // service role to use to publish Amazon Simple Notification Service (Amazon SNS) - // notifications for maintenance window Run Command tasks. - ServiceRoleArn *string - - // The targets (either managed nodes or tags). Managed nodes are specified using - // Key=instanceids,Values=, . Tags are specified using Key=,Values= . - Targets []Target - - // The resource that the task uses during execution. For RUN_COMMAND and AUTOMATION - // task types, TaskArn is the Amazon Web Services Systems Manager (SSM document) - // name or ARN. For LAMBDA tasks, it's the function name or ARN. For STEP_FUNCTIONS - // tasks, it's the state machine ARN. - TaskArn *string - - // The parameters that should be passed to the task when it is run. TaskParameters - // has been deprecated. To specify parameters to pass to a task when it runs, - // instead use the Parameters option in the TaskInvocationParameters structure. - // For information about how Systems Manager handles these options for the - // supported maintenance window task types, see - // MaintenanceWindowTaskInvocationParameters . - TaskParameters map[string]MaintenanceWindowTaskParameterValueExpression - - // The type of task. - Type MaintenanceWindowTaskType - - // The ID of the maintenance window where the task is registered. - WindowId *string - - // The task ID. - WindowTaskId *string - - noSmithyDocumentSerde -} - -// The parameters for task execution. -type MaintenanceWindowTaskInvocationParameters struct { - - // The parameters for an AUTOMATION task type. - Automation *MaintenanceWindowAutomationParameters - - // The parameters for a LAMBDA task type. - Lambda *MaintenanceWindowLambdaParameters - - // The parameters for a RUN_COMMAND task type. - RunCommand *MaintenanceWindowRunCommandParameters - - // The parameters for a STEP_FUNCTIONS task type. - StepFunctions *MaintenanceWindowStepFunctionsParameters - - noSmithyDocumentSerde -} - -// Defines the values for a task parameter. -type MaintenanceWindowTaskParameterValueExpression struct { - - // This field contains an array of 0 or more strings, each 1 to 255 characters in - // length. - Values []string - - noSmithyDocumentSerde -} - -// Metadata to assign to an Application Manager application. -type MetadataValue struct { - - // Metadata value to assign to an Application Manager application. - Value *string - - noSmithyDocumentSerde -} - -// A summary of resources that aren't compliant. The summary is organized -// according to resource type. -type NonCompliantSummary struct { - - // The total number of compliance items that aren't compliant. - NonCompliantCount int32 - - // A summary of the non-compliance severity by compliance type - SeveritySummary *SeveritySummary - - noSmithyDocumentSerde -} - -// Configurations for sending notifications. -type NotificationConfig struct { - - // An Amazon Resource Name (ARN) for an Amazon Simple Notification Service (Amazon - // SNS) topic. Run Command pushes notifications about command status changes to - // this topic. - NotificationArn *string - - // The different events for which you can receive notifications. To learn more - // about these events, see Monitoring Systems Manager status changes using Amazon - // SNS notifications (https://docs.aws.amazon.com/systems-manager/latest/userguide/monitoring-sns-notifications.html) - // in the Amazon Web Services Systems Manager User Guide. - NotificationEvents []NotificationEvent - - // The type of notification. - // - Command : Receive notification when the status of a command changes. - // - Invocation : For commands sent to multiple managed nodes, receive - // notification on a per-node basis when the status of a command changes. - NotificationType NotificationType - - noSmithyDocumentSerde -} - -// One or more aggregators for viewing counts of OpsData using different -// dimensions such as Source , CreatedTime , or Source and CreatedTime , to name a -// few. -type OpsAggregator struct { - - // Either a Range or Count aggregator for limiting an OpsData summary. - AggregatorType *string - - // A nested aggregator for viewing counts of OpsData. - Aggregators []OpsAggregator - - // The name of an OpsData attribute on which to limit the count of OpsData. - AttributeName *string - - // The aggregator filters. - Filters []OpsFilter - - // The data type name to use for viewing counts of OpsData. - TypeName *string - - // The aggregator value. - Values map[string]string - - noSmithyDocumentSerde -} - -// The result of the query. -type OpsEntity struct { - - // The data returned by the query. - Data map[string]OpsEntityItem - - // The query ID. - Id *string - - noSmithyDocumentSerde -} - -// The OpsData summary. -type OpsEntityItem struct { - - // The time the OpsData was captured. - CaptureTime *string - - // The details of an OpsData summary. - Content []map[string]string - - noSmithyDocumentSerde -} - -// A filter for viewing OpsData summaries. -type OpsFilter struct { - - // The name of the filter. - // - // This member is required. - Key *string - - // The filter value. - // - // This member is required. - Values []string - - // The type of filter. - Type OpsFilterOperatorType - - noSmithyDocumentSerde -} - -// Operations engineers and IT professionals use Amazon Web Services Systems -// Manager OpsCenter to view, investigate, and remediate operational work items -// (OpsItems) impacting the performance and health of their Amazon Web Services -// resources. OpsCenter is integrated with Amazon EventBridge and Amazon -// CloudWatch. This means you can configure these services to automatically create -// an OpsItem in OpsCenter when a CloudWatch alarm enters the ALARM state or when -// EventBridge processes an event from any Amazon Web Services service that -// publishes events. Configuring Amazon CloudWatch alarms and EventBridge events to -// automatically create OpsItems allows you to quickly diagnose and remediate -// issues with Amazon Web Services resources from a single console. To help you -// diagnose issues, each OpsItem includes contextually relevant information such as -// the name and ID of the Amazon Web Services resource that generated the OpsItem, -// alarm or event details, alarm history, and an alarm timeline graph. For the -// Amazon Web Services resource, OpsCenter aggregates information from Config, -// CloudTrail logs, and EventBridge, so you don't have to navigate across multiple -// console pages during your investigation. For more information, see OpsCenter (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter.html) -// in the Amazon Web Services Systems Manager User Guide. -type OpsItem struct { - - // The time a runbook workflow ended. Currently reported only for the OpsItem type - // /aws/changerequest . - ActualEndTime *time.Time - - // The time a runbook workflow started. Currently reported only for the OpsItem - // type /aws/changerequest . - ActualStartTime *time.Time - - // An OpsItem category. Category options include: Availability, Cost, Performance, - // Recovery, Security. - Category *string - - // The ARN of the Amazon Web Services account that created the OpsItem. - CreatedBy *string - - // The date and time the OpsItem was created. - CreatedTime *time.Time - - // The OpsItem description. - Description *string - - // The ARN of the Amazon Web Services account that last updated the OpsItem. - LastModifiedBy *string - - // The date and time the OpsItem was last updated. - LastModifiedTime *time.Time - - // The Amazon Resource Name (ARN) of an Amazon Simple Notification Service (Amazon - // SNS) topic where notifications are sent when this OpsItem is edited or changed. - Notifications []OpsItemNotification - - // Operational data is custom data that provides useful reference details about - // the OpsItem. For example, you can specify log files, error strings, license - // keys, troubleshooting tips, or other relevant data. You enter operational data - // as key-value pairs. The key has a maximum length of 128 characters. The value - // has a maximum size of 20 KB. Operational data keys can't begin with the - // following: amazon , aws , amzn , ssm , /amazon , /aws , /amzn , /ssm . You can - // choose to make the data searchable by other users in the account or you can - // restrict search access. Searchable data means that all users with access to the - // OpsItem Overview page (as provided by the DescribeOpsItems API operation) can - // view and search on the specified data. Operational data that isn't searchable is - // only viewable by users who have access to the OpsItem (as provided by the - // GetOpsItem API operation). Use the /aws/resources key in OperationalData to - // specify a related resource in the request. Use the /aws/automations key in - // OperationalData to associate an Automation runbook with the OpsItem. To view - // Amazon Web Services CLI example commands that use these keys, see Creating - // OpsItems manually (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-manually-create-OpsItems.html) - // in the Amazon Web Services Systems Manager User Guide. - OperationalData map[string]OpsItemDataValue - - // The OpsItem Amazon Resource Name (ARN). - OpsItemArn *string - - // The ID of the OpsItem. - OpsItemId *string - - // The type of OpsItem. Systems Manager supports the following types of OpsItems: - // - /aws/issue This type of OpsItem is used for default OpsItems created by - // OpsCenter. - // - /aws/changerequest This type of OpsItem is used by Change Manager for - // reviewing and approving or rejecting change requests. - // - /aws/insight This type of OpsItem is used by OpsCenter for aggregating and - // reporting on duplicate OpsItems. - OpsItemType *string - - // The time specified in a change request for a runbook workflow to end. Currently - // supported only for the OpsItem type /aws/changerequest . - PlannedEndTime *time.Time - - // The time specified in a change request for a runbook workflow to start. - // Currently supported only for the OpsItem type /aws/changerequest . - PlannedStartTime *time.Time - - // The importance of this OpsItem in relation to other OpsItems in the system. - Priority *int32 - - // One or more OpsItems that share something in common with the current OpsItem. - // For example, related OpsItems can include OpsItems with similar error messages, - // impacted resources, or statuses for the impacted resource. - RelatedOpsItems []RelatedOpsItem - - // The severity of the OpsItem. Severity options range from 1 to 4. - Severity *string - - // The origin of the OpsItem, such as Amazon EC2 or Systems Manager. The impacted - // resource is a subset of source. - Source *string - - // The OpsItem status. Status can be Open , In Progress , or Resolved . For more - // information, see Editing OpsItem details (https://docs.aws.amazon.com/systems-manager/latest/userguide/OpsCenter-working-with-OpsItems-editing-details.html) - // in the Amazon Web Services Systems Manager User Guide. - Status OpsItemStatus - - // A short heading that describes the nature of the OpsItem and the impacted - // resource. - Title *string - - // The version of this OpsItem. Each time the OpsItem is edited the version number - // increments by one. - Version *string - - noSmithyDocumentSerde -} - -// An object that defines the value of the key and its type in the OperationalData -// map. -type OpsItemDataValue struct { - - // The type of key-value pair. Valid types include SearchableString and String . - Type OpsItemDataType - - // The value of the OperationalData key. - Value *string - - noSmithyDocumentSerde -} - -// Describes a filter for a specific list of OpsItem events. You can filter event -// information by using tags. You specify tags by using a key-value pair mapping. -type OpsItemEventFilter struct { - - // The name of the filter key. Currently, the only supported value is OpsItemId . - // - // This member is required. - Key OpsItemEventFilterKey - - // The operator used by the filter call. Currently, the only supported value is - // Equal . - // - // This member is required. - Operator OpsItemEventFilterOperator - - // The values for the filter, consisting of one or more OpsItem IDs. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Summary information about an OpsItem event or that associated an OpsItem with a -// related item. -type OpsItemEventSummary struct { - - // Information about the user or resource that created the OpsItem event. - CreatedBy *OpsItemIdentity - - // The date and time the OpsItem event was created. - CreatedTime *time.Time - - // Specific information about the OpsItem event. - Detail *string - - // The type of information provided as a detail. - DetailType *string - - // The ID of the OpsItem event. - EventId *string - - // The ID of the OpsItem. - OpsItemId *string - - // The source of the OpsItem event. - Source *string - - noSmithyDocumentSerde -} - -// Describes an OpsItem filter. -type OpsItemFilter struct { - - // The name of the filter. - // - // This member is required. - Key OpsItemFilterKey - - // The operator used by the filter call. - // - // This member is required. - Operator OpsItemFilterOperator - - // The filter value. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Information about the user or resource that created an OpsItem event. -type OpsItemIdentity struct { - - // The Amazon Resource Name (ARN) of the IAM entity that created the OpsItem event. - Arn *string - - noSmithyDocumentSerde -} - -// A notification about the OpsItem. -type OpsItemNotification struct { - - // The Amazon Resource Name (ARN) of an Amazon Simple Notification Service (Amazon - // SNS) topic where notifications are sent when this OpsItem is edited or changed. - Arn *string - - noSmithyDocumentSerde -} - -// Describes a filter for a specific list of related-item resources. -type OpsItemRelatedItemsFilter struct { - - // The name of the filter key. Supported values include ResourceUri , ResourceType - // , or AssociationId . - // - // This member is required. - Key OpsItemRelatedItemsFilterKey - - // The operator used by the filter call. The only supported operator is EQUAL . - // - // This member is required. - Operator OpsItemRelatedItemsFilterOperator - - // The values for the filter. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Summary information about related-item resources for an OpsItem. -type OpsItemRelatedItemSummary struct { - - // The association ID. - AssociationId *string - - // The association type. - AssociationType *string - - // Information about the user or resource that created an OpsItem event. - CreatedBy *OpsItemIdentity - - // The time the related-item association was created. - CreatedTime *time.Time - - // Information about the user or resource that created an OpsItem event. - LastModifiedBy *OpsItemIdentity - - // The time the related-item association was last updated. - LastModifiedTime *time.Time - - // The OpsItem ID. - OpsItemId *string - - // The resource type. - ResourceType *string - - // The Amazon Resource Name (ARN) of the related-item resource. - ResourceUri *string - - noSmithyDocumentSerde -} - -// A count of OpsItems. -type OpsItemSummary struct { - - // The time a runbook workflow ended. Currently reported only for the OpsItem type - // /aws/changerequest . - ActualEndTime *time.Time - - // The time a runbook workflow started. Currently reported only for the OpsItem - // type /aws/changerequest . - ActualStartTime *time.Time - - // A list of OpsItems by category. - Category *string - - // The Amazon Resource Name (ARN) of the IAM entity that created the OpsItem. - CreatedBy *string - - // The date and time the OpsItem was created. - CreatedTime *time.Time - - // The Amazon Resource Name (ARN) of the IAM entity that created the OpsItem. - LastModifiedBy *string - - // The date and time the OpsItem was last updated. - LastModifiedTime *time.Time - - // Operational data is custom data that provides useful reference details about - // the OpsItem. - OperationalData map[string]OpsItemDataValue - - // The ID of the OpsItem. - OpsItemId *string - - // The type of OpsItem. Systems Manager supports the following types of OpsItems: - // - /aws/issue This type of OpsItem is used for default OpsItems created by - // OpsCenter. - // - /aws/changerequest This type of OpsItem is used by Change Manager for - // reviewing and approving or rejecting change requests. - // - /aws/insight This type of OpsItem is used by OpsCenter for aggregating and - // reporting on duplicate OpsItems. - OpsItemType *string - - // The time specified in a change request for a runbook workflow to end. Currently - // supported only for the OpsItem type /aws/changerequest . - PlannedEndTime *time.Time - - // The time specified in a change request for a runbook workflow to start. - // Currently supported only for the OpsItem type /aws/changerequest . - PlannedStartTime *time.Time - - // The importance of this OpsItem in relation to other OpsItems in the system. - Priority *int32 - - // A list of OpsItems by severity. - Severity *string - - // The impacted Amazon Web Services resource. - Source *string - - // The OpsItem status. Status can be Open , In Progress , or Resolved . - Status OpsItemStatus - - // A short heading that describes the nature of the OpsItem and the impacted - // resource. - Title *string - - noSmithyDocumentSerde -} - -// Operational metadata for an application in Application Manager. -type OpsMetadata struct { - - // The date the OpsMetadata objects was created. - CreationDate *time.Time - - // The date the OpsMetadata object was last updated. - LastModifiedDate *time.Time - - // The user name who last updated the OpsMetadata object. - LastModifiedUser *string - - // The Amazon Resource Name (ARN) of the OpsMetadata Object or blob. - OpsMetadataArn *string - - // The ID of the Application Manager application. - ResourceId *string - - noSmithyDocumentSerde -} - -// A filter to limit the number of OpsMetadata objects displayed. -type OpsMetadataFilter struct { - - // A filter key. - // - // This member is required. - Key *string - - // A filter value. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// The OpsItem data type to return. -type OpsResultAttribute struct { - - // Name of the data type. Valid value: AWS:OpsItem , AWS:EC2InstanceInformation , - // AWS:OpsItemTrendline , or AWS:ComplianceSummary . - // - // This member is required. - TypeName *string - - noSmithyDocumentSerde -} - -// Information about the source where the association execution details are stored. -type OutputSource struct { - - // The ID of the output source, for example the URL of an S3 bucket. - OutputSourceId *string - - // The type of source where the association execution details are stored, for - // example, Amazon S3. - OutputSourceType *string - - noSmithyDocumentSerde -} - -// An Amazon Web Services Systems Manager parameter in Parameter Store. -type Parameter struct { - - // The Amazon Resource Name (ARN) of the parameter. - ARN *string - - // The data type of the parameter, such as text or aws:ec2:image . The default is - // text . - DataType *string - - // Date the parameter was last changed or updated and the parameter version was - // created. - LastModifiedDate *time.Time - - // The name of the parameter. - Name *string - - // Either the version number or the label used to retrieve the parameter value. - // Specify selectors by using one of the following formats: parameter_name:version - // parameter_name:label - Selector *string - - // Applies to parameters that reference information in other Amazon Web Services - // services. SourceResult is the raw result or response from the source. - SourceResult *string - - // The type of parameter. Valid values include the following: String , StringList , - // and SecureString . If type is StringList , the system returns a comma-separated - // string with no spaces between commas in the Value field. - Type ParameterType - - // The parameter value. If type is StringList , the system returns a - // comma-separated string with no spaces between commas in the Value field. - Value *string - - // The parameter version. - Version int64 - - noSmithyDocumentSerde -} - -// Information about parameter usage. -type ParameterHistory struct { - - // Parameter names can include the following letters and symbols. a-zA-Z0-9_.- - AllowedPattern *string - - // The data type of the parameter, such as text or aws:ec2:image . The default is - // text . - DataType *string - - // Information about the parameter. - Description *string - - // The ID of the query key used for this parameter. - KeyId *string - - // Labels assigned to the parameter version. - Labels []string - - // Date the parameter was last changed or updated. - LastModifiedDate *time.Time - - // Amazon Resource Name (ARN) of the Amazon Web Services user who last changed the - // parameter. - LastModifiedUser *string - - // The name of the parameter. - Name *string - - // Information about the policies assigned to a parameter. Assigning parameter - // policies (https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-policies.html) - // in the Amazon Web Services Systems Manager User Guide. - Policies []ParameterInlinePolicy - - // The parameter tier. - Tier ParameterTier - - // The type of parameter used. - Type ParameterType - - // The parameter value. - Value *string - - // The parameter version. - Version int64 - - noSmithyDocumentSerde -} - -// One or more policies assigned to a parameter. -type ParameterInlinePolicy struct { - - // The status of the policy. Policies report the following statuses: Pending (the - // policy hasn't been enforced or applied yet), Finished (the policy was applied), - // Failed (the policy wasn't applied), or InProgress (the policy is being applied - // now). - PolicyStatus *string - - // The JSON text of the policy. - PolicyText *string - - // The type of policy. Parameter Store, a capability of Amazon Web Services - // Systems Manager, supports the following policy types: Expiration, - // ExpirationNotification, and NoChangeNotification. - PolicyType *string - - noSmithyDocumentSerde -} - -// Metadata includes information like the ARN of the last user and the date/time -// the parameter was last used. -type ParameterMetadata struct { - - // A parameter name can include only the following letters and symbols. - // a-zA-Z0-9_.- - AllowedPattern *string - - // The data type of the parameter, such as text or aws:ec2:image . The default is - // text . - DataType *string - - // Description of the parameter actions. - Description *string - - // The ID of the query key used for this parameter. - KeyId *string - - // Date the parameter was last changed or updated. - LastModifiedDate *time.Time - - // Amazon Resource Name (ARN) of the Amazon Web Services user who last changed the - // parameter. - LastModifiedUser *string - - // The parameter name. - Name *string - - // A list of policies associated with a parameter. - Policies []ParameterInlinePolicy - - // The parameter tier. - Tier ParameterTier - - // The type of parameter. Valid parameter types include the following: String , - // StringList , and SecureString . - Type ParameterType - - // The parameter version. - Version int64 - - noSmithyDocumentSerde -} - -// This data type is deprecated. Instead, use ParameterStringFilter . -type ParametersFilter struct { - - // The name of the filter. - // - // This member is required. - Key ParametersFilterKey - - // The filter values. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// One or more filters. Use a filter to return a more specific list of results. -type ParameterStringFilter struct { - - // The name of the filter. The ParameterStringFilter object is used by the - // DescribeParameters and GetParametersByPath API operations. However, not all of - // the pattern values listed for Key can be used with both operations. For - // DescribeParameters , all of the listed patterns are valid except Label . For - // GetParametersByPath , the following patterns listed for Key aren't valid: tag , - // DataType , Name , Path , and Tier . For examples of Amazon Web Services CLI - // commands demonstrating valid parameter filter constructions, see Searching for - // Systems Manager parameters (https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-search.html) - // in the Amazon Web Services Systems Manager User Guide. - // - // This member is required. - Key *string - - // For all filters used with DescribeParameters , valid options include Equals and - // BeginsWith . The Name filter additionally supports the Contains option. - // (Exception: For filters using the key Path , valid options include Recursive - // and OneLevel .) For filters used with GetParametersByPath , valid options - // include Equals and BeginsWith . (Exception: For filters using Label as the Key - // name, the only valid option is Equals .) - Option *string - - // The value you want to search for. - Values []string - - noSmithyDocumentSerde -} - -// A detailed status of the parent step. -type ParentStepDetails struct { - - // The name of the automation action. - Action *string - - // The current repetition of the loop represented by an integer. - Iteration *int32 - - // The current value of the specified iterator in the loop. - IteratorValue *string - - // The unique ID of a step execution. - StepExecutionId *string - - // The name of the step. - StepName *string - - noSmithyDocumentSerde -} - -// Represents metadata about a patch. -type Patch struct { - - // The Advisory ID of the patch. For example, RHSA-2020:3779 . Applies to - // Linux-based managed nodes only. - AdvisoryIds []string - - // The architecture of the patch. For example, in - // example-pkg-0.710.10-2.7.abcd.x86_64 , the architecture is indicated by x86_64 . - // Applies to Linux-based managed nodes only. - Arch *string - - // The Bugzilla ID of the patch. For example, 1600646 . Applies to Linux-based - // managed nodes only. - BugzillaIds []string - - // The Common Vulnerabilities and Exposures (CVE) ID of the patch. For example, - // CVE-2011-3192 . Applies to Linux-based managed nodes only. - CVEIds []string - - // The classification of the patch. For example, SecurityUpdates , Updates , or - // CriticalUpdates . - Classification *string - - // The URL where more information can be obtained about the patch. - ContentUrl *string - - // The description of the patch. - Description *string - - // The epoch of the patch. For example in pkg-example-EE-20180914-2.2.amzn1.noarch - // , the epoch value is 20180914-2 . Applies to Linux-based managed nodes only. - Epoch int32 - - // The ID of the patch. Applies to Windows patches only. This ID isn't the same as - // the Microsoft Knowledge Base ID. - Id *string - - // The Microsoft Knowledge Base ID of the patch. Applies to Windows patches only. - KbNumber *string - - // The language of the patch if it's language-specific. - Language *string - - // The ID of the Microsoft Security Response Center (MSRC) bulletin the patch is - // related to. For example, MS14-045 . Applies to Windows patches only. - MsrcNumber *string - - // The severity of the patch, such as Critical , Important , or Moderate . Applies - // to Windows patches only. - MsrcSeverity *string - - // The name of the patch. Applies to Linux-based managed nodes only. - Name *string - - // The specific product the patch is applicable for. For example, WindowsServer2016 - // or AmazonLinux2018.03 . - Product *string - - // The product family the patch is applicable for. For example, Windows or Amazon - // Linux 2 . - ProductFamily *string - - // The particular release of a patch. For example, in - // pkg-example-EE-20180914-2.2.amzn1.noarch , the release is 2.amaz1 . Applies to - // Linux-based managed nodes only. - Release *string - - // The date the patch was released. - ReleaseDate *time.Time - - // The source patch repository for the operating system and version, such as - // trusty-security for Ubuntu Server 14.04 LTE and focal-security for Ubuntu - // Server 20.04 LTE. Applies to Linux-based managed nodes only. - Repository *string - - // The severity level of the patch. For example, CRITICAL or MODERATE . - Severity *string - - // The title of the patch. - Title *string - - // The name of the vendor providing the patch. - Vendor *string - - // The version number of the patch. For example, in - // example-pkg-1.710.10-2.7.abcd.x86_64 , the version number is indicated by -1 . - // Applies to Linux-based managed nodes only. - Version *string - - noSmithyDocumentSerde -} - -// Defines the basic information about a patch baseline. -type PatchBaselineIdentity struct { - - // The description of the patch baseline. - BaselineDescription *string - - // The ID of the patch baseline. - BaselineId *string - - // The name of the patch baseline. - BaselineName *string - - // Whether this is the default baseline. Amazon Web Services Systems Manager - // supports creating multiple default patch baselines. For example, you can create - // a default patch baseline for each operating system. - DefaultBaseline bool - - // Defines the operating system the patch baseline applies to. The default value - // is WINDOWS . - OperatingSystem OperatingSystem - - noSmithyDocumentSerde -} - -// Information about the state of a patch on a particular managed node as it -// relates to the patch baseline used to patch the node. -type PatchComplianceData struct { - - // The classification of the patch, such as SecurityUpdates , Updates , and - // CriticalUpdates . - // - // This member is required. - Classification *string - - // The date/time the patch was installed on the managed node. Not all operating - // systems provide this level of information. - // - // This member is required. - InstalledTime *time.Time - - // The operating system-specific ID of the patch. - // - // This member is required. - KBId *string - - // The severity of the patch such as Critical , Important , and Moderate . - // - // This member is required. - Severity *string - - // The state of the patch on the managed node, such as INSTALLED or FAILED. For - // descriptions of each patch state, see About patch compliance (https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-compliance-about.html#sysman-compliance-monitor-patch) - // in the Amazon Web Services Systems Manager User Guide. - // - // This member is required. - State PatchComplianceDataState - - // The title of the patch. - // - // This member is required. - Title *string - - // The IDs of one or more Common Vulnerabilities and Exposure (CVE) issues that - // are resolved by the patch. - CVEIds *string - - noSmithyDocumentSerde -} - -// Defines which patches should be included in a patch baseline. A patch filter -// consists of a key and a set of values. The filter key is a patch property. For -// example, the available filter keys for WINDOWS are PATCH_SET , PRODUCT , -// PRODUCT_FAMILY , CLASSIFICATION , and MSRC_SEVERITY . The filter values define a -// matching criterion for the patch property indicated by the key. For example, if -// the filter key is PRODUCT and the filter values are ["Office 2013", "Office -// 2016"] , then the filter accepts all patches where product name is either -// "Office 2013" or "Office 2016". The filter values can be exact values for the -// patch property given as a key, or a wildcard (*), which matches all values. You -// can view lists of valid values for the patch properties by running the -// DescribePatchProperties command. For information about which patch properties -// can be used with each major operating system, see DescribePatchProperties . -type PatchFilter struct { - - // The key for the filter. Run the DescribePatchProperties command to view lists - // of valid keys for each operating system type. - // - // This member is required. - Key PatchFilterKey - - // The value for the filter key. Run the DescribePatchProperties command to view - // lists of valid values for each key based on operating system type. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// A set of patch filters, typically used for approval rules. -type PatchFilterGroup struct { - - // The set of patch filters that make up the group. - // - // This member is required. - PatchFilters []PatchFilter - - noSmithyDocumentSerde -} - -// The mapping between a patch group and the patch baseline the patch group is -// registered with. -type PatchGroupPatchBaselineMapping struct { - - // The patch baseline the patch group is registered with. - BaselineIdentity *PatchBaselineIdentity - - // The name of the patch group registered with the patch baseline. - PatchGroup *string - - noSmithyDocumentSerde -} - -// Defines a filter used in Patch Manager APIs. Supported filter keys depend on -// the API operation that includes the filter. Patch Manager API operations that -// use PatchOrchestratorFilter include the following: -// - DescribeAvailablePatches -// - DescribeInstancePatches -// - DescribePatchBaselines -// - DescribePatchGroups -type PatchOrchestratorFilter struct { - - // The key for the filter. - Key *string - - // The value for the filter. - Values []string - - noSmithyDocumentSerde -} - -// Defines an approval rule for a patch baseline. -type PatchRule struct { - - // The patch filter group that defines the criteria for the rule. - // - // This member is required. - PatchFilterGroup *PatchFilterGroup - - // The number of days after the release date of each patch matched by the rule - // that the patch is marked as approved in the patch baseline. For example, a value - // of 7 means that patches are approved seven days after they are released. Not - // supported on Debian Server or Ubuntu Server. - ApproveAfterDays *int32 - - // The cutoff date for auto approval of released patches. Any patches released on - // or before this date are installed automatically. Not supported on Debian Server - // or Ubuntu Server. Enter dates in the format YYYY-MM-DD . For example, 2021-12-31 - // . - ApproveUntilDate *string - - // A compliance severity level for all approved patches in a patch baseline. - ComplianceLevel PatchComplianceLevel - - // For managed nodes identified by the approval rule filters, enables a patch - // baseline to apply non-security updates available in the specified repository. - // The default value is false . Applies to Linux managed nodes only. - EnableNonSecurity *bool - - noSmithyDocumentSerde -} - -// A set of rules defining the approval rules for a patch baseline. -type PatchRuleGroup struct { - - // The rules that make up the rule group. - // - // This member is required. - PatchRules []PatchRule - - noSmithyDocumentSerde -} - -// Information about the patches to use to update the managed nodes, including -// target operating systems and source repository. Applies to Linux managed nodes -// only. -type PatchSource struct { - - // The value of the yum repo configuration. For example: [main] - // name=MyCustomRepository - // - // baseurl=https://my-custom-repository - // enabled=1 For information about other options available for your yum repository - // configuration, see dnf.conf(5) (https://man7.org/linux/man-pages/man5/dnf.conf.5.html) - // . - // - // This member is required. - Configuration *string - - // The name specified to identify the patch source. - // - // This member is required. - Name *string - - // The specific operating system versions a patch repository applies to, such as - // "Ubuntu16.04", "AmazonLinux2016.09", "RedhatEnterpriseLinux7.2" or "Suse12.7". - // For lists of supported product values, see PatchFilter . - // - // This member is required. - Products []string - - noSmithyDocumentSerde -} - -// Information about the approval status of a patch. -type PatchStatus struct { - - // The date the patch was approved (or will be approved if the status is - // PENDING_APPROVAL ). - ApprovalDate *time.Time - - // The compliance severity level for a patch. - ComplianceLevel PatchComplianceLevel - - // The approval status of a patch. - DeploymentStatus PatchDeploymentStatus - - noSmithyDocumentSerde -} - -// An aggregate of step execution statuses displayed in the Amazon Web Services -// Systems Manager console for a multi-Region and multi-account Automation -// execution. -type ProgressCounters struct { - - // The total number of steps that the system cancelled in all specified Amazon Web - // Services Regions and Amazon Web Services accounts for the current Automation - // execution. - CancelledSteps int32 - - // The total number of steps that failed to run in all specified Amazon Web - // Services Regions and Amazon Web Services accounts for the current Automation - // execution. - FailedSteps int32 - - // The total number of steps that successfully completed in all specified Amazon - // Web Services Regions and Amazon Web Services accounts for the current Automation - // execution. - SuccessSteps int32 - - // The total number of steps that timed out in all specified Amazon Web Services - // Regions and Amazon Web Services accounts for the current Automation execution. - TimedOutSteps int32 - - // The total number of steps run in all specified Amazon Web Services Regions and - // Amazon Web Services accounts for the current Automation execution. - TotalSteps int32 - - noSmithyDocumentSerde -} - -// Reserved for internal use. -type RegistrationMetadataItem struct { - - // Reserved for internal use. - // - // This member is required. - Key *string - - // Reserved for internal use. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// An OpsItems that shares something in common with the current OpsItem. For -// example, related OpsItems can include OpsItems with similar error messages, -// impacted resources, or statuses for the impacted resource. -type RelatedOpsItem struct { - - // The ID of an OpsItem related to the current OpsItem. - // - // This member is required. - OpsItemId *string - - noSmithyDocumentSerde -} - -// Information about targets that resolved during the Automation execution. -type ResolvedTargets struct { - - // A list of parameter values sent to targets that resolved during the Automation - // execution. - ParameterValues []string - - // A boolean value indicating whether the resolved target list is truncated. - Truncated bool - - noSmithyDocumentSerde -} - -// Compliance summary information for a specific resource. -type ResourceComplianceSummaryItem struct { - - // The compliance type. - ComplianceType *string - - // A list of items that are compliant for the resource. - CompliantSummary *CompliantSummary - - // Information about the execution. - ExecutionSummary *ComplianceExecutionSummary - - // A list of items that aren't compliant for the resource. - NonCompliantSummary *NonCompliantSummary - - // The highest severity item found for the resource. The resource is compliant for - // this item. - OverallSeverity ComplianceSeverity - - // The resource ID. - ResourceId *string - - // The resource type. - ResourceType *string - - // The compliance status for the resource. - Status ComplianceStatus - - noSmithyDocumentSerde -} - -// Information about the AwsOrganizationsSource resource data sync source. A sync -// source of this type can synchronize data from Organizations or, if an Amazon Web -// Services organization isn't present, from multiple Amazon Web Services Regions. -type ResourceDataSyncAwsOrganizationsSource struct { - - // If an Amazon Web Services organization is present, this is either - // OrganizationalUnits or EntireOrganization . For OrganizationalUnits , the data - // is aggregated from a set of organization units. For EntireOrganization , the - // data is aggregated from the entire Amazon Web Services organization. - // - // This member is required. - OrganizationSourceType *string - - // The Organizations organization units included in the sync. - OrganizationalUnits []ResourceDataSyncOrganizationalUnit - - noSmithyDocumentSerde -} - -// Synchronize Amazon Web Services Systems Manager Inventory data from multiple -// Amazon Web Services accounts defined in Organizations to a centralized Amazon S3 -// bucket. Data is synchronized to individual key prefixes in the central bucket. -// Each key prefix represents a different Amazon Web Services account ID. -type ResourceDataSyncDestinationDataSharing struct { - - // The sharing data type. Only Organization is supported. - DestinationDataSharingType *string - - noSmithyDocumentSerde -} - -// Information about a resource data sync configuration, including its current -// status and last successful sync. -type ResourceDataSyncItem struct { - - // The status reported by the last sync. - LastStatus LastResourceDataSyncStatus - - // The last time the sync operations returned a status of SUCCESSFUL (UTC). - LastSuccessfulSyncTime *time.Time - - // The status message details reported by the last sync. - LastSyncStatusMessage *string - - // The last time the configuration attempted to sync (UTC). - LastSyncTime *time.Time - - // Configuration information for the target S3 bucket. - S3Destination *ResourceDataSyncS3Destination - - // The date and time the configuration was created (UTC). - SyncCreatedTime *time.Time - - // The date and time the resource data sync was changed. - SyncLastModifiedTime *time.Time - - // The name of the resource data sync. - SyncName *string - - // Information about the source where the data was synchronized. - SyncSource *ResourceDataSyncSourceWithState - - // The type of resource data sync. If SyncType is SyncToDestination , then the - // resource data sync synchronizes data to an S3 bucket. If the SyncType is - // SyncFromSource then the resource data sync synchronizes data from Organizations - // or from multiple Amazon Web Services Regions. - SyncType *string - - noSmithyDocumentSerde -} - -// The Organizations organizational unit data source for the sync. -type ResourceDataSyncOrganizationalUnit struct { - - // The Organizations unit ID data source for the sync. - OrganizationalUnitId *string - - noSmithyDocumentSerde -} - -// Information about the target S3 bucket for the resource data sync. -type ResourceDataSyncS3Destination struct { - - // The name of the S3 bucket where the aggregated data is stored. - // - // This member is required. - BucketName *string - - // The Amazon Web Services Region with the S3 bucket targeted by the resource data - // sync. - // - // This member is required. - Region *string - - // A supported sync format. The following format is currently supported: JsonSerDe - // - // This member is required. - SyncFormat ResourceDataSyncS3Format - - // The ARN of an encryption key for a destination in Amazon S3. Must belong to the - // same Region as the destination S3 bucket. - AWSKMSKeyARN *string - - // Enables destination data sharing. By default, this field is null . - DestinationDataSharing *ResourceDataSyncDestinationDataSharing - - // An Amazon S3 prefix for the bucket. - Prefix *string - - noSmithyDocumentSerde -} - -// Information about the source of the data included in the resource data sync. -type ResourceDataSyncSource struct { - - // The SyncSource Amazon Web Services Regions included in the resource data sync. - // - // This member is required. - SourceRegions []string - - // The type of data source for the resource data sync. SourceType is either - // AwsOrganizations (if an organization is present in Organizations) or - // SingleAccountMultiRegions . - // - // This member is required. - SourceType *string - - // Information about the AwsOrganizationsSource resource data sync source. A sync - // source of this type can synchronize data from Organizations. - AwsOrganizationsSource *ResourceDataSyncAwsOrganizationsSource - - // When you create a resource data sync, if you choose one of the Organizations - // options, then Systems Manager automatically enables all OpsData sources in the - // selected Amazon Web Services Regions for all Amazon Web Services accounts in - // your organization (or in the selected organization units). For more information, - // see About multiple account and Region resource data syncs (https://docs.aws.amazon.com/systems-manager/latest/userguide/Explorer-resouce-data-sync-multiple-accounts-and-regions.html) - // in the Amazon Web Services Systems Manager User Guide. - EnableAllOpsDataSources bool - - // Whether to automatically synchronize and aggregate data from new Amazon Web - // Services Regions when those Regions come online. - IncludeFutureRegions bool - - noSmithyDocumentSerde -} - -// The data type name for including resource data sync state. There are four sync -// states: OrganizationNotExists (Your organization doesn't exist) NoPermissions -// (The system can't locate the service-linked role. This role is automatically -// created when a user creates a resource data sync in Amazon Web Services Systems -// Manager Explorer.) InvalidOrganizationalUnit (You specified or selected an -// invalid unit in the resource data sync configuration.) TrustedAccessDisabled -// (You disabled Systems Manager access in the organization in Organizations.) -type ResourceDataSyncSourceWithState struct { - - // The field name in SyncSource for the ResourceDataSyncAwsOrganizationsSource - // type. - AwsOrganizationsSource *ResourceDataSyncAwsOrganizationsSource - - // When you create a resource data sync, if you choose one of the Organizations - // options, then Systems Manager automatically enables all OpsData sources in the - // selected Amazon Web Services Regions for all Amazon Web Services accounts in - // your organization (or in the selected organization units). For more information, - // see About multiple account and Region resource data syncs (https://docs.aws.amazon.com/systems-manager/latest/userguide/Explorer-resouce-data-sync-multiple-accounts-and-regions.html) - // in the Amazon Web Services Systems Manager User Guide. - EnableAllOpsDataSources bool - - // Whether to automatically synchronize and aggregate data from new Amazon Web - // Services Regions when those Regions come online. - IncludeFutureRegions bool - - // The SyncSource Amazon Web Services Regions included in the resource data sync. - SourceRegions []string - - // The type of data source for the resource data sync. SourceType is either - // AwsOrganizations (if an organization is present in Organizations) or - // singleAccountMultiRegions . - SourceType *string - - // The data type name for including resource data sync state. There are four sync - // states: OrganizationNotExists : Your organization doesn't exist. NoPermissions : - // The system can't locate the service-linked role. This role is automatically - // created when a user creates a resource data sync in Explorer. - // InvalidOrganizationalUnit : You specified or selected an invalid unit in the - // resource data sync configuration. TrustedAccessDisabled : You disabled Systems - // Manager access in the organization in Organizations. - State *string - - noSmithyDocumentSerde -} - -// The inventory item result attribute. -type ResultAttribute struct { - - // Name of the inventory item type. Valid value: AWS:InstanceInformation . Default - // Value: AWS:InstanceInformation . - // - // This member is required. - TypeName *string - - noSmithyDocumentSerde -} - -// Information about the result of a document review request. -type ReviewInformation struct { - - // The time that the reviewer took action on the document review request. - ReviewedTime *time.Time - - // The reviewer assigned to take action on the document review request. - Reviewer *string - - // The current status of the document review request. - Status ReviewStatus - - noSmithyDocumentSerde -} - -// Information about an Automation runbook used in a runbook workflow in Change -// Manager. The Automation runbooks specified for the runbook workflow can't run -// until all required approvals for the change request have been received. -type Runbook struct { - - // The name of the Automation runbook used in a runbook workflow. - // - // This member is required. - DocumentName *string - - // The version of the Automation runbook used in a runbook workflow. - DocumentVersion *string - - // The MaxConcurrency value specified by the user when the operation started, - // indicating the maximum number of resources that the runbook operation can run on - // at the same time. - MaxConcurrency *string - - // The MaxErrors value specified by the user when the execution started, - // indicating the maximum number of errors that can occur during the operation - // before the updates are stopped or rolled back. - MaxErrors *string - - // The key-value map of execution parameters, which were supplied when calling - // StartChangeRequestExecution . - Parameters map[string][]string - - // Information about the Amazon Web Services Regions and Amazon Web Services - // accounts targeted by the current Runbook operation. - TargetLocations []TargetLocation - - // A key-value mapping of runbook parameters to target resources. Both Targets and - // TargetMaps can't be specified together. - TargetMaps []map[string][]string - - // The name of the parameter used as the target resource for the rate-controlled - // runbook workflow. Required if you specify Targets . - TargetParameterName *string - - // A key-value mapping to target resources that the runbook operation performs - // tasks on. Required if you specify TargetParameterName . - Targets []Target - - noSmithyDocumentSerde -} - -// An S3 bucket where you want to store the results of this request. -type S3OutputLocation struct { - - // The name of the S3 bucket. - OutputS3BucketName *string - - // The S3 bucket subfolder. - OutputS3KeyPrefix *string - - // The Amazon Web Services Region of the S3 bucket. - OutputS3Region *string - - noSmithyDocumentSerde -} - -// A URL for the Amazon Web Services Systems Manager (Systems Manager) bucket -// where you want to store the results of this request. -type S3OutputUrl struct { - - // A URL for an S3 bucket where you want to store the results of this request. - OutputUrl *string - - noSmithyDocumentSerde -} - -// Information about a scheduled execution for a maintenance window. -type ScheduledWindowExecution struct { - - // The time, in ISO-8601 Extended format, that the maintenance window is scheduled - // to be run. - ExecutionTime *string - - // The name of the maintenance window to be run. - Name *string - - // The ID of the maintenance window to be run. - WindowId *string - - noSmithyDocumentSerde -} - -// The service setting data structure. ServiceSetting is an account-level setting -// for an Amazon Web Services service. This setting defines how a user interacts -// with or uses a service or a feature of a service. For example, if an Amazon Web -// Services service charges money to the account based on feature or service usage, -// then the Amazon Web Services service team might create a default setting of -// "false". This means the user can't use this feature unless they change the -// setting to "true" and intentionally opt in for a paid feature. Services map a -// SettingId object to a setting value. Amazon Web Services services teams define -// the default value for a SettingId . You can't create a new SettingId , but you -// can overwrite the default value if you have the ssm:UpdateServiceSetting -// permission for the setting. Use the UpdateServiceSetting API operation to -// change the default setting. Or, use the ResetServiceSetting to change the value -// back to the original value defined by the Amazon Web Services service team. -type ServiceSetting struct { - - // The ARN of the service setting. - ARN *string - - // The last time the service setting was modified. - LastModifiedDate *time.Time - - // The ARN of the last modified user. This field is populated only if the setting - // value was overwritten. - LastModifiedUser *string - - // The ID of the service setting. - SettingId *string - - // The value of the service setting. - SettingValue *string - - // The status of the service setting. The value can be Default, Customized or - // PendingUpdate. - // - Default: The current setting uses a default value provisioned by the Amazon - // Web Services service team. - // - Customized: The current setting use a custom value specified by the - // customer. - // - PendingUpdate: The current setting uses a default or custom value, but a - // setting change request is pending approval. - Status *string - - noSmithyDocumentSerde -} - -// Information about a Session Manager connection to a managed node. -type Session struct { - - // Reserved for future use. - Details *string - - // The name of the Session Manager SSM document used to define the parameters and - // plugin settings for the session. For example, SSM-SessionManagerRunShell . - DocumentName *string - - // The date and time, in ISO-8601 Extended format, when the session was terminated. - EndDate *time.Time - - // The maximum duration of a session before it terminates. - MaxSessionDuration *string - - // Reserved for future use. - OutputUrl *SessionManagerOutputUrl - - // The ID of the Amazon Web Services user that started the session. - Owner *string - - // The reason for connecting to the instance. - Reason *string - - // The ID of the session. - SessionId *string - - // The date and time, in ISO-8601 Extended format, when the session began. - StartDate *time.Time - - // The status of the session. For example, "Connected" or "Terminated". - Status SessionStatus - - // The managed node that the Session Manager session connected to. - Target *string - - noSmithyDocumentSerde -} - -// Describes a filter for Session Manager information. -type SessionFilter struct { - - // The name of the filter. - // - // This member is required. - Key SessionFilterKey - - // The filter value. Valid values for each filter key are as follows: - // - InvokedAfter: Specify a timestamp to limit your results. For example, - // specify 2018-08-29T00:00:00Z to see sessions that started August 29, 2018, and - // later. - // - InvokedBefore: Specify a timestamp to limit your results. For example, - // specify 2018-08-29T00:00:00Z to see sessions that started before August 29, - // 2018. - // - Target: Specify a managed node to which session connections have been made. - // - Owner: Specify an Amazon Web Services user to see a list of sessions - // started by that user. - // - Status: Specify a valid session status to see a list of all sessions with - // that status. Status values you can specify include: - // - Connected - // - Connecting - // - Disconnected - // - Terminated - // - Terminating - // - Failed - // - SessionId: Specify a session ID to return details about the session. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Reserved for future use. -type SessionManagerOutputUrl struct { - - // Reserved for future use. - CloudWatchOutputUrl *string - - // Reserved for future use. - S3OutputUrl *string - - noSmithyDocumentSerde -} - -// The number of managed nodes found for each patch severity level defined in the -// request filter. -type SeveritySummary struct { - - // The total number of resources or compliance items that have a severity level of - // Critical . Critical severity is determined by the organization that published - // the compliance items. - CriticalCount int32 - - // The total number of resources or compliance items that have a severity level of - // high. High severity is determined by the organization that published the - // compliance items. - HighCount int32 - - // The total number of resources or compliance items that have a severity level of - // informational. Informational severity is determined by the organization that - // published the compliance items. - InformationalCount int32 - - // The total number of resources or compliance items that have a severity level of - // low. Low severity is determined by the organization that published the - // compliance items. - LowCount int32 - - // The total number of resources or compliance items that have a severity level of - // medium. Medium severity is determined by the organization that published the - // compliance items. - MediumCount int32 - - // The total number of resources or compliance items that have a severity level of - // unspecified. Unspecified severity is determined by the organization that - // published the compliance items. - UnspecifiedCount int32 - - noSmithyDocumentSerde -} - -// Detailed information about an the execution state of an Automation step. -type StepExecution struct { - - // The action this step performs. The action determines the behavior of the step. - Action *string - - // If a step has finished execution, this contains the time the execution ended. - // If the step hasn't yet concluded, this field isn't populated. - ExecutionEndTime *time.Time - - // If a step has begun execution, this contains the time the step started. If the - // step is in Pending status, this field isn't populated. - ExecutionStartTime *time.Time - - // Information about the Automation failure. - FailureDetails *FailureDetails - - // If a step failed, this message explains why the execution failed. - FailureMessage *string - - // Fully-resolved values passed into the step before execution. - Inputs map[string]string - - // The flag which can be used to help decide whether the failure of current step - // leads to the Automation failure. - IsCritical *bool - - // The flag which can be used to end automation no matter whether the step - // succeeds or fails. - IsEnd *bool - - // The maximum number of tries to run the action of the step. The default value is - // 1 . - MaxAttempts *int32 - - // The next step after the step succeeds. - NextStep *string - - // The action to take if the step fails. The default value is Abort . - OnFailure *string - - // Returned values from the execution of the step. - Outputs map[string][]string - - // A user-specified list of parameters to override when running a step. - OverriddenParameters map[string][]string - - // Information about the parent step. - ParentStepDetails *ParentStepDetails - - // A message associated with the response code for an execution. - Response *string - - // The response code returned by the execution of the step. - ResponseCode *string - - // The unique ID of a step execution. - StepExecutionId *string - - // The name of this execution step. - StepName *string - - // The execution status for this step. - StepStatus AutomationExecutionStatus - - // The combination of Amazon Web Services Regions and Amazon Web Services accounts - // targeted by the current Automation execution. - TargetLocation *TargetLocation - - // The targets for the step execution. - Targets []Target - - // The timeout seconds of the step. - TimeoutSeconds *int64 - - // The CloudWatch alarms that were invoked by the automation. - TriggeredAlarms []AlarmStateInformation - - // Strategies used when step fails, we support Continue and Abort. Abort will fail - // the automation when the step fails. Continue will ignore the failure of current - // step and allow automation to run the next step. With conditional branching, we - // add step:stepName to support the automation to go to another specific step. - ValidNextSteps []string - - noSmithyDocumentSerde -} - -// A filter to limit the amount of step execution information returned by the call. -type StepExecutionFilter struct { - - // One or more keys to limit the results. - // - // This member is required. - Key StepExecutionFilterKey - - // The values of the filter key. - // - // This member is required. - Values []string - - noSmithyDocumentSerde -} - -// Metadata that you assign to your Amazon Web Services resources. Tags enable you -// to categorize your resources in different ways, for example, by purpose, owner, -// or environment. In Amazon Web Services Systems Manager, you can apply tags to -// Systems Manager documents (SSM documents), managed nodes, maintenance windows, -// parameters, patch baselines, OpsItems, and OpsMetadata. -type Tag struct { - - // The name of the tag. - // - // This member is required. - Key *string - - // The value of the tag. - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// An array of search criteria that targets managed nodes using a key-value pair -// that you specify. One or more targets must be specified for maintenance window -// Run Command-type tasks. Depending on the task, targets are optional for other -// maintenance window task types (Automation, Lambda, and Step Functions). For more -// information about running tasks that don't specify targets, see Registering -// maintenance window tasks without targets (https://docs.aws.amazon.com/systems-manager/latest/userguide/maintenance-windows-targetless-tasks.html) -// in the Amazon Web Services Systems Manager User Guide. Supported formats include -// the following. -// - Key=InstanceIds,Values=,, -// - Key=tag:,Values=, -// - Key=tag-key,Values=, -// - Run Command and Maintenance window targets only: -// Key=resource-groups:Name,Values= -// - Maintenance window targets only: -// Key=resource-groups:ResourceTypeFilters,Values=, -// - Automation targets only: Key=ResourceGroup;Values= -// -// For example: -// -// - -// Key=InstanceIds,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE,i-07782c72faEXAMPLE -// - Key=tag:CostCenter,Values=CostCenter1,CostCenter2,CostCenter3 -// - Key=tag-key,Values=Name,Instance-Type,CostCenter -// - Run Command and Maintenance window targets only: -// Key=resource-groups:Name,Values=ProductionResourceGroup This example -// demonstrates how to target all resources in the resource group -// ProductionResourceGroup in your maintenance window. -// - Maintenance window targets only: -// Key=resource-groups:ResourceTypeFilters,Values=AWS::EC2::INSTANCE,AWS::EC2::VPC -// This example demonstrates how to target only Amazon Elastic Compute Cloud -// (Amazon EC2) instances and VPCs in your maintenance window. -// - Automation targets only: Key=ResourceGroup,Values=MyResourceGroup -// - State Manager association targets only: Key=InstanceIds,Values=* This -// example demonstrates how to target all managed instances in the Amazon Web -// Services Region where the association was created. -// -// For more information about how to send commands that target managed nodes using -// Key,Value parameters, see Targeting multiple instances (https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-multiple.html#send-commands-targeting) -// in the Amazon Web Services Systems Manager User Guide. -type Target struct { - - // User-defined criteria for sending commands that target managed nodes that meet - // the criteria. - Key *string - - // User-defined criteria that maps to Key . For example, if you specified - // tag:ServerRole , you could specify value:WebServer to run a command on - // instances that include EC2 tags of ServerRole,WebServer . Depending on the type - // of target, the maximum number of values for a key might be lower than the global - // maximum of 50. - Values []string - - noSmithyDocumentSerde -} - -// The combination of Amazon Web Services Regions and Amazon Web Services accounts -// targeted by the current Automation execution. -type TargetLocation struct { - - // The Amazon Web Services accounts targeted by the current Automation execution. - Accounts []string - - // The Automation execution role used by the currently running Automation. If not - // specified, the default value is AWS-SystemsManager-AutomationExecutionRole . - ExecutionRoleName *string - - // The Amazon Web Services Regions targeted by the current Automation execution. - Regions []string - - // The details for the CloudWatch alarm you want to apply to an automation or - // command. - TargetLocationAlarmConfiguration *AlarmConfiguration - - // The maximum number of Amazon Web Services Regions and Amazon Web Services - // accounts allowed to run the Automation concurrently. - TargetLocationMaxConcurrency *string - - // The maximum number of errors allowed before the system stops queueing - // additional Automation executions for the currently running Automation. - TargetLocationMaxErrors *string - - noSmithyDocumentSerde -} - -type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/validators.go deleted file mode 100644 index 37cb33a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssm/validators.go +++ /dev/null @@ -1,6858 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssm - -import ( - "context" - "fmt" - "github.com/aws/aws-sdk-go-v2/service/ssm/types" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" -) - -type validateOpAddTagsToResource struct { -} - -func (*validateOpAddTagsToResource) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAddTagsToResource) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AddTagsToResourceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAddTagsToResourceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpAssociateOpsItemRelatedItem struct { -} - -func (*validateOpAssociateOpsItemRelatedItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAssociateOpsItemRelatedItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AssociateOpsItemRelatedItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAssociateOpsItemRelatedItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCancelCommand struct { -} - -func (*validateOpCancelCommand) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCancelCommand) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CancelCommandInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCancelCommandInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCancelMaintenanceWindowExecution struct { -} - -func (*validateOpCancelMaintenanceWindowExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCancelMaintenanceWindowExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CancelMaintenanceWindowExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCancelMaintenanceWindowExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateActivation struct { -} - -func (*validateOpCreateActivation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateActivation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateActivationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateActivationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateAssociationBatch struct { -} - -func (*validateOpCreateAssociationBatch) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateAssociationBatch) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateAssociationBatchInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateAssociationBatchInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateAssociation struct { -} - -func (*validateOpCreateAssociation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateAssociation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateAssociationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateAssociationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateDocument struct { -} - -func (*validateOpCreateDocument) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateDocument) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateDocumentInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateDocumentInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateMaintenanceWindow struct { -} - -func (*validateOpCreateMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateOpsItem struct { -} - -func (*validateOpCreateOpsItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateOpsItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateOpsItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateOpsItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateOpsMetadata struct { -} - -func (*validateOpCreateOpsMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateOpsMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateOpsMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateOpsMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreatePatchBaseline struct { -} - -func (*validateOpCreatePatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreatePatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreatePatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreatePatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateResourceDataSync struct { -} - -func (*validateOpCreateResourceDataSync) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateResourceDataSync) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateResourceDataSyncInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateResourceDataSyncInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteActivation struct { -} - -func (*validateOpDeleteActivation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteActivation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteActivationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteActivationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteDocument struct { -} - -func (*validateOpDeleteDocument) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteDocument) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteDocumentInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteDocumentInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteInventory struct { -} - -func (*validateOpDeleteInventory) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteInventory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteInventoryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteInventoryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteMaintenanceWindow struct { -} - -func (*validateOpDeleteMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteOpsItem struct { -} - -func (*validateOpDeleteOpsItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteOpsItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteOpsItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteOpsItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteOpsMetadata struct { -} - -func (*validateOpDeleteOpsMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteOpsMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteOpsMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteOpsMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteParameter struct { -} - -func (*validateOpDeleteParameter) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteParameter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteParameterInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteParameterInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteParameters struct { -} - -func (*validateOpDeleteParameters) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteParameters) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteParametersInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteParametersInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeletePatchBaseline struct { -} - -func (*validateOpDeletePatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeletePatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeletePatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeletePatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteResourceDataSync struct { -} - -func (*validateOpDeleteResourceDataSync) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteResourceDataSync) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteResourceDataSyncInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteResourceDataSyncInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeleteResourcePolicy struct { -} - -func (*validateOpDeleteResourcePolicy) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeleteResourcePolicy) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeleteResourcePolicyInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeleteResourcePolicyInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeregisterManagedInstance struct { -} - -func (*validateOpDeregisterManagedInstance) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeregisterManagedInstance) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeregisterManagedInstanceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeregisterManagedInstanceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeregisterPatchBaselineForPatchGroup struct { -} - -func (*validateOpDeregisterPatchBaselineForPatchGroup) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeregisterPatchBaselineForPatchGroup) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeregisterPatchBaselineForPatchGroupInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeregisterPatchBaselineForPatchGroupInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeregisterTargetFromMaintenanceWindow struct { -} - -func (*validateOpDeregisterTargetFromMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeregisterTargetFromMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeregisterTargetFromMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeregisterTargetFromMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDeregisterTaskFromMaintenanceWindow struct { -} - -func (*validateOpDeregisterTaskFromMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDeregisterTaskFromMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DeregisterTaskFromMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDeregisterTaskFromMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeAssociationExecutions struct { -} - -func (*validateOpDescribeAssociationExecutions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeAssociationExecutions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeAssociationExecutionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeAssociationExecutionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeAssociationExecutionTargets struct { -} - -func (*validateOpDescribeAssociationExecutionTargets) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeAssociationExecutionTargets) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeAssociationExecutionTargetsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeAssociationExecutionTargetsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeAutomationExecutions struct { -} - -func (*validateOpDescribeAutomationExecutions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeAutomationExecutions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeAutomationExecutionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeAutomationExecutionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeAutomationStepExecutions struct { -} - -func (*validateOpDescribeAutomationStepExecutions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeAutomationStepExecutions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeAutomationStepExecutionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeAutomationStepExecutionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeDocument struct { -} - -func (*validateOpDescribeDocument) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeDocument) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeDocumentInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeDocumentInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeDocumentPermission struct { -} - -func (*validateOpDescribeDocumentPermission) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeDocumentPermission) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeDocumentPermissionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeDocumentPermissionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeEffectiveInstanceAssociations struct { -} - -func (*validateOpDescribeEffectiveInstanceAssociations) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeEffectiveInstanceAssociations) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeEffectiveInstanceAssociationsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeEffectiveInstanceAssociationsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeEffectivePatchesForPatchBaseline struct { -} - -func (*validateOpDescribeEffectivePatchesForPatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeEffectivePatchesForPatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeEffectivePatchesForPatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeEffectivePatchesForPatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeInstanceAssociationsStatus struct { -} - -func (*validateOpDescribeInstanceAssociationsStatus) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeInstanceAssociationsStatus) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeInstanceAssociationsStatusInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeInstanceAssociationsStatusInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeInstanceInformation struct { -} - -func (*validateOpDescribeInstanceInformation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeInstanceInformation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeInstanceInformationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeInstanceInformationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeInstancePatches struct { -} - -func (*validateOpDescribeInstancePatches) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeInstancePatches) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeInstancePatchesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeInstancePatchesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeInstancePatchStatesForPatchGroup struct { -} - -func (*validateOpDescribeInstancePatchStatesForPatchGroup) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeInstancePatchStatesForPatchGroup) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeInstancePatchStatesForPatchGroupInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeInstancePatchStatesForPatchGroupInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeInstancePatchStates struct { -} - -func (*validateOpDescribeInstancePatchStates) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeInstancePatchStates) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeInstancePatchStatesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeInstancePatchStatesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowExecutions struct { -} - -func (*validateOpDescribeMaintenanceWindowExecutions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowExecutions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowExecutionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowExecutionTaskInvocations struct { -} - -func (*validateOpDescribeMaintenanceWindowExecutionTaskInvocations) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowExecutionTaskInvocations) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionTaskInvocationsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowExecutionTaskInvocationsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowExecutionTasks struct { -} - -func (*validateOpDescribeMaintenanceWindowExecutionTasks) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowExecutionTasks) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowExecutionTasksInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowExecutionTasksInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowsForTarget struct { -} - -func (*validateOpDescribeMaintenanceWindowsForTarget) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowsForTarget) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowsForTargetInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowsForTargetInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowTargets struct { -} - -func (*validateOpDescribeMaintenanceWindowTargets) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowTargets) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowTargetsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowTargetsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeMaintenanceWindowTasks struct { -} - -func (*validateOpDescribeMaintenanceWindowTasks) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeMaintenanceWindowTasks) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeMaintenanceWindowTasksInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeMaintenanceWindowTasksInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeOpsItems struct { -} - -func (*validateOpDescribeOpsItems) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeOpsItems) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeOpsItemsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeOpsItemsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeParameters struct { -} - -func (*validateOpDescribeParameters) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeParameters) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeParametersInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeParametersInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribePatchGroupState struct { -} - -func (*validateOpDescribePatchGroupState) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribePatchGroupState) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribePatchGroupStateInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribePatchGroupStateInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribePatchProperties struct { -} - -func (*validateOpDescribePatchProperties) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribePatchProperties) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribePatchPropertiesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribePatchPropertiesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDescribeSessions struct { -} - -func (*validateOpDescribeSessions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDescribeSessions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DescribeSessionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDescribeSessionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDisassociateOpsItemRelatedItem struct { -} - -func (*validateOpDisassociateOpsItemRelatedItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDisassociateOpsItemRelatedItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DisassociateOpsItemRelatedItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDisassociateOpsItemRelatedItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetAutomationExecution struct { -} - -func (*validateOpGetAutomationExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetAutomationExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetAutomationExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetAutomationExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetCalendarState struct { -} - -func (*validateOpGetCalendarState) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetCalendarState) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetCalendarStateInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetCalendarStateInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetCommandInvocation struct { -} - -func (*validateOpGetCommandInvocation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetCommandInvocation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetCommandInvocationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetCommandInvocationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetConnectionStatus struct { -} - -func (*validateOpGetConnectionStatus) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetConnectionStatus) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetConnectionStatusInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetConnectionStatusInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetDeployablePatchSnapshotForInstance struct { -} - -func (*validateOpGetDeployablePatchSnapshotForInstance) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetDeployablePatchSnapshotForInstance) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetDeployablePatchSnapshotForInstanceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetDeployablePatchSnapshotForInstanceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetDocument struct { -} - -func (*validateOpGetDocument) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetDocument) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetDocumentInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetDocumentInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetInventory struct { -} - -func (*validateOpGetInventory) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetInventory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetInventoryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetInventoryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetMaintenanceWindowExecution struct { -} - -func (*validateOpGetMaintenanceWindowExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetMaintenanceWindowExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetMaintenanceWindowExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetMaintenanceWindowExecutionTask struct { -} - -func (*validateOpGetMaintenanceWindowExecutionTask) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetMaintenanceWindowExecutionTask) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionTaskInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetMaintenanceWindowExecutionTaskInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetMaintenanceWindowExecutionTaskInvocation struct { -} - -func (*validateOpGetMaintenanceWindowExecutionTaskInvocation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetMaintenanceWindowExecutionTaskInvocation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetMaintenanceWindowExecutionTaskInvocationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetMaintenanceWindowExecutionTaskInvocationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetMaintenanceWindow struct { -} - -func (*validateOpGetMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetMaintenanceWindowTask struct { -} - -func (*validateOpGetMaintenanceWindowTask) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetMaintenanceWindowTask) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetMaintenanceWindowTaskInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetMaintenanceWindowTaskInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetOpsItem struct { -} - -func (*validateOpGetOpsItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetOpsItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetOpsItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetOpsItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetOpsMetadata struct { -} - -func (*validateOpGetOpsMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetOpsMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetOpsMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetOpsMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetOpsSummary struct { -} - -func (*validateOpGetOpsSummary) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetOpsSummary) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetOpsSummaryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetOpsSummaryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetParameterHistory struct { -} - -func (*validateOpGetParameterHistory) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetParameterHistory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetParameterHistoryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetParameterHistoryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetParameter struct { -} - -func (*validateOpGetParameter) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetParameter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetParameterInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetParameterInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetParametersByPath struct { -} - -func (*validateOpGetParametersByPath) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetParametersByPath) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetParametersByPathInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetParametersByPathInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetParameters struct { -} - -func (*validateOpGetParameters) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetParameters) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetParametersInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetParametersInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetPatchBaselineForPatchGroup struct { -} - -func (*validateOpGetPatchBaselineForPatchGroup) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetPatchBaselineForPatchGroup) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetPatchBaselineForPatchGroupInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetPatchBaselineForPatchGroupInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetPatchBaseline struct { -} - -func (*validateOpGetPatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetPatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetPatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetPatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetResourcePolicies struct { -} - -func (*validateOpGetResourcePolicies) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetResourcePolicies) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetResourcePoliciesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetResourcePoliciesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetServiceSetting struct { -} - -func (*validateOpGetServiceSetting) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetServiceSetting) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetServiceSettingInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetServiceSettingInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpLabelParameterVersion struct { -} - -func (*validateOpLabelParameterVersion) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpLabelParameterVersion) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*LabelParameterVersionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpLabelParameterVersionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListAssociations struct { -} - -func (*validateOpListAssociations) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListAssociations) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListAssociationsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListAssociationsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListAssociationVersions struct { -} - -func (*validateOpListAssociationVersions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListAssociationVersions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListAssociationVersionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListAssociationVersionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListCommandInvocations struct { -} - -func (*validateOpListCommandInvocations) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListCommandInvocations) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListCommandInvocationsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListCommandInvocationsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListCommands struct { -} - -func (*validateOpListCommands) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListCommands) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListCommandsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListCommandsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListDocumentMetadataHistory struct { -} - -func (*validateOpListDocumentMetadataHistory) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListDocumentMetadataHistory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListDocumentMetadataHistoryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListDocumentMetadataHistoryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListDocuments struct { -} - -func (*validateOpListDocuments) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListDocuments) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListDocumentsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListDocumentsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListDocumentVersions struct { -} - -func (*validateOpListDocumentVersions) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListDocumentVersions) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListDocumentVersionsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListDocumentVersionsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListInventoryEntries struct { -} - -func (*validateOpListInventoryEntries) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListInventoryEntries) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListInventoryEntriesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListInventoryEntriesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListOpsItemEvents struct { -} - -func (*validateOpListOpsItemEvents) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListOpsItemEvents) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListOpsItemEventsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListOpsItemEventsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListOpsItemRelatedItems struct { -} - -func (*validateOpListOpsItemRelatedItems) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListOpsItemRelatedItems) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListOpsItemRelatedItemsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListOpsItemRelatedItemsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListOpsMetadata struct { -} - -func (*validateOpListOpsMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListOpsMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListOpsMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListOpsMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListTagsForResource struct { -} - -func (*validateOpListTagsForResource) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListTagsForResource) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListTagsForResourceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListTagsForResourceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpModifyDocumentPermission struct { -} - -func (*validateOpModifyDocumentPermission) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpModifyDocumentPermission) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ModifyDocumentPermissionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpModifyDocumentPermissionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpPutComplianceItems struct { -} - -func (*validateOpPutComplianceItems) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpPutComplianceItems) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*PutComplianceItemsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpPutComplianceItemsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpPutInventory struct { -} - -func (*validateOpPutInventory) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpPutInventory) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*PutInventoryInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpPutInventoryInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpPutParameter struct { -} - -func (*validateOpPutParameter) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpPutParameter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*PutParameterInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpPutParameterInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpPutResourcePolicy struct { -} - -func (*validateOpPutResourcePolicy) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpPutResourcePolicy) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*PutResourcePolicyInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpPutResourcePolicyInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRegisterDefaultPatchBaseline struct { -} - -func (*validateOpRegisterDefaultPatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRegisterDefaultPatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RegisterDefaultPatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRegisterDefaultPatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRegisterPatchBaselineForPatchGroup struct { -} - -func (*validateOpRegisterPatchBaselineForPatchGroup) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRegisterPatchBaselineForPatchGroup) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RegisterPatchBaselineForPatchGroupInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRegisterPatchBaselineForPatchGroupInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRegisterTargetWithMaintenanceWindow struct { -} - -func (*validateOpRegisterTargetWithMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRegisterTargetWithMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RegisterTargetWithMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRegisterTargetWithMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRegisterTaskWithMaintenanceWindow struct { -} - -func (*validateOpRegisterTaskWithMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRegisterTaskWithMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RegisterTaskWithMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRegisterTaskWithMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRemoveTagsFromResource struct { -} - -func (*validateOpRemoveTagsFromResource) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRemoveTagsFromResource) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RemoveTagsFromResourceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRemoveTagsFromResourceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpResetServiceSetting struct { -} - -func (*validateOpResetServiceSetting) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpResetServiceSetting) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ResetServiceSettingInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpResetServiceSettingInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpResumeSession struct { -} - -func (*validateOpResumeSession) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpResumeSession) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ResumeSessionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpResumeSessionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpSendAutomationSignal struct { -} - -func (*validateOpSendAutomationSignal) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpSendAutomationSignal) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*SendAutomationSignalInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpSendAutomationSignalInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpSendCommand struct { -} - -func (*validateOpSendCommand) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpSendCommand) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*SendCommandInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpSendCommandInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStartAssociationsOnce struct { -} - -func (*validateOpStartAssociationsOnce) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStartAssociationsOnce) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StartAssociationsOnceInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStartAssociationsOnceInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStartAutomationExecution struct { -} - -func (*validateOpStartAutomationExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStartAutomationExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StartAutomationExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStartAutomationExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStartChangeRequestExecution struct { -} - -func (*validateOpStartChangeRequestExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStartChangeRequestExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StartChangeRequestExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStartChangeRequestExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStartSession struct { -} - -func (*validateOpStartSession) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStartSession) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StartSessionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStartSessionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStopAutomationExecution struct { -} - -func (*validateOpStopAutomationExecution) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStopAutomationExecution) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StopAutomationExecutionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStopAutomationExecutionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpTerminateSession struct { -} - -func (*validateOpTerminateSession) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpTerminateSession) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*TerminateSessionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpTerminateSessionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUnlabelParameterVersion struct { -} - -func (*validateOpUnlabelParameterVersion) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUnlabelParameterVersion) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UnlabelParameterVersionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUnlabelParameterVersionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateAssociation struct { -} - -func (*validateOpUpdateAssociation) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateAssociation) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateAssociationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateAssociationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateAssociationStatus struct { -} - -func (*validateOpUpdateAssociationStatus) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateAssociationStatus) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateAssociationStatusInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateAssociationStatusInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateDocumentDefaultVersion struct { -} - -func (*validateOpUpdateDocumentDefaultVersion) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateDocumentDefaultVersion) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateDocumentDefaultVersionInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateDocumentDefaultVersionInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateDocument struct { -} - -func (*validateOpUpdateDocument) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateDocument) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateDocumentInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateDocumentInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateDocumentMetadata struct { -} - -func (*validateOpUpdateDocumentMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateDocumentMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateDocumentMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateDocumentMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateMaintenanceWindow struct { -} - -func (*validateOpUpdateMaintenanceWindow) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateMaintenanceWindow) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateMaintenanceWindowInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateMaintenanceWindowInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateMaintenanceWindowTarget struct { -} - -func (*validateOpUpdateMaintenanceWindowTarget) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateMaintenanceWindowTarget) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateMaintenanceWindowTargetInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateMaintenanceWindowTargetInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateMaintenanceWindowTask struct { -} - -func (*validateOpUpdateMaintenanceWindowTask) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateMaintenanceWindowTask) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateMaintenanceWindowTaskInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateMaintenanceWindowTaskInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateManagedInstanceRole struct { -} - -func (*validateOpUpdateManagedInstanceRole) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateManagedInstanceRole) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateManagedInstanceRoleInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateManagedInstanceRoleInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateOpsItem struct { -} - -func (*validateOpUpdateOpsItem) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateOpsItem) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateOpsItemInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateOpsItemInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateOpsMetadata struct { -} - -func (*validateOpUpdateOpsMetadata) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateOpsMetadata) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateOpsMetadataInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateOpsMetadataInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdatePatchBaseline struct { -} - -func (*validateOpUpdatePatchBaseline) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdatePatchBaseline) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdatePatchBaselineInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdatePatchBaselineInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateResourceDataSync struct { -} - -func (*validateOpUpdateResourceDataSync) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateResourceDataSync) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateResourceDataSyncInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateResourceDataSyncInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpUpdateServiceSetting struct { -} - -func (*validateOpUpdateServiceSetting) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpUpdateServiceSetting) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*UpdateServiceSettingInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpUpdateServiceSettingInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -func addOpAddTagsToResourceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAddTagsToResource{}, middleware.After) -} - -func addOpAssociateOpsItemRelatedItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAssociateOpsItemRelatedItem{}, middleware.After) -} - -func addOpCancelCommandValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCancelCommand{}, middleware.After) -} - -func addOpCancelMaintenanceWindowExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCancelMaintenanceWindowExecution{}, middleware.After) -} - -func addOpCreateActivationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateActivation{}, middleware.After) -} - -func addOpCreateAssociationBatchValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateAssociationBatch{}, middleware.After) -} - -func addOpCreateAssociationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateAssociation{}, middleware.After) -} - -func addOpCreateDocumentValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateDocument{}, middleware.After) -} - -func addOpCreateMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateMaintenanceWindow{}, middleware.After) -} - -func addOpCreateOpsItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateOpsItem{}, middleware.After) -} - -func addOpCreateOpsMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateOpsMetadata{}, middleware.After) -} - -func addOpCreatePatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreatePatchBaseline{}, middleware.After) -} - -func addOpCreateResourceDataSyncValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateResourceDataSync{}, middleware.After) -} - -func addOpDeleteActivationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteActivation{}, middleware.After) -} - -func addOpDeleteDocumentValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteDocument{}, middleware.After) -} - -func addOpDeleteInventoryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteInventory{}, middleware.After) -} - -func addOpDeleteMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteMaintenanceWindow{}, middleware.After) -} - -func addOpDeleteOpsItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteOpsItem{}, middleware.After) -} - -func addOpDeleteOpsMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteOpsMetadata{}, middleware.After) -} - -func addOpDeleteParameterValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteParameter{}, middleware.After) -} - -func addOpDeleteParametersValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteParameters{}, middleware.After) -} - -func addOpDeletePatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeletePatchBaseline{}, middleware.After) -} - -func addOpDeleteResourceDataSyncValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteResourceDataSync{}, middleware.After) -} - -func addOpDeleteResourcePolicyValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeleteResourcePolicy{}, middleware.After) -} - -func addOpDeregisterManagedInstanceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeregisterManagedInstance{}, middleware.After) -} - -func addOpDeregisterPatchBaselineForPatchGroupValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeregisterPatchBaselineForPatchGroup{}, middleware.After) -} - -func addOpDeregisterTargetFromMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeregisterTargetFromMaintenanceWindow{}, middleware.After) -} - -func addOpDeregisterTaskFromMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDeregisterTaskFromMaintenanceWindow{}, middleware.After) -} - -func addOpDescribeAssociationExecutionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeAssociationExecutions{}, middleware.After) -} - -func addOpDescribeAssociationExecutionTargetsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeAssociationExecutionTargets{}, middleware.After) -} - -func addOpDescribeAutomationExecutionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeAutomationExecutions{}, middleware.After) -} - -func addOpDescribeAutomationStepExecutionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeAutomationStepExecutions{}, middleware.After) -} - -func addOpDescribeDocumentValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeDocument{}, middleware.After) -} - -func addOpDescribeDocumentPermissionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeDocumentPermission{}, middleware.After) -} - -func addOpDescribeEffectiveInstanceAssociationsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeEffectiveInstanceAssociations{}, middleware.After) -} - -func addOpDescribeEffectivePatchesForPatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeEffectivePatchesForPatchBaseline{}, middleware.After) -} - -func addOpDescribeInstanceAssociationsStatusValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeInstanceAssociationsStatus{}, middleware.After) -} - -func addOpDescribeInstanceInformationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeInstanceInformation{}, middleware.After) -} - -func addOpDescribeInstancePatchesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeInstancePatches{}, middleware.After) -} - -func addOpDescribeInstancePatchStatesForPatchGroupValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeInstancePatchStatesForPatchGroup{}, middleware.After) -} - -func addOpDescribeInstancePatchStatesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeInstancePatchStates{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowExecutionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowExecutions{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowExecutionTaskInvocationsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowExecutionTaskInvocations{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowExecutionTasksValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowExecutionTasks{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowsForTargetValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowsForTarget{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowTargetsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowTargets{}, middleware.After) -} - -func addOpDescribeMaintenanceWindowTasksValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeMaintenanceWindowTasks{}, middleware.After) -} - -func addOpDescribeOpsItemsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeOpsItems{}, middleware.After) -} - -func addOpDescribeParametersValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeParameters{}, middleware.After) -} - -func addOpDescribePatchGroupStateValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribePatchGroupState{}, middleware.After) -} - -func addOpDescribePatchPropertiesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribePatchProperties{}, middleware.After) -} - -func addOpDescribeSessionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDescribeSessions{}, middleware.After) -} - -func addOpDisassociateOpsItemRelatedItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDisassociateOpsItemRelatedItem{}, middleware.After) -} - -func addOpGetAutomationExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetAutomationExecution{}, middleware.After) -} - -func addOpGetCalendarStateValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetCalendarState{}, middleware.After) -} - -func addOpGetCommandInvocationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetCommandInvocation{}, middleware.After) -} - -func addOpGetConnectionStatusValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetConnectionStatus{}, middleware.After) -} - -func addOpGetDeployablePatchSnapshotForInstanceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetDeployablePatchSnapshotForInstance{}, middleware.After) -} - -func addOpGetDocumentValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetDocument{}, middleware.After) -} - -func addOpGetInventoryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetInventory{}, middleware.After) -} - -func addOpGetMaintenanceWindowExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetMaintenanceWindowExecution{}, middleware.After) -} - -func addOpGetMaintenanceWindowExecutionTaskValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetMaintenanceWindowExecutionTask{}, middleware.After) -} - -func addOpGetMaintenanceWindowExecutionTaskInvocationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetMaintenanceWindowExecutionTaskInvocation{}, middleware.After) -} - -func addOpGetMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetMaintenanceWindow{}, middleware.After) -} - -func addOpGetMaintenanceWindowTaskValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetMaintenanceWindowTask{}, middleware.After) -} - -func addOpGetOpsItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetOpsItem{}, middleware.After) -} - -func addOpGetOpsMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetOpsMetadata{}, middleware.After) -} - -func addOpGetOpsSummaryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetOpsSummary{}, middleware.After) -} - -func addOpGetParameterHistoryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetParameterHistory{}, middleware.After) -} - -func addOpGetParameterValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetParameter{}, middleware.After) -} - -func addOpGetParametersByPathValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetParametersByPath{}, middleware.After) -} - -func addOpGetParametersValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetParameters{}, middleware.After) -} - -func addOpGetPatchBaselineForPatchGroupValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetPatchBaselineForPatchGroup{}, middleware.After) -} - -func addOpGetPatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetPatchBaseline{}, middleware.After) -} - -func addOpGetResourcePoliciesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetResourcePolicies{}, middleware.After) -} - -func addOpGetServiceSettingValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetServiceSetting{}, middleware.After) -} - -func addOpLabelParameterVersionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpLabelParameterVersion{}, middleware.After) -} - -func addOpListAssociationsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListAssociations{}, middleware.After) -} - -func addOpListAssociationVersionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListAssociationVersions{}, middleware.After) -} - -func addOpListCommandInvocationsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListCommandInvocations{}, middleware.After) -} - -func addOpListCommandsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListCommands{}, middleware.After) -} - -func addOpListDocumentMetadataHistoryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListDocumentMetadataHistory{}, middleware.After) -} - -func addOpListDocumentsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListDocuments{}, middleware.After) -} - -func addOpListDocumentVersionsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListDocumentVersions{}, middleware.After) -} - -func addOpListInventoryEntriesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListInventoryEntries{}, middleware.After) -} - -func addOpListOpsItemEventsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListOpsItemEvents{}, middleware.After) -} - -func addOpListOpsItemRelatedItemsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListOpsItemRelatedItems{}, middleware.After) -} - -func addOpListOpsMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListOpsMetadata{}, middleware.After) -} - -func addOpListTagsForResourceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListTagsForResource{}, middleware.After) -} - -func addOpModifyDocumentPermissionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpModifyDocumentPermission{}, middleware.After) -} - -func addOpPutComplianceItemsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpPutComplianceItems{}, middleware.After) -} - -func addOpPutInventoryValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpPutInventory{}, middleware.After) -} - -func addOpPutParameterValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpPutParameter{}, middleware.After) -} - -func addOpPutResourcePolicyValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpPutResourcePolicy{}, middleware.After) -} - -func addOpRegisterDefaultPatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRegisterDefaultPatchBaseline{}, middleware.After) -} - -func addOpRegisterPatchBaselineForPatchGroupValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRegisterPatchBaselineForPatchGroup{}, middleware.After) -} - -func addOpRegisterTargetWithMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRegisterTargetWithMaintenanceWindow{}, middleware.After) -} - -func addOpRegisterTaskWithMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRegisterTaskWithMaintenanceWindow{}, middleware.After) -} - -func addOpRemoveTagsFromResourceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRemoveTagsFromResource{}, middleware.After) -} - -func addOpResetServiceSettingValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpResetServiceSetting{}, middleware.After) -} - -func addOpResumeSessionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpResumeSession{}, middleware.After) -} - -func addOpSendAutomationSignalValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpSendAutomationSignal{}, middleware.After) -} - -func addOpSendCommandValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpSendCommand{}, middleware.After) -} - -func addOpStartAssociationsOnceValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStartAssociationsOnce{}, middleware.After) -} - -func addOpStartAutomationExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStartAutomationExecution{}, middleware.After) -} - -func addOpStartChangeRequestExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStartChangeRequestExecution{}, middleware.After) -} - -func addOpStartSessionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStartSession{}, middleware.After) -} - -func addOpStopAutomationExecutionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStopAutomationExecution{}, middleware.After) -} - -func addOpTerminateSessionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpTerminateSession{}, middleware.After) -} - -func addOpUnlabelParameterVersionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUnlabelParameterVersion{}, middleware.After) -} - -func addOpUpdateAssociationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateAssociation{}, middleware.After) -} - -func addOpUpdateAssociationStatusValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateAssociationStatus{}, middleware.After) -} - -func addOpUpdateDocumentDefaultVersionValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateDocumentDefaultVersion{}, middleware.After) -} - -func addOpUpdateDocumentValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateDocument{}, middleware.After) -} - -func addOpUpdateDocumentMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateDocumentMetadata{}, middleware.After) -} - -func addOpUpdateMaintenanceWindowValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateMaintenanceWindow{}, middleware.After) -} - -func addOpUpdateMaintenanceWindowTargetValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateMaintenanceWindowTarget{}, middleware.After) -} - -func addOpUpdateMaintenanceWindowTaskValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateMaintenanceWindowTask{}, middleware.After) -} - -func addOpUpdateManagedInstanceRoleValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateManagedInstanceRole{}, middleware.After) -} - -func addOpUpdateOpsItemValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateOpsItem{}, middleware.After) -} - -func addOpUpdateOpsMetadataValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateOpsMetadata{}, middleware.After) -} - -func addOpUpdatePatchBaselineValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdatePatchBaseline{}, middleware.After) -} - -func addOpUpdateResourceDataSyncValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateResourceDataSync{}, middleware.After) -} - -func addOpUpdateServiceSettingValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpUpdateServiceSetting{}, middleware.After) -} - -func validateAlarm(v *types.Alarm) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "Alarm"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAlarmConfiguration(v *types.AlarmConfiguration) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AlarmConfiguration"} - if v.Alarms == nil { - invalidParams.Add(smithy.NewErrParamRequired("Alarms")) - } else if v.Alarms != nil { - if err := validateAlarmList(v.Alarms); err != nil { - invalidParams.AddNested("Alarms", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAlarmList(v []types.Alarm) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AlarmList"} - for i := range v { - if err := validateAlarm(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationExecutionFilter(v *types.AssociationExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationExecutionFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if len(v.Type) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Type")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationExecutionFilterList(v []types.AssociationExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationExecutionFilterList"} - for i := range v { - if err := validateAssociationExecutionFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationExecutionTargetsFilter(v *types.AssociationExecutionTargetsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationExecutionTargetsFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationExecutionTargetsFilterList(v []types.AssociationExecutionTargetsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationExecutionTargetsFilterList"} - for i := range v { - if err := validateAssociationExecutionTargetsFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationFilter(v *types.AssociationFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationFilterList(v []types.AssociationFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationFilterList"} - for i := range v { - if err := validateAssociationFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAssociationStatus(v *types.AssociationStatus) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociationStatus"} - if v.Date == nil { - invalidParams.Add(smithy.NewErrParamRequired("Date")) - } - if len(v.Name) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Message == nil { - invalidParams.Add(smithy.NewErrParamRequired("Message")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAutomationExecutionFilter(v *types.AutomationExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AutomationExecutionFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateAutomationExecutionFilterList(v []types.AutomationExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AutomationExecutionFilterList"} - for i := range v { - if err := validateAutomationExecutionFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateBaselineOverride(v *types.BaselineOverride) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "BaselineOverride"} - if v.GlobalFilters != nil { - if err := validatePatchFilterGroup(v.GlobalFilters); err != nil { - invalidParams.AddNested("GlobalFilters", err.(smithy.InvalidParamsError)) - } - } - if v.ApprovalRules != nil { - if err := validatePatchRuleGroup(v.ApprovalRules); err != nil { - invalidParams.AddNested("ApprovalRules", err.(smithy.InvalidParamsError)) - } - } - if v.Sources != nil { - if err := validatePatchSourceList(v.Sources); err != nil { - invalidParams.AddNested("Sources", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateCommandFilter(v *types.CommandFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CommandFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateCommandFilterList(v []types.CommandFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CommandFilterList"} - for i := range v { - if err := validateCommandFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateComplianceExecutionSummary(v *types.ComplianceExecutionSummary) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ComplianceExecutionSummary"} - if v.ExecutionTime == nil { - invalidParams.Add(smithy.NewErrParamRequired("ExecutionTime")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateComplianceItemEntry(v *types.ComplianceItemEntry) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ComplianceItemEntry"} - if len(v.Severity) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Severity")) - } - if len(v.Status) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Status")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateComplianceItemEntryList(v []types.ComplianceItemEntry) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ComplianceItemEntryList"} - for i := range v { - if err := validateComplianceItemEntry(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateCreateAssociationBatchRequestEntries(v []types.CreateAssociationBatchRequestEntry) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateAssociationBatchRequestEntries"} - for i := range v { - if err := validateCreateAssociationBatchRequestEntry(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateCreateAssociationBatchRequestEntry(v *types.CreateAssociationBatchRequestEntry) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateAssociationBatchRequestEntry"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.TargetLocations != nil { - if err := validateTargetLocations(v.TargetLocations); err != nil { - invalidParams.AddNested("TargetLocations", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateDocumentFilter(v *types.DocumentFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DocumentFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateDocumentFilterList(v []types.DocumentFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DocumentFilterList"} - for i := range v { - if err := validateDocumentFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateDocumentRequires(v *types.DocumentRequires) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DocumentRequires"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateDocumentRequiresList(v []types.DocumentRequires) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DocumentRequiresList"} - for i := range v { - if err := validateDocumentRequires(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateDocumentReviews(v *types.DocumentReviews) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DocumentReviews"} - if len(v.Action) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Action")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstanceInformationFilter(v *types.InstanceInformationFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstanceInformationFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.ValueSet == nil { - invalidParams.Add(smithy.NewErrParamRequired("ValueSet")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstanceInformationFilterList(v []types.InstanceInformationFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstanceInformationFilterList"} - for i := range v { - if err := validateInstanceInformationFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstanceInformationStringFilter(v *types.InstanceInformationStringFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstanceInformationStringFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstanceInformationStringFilterList(v []types.InstanceInformationStringFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstanceInformationStringFilterList"} - for i := range v { - if err := validateInstanceInformationStringFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstancePatchStateFilter(v *types.InstancePatchStateFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstancePatchStateFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if len(v.Type) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Type")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInstancePatchStateFilterList(v []types.InstancePatchStateFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InstancePatchStateFilterList"} - for i := range v { - if err := validateInstancePatchStateFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryAggregator(v *types.InventoryAggregator) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryAggregator"} - if v.Aggregators != nil { - if err := validateInventoryAggregatorList(v.Aggregators); err != nil { - invalidParams.AddNested("Aggregators", err.(smithy.InvalidParamsError)) - } - } - if v.Groups != nil { - if err := validateInventoryGroupList(v.Groups); err != nil { - invalidParams.AddNested("Groups", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryAggregatorList(v []types.InventoryAggregator) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryAggregatorList"} - for i := range v { - if err := validateInventoryAggregator(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryFilter(v *types.InventoryFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryFilterList(v []types.InventoryFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryFilterList"} - for i := range v { - if err := validateInventoryFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryGroup(v *types.InventoryGroup) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryGroup"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Filters == nil { - invalidParams.Add(smithy.NewErrParamRequired("Filters")) - } else if v.Filters != nil { - if err := validateInventoryFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryGroupList(v []types.InventoryGroup) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryGroupList"} - for i := range v { - if err := validateInventoryGroup(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryItem(v *types.InventoryItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryItem"} - if v.TypeName == nil { - invalidParams.Add(smithy.NewErrParamRequired("TypeName")) - } - if v.SchemaVersion == nil { - invalidParams.Add(smithy.NewErrParamRequired("SchemaVersion")) - } - if v.CaptureTime == nil { - invalidParams.Add(smithy.NewErrParamRequired("CaptureTime")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateInventoryItemList(v []types.InventoryItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "InventoryItemList"} - for i := range v { - if err := validateInventoryItem(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateLoggingInfo(v *types.LoggingInfo) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "LoggingInfo"} - if v.S3BucketName == nil { - invalidParams.Add(smithy.NewErrParamRequired("S3BucketName")) - } - if v.S3Region == nil { - invalidParams.Add(smithy.NewErrParamRequired("S3Region")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsAggregator(v *types.OpsAggregator) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsAggregator"} - if v.Filters != nil { - if err := validateOpsFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if v.Aggregators != nil { - if err := validateOpsAggregatorList(v.Aggregators); err != nil { - invalidParams.AddNested("Aggregators", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsAggregatorList(v []types.OpsAggregator) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsAggregatorList"} - for i := range v { - if err := validateOpsAggregator(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsFilter(v *types.OpsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsFilterList(v []types.OpsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsFilterList"} - for i := range v { - if err := validateOpsFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemEventFilter(v *types.OpsItemEventFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemEventFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if len(v.Operator) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Operator")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemEventFilters(v []types.OpsItemEventFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemEventFilters"} - for i := range v { - if err := validateOpsItemEventFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemFilter(v *types.OpsItemFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if len(v.Operator) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Operator")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemFilters(v []types.OpsItemFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemFilters"} - for i := range v { - if err := validateOpsItemFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemRelatedItemsFilter(v *types.OpsItemRelatedItemsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemRelatedItemsFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if len(v.Operator) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Operator")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsItemRelatedItemsFilters(v []types.OpsItemRelatedItemsFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsItemRelatedItemsFilters"} - for i := range v { - if err := validateOpsItemRelatedItemsFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsMetadataFilter(v *types.OpsMetadataFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsMetadataFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsMetadataFilterList(v []types.OpsMetadataFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsMetadataFilterList"} - for i := range v { - if err := validateOpsMetadataFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsResultAttribute(v *types.OpsResultAttribute) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsResultAttribute"} - if v.TypeName == nil { - invalidParams.Add(smithy.NewErrParamRequired("TypeName")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpsResultAttributeList(v []types.OpsResultAttribute) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "OpsResultAttributeList"} - for i := range v { - if err := validateOpsResultAttribute(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateParametersFilter(v *types.ParametersFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ParametersFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateParametersFilterList(v []types.ParametersFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ParametersFilterList"} - for i := range v { - if err := validateParametersFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateParameterStringFilter(v *types.ParameterStringFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ParameterStringFilter"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateParameterStringFilterList(v []types.ParameterStringFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ParameterStringFilterList"} - for i := range v { - if err := validateParameterStringFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchFilter(v *types.PatchFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchFilterGroup(v *types.PatchFilterGroup) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchFilterGroup"} - if v.PatchFilters == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchFilters")) - } else if v.PatchFilters != nil { - if err := validatePatchFilterList(v.PatchFilters); err != nil { - invalidParams.AddNested("PatchFilters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchFilterList(v []types.PatchFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchFilterList"} - for i := range v { - if err := validatePatchFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchRule(v *types.PatchRule) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchRule"} - if v.PatchFilterGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchFilterGroup")) - } else if v.PatchFilterGroup != nil { - if err := validatePatchFilterGroup(v.PatchFilterGroup); err != nil { - invalidParams.AddNested("PatchFilterGroup", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchRuleGroup(v *types.PatchRuleGroup) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchRuleGroup"} - if v.PatchRules == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchRules")) - } else if v.PatchRules != nil { - if err := validatePatchRuleList(v.PatchRules); err != nil { - invalidParams.AddNested("PatchRules", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchRuleList(v []types.PatchRule) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchRuleList"} - for i := range v { - if err := validatePatchRule(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchSource(v *types.PatchSource) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchSource"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Products == nil { - invalidParams.Add(smithy.NewErrParamRequired("Products")) - } - if v.Configuration == nil { - invalidParams.Add(smithy.NewErrParamRequired("Configuration")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validatePatchSourceList(v []types.PatchSource) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PatchSourceList"} - for i := range v { - if err := validatePatchSource(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRegistrationMetadataItem(v *types.RegistrationMetadataItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegistrationMetadataItem"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRegistrationMetadataList(v []types.RegistrationMetadataItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegistrationMetadataList"} - for i := range v { - if err := validateRegistrationMetadataItem(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRelatedOpsItem(v *types.RelatedOpsItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RelatedOpsItem"} - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRelatedOpsItems(v []types.RelatedOpsItem) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RelatedOpsItems"} - for i := range v { - if err := validateRelatedOpsItem(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateResourceDataSyncAwsOrganizationsSource(v *types.ResourceDataSyncAwsOrganizationsSource) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResourceDataSyncAwsOrganizationsSource"} - if v.OrganizationSourceType == nil { - invalidParams.Add(smithy.NewErrParamRequired("OrganizationSourceType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateResourceDataSyncS3Destination(v *types.ResourceDataSyncS3Destination) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResourceDataSyncS3Destination"} - if v.BucketName == nil { - invalidParams.Add(smithy.NewErrParamRequired("BucketName")) - } - if len(v.SyncFormat) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("SyncFormat")) - } - if v.Region == nil { - invalidParams.Add(smithy.NewErrParamRequired("Region")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateResourceDataSyncSource(v *types.ResourceDataSyncSource) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResourceDataSyncSource"} - if v.SourceType == nil { - invalidParams.Add(smithy.NewErrParamRequired("SourceType")) - } - if v.AwsOrganizationsSource != nil { - if err := validateResourceDataSyncAwsOrganizationsSource(v.AwsOrganizationsSource); err != nil { - invalidParams.AddNested("AwsOrganizationsSource", err.(smithy.InvalidParamsError)) - } - } - if v.SourceRegions == nil { - invalidParams.Add(smithy.NewErrParamRequired("SourceRegions")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateResultAttribute(v *types.ResultAttribute) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResultAttribute"} - if v.TypeName == nil { - invalidParams.Add(smithy.NewErrParamRequired("TypeName")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateResultAttributeList(v []types.ResultAttribute) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResultAttributeList"} - for i := range v { - if err := validateResultAttribute(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRunbook(v *types.Runbook) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "Runbook"} - if v.DocumentName == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentName")) - } - if v.TargetLocations != nil { - if err := validateTargetLocations(v.TargetLocations); err != nil { - invalidParams.AddNested("TargetLocations", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateRunbooks(v []types.Runbook) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "Runbooks"} - for i := range v { - if err := validateRunbook(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateSessionFilter(v *types.SessionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "SessionFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateSessionFilterList(v []types.SessionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "SessionFilterList"} - for i := range v { - if err := validateSessionFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateStepExecutionFilter(v *types.StepExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StepExecutionFilter"} - if len(v.Key) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Values == nil { - invalidParams.Add(smithy.NewErrParamRequired("Values")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateStepExecutionFilterList(v []types.StepExecutionFilter) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StepExecutionFilterList"} - for i := range v { - if err := validateStepExecutionFilter(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateTag(v *types.Tag) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "Tag"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateTagList(v []types.Tag) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "TagList"} - for i := range v { - if err := validateTag(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateTargetLocation(v *types.TargetLocation) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "TargetLocation"} - if v.TargetLocationAlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.TargetLocationAlarmConfiguration); err != nil { - invalidParams.AddNested("TargetLocationAlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateTargetLocations(v []types.TargetLocation) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "TargetLocations"} - for i := range v { - if err := validateTargetLocation(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAddTagsToResourceInput(v *AddTagsToResourceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AddTagsToResourceInput"} - if len(v.ResourceType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.ResourceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceId")) - } - if v.Tags == nil { - invalidParams.Add(smithy.NewErrParamRequired("Tags")) - } else if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAssociateOpsItemRelatedItemInput(v *AssociateOpsItemRelatedItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssociateOpsItemRelatedItemInput"} - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if v.AssociationType == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationType")) - } - if v.ResourceType == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.ResourceUri == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceUri")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCancelCommandInput(v *CancelCommandInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CancelCommandInput"} - if v.CommandId == nil { - invalidParams.Add(smithy.NewErrParamRequired("CommandId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCancelMaintenanceWindowExecutionInput(v *CancelMaintenanceWindowExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CancelMaintenanceWindowExecutionInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateActivationInput(v *CreateActivationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateActivationInput"} - if v.IamRole == nil { - invalidParams.Add(smithy.NewErrParamRequired("IamRole")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if v.RegistrationMetadata != nil { - if err := validateRegistrationMetadataList(v.RegistrationMetadata); err != nil { - invalidParams.AddNested("RegistrationMetadata", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateAssociationBatchInput(v *CreateAssociationBatchInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateAssociationBatchInput"} - if v.Entries == nil { - invalidParams.Add(smithy.NewErrParamRequired("Entries")) - } else if v.Entries != nil { - if err := validateCreateAssociationBatchRequestEntries(v.Entries); err != nil { - invalidParams.AddNested("Entries", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateAssociationInput(v *CreateAssociationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateAssociationInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.TargetLocations != nil { - if err := validateTargetLocations(v.TargetLocations); err != nil { - invalidParams.AddNested("TargetLocations", err.(smithy.InvalidParamsError)) - } - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateDocumentInput(v *CreateDocumentInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateDocumentInput"} - if v.Content == nil { - invalidParams.Add(smithy.NewErrParamRequired("Content")) - } - if v.Requires != nil { - if err := validateDocumentRequiresList(v.Requires); err != nil { - invalidParams.AddNested("Requires", err.(smithy.InvalidParamsError)) - } - } - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateMaintenanceWindowInput(v *CreateMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateMaintenanceWindowInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Schedule == nil { - invalidParams.Add(smithy.NewErrParamRequired("Schedule")) - } - if v.Duration == nil { - invalidParams.Add(smithy.NewErrParamRequired("Duration")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateOpsItemInput(v *CreateOpsItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateOpsItemInput"} - if v.Description == nil { - invalidParams.Add(smithy.NewErrParamRequired("Description")) - } - if v.RelatedOpsItems != nil { - if err := validateRelatedOpsItems(v.RelatedOpsItems); err != nil { - invalidParams.AddNested("RelatedOpsItems", err.(smithy.InvalidParamsError)) - } - } - if v.Source == nil { - invalidParams.Add(smithy.NewErrParamRequired("Source")) - } - if v.Title == nil { - invalidParams.Add(smithy.NewErrParamRequired("Title")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateOpsMetadataInput(v *CreateOpsMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateOpsMetadataInput"} - if v.ResourceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceId")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreatePatchBaselineInput(v *CreatePatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreatePatchBaselineInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.GlobalFilters != nil { - if err := validatePatchFilterGroup(v.GlobalFilters); err != nil { - invalidParams.AddNested("GlobalFilters", err.(smithy.InvalidParamsError)) - } - } - if v.ApprovalRules != nil { - if err := validatePatchRuleGroup(v.ApprovalRules); err != nil { - invalidParams.AddNested("ApprovalRules", err.(smithy.InvalidParamsError)) - } - } - if v.Sources != nil { - if err := validatePatchSourceList(v.Sources); err != nil { - invalidParams.AddNested("Sources", err.(smithy.InvalidParamsError)) - } - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateResourceDataSyncInput(v *CreateResourceDataSyncInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateResourceDataSyncInput"} - if v.SyncName == nil { - invalidParams.Add(smithy.NewErrParamRequired("SyncName")) - } - if v.S3Destination != nil { - if err := validateResourceDataSyncS3Destination(v.S3Destination); err != nil { - invalidParams.AddNested("S3Destination", err.(smithy.InvalidParamsError)) - } - } - if v.SyncSource != nil { - if err := validateResourceDataSyncSource(v.SyncSource); err != nil { - invalidParams.AddNested("SyncSource", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteActivationInput(v *DeleteActivationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteActivationInput"} - if v.ActivationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ActivationId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteDocumentInput(v *DeleteDocumentInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteDocumentInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteInventoryInput(v *DeleteInventoryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteInventoryInput"} - if v.TypeName == nil { - invalidParams.Add(smithy.NewErrParamRequired("TypeName")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteMaintenanceWindowInput(v *DeleteMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteOpsItemInput(v *DeleteOpsItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteOpsItemInput"} - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteOpsMetadataInput(v *DeleteOpsMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteOpsMetadataInput"} - if v.OpsMetadataArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsMetadataArn")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteParameterInput(v *DeleteParameterInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteParameterInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteParametersInput(v *DeleteParametersInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteParametersInput"} - if v.Names == nil { - invalidParams.Add(smithy.NewErrParamRequired("Names")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeletePatchBaselineInput(v *DeletePatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeletePatchBaselineInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteResourceDataSyncInput(v *DeleteResourceDataSyncInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteResourceDataSyncInput"} - if v.SyncName == nil { - invalidParams.Add(smithy.NewErrParamRequired("SyncName")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeleteResourcePolicyInput(v *DeleteResourcePolicyInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeleteResourcePolicyInput"} - if v.ResourceArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceArn")) - } - if v.PolicyId == nil { - invalidParams.Add(smithy.NewErrParamRequired("PolicyId")) - } - if v.PolicyHash == nil { - invalidParams.Add(smithy.NewErrParamRequired("PolicyHash")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeregisterManagedInstanceInput(v *DeregisterManagedInstanceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeregisterManagedInstanceInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeregisterPatchBaselineForPatchGroupInput(v *DeregisterPatchBaselineForPatchGroupInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeregisterPatchBaselineForPatchGroupInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if v.PatchGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchGroup")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeregisterTargetFromMaintenanceWindowInput(v *DeregisterTargetFromMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeregisterTargetFromMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.WindowTargetId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowTargetId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDeregisterTaskFromMaintenanceWindowInput(v *DeregisterTaskFromMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DeregisterTaskFromMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.WindowTaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowTaskId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeAssociationExecutionsInput(v *DescribeAssociationExecutionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeAssociationExecutionsInput"} - if v.AssociationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationId")) - } - if v.Filters != nil { - if err := validateAssociationExecutionFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeAssociationExecutionTargetsInput(v *DescribeAssociationExecutionTargetsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeAssociationExecutionTargetsInput"} - if v.AssociationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationId")) - } - if v.ExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ExecutionId")) - } - if v.Filters != nil { - if err := validateAssociationExecutionTargetsFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeAutomationExecutionsInput(v *DescribeAutomationExecutionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeAutomationExecutionsInput"} - if v.Filters != nil { - if err := validateAutomationExecutionFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeAutomationStepExecutionsInput(v *DescribeAutomationStepExecutionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeAutomationStepExecutionsInput"} - if v.AutomationExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AutomationExecutionId")) - } - if v.Filters != nil { - if err := validateStepExecutionFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeDocumentInput(v *DescribeDocumentInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeDocumentInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeDocumentPermissionInput(v *DescribeDocumentPermissionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeDocumentPermissionInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if len(v.PermissionType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("PermissionType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeEffectiveInstanceAssociationsInput(v *DescribeEffectiveInstanceAssociationsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeEffectiveInstanceAssociationsInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeEffectivePatchesForPatchBaselineInput(v *DescribeEffectivePatchesForPatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeEffectivePatchesForPatchBaselineInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeInstanceAssociationsStatusInput(v *DescribeInstanceAssociationsStatusInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeInstanceAssociationsStatusInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeInstanceInformationInput(v *DescribeInstanceInformationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeInstanceInformationInput"} - if v.InstanceInformationFilterList != nil { - if err := validateInstanceInformationFilterList(v.InstanceInformationFilterList); err != nil { - invalidParams.AddNested("InstanceInformationFilterList", err.(smithy.InvalidParamsError)) - } - } - if v.Filters != nil { - if err := validateInstanceInformationStringFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeInstancePatchesInput(v *DescribeInstancePatchesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeInstancePatchesInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeInstancePatchStatesForPatchGroupInput(v *DescribeInstancePatchStatesForPatchGroupInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeInstancePatchStatesForPatchGroupInput"} - if v.PatchGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchGroup")) - } - if v.Filters != nil { - if err := validateInstancePatchStateFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeInstancePatchStatesInput(v *DescribeInstancePatchStatesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeInstancePatchStatesInput"} - if v.InstanceIds == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceIds")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowExecutionsInput(v *DescribeMaintenanceWindowExecutionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowExecutionsInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowExecutionTaskInvocationsInput(v *DescribeMaintenanceWindowExecutionTaskInvocationsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowExecutionTaskInvocationsInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if v.TaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("TaskId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowExecutionTasksInput(v *DescribeMaintenanceWindowExecutionTasksInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowExecutionTasksInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowsForTargetInput(v *DescribeMaintenanceWindowsForTargetInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowsForTargetInput"} - if v.Targets == nil { - invalidParams.Add(smithy.NewErrParamRequired("Targets")) - } - if len(v.ResourceType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowTargetsInput(v *DescribeMaintenanceWindowTargetsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowTargetsInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeMaintenanceWindowTasksInput(v *DescribeMaintenanceWindowTasksInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeMaintenanceWindowTasksInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeOpsItemsInput(v *DescribeOpsItemsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeOpsItemsInput"} - if v.OpsItemFilters != nil { - if err := validateOpsItemFilters(v.OpsItemFilters); err != nil { - invalidParams.AddNested("OpsItemFilters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeParametersInput(v *DescribeParametersInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeParametersInput"} - if v.Filters != nil { - if err := validateParametersFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if v.ParameterFilters != nil { - if err := validateParameterStringFilterList(v.ParameterFilters); err != nil { - invalidParams.AddNested("ParameterFilters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribePatchGroupStateInput(v *DescribePatchGroupStateInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribePatchGroupStateInput"} - if v.PatchGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchGroup")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribePatchPropertiesInput(v *DescribePatchPropertiesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribePatchPropertiesInput"} - if len(v.OperatingSystem) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("OperatingSystem")) - } - if len(v.Property) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Property")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDescribeSessionsInput(v *DescribeSessionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DescribeSessionsInput"} - if len(v.State) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("State")) - } - if v.Filters != nil { - if err := validateSessionFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDisassociateOpsItemRelatedItemInput(v *DisassociateOpsItemRelatedItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DisassociateOpsItemRelatedItemInput"} - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if v.AssociationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetAutomationExecutionInput(v *GetAutomationExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetAutomationExecutionInput"} - if v.AutomationExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AutomationExecutionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetCalendarStateInput(v *GetCalendarStateInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetCalendarStateInput"} - if v.CalendarNames == nil { - invalidParams.Add(smithy.NewErrParamRequired("CalendarNames")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetCommandInvocationInput(v *GetCommandInvocationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetCommandInvocationInput"} - if v.CommandId == nil { - invalidParams.Add(smithy.NewErrParamRequired("CommandId")) - } - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetConnectionStatusInput(v *GetConnectionStatusInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetConnectionStatusInput"} - if v.Target == nil { - invalidParams.Add(smithy.NewErrParamRequired("Target")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetDeployablePatchSnapshotForInstanceInput(v *GetDeployablePatchSnapshotForInstanceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetDeployablePatchSnapshotForInstanceInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if v.SnapshotId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SnapshotId")) - } - if v.BaselineOverride != nil { - if err := validateBaselineOverride(v.BaselineOverride); err != nil { - invalidParams.AddNested("BaselineOverride", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetDocumentInput(v *GetDocumentInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetDocumentInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetInventoryInput(v *GetInventoryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetInventoryInput"} - if v.Filters != nil { - if err := validateInventoryFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if v.Aggregators != nil { - if err := validateInventoryAggregatorList(v.Aggregators); err != nil { - invalidParams.AddNested("Aggregators", err.(smithy.InvalidParamsError)) - } - } - if v.ResultAttributes != nil { - if err := validateResultAttributeList(v.ResultAttributes); err != nil { - invalidParams.AddNested("ResultAttributes", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetMaintenanceWindowExecutionInput(v *GetMaintenanceWindowExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetMaintenanceWindowExecutionInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetMaintenanceWindowExecutionTaskInput(v *GetMaintenanceWindowExecutionTaskInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetMaintenanceWindowExecutionTaskInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if v.TaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("TaskId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetMaintenanceWindowExecutionTaskInvocationInput(v *GetMaintenanceWindowExecutionTaskInvocationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetMaintenanceWindowExecutionTaskInvocationInput"} - if v.WindowExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowExecutionId")) - } - if v.TaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("TaskId")) - } - if v.InvocationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InvocationId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetMaintenanceWindowInput(v *GetMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetMaintenanceWindowTaskInput(v *GetMaintenanceWindowTaskInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetMaintenanceWindowTaskInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.WindowTaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowTaskId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetOpsItemInput(v *GetOpsItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetOpsItemInput"} - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetOpsMetadataInput(v *GetOpsMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetOpsMetadataInput"} - if v.OpsMetadataArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsMetadataArn")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetOpsSummaryInput(v *GetOpsSummaryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetOpsSummaryInput"} - if v.Filters != nil { - if err := validateOpsFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if v.Aggregators != nil { - if err := validateOpsAggregatorList(v.Aggregators); err != nil { - invalidParams.AddNested("Aggregators", err.(smithy.InvalidParamsError)) - } - } - if v.ResultAttributes != nil { - if err := validateOpsResultAttributeList(v.ResultAttributes); err != nil { - invalidParams.AddNested("ResultAttributes", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetParameterHistoryInput(v *GetParameterHistoryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetParameterHistoryInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetParameterInput(v *GetParameterInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetParameterInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetParametersByPathInput(v *GetParametersByPathInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetParametersByPathInput"} - if v.Path == nil { - invalidParams.Add(smithy.NewErrParamRequired("Path")) - } - if v.ParameterFilters != nil { - if err := validateParameterStringFilterList(v.ParameterFilters); err != nil { - invalidParams.AddNested("ParameterFilters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetParametersInput(v *GetParametersInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetParametersInput"} - if v.Names == nil { - invalidParams.Add(smithy.NewErrParamRequired("Names")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetPatchBaselineForPatchGroupInput(v *GetPatchBaselineForPatchGroupInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetPatchBaselineForPatchGroupInput"} - if v.PatchGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchGroup")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetPatchBaselineInput(v *GetPatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetPatchBaselineInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetResourcePoliciesInput(v *GetResourcePoliciesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetResourcePoliciesInput"} - if v.ResourceArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceArn")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetServiceSettingInput(v *GetServiceSettingInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetServiceSettingInput"} - if v.SettingId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SettingId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpLabelParameterVersionInput(v *LabelParameterVersionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "LabelParameterVersionInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Labels == nil { - invalidParams.Add(smithy.NewErrParamRequired("Labels")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListAssociationsInput(v *ListAssociationsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListAssociationsInput"} - if v.AssociationFilterList != nil { - if err := validateAssociationFilterList(v.AssociationFilterList); err != nil { - invalidParams.AddNested("AssociationFilterList", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListAssociationVersionsInput(v *ListAssociationVersionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListAssociationVersionsInput"} - if v.AssociationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListCommandInvocationsInput(v *ListCommandInvocationsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListCommandInvocationsInput"} - if v.Filters != nil { - if err := validateCommandFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListCommandsInput(v *ListCommandsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListCommandsInput"} - if v.Filters != nil { - if err := validateCommandFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListDocumentMetadataHistoryInput(v *ListDocumentMetadataHistoryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListDocumentMetadataHistoryInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if len(v.Metadata) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("Metadata")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListDocumentsInput(v *ListDocumentsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListDocumentsInput"} - if v.DocumentFilterList != nil { - if err := validateDocumentFilterList(v.DocumentFilterList); err != nil { - invalidParams.AddNested("DocumentFilterList", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListDocumentVersionsInput(v *ListDocumentVersionsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListDocumentVersionsInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListInventoryEntriesInput(v *ListInventoryEntriesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListInventoryEntriesInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if v.TypeName == nil { - invalidParams.Add(smithy.NewErrParamRequired("TypeName")) - } - if v.Filters != nil { - if err := validateInventoryFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListOpsItemEventsInput(v *ListOpsItemEventsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListOpsItemEventsInput"} - if v.Filters != nil { - if err := validateOpsItemEventFilters(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListOpsItemRelatedItemsInput(v *ListOpsItemRelatedItemsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListOpsItemRelatedItemsInput"} - if v.Filters != nil { - if err := validateOpsItemRelatedItemsFilters(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListOpsMetadataInput(v *ListOpsMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListOpsMetadataInput"} - if v.Filters != nil { - if err := validateOpsMetadataFilterList(v.Filters); err != nil { - invalidParams.AddNested("Filters", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListTagsForResourceInput(v *ListTagsForResourceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListTagsForResourceInput"} - if len(v.ResourceType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.ResourceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpModifyDocumentPermissionInput(v *ModifyDocumentPermissionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ModifyDocumentPermissionInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if len(v.PermissionType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("PermissionType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpPutComplianceItemsInput(v *PutComplianceItemsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PutComplianceItemsInput"} - if v.ResourceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceId")) - } - if v.ResourceType == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.ComplianceType == nil { - invalidParams.Add(smithy.NewErrParamRequired("ComplianceType")) - } - if v.ExecutionSummary == nil { - invalidParams.Add(smithy.NewErrParamRequired("ExecutionSummary")) - } else if v.ExecutionSummary != nil { - if err := validateComplianceExecutionSummary(v.ExecutionSummary); err != nil { - invalidParams.AddNested("ExecutionSummary", err.(smithy.InvalidParamsError)) - } - } - if v.Items == nil { - invalidParams.Add(smithy.NewErrParamRequired("Items")) - } else if v.Items != nil { - if err := validateComplianceItemEntryList(v.Items); err != nil { - invalidParams.AddNested("Items", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpPutInventoryInput(v *PutInventoryInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PutInventoryInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if v.Items == nil { - invalidParams.Add(smithy.NewErrParamRequired("Items")) - } else if v.Items != nil { - if err := validateInventoryItemList(v.Items); err != nil { - invalidParams.AddNested("Items", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpPutParameterInput(v *PutParameterInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PutParameterInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpPutResourcePolicyInput(v *PutResourcePolicyInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "PutResourcePolicyInput"} - if v.ResourceArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceArn")) - } - if v.Policy == nil { - invalidParams.Add(smithy.NewErrParamRequired("Policy")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRegisterDefaultPatchBaselineInput(v *RegisterDefaultPatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegisterDefaultPatchBaselineInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRegisterPatchBaselineForPatchGroupInput(v *RegisterPatchBaselineForPatchGroupInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegisterPatchBaselineForPatchGroupInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if v.PatchGroup == nil { - invalidParams.Add(smithy.NewErrParamRequired("PatchGroup")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRegisterTargetWithMaintenanceWindowInput(v *RegisterTargetWithMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegisterTargetWithMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if len(v.ResourceType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.Targets == nil { - invalidParams.Add(smithy.NewErrParamRequired("Targets")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRegisterTaskWithMaintenanceWindowInput(v *RegisterTaskWithMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegisterTaskWithMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.TaskArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("TaskArn")) - } - if len(v.TaskType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("TaskType")) - } - if v.LoggingInfo != nil { - if err := validateLoggingInfo(v.LoggingInfo); err != nil { - invalidParams.AddNested("LoggingInfo", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRemoveTagsFromResourceInput(v *RemoveTagsFromResourceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RemoveTagsFromResourceInput"} - if len(v.ResourceType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("ResourceType")) - } - if v.ResourceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ResourceId")) - } - if v.TagKeys == nil { - invalidParams.Add(smithy.NewErrParamRequired("TagKeys")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpResetServiceSettingInput(v *ResetServiceSettingInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResetServiceSettingInput"} - if v.SettingId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SettingId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpResumeSessionInput(v *ResumeSessionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ResumeSessionInput"} - if v.SessionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SessionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpSendAutomationSignalInput(v *SendAutomationSignalInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "SendAutomationSignalInput"} - if v.AutomationExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AutomationExecutionId")) - } - if len(v.SignalType) == 0 { - invalidParams.Add(smithy.NewErrParamRequired("SignalType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpSendCommandInput(v *SendCommandInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "SendCommandInput"} - if v.DocumentName == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentName")) - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStartAssociationsOnceInput(v *StartAssociationsOnceInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StartAssociationsOnceInput"} - if v.AssociationIds == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationIds")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStartAutomationExecutionInput(v *StartAutomationExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StartAutomationExecutionInput"} - if v.DocumentName == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentName")) - } - if v.TargetLocations != nil { - if err := validateTargetLocations(v.TargetLocations); err != nil { - invalidParams.AddNested("TargetLocations", err.(smithy.InvalidParamsError)) - } - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStartChangeRequestExecutionInput(v *StartChangeRequestExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StartChangeRequestExecutionInput"} - if v.DocumentName == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentName")) - } - if v.Runbooks == nil { - invalidParams.Add(smithy.NewErrParamRequired("Runbooks")) - } else if v.Runbooks != nil { - if err := validateRunbooks(v.Runbooks); err != nil { - invalidParams.AddNested("Runbooks", err.(smithy.InvalidParamsError)) - } - } - if v.Tags != nil { - if err := validateTagList(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStartSessionInput(v *StartSessionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StartSessionInput"} - if v.Target == nil { - invalidParams.Add(smithy.NewErrParamRequired("Target")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStopAutomationExecutionInput(v *StopAutomationExecutionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StopAutomationExecutionInput"} - if v.AutomationExecutionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AutomationExecutionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpTerminateSessionInput(v *TerminateSessionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "TerminateSessionInput"} - if v.SessionId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SessionId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUnlabelParameterVersionInput(v *UnlabelParameterVersionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UnlabelParameterVersionInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.ParameterVersion == nil { - invalidParams.Add(smithy.NewErrParamRequired("ParameterVersion")) - } - if v.Labels == nil { - invalidParams.Add(smithy.NewErrParamRequired("Labels")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateAssociationInput(v *UpdateAssociationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateAssociationInput"} - if v.AssociationId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationId")) - } - if v.TargetLocations != nil { - if err := validateTargetLocations(v.TargetLocations); err != nil { - invalidParams.AddNested("TargetLocations", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateAssociationStatusInput(v *UpdateAssociationStatusInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateAssociationStatusInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if v.AssociationStatus == nil { - invalidParams.Add(smithy.NewErrParamRequired("AssociationStatus")) - } else if v.AssociationStatus != nil { - if err := validateAssociationStatus(v.AssociationStatus); err != nil { - invalidParams.AddNested("AssociationStatus", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateDocumentDefaultVersionInput(v *UpdateDocumentDefaultVersionInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateDocumentDefaultVersionInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.DocumentVersion == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentVersion")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateDocumentInput(v *UpdateDocumentInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateDocumentInput"} - if v.Content == nil { - invalidParams.Add(smithy.NewErrParamRequired("Content")) - } - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateDocumentMetadataInput(v *UpdateDocumentMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateDocumentMetadataInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.DocumentReviews == nil { - invalidParams.Add(smithy.NewErrParamRequired("DocumentReviews")) - } else if v.DocumentReviews != nil { - if err := validateDocumentReviews(v.DocumentReviews); err != nil { - invalidParams.AddNested("DocumentReviews", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateMaintenanceWindowInput(v *UpdateMaintenanceWindowInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateMaintenanceWindowInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateMaintenanceWindowTargetInput(v *UpdateMaintenanceWindowTargetInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateMaintenanceWindowTargetInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.WindowTargetId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowTargetId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateMaintenanceWindowTaskInput(v *UpdateMaintenanceWindowTaskInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateMaintenanceWindowTaskInput"} - if v.WindowId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowId")) - } - if v.WindowTaskId == nil { - invalidParams.Add(smithy.NewErrParamRequired("WindowTaskId")) - } - if v.LoggingInfo != nil { - if err := validateLoggingInfo(v.LoggingInfo); err != nil { - invalidParams.AddNested("LoggingInfo", err.(smithy.InvalidParamsError)) - } - } - if v.AlarmConfiguration != nil { - if err := validateAlarmConfiguration(v.AlarmConfiguration); err != nil { - invalidParams.AddNested("AlarmConfiguration", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateManagedInstanceRoleInput(v *UpdateManagedInstanceRoleInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateManagedInstanceRoleInput"} - if v.InstanceId == nil { - invalidParams.Add(smithy.NewErrParamRequired("InstanceId")) - } - if v.IamRole == nil { - invalidParams.Add(smithy.NewErrParamRequired("IamRole")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateOpsItemInput(v *UpdateOpsItemInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateOpsItemInput"} - if v.RelatedOpsItems != nil { - if err := validateRelatedOpsItems(v.RelatedOpsItems); err != nil { - invalidParams.AddNested("RelatedOpsItems", err.(smithy.InvalidParamsError)) - } - } - if v.OpsItemId == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsItemId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateOpsMetadataInput(v *UpdateOpsMetadataInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateOpsMetadataInput"} - if v.OpsMetadataArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("OpsMetadataArn")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdatePatchBaselineInput(v *UpdatePatchBaselineInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdatePatchBaselineInput"} - if v.BaselineId == nil { - invalidParams.Add(smithy.NewErrParamRequired("BaselineId")) - } - if v.GlobalFilters != nil { - if err := validatePatchFilterGroup(v.GlobalFilters); err != nil { - invalidParams.AddNested("GlobalFilters", err.(smithy.InvalidParamsError)) - } - } - if v.ApprovalRules != nil { - if err := validatePatchRuleGroup(v.ApprovalRules); err != nil { - invalidParams.AddNested("ApprovalRules", err.(smithy.InvalidParamsError)) - } - } - if v.Sources != nil { - if err := validatePatchSourceList(v.Sources); err != nil { - invalidParams.AddNested("Sources", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateResourceDataSyncInput(v *UpdateResourceDataSyncInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateResourceDataSyncInput"} - if v.SyncName == nil { - invalidParams.Add(smithy.NewErrParamRequired("SyncName")) - } - if v.SyncType == nil { - invalidParams.Add(smithy.NewErrParamRequired("SyncType")) - } - if v.SyncSource == nil { - invalidParams.Add(smithy.NewErrParamRequired("SyncSource")) - } else if v.SyncSource != nil { - if err := validateResourceDataSyncSource(v.SyncSource); err != nil { - invalidParams.AddNested("SyncSource", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpUpdateServiceSettingInput(v *UpdateServiceSettingInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "UpdateServiceSettingInput"} - if v.SettingId == nil { - invalidParams.Add(smithy.NewErrParamRequired("SettingId")) - } - if v.SettingValue == nil { - invalidParams.Add(smithy.NewErrParamRequired("SettingValue")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md index 4a1d033..42c252b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md @@ -1,3 +1,161 @@ +# v1.41.5 (2025-12-09) + +* No change notes available for this release. + +# v1.41.4 (2025-12-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.41.3 (2025-12-02) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. + +# v1.41.2 (2025-11-25) + +* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 + +# v1.41.1 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.41.0 (2025-11-19) + +* **Feature**: IAM now supports outbound identity federation via the STS GetWebIdentityToken API, enabling AWS workloads to securely authenticate with external services using short-lived JSON Web Tokens. + +# v1.40.2 (2025-11-12) + +* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use. +* **Bug Fix**: Reduce allocation overhead when the client doesn't have any HTTP interceptors configured. +* **Bug Fix**: Remove blank trace spans towards the beginning of the request that added no additional information. This conveys a slight reduction in overall allocations. + +# v1.40.1 (2025-11-11) + +* **Bug Fix**: Return validation error if input region is not a valid host label. + +# v1.40.0 (2025-11-10) + +* **Feature**: Added GetDelegatedAccessToken API, which is not available for general use at this time. + +# v1.39.1 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.39.0 (2025-10-30) + +* **Feature**: Update endpoint ruleset parameters casing +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.9 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.8 (2025-10-22) + +* No change notes available for this release. + +# v1.38.7 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.6 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.5 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.4 (2025-09-10) + +* No change notes available for this release. + +# v1.38.3 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.2 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.0 (2025-08-21) + +* **Feature**: Remove incorrect endpoint tests +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.37.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.36.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.1 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.0 (2025-06-17) + +* **Feature**: The AWS Security Token Service APIs AssumeRoleWithSAML and AssumeRoleWithWebIdentity can now be invoked without pre-configured AWS credentials in the SDK configuration. +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.21 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.20 (2025-06-06) + +* No change notes available for this release. + +# v1.33.19 (2025-04-10) + +* No change notes available for this release. + +# v1.33.18 (2025-04-03) + +* No change notes available for this release. + +# v1.33.17 (2025-03-04.2) + +* **Bug Fix**: Add assurance test for operation order. + +# v1.33.16 (2025-02-27) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.15 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.14 (2025-02-05) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.33.13 (2025-02-04) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go index 2578732..70228d0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go @@ -68,7 +68,12 @@ func timeOperationMetric[T any]( ctx context.Context, metric string, fn func() (T, error), opts ...metrics.RecordMetricOption, ) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return fn() + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) start := time.Now() @@ -81,7 +86,12 @@ func timeOperationMetric[T any]( } func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return func() {} + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) var ended bool @@ -109,6 +119,12 @@ func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { type operationMetricsKey struct{} func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { + if _, ok := mp.(metrics.NopMeterProvider); ok { + // not using the metrics system - setting up the metrics context is a memory-intensive operation + // so we should skip it in this case + return parent, nil + } + meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sts") om := &operationMetrics{} @@ -156,7 +172,10 @@ func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Hi } func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) + if v := ctx.Value(operationMetricsKey{}); v != nil { + return v.(*operationMetrics) + } + return nil } func operationTracer(p tracing.TracerProvider) tracing.Tracer { @@ -423,24 +442,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -554,6 +582,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -765,6 +797,37 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { return nil } +type setCredentialSourceMiddleware struct { + ua *awsmiddleware.RequestUserAgent + options Options +} + +func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } + +func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( + out middleware.BuildOutput, metadata middleware.Metadata, err error, +) { + asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) + if !ok { + return next.HandleBuild(ctx, in) + } + providerSources := asProviderSource.ProviderSources() + for _, source := range providerSources { + m.ua.AddCredentialsSource(source) + } + return next.HandleBuild(ctx, in) +} + +func addCredentialSource(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + mw := setCredentialSourceMiddleware{ua: ua, options: options} + return stack.Build.Insert(&mw, "UserAgent", middleware.Before) +} + func resolveTracerProvider(options *Options) { if options.TracerProvider == nil { options.TracerProvider = &tracing.NopTracerProvider{} @@ -977,88 +1040,62 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } -type spanInitializeStart struct { +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) } -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) } -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") +func addInterceptors(stack *middleware.Stack, opts Options) error { + // middlewares are expensive, don't add all of these interceptor ones unless the caller + // actually has at least one interceptor configured + // + // at the moment it's all-or-nothing because some of the middlewares here are responsible for + // setting fields in the interceptor context for future ones + if len(opts.Interceptors.BeforeExecution) == 0 && + len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && + len(opts.Interceptors.BeforeRetryLoop) == 0 && + len(opts.Interceptors.BeforeAttempt) == 0 && + len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && + len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && + len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && + len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { + return nil + } - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} - -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) + return errors.Join( + stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After), + stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before), + stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After), + stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After), + stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) + stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before), + ) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go index d056327..0ddd362 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go @@ -147,7 +147,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- + // include underscores or any of the following characters: +=,.@- // // [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds // [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname @@ -196,7 +196,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@:/- + // include underscores or any of the following characters: +=,.@:\/- // // [How to Use an External ID When Granting Access to Your Amazon Web Services Resources to a Third Party]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html ExternalId *string @@ -279,7 +279,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- + // include underscores or any of the following characters: +=/:,.@- SerialNumber *string // The source identity specified by the principal that is calling the AssumeRole @@ -478,6 +478,9 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpAssumeRoleValidationMiddleware(stack); err != nil { return err } @@ -499,16 +502,13 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go index d0e117a..15f1dd9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go @@ -23,6 +23,9 @@ import ( // these temporary security credentials to sign calls to Amazon Web Services // services. // +// AssumeRoleWithSAML will not work on IAM Identity Center managed roles. These +// roles' names start with AWSReservedSSO_ . +// // # Session Duration // // By default, the temporary security credentials created by AssumeRoleWithSAML @@ -410,6 +413,9 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpAssumeRoleWithSAMLValidationMiddleware(stack); err != nil { return err } @@ -431,16 +437,13 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go index 0ae4bc1..7006eb3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go @@ -75,7 +75,7 @@ import ( // // (Optional) You can configure your IdP to pass attributes into your web identity // token as session tags. Each session tag consists of a key name and an associated -// value. For more information about session tags, see [Passing Session Tags in STS]in the IAM User Guide. +// value. For more information about session tags, see [Passing session tags using AssumeRoleWithWebIdentity]in the IAM User Guide. // // You can pass up to 50 session tags. The plaintext session tag keys can’t exceed // 128 characters and the values can’t exceed 256 characters. For these and @@ -123,6 +123,7 @@ import ( // providers to get and use temporary security credentials. // // [Amazon Web Services SDK for iOS Developer Guide]: http://aws.amazon.com/sdkforios/ +// [Passing session tags using AssumeRoleWithWebIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp // [Amazon Web Services SDK for Android Developer Guide]: http://aws.amazon.com/sdkforandroid/ // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length // [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session @@ -135,7 +136,6 @@ import ( // [Using IAM Roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session // [Amazon Cognito federated identities]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html // [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining // [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration // [Using Web Identity Federation API Operations for Mobile Apps]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html @@ -430,6 +430,9 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpAssumeRoleWithWebIdentityValidationMiddleware(stack); err != nil { return err } @@ -451,16 +454,13 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go index cd976e5..009c405 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go @@ -12,7 +12,9 @@ import ( ) // Returns a set of short term credentials you can use to perform privileged tasks -// on a member account in your organization. +// on a member account in your organization. You must use credentials from an +// Organizations management account or a delegated administrator account for IAM to +// call AssumeRoot . You cannot use root user credentials to make this call. // // Before you can launch a privileged session, you must have centralized root // access in your organization. For steps to enable this feature, see [Centralize root access for member accounts]in the IAM @@ -24,8 +26,16 @@ import ( // You can track AssumeRoot in CloudTrail logs to determine what actions were // performed in a session. For more information, see [Track privileged tasks in CloudTrail]in the IAM User Guide. // +// When granting access to privileged tasks you should only grant the necessary +// permissions required to perform that task. For more information, see [Security best practices in IAM]. In +// addition, you can use [service control policies](SCPs) to manage and limit permissions in your +// organization. See [General examples]in the Organizations User Guide for more information on SCPs. +// // [Endpoints]: https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html#sts-endpoints +// [Security best practices in IAM]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html // [Track privileged tasks in CloudTrail]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-track-privileged-tasks.html +// [General examples]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples_general.html +// [service control policies]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html // [Centralize root access for member accounts]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-enable-root-access.html func (c *Client) AssumeRoot(ctx context.Context, params *AssumeRootInput, optFns ...func(*Options)) (*AssumeRootOutput, error) { if params == nil { @@ -50,8 +60,10 @@ type AssumeRootInput struct { TargetPrincipal *string // The identity based policy that scopes the session to the privileged tasks that - // can be performed. You can use one of following Amazon Web Services managed - // policies to scope root session actions. + // can be performed. You must + // + // use one of following Amazon Web Services managed policies to scope root session + // actions: // // [IAMAuditRootUserCredentials] // @@ -175,6 +187,9 @@ func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, opti if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpAssumeRootValidationMiddleware(stack); err != nil { return err } @@ -196,16 +211,13 @@ func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, opti if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go index a56840e..b00b0c4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go @@ -147,6 +147,9 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDecodeAuthorizationMessageValidationMiddleware(stack); err != nil { return err } @@ -168,16 +171,13 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go index c80b055..887bb08 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go @@ -138,6 +138,9 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetAccessKeyInfoValidationMiddleware(stack); err != nil { return err } @@ -159,16 +162,13 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go index 49304bd..2c8d886 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go @@ -129,6 +129,9 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetCallerIdentity(options.Region), middleware.Before); err != nil { return err } @@ -147,16 +150,13 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go new file mode 100644 index 0000000..092ec13 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go @@ -0,0 +1,172 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package sts + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/sts/types" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// Exchanges a trade-in token for temporary Amazon Web Services credentials with +// the permissions associated with the assumed principal. This operation allows you +// to obtain credentials for a specific principal based on a trade-in token, +// enabling delegation of access to Amazon Web Services resources. +func (c *Client) GetDelegatedAccessToken(ctx context.Context, params *GetDelegatedAccessTokenInput, optFns ...func(*Options)) (*GetDelegatedAccessTokenOutput, error) { + if params == nil { + params = &GetDelegatedAccessTokenInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "GetDelegatedAccessToken", params, optFns, c.addOperationGetDelegatedAccessTokenMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*GetDelegatedAccessTokenOutput) + out.ResultMetadata = metadata + return out, nil +} + +type GetDelegatedAccessTokenInput struct { + + // The token to exchange for temporary Amazon Web Services credentials. This token + // must be valid and unexpired at the time of the request. + // + // This member is required. + TradeInToken *string + + noSmithyDocumentSerde +} + +type GetDelegatedAccessTokenOutput struct { + + // The Amazon Resource Name (ARN) of the principal that was assumed when obtaining + // the delegated access token. This ARN identifies the IAM entity whose permissions + // are granted by the temporary credentials. + AssumedPrincipal *string + + // Amazon Web Services credentials for API authentication. + Credentials *types.Credentials + + // The percentage of the maximum policy size that is used by the session policy. + // The policy size is calculated as the sum of all the session policies and + // permission boundaries attached to the session. If the packed size exceeds 100%, + // the request fails. + PackedPolicySize *int32 + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationGetDelegatedAccessTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsquery_serializeOpGetDelegatedAccessToken{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetDelegatedAccessToken{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "GetDelegatedAccessToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addSpanRetryLoop(stack, options); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addTimeOffsetBuild(stack, c); err != nil { + return err + } + if err = addUserAgentRetryMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpGetDelegatedAccessTokenValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDelegatedAccessToken(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opGetDelegatedAccessToken(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "GetDelegatedAccessToken", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go index e2ecc79..e0fc9a5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go @@ -351,6 +351,9 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetFederationTokenValidationMiddleware(stack); err != nil { return err } @@ -372,16 +375,13 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go index fdc4511..2f931f4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go @@ -200,6 +200,9 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetSessionToken(options.Region), middleware.Before); err != nil { return err } @@ -218,16 +221,13 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go new file mode 100644 index 0000000..306ee43 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go @@ -0,0 +1,195 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package sts + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/sts/types" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" + "time" +) + +// Returns a signed JSON Web Token (JWT) that represents the calling Amazon Web +// Services identity. The returned JWT can be used to authenticate with external +// services that support OIDC discovery. The token is signed by Amazon Web Services +// STS and can be publicly verified using the verification keys published at the +// issuer's JWKS endpoint. +func (c *Client) GetWebIdentityToken(ctx context.Context, params *GetWebIdentityTokenInput, optFns ...func(*Options)) (*GetWebIdentityTokenOutput, error) { + if params == nil { + params = &GetWebIdentityTokenInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "GetWebIdentityToken", params, optFns, c.addOperationGetWebIdentityTokenMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*GetWebIdentityTokenOutput) + out.ResultMetadata = metadata + return out, nil +} + +type GetWebIdentityTokenInput struct { + + // The intended recipient of the web identity token. This value populates the aud + // claim in the JWT and should identify the service or application that will + // validate and use the token. The external service should verify this claim to + // ensure the token was intended for their use. + // + // This member is required. + Audience []string + + // The cryptographic algorithm to use for signing the JSON Web Token (JWT). Valid + // values are RS256 (RSA with SHA-256) and ES384 (ECDSA using P-384 curve with + // SHA-384). + // + // This member is required. + SigningAlgorithm *string + + // The duration, in seconds, for which the JSON Web Token (JWT) will remain valid. + // The value can range from 60 seconds (1 minute) to 3600 seconds (1 hour). If not + // specified, the default duration is 300 seconds (5 minutes). The token is + // designed to be short-lived and should be used for proof of identity, then + // exchanged for credentials or short-lived tokens in the external service. + DurationSeconds *int32 + + // An optional list of tags to include in the JSON Web Token (JWT). These tags are + // added as custom claims to the JWT and can be used by the downstream service for + // authorization decisions. + Tags []types.Tag + + noSmithyDocumentSerde +} + +type GetWebIdentityTokenOutput struct { + + // The date and time when the web identity token expires, in UTC. The expiration + // is determined by adding the DurationSeconds value to the time the token was + // issued. After this time, the token should no longer be considered valid. + Expiration *time.Time + + // A signed JSON Web Token (JWT) that represents the caller's Amazon Web Services + // identity. The token contains standard JWT claims such as subject, audience, + // expiration time, and additional identity attributes added by STS as custom + // claims. You can also add your own custom claims to the token by passing tags as + // request parameters to the GetWebIdentityToken API. The token is signed using + // the specified signing algorithm and can be verified using the verification keys + // available at the issuer's JWKS endpoint. + WebIdentityToken *string + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsquery_serializeOpGetWebIdentityToken{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetWebIdentityToken{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "GetWebIdentityToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addSpanRetryLoop(stack, options); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addTimeOffsetBuild(stack, c); err != nil { + return err + } + if err = addUserAgentRetryMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpGetWebIdentityTokenValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetWebIdentityToken(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opGetWebIdentityToken(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "GetWebIdentityToken", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go index a90b2b7..4db5a51 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go @@ -12,10 +12,13 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { +func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { params.Region = options.Region + return nil } type setLegacyContextSigningOptionsMiddleware struct { @@ -92,14 +95,16 @@ type AuthResolverParameters struct { Region string } -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { +func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { params := &AuthResolverParameters{ Operation: operation, } - bindAuthParamsRegion(ctx, params, input, options) + if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { + return nil, err + } - return params + return params, nil } // AuthSchemeResolver returns a set of possible authentication options for an @@ -162,7 +167,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") defer span.End() - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) + } options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) if err != nil { return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) @@ -181,7 +189,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -200,6 +209,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go index 5934989..8c1ce35 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go @@ -21,17 +21,8 @@ import ( "io" "strconv" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsAwsquery_deserializeOpAssumeRole struct { } @@ -855,6 +846,124 @@ func awsAwsquery_deserializeOpErrorGetCallerIdentity(response *smithyhttp.Respon } } +type awsAwsquery_deserializeOpGetDelegatedAccessToken struct { +} + +func (*awsAwsquery_deserializeOpGetDelegatedAccessToken) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsquery_deserializeOpGetDelegatedAccessToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response, &metadata) + } + output := &GetDelegatedAccessTokenOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(response.Body, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return out, metadata, nil + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("GetDelegatedAccessTokenResult") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + return out, metadata, err +} + +func awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) + if err != nil { + return err + } + if reqID := errorComponents.RequestID; len(reqID) != 0 { + awsmiddleware.SetRequestIDMetadata(metadata, reqID) + } + if len(errorComponents.Code) != 0 { + errorCode = errorComponents.Code + } + if len(errorComponents.Message) != 0 { + errorMessage = errorComponents.Message + } + errorBody.Seek(0, io.SeekStart) + switch { + case strings.EqualFold("ExpiredTradeInTokenException", errorCode): + return awsAwsquery_deserializeErrorExpiredTradeInTokenException(response, errorBody) + + case strings.EqualFold("PackedPolicyTooLarge", errorCode): + return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) + + case strings.EqualFold("RegionDisabledException", errorCode): + return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + type awsAwsquery_deserializeOpGetFederationToken struct { } @@ -1085,6 +1194,124 @@ func awsAwsquery_deserializeOpErrorGetSessionToken(response *smithyhttp.Response } } +type awsAwsquery_deserializeOpGetWebIdentityToken struct { +} + +func (*awsAwsquery_deserializeOpGetWebIdentityToken) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsquery_deserializeOpGetWebIdentityToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsquery_deserializeOpErrorGetWebIdentityToken(response, &metadata) + } + output := &GetWebIdentityTokenOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(response.Body, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return out, metadata, nil + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("GetWebIdentityTokenResult") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + return out, metadata, err +} + +func awsAwsquery_deserializeOpErrorGetWebIdentityToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) + if err != nil { + return err + } + if reqID := errorComponents.RequestID; len(reqID) != 0 { + awsmiddleware.SetRequestIDMetadata(metadata, reqID) + } + if len(errorComponents.Code) != 0 { + errorCode = errorComponents.Code + } + if len(errorComponents.Message) != 0 { + errorMessage = errorComponents.Message + } + errorBody.Seek(0, io.SeekStart) + switch { + case strings.EqualFold("JWTPayloadSizeExceededException", errorCode): + return awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response, errorBody) + + case strings.EqualFold("OutboundWebIdentityFederationDisabledException", errorCode): + return awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response, errorBody) + + case strings.EqualFold("SessionDurationEscalationException", errorCode): + return awsAwsquery_deserializeErrorSessionDurationEscalationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.ExpiredTokenException{} var buff [1024]byte @@ -1129,6 +1356,50 @@ func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Resp return output } +func awsAwsquery_deserializeErrorExpiredTradeInTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.ExpiredTradeInTokenException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentExpiredTradeInTokenException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.IDPCommunicationErrorException{} var buff [1024]byte @@ -1305,6 +1576,50 @@ func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyh return output } +func awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.JWTPayloadSizeExceededException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.MalformedPolicyDocumentException{} var buff [1024]byte @@ -1349,6 +1664,50 @@ func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smit return output } +func awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.OutboundWebIdentityFederationDisabledException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.PackedPolicyTooLargeException{} var buff [1024]byte @@ -1437,6 +1796,50 @@ func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Re return output } +func awsAwsquery_deserializeErrorSessionDurationEscalationException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.SessionDurationEscalationException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentSessionDurationEscalationException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + func awsAwsquery_deserializeDocumentAssumedRoleUser(v **types.AssumedRoleUser, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -1640,6 +2043,55 @@ func awsAwsquery_deserializeDocumentExpiredTokenException(v **types.ExpiredToken return nil } +func awsAwsquery_deserializeDocumentExpiredTradeInTokenException(v **types.ExpiredTradeInTokenException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.ExpiredTradeInTokenException + if *v == nil { + sv = &types.ExpiredTradeInTokenException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentFederatedUser(v **types.FederatedUser, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -1898,6 +2350,55 @@ func awsAwsquery_deserializeDocumentInvalidIdentityTokenException(v **types.Inva return nil } +func awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(v **types.JWTPayloadSizeExceededException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.JWTPayloadSizeExceededException + if *v == nil { + sv = &types.JWTPayloadSizeExceededException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.MalformedPolicyDocumentException, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -1947,6 +2448,55 @@ func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.M return nil } +func awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(v **types.OutboundWebIdentityFederationDisabledException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.OutboundWebIdentityFederationDisabledException + if *v == nil { + sv = &types.OutboundWebIdentityFederationDisabledException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(v **types.PackedPolicyTooLargeException, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2045,6 +2595,55 @@ func awsAwsquery_deserializeDocumentRegionDisabledException(v **types.RegionDisa return nil } +func awsAwsquery_deserializeDocumentSessionDurationEscalationException(v **types.SessionDurationEscalationException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.SessionDurationEscalationException + if *v == nil { + sv = &types.SessionDurationEscalationException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeOpDocumentAssumeRoleOutput(v **AssumeRoleOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2611,6 +3210,78 @@ func awsAwsquery_deserializeOpDocumentGetCallerIdentityOutput(v **GetCallerIdent return nil } +func awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(v **GetDelegatedAccessTokenOutput, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *GetDelegatedAccessTokenOutput + if *v == nil { + sv = &GetDelegatedAccessTokenOutput{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("AssumedPrincipal", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.AssumedPrincipal = ptr.String(xtv) + } + + case strings.EqualFold("Credentials", t.Name.Local): + nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) + if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { + return err + } + + case strings.EqualFold("PackedPolicySize", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + i64, err := strconv.ParseInt(xtv, 10, 64) + if err != nil { + return err + } + sv.PackedPolicySize = ptr.Int32(int32(i64)) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeOpDocumentGetFederationTokenOutput(v **GetFederationTokenOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2717,3 +3388,69 @@ func awsAwsquery_deserializeOpDocumentGetSessionTokenOutput(v **GetSessionTokenO *v = sv return nil } + +func awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(v **GetWebIdentityTokenOutput, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *GetWebIdentityTokenOutput + if *v == nil { + sv = &GetWebIdentityTokenOutput{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("Expiration", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + t, err := smithytime.ParseDateTime(xtv) + if err != nil { + return err + } + sv.Expiration = ptr.Time(t) + } + + case strings.EqualFold("WebIdentityToken", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.WebIdentityToken = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go index dca2ce3..c8f9526 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go @@ -15,6 +15,7 @@ import ( smithy "github.com/aws/smithy-go" smithyauth "github.com/aws/smithy-go/auth" smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/aws/smithy-go/endpoints/private/rulesfn" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" "github.com/aws/smithy-go/tracing" @@ -218,11 +219,15 @@ func resolveBaseEndpoint(cfg aws.Config, o *Options) { } } -func bindRegion(region string) *string { +func bindRegion(region string) (*string, error) { if region == "" { - return nil + return nil, nil } - return aws.String(endpoints.MapFIPSRegion(region)) + if !rulesfn.IsValidHostLabel(region, true) { + return nil, fmt.Errorf("invalid input region %s", region) + } + + return aws.String(endpoints.MapFIPSRegion(region)), nil } // EndpointParameters provides the parameters that influence how endpoints are @@ -346,8 +351,11 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS _UseGlobalEndpoint := *params.UseGlobalEndpoint + _ = _UseGlobalEndpoint if _UseGlobalEndpoint == true { if !(params.Endpoint != nil) { @@ -1057,10 +1065,15 @@ type endpointParamsBinder interface { bindEndpointParams(*EndpointParameters) } -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { +func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { params := &EndpointParameters{} - params.Region = bindRegion(options.Region) + region, err := bindRegion(options.Region) + if err != nil { + return nil, err + } + params.Region = region + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) params.Endpoint = options.BaseEndpoint @@ -1069,7 +1082,7 @@ func bindEndpointParams(ctx context.Context, input interface{}, options Options) b.bindEndpointParams(params) } - return params + return params, nil } type resolveEndpointV2Middleware struct { @@ -1099,7 +1112,10 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") } - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) + } endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", func() (smithyendpoints.Endpoint, error) { return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json index 70a8845..e61823e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json @@ -17,8 +17,10 @@ "api_op_DecodeAuthorizationMessage.go", "api_op_GetAccessKeyInfo.go", "api_op_GetCallerIdentity.go", + "api_op_GetDelegatedAccessToken.go", "api_op_GetFederationToken.go", "api_op_GetSessionToken.go", + "api_op_GetWebIdentityToken.go", "auth.go", "deserializers.go", "doc.go", @@ -32,11 +34,12 @@ "protocol_test.go", "serializers.go", "snapshot_test.go", + "sra_operation_order_test.go", "types/errors.go", "types/types.go", "validators.go" ], - "go": "1.15", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/sts", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go index 2827701..c081cde 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go @@ -3,4 +3,4 @@ package sts // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.33.13" +const goModuleVersion = "1.41.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go index 8fc2012..be72d93 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go @@ -87,6 +87,7 @@ func New() *Resolver { var partitionRegexp = struct { Aws *regexp.Regexp AwsCn *regexp.Regexp + AwsEusc *regexp.Regexp AwsIso *regexp.Regexp AwsIsoB *regexp.Regexp AwsIsoE *regexp.Regexp @@ -96,6 +97,7 @@ var partitionRegexp = struct { Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), + AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), @@ -145,6 +147,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "ap-east-1", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "ap-east-2", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-northeast-1", }: endpoints.Endpoint{}, @@ -175,6 +180,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "ap-southeast-5", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "ap-southeast-6", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-southeast-7", }: endpoints.Endpoint{}, @@ -348,6 +356,46 @@ var defaultPartitions = endpoints.Partitions{ }: endpoints.Endpoint{}, }, }, + { + ID: "aws-eusc", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "sts.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "sts-fips.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "sts-fips.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "sts.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsEusc, + IsRegionalized: true, + Endpoints: endpoints.Endpoints{ + endpoints.EndpointKey{ + Region: "eusc-de-east-1", + }: endpoints.Endpoint{}, + }, + }, { ID: "aws-iso", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ @@ -401,6 +449,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "us-isob-east-1", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "us-isob-west-1", + }: endpoints.Endpoint{}, }, }, { @@ -423,6 +474,11 @@ var defaultPartitions = endpoints.Partitions{ }, RegionRegex: partitionRegexp.AwsIsoE, IsRegionalized: true, + Endpoints: endpoints.Endpoints{ + endpoints.EndpointKey{ + Region: "eu-isoe-west-1", + }: endpoints.Endpoint{}, + }, }, { ID: "aws-iso-f", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go index e1398f3..f60b7d3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go index 96b2221..5e22738 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go @@ -502,6 +502,76 @@ func (m *awsAwsquery_serializeOpGetCallerIdentity) HandleSerialize(ctx context.C return next.HandleSerialize(ctx, in) } +type awsAwsquery_serializeOpGetDelegatedAccessToken struct { +} + +func (*awsAwsquery_serializeOpGetDelegatedAccessToken) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsquery_serializeOpGetDelegatedAccessToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") + + bodyWriter := bytes.NewBuffer(nil) + bodyEncoder := query.NewEncoder(bodyWriter) + body := bodyEncoder.Object() + body.Key("Action").String("GetDelegatedAccessToken") + body.Key("Version").String("2011-06-15") + + if err := awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(input, bodyEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + err = bodyEncoder.Encode() + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} + type awsAwsquery_serializeOpGetFederationToken struct { } @@ -641,6 +711,76 @@ func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Con span.End() return next.HandleSerialize(ctx, in) } + +type awsAwsquery_serializeOpGetWebIdentityToken struct { +} + +func (*awsAwsquery_serializeOpGetWebIdentityToken) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsquery_serializeOpGetWebIdentityToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*GetWebIdentityTokenInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") + + bodyWriter := bytes.NewBuffer(nil) + bodyEncoder := query.NewEncoder(bodyWriter) + body := bodyEncoder.Object() + body.Key("Action").String("GetWebIdentityToken") + body.Key("Version").String("2011-06-15") + + if err := awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(input, bodyEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + err = bodyEncoder.Encode() + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} func awsAwsquery_serializeDocumentPolicyDescriptorListType(v []types.PolicyDescriptorType, value query.Value) error { array := value.Array("member") @@ -733,6 +873,16 @@ func awsAwsquery_serializeDocumentTagListType(v []types.Tag, value query.Value) return nil } +func awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v []string, value query.Value) error { + array := value.Array("member") + + for i := range v { + av := array.Value() + av.String(v[i]) + } + return nil +} + func awsAwsquery_serializeOpDocumentAssumeRoleInput(v *AssumeRoleInput, value query.Value) error { object := value.Object() _ = object @@ -946,6 +1096,18 @@ func awsAwsquery_serializeOpDocumentGetCallerIdentityInput(v *GetCallerIdentityI return nil } +func awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput, value query.Value) error { + object := value.Object() + _ = object + + if v.TradeInToken != nil { + objectKey := object.Key("TradeInToken") + objectKey.String(*v.TradeInToken) + } + + return nil +} + func awsAwsquery_serializeOpDocumentGetFederationTokenInput(v *GetFederationTokenInput, value query.Value) error { object := value.Object() _ = object @@ -1003,3 +1165,34 @@ func awsAwsquery_serializeOpDocumentGetSessionTokenInput(v *GetSessionTokenInput return nil } + +func awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(v *GetWebIdentityTokenInput, value query.Value) error { + object := value.Object() + _ = object + + if v.Audience != nil { + objectKey := object.Key("Audience") + if err := awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v.Audience, objectKey); err != nil { + return err + } + } + + if v.DurationSeconds != nil { + objectKey := object.Key("DurationSeconds") + objectKey.Integer(*v.DurationSeconds) + } + + if v.SigningAlgorithm != nil { + objectKey := object.Key("SigningAlgorithm") + objectKey.String(*v.SigningAlgorithm) + } + + if v.Tags != nil { + objectKey := object.Key("Tags") + if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go index 041629b..70d99a2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go @@ -34,6 +34,33 @@ func (e *ExpiredTokenException) ErrorCode() string { } func (e *ExpiredTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The trade-in token provided in the request has expired and can no longer be +// exchanged for credentials. Request a new token and retry the operation. +type ExpiredTradeInTokenException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *ExpiredTradeInTokenException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *ExpiredTradeInTokenException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *ExpiredTradeInTokenException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ExpiredTradeInTokenException" + } + return *e.ErrorCodeOverride +} +func (e *ExpiredTradeInTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // The request could not be fulfilled because the identity provider (IDP) that was // asked to verify the incoming identity token could not be reached. This is often // a transient error caused by network conditions. Retry the request a limited @@ -152,6 +179,34 @@ func (e *InvalidIdentityTokenException) ErrorCode() string { } func (e *InvalidIdentityTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The requested token payload size exceeds the maximum allowed size. Reduce the +// number of request tags included in the GetWebIdentityToken API call to reduce +// the token payload size. +type JWTPayloadSizeExceededException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *JWTPayloadSizeExceededException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *JWTPayloadSizeExceededException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *JWTPayloadSizeExceededException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "JWTPayloadSizeExceededException" + } + return *e.ErrorCodeOverride +} +func (e *JWTPayloadSizeExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // The request was rejected because the policy document was malformed. The error // message describes the specific error. type MalformedPolicyDocumentException struct { @@ -179,6 +234,36 @@ func (e *MalformedPolicyDocumentException) ErrorCode() string { } func (e *MalformedPolicyDocumentException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The outbound web identity federation feature is not enabled for this account. +// To use this feature, you must first enable it through the Amazon Web Services +// Management Console or API. +type OutboundWebIdentityFederationDisabledException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *OutboundWebIdentityFederationDisabledException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "OutboundWebIdentityFederationDisabledException" + } + return *e.ErrorCodeOverride +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} + // The request was rejected because the total packed size of the session policies // and session tags combined was too large. An Amazon Web Services conversion // compresses the session policy document, session policy ARNs, and session tags @@ -221,7 +306,7 @@ func (e *PackedPolicyTooLargeException) ErrorFault() smithy.ErrorFault { return // console to activate STS in that region. For more information, see [Activating and Deactivating STS in an Amazon Web Services Region]in the IAM // User Guide. // -// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html +// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate type RegionDisabledException struct { Message *string @@ -246,3 +331,33 @@ func (e *RegionDisabledException) ErrorCode() string { return *e.ErrorCodeOverride } func (e *RegionDisabledException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// The requested token duration would extend the session beyond its original +// expiration time. You cannot use this operation to extend the lifetime of a +// session beyond what was granted when the session was originally created. +type SessionDurationEscalationException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *SessionDurationEscalationException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *SessionDurationEscalationException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *SessionDurationEscalationException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "SessionDurationEscalationException" + } + return *e.ErrorCodeOverride +} +func (e *SessionDurationEscalationException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go index 1026e22..4d37dd2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go @@ -130,6 +130,26 @@ func (m *validateOpGetAccessKeyInfo) HandleInitialize(ctx context.Context, in mi return next.HandleInitialize(ctx, in) } +type validateOpGetDelegatedAccessToken struct { +} + +func (*validateOpGetDelegatedAccessToken) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpGetDelegatedAccessToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpGetDelegatedAccessTokenInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + type validateOpGetFederationToken struct { } @@ -150,6 +170,26 @@ func (m *validateOpGetFederationToken) HandleInitialize(ctx context.Context, in return next.HandleInitialize(ctx, in) } +type validateOpGetWebIdentityToken struct { +} + +func (*validateOpGetWebIdentityToken) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpGetWebIdentityToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*GetWebIdentityTokenInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpGetWebIdentityTokenInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + func addOpAssumeRoleValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpAssumeRole{}, middleware.After) } @@ -174,10 +214,18 @@ func addOpGetAccessKeyInfoValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpGetAccessKeyInfo{}, middleware.After) } +func addOpGetDelegatedAccessTokenValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpGetDelegatedAccessToken{}, middleware.After) +} + func addOpGetFederationTokenValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpGetFederationToken{}, middleware.After) } +func addOpGetWebIdentityTokenValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpGetWebIdentityToken{}, middleware.After) +} + func validateTag(v *types.Tag) error { if v == nil { return nil @@ -326,6 +374,21 @@ func validateOpGetAccessKeyInfoInput(v *GetAccessKeyInfoInput) error { } } +func validateOpGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "GetDelegatedAccessTokenInput"} + if v.TradeInToken == nil { + invalidParams.Add(smithy.NewErrParamRequired("TradeInToken")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error { if v == nil { return nil @@ -345,3 +408,26 @@ func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error { return nil } } + +func validateOpGetWebIdentityTokenInput(v *GetWebIdentityTokenInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "GetWebIdentityTokenInput"} + if v.Audience == nil { + invalidParams.Add(smithy.NewErrParamRequired("Audience")) + } + if v.SigningAlgorithm == nil { + invalidParams.Add(smithy.NewErrParamRequired("SigningAlgorithm")) + } + if v.Tags != nil { + if err := validateTagListType(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md index de39171..80af245 100644 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ b/vendor/github.com/aws/smithy-go/CHANGELOG.md @@ -1,3 +1,72 @@ +# Release (2025-12-01) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.24.0 + * **Feature**: Improve allocation footprint of the middleware stack. This should convey a ~10% reduction in allocations per SDK request. + +# Release (2025-11-03) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.23.2 + * **Bug Fix**: Adjust the initial sizes of each middleware phase to avoid some unnecessary reallocation. + * **Bug Fix**: Avoid unnecessary allocation overhead from the metrics system when not in use. + +# Release (2025-10-15) + +## General Highlights +* **Dependency Update**: Bump minimum go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# Release (2025-09-18) + +## Module Highlights +* `github.com/aws/smithy-go/aws-http-auth`: [v1.1.0](aws-http-auth/CHANGELOG.md#v110-2025-09-18) + * **Feature**: Added support for SIG4/SIGV4A querystring authentication. + +# Release (2025-08-27) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.23.0 + * **Feature**: Sort map keys in JSON Document types. + +# Release (2025-07-24) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.5 + * **Feature**: Add HTTP interceptors. + +# Release (2025-06-16) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.4 + * **Bug Fix**: Fix CBOR serd empty check for string and enum fields + * **Bug Fix**: Fix HTTP metrics data race. + * **Bug Fix**: Replace usages of deprecated ioutil package. + +# Release (2025-02-17) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.3 + * **Dependency Update**: Bump minimum Go version to 1.22 per our language support policy. + # Release (2025-01-21) ## General Highlights diff --git a/vendor/github.com/aws/smithy-go/Makefile b/vendor/github.com/aws/smithy-go/Makefile index a3c2cf1..a12b124 100644 --- a/vendor/github.com/aws/smithy-go/Makefile +++ b/vendor/github.com/aws/smithy-go/Makefile @@ -13,6 +13,7 @@ REPOTOOLS_CMD_GENERATE_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/generatechangelog@${R REPOTOOLS_CMD_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} REPOTOOLS_CMD_TAG_RELEASE = ${REPOTOOLS_MODULE}/cmd/tagrelease@${REPOTOOLS_VERSION} REPOTOOLS_CMD_MODULE_VERSION = ${REPOTOOLS_MODULE}/cmd/moduleversion@${REPOTOOLS_VERSION} +REPOTOOLS_CMD_EACHMODULE = ${REPOTOOLS_MODULE}/cmd/eachmodule@${REPOTOOLS_VERSION} UNIT_TEST_TAGS= BUILD_TAGS= @@ -30,6 +31,24 @@ smithy-build: smithy-clean: cd codegen && ./gradlew clean +GRADLE_RETRIES := 3 +GRADLE_SLEEP := 2 + +# We're making a call to ./gradlew to trigger downloading Gradle and +# starting the daemon. Any call works, so using `./gradlew help` +ensure-gradle-up: + @cd codegen && for i in $(shell seq 1 $(GRADLE_RETRIES)); do \ + echo "Checking if Gradle daemon is up, attempt $$i..."; \ + if ./gradlew help; then \ + echo "Gradle daemon is up!"; \ + exit 0; \ + fi; \ + echo "Failed to start Gradle, retrying in $(GRADLE_SLEEP) seconds..."; \ + sleep $(GRADLE_SLEEP); \ + done; \ + echo "Failed to start Gradle after $(GRADLE_RETRIES) attempts."; \ + exit 1 + ################## # Linting/Verify # ################## @@ -37,8 +56,11 @@ smithy-clean: verify: vet -vet: - go vet ${BUILD_TAGS} --all ./... +vet: vet-modules-. + +vet-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst vet-modules-,,$@) \ + "go vet ${BUILD_TAGS} --all ./..." cover: go test ${BUILD_TAGS} -coverprofile c.out ./... @@ -48,23 +70,22 @@ cover: ################ # Unit Testing # ################ -.PHONY: unit unit-race unit-test unit-race-test +.PHONY: test unit unit-race -unit: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} ./... +test: unit-race -unit-race: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... +unit: verify unit-modules-. -unit-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} ./... +unit-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-modules-,,$@) \ + "go test -timeout=1m ${UNIT_TEST_TAGS} ./..." + +unit-race: verify unit-race-modules-. + +unit-race-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-race-modules-,,$@) \ + "go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./..." -unit-race-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... ##################### # Release Process # diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md index 08df745..ddce37b 100644 --- a/vendor/github.com/aws/smithy-go/README.md +++ b/vendor/github.com/aws/smithy-go/README.md @@ -4,19 +4,21 @@ [Smithy](https://smithy.io/) code generators for Go and the accompanying smithy-go runtime. -The smithy-go runtime requires a minimum version of Go 1.20. +The smithy-go runtime requires a minimum version of Go 1.23. **WARNING: All interfaces are subject to change.** -## Can I use the code generators? +## :no_entry_sign: DO NOT use the code generators in this repository + +**The code generators in this repository do not generate working clients at +this time.** In order to generate a usable smithy client you must provide a [protocol definition](https://github.com/aws/smithy-go/blob/main/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/ProtocolGenerator.java), such as [AWS restJson1](https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html), in order to generate transport mechanisms and serialization/deserialization code ("serde") accordingly. -The code generator does not currently support any protocols out of the box other than the new `smithy.protocols#rpcv2Cbor`, -therefore the useability of this project on its own is currently limited. +The code generator does not currently support any protocols out of the box. Support for all [AWS protocols](https://smithy.io/2.0/aws/protocols/index.html) exists in [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2). We are tracking the movement of those out of the SDK into smithy-go in @@ -31,6 +33,7 @@ This repository implements the following Smithy build plugins: |----|------------|-------------| | `go-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go client code generation for Smithy models. | | `go-server-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go server code generation for Smithy models. | +| `go-shape-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go shape code generation (types only) for Smithy models. | **NOTE: Build plugins are not currently published to mavenCentral. You must publish to mavenLocal to make the build plugins visible to the Smithy CLI. The artifact version is currently fixed at 0.1.0.** @@ -77,7 +80,7 @@ example created from `smithy init`: "service": "example.weather#Weather", "module": "github.com/example/weather", "generateGoMod": true, - "goDirective": "1.20" + "goDirective": "1.23" } } } @@ -87,6 +90,10 @@ example created from `smithy init`: This plugin is a work-in-progress and is currently undocumented. +## `go-shape-codegen` + +This plugin is a work-in-progress and is currently undocumented. + ## License This project is licensed under the Apache-2.0 License. diff --git a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go index a935283..f778272 100644 --- a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go +++ b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go @@ -9,7 +9,7 @@ import ( // Endpoint is the endpoint object returned by Endpoint resolution V2 type Endpoint struct { - // The complete URL minimally specfiying the scheme and host. + // The complete URL minimally specifying the scheme and host. // May optionally specify the port and base path component. URI url.URL diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go new file mode 100644 index 0000000..e24e190 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go @@ -0,0 +1,4 @@ +// Package rulesfn provides endpoint rule functions for evaluating endpoint +// resolution rules. + +package rulesfn diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go new file mode 100644 index 0000000..5cf4a7b --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go @@ -0,0 +1,25 @@ +package rulesfn + +// Substring returns the substring of the input provided. If the start or stop +// indexes are not valid for the input nil will be returned. If errors occur +// they will be added to the provided [ErrorCollector]. +func SubString(input string, start, stop int, reverse bool) *string { + if start < 0 || stop < 1 || start >= stop || len(input) < stop { + return nil + } + + for _, r := range input { + if r > 127 { + return nil + } + } + + if !reverse { + v := input[start:stop] + return &v + } + + rStart := len(input) - stop + rStop := len(input) - start + return SubString(input, rStart, rStop, false) +} diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go new file mode 100644 index 0000000..0c11541 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go @@ -0,0 +1,130 @@ +package rulesfn + +import ( + "fmt" + "net" + "net/url" + "strings" + + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// IsValidHostLabel returns if the input is a single valid [RFC 1123] host +// label. If allowSubDomains is true, will allow validation to include nested +// host labels. Returns false if the input is not a valid host label. If errors +// occur they will be added to the provided [ErrorCollector]. +// +// [RFC 1123]: https://www.ietf.org/rfc/rfc1123.txt +func IsValidHostLabel(input string, allowSubDomains bool) bool { + var labels []string + if allowSubDomains { + labels = strings.Split(input, ".") + } else { + labels = []string{input} + } + + for _, label := range labels { + if !smithyhttp.ValidHostLabel(label) { + return false + } + } + + return true +} + +// ParseURL returns a [URL] if the provided string could be parsed. Returns nil +// if the string could not be parsed. Any parsing error will be added to the +// [ErrorCollector]. +// +// If the input URL string contains an IP6 address with a zone index. The +// returned [builtin.URL.Authority] value will contain the percent escaped (%) +// zone index separator. +func ParseURL(input string) *URL { + u, err := url.Parse(input) + if err != nil { + return nil + } + + if u.RawQuery != "" { + return nil + } + + if u.Scheme != "http" && u.Scheme != "https" { + return nil + } + + normalizedPath := u.Path + if !strings.HasPrefix(normalizedPath, "/") { + normalizedPath = "/" + normalizedPath + } + if !strings.HasSuffix(normalizedPath, "/") { + normalizedPath = normalizedPath + "/" + } + + // IP6 hosts may have zone indexes that need to be escaped to be valid in a + // URI. The Go URL parser will unescape the `%25` into `%`. This needs to + // be reverted since the returned URL will be used in string builders. + authority := strings.ReplaceAll(u.Host, "%", "%25") + + return &URL{ + Scheme: u.Scheme, + Authority: authority, + Path: u.Path, + NormalizedPath: normalizedPath, + IsIp: net.ParseIP(hostnameWithoutZone(u)) != nil, + } +} + +// URL provides the structure describing the parts of a parsed URL returned by +// [ParseURL]. +type URL struct { + Scheme string // https://www.rfc-editor.org/rfc/rfc3986#section-3.1 + Authority string // https://www.rfc-editor.org/rfc/rfc3986#section-3.2 + Path string // https://www.rfc-editor.org/rfc/rfc3986#section-3.3 + NormalizedPath string // https://www.rfc-editor.org/rfc/rfc3986#section-6.2.3 + IsIp bool +} + +// URIEncode returns an percent-encoded [RFC3986 section 2.1] version of the +// input string. +// +// [RFC3986 section 2.1]: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 +func URIEncode(input string) string { + var output strings.Builder + for _, c := range []byte(input) { + if validPercentEncodedChar(c) { + output.WriteByte(c) + continue + } + + fmt.Fprintf(&output, "%%%X", c) + } + + return output.String() +} + +func validPercentEncodedChar(c byte) bool { + return (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || c == '_' || c == '.' || c == '~' +} + +// hostname implements u.Hostname() but strips the ipv6 zone ID (if present) +// such that net.ParseIP can still recognize IPv6 addresses with zone IDs. +// +// FUTURE(10/2023): netip.ParseAddr handles this natively but we can't take +// that package as a dependency yet due to our min go version (1.15, netip +// starts in 1.18). When we align with go runtime deprecation policy in +// 10/2023, we can remove this. +func hostnameWithoutZone(u *url.URL) string { + full := u.Hostname() + + // this more or less mimics the internals of net/ (see unexported + // splitHostZone in that source) but throws the zone away because we don't + // need it + if i := strings.LastIndex(full, "%"); i > -1 { + return full[:i] + } + return full +} diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go index a51ceca..b6c4c2f 100644 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ b/vendor/github.com/aws/smithy-go/go_module_metadata.go @@ -3,4 +3,4 @@ package smithy // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.22.2" +const goModuleVersion = "1.24.0" diff --git a/vendor/github.com/aws/smithy-go/metrics/nop.go b/vendor/github.com/aws/smithy-go/metrics/nop.go index fb374e1..444126d 100644 --- a/vendor/github.com/aws/smithy-go/metrics/nop.go +++ b/vendor/github.com/aws/smithy-go/metrics/nop.go @@ -9,54 +9,82 @@ var _ MeterProvider = (*NopMeterProvider)(nil) // Meter returns a meter which creates no-op instruments. func (NopMeterProvider) Meter(string, ...MeterOption) Meter { - return nopMeter{} + return NopMeter{} } -type nopMeter struct{} +// NopMeter creates no-op instruments. +type NopMeter struct{} -var _ Meter = (*nopMeter)(nil) +var _ Meter = (*NopMeter)(nil) -func (nopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) { - return nopInstrument[int64]{}, nil +// Int64Counter creates a no-op instrument. +func (NopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) { - return nopInstrument[int64]{}, nil + +// Int64UpDownCounter creates a no-op instrument. +func (NopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) { - return nopInstrument[int64]{}, nil + +// Int64Gauge creates a no-op instrument. +func (NopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) { - return nopInstrument[int64]{}, nil + +// Int64Histogram creates a no-op instrument. +func (NopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncCounter creates a no-op instrument. +func (NopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncUpDownCounter creates a no-op instrument. +func (NopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncGauge creates a no-op instrument. +func (NopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) { - return nopInstrument[float64]{}, nil + +// Float64Counter creates a no-op instrument. +func (NopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) { - return nopInstrument[float64]{}, nil + +// Float64UpDownCounter creates a no-op instrument. +func (NopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) { - return nopInstrument[float64]{}, nil + +// Float64Gauge creates a no-op instrument. +func (NopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) { - return nopInstrument[float64]{}, nil + +// Float64Histogram creates a no-op instrument. +func (NopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncCounter creates a no-op instrument. +func (NopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncUpDownCounter creates a no-op instrument. +func (NopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncGauge creates a no-op instrument. +func (NopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } type nopInstrument[N any] struct{} @@ -65,3 +93,6 @@ func (nopInstrument[N]) Add(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[N]) Sample(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[N]) Record(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[_]) Stop() {} + +var nopInstrumentInt64 = nopInstrument[int64]{} +var nopInstrumentFloat64 = nopInstrument[float64]{} diff --git a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go b/vendor/github.com/aws/smithy-go/middleware/ordered_group.go index 4b19530..daf9013 100644 --- a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go +++ b/vendor/github.com/aws/smithy-go/middleware/ordered_group.go @@ -23,12 +23,14 @@ type orderedIDs struct { items map[string]ider } -const baseOrderedItems = 5 +// selected based on the general upper bound of # of middlewares in each step +// in the downstream aws-sdk-go-v2 +const baseOrderedItems = 8 -func newOrderedIDs() *orderedIDs { +func newOrderedIDs(cap int) *orderedIDs { return &orderedIDs{ - order: newRelativeOrder(), - items: make(map[string]ider, baseOrderedItems), + order: newRelativeOrder(cap), + items: make(map[string]ider, cap), } } @@ -141,9 +143,9 @@ type relativeOrder struct { order []string } -func newRelativeOrder() *relativeOrder { +func newRelativeOrder(cap int) *relativeOrder { return &relativeOrder{ - order: make([]string, 0, baseOrderedItems), + order: make([]string, 0, cap), } } diff --git a/vendor/github.com/aws/smithy-go/middleware/step_build.go b/vendor/github.com/aws/smithy-go/middleware/step_build.go index 7e1d94c..db8c267 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_build.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_build.go @@ -1,7 +1,9 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware import ( "context" + "fmt" ) // BuildInput provides the input parameters for the BuildMiddleware to consume. @@ -25,14 +27,14 @@ type BuildHandler interface { } // BuildMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next BuildHandler for further +// build step. Delegates to the next BuildHandler for further // processing. type BuildMiddleware interface { - // Unique ID for the middleware in theBuildStep. The step does not allow - // duplicate IDs. + // ID returns a unique ID for the middleware in the BuildStep. The step does not + // allow duplicate IDs. ID() string - // Invokes the middleware behavior which must delegate to the next handler + // HandleBuild invokes the middleware behavior which must delegate to the next handler // for the middleware chain to continue. The method must return a result or // error to its caller. HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) ( @@ -54,7 +56,9 @@ type buildMiddlewareFunc struct { id string // Middleware function to be called. - fn func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error) + fn func(context.Context, BuildInput, BuildHandler) ( + BuildOutput, Metadata, error, + ) } // ID returns the unique ID for the middleware. @@ -69,23 +73,22 @@ func (s buildMiddlewareFunc) HandleBuild(ctx context.Context, in BuildInput, nex var _ BuildMiddleware = (buildMiddlewareFunc{}) -// BuildStep provides the ordered grouping of BuildMiddleware to be invoked on -// a handler. +// BuildStep provides the ordered grouping of BuildMiddleware to be +// invoked on a handler. type BuildStep struct { - ids *orderedIDs + head *decoratedBuildHandler + tail *decoratedBuildHandler } -// NewBuildStep returns a BuildStep ready to have middleware for -// initialization added to it. +// NewBuildStep returns an BuildStep ready to have middleware for +// build added to it. func NewBuildStep() *BuildStep { - return &BuildStep{ - ids: newOrderedIDs(), - } + return &BuildStep{} } var _ Middleware = (*BuildStep)(nil) -// ID returns the unique name of the step as a middleware. +// ID returns the unique ID of the step as a middleware. func (s *BuildStep) ID() string { return "Build stack step" } @@ -97,77 +100,161 @@ func (s *BuildStep) ID() string { func (s *BuildStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h BuildHandler = buildWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedBuildHandler{ - Next: h, - With: order[i].(BuildMiddleware), - } - } - sIn := BuildInput{ Request: in, } - res, metadata, err := h.HandleBuild(ctx, sIn) + wh := &buildWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleBuild(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleBuild(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *BuildStep) Get(id string) (BuildMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(BuildMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *BuildStep) Add(m BuildMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedBuildHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedBuildHandler{s.head, m} + } else { + tail := &decoratedBuildHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } -// Insert injects the middleware relative to an existing middleware id. -// Returns an error if the original middleware does not exist, or the middleware +// Insert injects the middleware relative to an existing middleware ID. +// Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *BuildStep) Insert(m BuildMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedBuildHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedBuildHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedBuildHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedBuildHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or an error if the middleware to be removed +// Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *BuildStep) Swap(id string, m BuildMiddleware) (BuildMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(BuildMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *BuildStep) Remove(id string) (BuildMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(BuildMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedBuildHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *BuildStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *buildWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedBuildHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *BuildStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *BuildStep) get(id string) (found, prev *decoratedBuildHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *buildWrapHandler + h, _ = h.Next.(*decoratedBuildHandler) + } + return } type buildWrapHandler struct { @@ -176,7 +263,7 @@ type buildWrapHandler struct { var _ BuildHandler = (*buildWrapHandler)(nil) -// Implements BuildHandler, converts types and delegates to underlying +// HandleBuild implements BuildHandler, converts types and delegates to underlying // generic handler. func (w buildWrapHandler) HandleBuild(ctx context.Context, in BuildInput) ( out BuildOutput, metadata Metadata, err error, @@ -200,12 +287,12 @@ func (h decoratedBuildHandler) HandleBuild(ctx context.Context, in BuildInput) ( return h.With.HandleBuild(ctx, in, h.Next) } -// BuildHandlerFunc provides a wrapper around a function to be used as a build middleware handler. +// BuildHandlerFunc provides a wrapper around a function to be used as buildMiddleware. type BuildHandlerFunc func(context.Context, BuildInput) (BuildOutput, Metadata, error) -// HandleBuild invokes the wrapped function with the provided arguments. -func (b BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) { - return b(ctx, in) +// HandleBuild calls the wrapped function with the provided arguments. +func (f BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) { + return f(ctx, in) } var _ BuildHandler = BuildHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go b/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go index 4486072..1f337f2 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go @@ -1,7 +1,9 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware import ( "context" + "fmt" ) // DeserializeInput provides the input parameters for the DeserializeInput to @@ -11,10 +13,7 @@ type DeserializeInput struct { Request interface{} } -// DeserializeOutput provides the result returned by the next -// DeserializeHandler. The DeserializeMiddleware should deserialize the -// RawResponse into a Result that can be consumed by middleware higher up in -// the stack. +// DeserializeOutput provides the result returned by the next DeserializeHandler. type DeserializeOutput struct { RawResponse interface{} Result interface{} @@ -29,7 +28,7 @@ type DeserializeHandler interface { } // DeserializeMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next DeserializeHandler for further +// deserialize step. Delegates to the next DeserializeHandler for further // processing. type DeserializeMiddleware interface { // ID returns a unique ID for the middleware in the DeserializeStep. The step does not @@ -44,8 +43,8 @@ type DeserializeMiddleware interface { ) } -// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID -// provided, and the func to be invoked. +// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID provided, +// and the func to be invoked. func DeserializeMiddlewareFunc(id string, fn func(context.Context, DeserializeInput, DeserializeHandler) (DeserializeOutput, Metadata, error)) DeserializeMiddleware { return deserializeMiddlewareFunc{ id: id, @@ -78,15 +77,14 @@ var _ DeserializeMiddleware = (deserializeMiddlewareFunc{}) // DeserializeStep provides the ordered grouping of DeserializeMiddleware to be // invoked on a handler. type DeserializeStep struct { - ids *orderedIDs + head *decoratedDeserializeHandler + tail *decoratedDeserializeHandler } -// NewDeserializeStep returns a DeserializeStep ready to have middleware for -// initialization added to it. +// NewDeserializeStep returns an DeserializeStep ready to have middleware for +// deserialize added to it. func NewDeserializeStep() *DeserializeStep { - return &DeserializeStep{ - ids: newOrderedIDs(), - } + return &DeserializeStep{} } var _ Middleware = (*DeserializeStep)(nil) @@ -103,77 +101,161 @@ func (s *DeserializeStep) ID() string { func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h DeserializeHandler = deserializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedDeserializeHandler{ - Next: h, - With: order[i].(DeserializeMiddleware), - } - } - sIn := DeserializeInput{ Request: in, } - res, metadata, err := h.HandleDeserialize(ctx, sIn) + wh := &deserializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleDeserialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleDeserialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(DeserializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedDeserializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedDeserializeHandler{s.head, m} + } else { + tail := &decoratedDeserializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedDeserializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedDeserializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedDeserializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedDeserializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(DeserializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(DeserializeMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedDeserializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *DeserializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *deserializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedDeserializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *DeserializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *DeserializeStep) get(id string) (found, prev *decoratedDeserializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *deserializeWrapHandler + h, _ = h.Next.(*decoratedDeserializeHandler) + } + return } type deserializeWrapHandler struct { @@ -187,9 +269,10 @@ var _ DeserializeHandler = (*deserializeWrapHandler)(nil) func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) ( out DeserializeOutput, metadata Metadata, err error, ) { - resp, metadata, err := w.Next.Handle(ctx, in.Request) + res, metadata, err := w.Next.Handle(ctx, in.Request) return DeserializeOutput{ - RawResponse: resp, + RawResponse: res, + Result: nil, }, metadata, err } @@ -206,12 +289,12 @@ func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in D return h.With.HandleDeserialize(ctx, in, h.Next) } -// DeserializeHandlerFunc provides a wrapper around a function to be used as a deserialize middleware handler. +// DeserializeHandlerFunc provides a wrapper around a function to be used as deserializeMiddleware. type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error) -// HandleDeserialize invokes the wrapped function with the given arguments. -func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) { - return d(ctx, in) +// HandleDeserialize calls the wrapped function with the provided arguments. +func (f DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) { + return f(ctx, in) } var _ DeserializeHandler = DeserializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go b/vendor/github.com/aws/smithy-go/middleware/step_finalize.go index 065e388..1a0ad9f 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_finalize.go @@ -1,6 +1,10 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // FinalizeInput provides the input parameters for the FinalizeMiddleware to // consume. FinalizeMiddleware may modify the Request value before forwarding @@ -23,7 +27,7 @@ type FinalizeHandler interface { } // FinalizeMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next FinalizeHandler for further +// finalize step. Delegates to the next FinalizeHandler for further // processing. type FinalizeMiddleware interface { // ID returns a unique ID for the middleware in the FinalizeStep. The step does not @@ -38,8 +42,8 @@ type FinalizeMiddleware interface { ) } -// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID -// provided, and the func to be invoked. +// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID provided, +// and the func to be invoked. func FinalizeMiddlewareFunc(id string, fn func(context.Context, FinalizeInput, FinalizeHandler) (FinalizeOutput, Metadata, error)) FinalizeMiddleware { return finalizeMiddlewareFunc{ id: id, @@ -72,20 +76,19 @@ var _ FinalizeMiddleware = (finalizeMiddlewareFunc{}) // FinalizeStep provides the ordered grouping of FinalizeMiddleware to be // invoked on a handler. type FinalizeStep struct { - ids *orderedIDs + head *decoratedFinalizeHandler + tail *decoratedFinalizeHandler } -// NewFinalizeStep returns a FinalizeStep ready to have middleware for -// initialization added to it. +// NewFinalizeStep returns an FinalizeStep ready to have middleware for +// finalize added to it. func NewFinalizeStep() *FinalizeStep { - return &FinalizeStep{ - ids: newOrderedIDs(), - } + return &FinalizeStep{} } var _ Middleware = (*FinalizeStep)(nil) -// ID returns the unique id of the step as a middleware. +// ID returns the unique ID of the step as a middleware. func (s *FinalizeStep) ID() string { return "Finalize stack step" } @@ -97,77 +100,161 @@ func (s *FinalizeStep) ID() string { func (s *FinalizeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h FinalizeHandler = finalizeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedFinalizeHandler{ - Next: h, - With: order[i].(FinalizeMiddleware), - } - } - sIn := FinalizeInput{ Request: in, } - res, metadata, err := h.HandleFinalize(ctx, sIn) + wh := &finalizeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleFinalize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleFinalize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *FinalizeStep) Get(id string) (FinalizeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(FinalizeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *FinalizeStep) Add(m FinalizeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedFinalizeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedFinalizeHandler{s.head, m} + } else { + tail := &decoratedFinalizeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *FinalizeStep) Insert(m FinalizeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedFinalizeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedFinalizeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedFinalizeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedFinalizeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *FinalizeStep) Swap(id string, m FinalizeMiddleware) (FinalizeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(FinalizeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *FinalizeStep) Remove(id string) (FinalizeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(FinalizeMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedFinalizeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *FinalizeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *finalizeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedFinalizeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *FinalizeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *FinalizeStep) get(id string) (found, prev *decoratedFinalizeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *finalizeWrapHandler + h, _ = h.Next.(*decoratedFinalizeHandler) + } + return } type finalizeWrapHandler struct { @@ -200,10 +287,10 @@ func (h decoratedFinalizeHandler) HandleFinalize(ctx context.Context, in Finaliz return h.With.HandleFinalize(ctx, in, h.Next) } -// FinalizeHandlerFunc provides a wrapper around a function to be used as a finalize middleware handler. +// FinalizeHandlerFunc provides a wrapper around a function to be used as finalizeMiddleware. type FinalizeHandlerFunc func(context.Context, FinalizeInput) (FinalizeOutput, Metadata, error) -// HandleFinalize invokes the wrapped function with the given arguments. +// HandleFinalize calls the wrapped function with the provided arguments. func (f FinalizeHandlerFunc) HandleFinalize(ctx context.Context, in FinalizeInput) (FinalizeOutput, Metadata, error) { return f(ctx, in) } diff --git a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go b/vendor/github.com/aws/smithy-go/middleware/step_initialize.go index fe35914..446f3b7 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_initialize.go @@ -1,10 +1,15 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // InitializeInput wraps the input parameters for the InitializeMiddlewares to // consume. InitializeMiddleware may modify the parameter value before // forwarding it along to the next InitializeHandler. + type InitializeInput struct { Parameters interface{} } @@ -72,15 +77,14 @@ var _ InitializeMiddleware = (initializeMiddlewareFunc{}) // InitializeStep provides the ordered grouping of InitializeMiddleware to be // invoked on a handler. type InitializeStep struct { - ids *orderedIDs + head *decoratedInitializeHandler + tail *decoratedInitializeHandler } // NewInitializeStep returns an InitializeStep ready to have middleware for -// initialization added to it. +// initialize added to it. func NewInitializeStep() *InitializeStep { - return &InitializeStep{ - ids: newOrderedIDs(), - } + return &InitializeStep{} } var _ Middleware = (*InitializeStep)(nil) @@ -97,77 +101,161 @@ func (s *InitializeStep) ID() string { func (s *InitializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h InitializeHandler = initializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedInitializeHandler{ - Next: h, - With: order[i].(InitializeMiddleware), - } - } - sIn := InitializeInput{ Parameters: in, } - res, metadata, err := h.HandleInitialize(ctx, sIn) + wh := &initializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleInitialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleInitialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *InitializeStep) Get(id string) (InitializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(InitializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *InitializeStep) Add(m InitializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedInitializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedInitializeHandler{s.head, m} + } else { + tail := &decoratedInitializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *InitializeStep) Insert(m InitializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedInitializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedInitializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedInitializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedInitializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *InitializeStep) Swap(id string, m InitializeMiddleware) (InitializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(InitializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *InitializeStep) Remove(id string) (InitializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(InitializeMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedInitializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *InitializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *initializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedInitializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *InitializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *InitializeStep) get(id string) (found, prev *decoratedInitializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *initializeWrapHandler + h, _ = h.Next.(*decoratedInitializeHandler) + } + return } type initializeWrapHandler struct { @@ -200,12 +288,12 @@ func (h decoratedInitializeHandler) HandleInitialize(ctx context.Context, in Ini return h.With.HandleInitialize(ctx, in, h.Next) } -// InitializeHandlerFunc provides a wrapper around a function to be used as an initialize middleware handler. +// InitializeHandlerFunc provides a wrapper around a function to be used as initializeMiddleware. type InitializeHandlerFunc func(context.Context, InitializeInput) (InitializeOutput, Metadata, error) // HandleInitialize calls the wrapped function with the provided arguments. -func (i InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) { - return i(ctx, in) +func (f InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) { + return f(ctx, in) } var _ InitializeHandler = InitializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go b/vendor/github.com/aws/smithy-go/middleware/step_serialize.go index 114bafc..942ebb4 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_serialize.go @@ -1,6 +1,10 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // SerializeInput provides the input parameters for the SerializeMiddleware to // consume. SerializeMiddleware may modify the Request value before forwarding @@ -41,8 +45,8 @@ type SerializeMiddleware interface { ) } -// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID -// provided, and the func to be invoked. +// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID provided, +// and the func to be invoked. func SerializeMiddlewareFunc(id string, fn func(context.Context, SerializeInput, SerializeHandler) (SerializeOutput, Metadata, error)) SerializeMiddleware { return serializeMiddlewareFunc{ id: id, @@ -75,17 +79,15 @@ var _ SerializeMiddleware = (serializeMiddlewareFunc{}) // SerializeStep provides the ordered grouping of SerializeMiddleware to be // invoked on a handler. type SerializeStep struct { + head *decoratedSerializeHandler + tail *decoratedSerializeHandler newRequest func() interface{} - ids *orderedIDs } -// NewSerializeStep returns a SerializeStep ready to have middleware for -// initialization added to it. The newRequest func parameter is used to -// initialize the transport specific request for the stack SerializeStep to -// serialize the input parameters into. +// NewSerializeStep returns an SerializeStep ready to have middleware for +// serialize added to it. func NewSerializeStep(newRequest func() interface{}) *SerializeStep { return &SerializeStep{ - ids: newOrderedIDs(), newRequest: newRequest, } } @@ -104,78 +106,162 @@ func (s *SerializeStep) ID() string { func (s *SerializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h SerializeHandler = serializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedSerializeHandler{ - Next: h, - With: order[i].(SerializeMiddleware), - } - } - sIn := SerializeInput{ Parameters: in, Request: s.newRequest(), } - res, metadata, err := h.HandleSerialize(ctx, sIn) + wh := &serializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleSerialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleSerialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *SerializeStep) Get(id string) (SerializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(SerializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *SerializeStep) Add(m SerializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedSerializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedSerializeHandler{s.head, m} + } else { + tail := &decoratedSerializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *SerializeStep) Insert(m SerializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedSerializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedSerializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedSerializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedSerializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *SerializeStep) Swap(id string, m SerializeMiddleware) (SerializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(SerializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *SerializeStep) Remove(id string) (SerializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(SerializeMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedSerializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *SerializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *serializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedSerializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *SerializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *SerializeStep) get(id string) (found, prev *decoratedSerializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *serializeWrapHandler + h, _ = h.Next.(*decoratedSerializeHandler) + } + return } type serializeWrapHandler struct { @@ -184,7 +270,7 @@ type serializeWrapHandler struct { var _ SerializeHandler = (*serializeWrapHandler)(nil) -// Implements SerializeHandler, converts types and delegates to underlying +// HandleSerialize implements SerializeHandler, converts types and delegates to underlying // generic handler. func (w serializeWrapHandler) HandleSerialize(ctx context.Context, in SerializeInput) ( out SerializeOutput, metadata Metadata, err error, @@ -208,12 +294,12 @@ func (h decoratedSerializeHandler) HandleSerialize(ctx context.Context, in Seria return h.With.HandleSerialize(ctx, in, h.Next) } -// SerializeHandlerFunc provides a wrapper around a function to be used as a serialize middleware handler. +// SerializeHandlerFunc provides a wrapper around a function to be used as serializeMiddleware. type SerializeHandlerFunc func(context.Context, SerializeInput) (SerializeOutput, Metadata, error) // HandleSerialize calls the wrapped function with the provided arguments. -func (s SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) { - return s(ctx, in) +func (f SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) { + return f(ctx, in) } var _ SerializeHandler = SerializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/modman.toml b/vendor/github.com/aws/smithy-go/modman.toml index 9d94b7c..aac582f 100644 --- a/vendor/github.com/aws/smithy-go/modman.toml +++ b/vendor/github.com/aws/smithy-go/modman.toml @@ -1,5 +1,4 @@ [dependencies] - "github.com/jmespath/go-jmespath" = "v0.4.0" [modules] diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor.go new file mode 100644 index 0000000..e21f263 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/transport/http/interceptor.go @@ -0,0 +1,321 @@ +package http + +import ( + "context" +) + +func icopy[T any](v []T) []T { + s := make([]T, len(v)) + copy(s, v) + return s +} + +// InterceptorContext is all the information available in different +// interceptors. +// +// Not all information is available in each interceptor, see each interface +// definition for more details. +type InterceptorContext struct { + Input any + Request *Request + + Output any + Response *Response +} + +// InterceptorRegistry holds a list of operation interceptors. +// +// Interceptors allow callers to insert custom behavior at well-defined points +// within a client's operation lifecycle. +// +// # Interceptor context +// +// All interceptors are invoked with a context object that contains input and +// output containers for the operation. The individual fields that are +// available will depend on what the interceptor is and, in certain +// interceptors, how far the operation was able to progress. See the +// documentation for each interface definition for more information about field +// availability. +// +// Implementations MUST NOT directly mutate the values of the fields in the +// interceptor context. They are free to mutate the existing values _pointed +// to_ by those fields, however. +// +// # Returning errors +// +// All interceptors can return errors. If an interceptor returns an error +// _before_ the client's retry loop, the operation will fail immediately. If +// one returns an error _within_ the retry loop, the error WILL be considered +// according to the client's retry policy. +// +// # Adding interceptors +// +// Idiomatically you will simply use one of the Add() receiver methods to +// register interceptors as desired. However, the list for each interface is +// exported on the registry struct and the caller is free to manipulate it +// directly, for example, to register a number of interceptors all at once, or +// to remove one that was previously registered. +// +// The base SDK client WILL NOT add any interceptors. SDK operations and +// customizations are implemented in terms of middleware. +// +// Modifications to the registry will not persist across operation calls when +// using per-operation functional options. This means you can register +// interceptors on a per-operation basis without affecting other operations. +type InterceptorRegistry struct { + BeforeExecution []BeforeExecutionInterceptor + BeforeSerialization []BeforeSerializationInterceptor + AfterSerialization []AfterSerializationInterceptor + BeforeRetryLoop []BeforeRetryLoopInterceptor + BeforeAttempt []BeforeAttemptInterceptor + BeforeSigning []BeforeSigningInterceptor + AfterSigning []AfterSigningInterceptor + BeforeTransmit []BeforeTransmitInterceptor + AfterTransmit []AfterTransmitInterceptor + BeforeDeserialization []BeforeDeserializationInterceptor + AfterDeserialization []AfterDeserializationInterceptor + AfterAttempt []AfterAttemptInterceptor + AfterExecution []AfterExecutionInterceptor +} + +// Copy returns a deep copy of the registry. This is used by SDK clients on +// each operation call in order to prevent per-op config mutation from +// persisting. +func (i *InterceptorRegistry) Copy() InterceptorRegistry { + return InterceptorRegistry{ + BeforeExecution: icopy(i.BeforeExecution), + BeforeSerialization: icopy(i.BeforeSerialization), + AfterSerialization: icopy(i.AfterSerialization), + BeforeRetryLoop: icopy(i.BeforeRetryLoop), + BeforeAttempt: icopy(i.BeforeAttempt), + BeforeSigning: icopy(i.BeforeSigning), + AfterSigning: icopy(i.AfterSigning), + BeforeTransmit: icopy(i.BeforeTransmit), + AfterTransmit: icopy(i.AfterTransmit), + BeforeDeserialization: icopy(i.BeforeDeserialization), + AfterDeserialization: icopy(i.AfterDeserialization), + AfterAttempt: icopy(i.AfterAttempt), + AfterExecution: icopy(i.AfterExecution), + } +} + +// AddBeforeExecution registers the provided BeforeExecutionInterceptor. +func (i *InterceptorRegistry) AddBeforeExecution(v BeforeExecutionInterceptor) { + i.BeforeExecution = append(i.BeforeExecution, v) +} + +// AddBeforeSerialization registers the provided BeforeSerializationInterceptor. +func (i *InterceptorRegistry) AddBeforeSerialization(v BeforeSerializationInterceptor) { + i.BeforeSerialization = append(i.BeforeSerialization, v) +} + +// AddAfterSerialization registers the provided AfterSerializationInterceptor. +func (i *InterceptorRegistry) AddAfterSerialization(v AfterSerializationInterceptor) { + i.AfterSerialization = append(i.AfterSerialization, v) +} + +// AddBeforeRetryLoop registers the provided BeforeRetryLoopInterceptor. +func (i *InterceptorRegistry) AddBeforeRetryLoop(v BeforeRetryLoopInterceptor) { + i.BeforeRetryLoop = append(i.BeforeRetryLoop, v) +} + +// AddBeforeAttempt registers the provided BeforeAttemptInterceptor. +func (i *InterceptorRegistry) AddBeforeAttempt(v BeforeAttemptInterceptor) { + i.BeforeAttempt = append(i.BeforeAttempt, v) +} + +// AddBeforeSigning registers the provided BeforeSigningInterceptor. +func (i *InterceptorRegistry) AddBeforeSigning(v BeforeSigningInterceptor) { + i.BeforeSigning = append(i.BeforeSigning, v) +} + +// AddAfterSigning registers the provided AfterSigningInterceptor. +func (i *InterceptorRegistry) AddAfterSigning(v AfterSigningInterceptor) { + i.AfterSigning = append(i.AfterSigning, v) +} + +// AddBeforeTransmit registers the provided BeforeTransmitInterceptor. +func (i *InterceptorRegistry) AddBeforeTransmit(v BeforeTransmitInterceptor) { + i.BeforeTransmit = append(i.BeforeTransmit, v) +} + +// AddAfterTransmit registers the provided AfterTransmitInterceptor. +func (i *InterceptorRegistry) AddAfterTransmit(v AfterTransmitInterceptor) { + i.AfterTransmit = append(i.AfterTransmit, v) +} + +// AddBeforeDeserialization registers the provided BeforeDeserializationInterceptor. +func (i *InterceptorRegistry) AddBeforeDeserialization(v BeforeDeserializationInterceptor) { + i.BeforeDeserialization = append(i.BeforeDeserialization, v) +} + +// AddAfterDeserialization registers the provided AfterDeserializationInterceptor. +func (i *InterceptorRegistry) AddAfterDeserialization(v AfterDeserializationInterceptor) { + i.AfterDeserialization = append(i.AfterDeserialization, v) +} + +// AddAfterAttempt registers the provided AfterAttemptInterceptor. +func (i *InterceptorRegistry) AddAfterAttempt(v AfterAttemptInterceptor) { + i.AfterAttempt = append(i.AfterAttempt, v) +} + +// AddAfterExecution registers the provided AfterExecutionInterceptor. +func (i *InterceptorRegistry) AddAfterExecution(v AfterExecutionInterceptor) { + i.AfterExecution = append(i.AfterExecution, v) +} + +// BeforeExecutionInterceptor runs before anything else in the operation +// lifecycle. +// +// Available InterceptorContext fields: +// - Input +type BeforeExecutionInterceptor interface { + BeforeExecution(ctx context.Context, in *InterceptorContext) error +} + +// BeforeSerializationInterceptor runs before the operation input is serialized +// into its transport request. +// +// Serialization occurs before the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +type BeforeSerializationInterceptor interface { + BeforeSerialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterSerializationInterceptor runs after the operation input is serialized +// into its transport request. +// +// Available InterceptorContext fields: +// - Input +// - Request +type AfterSerializationInterceptor interface { + AfterSerialization(ctx context.Context, in *InterceptorContext) error +} + +// BeforeRetryLoopInterceptor runs right before the operation enters the retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeRetryLoopInterceptor interface { + BeforeRetryLoop(ctx context.Context, in *InterceptorContext) error +} + +// BeforeAttemptInterceptor runs right before every attempt in the retry loop. +// +// If this interceptor returns an error, AfterAttempt interceptors WILL NOT be +// invoked. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeAttemptInterceptor interface { + BeforeAttempt(ctx context.Context, in *InterceptorContext) error +} + +// BeforeSigningInterceptor runs right before the request is signed. +// +// Signing occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeSigningInterceptor interface { + BeforeSigning(ctx context.Context, in *InterceptorContext) error +} + +// AfterSigningInterceptor runs right after the request is signed. +// +// It is unsafe to modify the outgoing HTTP request at or past this hook, since +// doing so may invalidate the signature of the request. +// +// Available InterceptorContext fields: +// - Input +// - Request +type AfterSigningInterceptor interface { + AfterSigning(ctx context.Context, in *InterceptorContext) error +} + +// BeforeTransmitInterceptor runs right before the HTTP request is sent. +// +// HTTP transmit occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeTransmitInterceptor interface { + BeforeTransmit(ctx context.Context, in *InterceptorContext) error +} + +// AfterTransmitInterceptor runs right after the HTTP response is received. +// +// It will always be invoked when a response is received, regardless of its +// status code. Conversely, it WILL NOT be invoked if the HTTP round-trip was +// not successful, e.g. because of a DNS resolution error +// +// Available InterceptorContext fields: +// - Input +// - Request +// - Response +type AfterTransmitInterceptor interface { + AfterTransmit(ctx context.Context, in *InterceptorContext) error +} + +// BeforeDeserializationInterceptor runs right before the incoming HTTP response +// is deserialized. +// +// This interceptor IS NOT invoked if the HTTP round-trip was not successful. +// +// Deserialization occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +// - Response +type BeforeDeserializationInterceptor interface { + BeforeDeserialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterDeserializationInterceptor runs right after the incoming HTTP response +// is deserialized. This hook is invoked regardless of whether the deserialized +// result was an error. +// +// This interceptor IS NOT invoked if the HTTP round-trip was not successful. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request +// - Response +type AfterDeserializationInterceptor interface { + AfterDeserialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterAttemptInterceptor runs right after the incoming HTTP response +// is deserialized. This hook is invoked regardless of whether the deserialized +// result was an error, or if another interceptor within the retry loop +// returned an error. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request (IF the operation did not return an error during serialization) +// - Response (IF the operation was able to transmit the HTTP request) +type AfterAttemptInterceptor interface { + AfterAttempt(ctx context.Context, in *InterceptorContext) error +} + +// AfterExecutionInterceptor runs after everything else. It runs regardless of +// how far the operation progressed in its lifecycle, and regardless of whether +// the operation succeeded or failed. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request (IF the operation did not return an error during serialization) +// - Response (IF the operation was able to transmit the HTTP request) +type AfterExecutionInterceptor interface { + AfterExecution(ctx context.Context, in *InterceptorContext) error +} diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go new file mode 100644 index 0000000..2cc4b57 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go @@ -0,0 +1,325 @@ +package http + +import ( + "context" + "errors" + + "github.com/aws/smithy-go/middleware" +) + +type ictxKey struct{} + +func withIctx(ctx context.Context) context.Context { + return middleware.WithStackValue(ctx, ictxKey{}, &InterceptorContext{}) +} + +func getIctx(ctx context.Context) *InterceptorContext { + return middleware.GetStackValue(ctx, ictxKey{}).(*InterceptorContext) +} + +// InterceptExecution runs Before/AfterExecutionInterceptors. +type InterceptExecution struct { + BeforeExecution []BeforeExecutionInterceptor + AfterExecution []AfterExecutionInterceptor +} + +// ID identifies the middleware. +func (m *InterceptExecution) ID() string { + return "InterceptExecution" +} + +// HandleInitialize runs the interceptors. +func (m *InterceptExecution) HandleInitialize( + ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, +) ( + out middleware.InitializeOutput, md middleware.Metadata, err error, +) { + ctx = withIctx(ctx) + getIctx(ctx).Input = in.Parameters + + for _, i := range m.BeforeExecution { + if err := i.BeforeExecution(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleInitialize(ctx, in) + + for _, i := range m.AfterExecution { + if err := i.AfterExecution(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptBeforeSerialization runs BeforeSerializationInterceptors. +type InterceptBeforeSerialization struct { + Interceptors []BeforeSerializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeSerialization) ID() string { + return "InterceptBeforeSerialization" +} + +// HandleSerialize runs the interceptors. +func (m *InterceptBeforeSerialization) HandleSerialize( + ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, +) ( + out middleware.SerializeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeSerialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleSerialize(ctx, in) +} + +// InterceptAfterSerialization runs AfterSerializationInterceptors. +type InterceptAfterSerialization struct { + Interceptors []AfterSerializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterSerialization) ID() string { + return "InterceptAfterSerialization" +} + +// HandleSerialize runs the interceptors. +func (m *InterceptAfterSerialization) HandleSerialize( + ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, +) ( + out middleware.SerializeOutput, md middleware.Metadata, err error, +) { + getIctx(ctx).Request = in.Request.(*Request) + + for _, i := range m.Interceptors { + if err := i.AfterSerialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleSerialize(ctx, in) +} + +// InterceptBeforeRetryLoop runs BeforeRetryLoopInterceptors. +type InterceptBeforeRetryLoop struct { + Interceptors []BeforeRetryLoopInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeRetryLoop) ID() string { + return "InterceptBeforeRetryLoop" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptBeforeRetryLoop) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeRetryLoop(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptBeforeSigning runs BeforeSigningInterceptors. +type InterceptBeforeSigning struct { + Interceptors []BeforeSigningInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeSigning) ID() string { + return "InterceptBeforeSigning" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptBeforeSigning) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeSigning(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptAfterSigning runs AfterSigningInterceptors. +type InterceptAfterSigning struct { + Interceptors []AfterSigningInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterSigning) ID() string { + return "InterceptAfterSigning" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptAfterSigning) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.AfterSigning(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptTransmit runs BeforeTransmitInterceptors and AfterTransmitInterceptors. +type InterceptTransmit struct { + BeforeTransmit []BeforeTransmitInterceptor + AfterTransmit []AfterTransmitInterceptor +} + +// ID identifies the middleware. +func (m *InterceptTransmit) ID() string { + return "InterceptTransmit" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptTransmit) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.BeforeTransmit { + if err := i.BeforeTransmit(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, md, err + } + + // the root of the decorated middleware guarantees this will be here + // (client.go: ClientHandler.Handle) + getIctx(ctx).Response = out.RawResponse.(*Response) + + for _, i := range m.AfterTransmit { + if err := i.AfterTransmit(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptBeforeDeserialization runs BeforeDeserializationInterceptors. +type InterceptBeforeDeserialization struct { + Interceptors []BeforeDeserializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeDeserialization) ID() string { + return "InterceptBeforeDeserialization" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptBeforeDeserialization) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + var terr *RequestSendError + if errors.As(err, &terr) { + return out, md, err + } + } + + for _, i := range m.Interceptors { + if err := i.BeforeDeserialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptAfterDeserialization runs AfterDeserializationInterceptors. +type InterceptAfterDeserialization struct { + Interceptors []AfterDeserializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterDeserialization) ID() string { + return "InterceptAfterDeserialization" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptAfterDeserialization) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + var terr *RequestSendError + if errors.As(err, &terr) { + return out, md, err + } + } + + getIctx(ctx).Output = out.Result + + for _, i := range m.Interceptors { + if err := i.AfterDeserialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptAttempt runs AfterAttemptInterceptors. +type InterceptAttempt struct { + BeforeAttempt []BeforeAttemptInterceptor + AfterAttempt []AfterAttemptInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAttempt) ID() string { + return "InterceptAttempt" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptAttempt) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.BeforeAttempt { + if err := i.BeforeAttempt(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleFinalize(ctx, in) + + for _, i := range m.AfterAttempt { + if err := i.AfterAttempt(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} diff --git a/vendor/github.com/aws/smithy-go/transport/http/metrics.go b/vendor/github.com/aws/smithy-go/transport/http/metrics.go index d1beaa5..b4cd4a4 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/metrics.go +++ b/vendor/github.com/aws/smithy-go/transport/http/metrics.go @@ -17,6 +17,12 @@ var now = time.Now func withMetrics(parent context.Context, client ClientDo, meter metrics.Meter) ( context.Context, ClientDo, error, ) { + // WithClientTrace is an expensive operation - avoid calling it if we're + // not actually using a metrics sink. + if _, ok := meter.(metrics.NopMeter); ok { + return parent, client, nil + } + hm, err := newHTTPMetrics(meter) if err != nil { return nil, nil, err diff --git a/vendor/github.com/aws/smithy-go/waiter/logger.go b/vendor/github.com/aws/smithy-go/waiter/logger.go deleted file mode 100644 index 8d70a03..0000000 --- a/vendor/github.com/aws/smithy-go/waiter/logger.go +++ /dev/null @@ -1,36 +0,0 @@ -package waiter - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// Logger is the Logger middleware used by the waiter to log an attempt -type Logger struct { - // Attempt is the current attempt to be logged - Attempt int64 -} - -// ID representing the Logger middleware -func (*Logger) ID() string { - return "WaiterLogger" -} - -// HandleInitialize performs handling of request in initialize stack step -func (m *Logger) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - logger := middleware.GetLogger(ctx) - - logger.Logf(logging.Debug, fmt.Sprintf("attempting waiter request, attempt count: %d", m.Attempt)) - - return next.HandleInitialize(ctx, in) -} - -// AddLogger is a helper util to add waiter logger after `SetLogger` middleware in -func (m Logger) AddLogger(stack *middleware.Stack) error { - return stack.Initialize.Insert(&m, "SetLogger", middleware.After) -} diff --git a/vendor/github.com/aws/smithy-go/waiter/waiter.go b/vendor/github.com/aws/smithy-go/waiter/waiter.go deleted file mode 100644 index 03e46e2..0000000 --- a/vendor/github.com/aws/smithy-go/waiter/waiter.go +++ /dev/null @@ -1,66 +0,0 @@ -package waiter - -import ( - "fmt" - "math" - "time" - - "github.com/aws/smithy-go/rand" -) - -// ComputeDelay computes delay between waiter attempts. The function takes in a current attempt count, -// minimum delay, maximum delay, and remaining wait time for waiter as input. The inputs minDelay and maxDelay -// must always be greater than 0, along with minDelay lesser than or equal to maxDelay. -// -// Returns the computed delay and if next attempt count is possible within the given input time constraints. -// Note that the zeroth attempt results in no delay. -func ComputeDelay(attempt int64, minDelay, maxDelay, remainingTime time.Duration) (delay time.Duration, err error) { - // zeroth attempt, no delay - if attempt <= 0 { - return 0, nil - } - - // remainingTime is zero or less, no delay - if remainingTime <= 0 { - return 0, nil - } - - // validate min delay is greater than 0 - if minDelay == 0 { - return 0, fmt.Errorf("minDelay must be greater than zero when computing Delay") - } - - // validate max delay is greater than 0 - if maxDelay == 0 { - return 0, fmt.Errorf("maxDelay must be greater than zero when computing Delay") - } - - // Get attempt ceiling to prevent integer overflow. - attemptCeiling := (math.Log(float64(maxDelay/minDelay)) / math.Log(2)) + 1 - - if attempt > int64(attemptCeiling) { - delay = maxDelay - } else { - // Compute exponential delay based on attempt. - ri := 1 << uint64(attempt-1) - // compute delay - delay = minDelay * time.Duration(ri) - } - - if delay != minDelay { - // randomize to get jitter between min delay and delay value - d, err := rand.CryptoRandInt63n(int64(delay - minDelay)) - if err != nil { - return 0, fmt.Errorf("error computing retry jitter, %w", err) - } - - delay = time.Duration(d) + minDelay - } - - // check if this is the last attempt possible and compute delay accordingly - if remainingTime-delay <= minDelay { - delay = remainingTime - minDelay - } - - return delay, nil -} diff --git a/vendor/github.com/coreos/go-iptables/LICENSE b/vendor/github.com/coreos/go-iptables/LICENSE deleted file mode 100644 index 37ec93a..0000000 --- a/vendor/github.com/coreos/go-iptables/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/coreos/go-iptables/NOTICE b/vendor/github.com/coreos/go-iptables/NOTICE deleted file mode 100644 index 23a0ada..0000000 --- a/vendor/github.com/coreos/go-iptables/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2018 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-iptables/iptables/iptables.go b/vendor/github.com/coreos/go-iptables/iptables/iptables.go deleted file mode 100644 index 6c5bbd7..0000000 --- a/vendor/github.com/coreos/go-iptables/iptables/iptables.go +++ /dev/null @@ -1,745 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 iptables - -import ( - "bytes" - "fmt" - "io" - "net" - "os/exec" - "regexp" - "strconv" - "strings" - "syscall" -) - -// Adds the output of stderr to exec.ExitError -type Error struct { - exec.ExitError - cmd exec.Cmd - msg string - exitStatus *int //for overriding -} - -func (e *Error) ExitStatus() int { - if e.exitStatus != nil { - return *e.exitStatus - } - return e.Sys().(syscall.WaitStatus).ExitStatus() -} - -func (e *Error) Error() string { - return fmt.Sprintf("running %v: exit status %v: %v", e.cmd.Args, e.ExitStatus(), e.msg) -} - -var isNotExistPatterns = []string{ - "Bad rule (does a matching rule exist in that chain?).\n", - "No chain/target/match by that name.\n", - "No such file or directory", - "does not exist", -} - -// IsNotExist returns true if the error is due to the chain or rule not existing -func (e *Error) IsNotExist() bool { - for _, str := range isNotExistPatterns { - if strings.Contains(e.msg, str) { - return true - } - } - return false -} - -// Protocol to differentiate between IPv4 and IPv6 -type Protocol byte - -const ( - ProtocolIPv4 Protocol = iota - ProtocolIPv6 -) - -type IPTables struct { - path string - proto Protocol - hasCheck bool - hasWait bool - waitSupportSecond bool - hasRandomFully bool - v1 int - v2 int - v3 int - mode string // the underlying iptables operating mode, e.g. nf_tables - timeout int // time to wait for the iptables lock, default waits forever -} - -// Stat represents a structured statistic entry. -type Stat struct { - Packets uint64 `json:"pkts"` - Bytes uint64 `json:"bytes"` - Target string `json:"target"` - Protocol string `json:"prot"` - Opt string `json:"opt"` - Input string `json:"in"` - Output string `json:"out"` - Source *net.IPNet `json:"source"` - Destination *net.IPNet `json:"destination"` - Options string `json:"options"` -} - -type option func(*IPTables) - -func IPFamily(proto Protocol) option { - return func(ipt *IPTables) { - ipt.proto = proto - } -} - -func Timeout(timeout int) option { - return func(ipt *IPTables) { - ipt.timeout = timeout - } -} - -func Path(path string) option { - return func(ipt *IPTables) { - ipt.path = path - } -} - -// New creates a new IPTables configured with the options passed as parameters. -// Supported parameters are: -// -// IPFamily(Protocol) -// Timeout(int) -// Path(string) -// -// For backwards compatibility, by default New uses IPv4 and timeout 0. -// i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing -// the IPFamily and Timeout options as follow: -// -// ip6t := New(IPFamily(ProtocolIPv6), Timeout(5)) -func New(opts ...option) (*IPTables, error) { - - ipt := &IPTables{ - proto: ProtocolIPv4, - timeout: 0, - path: "", - } - - for _, opt := range opts { - opt(ipt) - } - - // if path wasn't preset through New(Path()), autodiscover it - cmd := "" - if ipt.path == "" { - cmd = getIptablesCommand(ipt.proto) - } else { - cmd = ipt.path - } - path, err := exec.LookPath(cmd) - if err != nil { - return nil, err - } - ipt.path = path - - vstring, err := getIptablesVersionString(path) - if err != nil { - return nil, fmt.Errorf("could not get iptables version: %v", err) - } - v1, v2, v3, mode, err := extractIptablesVersion(vstring) - if err != nil { - return nil, fmt.Errorf("failed to extract iptables version from [%s]: %v", vstring, err) - } - ipt.v1 = v1 - ipt.v2 = v2 - ipt.v3 = v3 - ipt.mode = mode - - checkPresent, waitPresent, waitSupportSecond, randomFullyPresent := getIptablesCommandSupport(v1, v2, v3) - ipt.hasCheck = checkPresent - ipt.hasWait = waitPresent - ipt.waitSupportSecond = waitSupportSecond - ipt.hasRandomFully = randomFullyPresent - - return ipt, nil -} - -// New creates a new IPTables for the given proto. -// The proto will determine which command is used, either "iptables" or "ip6tables". -func NewWithProtocol(proto Protocol) (*IPTables, error) { - return New(IPFamily(proto), Timeout(0)) -} - -// Proto returns the protocol used by this IPTables. -func (ipt *IPTables) Proto() Protocol { - return ipt.proto -} - -// Exists checks if given rulespec in specified table/chain exists -func (ipt *IPTables) Exists(table, chain string, rulespec ...string) (bool, error) { - if !ipt.hasCheck { - return ipt.existsForOldIptables(table, chain, rulespec) - - } - cmd := append([]string{"-t", table, "-C", chain}, rulespec...) - err := ipt.run(cmd...) - eerr, eok := err.(*Error) - switch { - case err == nil: - return true, nil - case eok && eerr.ExitStatus() == 1: - return false, nil - default: - return false, err - } -} - -// Insert inserts rulespec to specified table/chain (in specified pos) -func (ipt *IPTables) Insert(table, chain string, pos int, rulespec ...string) error { - cmd := append([]string{"-t", table, "-I", chain, strconv.Itoa(pos)}, rulespec...) - return ipt.run(cmd...) -} - -// Replace replaces rulespec to specified table/chain (in specified pos) -func (ipt *IPTables) Replace(table, chain string, pos int, rulespec ...string) error { - cmd := append([]string{"-t", table, "-R", chain, strconv.Itoa(pos)}, rulespec...) - return ipt.run(cmd...) -} - -// InsertUnique acts like Insert except that it won't insert a duplicate (no matter the position in the chain) -func (ipt *IPTables) InsertUnique(table, chain string, pos int, rulespec ...string) error { - exists, err := ipt.Exists(table, chain, rulespec...) - if err != nil { - return err - } - - if !exists { - return ipt.Insert(table, chain, pos, rulespec...) - } - - return nil -} - -// Append appends rulespec to specified table/chain -func (ipt *IPTables) Append(table, chain string, rulespec ...string) error { - cmd := append([]string{"-t", table, "-A", chain}, rulespec...) - return ipt.run(cmd...) -} - -// AppendUnique acts like Append except that it won't add a duplicate -func (ipt *IPTables) AppendUnique(table, chain string, rulespec ...string) error { - exists, err := ipt.Exists(table, chain, rulespec...) - if err != nil { - return err - } - - if !exists { - return ipt.Append(table, chain, rulespec...) - } - - return nil -} - -// Delete removes rulespec in specified table/chain -func (ipt *IPTables) Delete(table, chain string, rulespec ...string) error { - cmd := append([]string{"-t", table, "-D", chain}, rulespec...) - return ipt.run(cmd...) -} - -func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) error { - exists, err := ipt.Exists(table, chain, rulespec...) - if err == nil && exists { - err = ipt.Delete(table, chain, rulespec...) - } - return err -} - -// List rules in specified table/chain -func (ipt *IPTables) ListById(table, chain string, id int) (string, error) { - args := []string{"-t", table, "-S", chain, strconv.Itoa(id)} - rule, err := ipt.executeList(args) - if err != nil { - return "", err - } - return rule[0], nil -} - -// List rules in specified table/chain -func (ipt *IPTables) List(table, chain string) ([]string, error) { - args := []string{"-t", table, "-S", chain} - return ipt.executeList(args) -} - -// List rules (with counters) in specified table/chain -func (ipt *IPTables) ListWithCounters(table, chain string) ([]string, error) { - args := []string{"-t", table, "-v", "-S", chain} - return ipt.executeList(args) -} - -// ListChains returns a slice containing the name of each chain in the specified table. -func (ipt *IPTables) ListChains(table string) ([]string, error) { - args := []string{"-t", table, "-S"} - - result, err := ipt.executeList(args) - if err != nil { - return nil, err - } - - // Iterate over rules to find all default (-P) and user-specified (-N) chains. - // Chains definition always come before rules. - // Format is the following: - // -P OUTPUT ACCEPT - // -N Custom - var chains []string - for _, val := range result { - if strings.HasPrefix(val, "-P") || strings.HasPrefix(val, "-N") { - chains = append(chains, strings.Fields(val)[1]) - } else { - break - } - } - return chains, nil -} - -// '-S' is fine with non existing rule index as long as the chain exists -// therefore pass index 1 to reduce overhead for large chains -func (ipt *IPTables) ChainExists(table, chain string) (bool, error) { - err := ipt.run("-t", table, "-S", chain, "1") - eerr, eok := err.(*Error) - switch { - case err == nil: - return true, nil - case eok && eerr.ExitStatus() == 1: - return false, nil - default: - return false, err - } -} - -// Stats lists rules including the byte and packet counts -func (ipt *IPTables) Stats(table, chain string) ([][]string, error) { - args := []string{"-t", table, "-L", chain, "-n", "-v", "-x"} - lines, err := ipt.executeList(args) - if err != nil { - return nil, err - } - - appendSubnet := func(addr string) string { - if strings.IndexByte(addr, byte('/')) < 0 { - if strings.IndexByte(addr, '.') < 0 { - return addr + "/128" - } - return addr + "/32" - } - return addr - } - - ipv6 := ipt.proto == ProtocolIPv6 - - // Skip the warning if exist - if strings.HasPrefix(lines[0], "#") { - lines = lines[1:] - } - - rows := [][]string{} - for i, line := range lines { - // Skip over chain name and field header - if i < 2 { - continue - } - - // Fields: - // 0=pkts 1=bytes 2=target 3=prot 4=opt 5=in 6=out 7=source 8=destination 9=options - line = strings.TrimSpace(line) - fields := strings.Fields(line) - - // The ip6tables verbose output cannot be naively split due to the default "opt" - // field containing 2 single spaces. - if ipv6 { - // Check if field 6 is "opt" or "source" address - dest := fields[6] - ip, _, _ := net.ParseCIDR(dest) - if ip == nil { - ip = net.ParseIP(dest) - } - - // If we detected a CIDR or IP, the "opt" field is empty.. insert it. - if ip != nil { - f := []string{} - f = append(f, fields[:4]...) - f = append(f, " ") // Empty "opt" field for ip6tables - f = append(f, fields[4:]...) - fields = f - } - } - - // Adjust "source" and "destination" to include netmask, to match regular - // List output - fields[7] = appendSubnet(fields[7]) - fields[8] = appendSubnet(fields[8]) - - // Combine "options" fields 9... into a single space-delimited field. - options := fields[9:] - fields = fields[:9] - fields = append(fields, strings.Join(options, " ")) - rows = append(rows, fields) - } - return rows, nil -} - -// ParseStat parses a single statistic row into a Stat struct. The input should -// be a string slice that is returned from calling the Stat method. -func (ipt *IPTables) ParseStat(stat []string) (parsed Stat, err error) { - // For forward-compatibility, expect at least 10 fields in the stat - if len(stat) < 10 { - return parsed, fmt.Errorf("stat contained fewer fields than expected") - } - - // Convert the fields that are not plain strings - parsed.Packets, err = strconv.ParseUint(stat[0], 0, 64) - if err != nil { - return parsed, fmt.Errorf(err.Error(), "could not parse packets") - } - parsed.Bytes, err = strconv.ParseUint(stat[1], 0, 64) - if err != nil { - return parsed, fmt.Errorf(err.Error(), "could not parse bytes") - } - _, parsed.Source, err = net.ParseCIDR(stat[7]) - if err != nil { - return parsed, fmt.Errorf(err.Error(), "could not parse source") - } - _, parsed.Destination, err = net.ParseCIDR(stat[8]) - if err != nil { - return parsed, fmt.Errorf(err.Error(), "could not parse destination") - } - - // Put the fields that are strings - parsed.Target = stat[2] - parsed.Protocol = stat[3] - parsed.Opt = stat[4] - parsed.Input = stat[5] - parsed.Output = stat[6] - parsed.Options = stat[9] - - return parsed, nil -} - -// StructuredStats returns statistics as structured data which may be further -// parsed and marshaled. -func (ipt *IPTables) StructuredStats(table, chain string) ([]Stat, error) { - rawStats, err := ipt.Stats(table, chain) - if err != nil { - return nil, err - } - - structStats := []Stat{} - for _, rawStat := range rawStats { - stat, err := ipt.ParseStat(rawStat) - if err != nil { - return nil, err - } - structStats = append(structStats, stat) - } - - return structStats, nil -} - -func (ipt *IPTables) executeList(args []string) ([]string, error) { - var stdout bytes.Buffer - if err := ipt.runWithOutput(args, &stdout); err != nil { - return nil, err - } - - rules := strings.Split(stdout.String(), "\n") - - // strip trailing newline - if len(rules) > 0 && rules[len(rules)-1] == "" { - rules = rules[:len(rules)-1] - } - - for i, rule := range rules { - rules[i] = filterRuleOutput(rule) - } - - return rules, nil -} - -// NewChain creates a new chain in the specified table. -// If the chain already exists, it will result in an error. -func (ipt *IPTables) NewChain(table, chain string) error { - return ipt.run("-t", table, "-N", chain) -} - -const existsErr = 1 - -// ClearChain flushed (deletes all rules) in the specified table/chain. -// If the chain does not exist, a new one will be created -func (ipt *IPTables) ClearChain(table, chain string) error { - err := ipt.NewChain(table, chain) - - eerr, eok := err.(*Error) - switch { - case err == nil: - return nil - case eok && eerr.ExitStatus() == existsErr: - // chain already exists. Flush (clear) it. - return ipt.run("-t", table, "-F", chain) - default: - return err - } -} - -// RenameChain renames the old chain to the new one. -func (ipt *IPTables) RenameChain(table, oldChain, newChain string) error { - return ipt.run("-t", table, "-E", oldChain, newChain) -} - -// DeleteChain deletes the chain in the specified table. -// The chain must be empty -func (ipt *IPTables) DeleteChain(table, chain string) error { - return ipt.run("-t", table, "-X", chain) -} - -func (ipt *IPTables) ClearAndDeleteChain(table, chain string) error { - exists, err := ipt.ChainExists(table, chain) - if err != nil || !exists { - return err - } - err = ipt.run("-t", table, "-F", chain) - if err == nil { - err = ipt.run("-t", table, "-X", chain) - } - return err -} - -func (ipt *IPTables) ClearAll() error { - return ipt.run("-F") -} - -func (ipt *IPTables) DeleteAll() error { - return ipt.run("-X") -} - -// ChangePolicy changes policy on chain to target -func (ipt *IPTables) ChangePolicy(table, chain, target string) error { - return ipt.run("-t", table, "-P", chain, target) -} - -// Check if the underlying iptables command supports the --random-fully flag -func (ipt *IPTables) HasRandomFully() bool { - return ipt.hasRandomFully -} - -// Return version components of the underlying iptables command -func (ipt *IPTables) GetIptablesVersion() (int, int, int) { - return ipt.v1, ipt.v2, ipt.v3 -} - -// run runs an iptables command with the given arguments, ignoring -// any stdout output -func (ipt *IPTables) run(args ...string) error { - return ipt.runWithOutput(args, nil) -} - -// runWithOutput runs an iptables command with the given arguments, -// writing any stdout output to the given writer -func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error { - args = append([]string{ipt.path}, args...) - if ipt.hasWait { - args = append(args, "--wait") - if ipt.timeout != 0 && ipt.waitSupportSecond { - args = append(args, strconv.Itoa(ipt.timeout)) - } - } else { - fmu, err := newXtablesFileLock() - if err != nil { - return err - } - ul, err := fmu.tryLock() - if err != nil { - syscall.Close(fmu.fd) - return err - } - defer func() { - _ = ul.Unlock() - }() - } - - var stderr bytes.Buffer - cmd := exec.Cmd{ - Path: ipt.path, - Args: args, - Stdout: stdout, - Stderr: &stderr, - } - - if err := cmd.Run(); err != nil { - switch e := err.(type) { - case *exec.ExitError: - return &Error{*e, cmd, stderr.String(), nil} - default: - return err - } - } - - return nil -} - -// getIptablesCommand returns the correct command for the given protocol, either "iptables" or "ip6tables". -func getIptablesCommand(proto Protocol) string { - if proto == ProtocolIPv6 { - return "ip6tables" - } else { - return "iptables" - } -} - -// Checks if iptables has the "-C" and "--wait" flag -func getIptablesCommandSupport(v1 int, v2 int, v3 int) (bool, bool, bool, bool) { - return iptablesHasCheckCommand(v1, v2, v3), iptablesHasWaitCommand(v1, v2, v3), iptablesWaitSupportSecond(v1, v2, v3), iptablesHasRandomFully(v1, v2, v3) -} - -// getIptablesVersion returns the first three components of the iptables version -// and the operating mode (e.g. nf_tables or legacy) -// e.g. "iptables v1.3.66" would return (1, 3, 66, legacy, nil) -func extractIptablesVersion(str string) (int, int, int, string, error) { - versionMatcher := regexp.MustCompile(`v([0-9]+)\.([0-9]+)\.([0-9]+)(?:\s+\((\w+))?`) - result := versionMatcher.FindStringSubmatch(str) - if result == nil { - return 0, 0, 0, "", fmt.Errorf("no iptables version found in string: %s", str) - } - - v1, err := strconv.Atoi(result[1]) - if err != nil { - return 0, 0, 0, "", err - } - - v2, err := strconv.Atoi(result[2]) - if err != nil { - return 0, 0, 0, "", err - } - - v3, err := strconv.Atoi(result[3]) - if err != nil { - return 0, 0, 0, "", err - } - - mode := "legacy" - if result[4] != "" { - mode = result[4] - } - return v1, v2, v3, mode, nil -} - -// Runs "iptables --version" to get the version string -func getIptablesVersionString(path string) (string, error) { - cmd := exec.Command(path, "--version") - var out bytes.Buffer - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return "", err - } - return out.String(), nil -} - -// Checks if an iptables version is after 1.4.11, when --check was added -func iptablesHasCheckCommand(v1 int, v2 int, v3 int) bool { - if v1 > 1 { - return true - } - if v1 == 1 && v2 > 4 { - return true - } - if v1 == 1 && v2 == 4 && v3 >= 11 { - return true - } - return false -} - -// Checks if an iptables version is after 1.4.20, when --wait was added -func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool { - if v1 > 1 { - return true - } - if v1 == 1 && v2 > 4 { - return true - } - if v1 == 1 && v2 == 4 && v3 >= 20 { - return true - } - return false -} - -// Checks if an iptablse version is after 1.6.0, when --wait support second -func iptablesWaitSupportSecond(v1 int, v2 int, v3 int) bool { - if v1 > 1 { - return true - } - if v1 == 1 && v2 >= 6 { - return true - } - return false -} - -// Checks if an iptables version is after 1.6.2, when --random-fully was added -func iptablesHasRandomFully(v1 int, v2 int, v3 int) bool { - if v1 > 1 { - return true - } - if v1 == 1 && v2 > 6 { - return true - } - if v1 == 1 && v2 == 6 && v3 >= 2 { - return true - } - return false -} - -// Checks if a rule specification exists for a table -func (ipt *IPTables) existsForOldIptables(table, chain string, rulespec []string) (bool, error) { - rs := strings.Join(append([]string{"-A", chain}, rulespec...), " ") - args := []string{"-t", table, "-S"} - var stdout bytes.Buffer - err := ipt.runWithOutput(args, &stdout) - if err != nil { - return false, err - } - return strings.Contains(stdout.String(), rs), nil -} - -// counterRegex is the regex used to detect nftables counter format -var counterRegex = regexp.MustCompile(`^\[([0-9]+):([0-9]+)\] `) - -// filterRuleOutput works around some inconsistencies in output. -// For example, when iptables is in legacy vs. nftables mode, it produces -// different results. -func filterRuleOutput(rule string) string { - out := rule - - // work around an output difference in nftables mode where counters - // are output in iptables-save format, rather than iptables -S format - // The string begins with "[0:0]" - // - // Fixes #49 - if groups := counterRegex.FindStringSubmatch(out); groups != nil { - // drop the brackets - out = out[len(groups[0]):] - out = fmt.Sprintf("%s -c %s %s", out, groups[1], groups[2]) - } - - return out -} diff --git a/vendor/github.com/coreos/go-iptables/iptables/lock.go b/vendor/github.com/coreos/go-iptables/iptables/lock.go deleted file mode 100644 index a88e92b..0000000 --- a/vendor/github.com/coreos/go-iptables/iptables/lock.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 iptables - -import ( - "os" - "sync" - "syscall" -) - -const ( - // In earlier versions of iptables, the xtables lock was implemented - // via a Unix socket, but now flock is used via this lockfile: - // http://git.netfilter.org/iptables/commit/?id=aa562a660d1555b13cffbac1e744033e91f82707 - // Note the LSB-conforming "/run" directory does not exist on old - // distributions, so assume "/var" is symlinked - xtablesLockFilePath = "/var/run/xtables.lock" - - defaultFilePerm = 0600 -) - -type Unlocker interface { - Unlock() error -} - -type nopUnlocker struct{} - -func (_ nopUnlocker) Unlock() error { return nil } - -type fileLock struct { - // mu is used to protect against concurrent invocations from within this process - mu sync.Mutex - fd int -} - -// tryLock takes an exclusive lock on the xtables lock file without blocking. -// This is best-effort only: if the exclusive lock would block (i.e. because -// another process already holds it), no error is returned. Otherwise, any -// error encountered during the locking operation is returned. -// The returned Unlocker should be used to release the lock when the caller is -// done invoking iptables commands. -func (l *fileLock) tryLock() (Unlocker, error) { - l.mu.Lock() - err := syscall.Flock(l.fd, syscall.LOCK_EX|syscall.LOCK_NB) - switch err { - case syscall.EWOULDBLOCK: - l.mu.Unlock() - return nopUnlocker{}, nil - case nil: - return l, nil - default: - l.mu.Unlock() - return nil, err - } -} - -// Unlock closes the underlying file, which implicitly unlocks it as well. It -// also unlocks the associated mutex. -func (l *fileLock) Unlock() error { - defer l.mu.Unlock() - return syscall.Close(l.fd) -} - -// newXtablesFileLock opens a new lock on the xtables lockfile without -// acquiring the lock -func newXtablesFileLock() (*fileLock, error) { - fd, err := syscall.Open(xtablesLockFilePath, os.O_CREATE, defaultFilePerm) - if err != nil { - return nil, err - } - return &fileLock{fd: fd}, nil -} diff --git a/vendor/github.com/creachadair/msync/LICENSE b/vendor/github.com/creachadair/msync/LICENSE new file mode 100644 index 0000000..eae4b1a --- /dev/null +++ b/vendor/github.com/creachadair/msync/LICENSE @@ -0,0 +1,26 @@ +Copyright (C) 2022, Michael J. Fromberger +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + (1) Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + (2) 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. + + (3) The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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/creachadair/msync/trigger/trigger.go b/vendor/github.com/creachadair/msync/trigger/trigger.go new file mode 100644 index 0000000..1422407 --- /dev/null +++ b/vendor/github.com/creachadair/msync/trigger/trigger.go @@ -0,0 +1,81 @@ +// Package trigger implements channel-based condition variable. +package trigger + +import "sync" + +// A Cond is a condition shared by multiple goroutines. The [Cond.Ready] +// method returns a channel that is closed when the condition is activated. +// +// When a condition is first created it is inactive. While inactive, reads on +// the ready channel will block. The condition remains inactive until +// [Cond.Set] or [Cond.Signal] is called, either of which causes the current +// ready channel to be closed (and thus deliver a zero value). Once a condition +// has been activated, it remains active until it is reset. Use [Cond.Reset] to +// make it inactive again. +// +// The [Cond.Signal] method activates and then immediately resets the +// condition, acting as Set and Reset done in a single step. +// +// A zero Cond is ready for use, and is inactive, but must not be copied after +// any of its methods have been called. +type Cond struct { + μ sync.Mutex + ch chan struct{} + closed bool + + // The signal channel is lazily initialized by the first waiter. +} + +// New constructs a new inactive [Cond]. +func New() *Cond { return new(Cond) } + +// Signal activates and immediately resets the condition. If the condition was +// already active, this is equivalent to [Cond.Reset]. +func (c *Cond) Signal() { + c.μ.Lock() + defer c.μ.Unlock() + + if c.ch != nil && !c.closed { + close(c.ch) // wake any pending waiters + } + c.ch = nil + c.closed = false +} + +// Set activates the condition. If it was already active, Set has no effect. +func (c *Cond) Set() { + c.μ.Lock() + defer c.μ.Unlock() + + if c.ch == nil { + c.ch = make(chan struct{}) + } + if !c.closed { + close(c.ch) + c.closed = true + } +} + +// Reset resets the condition. If it was already inactive, Reset has no effect. +func (c *Cond) Reset() { + c.μ.Lock() + defer c.μ.Unlock() + + if c.closed { + c.ch = nil + c.closed = false + } +} + +// Ready returns a channel that is closed when c is activated. If c is active +// when Ready is called, the returned channel will already be closed. +func (c *Cond) Ready() <-chan struct{} { + c.μ.Lock() + defer c.μ.Unlock() + + if c.ch == nil { + c.ch = make(chan struct{}) + c.closed = false + } + return c.ch +} diff --git a/vendor/github.com/digitalocean/go-smbios/AUTHORS b/vendor/github.com/digitalocean/go-smbios/AUTHORS deleted file mode 100644 index e2a7e2b..0000000 --- a/vendor/github.com/digitalocean/go-smbios/AUTHORS +++ /dev/null @@ -1,11 +0,0 @@ -Maintainer ----------- -DigitalOcean, Inc - -Original Authors ----------------- -Matt Layher - -Contributors ------------- -Christopher Dudley \ No newline at end of file diff --git a/vendor/github.com/digitalocean/go-smbios/LICENSE.md b/vendor/github.com/digitalocean/go-smbios/LICENSE.md deleted file mode 100644 index 84a5a44..0000000 --- a/vendor/github.com/digitalocean/go-smbios/LICENSE.md +++ /dev/null @@ -1,195 +0,0 @@ -Apache License -============== - -_Version 2.0, January 2004_ -_<>_ - -### Terms and Conditions for use, reproduction, and distribution - -#### 1. Definitions - -“License” shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -“Licensor” shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -“Legal Entity” shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, “control” means **(i)** the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the -outstanding shares, or **(iii)** beneficial ownership of such entity. - -“You” (or “Your”) shall mean an individual or Legal Entity exercising -permissions granted by this License. - -“Source” form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -“Object” form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -“Work” shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -“Derivative Works” shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -“Contribution” shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -“submitted” means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as “Not a Contribution.” - -“Contributor” shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -#### 2. Grant of Copyright License - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -#### 3. Grant of Patent License - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -#### 4. Redistribution - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -* **(a)** You must give any other recipients of the Work or Derivative Works a copy of -this License; and -* **(b)** You must cause any modified files to carry prominent notices stating that You -changed the files; and -* **(c)** You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. - -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -#### 5. Submission of Contributions - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -#### 6. Trademarks - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -#### 7. Disclaimer of Warranty - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -#### 8. Limitation of Liability - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -#### 9. Accepting Warranty or Additional Liability - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -_END OF TERMS AND CONDITIONS_ - -### APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets `[]` replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same “printed page” as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/decoder.go b/vendor/github.com/digitalocean/go-smbios/smbios/decoder.go deleted file mode 100644 index 4b00578..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/decoder.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios - -import ( - "bufio" - "bytes" - "encoding/binary" - "io" -) - -const ( - // headerLen is the length of the Header structure. - headerLen = 4 - - // typeEndOfTable indicates the end of a stream of Structures. - typeEndOfTable = 127 -) - -var ( - // Byte slices used to help parsing string-sets. - null = []byte{0x00} - endStringSet = []byte{0x00, 0x00} -) - -// A Decoder decodes Structures from a stream. -type Decoder struct { - br *bufio.Reader - b []byte -} - -// Stream locates and opens a stream of SMBIOS data and the SMBIOS entry -// point from an operating system-specific location. The stream must be -// closed after decoding to free its resources. -// -// If no suitable location is found, an error is returned. -func Stream() (io.ReadCloser, EntryPoint, error) { - rc, ep, err := stream() - if err != nil { - return nil, nil, err - } - - // The io.ReadCloser from stream could be any one of a number of types - // depending on the source of the SMBIOS stream information. - // - // To prevent the caller from potentially tampering with something dangerous - // like mmap'd memory by using a type assertion, we make the io.ReadCloser - // into an opaque and unexported type to prevent type assertion. - return &opaqueReadCloser{rc: rc}, ep, nil -} - -// NewDecoder creates a Decoder which decodes Structures from the input stream. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - br: bufio.NewReader(r), - b: make([]byte, 1024), - } -} - -// Decode decodes Structures from the Decoder's stream until an End-of-table -// structure is found. -func (d *Decoder) Decode() ([]*Structure, error) { - var ss []*Structure - - for { - s, err := d.next() - if err != nil { - return nil, err - } - - // End-of-table structure indicates end of stream. - ss = append(ss, s) - if s.Header.Type == typeEndOfTable { - break - } - } - - return ss, nil -} - -// next decodes the next Structure from the stream. -func (d *Decoder) next() (*Structure, error) { - h, err := d.parseHeader() - if err != nil { - return nil, err - } - - // Length of formatted section is length specified by header, minus - // the length of the header itself. - l := int(h.Length) - headerLen - fb, err := d.parseFormatted(l) - if err != nil { - return nil, err - } - - ss, err := d.parseStrings() - if err != nil { - return nil, err - } - - return &Structure{ - Header: *h, - Formatted: fb, - Strings: ss, - }, nil -} - -// parseHeader parses a Structure's Header from the stream. -func (d *Decoder) parseHeader() (*Header, error) { - if _, err := io.ReadFull(d.br, d.b[:headerLen]); err != nil { - return nil, err - } - - return &Header{ - Type: d.b[0], - Length: d.b[1], - Handle: binary.LittleEndian.Uint16(d.b[2:4]), - }, nil -} - -// parseFormatted parses a Structure's formatted data from the stream. -func (d *Decoder) parseFormatted(l int) ([]byte, error) { - // Guard against malformed input length. - if l < 0 { - return nil, io.ErrUnexpectedEOF - } - if l == 0 { - // No formatted data. - return nil, nil - } - - if _, err := io.ReadFull(d.br, d.b[:l]); err != nil { - return nil, err - } - - // Make a copy to free up the internal buffer. - fb := make([]byte, len(d.b[:l])) - copy(fb, d.b[:l]) - - return fb, nil -} - -// parseStrings parses a Structure's strings from the stream, if they -// are present. -func (d *Decoder) parseStrings() ([]string, error) { - term, err := d.br.Peek(2) - if err != nil { - return nil, err - } - - // If no string-set present, discard delimeter and end parsing. - if bytes.Equal(term, endStringSet) { - if _, err := d.br.Discard(2); err != nil { - return nil, err - } - - return nil, nil - } - - var ss []string - for { - s, more, err := d.parseString() - if err != nil { - return nil, err - } - - // When final string is received, end parse loop. - ss = append(ss, s) - if !more { - break - } - } - - return ss, nil -} - -// parseString parses a single string from the stream, and returns if -// any more strings are present. -func (d *Decoder) parseString() (str string, more bool, err error) { - // We initially read bytes because it's more efficient to manipulate bytes - // and allocate a string once we're all done. - // - // Strings are null-terminated. - raw, err := d.br.ReadBytes(0x00) - if err != nil { - return "", false, err - } - - b := bytes.TrimRight(raw, "\x00") - - peek, err := d.br.Peek(1) - if err != nil { - return "", false, err - } - - if !bytes.Equal(peek, null) { - // Next byte isn't null; more strings to come. - return string(b), true, nil - } - - // If two null bytes appear in a row, end of string-set. - // Discard the null and indicate no more strings. - if _, err := d.br.Discard(1); err != nil { - return "", false, err - } - - return string(b), false, nil -} - -var _ io.ReadCloser = &opaqueReadCloser{} - -// An opaqueReadCloser masks the type of the underlying io.ReadCloser to -// prevent type assertions. -type opaqueReadCloser struct { - rc io.ReadCloser -} - -func (rc *opaqueReadCloser) Read(b []byte) (int, error) { return rc.rc.Read(b) } -func (rc *opaqueReadCloser) Close() error { return rc.rc.Close() } diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/doc.go b/vendor/github.com/digitalocean/go-smbios/smbios/doc.go deleted file mode 100644 index f757511..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios provides detection and access to System Management BIOS (SMBIOS) -// and Desktop Management Interface (DMI) data and structures. -package smbios diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/entrypoint.go b/vendor/github.com/digitalocean/go-smbios/smbios/entrypoint.go deleted file mode 100644 index 4946faf..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/entrypoint.go +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - "io/ioutil" -) - -// Anchor strings used to detect entry points. -var ( - // Used when searching for an entry point in memory. - magicPrefix = []byte("_SM") - - // Used to determine specific entry point types. - magic32 = []byte("_SM_") - magic64 = []byte("_SM3_") - magicDMI = []byte("_DMI_") -) - -// An EntryPoint is an SMBIOS entry point. EntryPoints contain various -// properties about SMBIOS. -// -// Use a type assertion to access detailed EntryPoint information. -type EntryPoint interface { - // Table returns the memory address and maximum size of the SMBIOS table. - Table() (address, size int) - - // Version returns the system's SMBIOS version. - Version() (major, minor, revision int) -} - -// ParseEntryPoint parses an EntryPoint from the input stream. -func ParseEntryPoint(r io.Reader) (EntryPoint, error) { - // Prevent unbounded reads since this structure should be small. - b, err := ioutil.ReadAll(io.LimitReader(r, 64)) - if err != nil { - return nil, err - } - - if l := len(b); l < 4 { - return nil, fmt.Errorf("too few bytes for SMBIOS entry point magic: %d", l) - } - - switch { - case bytes.HasPrefix(b, magic32): - return parse32(b) - case bytes.HasPrefix(b, magic64): - return parse64(b) - } - - return nil, fmt.Errorf("unrecognized SMBIOS entry point magic: %v", b[0:4]) -} - -var _ EntryPoint = &EntryPoint32Bit{} - -// EntryPoint32Bit is the SMBIOS 32-bit Entry Point structure, used starting -// in SMBIOS 2.1. -type EntryPoint32Bit struct { - Anchor string - Checksum uint8 - Length uint8 - Major uint8 - Minor uint8 - MaxStructureSize uint16 - EntryPointRevision uint8 - FormattedArea [5]byte - IntermediateAnchor string - IntermediateChecksum uint8 - StructureTableLength uint16 - StructureTableAddress uint32 - NumberStructures uint16 - BCDRevision uint8 -} - -// Table implements EntryPoint. -func (e *EntryPoint32Bit) Table() (address, size int) { - return int(e.StructureTableAddress), int(e.StructureTableLength) -} - -// Version implements EntryPoint. -func (e *EntryPoint32Bit) Version() (major, minor, revision int) { - return int(e.Major), int(e.Minor), 0 -} - -// parse32 parses an EntryPoint32Bit from b. -func parse32(b []byte) (*EntryPoint32Bit, error) { - l := len(b) - - // Correct minimum length as of SMBIOS 3.1.1. - const expLen = 31 - if l < expLen { - return nil, fmt.Errorf("expected SMBIOS 32-bit entry point minimum length of at least %d, but got: %d", expLen, l) - } - - // Allow more data in the buffer than the actual length, for when the - // entry point is being read from system memory. - length := b[5] - if l < int(length) { - return nil, fmt.Errorf("expected SMBIOS 32-bit entry point actual length of at least %d, but got: %d", length, l) - } - - // Look for intermediate anchor with DMI magic. - iAnchor := b[16:21] - if !bytes.Equal(iAnchor, magicDMI) { - return nil, fmt.Errorf("incorrect DMI magic in SMBIOS 32-bit entry point: %v", iAnchor) - } - - // Entry point checksum occurs at index 4, compute and verify it. - const epChkIndex = 4 - epChk := b[epChkIndex] - if err := checksum(epChk, epChkIndex, b[:length]); err != nil { - return nil, err - } - - // Since we already computed the checksum for the outer entry point, - // no real need to compute it for the intermediate entry point. - - ep := &EntryPoint32Bit{ - Anchor: string(b[0:4]), - Checksum: epChk, - Length: length, - Major: b[6], - Minor: b[7], - MaxStructureSize: binary.LittleEndian.Uint16(b[8:10]), - EntryPointRevision: b[10], - IntermediateAnchor: string(iAnchor), - IntermediateChecksum: b[21], - StructureTableLength: binary.LittleEndian.Uint16(b[22:24]), - StructureTableAddress: binary.LittleEndian.Uint32(b[24:28]), - NumberStructures: binary.LittleEndian.Uint16(b[28:30]), - BCDRevision: b[30], - } - copy(ep.FormattedArea[:], b[10:15]) - - return ep, nil -} - -var _ EntryPoint = &EntryPoint64Bit{} - -// EntryPoint64Bit is the SMBIOS 64-bit Entry Point structure, used starting -// in SMBIOS 3.0. -type EntryPoint64Bit struct { - Anchor string - Checksum uint8 - Length uint8 - Major uint8 - Minor uint8 - Revision uint8 - EntryPointRevision uint8 - Reserved uint8 - StructureTableMaxSize uint32 - StructureTableAddress uint64 -} - -// Table implements EntryPoint. -func (e *EntryPoint64Bit) Table() (address, size int) { - return int(e.StructureTableAddress), int(e.StructureTableMaxSize) -} - -// Version implements EntryPoint. -func (e *EntryPoint64Bit) Version() (major, minor, revision int) { - return int(e.Major), int(e.Minor), int(e.Revision) -} - -const ( - // expLen64 is the expected minimum length of a 64-bit entry point. - // Correct minimum length as of SMBIOS 3.1.1. - expLen64 = 24 - - // chkIndex64 is the index of the checksum byte in a 64-bit entry point. - chkIndex64 = 5 -) - -// parse64 parses an EntryPoint64Bit from b. -func parse64(b []byte) (*EntryPoint64Bit, error) { - l := len(b) - - // Ensure expected minimum length. - if l < expLen64 { - return nil, fmt.Errorf("expected SMBIOS 64-bit entry point minimum length of at least %d, but got: %d", expLen64, l) - } - - // Allow more data in the buffer than the actual length, for when the - // entry point is being read from system memory. - length := b[6] - if l < int(length) { - return nil, fmt.Errorf("expected SMBIOS 64-bit entry point actual length of at least %d, but got: %d", length, l) - } - - // Checksum occurs at index 5, compute and verify it. - chk := b[chkIndex64] - if err := checksum(chk, chkIndex64, b); err != nil { - return nil, err - } - - return &EntryPoint64Bit{ - Anchor: string(b[0:5]), - Checksum: chk, - Length: length, - Major: b[7], - Minor: b[8], - Revision: b[9], - EntryPointRevision: b[10], - Reserved: b[11], - StructureTableMaxSize: binary.LittleEndian.Uint32(b[12:16]), - StructureTableAddress: binary.LittleEndian.Uint64(b[16:24]), - }, nil -} - -// checksum computes the checksum of b using the starting value of start, and -// skipping the checksum byte which occurs at index chkIndex. -// -// checksum assumes that b has already had its bounds checked. -func checksum(start uint8, chkIndex int, b []byte) error { - chk := start - for i := range b { - // Checksum computation does not include index of checksum byte. - if i == chkIndex { - continue - } - - chk += b[i] - } - - if chk != 0 { - return fmt.Errorf("invalid entry point checksum %#02x from initial checksum %#02x", chk, start) - } - - return nil -} - -// WindowsEntryPoint contains SMBIOS Table entry point data returned from -// GetSystemFirmwareTable. As raw access to the underlying memory is not given, -// the full breadth of information is not available. -type WindowsEntryPoint struct { - Size uint32 - MajorVersion byte - MinorVersion byte - Revision byte -} - -// Table implements EntryPoint. The returned address will always be 0, as it -// is not returned by GetSystemFirmwareTable. -func (e *WindowsEntryPoint) Table() (address, size int) { - return 0, int(e.Size) -} - -// Version implements EntryPoint. -func (e *WindowsEntryPoint) Version() (major, minor, revision int) { - return int(e.MajorVersion), int(e.MinorVersion), int(e.Revision) -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/fuzz.go b/vendor/github.com/digitalocean/go-smbios/smbios/fuzz.go deleted file mode 100644 index 8cb64cd..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/fuzz.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//+build gofuzz - -package smbios - -import ( - "bytes" -) - -func Fuzz(data []byte) int { - return fuzzDecoder(data) -} - -func fuzzDecoder(data []byte) int { - d := NewDecoder(bytes.NewReader(data)) - - if _, err := d.Decode(); err != nil { - return 0 - } - - return 1 -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/stream_linux.go b/vendor/github.com/digitalocean/go-smbios/smbios/stream_linux.go deleted file mode 100644 index 280bca4..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/stream_linux.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//+build linux - -package smbios - -import ( - "io" - "os" -) - -const ( - // sysfs locations for SMBIOS information. - sysfsDMI = "/sys/firmware/dmi/tables/DMI" - sysfsEntryPoint = "/sys/firmware/dmi/tables/smbios_entry_point" -) - -// stream opens the SMBIOS entry point and an SMBIOS structure stream. -func stream() (io.ReadCloser, EntryPoint, error) { - // First, check for the sysfs location present in modern kernels. - _, err := os.Stat(sysfsEntryPoint) - switch { - case err == nil: - return sysfsStream(sysfsEntryPoint, sysfsDMI) - case os.IsNotExist(err): - // Fall back to the standard UNIX-like system method. - return devMemStream() - default: - return nil, nil, err - } -} - -// sysfsStream reads the SMBIOS entry point and structure stream from -// two files; usually the modern sysfs locations. -func sysfsStream(entryPoint, dmi string) (io.ReadCloser, EntryPoint, error) { - epf, err := os.Open(entryPoint) - if err != nil { - return nil, nil, err - } - defer epf.Close() - - ep, err := ParseEntryPoint(epf) - if err != nil { - return nil, nil, err - } - - sf, err := os.Open(dmi) - if err != nil { - return nil, nil, err - } - - return sf, ep, nil -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/stream_memory.go b/vendor/github.com/digitalocean/go-smbios/smbios/stream_memory.go deleted file mode 100644 index fc2b70e..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/stream_memory.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios - -import ( - "bytes" - "errors" - "io" - "io/ioutil" - "os" -) - -const ( - // devMem is the UNIX-like system memory device location used to - // find SMBIOS information. - devMem = "/dev/mem" - - // SMBIOS specification indicates that the entry point should exist - // between these two memory addresses. - startAddr = 0x000f0000 - endAddr = 0x000fffff -) - -// memoryStream reads the SMBIOS entry point and structure stream from -// an io.ReadSeeker (usually system memory). -// -// memoryStream is an entry point for tests. -func memoryStream(rs io.ReadSeeker, startAddr, endAddr int) (io.ReadCloser, EntryPoint, error) { - // Try to find the entry point. - addr, err := findEntryPoint(rs, startAddr, endAddr) - if err != nil { - return nil, nil, err - } - - // Found it; seek to the location of the entry point. - if _, err := rs.Seek(int64(addr), io.SeekStart); err != nil { - return nil, nil, err - } - - // Read the entry point and determine where the SMBIOS table is. - ep, err := ParseEntryPoint(rs) - if err != nil { - return nil, nil, err - } - - // Seek to the start of the SMBIOS table. - tableAddr, tableSize := ep.Table() - if _, err := rs.Seek(int64(tableAddr), io.SeekStart); err != nil { - return nil, nil, err - } - - // Make a copy of the memory so we don't return a handle to system memory - // to the caller. - out := make([]byte, tableSize) - if _, err := io.ReadFull(rs, out); err != nil { - return nil, nil, err - } - - return ioutil.NopCloser(bytes.NewReader(out)), ep, nil -} - -// findEntryPoint attempts to locate the entry point structure in the io.ReadSeeker -// using the start and end bound as hints for its location. -func findEntryPoint(rs io.ReadSeeker, start, end int) (int, error) { - // Begin searching at the start bound. - if _, err := rs.Seek(int64(start), io.SeekStart); err != nil { - return 0, err - } - - // Iterate one "paragraph" of memory at a time until we either find the entry point - // or reach the end bound. - const paragraph = 16 - b := make([]byte, paragraph) - - var ( - addr int - found bool - ) - - for addr = start; addr < end; addr += paragraph { - if _, err := io.ReadFull(rs, b); err != nil { - return 0, err - } - - // Both the 32-bit and 64-bit entry point have a similar prefix. - if bytes.HasPrefix(b, magicPrefix) { - found = true - break - } - } - - if !found { - return 0, errors.New("no SMBIOS entry point found in memory") - } - - // Return the exact memory location of the entry point. - return addr, nil -} - -// devMemStream reads the SMBIOS entry point and structure stream from -// the UNIX-like system /dev/mem device. -// -// This is UNIX-like system specific, but since it doesn't employ any system -// calls or OS-dependent constants, it remains in this file for simplicity. -func devMemStream() (io.ReadCloser, EntryPoint, error) { - mem, err := os.Open(devMem) - if err != nil { - return nil, nil, err - } - defer mem.Close() - - return memoryStream(mem, startAddr, endAddr) -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/stream_others.go b/vendor/github.com/digitalocean/go-smbios/smbios/stream_others.go deleted file mode 100644 index f7c860b..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/stream_others.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//+build !dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows - -package smbios - -import ( - "fmt" - "io" - "runtime" -) - -// stream is not implemented for unsupported platforms. -func stream() (io.ReadCloser, EntryPoint, error) { - return nil, nil, fmt.Errorf("opening SMBIOS stream not implemented on %q", runtime.GOOS) -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/stream_unix.go b/vendor/github.com/digitalocean/go-smbios/smbios/stream_unix.go deleted file mode 100644 index 3146553..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/stream_unix.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//+build dragonfly freebsd netbsd openbsd solaris - -// Linux intentionally omitted because it has an alternative method that -// is used before attempting /dev/mem access. See stream_linux.go. - -package smbios - -import ( - "io" -) - -// stream opens the SMBIOS entry point and an SMBIOS structure stream. -func stream() (io.ReadCloser, EntryPoint, error) { - // Use the standard UNIX-like system method. - return devMemStream() -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/stream_windows.go b/vendor/github.com/digitalocean/go-smbios/smbios/stream_windows.go deleted file mode 100644 index 92d0537..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/stream_windows.go +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "syscall" - "unsafe" -) - -// firmwareTableProviderSigRSMB is the identifier for the raw SMBIOS firmware table -// provider. -// It is equal to the ASCII characters 'RSMB' packed into a uint32. -// In the C++ example code in the MSDN documentation, this is specified using -// multi-byte character literals, which are automatically coerced to an integer by -// the C++ compiler. -const firmwareTableProviderSigRSMB uint32 = 0x52534d42 - -// smbiosDataHeaderSize is size of the "header" (non-variable) part of the -// RawSMBIOSData struct. This serves as both the offset to the actual -// SMBIOS table data, and the minimum possible size of a valid RawSMBIOSDATA -// struct (with a table length of 0). -const rawSMBIOSDataHeaderSize = 8 - -var ( - libKernel32 = syscall.NewLazyDLL("kernel32.dll") - - // MSDN Documentation for GetSystemFirmwareTable: - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724379(v=vs.85).aspx - procGetSystemFirmwareTable = libKernel32.NewProc("GetSystemFirmwareTable") -) - -// nativeEndian returns the native byte order of this system. -func nativeEndian() binary.ByteOrder { - // Determine endianness by interpreting a uint16 as a byte slice. - v := uint16(1) - b := *(*[2]byte)(unsafe.Pointer(&v)) - - if b[0] == 1 { - return binary.LittleEndian - } - - return binary.BigEndian -} - -// windowsStream parses the data returned from GetSystemFirmwareTable('RSMB',...) -// and returns a stream and entrypoint that can be used to decode the system's -// SMBIOS table. -// -// When calling GetSystemFirmwareTable with FirmwareTableProviderSignature = "RSMB", -// Windows will write a RawSMBIOSData struct into the output buffer. -// Thus, `buf` is expected to contain a valid RawSMBIOSData structure. -// -// From windows.h: -// -// struct RawSMBIOSData { -// BYTE Used20CallingMethod; -// BYTE SMBIOSMajorVersion; -// BYTE SMBIOSMinorVersion; -// BYTE DMIRevision; -// DWORD Length; -// BYTE SMBIOSTableData[]; -// } -// -// Note: a DWORD is equivalent to a uint32 -// See: https://msdn.microsoft.com/en-us/library/cc230318.aspx -func windowsStream(buf []byte) (io.ReadCloser, EntryPoint, error) { - bufLen := uint32(len(buf)) - - // Do an additional check to make sure the actual amount written is sane. - if bufLen < rawSMBIOSDataHeaderSize { - return nil, nil, fmt.Errorf("GetSystemFirmwareTable wrote less data than expected: wrote %d bytes, expected at least 8 bytes", bufLen) - } - - tableSize := nativeEndian().Uint32(buf[4:8]) - if rawSMBIOSDataHeaderSize+tableSize > bufLen { - return nil, nil, errors.New("reported SMBIOS table size exceeds buffer") - } - - entryPoint := &WindowsEntryPoint{ - MajorVersion: buf[1], - MinorVersion: buf[2], - Revision: buf[3], - Size: tableSize, - } - - tableBuff := buf[rawSMBIOSDataHeaderSize : rawSMBIOSDataHeaderSize+tableSize] - - return ioutil.NopCloser(bytes.NewReader(tableBuff)), entryPoint, nil -} - -func stream() (io.ReadCloser, EntryPoint, error) { - // Call first with empty buffer to get size. - r1, _, err := procGetSystemFirmwareTable.Call( - uintptr(firmwareTableProviderSigRSMB), // FirmwareTableProviderSignature = 'RSMB' - 0, // FirmwareTableID = 0 - 0, // pFirmwareTableBuffer = NULL - 0, // BufferSize = 0 - ) - - // LazyProc.Call will always return err != nil, so we need to check the primary - // return value (r1) to determine whether or not an error occurred. - // In this case, r1 should contain the size of the needed buffer, so it will only - // be 0 if the function call failed for some reason. - // - // Godoc for LazyProc.Call: - // https://golang.org/pkg/syscall/?GOOS=windows&GOARCH=amd64#LazyProc.Call - if r1 == 0 { - return nil, nil, fmt.Errorf("failed to determine size of buffer needed: %v", err) - } - if r1 < rawSMBIOSDataHeaderSize { - return nil, nil, fmt.Errorf("reported buffer size smaller than expected: reported %d, expected >= 8", r1) - } - - bufferSize := uint32(r1) - buffer := make([]byte, bufferSize) - - r1, _, err = procGetSystemFirmwareTable.Call( - uintptr(firmwareTableProviderSigRSMB), // FirmwareTableProviderSignature = 'RSMB' - 0, // FirmwareTableID = 0 - uintptr(unsafe.Pointer(&buffer[0])), // pFirmwareTableBuffer = &buffer - uintptr(bufferSize), // BufferSize = bufferSize - ) - bytesWritten := uint32(r1) - - // Check for the two possible failure cases documented in API: - if bytesWritten > bufferSize { - return nil, nil, fmt.Errorf("buffer size was too small, somehow: have %d bytes, Windows wanted %d bytes", bufferSize, bytesWritten) - } - if bytesWritten == 0 { - return nil, nil, fmt.Errorf("failed to read SMBIOS data: %v", err) - } - - // At this point, bytesWritten <= bufferSize, which means the call succeeded as - // per the MSDN documentation. - - return windowsStream(buffer[:bytesWritten]) -} diff --git a/vendor/github.com/digitalocean/go-smbios/smbios/structure.go b/vendor/github.com/digitalocean/go-smbios/smbios/structure.go deleted file mode 100644 index 8cd107f..0000000 --- a/vendor/github.com/digitalocean/go-smbios/smbios/structure.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017-2018 DigitalOcean. -// -// 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 smbios - -// A Header is a Structure's header. -type Header struct { - Type uint8 - Length uint8 - Handle uint16 -} - -// A Structure is an SMBIOS structure. -type Structure struct { - Header Header - Formatted []byte - Strings []string -} diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md index af0a795..d072b81 100644 --- a/vendor/github.com/fxamacker/cbor/v2/README.md +++ b/vendor/github.com/fxamacker/cbor/v2/README.md @@ -1,30 +1,31 @@ -# CBOR Codec in Go - - +

CBOR Codec Go logo

[fxamacker/cbor](https://github.com/fxamacker/cbor) is a library for encoding and decoding [CBOR](https://www.rfc-editor.org/info/std94) and [CBOR Sequences](https://www.rfc-editor.org/rfc/rfc8742.html). CBOR is a [trusted alternative](https://www.rfc-editor.org/rfc/rfc8949.html#name-comparison-of-other-binary-) to JSON, MessagePack, Protocol Buffers, etc.  CBOR is an Internet Standard defined by [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94) and is designed to be relevant for decades. -`fxamacker/cbor` is used in projects by Arm Ltd., Cisco, EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, Kubernetes, Let's Encrypt (ISRG), Linux Foundation, Microsoft, Mozilla, Oasis Protocol, Tailscale, Teleport, [etc](https://github.com/fxamacker/cbor#who-uses-fxamackercbor). +`fxamacker/cbor` is used in projects by Arm Ltd., EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, IBM, Kubernetes[*](https://github.com/search?q=org%3Akubernetes%20fxamacker%2Fcbor&type=code), Let's Encrypt, Linux Foundation, Microsoft, Oasis Protocol, Red Hat[*](https://github.com/search?q=org%3Aopenshift+fxamacker%2Fcbor&type=code), Tailscale[*](https://github.com/search?q=org%3Atailscale+fxamacker%2Fcbor&type=code), Veraison[*](https://github.com/search?q=org%3Averaison+fxamacker%2Fcbor&type=code), [etc](https://github.com/fxamacker/cbor#who-uses-fxamackercbor). -See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `cbor.MarshalToBuffer()` and `UserBufferEncMode` accepts user-specified buffer. +See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `MarshalToBuffer` and `UserBufferEncMode` accepts user-specified buffer. ## fxamacker/cbor [![](https://github.com/fxamacker/cbor/workflows/ci/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3Aci) -[![](https://github.com/fxamacker/cbor/workflows/cover%20%E2%89%A596%25/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A596%25%22) +[![](https://github.com/fxamacker/cbor/workflows/cover%20%E2%89%A597%25/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A597%25%22) [![CodeQL](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml) [![](https://img.shields.io/badge/fuzzing-passing-44c010)](#fuzzing-and-code-coverage) [![Go Report Card](https://goreportcard.com/badge/github.com/fxamacker/cbor)](https://goreportcard.com/report/github.com/fxamacker/cbor) +[![](https://img.shields.io/ossf-scorecard/github.com/fxamacker/cbor?label=openssf%20scorecard)](https://github.com/fxamacker/cbor#fuzzing-and-code-coverage) `fxamacker/cbor` is a CBOR codec in full conformance with [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94). It also supports CBOR Sequences ([RFC 8742](https://www.rfc-editor.org/rfc/rfc8742.html)) and Extended Diagnostic Notation ([Appendix G of RFC 8610](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G)). Features include full support for CBOR tags, [Core Deterministic Encoding](https://www.rfc-editor.org/rfc/rfc8949.html#name-core-deterministic-encoding), duplicate map key detection, etc. +API is mostly same as `encoding/json`, plus interfaces that simplify concurrency and CBOR options. + Design balances trade-offs between security, speed, concurrency, encoded data size, usability, etc. -
Highlights

+

🔎  Highlights

__🚀  Speed__ @@ -38,7 +39,7 @@ Codec passed multiple confidential security assessments in 2022. No vulnerabili __🗜️  Data Size__ -Struct tags (`toarray`, `keyasint`, `omitempty`) automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit. +Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) and field tag "-" automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit. __:jigsaw:  Usability__ @@ -58,164 +59,205 @@ Features include CBOR [extension points](https://www.rfc-editor.org/rfc/rfc8949. `fxamacker/cbor` has configurable limits, etc. that defend against malicious CBOR data. -By contrast, `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security). +Notably, `fxamacker/cbor` is fast at rejecting malformed CBOR data. -

Example decoding with encoding/gob 💥 fatal error (out of memory)

+> [!NOTE] +> Benchmarks rejecting 10 bytes of malicious CBOR data decoding to `[]byte`: +> +> | Codec | Speed (ns/op) | Memory | Allocs | +> | :---- | ------------: | -----: | -----: | +> | fxamacker/cbor 2.7.0 | 47 ± 7% | 32 B/op | 2 allocs/op | +> | ugorji/go 1.2.12 | 5878187 ± 3% | 67111556 B/op | 13 allocs/op | +> +> Faster hardware (overclocked DDR4 or DDR5) can reduce speed difference. +> +>

🔎  Benchmark details

+> +> Latest comparison for decoding CBOR data to Go `[]byte`: +> - Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` +> - go1.22.7, linux/amd64, i5-13600K (DDR4-2933, disabled e-cores) +> - go test -bench=. -benchmem -count=20 +> +> #### Prior comparisons +> +> | Codec | Speed (ns/op) | Memory | Allocs | +> | :---- | ------------: | -----: | -----: | +> | fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op | +> | fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op | +> | ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op | +> | ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate | +> +> - Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` +> - go1.19.6, linux/amd64, i5-13600K (DDR4) +> - go test -bench=. -benchmem -count=20 +> +>

-```Go -// Example of encoding/gob having "fatal error: runtime: out of memory" -// while decoding 181 bytes. -package main -import ( - "bytes" - "encoding/gob" - "encoding/hex" - "fmt" -) +In contrast, some codecs can crash or use excessive resources while decoding bad data. -// Example data is from https://github.com/golang/go/issues/24446 -// (shortened to 181 bytes). -const data = "4dffb503010102303001ff30000109010130010800010130010800010130" + - "01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" + - "860001013001ff860001013001ffb80000001eff850401010e3030303030" + - "30303030303030303001ff3000010c0104000016ffb70201010830303030" + - "3030303001ff3000010c000030ffb6040405fcff00303030303030303030" + - "303030303030303030303030303030303030303030303030303030303030" + - "30" +> [!WARNING] +> Go's `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security). +> +>
🔎  gob fatal error (out of memory) 💥 decoding 181 bytes

+> +> ```Go +> // Example of encoding/gob having "fatal error: runtime: out of memory" +> // while decoding 181 bytes (all Go versions as of Dec. 8, 2024). +> package main +> import ( +> "bytes" +> "encoding/gob" +> "encoding/hex" +> "fmt" +> ) +> +> // Example data is from https://github.com/golang/go/issues/24446 +> // (shortened to 181 bytes). +> const data = "4dffb503010102303001ff30000109010130010800010130010800010130" + +> "01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" + +> "860001013001ff860001013001ffb80000001eff850401010e3030303030" + +> "30303030303030303001ff3000010c0104000016ffb70201010830303030" + +> "3030303001ff3000010c000030ffb6040405fcff00303030303030303030" + +> "303030303030303030303030303030303030303030303030303030303030" + +> "30" +> +> type X struct { +> J *X +> K map[string]int +> } +> +> func main() { +> raw, _ := hex.DecodeString(data) +> decoder := gob.NewDecoder(bytes.NewReader(raw)) +> +> var x X +> decoder.Decode(&x) // fatal error: runtime: out of memory +> fmt.Println("Decoding finished.") +> } +> ``` +> +> +>

-type X struct { - J *X - K map[string]int -} +### Smaller Encodings with Struct Tag Options -func main() { - raw, _ := hex.DecodeString(data) - decoder := gob.NewDecoder(bytes.NewReader(raw)) +Struct tags automatically reduce encoded size of structs and improve speed. - var x X - decoder.Decode(&x) // fatal error: runtime: out of memory - fmt.Println("Decoding finished.") -} -``` +We can write less code by using struct tag options: +- `toarray`: encode without field names (decode back to original struct) +- `keyasint`: encode field names as integers (decode back to original struct) +- `omitempty`: omit empty field when encoding +- `omitzero`: omit zero-value field when encoding -
+As a special case, struct field tag "-" omits the field. -
- -`fxamacker/cbor` is fast at rejecting malformed CBOR data. E.g. attempts to -decode 10 bytes of malicious CBOR data to `[]byte` (with default settings): - -| Codec | Speed (ns/op) | Memory | Allocs | -| :---- | ------------: | -----: | -----: | -| fxamacker/cbor 2.5.0 | 44 ± 5% | 32 B/op | 2 allocs/op | -| ugorji/go 1.2.11 | 5353261 ± 4% | 67111321 B/op | 13 allocs/op | - -
Benchmark details

- -Latest comparison used: -- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` -- go1.19.10, linux/amd64, i5-13600K (disabled all e-cores, DDR4 @2933) -- go test -bench=. -benchmem -count=20 - -#### Prior comparisons - -| Codec | Speed (ns/op) | Memory | Allocs | -| :---- | ------------: | -----: | -----: | -| fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op | -| fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op | -| ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op | -| ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate | - -- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` -- go1.19.6, linux/amd64, i5-13600K (DDR4) -- go test -bench=. -benchmem -count=20 - -


- -
- -### Smaller Encodings with Struct Tags - -Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs. - -
Example encoding 3-level nested Go struct to 1 byte CBOR

- -https://go.dev/play/p/YxwvfPdFQG2 - -```Go -// Example encoding nested struct (with omitempty tag) -// - encoding/json: 18 byte JSON -// - fxamacker/cbor: 1 byte CBOR -package main - -import ( - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/fxamacker/cbor/v2" -) - -type GrandChild struct { - Quux int `json:",omitempty"` -} - -type Child struct { - Baz int `json:",omitempty"` - Qux GrandChild `json:",omitempty"` -} - -type Parent struct { - Foo Child `json:",omitempty"` - Bar int `json:",omitempty"` -} - -func cb() { - results, _ := cbor.Marshal(Parent{}) - fmt.Println("hex(CBOR): " + hex.EncodeToString(results)) - - text, _ := cbor.Diagnose(results) // Diagnostic Notation - fmt.Println("DN: " + text) -} - -func js() { - results, _ := json.Marshal(Parent{}) - fmt.Println("hex(JSON): " + hex.EncodeToString(results)) - - text := string(results) // JSON - fmt.Println("JSON: " + text) -} - -func main() { - cb() - fmt.Println("-------------") - js() -} -``` - -Output (DN is Diagnostic Notation): -``` -hex(CBOR): a0 -DN: {} -------------- -hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d -JSON: {"Foo":{"Qux":{}}} -``` - -


- -
- -Example using different struct tags together: +NOTE: When a struct uses `toarray`, the encoder will ignore `omitempty` and `omitzero` to prevent position of encoded array elements from changing. This allows decoder to match encoded elements to their Go struct field. ![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags") -API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options. +> [!NOTE] +> `fxamacker/cbor` can encode a 3-level nested Go struct to 1 byte! +> - `encoding/json`: 18 bytes of JSON +> - `fxamacker/cbor`: 1 byte of CBOR +> +>
🔎  Encoding 3-level nested Go struct with omitempty

+> +> https://go.dev/play/p/YxwvfPdFQG2 +> +> ```Go +> // Example encoding nested struct (with omitempty tag) +> // - encoding/json: 18 byte JSON +> // - fxamacker/cbor: 1 byte CBOR +> +> package main +> +> import ( +> "encoding/hex" +> "encoding/json" +> "fmt" +> +> "github.com/fxamacker/cbor/v2" +> ) +> +> type GrandChild struct { +> Quux int `json:",omitempty"` +> } +> +> type Child struct { +> Baz int `json:",omitempty"` +> Qux GrandChild `json:",omitempty"` +> } +> +> type Parent struct { +> Foo Child `json:",omitempty"` +> Bar int `json:",omitempty"` +> } +> +> func cb() { +> results, _ := cbor.Marshal(Parent{}) +> fmt.Println("hex(CBOR): " + hex.EncodeToString(results)) +> +> text, _ := cbor.Diagnose(results) // Diagnostic Notation +> fmt.Println("DN: " + text) +> } +> +> func js() { +> results, _ := json.Marshal(Parent{}) +> fmt.Println("hex(JSON): " + hex.EncodeToString(results)) +> +> text := string(results) // JSON +> fmt.Println("JSON: " + text) +> } +> +> func main() { +> cb() +> fmt.Println("-------------") +> js() +> } +> ``` +> +> Output (DN is Diagnostic Notation): +> ``` +> hex(CBOR): a0 +> DN: {} +> ------------- +> hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d +> JSON: {"Foo":{"Qux":{}}} +> ``` +> +>

+ ## Quick Start __Install__: `go get github.com/fxamacker/cbor/v2` and `import "github.com/fxamacker/cbor/v2"`. +> [!TIP] +> +> Tinygo users can try beta/experimental branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta). +> +>
🔎  More about tinygo feature branch +> +> ### Tinygo +> +> Branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta) is based on fxamacker/cbor v2.7.0 and it can be compiled using tinygo v0.33 (also compiles with golang/go). +> +> It passes unit tests (with both go1.22 and tinygo v0.33) and is considered beta/experimental for tinygo. +> +> :warning: The `feature/cbor-tinygo-beta` branch does not get fuzz tested yet. +> +> Changes in this feature branch only affect tinygo compiled software. Summary of changes: +> - default `DecOptions.MaxNestedLevels` is reduced to 16 (was 32). User can specify higher limit but 24+ crashes tests when compiled with tinygo v0.33. +> - disabled decoding CBOR tag data to Go interface because tinygo v0.33 is missing needed feature. +> - encoding error message can be different when encoding function type. +> +> Related tinygo issues: +> - https://github.com/tinygo-org/tinygo/issues/4277 +> - https://github.com/tinygo-org/tinygo/issues/4458 +> +>
+ + ### Key Points This library can encode and decode CBOR (RFC 8949) and CBOR Sequences (RFC 8742). @@ -252,16 +294,17 @@ rest, err = cbor.UnmarshalFirst(b, &v) // decode []byte b to v // DiagnoseFirst translates first CBOR data item to text and returns remaining bytes. text, rest, err = cbor.DiagnoseFirst(b) // decode []byte b to Diagnostic Notation text -// NOTE: Unmarshal returns ExtraneousDataError if there are remaining bytes, -// but new funcs UnmarshalFirst and DiagnoseFirst do not. +// NOTE: Unmarshal() returns ExtraneousDataError if there are remaining bytes, but +// UnmarshalFirst() and DiagnoseFirst() allow trailing bytes. ``` -__IMPORTANT__: 👉 CBOR settings allow trade-offs between speed, security, encoding size, etc. - -- Different CBOR libraries may use different default settings. -- CBOR-based formats or protocols usually require specific settings. - -For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset. +> [!IMPORTANT] +> CBOR settings allow trade-offs between speed, security, encoding size, etc. +> +> - Different CBOR libraries may use different default settings. +> - CBOR-based formats or protocols usually require specific settings. +> +> For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset. ### Presets @@ -312,9 +355,63 @@ err = em.MarshalToBuffer(v, &buf) // encode v to provided buf ### Struct Tags -Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs. +Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) reduce encoded size of structs. -
Example encoding 3-level nested Go struct to 1 byte CBOR

+As a special case, struct field tag "-" omits the field. + +

🔎  Example encoding with struct field tag "-"

+ +https://go.dev/play/p/aWEIFxd7InX + +```Go +// https://github.com/fxamacker/cbor/issues/652 +package main + +import ( + "encoding/json" + "fmt" + + "github.com/fxamacker/cbor/v2" +) + +// The `cbor:"-"` tag omits the Type field when encoding to CBOR. +type Entity struct { + _ struct{} `cbor:",toarray"` + ID uint64 `json:"id"` + Type string `cbor:"-" json:"typeOf"` + Name string `json:"name"` +} + +func main() { + entity := Entity{ + ID: 1, + Type: "int64", + Name: "Identifier", + } + + c, _ := cbor.Marshal(entity) + diag, _ := cbor.Diagnose(c) + fmt.Printf("CBOR in hex: %x\n", c) + fmt.Printf("CBOR in edn: %s\n", diag) + + j, _ := json.Marshal(entity) + fmt.Printf("JSON: %s\n", string(j)) + + fmt.Printf("JSON encoding is %d bytes\n", len(j)) + fmt.Printf("CBOR encoding is %d bytes\n", len(c)) + + // Output: + // CBOR in hex: 82016a4964656e746966696572 + // CBOR in edn: [1, "Identifier"] + // JSON: {"id":1,"typeOf":"int64","name":"Identifier"} + // JSON encoding is 45 bytes + // CBOR encoding is 13 bytes +} +``` + +

+ +
🔎  Example encoding 3-level nested Go struct to 1 byte CBOR

https://go.dev/play/p/YxwvfPdFQG2 @@ -382,13 +479,13 @@ JSON: {"Foo":{"Qux":{}}}

-
Example using several struct tags

+

🔎  Example using struct tag options

![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")

-Struct tags simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys. +Struct tag options simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys. ### CBOR Tags @@ -404,7 +501,7 @@ em, err := opts.EncModeWithSharedTags(ts) // mutable shared CBOR tags `TagSet` and modes using it are safe for concurrent use. Equivalent API is available for `DecMode`. -
Example using TagSet and TagOptions

+

🔎  Example using TagSet and TagOptions

```go // Use signedCWT struct defined in "Decoding CWT" example. @@ -430,16 +527,149 @@ if err := dm.Unmarshal(data, &v); err != nil { em, _ := cbor.EncOptions{}.EncModeWithTags(tags) // Marshal signedCWT with tag number. -if data, err := cbor.Marshal(v); err != nil { +if data, err := em.Marshal(v); err != nil { return err } ```

+👉 `fxamacker/cbor` allows user apps to use almost any current or future CBOR tag number by implementing `cbor.Marshaler` and `cbor.Unmarshaler` interfaces. + +Basically, `MarshalCBOR` and `UnmarshalCBOR` functions can be implemented by user apps and those functions will automatically be called by this CBOR codec's `Marshal`, `Unmarshal`, etc. + +The following [example](https://github.com/fxamacker/cbor/blob/master/example_embedded_json_tag_for_cbor_test.go) shows how to encode and decode a tagged CBOR data item with tag number 262. The tag content is a JSON object "embedded" as a CBOR byte string (major type 2). + +
🔎  Example using Embedded JSON Tag for CBOR (tag 262) + +```go +// https://github.com/fxamacker/cbor/issues/657 + +package cbor_test + +// NOTE: RFC 8949 does not mention tag number 262. IANA assigned +// CBOR tag number 262 as "Embedded JSON Object" specified by the +// document Embedded JSON Tag for CBOR: +// +// "Tag 262 can be applied to a byte string (major type 2) to indicate +// that the byte string is a JSON Object. The length of the byte string +// indicates the content." +// +// For more info, see Embedded JSON Tag for CBOR at: +// https://github.com/toravir/CBOR-Tag-Specs/blob/master/embeddedJSON.md + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/fxamacker/cbor/v2" +) + +// cborTagNumForEmbeddedJSON is the CBOR tag number 262. +const cborTagNumForEmbeddedJSON = 262 + +// EmbeddedJSON represents a Go value to be encoded as a tagged CBOR data item +// with tag number 262 and the tag content is a JSON object "embedded" as a +// CBOR byte string (major type 2). +type EmbeddedJSON struct { + any +} + +func NewEmbeddedJSON(val any) EmbeddedJSON { + return EmbeddedJSON{val} +} + +// MarshalCBOR encodes EmbeddedJSON to a tagged CBOR data item with the +// tag number 262 and the tag content is a JSON object that is +// "embedded" as a CBOR byte string. +func (v EmbeddedJSON) MarshalCBOR() ([]byte, error) { + // Encode v to JSON object. + data, err := json.Marshal(v) + if err != nil { + return nil, err + } + + // Create cbor.Tag representing a tagged CBOR data item. + tag := cbor.Tag{ + Number: cborTagNumForEmbeddedJSON, + Content: data, + } + + // Marshal to a tagged CBOR data item. + return cbor.Marshal(tag) +} + +// UnmarshalCBOR decodes a tagged CBOR data item to EmbeddedJSON. +// The byte slice provided to this function must contain a single +// tagged CBOR data item with the tag number 262 and tag content +// must be a JSON object "embedded" as a CBOR byte string. +func (v *EmbeddedJSON) UnmarshalCBOR(b []byte) error { + // Unmarshal tagged CBOR data item. + var tag cbor.Tag + if err := cbor.Unmarshal(b, &tag); err != nil { + return err + } + + // Check tag number. + if tag.Number != cborTagNumForEmbeddedJSON { + return fmt.Errorf("got tag number %d, expect tag number %d", tag.Number, cborTagNumForEmbeddedJSON) + } + + // Check tag content. + jsonData, isByteString := tag.Content.([]byte) + if !isByteString { + return fmt.Errorf("got tag content type %T, expect tag content []byte", tag.Content) + } + + // Unmarshal JSON object. + return json.Unmarshal(jsonData, v) +} + +// MarshalJSON encodes EmbeddedJSON to a JSON object. +func (v EmbeddedJSON) MarshalJSON() ([]byte, error) { + return json.Marshal(v.any) +} + +// UnmarshalJSON decodes a JSON object. +func (v *EmbeddedJSON) UnmarshalJSON(b []byte) error { + dec := json.NewDecoder(bytes.NewReader(b)) + dec.UseNumber() + return dec.Decode(&v.any) +} + +func Example_embeddedJSONTagForCBOR() { + value := NewEmbeddedJSON(map[string]any{ + "name": "gopher", + "id": json.Number("42"), + }) + + data, err := cbor.Marshal(value) + if err != nil { + panic(err) + } + + fmt.Printf("cbor: %x\n", data) + + var v EmbeddedJSON + err = cbor.Unmarshal(data, &v) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", v.any) + for k, v := range v.any.(map[string]any) { + fmt.Printf(" %s: %v (%T)\n", k, v, v) + } +} +``` + +
+ + ### Functions and Interfaces -
Functions and interfaces at a glance

+

🔎  Functions and interfaces at a glance

Common functions with same API as `encoding/json`: - `Marshal`, `Unmarshal` @@ -453,7 +683,7 @@ because RFC 8949 treats CBOR data item with remaining bytes as malformed. Other useful functions: - `Diagnose`, `DiagnoseFirst` produce human-readable [Extended Diagnostic Notation](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G) from CBOR data. - `UnmarshalFirst` decodes first CBOR data item and return any remaining bytes. -- `Wellformed` returns true if the the CBOR data item is well-formed. +- `Wellformed` returns true if the CBOR data item is well-formed. Interfaces identical or comparable to Go `encoding` packages include: `Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`. @@ -472,15 +702,28 @@ Default limits may need to be increased for systems handling very large data (e. ## Status -v2.7.0 (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. +[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. +- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string. +- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function. +- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR. + +v2.9.0 passed fuzz tests and is production quality. + +The minimum version of Go required to build: +- v2.8.0 and newer releases require go 1.20+. +- v2.7.1 and older releases require go 1.17+. For more details, see [release notes](https://github.com/fxamacker/cbor/releases). -### Prior Release +### Prior Releases + +[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. + +[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. [v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. -v2.5.0 was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). +[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). __IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading. @@ -489,7 +732,7 @@ See [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0 See ["Version and API Changes"](https://github.com/fxamacker/cbor#versions-and-api-changes) section for more info about version numbering, etc. - {{ .csrfField }} - - - - - ` - - var t = template.Must(template.New("signup_form.tmpl").Parse(form)) - - func main() { - r := mux.NewRouter() - r.HandleFunc("/signup", ShowSignupForm) - // All POST requests without a valid token will return HTTP 403 Forbidden. - // We should also ensure that our mutating (non-idempotent) handler only - // matches on POST requests. We can check that here, at the router level, or - // within the handler itself via r.Method. - r.HandleFunc("/signup/post", SubmitSignupForm).Methods("POST") - - // Add the middleware to your router by wrapping it. - http.ListenAndServe(":8000", - csrf.Protect([]byte("32-byte-long-auth-key"))(r)) - // PS: Don't forget to pass csrf.Secure(false) if you're developing locally - // over plain HTTP (just don't leave it on in production). - } - - func ShowSignupForm(w http.ResponseWriter, r *http.Request) { - // signup_form.tmpl just needs a {{ .csrfField }} template tag for - // csrf.TemplateField to inject the CSRF token into. Easy! - t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{}{ - csrf.TemplateTag: csrf.TemplateField(r), - }) - } - - func SubmitSignupForm(w http.ResponseWriter, r *http.Request) { - // We can trust that requests making it this far have satisfied - // our CSRF protection requirements. - fmt.Fprintf(w, "%v\n", r.PostForm) - } - -Note that the CSRF middleware will (by necessity) consume the request body if the -token is passed via POST form values. If you need to consume this in your -handler, insert your own middleware earlier in the chain to capture the request -body. - -You can also send the CSRF token in the response header. This approach is useful -if you're using a front-end JavaScript framework like Ember or Angular, or are -providing a JSON API: - - package main - - import ( - "github.com/gorilla/csrf" - "github.com/gorilla/mux" - ) - - func main() { - r := mux.NewRouter() - - api := r.PathPrefix("/api").Subrouter() - api.HandleFunc("/user/:id", GetUser).Methods("GET") - - http.ListenAndServe(":8000", - csrf.Protect([]byte("32-byte-long-auth-key"))(r)) - } - - func GetUser(w http.ResponseWriter, r *http.Request) { - // Authenticate the request, get the id from the route params, - // and fetch the user from the DB, etc. - - // Get the token and pass it in the CSRF header. Our JSON-speaking client - // or JavaScript framework can now read the header and return the token in - // in its own "X-CSRF-Token" request header on the subsequent POST. - w.Header().Set("X-CSRF-Token", csrf.Token(r)) - b, err := json.Marshal(user) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - - w.Write(b) - } - -If you're writing a client that's supposed to mimic browser behavior, make sure to -send back the CSRF cookie (the default name is _gorilla_csrf, but this can be changed -with the CookieName Option) along with either the X-CSRF-Token header or the gorilla.csrf.Token form field. - -In addition: getting CSRF protection right is important, so here's some background: - -* This library generates unique-per-request (masked) tokens as a mitigation -against the BREACH attack (http://breachattack.com/). - -* The 'base' (unmasked) token is stored in the session, which means that -multiple browser tabs won't cause a user problems as their per-request token -is compared with the base token. - -* Operates on a "whitelist only" approach where safe (non-mutating) HTTP methods -(GET, HEAD, OPTIONS, TRACE) are the *only* methods where token validation is not -enforced. - -* The design is based on the battle-tested Django -(https://docs.djangoproject.com/en/1.8/ref/csrf/) and Ruby on Rails -(http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html) -approaches. - -* Cookies are authenticated and based on the securecookie -(https://github.com/gorilla/securecookie) library. They're also Secure (issued -over HTTPS only) and are HttpOnly by default, because sane defaults are -important. - -* Go's `crypto/rand` library is used to generate the 32 byte (256 bit) tokens -and the one-time-pad used for masking them. - -This library does not seek to be adventurous. - -*/ -package csrf diff --git a/vendor/github.com/gorilla/csrf/helpers.go b/vendor/github.com/gorilla/csrf/helpers.go deleted file mode 100644 index 99005ee..0000000 --- a/vendor/github.com/gorilla/csrf/helpers.go +++ /dev/null @@ -1,207 +0,0 @@ -package csrf - -import ( - "crypto/rand" - "crypto/subtle" - "encoding/base64" - "fmt" - "html/template" - "net/http" - "net/url" -) - -// Token returns a masked CSRF token ready for passing into HTML template or -// a JSON response body. An empty token will be returned if the middleware -// has not been applied (which will fail subsequent validation). -func Token(r *http.Request) string { - if val, err := contextGet(r, tokenKey); err == nil { - if maskedToken, ok := val.(string); ok { - return maskedToken - } - } - - return "" -} - -// FailureReason makes CSRF validation errors available in the request context. -// This is useful when you want to log the cause of the error or report it to -// client. -func FailureReason(r *http.Request) error { - if val, err := contextGet(r, errorKey); err == nil { - if err, ok := val.(error); ok { - return err - } - } - - return nil -} - -// UnsafeSkipCheck will skip the CSRF check for any requests. This must be -// called before the CSRF middleware. -// -// Note: You should not set this without otherwise securing the request from -// CSRF attacks. The primary use-case for this function is to turn off CSRF -// checks for non-browser clients using authorization tokens against your API. -func UnsafeSkipCheck(r *http.Request) *http.Request { - return contextSave(r, skipCheckKey, true) -} - -// TemplateField is a template helper for html/template that provides an field -// populated with a CSRF token. -// -// Example: -// -// // The following tag in our form.tmpl template: -// {{ .csrfField }} -// -// // ... becomes: -// -func TemplateField(r *http.Request) template.HTML { - if name, err := contextGet(r, formKey); err == nil { - fragment := fmt.Sprintf(``, - name, Token(r)) - - return template.HTML(fragment) // #nosec G203 - } - - return template.HTML("") -} - -// mask returns a unique-per-request token to mitigate the BREACH attack -// as per http://breachattack.com/#mitigations -// -// The token is generated by XOR'ing a one-time-pad and the base (session) CSRF -// token and returning them together as a 64-byte slice. This effectively -// randomises the token on a per-request basis without breaking multiple browser -// tabs/windows. -func mask(realToken []byte, _ *http.Request) string { - otp, err := generateRandomBytes(tokenLength) - if err != nil { - return "" - } - - // XOR the OTP with the real token to generate a masked token. Append the - // OTP to the front of the masked token to allow unmasking in the subsequent - // request. - return base64.StdEncoding.EncodeToString(append(otp, xorToken(otp, realToken)...)) -} - -// unmask splits the issued token (one-time-pad + masked token) and returns the -// unmasked request token for comparison. -func unmask(issued []byte) []byte { - // Issued tokens are always masked and combined with the pad. - if len(issued) != tokenLength*2 { - return nil - } - - // We now know the length of the byte slice. - otp := issued[tokenLength:] - masked := issued[:tokenLength] - - // Unmask the token by XOR'ing it against the OTP used to mask it. - return xorToken(otp, masked) -} - -// requestToken returns the issued token (pad + masked token) from the HTTP POST -// body or HTTP header. It will return nil if the token fails to decode. -func (cs *csrf) requestToken(r *http.Request) ([]byte, error) { - // 1. Check the HTTP header first. - issued := r.Header.Get(cs.opts.RequestHeader) - - // 2. Fall back to the POST (form) value. - if issued == "" { - issued = r.PostFormValue(cs.opts.FieldName) - } - - // 3. Finally, fall back to the multipart form (if set). - if issued == "" && r.MultipartForm != nil { - vals := r.MultipartForm.Value[cs.opts.FieldName] - - if len(vals) > 0 { - issued = vals[0] - } - } - - // Return nil (equivalent to empty byte slice) if no token was found - if issued == "" { - return nil, nil - } - - // Decode the "issued" (pad + masked) token sent in the request. Return a - // nil byte slice on a decoding error (this will fail upstream). - decoded, err := base64.StdEncoding.DecodeString(issued) - if err != nil { - return nil, err - } - - return decoded, nil -} - -// generateRandomBytes returns securely generated random bytes. -// It will return an error if the system's secure random number generator -// fails to function correctly. -func generateRandomBytes(n int) ([]byte, error) { - b := make([]byte, n) - _, err := rand.Read(b) - // err == nil only if len(b) == n - if err != nil { - return nil, err - } - - return b, nil - -} - -// sameOrigin returns true if URLs a and b share the same origin. The same -// origin is defined as host (which includes the port) and scheme. -func sameOrigin(a, b *url.URL) bool { - return (a.Scheme == b.Scheme && a.Host == b.Host) -} - -// compare securely (constant-time) compares the unmasked token from the request -// against the real token from the session. -func compareTokens(a, b []byte) bool { - // This is required as subtle.ConstantTimeCompare does not check for equal - // lengths in Go versions prior to 1.3. - if len(a) != len(b) { - return false - } - - return subtle.ConstantTimeCompare(a, b) == 1 -} - -// xorToken XORs tokens ([]byte) to provide unique-per-request CSRF tokens. It -// will return a masked token if the base token is XOR'ed with a one-time-pad. -// An unmasked token will be returned if a masked token is XOR'ed with the -// one-time-pad used to mask it. -func xorToken(a, b []byte) []byte { - n := len(a) - if len(b) < n { - n = len(b) - } - - res := make([]byte, n) - - for i := 0; i < n; i++ { - res[i] = a[i] ^ b[i] - } - - return res -} - -// contains is a helper function to check if a string exists in a slice - e.g. -// whether a HTTP method exists in a list of safe methods. -func contains(vals []string, s string) bool { - for _, v := range vals { - if v == s { - return true - } - } - - return false -} - -// envError stores a CSRF error in the request context. -func envError(r *http.Request, err error) *http.Request { - return contextSave(r, errorKey, err) -} diff --git a/vendor/github.com/gorilla/csrf/options.go b/vendor/github.com/gorilla/csrf/options.go deleted file mode 100644 index c61d301..0000000 --- a/vendor/github.com/gorilla/csrf/options.go +++ /dev/null @@ -1,171 +0,0 @@ -package csrf - -import ( - "net/http" -) - -// Option describes a functional option for configuring the CSRF handler. -type Option func(*csrf) - -// MaxAge sets the maximum age (in seconds) of a CSRF token's underlying cookie. -// Defaults to 12 hours. Call csrf.MaxAge(0) to explicitly set session-only -// cookies. -func MaxAge(age int) Option { - return func(cs *csrf) { - cs.opts.MaxAge = age - } -} - -// Domain sets the cookie domain. Defaults to the current domain of the request -// only (recommended). -// -// This should be a hostname and not a URL. If set, the domain is treated as -// being prefixed with a '.' - e.g. "example.com" becomes ".example.com" and -// matches "www.example.com" and "secure.example.com". -func Domain(domain string) Option { - return func(cs *csrf) { - cs.opts.Domain = domain - } -} - -// Path sets the cookie path. Defaults to the path the cookie was issued from -// (recommended). -// -// This instructs clients to only respond with cookie for that path and its -// subpaths - i.e. a cookie issued from "/register" would be included in requests -// to "/register/step2" and "/register/submit". -func Path(p string) Option { - return func(cs *csrf) { - cs.opts.Path = p - } -} - -// Secure sets the 'Secure' flag on the cookie. Defaults to true (recommended). -// Set this to 'false' in your development environment otherwise the cookie won't -// be sent over an insecure channel. Setting this via the presence of a 'DEV' -// environmental variable is a good way of making sure this won't make it to a -// production environment. -func Secure(s bool) Option { - return func(cs *csrf) { - cs.opts.Secure = s - } -} - -// HttpOnly sets the 'HttpOnly' flag on the cookie. Defaults to true (recommended). -func HttpOnly(h bool) Option { - return func(cs *csrf) { - // Note that the function and field names match the case of the - // related http.Cookie field instead of the "correct" HTTPOnly name - // that golint suggests. - cs.opts.HttpOnly = h - } -} - -// SameSite sets the cookie SameSite attribute. Defaults to blank to maintain -// backwards compatibility, however, Strict is recommended. -// -// SameSite(SameSiteStrictMode) will prevent the cookie from being sent by the -// browser to the target site in all cross-site browsing context, even when -// following a regular link (GET request). -// -// SameSite(SameSiteLaxMode) provides a reasonable balance between security and -// usability for websites that want to maintain user's logged-in session after -// the user arrives from an external link. The session cookie would be allowed -// when following a regular link from an external website while blocking it in -// CSRF-prone request methods (e.g. POST). -// -// This option is only available for go 1.11+. -func SameSite(s SameSiteMode) Option { - return func(cs *csrf) { - cs.opts.SameSite = s - } -} - -// ErrorHandler allows you to change the handler called when CSRF request -// processing encounters an invalid token or request. A typical use would be to -// provide a handler that returns a static HTML file with a HTTP 403 status. By -// default a HTTP 403 status and a plain text CSRF failure reason are served. -// -// Note that a custom error handler can also access the csrf.FailureReason(r) -// function to retrieve the CSRF validation reason from the request context. -func ErrorHandler(h http.Handler) Option { - return func(cs *csrf) { - cs.opts.ErrorHandler = h - } -} - -// RequestHeader allows you to change the request header the CSRF middleware -// inspects. The default is X-CSRF-Token. -func RequestHeader(header string) Option { - return func(cs *csrf) { - cs.opts.RequestHeader = header - } -} - -// FieldName allows you to change the name attribute of the hidden field -// inspected by this package. The default is 'gorilla.csrf.Token'. -func FieldName(name string) Option { - return func(cs *csrf) { - cs.opts.FieldName = name - } -} - -// CookieName changes the name of the CSRF cookie issued to clients. -// -// Note that cookie names should not contain whitespace, commas, semicolons, -// backslashes or control characters as per RFC6265. -func CookieName(name string) Option { - return func(cs *csrf) { - cs.opts.CookieName = name - } -} - -// TrustedOrigins configures a set of origins (Referers) that are considered as trusted. -// This will allow cross-domain CSRF use-cases - e.g. where the front-end is served -// from a different domain than the API server - to correctly pass a CSRF check. -// -// You should only provide origins you own or have full control over. -func TrustedOrigins(origins []string) Option { - return func(cs *csrf) { - cs.opts.TrustedOrigins = origins - } -} - -// setStore sets the store used by the CSRF middleware. -// Note: this is private (for now) to allow for internal API changes. -func setStore(s store) Option { - return func(cs *csrf) { - cs.st = s - } -} - -// parseOptions parses the supplied options functions and returns a configured -// csrf handler. -func parseOptions(h http.Handler, opts ...Option) *csrf { - // Set the handler to call after processing. - cs := &csrf{ - h: h, - } - - // Default to true. See Secure & HttpOnly function comments for rationale. - // Set here to allow package users to override the default. - cs.opts.Secure = true - cs.opts.HttpOnly = true - - // Set SameSite=Lax by default, allowing the CSRF cookie to only be sent on - // top-level navigations. - cs.opts.SameSite = SameSiteLaxMode - - // Default; only override this if the package user explicitly calls MaxAge(0) - cs.opts.MaxAge = defaultAge - - // Range over each options function and apply it - // to our csrf type to configure it. Options functions are - // applied in order, with any conflicting options overriding - // earlier calls. - for _, option := range opts { - option(cs) - } - - return cs -} diff --git a/vendor/github.com/gorilla/csrf/store.go b/vendor/github.com/gorilla/csrf/store.go deleted file mode 100644 index 4e6382b..0000000 --- a/vendor/github.com/gorilla/csrf/store.go +++ /dev/null @@ -1,87 +0,0 @@ -//go:build go1.11 -// +build go1.11 - -package csrf - -import ( - "net/http" - "time" - - "github.com/gorilla/securecookie" -) - -// store represents the session storage used for CSRF tokens. -type store interface { - // Get returns the real CSRF token from the store. - Get(*http.Request) ([]byte, error) - // Save stores the real CSRF token in the store and writes a - // cookie to the http.ResponseWriter. - // For non-cookie stores, the cookie should contain a unique (256 bit) ID - // or key that references the token in the backend store. - // csrf.GenerateRandomBytes is a helper function for generating secure IDs. - Save(token []byte, w http.ResponseWriter) error -} - -// cookieStore is a signed cookie session store for CSRF tokens. -type cookieStore struct { - name string - maxAge int - secure bool - httpOnly bool - path string - domain string - sc *securecookie.SecureCookie - sameSite SameSiteMode -} - -// Get retrieves a CSRF token from the session cookie. It returns an empty token -// if decoding fails (e.g. HMAC validation fails or the named cookie doesn't exist). -func (cs *cookieStore) Get(r *http.Request) ([]byte, error) { - // Retrieve the cookie from the request - cookie, err := r.Cookie(cs.name) - if err != nil { - return nil, err - } - - token := make([]byte, tokenLength) - // Decode the HMAC authenticated cookie. - err = cs.sc.Decode(cs.name, cookie.Value, &token) - if err != nil { - return nil, err - } - - return token, nil -} - -// Save stores the CSRF token in the session cookie. -func (cs *cookieStore) Save(token []byte, w http.ResponseWriter) error { - // Generate an encoded cookie value with the CSRF token. - encoded, err := cs.sc.Encode(cs.name, token) - if err != nil { - return err - } - - cookie := &http.Cookie{ - Name: cs.name, - Value: encoded, - MaxAge: cs.maxAge, - HttpOnly: cs.httpOnly, - Secure: cs.secure, - SameSite: http.SameSite(cs.sameSite), - Path: cs.path, - Domain: cs.domain, - } - - // Set the Expires field on the cookie based on the MaxAge - // If MaxAge <= 0, we don't set the Expires attribute, making the cookie - // session-only. - if cs.maxAge > 0 { - cookie.Expires = time.Now().Add( - time.Duration(cs.maxAge) * time.Second) - } - - // Write the authenticated cookie to the response. - http.SetCookie(w, cookie) - - return nil -} diff --git a/vendor/github.com/gorilla/csrf/store_legacy.go b/vendor/github.com/gorilla/csrf/store_legacy.go deleted file mode 100644 index 4e1fb9e..0000000 --- a/vendor/github.com/gorilla/csrf/store_legacy.go +++ /dev/null @@ -1,88 +0,0 @@ -//go:build !go1.11 -// +build !go1.11 - -// file for compatibility with go versions prior to 1.11 - -package csrf - -import ( - "net/http" - "time" - - "github.com/gorilla/securecookie" -) - -// store represents the session storage used for CSRF tokens. -type store interface { - // Get returns the real CSRF token from the store. - Get(*http.Request) ([]byte, error) - // Save stores the real CSRF token in the store and writes a - // cookie to the http.ResponseWriter. - // For non-cookie stores, the cookie should contain a unique (256 bit) ID - // or key that references the token in the backend store. - // csrf.GenerateRandomBytes is a helper function for generating secure IDs. - Save(token []byte, w http.ResponseWriter) error -} - -// cookieStore is a signed cookie session store for CSRF tokens. -type cookieStore struct { - name string - maxAge int - secure bool - httpOnly bool - path string - domain string - sc *securecookie.SecureCookie - sameSite SameSiteMode -} - -// Get retrieves a CSRF token from the session cookie. It returns an empty token -// if decoding fails (e.g. HMAC validation fails or the named cookie doesn't exist). -func (cs *cookieStore) Get(r *http.Request) ([]byte, error) { - // Retrieve the cookie from the request - cookie, err := r.Cookie(cs.name) - if err != nil { - return nil, err - } - - token := make([]byte, tokenLength) - // Decode the HMAC authenticated cookie. - err = cs.sc.Decode(cs.name, cookie.Value, &token) - if err != nil { - return nil, err - } - - return token, nil -} - -// Save stores the CSRF token in the session cookie. -func (cs *cookieStore) Save(token []byte, w http.ResponseWriter) error { - // Generate an encoded cookie value with the CSRF token. - encoded, err := cs.sc.Encode(cs.name, token) - if err != nil { - return err - } - - cookie := &http.Cookie{ - Name: cs.name, - Value: encoded, - MaxAge: cs.maxAge, - HttpOnly: cs.httpOnly, - Secure: cs.secure, - Path: cs.path, - Domain: cs.domain, - } - - // Set the Expires field on the cookie based on the MaxAge - // If MaxAge <= 0, we don't set the Expires attribute, making the cookie - // session-only. - if cs.maxAge > 0 { - cookie.Expires = time.Now().Add( - time.Duration(cs.maxAge) * time.Second) - } - - // Write the authenticated cookie to the response. - http.SetCookie(w, cookie) - - return nil -} diff --git a/vendor/github.com/gorilla/securecookie/.editorconfig b/vendor/github.com/gorilla/securecookie/.editorconfig deleted file mode 100644 index 2940ec9..0000000 --- a/vendor/github.com/gorilla/securecookie/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -; https://editorconfig.org/ - -root = true - -[*] -insert_final_newline = true -charset = utf-8 -trim_trailing_whitespace = true -indent_style = space -indent_size = 2 - -[{Makefile,go.mod,go.sum,*.go,.gitmodules}] -indent_style = tab -indent_size = 4 - -[*.md] -indent_size = 4 -trim_trailing_whitespace = false - -eclint_indent_style = unset diff --git a/vendor/github.com/gorilla/securecookie/.gitignore b/vendor/github.com/gorilla/securecookie/.gitignore deleted file mode 100644 index 84039fe..0000000 --- a/vendor/github.com/gorilla/securecookie/.gitignore +++ /dev/null @@ -1 +0,0 @@ -coverage.coverprofile diff --git a/vendor/github.com/gorilla/securecookie/LICENSE b/vendor/github.com/gorilla/securecookie/LICENSE deleted file mode 100644 index bb9d80b..0000000 --- a/vendor/github.com/gorilla/securecookie/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2023 The Gorilla Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/securecookie/Makefile b/vendor/github.com/gorilla/securecookie/Makefile deleted file mode 100644 index 2b9008a..0000000 --- a/vendor/github.com/gorilla/securecookie/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -GO_LINT=$(shell which golangci-lint 2> /dev/null || echo '') -GO_LINT_URI=github.com/golangci/golangci-lint/cmd/golangci-lint@latest - -GO_SEC=$(shell which gosec 2> /dev/null || echo '') -GO_SEC_URI=github.com/securego/gosec/v2/cmd/gosec@latest - -GO_VULNCHECK=$(shell which govulncheck 2> /dev/null || echo '') -GO_VULNCHECK_URI=golang.org/x/vuln/cmd/govulncheck@latest - -.PHONY: golangci-lint -golangci-lint: - $(if $(GO_LINT), ,go install $(GO_LINT_URI)) - @echo "##### Running golangci-lint" - golangci-lint run -v - -.PHONY: gosec -gosec: - $(if $(GO_SEC), ,go install $(GO_SEC_URI)) - @echo "##### Running gosec" - gosec ./... - -.PHONY: govulncheck -govulncheck: - $(if $(GO_VULNCHECK), ,go install $(GO_VULNCHECK_URI)) - @echo "##### Running govulncheck" - govulncheck ./... - -.PHONY: verify -verify: golangci-lint gosec govulncheck - -.PHONY: test -test: - @echo "##### Running tests" - go test -race -cover -coverprofile=coverage.coverprofile -covermode=atomic -v ./... - -.PHONY: fuzz -fuzz: - @echo "##### Running fuzz tests" - go test -v -fuzz FuzzEncodeDecode -fuzztime 60s diff --git a/vendor/github.com/gorilla/securecookie/README.md b/vendor/github.com/gorilla/securecookie/README.md deleted file mode 100644 index c3b9815..0000000 --- a/vendor/github.com/gorilla/securecookie/README.md +++ /dev/null @@ -1,144 +0,0 @@ -# gorilla/securecookie - -![testing](https://github.com/gorilla/securecookie/actions/workflows/test.yml/badge.svg) -[![codecov](https://codecov.io/github/gorilla/securecookie/branch/main/graph/badge.svg)](https://codecov.io/github/gorilla/securecookie) -[![godoc](https://godoc.org/github.com/gorilla/securecookie?status.svg)](https://godoc.org/github.com/gorilla/securecookie) -[![sourcegraph](https://sourcegraph.com/github.com/gorilla/securecookie/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/securecookie?badge) - -![Gorilla Logo](https://github.com/gorilla/.github/assets/53367916/d92caabf-98e0-473e-bfbf-ab554ba435e5) - -securecookie encodes and decodes authenticated and optionally encrypted -cookie values. - -Secure cookies can't be forged, because their values are validated using HMAC. -When encrypted, the content is also inaccessible to malicious eyes. It is still -recommended that sensitive data not be stored in cookies, and that HTTPS be used -to prevent cookie [replay attacks](https://en.wikipedia.org/wiki/Replay_attack). - -## Examples - -To use it, first create a new SecureCookie instance: - -```go -// Hash keys should be at least 32 bytes long -var hashKey = []byte("very-secret") -// Block keys should be 16 bytes (AES-128) or 32 bytes (AES-256) long. -// Shorter keys may weaken the encryption used. -var blockKey = []byte("a-lot-secret") -var s = securecookie.New(hashKey, blockKey) -``` - -The hashKey is required, used to authenticate the cookie value using HMAC. -It is recommended to use a key with 32 or 64 bytes. - -The blockKey is optional, used to encrypt the cookie value -- set it to nil -to not use encryption. If set, the length must correspond to the block size -of the encryption algorithm. For AES, used by default, valid lengths are -16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. - -Strong keys can be created using the convenience function -`GenerateRandomKey()`. Note that keys created using `GenerateRandomKey()` are not -automatically persisted. New keys will be created when the application is -restarted, and previously issued cookies will not be able to be decoded. - -Once a SecureCookie instance is set, use it to encode a cookie value: - -```go -func SetCookieHandler(w http.ResponseWriter, r *http.Request) { - value := map[string]string{ - "foo": "bar", - } - if encoded, err := s.Encode("cookie-name", value); err == nil { - cookie := &http.Cookie{ - Name: "cookie-name", - Value: encoded, - Path: "/", - Secure: true, - HttpOnly: true, - } - http.SetCookie(w, cookie) - } -} -``` - -Later, use the same SecureCookie instance to decode and validate a cookie -value: - -```go -func ReadCookieHandler(w http.ResponseWriter, r *http.Request) { - if cookie, err := r.Cookie("cookie-name"); err == nil { - value := make(map[string]string) - if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil { - fmt.Fprintf(w, "The value of foo is %q", value["foo"]) - } - } -} -``` - -We stored a map[string]string, but secure cookies can hold any value that -can be encoded using `encoding/gob`. To store custom types, they must be -registered first using gob.Register(). For basic types this is not needed; -it works out of the box. An optional JSON encoder that uses `encoding/json` is -available for types compatible with JSON. - -### Key Rotation -Rotating keys is an important part of any security strategy. The `EncodeMulti` and -`DecodeMulti` functions allow for multiple keys to be rotated in and out. -For example, let's take a system that stores keys in a map: - -```go -// keys stored in a map will not be persisted between restarts -// a more persistent storage should be considered for production applications. -var cookies = map[string]*securecookie.SecureCookie{ - "previous": securecookie.New( - securecookie.GenerateRandomKey(64), - securecookie.GenerateRandomKey(32), - ), - "current": securecookie.New( - securecookie.GenerateRandomKey(64), - securecookie.GenerateRandomKey(32), - ), -} -``` - -Using the current key to encode new cookies: -```go -func SetCookieHandler(w http.ResponseWriter, r *http.Request) { - value := map[string]string{ - "foo": "bar", - } - if encoded, err := securecookie.EncodeMulti("cookie-name", value, cookies["current"]); err == nil { - cookie := &http.Cookie{ - Name: "cookie-name", - Value: encoded, - Path: "/", - } - http.SetCookie(w, cookie) - } -} -``` - -Later, decode cookies. Check against all valid keys: -```go -func ReadCookieHandler(w http.ResponseWriter, r *http.Request) { - if cookie, err := r.Cookie("cookie-name"); err == nil { - value := make(map[string]string) - err = securecookie.DecodeMulti("cookie-name", cookie.Value, &value, cookies["current"], cookies["previous"]) - if err == nil { - fmt.Fprintf(w, "The value of foo is %q", value["foo"]) - } - } -} -``` - -Rotate the keys. This strategy allows previously issued cookies to be valid until the next rotation: -```go -func Rotate(newCookie *securecookie.SecureCookie) { - cookies["previous"] = cookies["current"] - cookies["current"] = newCookie -} -``` - -## License - -BSD licensed. See the LICENSE file for details. diff --git a/vendor/github.com/gorilla/securecookie/doc.go b/vendor/github.com/gorilla/securecookie/doc.go deleted file mode 100644 index ae89408..0000000 --- a/vendor/github.com/gorilla/securecookie/doc.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2012 The Gorilla 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 securecookie encodes and decodes authenticated and optionally -encrypted cookie values. - -Secure cookies can't be forged, because their values are validated using HMAC. -When encrypted, the content is also inaccessible to malicious eyes. - -To use it, first create a new SecureCookie instance: - - var hashKey = []byte("very-secret") - var blockKey = []byte("a-lot-secret") - var s = securecookie.New(hashKey, blockKey) - -The hashKey is required, used to authenticate the cookie value using HMAC. -It is recommended to use a key with 32 or 64 bytes. - -The blockKey is optional, used to encrypt the cookie value -- set it to nil -to not use encryption. If set, the length must correspond to the block size -of the encryption algorithm. For AES, used by default, valid lengths are -16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. - -Strong keys can be created using the convenience function GenerateRandomKey(). - -Once a SecureCookie instance is set, use it to encode a cookie value: - - func SetCookieHandler(w http.ResponseWriter, r *http.Request) { - value := map[string]string{ - "foo": "bar", - } - if encoded, err := s.Encode("cookie-name", value); err == nil { - cookie := &http.Cookie{ - Name: "cookie-name", - Value: encoded, - Path: "/", - } - http.SetCookie(w, cookie) - } - } - -Later, use the same SecureCookie instance to decode and validate a cookie -value: - - func ReadCookieHandler(w http.ResponseWriter, r *http.Request) { - if cookie, err := r.Cookie("cookie-name"); err == nil { - value := make(map[string]string) - if err = s2.Decode("cookie-name", cookie.Value, &value); err == nil { - fmt.Fprintf(w, "The value of foo is %q", value["foo"]) - } - } - } - -We stored a map[string]string, but secure cookies can hold any value that -can be encoded using encoding/gob. To store custom types, they must be -registered first using gob.Register(). For basic types this is not needed; -it works out of the box. -*/ -package securecookie diff --git a/vendor/github.com/gorilla/securecookie/securecookie.go b/vendor/github.com/gorilla/securecookie/securecookie.go deleted file mode 100644 index 4d5ea86..0000000 --- a/vendor/github.com/gorilla/securecookie/securecookie.go +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright 2012 The Gorilla 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 securecookie - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "crypto/subtle" - "encoding/base64" - "encoding/gob" - "encoding/json" - "fmt" - "hash" - "io" - "strconv" - "strings" - "time" -) - -// Error is the interface of all errors returned by functions in this library. -type Error interface { - error - - // IsUsage returns true for errors indicating the client code probably - // uses this library incorrectly. For example, the client may have - // failed to provide a valid hash key, or may have failed to configure - // the Serializer adequately for encoding value. - IsUsage() bool - - // IsDecode returns true for errors indicating that a cookie could not - // be decoded and validated. Since cookies are usually untrusted - // user-provided input, errors of this type should be expected. - // Usually, the proper action is simply to reject the request. - IsDecode() bool - - // IsInternal returns true for unexpected errors occurring in the - // securecookie implementation. - IsInternal() bool - - // Cause, if it returns a non-nil value, indicates that this error was - // propagated from some underlying library. If this method returns nil, - // this error was raised directly by this library. - // - // Cause is provided principally for debugging/logging purposes; it is - // rare that application logic should perform meaningfully different - // logic based on Cause. See, for example, the caveats described on - // (MultiError).Cause(). - Cause() error -} - -// errorType is a bitmask giving the error type(s) of an cookieError value. -type errorType int - -const ( - usageError = errorType(1 << iota) - decodeError - internalError -) - -type cookieError struct { - typ errorType - msg string - cause error -} - -func (e cookieError) IsUsage() bool { return (e.typ & usageError) != 0 } -func (e cookieError) IsDecode() bool { return (e.typ & decodeError) != 0 } -func (e cookieError) IsInternal() bool { return (e.typ & internalError) != 0 } - -func (e cookieError) Cause() error { return e.cause } - -func (e cookieError) Error() string { - parts := []string{"securecookie: "} - if e.msg == "" { - parts = append(parts, "error") - } else { - parts = append(parts, e.msg) - } - if c := e.Cause(); c != nil { - parts = append(parts, " - caused by: ", c.Error()) - } - return strings.Join(parts, "") -} - -var ( - errGeneratingIV = cookieError{typ: internalError, msg: "failed to generate random iv"} - - errNoCodecs = cookieError{typ: usageError, msg: "no codecs provided"} - errHashKeyNotSet = cookieError{typ: usageError, msg: "hash key is not set"} - errBlockKeyNotSet = cookieError{typ: usageError, msg: "block key is not set"} - errEncodedValueTooLong = cookieError{typ: usageError, msg: "the value is too long"} - - errValueToDecodeTooLong = cookieError{typ: decodeError, msg: "the value is too long"} - errTimestampInvalid = cookieError{typ: decodeError, msg: "invalid timestamp"} - errTimestampTooNew = cookieError{typ: decodeError, msg: "timestamp is too new"} - errTimestampExpired = cookieError{typ: decodeError, msg: "expired timestamp"} - errDecryptionFailed = cookieError{typ: decodeError, msg: "the value could not be decrypted"} - errValueNotByte = cookieError{typ: decodeError, msg: "value not a []byte."} - errValueNotBytePtr = cookieError{typ: decodeError, msg: "value not a pointer to []byte."} - - // ErrMacInvalid indicates that cookie decoding failed because the HMAC - // could not be extracted and verified. Direct use of this error - // variable is deprecated; it is public only for legacy compatibility, - // and may be privatized in the future, as it is rarely useful to - // distinguish between this error and other Error implementations. - ErrMacInvalid = cookieError{typ: decodeError, msg: "the value is not valid"} -) - -// Codec defines an interface to encode and decode cookie values. -type Codec interface { - Encode(name string, value interface{}) (string, error) - Decode(name, value string, dst interface{}) error -} - -// New returns a new SecureCookie. -// -// hashKey is required, used to authenticate values using HMAC. Create it using -// GenerateRandomKey(). It is recommended to use a key with 32 or 64 bytes. -// -// blockKey is optional, used to encrypt values. Create it using -// GenerateRandomKey(). The key length must correspond to the key size -// of the encryption algorithm. For AES, used by default, valid lengths are -// 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256. -// The default encoder used for cookie serialization is encoding/gob. -// -// Note that keys created using GenerateRandomKey() are not automatically -// persisted. New keys will be created when the application is restarted, and -// previously issued cookies will not be able to be decoded. -func New(hashKey, blockKey []byte) *SecureCookie { - s := &SecureCookie{ - hashKey: hashKey, - blockKey: blockKey, - hashFunc: sha256.New, - maxAge: 86400 * 30, - maxLength: 4096, - sz: GobEncoder{}, - } - if len(hashKey) == 0 { - s.err = errHashKeyNotSet - } - if blockKey != nil { - s.BlockFunc(aes.NewCipher) - } - return s -} - -// SecureCookie encodes and decodes authenticated and optionally encrypted -// cookie values. -type SecureCookie struct { - hashKey []byte - hashFunc func() hash.Hash - blockKey []byte - block cipher.Block - maxLength int - maxAge int64 - minAge int64 - err error - sz Serializer - // For testing purposes, the function that returns the current timestamp. - // If not set, it will use time.Now().UTC().Unix(). - timeFunc func() int64 -} - -// Serializer provides an interface for providing custom serializers for cookie -// values. -type Serializer interface { - Serialize(src interface{}) ([]byte, error) - Deserialize(src []byte, dst interface{}) error -} - -// GobEncoder encodes cookie values using encoding/gob. This is the simplest -// encoder and can handle complex types via gob.Register. -type GobEncoder struct{} - -// JSONEncoder encodes cookie values using encoding/json. Users who wish to -// encode complex types need to satisfy the json.Marshaller and -// json.Unmarshaller interfaces. -type JSONEncoder struct{} - -// NopEncoder does not encode cookie values, and instead simply accepts a []byte -// (as an interface{}) and returns a []byte. This is particularly useful when -// you encoding an object upstream and do not wish to re-encode it. -type NopEncoder struct{} - -// MaxLength restricts the maximum length, in bytes, for the cookie value. -// -// Default is 4096, which is the maximum value accepted by Internet Explorer. -func (s *SecureCookie) MaxLength(value int) *SecureCookie { - s.maxLength = value - return s -} - -// MaxAge restricts the maximum age, in seconds, for the cookie value. -// -// Default is 86400 * 30. Set it to 0 for no restriction. -func (s *SecureCookie) MaxAge(value int) *SecureCookie { - s.maxAge = int64(value) - return s -} - -// MinAge restricts the minimum age, in seconds, for the cookie value. -// -// Default is 0 (no restriction). -func (s *SecureCookie) MinAge(value int) *SecureCookie { - s.minAge = int64(value) - return s -} - -// HashFunc sets the hash function used to create HMAC. -// -// Default is crypto/sha256.New. -func (s *SecureCookie) HashFunc(f func() hash.Hash) *SecureCookie { - s.hashFunc = f - return s -} - -// BlockFunc sets the encryption function used to create a cipher.Block. -// -// Default is crypto/aes.New. -func (s *SecureCookie) BlockFunc(f func([]byte) (cipher.Block, error)) *SecureCookie { - if s.blockKey == nil { - s.err = errBlockKeyNotSet - } else if block, err := f(s.blockKey); err == nil { - s.block = block - } else { - s.err = cookieError{cause: err, typ: usageError} - } - return s -} - -// Encoding sets the encoding/serialization method for cookies. -// -// Default is encoding/gob. To encode special structures using encoding/gob, -// they must be registered first using gob.Register(). -func (s *SecureCookie) SetSerializer(sz Serializer) *SecureCookie { - s.sz = sz - - return s -} - -// Encode encodes a cookie value. -// -// It serializes, optionally encrypts, signs with a message authentication code, -// and finally encodes the value. -// -// The name argument is the cookie name. It is stored with the encoded value. -// The value argument is the value to be encoded. It can be any value that can -// be encoded using the currently selected serializer; see SetSerializer(). -// -// It is the client's responsibility to ensure that value, when encoded using -// the current serialization/encryption settings on s and then base64-encoded, -// is shorter than the maximum permissible length. -func (s *SecureCookie) Encode(name string, value interface{}) (string, error) { - if s.err != nil { - return "", s.err - } - if s.hashKey == nil { - s.err = errHashKeyNotSet - return "", s.err - } - var err error - var b []byte - // 1. Serialize. - if b, err = s.sz.Serialize(value); err != nil { - return "", cookieError{cause: err, typ: usageError} - } - // 2. Encrypt (optional). - if s.block != nil { - if b, err = encrypt(s.block, b); err != nil { - return "", cookieError{cause: err, typ: usageError} - } - } - b = encode(b) - // 3. Create MAC for "name|date|value". Extra pipe to be used later. - b = []byte(fmt.Sprintf("%s|%d|%s|", name, s.timestamp(), b)) - mac := createMac(hmac.New(s.hashFunc, s.hashKey), b[:len(b)-1]) - // Append mac, remove name. - b = append(b, mac...)[len(name)+1:] - // 4. Encode to base64. - b = encode(b) - // 5. Check length. - if s.maxLength != 0 && len(b) > s.maxLength { - return "", fmt.Errorf("%s: %d", errEncodedValueTooLong, len(b)) - } - // Done. - return string(b), nil -} - -// Decode decodes a cookie value. -// -// It decodes, verifies a message authentication code, optionally decrypts and -// finally deserializes the value. -// -// The name argument is the cookie name. It must be the same name used when -// it was stored. The value argument is the encoded cookie value. The dst -// argument is where the cookie will be decoded. It must be a pointer. -func (s *SecureCookie) Decode(name, value string, dst interface{}) error { - if s.err != nil { - return s.err - } - if s.hashKey == nil { - s.err = errHashKeyNotSet - return s.err - } - // 1. Check length. - if s.maxLength != 0 && len(value) > s.maxLength { - return fmt.Errorf("%s: %d", errValueToDecodeTooLong, len(value)) - } - // 2. Decode from base64. - b, err := decode([]byte(value)) - if err != nil { - return err - } - // 3. Verify MAC. Value is "date|value|mac". - parts := bytes.SplitN(b, []byte("|"), 3) - if len(parts) != 3 { - return ErrMacInvalid - } - h := hmac.New(s.hashFunc, s.hashKey) - b = append([]byte(name+"|"), b[:len(b)-len(parts[2])-1]...) - if err = verifyMac(h, b, parts[2]); err != nil { - return err - } - // 4. Verify date ranges. - var t1 int64 - if t1, err = strconv.ParseInt(string(parts[0]), 10, 64); err != nil { - return errTimestampInvalid - } - t2 := s.timestamp() - if s.minAge != 0 && t1 > t2-s.minAge { - return errTimestampTooNew - } - if s.maxAge != 0 && t1 < t2-s.maxAge { - return errTimestampExpired - } - // 5. Decrypt (optional). - b, err = decode(parts[1]) - if err != nil { - return err - } - if s.block != nil { - if b, err = decrypt(s.block, b); err != nil { - return err - } - } - // 6. Deserialize. - if err = s.sz.Deserialize(b, dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - // Done. - return nil -} - -// timestamp returns the current timestamp, in seconds. -// -// For testing purposes, the function that generates the timestamp can be -// overridden. If not set, it will return time.Now().UTC().Unix(). -func (s *SecureCookie) timestamp() int64 { - if s.timeFunc == nil { - return time.Now().UTC().Unix() - } - return s.timeFunc() -} - -// Authentication ------------------------------------------------------------- - -// createMac creates a message authentication code (MAC). -func createMac(h hash.Hash, value []byte) []byte { - h.Write(value) - return h.Sum(nil) -} - -// verifyMac verifies that a message authentication code (MAC) is valid. -func verifyMac(h hash.Hash, value []byte, mac []byte) error { - mac2 := createMac(h, value) - // Check that both MACs are of equal length, as subtle.ConstantTimeCompare - // does not do this prior to Go 1.4. - if len(mac) == len(mac2) && subtle.ConstantTimeCompare(mac, mac2) == 1 { - return nil - } - return ErrMacInvalid -} - -// Encryption ----------------------------------------------------------------- - -// encrypt encrypts a value using the given block in counter mode. -// -// A random initialization vector ( https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV) ) with the length of the -// block size is prepended to the resulting ciphertext. -func encrypt(block cipher.Block, value []byte) ([]byte, error) { - iv := GenerateRandomKey(block.BlockSize()) - if iv == nil { - return nil, errGeneratingIV - } - // Encrypt it. - stream := cipher.NewCTR(block, iv) - stream.XORKeyStream(value, value) - // Return iv + ciphertext. - return append(iv, value...), nil -} - -// decrypt decrypts a value using the given block in counter mode. -// -// The value to be decrypted must be prepended by a initialization vector -// ( https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_(IV) ) with the length of the block size. -func decrypt(block cipher.Block, value []byte) ([]byte, error) { - size := block.BlockSize() - if len(value) > size { - // Extract iv. - iv := value[:size] - // Extract ciphertext. - value = value[size:] - // Decrypt it. - stream := cipher.NewCTR(block, iv) - stream.XORKeyStream(value, value) - return value, nil - } - return nil, errDecryptionFailed -} - -// Serialization -------------------------------------------------------------- - -// Serialize encodes a value using gob. -func (e GobEncoder) Serialize(src interface{}) ([]byte, error) { - buf := new(bytes.Buffer) - enc := gob.NewEncoder(buf) - if err := enc.Encode(src); err != nil { - return nil, cookieError{cause: err, typ: usageError} - } - return buf.Bytes(), nil -} - -// Deserialize decodes a value using gob. -func (e GobEncoder) Deserialize(src []byte, dst interface{}) error { - dec := gob.NewDecoder(bytes.NewBuffer(src)) - if err := dec.Decode(dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - return nil -} - -// Serialize encodes a value using encoding/json. -func (e JSONEncoder) Serialize(src interface{}) ([]byte, error) { - buf := new(bytes.Buffer) - enc := json.NewEncoder(buf) - if err := enc.Encode(src); err != nil { - return nil, cookieError{cause: err, typ: usageError} - } - return buf.Bytes(), nil -} - -// Deserialize decodes a value using encoding/json. -func (e JSONEncoder) Deserialize(src []byte, dst interface{}) error { - dec := json.NewDecoder(bytes.NewReader(src)) - if err := dec.Decode(dst); err != nil { - return cookieError{cause: err, typ: decodeError} - } - return nil -} - -// Serialize passes a []byte through as-is. -func (e NopEncoder) Serialize(src interface{}) ([]byte, error) { - if b, ok := src.([]byte); ok { - return b, nil - } - - return nil, errValueNotByte -} - -// Deserialize passes a []byte through as-is. -func (e NopEncoder) Deserialize(src []byte, dst interface{}) error { - if dat, ok := dst.(*[]byte); ok { - *dat = src - return nil - } - return errValueNotBytePtr -} - -// Encoding ------------------------------------------------------------------- - -// encode encodes a value using base64. -func encode(value []byte) []byte { - encoded := make([]byte, base64.URLEncoding.EncodedLen(len(value))) - base64.URLEncoding.Encode(encoded, value) - return encoded -} - -// decode decodes a cookie using base64. -func decode(value []byte) ([]byte, error) { - decoded := make([]byte, base64.URLEncoding.DecodedLen(len(value))) - b, err := base64.URLEncoding.Decode(decoded, value) - if err != nil { - return nil, cookieError{cause: err, typ: decodeError, msg: "base64 decode failed"} - } - return decoded[:b], nil -} - -// Helpers -------------------------------------------------------------------- - -// GenerateRandomKey creates a random key with the given length in bytes. -// On failure, returns nil. -// -// Note that keys created using `GenerateRandomKey()` are not automatically -// persisted. New keys will be created when the application is restarted, and -// previously issued cookies will not be able to be decoded. -// -// Callers should explicitly check for the possibility of a nil return, treat -// it as a failure of the system random number generator, and not continue. -func GenerateRandomKey(length int) []byte { - k := make([]byte, length) - if _, err := io.ReadFull(rand.Reader, k); err != nil { - return nil - } - return k -} - -// CodecsFromPairs returns a slice of SecureCookie instances. -// -// It is a convenience function to create a list of codecs for key rotation. Note -// that the generated Codecs will have the default options applied: callers -// should iterate over each Codec and type-assert the underlying *SecureCookie to -// change these. -// -// Example: -// -// codecs := securecookie.CodecsFromPairs( -// []byte("new-hash-key"), -// []byte("new-block-key"), -// []byte("old-hash-key"), -// []byte("old-block-key"), -// ) -// -// // Modify each instance. -// for _, s := range codecs { -// if cookie, ok := s.(*securecookie.SecureCookie); ok { -// cookie.MaxAge(86400 * 7) -// cookie.SetSerializer(securecookie.JSONEncoder{}) -// cookie.HashFunc(sha512.New512_256) -// } -// } -func CodecsFromPairs(keyPairs ...[]byte) []Codec { - codecs := make([]Codec, len(keyPairs)/2+len(keyPairs)%2) - for i := 0; i < len(keyPairs); i += 2 { - var blockKey []byte - if i+1 < len(keyPairs) { - blockKey = keyPairs[i+1] - } - codecs[i/2] = New(keyPairs[i], blockKey) - } - return codecs -} - -// EncodeMulti encodes a cookie value using a group of codecs. -// -// The codecs are tried in order. Multiple codecs are accepted to allow -// key rotation. -// -// On error, may return a MultiError. -func EncodeMulti(name string, value interface{}, codecs ...Codec) (string, error) { - if len(codecs) == 0 { - return "", errNoCodecs - } - - var errors MultiError - for _, codec := range codecs { - encoded, err := codec.Encode(name, value) - if err == nil { - return encoded, nil - } - errors = append(errors, err) - } - return "", errors -} - -// DecodeMulti decodes a cookie value using a group of codecs. -// -// The codecs are tried in order. Multiple codecs are accepted to allow -// key rotation. -// -// On error, may return a MultiError. -func DecodeMulti(name string, value string, dst interface{}, codecs ...Codec) error { - if len(codecs) == 0 { - return errNoCodecs - } - - var errors MultiError - for _, codec := range codecs { - err := codec.Decode(name, value, dst) - if err == nil { - return nil - } - errors = append(errors, err) - } - return errors -} - -// MultiError groups multiple errors. -type MultiError []error - -func (m MultiError) IsUsage() bool { return m.any(func(e Error) bool { return e.IsUsage() }) } -func (m MultiError) IsDecode() bool { return m.any(func(e Error) bool { return e.IsDecode() }) } -func (m MultiError) IsInternal() bool { return m.any(func(e Error) bool { return e.IsInternal() }) } - -// Cause returns nil for MultiError; there is no unique underlying cause in the -// general case. -// -// Note: we could conceivably return a non-nil Cause only when there is exactly -// one child error with a Cause. However, it would be brittle for client code -// to rely on the arity of causes inside a MultiError, so we have opted not to -// provide this functionality. Clients which really wish to access the Causes -// of the underlying errors are free to iterate through the errors themselves. -func (m MultiError) Cause() error { return nil } - -func (m MultiError) Error() string { - s, n := "", 0 - for _, e := range m { - if e != nil { - if n == 0 { - s = e.Error() - } - n++ - } - } - switch n { - case 0: - return "(0 errors)" - case 1: - return s - case 2: - return s + " (and 1 other error)" - } - return fmt.Sprintf("%s (and %d other errors)", s, n-1) -} - -// any returns true if any element of m is an Error for which pred returns true. -func (m MultiError) any(pred func(Error) bool) bool { - for _, e := range m { - if ourErr, ok := e.(Error); ok && pred(ourErr) { - return true - } - } - return false -} diff --git a/vendor/github.com/huin/goupnp/.gitignore b/vendor/github.com/huin/goupnp/.gitignore new file mode 100644 index 0000000..26031b6 --- /dev/null +++ b/vendor/github.com/huin/goupnp/.gitignore @@ -0,0 +1,3 @@ +*.zip +*.sublime-workspace +*.download \ No newline at end of file diff --git a/vendor/github.com/tailscale/goupnp/GUIDE.md b/vendor/github.com/huin/goupnp/GUIDE.md similarity index 100% rename from vendor/github.com/tailscale/goupnp/GUIDE.md rename to vendor/github.com/huin/goupnp/GUIDE.md diff --git a/vendor/github.com/tailscale/goupnp/LICENSE b/vendor/github.com/huin/goupnp/LICENSE similarity index 100% rename from vendor/github.com/tailscale/goupnp/LICENSE rename to vendor/github.com/huin/goupnp/LICENSE diff --git a/vendor/github.com/huin/goupnp/Makefile b/vendor/github.com/huin/goupnp/Makefile new file mode 100644 index 0000000..3ddd869 --- /dev/null +++ b/vendor/github.com/huin/goupnp/Makefile @@ -0,0 +1,2 @@ +gen: + (cd cmd/goupnpdcpgen/; go install); go generate ./... \ No newline at end of file diff --git a/vendor/github.com/huin/goupnp/README.md b/vendor/github.com/huin/goupnp/README.md new file mode 100644 index 0000000..49bd038 --- /dev/null +++ b/vendor/github.com/huin/goupnp/README.md @@ -0,0 +1,76 @@ +goupnp is a UPnP client library for Go + +## Installation + +Run `go get -u github.com/huin/goupnp`. + +## Documentation + +See [GUIDE.md](GUIDE.md) for a quick start on the most common use case for this +library. + +Supported DCPs (you probably want to start with one of these): + +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) av1](https://godoc.org/github.com/huin/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1. +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway1](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1. +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) internetgateway2](https://godoc.org/github.com/huin/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2. + +Core components: + +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) (goupnp)](https://godoc.org/github.com/huin/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs. +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) httpu](https://godoc.org/github.com/huin/goupnp/httpu) HTTPU implementation, underlies SSDP. +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) ssdp](https://godoc.org/github.com/huin/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network. +- [![GoDoc](https://godoc.org/github.com/huin/goupnp?status.svg) soap](https://godoc.org/github.com/huin/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services. + +## Regenerating dcps generated source code: + +1. Build code generator: + + `go get -u github.com/huin/goupnp/cmd/goupnpdcpgen` + +2. Regenerate the code: + + `go generate ./...` + +## Supporting additional UPnP devices and services: + +Supporting additional services is, in the trivial case, simply a matter of +adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`, +regenerating the source code (see above), and committing that source code. + +However, it would be helpful if anyone needing such a service could test the +service against the service they have, and then reporting any trouble +encountered as an [issue on this +project](https://github.com/huin/goupnp/issues/new). If it just works, then +please report at least minimal working functionality as an issue, and +optionally contribute the metadata upstream. + +## Migrating due to Breaking Changes + +- \#40 introduced a breaking change to handling non-utf8 encodings, but removes a heavy + dependency on `golang.org/x/net` with charset encodings. If this breaks your usage of this + library, you can return to the old behavior by modifying the exported variable and importing + the package yourself: + +```go +import ( + "golang.org/x/net/html/charset" + "github.com/huin/goupnp" +) + +func init() { + // should be modified before goupnp libraries are in use. + goupnp.CharsetReaderFault = charset.NewReaderLabel +} +``` + +## `v2alpha` + +The `v2alpha` subdirectory contains experimental work on a version 2 API. The plan is to eventually +create a `v2` subdirectory with a stable version of the version 2 API. The v1 API will stay where +it currently is. + +> NOTE: +> +> * `v2alpha` will be deleted one day, so don't rely on it always existing. +> * `v2alpha` will have API breaking changes, even with itself. diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go b/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go new file mode 100644 index 0000000..88f8d77 --- /dev/null +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway2/gen.go @@ -0,0 +1,2 @@ +//go:generate goupnpdcpgen -dcp_name internetgateway2 -code_tmpl_file ../dcps.gotemplate +package internetgateway2 diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go b/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go new file mode 100644 index 0000000..42a1578 --- /dev/null +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go @@ -0,0 +1,6889 @@ +// Client for UPnP Device Control Protocol Internet Gateway Device v2. +// +// This DCP is documented in detail at: +// - http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf +// +// Typically, use one of the New* functions to create clients for services. +package internetgateway2 + +// *********************************************************** +// GENERATED FILE - DO NOT EDIT BY HAND. See README.md +// *********************************************************** + +import ( + "context" + "net/url" + "time" + + "github.com/huin/goupnp" + "github.com/huin/goupnp/soap" +) + +// Hack to avoid Go complaining if time isn't used. +var _ time.Time + +// Device URNs: +const ( + URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" + URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" + URN_WANConnectionDevice_2 = "urn:schemas-upnp-org:device:WANConnectionDevice:2" + URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" + URN_WANDevice_2 = "urn:schemas-upnp-org:device:WANDevice:2" +) + +// Service URNs: +const ( + URN_DeviceProtection_1 = "urn:schemas-upnp-org:service:DeviceProtection:1" + URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1" + URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1" + URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1" + URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" + URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1" + URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1" + URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" + URN_WANIPConnection_2 = "urn:schemas-upnp-org:service:WANIPConnection:2" + URN_WANIPv6FirewallControl_1 = "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" + URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1" + URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" +) + +// DeviceProtection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:DeviceProtection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type DeviceProtection1 struct { + goupnp.ServiceClient +} + +// NewDeviceProtection1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewDeviceProtection1ClientsCtx(ctx context.Context) (clients []*DeviceProtection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_DeviceProtection_1); err != nil { + return + } + clients = newDeviceProtection1ClientsFromGenericClients(genericClients) + return +} + +// NewDeviceProtection1Clients is the legacy version of NewDeviceProtection1ClientsCtx, but uses +// context.Background() as the context. +func NewDeviceProtection1Clients() (clients []*DeviceProtection1, errors []error, err error) { + return NewDeviceProtection1ClientsCtx(context.Background()) +} + +// NewDeviceProtection1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewDeviceProtection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*DeviceProtection1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_DeviceProtection_1) + if err != nil { + return nil, err + } + return newDeviceProtection1ClientsFromGenericClients(genericClients), nil +} + +// NewDeviceProtection1ClientsByURL is the legacy version of NewDeviceProtection1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewDeviceProtection1ClientsByURL(loc *url.URL) ([]*DeviceProtection1, error) { + return NewDeviceProtection1ClientsByURLCtx(context.Background(), loc) +} + +// NewDeviceProtection1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewDeviceProtection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*DeviceProtection1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_DeviceProtection_1) + if err != nil { + return nil, err + } + return newDeviceProtection1ClientsFromGenericClients(genericClients), nil +} + +func newDeviceProtection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*DeviceProtection1 { + clients := make([]*DeviceProtection1, len(genericClients)) + for i := range genericClients { + clients[i] = &DeviceProtection1{genericClients[i]} + } + return clients +} + +func (client *DeviceProtection1) AddIdentityListCtx( + ctx context.Context, + IdentityList string, +) (IdentityListResult string, err error) { + // Request structure. + request := &struct { + IdentityList string + }{} + // BEGIN Marshal arguments into request. + + if request.IdentityList, err = soap.MarshalString(IdentityList); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + IdentityListResult string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "AddIdentityList", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if IdentityListResult, err = soap.UnmarshalString(response.IdentityListResult); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// AddIdentityList is the legacy version of AddIdentityListCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) AddIdentityList(IdentityList string) (IdentityListResult string, err error) { + return client.AddIdentityListCtx(context.Background(), + IdentityList, + ) +} + +func (client *DeviceProtection1) AddRolesForIdentityCtx( + ctx context.Context, + Identity string, + RoleList string, +) (err error) { + // Request structure. + request := &struct { + Identity string + RoleList string + }{} + // BEGIN Marshal arguments into request. + + if request.Identity, err = soap.MarshalString(Identity); err != nil { + return + } + if request.RoleList, err = soap.MarshalString(RoleList); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "AddRolesForIdentity", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// AddRolesForIdentity is the legacy version of AddRolesForIdentityCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) AddRolesForIdentity(Identity string, RoleList string) (err error) { + return client.AddRolesForIdentityCtx(context.Background(), + Identity, + RoleList, + ) +} + +func (client *DeviceProtection1) GetACLDataCtx( + ctx context.Context, +) (ACL string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + ACL string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "GetACLData", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if ACL, err = soap.UnmarshalString(response.ACL); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetACLData is the legacy version of GetACLDataCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) GetACLData() (ACL string, err error) { + return client.GetACLDataCtx(context.Background()) +} + +func (client *DeviceProtection1) GetAssignedRolesCtx( + ctx context.Context, +) (RoleList string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + RoleList string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "GetAssignedRoles", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if RoleList, err = soap.UnmarshalString(response.RoleList); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAssignedRoles is the legacy version of GetAssignedRolesCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) GetAssignedRoles() (RoleList string, err error) { + return client.GetAssignedRolesCtx(context.Background()) +} + +func (client *DeviceProtection1) GetRolesForActionCtx( + ctx context.Context, + DeviceUDN string, + ServiceId string, + ActionName string, +) (RoleList string, RestrictedRoleList string, err error) { + // Request structure. + request := &struct { + DeviceUDN string + ServiceId string + ActionName string + }{} + // BEGIN Marshal arguments into request. + + if request.DeviceUDN, err = soap.MarshalString(DeviceUDN); err != nil { + return + } + if request.ServiceId, err = soap.MarshalString(ServiceId); err != nil { + return + } + if request.ActionName, err = soap.MarshalString(ActionName); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + RoleList string + RestrictedRoleList string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "GetRolesForAction", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if RoleList, err = soap.UnmarshalString(response.RoleList); err != nil { + return + } + if RestrictedRoleList, err = soap.UnmarshalString(response.RestrictedRoleList); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetRolesForAction is the legacy version of GetRolesForActionCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) GetRolesForAction(DeviceUDN string, ServiceId string, ActionName string) (RoleList string, RestrictedRoleList string, err error) { + return client.GetRolesForActionCtx(context.Background(), + DeviceUDN, + ServiceId, + ActionName, + ) +} + +func (client *DeviceProtection1) GetSupportedProtocolsCtx( + ctx context.Context, +) (ProtocolList string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + ProtocolList string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "GetSupportedProtocols", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if ProtocolList, err = soap.UnmarshalString(response.ProtocolList); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetSupportedProtocols is the legacy version of GetSupportedProtocolsCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) GetSupportedProtocols() (ProtocolList string, err error) { + return client.GetSupportedProtocolsCtx(context.Background()) +} + +func (client *DeviceProtection1) GetUserLoginChallengeCtx( + ctx context.Context, + ProtocolType string, + Name string, +) (Salt []byte, Challenge []byte, err error) { + // Request structure. + request := &struct { + ProtocolType string + Name string + }{} + // BEGIN Marshal arguments into request. + + if request.ProtocolType, err = soap.MarshalString(ProtocolType); err != nil { + return + } + if request.Name, err = soap.MarshalString(Name); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + Salt string + Challenge string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "GetUserLoginChallenge", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if Salt, err = soap.UnmarshalBinBase64(response.Salt); err != nil { + return + } + if Challenge, err = soap.UnmarshalBinBase64(response.Challenge); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUserLoginChallenge is the legacy version of GetUserLoginChallengeCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) GetUserLoginChallenge(ProtocolType string, Name string) (Salt []byte, Challenge []byte, err error) { + return client.GetUserLoginChallengeCtx(context.Background(), + ProtocolType, + Name, + ) +} + +func (client *DeviceProtection1) RemoveIdentityCtx( + ctx context.Context, + Identity string, +) (err error) { + // Request structure. + request := &struct { + Identity string + }{} + // BEGIN Marshal arguments into request. + + if request.Identity, err = soap.MarshalString(Identity); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "RemoveIdentity", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RemoveIdentity is the legacy version of RemoveIdentityCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) RemoveIdentity(Identity string) (err error) { + return client.RemoveIdentityCtx(context.Background(), + Identity, + ) +} + +func (client *DeviceProtection1) RemoveRolesForIdentityCtx( + ctx context.Context, + Identity string, + RoleList string, +) (err error) { + // Request structure. + request := &struct { + Identity string + RoleList string + }{} + // BEGIN Marshal arguments into request. + + if request.Identity, err = soap.MarshalString(Identity); err != nil { + return + } + if request.RoleList, err = soap.MarshalString(RoleList); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "RemoveRolesForIdentity", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RemoveRolesForIdentity is the legacy version of RemoveRolesForIdentityCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) RemoveRolesForIdentity(Identity string, RoleList string) (err error) { + return client.RemoveRolesForIdentityCtx(context.Background(), + Identity, + RoleList, + ) +} + +func (client *DeviceProtection1) SendSetupMessageCtx( + ctx context.Context, + ProtocolType string, + InMessage []byte, +) (OutMessage []byte, err error) { + // Request structure. + request := &struct { + ProtocolType string + InMessage string + }{} + // BEGIN Marshal arguments into request. + + if request.ProtocolType, err = soap.MarshalString(ProtocolType); err != nil { + return + } + if request.InMessage, err = soap.MarshalBinBase64(InMessage); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + OutMessage string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "SendSetupMessage", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if OutMessage, err = soap.UnmarshalBinBase64(response.OutMessage); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// SendSetupMessage is the legacy version of SendSetupMessageCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) SendSetupMessage(ProtocolType string, InMessage []byte) (OutMessage []byte, err error) { + return client.SendSetupMessageCtx(context.Background(), + ProtocolType, + InMessage, + ) +} + +func (client *DeviceProtection1) SetUserLoginPasswordCtx( + ctx context.Context, + ProtocolType string, + Name string, + Stored []byte, + Salt []byte, +) (err error) { + // Request structure. + request := &struct { + ProtocolType string + Name string + Stored string + Salt string + }{} + // BEGIN Marshal arguments into request. + + if request.ProtocolType, err = soap.MarshalString(ProtocolType); err != nil { + return + } + if request.Name, err = soap.MarshalString(Name); err != nil { + return + } + if request.Stored, err = soap.MarshalBinBase64(Stored); err != nil { + return + } + if request.Salt, err = soap.MarshalBinBase64(Salt); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "SetUserLoginPassword", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetUserLoginPassword is the legacy version of SetUserLoginPasswordCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) SetUserLoginPassword(ProtocolType string, Name string, Stored []byte, Salt []byte) (err error) { + return client.SetUserLoginPasswordCtx(context.Background(), + ProtocolType, + Name, + Stored, + Salt, + ) +} + +func (client *DeviceProtection1) UserLoginCtx( + ctx context.Context, + ProtocolType string, + Challenge []byte, + Authenticator []byte, +) (err error) { + // Request structure. + request := &struct { + ProtocolType string + Challenge string + Authenticator string + }{} + // BEGIN Marshal arguments into request. + + if request.ProtocolType, err = soap.MarshalString(ProtocolType); err != nil { + return + } + if request.Challenge, err = soap.MarshalBinBase64(Challenge); err != nil { + return + } + if request.Authenticator, err = soap.MarshalBinBase64(Authenticator); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "UserLogin", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// UserLogin is the legacy version of UserLoginCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) UserLogin(ProtocolType string, Challenge []byte, Authenticator []byte) (err error) { + return client.UserLoginCtx(context.Background(), + ProtocolType, + Challenge, + Authenticator, + ) +} + +func (client *DeviceProtection1) UserLogoutCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_DeviceProtection_1, "UserLogout", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// UserLogout is the legacy version of UserLogoutCtx, but uses +// context.Background() as the context. +func (client *DeviceProtection1) UserLogout() (err error) { + return client.UserLogoutCtx(context.Background()) +} + +// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type LANHostConfigManagement1 struct { + goupnp.ServiceClient +} + +// NewLANHostConfigManagement1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLANHostConfigManagement1ClientsCtx(ctx context.Context) (clients []*LANHostConfigManagement1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_LANHostConfigManagement_1); err != nil { + return + } + clients = newLANHostConfigManagement1ClientsFromGenericClients(genericClients) + return +} + +// NewLANHostConfigManagement1Clients is the legacy version of NewLANHostConfigManagement1ClientsCtx, but uses +// context.Background() as the context. +func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) { + return NewLANHostConfigManagement1ClientsCtx(context.Background()) +} + +// NewLANHostConfigManagement1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewLANHostConfigManagement1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*LANHostConfigManagement1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_LANHostConfigManagement_1) + if err != nil { + return nil, err + } + return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil +} + +// NewLANHostConfigManagement1ClientsByURL is the legacy version of NewLANHostConfigManagement1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewLANHostConfigManagement1ClientsByURL(loc *url.URL) ([]*LANHostConfigManagement1, error) { + return NewLANHostConfigManagement1ClientsByURLCtx(context.Background(), loc) +} + +// NewLANHostConfigManagement1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewLANHostConfigManagement1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*LANHostConfigManagement1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_LANHostConfigManagement_1) + if err != nil { + return nil, err + } + return newLANHostConfigManagement1ClientsFromGenericClients(genericClients), nil +} + +func newLANHostConfigManagement1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*LANHostConfigManagement1 { + clients := make([]*LANHostConfigManagement1, len(genericClients)) + for i := range genericClients { + clients[i] = &LANHostConfigManagement1{genericClients[i]} + } + return clients +} + +func (client *LANHostConfigManagement1) DeleteDNSServerCtx( + ctx context.Context, + NewDNSServers string, +) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeleteDNSServer is the legacy version of DeleteDNSServerCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) { + return client.DeleteDNSServerCtx(context.Background(), + NewDNSServers, + ) +} + +func (client *LANHostConfigManagement1) DeleteIPRouterCtx( + ctx context.Context, + NewIPRouters string, +) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeleteIPRouter is the legacy version of DeleteIPRouterCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) { + return client.DeleteIPRouterCtx(context.Background(), + NewIPRouters, + ) +} + +func (client *LANHostConfigManagement1) DeleteReservedAddressCtx( + ctx context.Context, + NewReservedAddresses string, +) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeleteReservedAddress is the legacy version of DeleteReservedAddressCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) { + return client.DeleteReservedAddressCtx(context.Background(), + NewReservedAddresses, + ) +} + +func (client *LANHostConfigManagement1) GetAddressRangeCtx( + ctx context.Context, +) (NewMinAddress string, NewMaxAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMinAddress string + NewMaxAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil { + return + } + if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAddressRange is the legacy version of GetAddressRangeCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) { + return client.GetAddressRangeCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetDHCPRelayCtx( + ctx context.Context, +) (NewDHCPRelay bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPRelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDHCPRelay is the legacy version of GetDHCPRelayCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) { + return client.GetDHCPRelayCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetDHCPServerConfigurableCtx( + ctx context.Context, +) (NewDHCPServerConfigurable bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDHCPServerConfigurable string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDHCPServerConfigurable is the legacy version of GetDHCPServerConfigurableCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) { + return client.GetDHCPServerConfigurableCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetDNSServersCtx( + ctx context.Context, +) (NewDNSServers string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDNSServers string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDNSServers is the legacy version of GetDNSServersCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) { + return client.GetDNSServersCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetDomainNameCtx( + ctx context.Context, +) (NewDomainName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDomainName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDomainName is the legacy version of GetDomainNameCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) { + return client.GetDomainNameCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetIPRoutersListCtx( + ctx context.Context, +) (NewIPRouters string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIPRouters string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetIPRoutersList is the legacy version of GetIPRoutersListCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) { + return client.GetIPRoutersListCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetReservedAddressesCtx( + ctx context.Context, +) (NewReservedAddresses string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewReservedAddresses string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetReservedAddresses is the legacy version of GetReservedAddressesCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) { + return client.GetReservedAddressesCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) GetSubnetMaskCtx( + ctx context.Context, +) (NewSubnetMask string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewSubnetMask string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetSubnetMask is the legacy version of GetSubnetMaskCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) { + return client.GetSubnetMaskCtx(context.Background()) +} + +func (client *LANHostConfigManagement1) SetAddressRangeCtx( + ctx context.Context, + NewMinAddress string, + NewMaxAddress string, +) (err error) { + // Request structure. + request := &struct { + NewMinAddress string + NewMaxAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil { + return + } + if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetAddressRange is the legacy version of SetAddressRangeCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) { + return client.SetAddressRangeCtx(context.Background(), + NewMinAddress, + NewMaxAddress, + ) +} + +func (client *LANHostConfigManagement1) SetDHCPRelayCtx( + ctx context.Context, + NewDHCPRelay bool, +) (err error) { + // Request structure. + request := &struct { + NewDHCPRelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDHCPRelay is the legacy version of SetDHCPRelayCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) { + return client.SetDHCPRelayCtx(context.Background(), + NewDHCPRelay, + ) +} + +func (client *LANHostConfigManagement1) SetDHCPServerConfigurableCtx( + ctx context.Context, + NewDHCPServerConfigurable bool, +) (err error) { + // Request structure. + request := &struct { + NewDHCPServerConfigurable string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDHCPServerConfigurable is the legacy version of SetDHCPServerConfigurableCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) { + return client.SetDHCPServerConfigurableCtx(context.Background(), + NewDHCPServerConfigurable, + ) +} + +func (client *LANHostConfigManagement1) SetDNSServerCtx( + ctx context.Context, + NewDNSServers string, +) (err error) { + // Request structure. + request := &struct { + NewDNSServers string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDNSServer is the legacy version of SetDNSServerCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) { + return client.SetDNSServerCtx(context.Background(), + NewDNSServers, + ) +} + +func (client *LANHostConfigManagement1) SetDomainNameCtx( + ctx context.Context, + NewDomainName string, +) (err error) { + // Request structure. + request := &struct { + NewDomainName string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDomainName is the legacy version of SetDomainNameCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) { + return client.SetDomainNameCtx(context.Background(), + NewDomainName, + ) +} + +func (client *LANHostConfigManagement1) SetIPRouterCtx( + ctx context.Context, + NewIPRouters string, +) (err error) { + // Request structure. + request := &struct { + NewIPRouters string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetIPRouter is the legacy version of SetIPRouterCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) { + return client.SetIPRouterCtx(context.Background(), + NewIPRouters, + ) +} + +func (client *LANHostConfigManagement1) SetReservedAddressCtx( + ctx context.Context, + NewReservedAddresses string, +) (err error) { + // Request structure. + request := &struct { + NewReservedAddresses string + }{} + // BEGIN Marshal arguments into request. + + if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetReservedAddress is the legacy version of SetReservedAddressCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) { + return client.SetReservedAddressCtx(context.Background(), + NewReservedAddresses, + ) +} + +func (client *LANHostConfigManagement1) SetSubnetMaskCtx( + ctx context.Context, + NewSubnetMask string, +) (err error) { + // Request structure. + request := &struct { + NewSubnetMask string + }{} + // BEGIN Marshal arguments into request. + + if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetSubnetMask is the legacy version of SetSubnetMaskCtx, but uses +// context.Background() as the context. +func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) { + return client.SetSubnetMaskCtx(context.Background(), + NewSubnetMask, + ) +} + +// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type Layer3Forwarding1 struct { + goupnp.ServiceClient +} + +// NewLayer3Forwarding1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewLayer3Forwarding1ClientsCtx(ctx context.Context) (clients []*Layer3Forwarding1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_Layer3Forwarding_1); err != nil { + return + } + clients = newLayer3Forwarding1ClientsFromGenericClients(genericClients) + return +} + +// NewLayer3Forwarding1Clients is the legacy version of NewLayer3Forwarding1ClientsCtx, but uses +// context.Background() as the context. +func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) { + return NewLayer3Forwarding1ClientsCtx(context.Background()) +} + +// NewLayer3Forwarding1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewLayer3Forwarding1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*Layer3Forwarding1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_Layer3Forwarding_1) + if err != nil { + return nil, err + } + return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil +} + +// NewLayer3Forwarding1ClientsByURL is the legacy version of NewLayer3Forwarding1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewLayer3Forwarding1ClientsByURL(loc *url.URL) ([]*Layer3Forwarding1, error) { + return NewLayer3Forwarding1ClientsByURLCtx(context.Background(), loc) +} + +// NewLayer3Forwarding1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewLayer3Forwarding1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*Layer3Forwarding1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_Layer3Forwarding_1) + if err != nil { + return nil, err + } + return newLayer3Forwarding1ClientsFromGenericClients(genericClients), nil +} + +func newLayer3Forwarding1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*Layer3Forwarding1 { + clients := make([]*Layer3Forwarding1, len(genericClients)) + for i := range genericClients { + clients[i] = &Layer3Forwarding1{genericClients[i]} + } + return clients +} + +func (client *Layer3Forwarding1) GetDefaultConnectionServiceCtx( + ctx context.Context, +) (NewDefaultConnectionService string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDefaultConnectionService string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDefaultConnectionService is the legacy version of GetDefaultConnectionServiceCtx, but uses +// context.Background() as the context. +func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) { + return client.GetDefaultConnectionServiceCtx(context.Background()) +} + +func (client *Layer3Forwarding1) SetDefaultConnectionServiceCtx( + ctx context.Context, + NewDefaultConnectionService string, +) (err error) { + // Request structure. + request := &struct { + NewDefaultConnectionService string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDefaultConnectionService is the legacy version of SetDefaultConnectionServiceCtx, but uses +// context.Background() as the context. +func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) { + return client.SetDefaultConnectionServiceCtx(context.Background(), + NewDefaultConnectionService, + ) +} + +// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCableLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCableLinkConfig1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCableLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANCableLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCableLinkConfig_1); err != nil { + return + } + clients = newWANCableLinkConfig1ClientsFromGenericClients(genericClients) + return +} + +// NewWANCableLinkConfig1Clients is the legacy version of NewWANCableLinkConfig1ClientsCtx, but uses +// context.Background() as the context. +func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) { + return NewWANCableLinkConfig1ClientsCtx(context.Background()) +} + +// NewWANCableLinkConfig1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANCableLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCableLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCableLinkConfig_1) + if err != nil { + return nil, err + } + return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +// NewWANCableLinkConfig1ClientsByURL is the legacy version of NewWANCableLinkConfig1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANCableLinkConfig1ClientsByURL(loc *url.URL) ([]*WANCableLinkConfig1, error) { + return NewWANCableLinkConfig1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANCableLinkConfig1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANCableLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCableLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCableLinkConfig_1) + if err != nil { + return nil, err + } + return newWANCableLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +func newWANCableLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANCableLinkConfig1 { + clients := make([]*WANCableLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCableLinkConfig1{genericClients[i]} + } + return clients +} + +func (client *WANCableLinkConfig1) GetBPIEncryptionEnabledCtx( + ctx context.Context, +) (NewBPIEncryptionEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewBPIEncryptionEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetBPIEncryptionEnabled is the legacy version of GetBPIEncryptionEnabledCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) { + return client.GetBPIEncryptionEnabledCtx(context.Background()) +} + +// +// Return values: +// +// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied +// +// * NewLinkType: allowed values: Ethernet +func (client *WANCableLinkConfig1) GetCableLinkConfigInfoCtx( + ctx context.Context, +) (NewCableLinkConfigState string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewCableLinkConfigState string + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetCableLinkConfigInfo is the legacy version of GetCableLinkConfigInfoCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) { + return client.GetCableLinkConfigInfoCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetConfigFileCtx( + ctx context.Context, +) (NewConfigFile string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConfigFile string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetConfigFile is the legacy version of GetConfigFileCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) { + return client.GetConfigFileCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetDownstreamFrequencyCtx( + ctx context.Context, +) (NewDownstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDownstreamFrequency is the legacy version of GetDownstreamFrequencyCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) { + return client.GetDownstreamFrequencyCtx(context.Background()) +} + +// +// Return values: +// +// * NewDownstreamModulation: allowed values: 64QAM, 256QAM +func (client *WANCableLinkConfig1) GetDownstreamModulationCtx( + ctx context.Context, +) (NewDownstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDownstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDownstreamModulation is the legacy version of GetDownstreamModulationCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) { + return client.GetDownstreamModulationCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetTFTPServerCtx( + ctx context.Context, +) (NewTFTPServer string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTFTPServer string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetTFTPServer is the legacy version of GetTFTPServerCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) { + return client.GetTFTPServerCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetUpstreamChannelIDCtx( + ctx context.Context, +) (NewUpstreamChannelID uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamChannelID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUpstreamChannelID is the legacy version of GetUpstreamChannelIDCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) { + return client.GetUpstreamChannelIDCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetUpstreamFrequencyCtx( + ctx context.Context, +) (NewUpstreamFrequency uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamFrequency string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUpstreamFrequency is the legacy version of GetUpstreamFrequencyCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) { + return client.GetUpstreamFrequencyCtx(context.Background()) +} + +// +// Return values: +// +// * NewUpstreamModulation: allowed values: QPSK, 16QAM +func (client *WANCableLinkConfig1) GetUpstreamModulationCtx( + ctx context.Context, +) (NewUpstreamModulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamModulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUpstreamModulation is the legacy version of GetUpstreamModulationCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) { + return client.GetUpstreamModulationCtx(context.Background()) +} + +func (client *WANCableLinkConfig1) GetUpstreamPowerLevelCtx( + ctx context.Context, +) (NewUpstreamPowerLevel uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamPowerLevel string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUpstreamPowerLevel is the legacy version of GetUpstreamPowerLevelCtx, but uses +// context.Background() as the context. +func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) { + return client.GetUpstreamPowerLevelCtx(context.Background()) +} + +// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANCommonInterfaceConfig1 struct { + goupnp.ServiceClient +} + +// NewWANCommonInterfaceConfig1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANCommonInterfaceConfig1ClientsCtx(ctx context.Context) (clients []*WANCommonInterfaceConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANCommonInterfaceConfig_1); err != nil { + return + } + clients = newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients) + return +} + +// NewWANCommonInterfaceConfig1Clients is the legacy version of NewWANCommonInterfaceConfig1ClientsCtx, but uses +// context.Background() as the context. +func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) { + return NewWANCommonInterfaceConfig1ClientsCtx(context.Background()) +} + +// NewWANCommonInterfaceConfig1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANCommonInterfaceConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANCommonInterfaceConfig_1) + if err != nil { + return nil, err + } + return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil +} + +// NewWANCommonInterfaceConfig1ClientsByURL is the legacy version of NewWANCommonInterfaceConfig1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANCommonInterfaceConfig1ClientsByURL(loc *url.URL) ([]*WANCommonInterfaceConfig1, error) { + return NewWANCommonInterfaceConfig1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANCommonInterfaceConfig1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANCommonInterfaceConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANCommonInterfaceConfig1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANCommonInterfaceConfig_1) + if err != nil { + return nil, err + } + return newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients), nil +} + +func newWANCommonInterfaceConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANCommonInterfaceConfig1 { + clients := make([]*WANCommonInterfaceConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANCommonInterfaceConfig1{genericClients[i]} + } + return clients +} + +func (client *WANCommonInterfaceConfig1) GetActiveConnectionCtx( + ctx context.Context, + NewActiveConnectionIndex uint16, +) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { + // Request structure. + request := &struct { + NewActiveConnectionIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewActiveConnDeviceContainer string + NewActiveConnectionServiceID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil { + return + } + if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetActiveConnection is the legacy version of GetActiveConnectionCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) { + return client.GetActiveConnectionCtx(context.Background(), + NewActiveConnectionIndex, + ) +} + +// +// Return values: +// +// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet +// +// * NewPhysicalLinkStatus: allowed values: Up, Down +func (client *WANCommonInterfaceConfig1) GetCommonLinkPropertiesCtx( + ctx context.Context, +) (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessType string + NewLayer1UpstreamMaxBitRate string + NewLayer1DownstreamMaxBitRate string + NewPhysicalLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil { + return + } + if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil { + return + } + if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil { + return + } + if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetCommonLinkProperties is the legacy version of GetCommonLinkPropertiesCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) { + return client.GetCommonLinkPropertiesCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetEnabledForInternetCtx( + ctx context.Context, +) (NewEnabledForInternet bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEnabledForInternet string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetEnabledForInternet is the legacy version of GetEnabledForInternetCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) { + return client.GetEnabledForInternetCtx(context.Background()) +} + +// +// Return values: +// +// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1 +func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnectionsCtx( + ctx context.Context, +) (NewMaximumActiveConnections uint16, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewMaximumActiveConnections string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetMaximumActiveConnections is the legacy version of GetMaximumActiveConnectionsCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) { + return client.GetMaximumActiveConnectionsCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceivedCtx( + ctx context.Context, +) (NewTotalBytesReceived uint64, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesReceived, err = soap.UnmarshalUi8(response.NewTotalBytesReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetTotalBytesReceived is the legacy version of GetTotalBytesReceivedCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint64, err error) { + return client.GetTotalBytesReceivedCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetTotalBytesSentCtx( + ctx context.Context, +) (NewTotalBytesSent uint64, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalBytesSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalBytesSent, err = soap.UnmarshalUi8(response.NewTotalBytesSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetTotalBytesSent is the legacy version of GetTotalBytesSentCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint64, err error) { + return client.GetTotalBytesSentCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceivedCtx( + ctx context.Context, +) (NewTotalPacketsReceived uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsReceived string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetTotalPacketsReceived is the legacy version of GetTotalPacketsReceivedCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) { + return client.GetTotalPacketsReceivedCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetTotalPacketsSentCtx( + ctx context.Context, +) (NewTotalPacketsSent uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewTotalPacketsSent string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetTotalPacketsSent is the legacy version of GetTotalPacketsSentCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) { + return client.GetTotalPacketsSentCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) GetWANAccessProviderCtx( + ctx context.Context, +) (NewWANAccessProvider string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWANAccessProvider string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetWANAccessProvider is the legacy version of GetWANAccessProviderCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) { + return client.GetWANAccessProviderCtx(context.Background()) +} + +func (client *WANCommonInterfaceConfig1) SetEnabledForInternetCtx( + ctx context.Context, + NewEnabledForInternet bool, +) (err error) { + // Request structure. + request := &struct { + NewEnabledForInternet string + }{} + // BEGIN Marshal arguments into request. + + if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetEnabledForInternet is the legacy version of SetEnabledForInternetCtx, but uses +// context.Background() as the context. +func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) { + return client.SetEnabledForInternetCtx(context.Background(), + NewEnabledForInternet, + ) +} + +// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANDSLLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANDSLLinkConfig1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANDSLLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANDSLLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANDSLLinkConfig_1); err != nil { + return + } + clients = newWANDSLLinkConfig1ClientsFromGenericClients(genericClients) + return +} + +// NewWANDSLLinkConfig1Clients is the legacy version of NewWANDSLLinkConfig1ClientsCtx, but uses +// context.Background() as the context. +func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) { + return NewWANDSLLinkConfig1ClientsCtx(context.Background()) +} + +// NewWANDSLLinkConfig1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANDSLLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANDSLLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANDSLLinkConfig_1) + if err != nil { + return nil, err + } + return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +// NewWANDSLLinkConfig1ClientsByURL is the legacy version of NewWANDSLLinkConfig1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANDSLLinkConfig1ClientsByURL(loc *url.URL) ([]*WANDSLLinkConfig1, error) { + return NewWANDSLLinkConfig1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANDSLLinkConfig1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANDSLLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANDSLLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANDSLLinkConfig_1) + if err != nil { + return nil, err + } + return newWANDSLLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +func newWANDSLLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANDSLLinkConfig1 { + clients := make([]*WANDSLLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANDSLLinkConfig1{genericClients[i]} + } + return clients +} + +func (client *WANDSLLinkConfig1) GetATMEncapsulationCtx( + ctx context.Context, +) (NewATMEncapsulation string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewATMEncapsulation string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetATMEncapsulation is the legacy version of GetATMEncapsulationCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) { + return client.GetATMEncapsulationCtx(context.Background()) +} + +func (client *WANDSLLinkConfig1) GetAutoConfigCtx( + ctx context.Context, +) (NewAutoConfig bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoConfig string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAutoConfig is the legacy version of GetAutoConfigCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) { + return client.GetAutoConfigCtx(context.Background()) +} + +// +// Return values: +// +// * NewLinkStatus: allowed values: Up, Down +func (client *WANDSLLinkConfig1) GetDSLLinkInfoCtx( + ctx context.Context, +) (NewLinkType string, NewLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewLinkType string + NewLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDSLLinkInfo is the legacy version of GetDSLLinkInfoCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) { + return client.GetDSLLinkInfoCtx(context.Background()) +} + +func (client *WANDSLLinkConfig1) GetDestinationAddressCtx( + ctx context.Context, +) (NewDestinationAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDestinationAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDestinationAddress is the legacy version of GetDestinationAddressCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) { + return client.GetDestinationAddressCtx(context.Background()) +} + +func (client *WANDSLLinkConfig1) GetFCSPreservedCtx( + ctx context.Context, +) (NewFCSPreserved bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFCSPreserved string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetFCSPreserved is the legacy version of GetFCSPreservedCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) { + return client.GetFCSPreservedCtx(context.Background()) +} + +func (client *WANDSLLinkConfig1) GetModulationTypeCtx( + ctx context.Context, +) (NewModulationType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewModulationType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetModulationType is the legacy version of GetModulationTypeCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) { + return client.GetModulationTypeCtx(context.Background()) +} + +func (client *WANDSLLinkConfig1) SetATMEncapsulationCtx( + ctx context.Context, + NewATMEncapsulation string, +) (err error) { + // Request structure. + request := &struct { + NewATMEncapsulation string + }{} + // BEGIN Marshal arguments into request. + + if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetATMEncapsulation is the legacy version of SetATMEncapsulationCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) { + return client.SetATMEncapsulationCtx(context.Background(), + NewATMEncapsulation, + ) +} + +func (client *WANDSLLinkConfig1) SetDSLLinkTypeCtx( + ctx context.Context, + NewLinkType string, +) (err error) { + // Request structure. + request := &struct { + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDSLLinkType is the legacy version of SetDSLLinkTypeCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) { + return client.SetDSLLinkTypeCtx(context.Background(), + NewLinkType, + ) +} + +func (client *WANDSLLinkConfig1) SetDestinationAddressCtx( + ctx context.Context, + NewDestinationAddress string, +) (err error) { + // Request structure. + request := &struct { + NewDestinationAddress string + }{} + // BEGIN Marshal arguments into request. + + if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetDestinationAddress is the legacy version of SetDestinationAddressCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) { + return client.SetDestinationAddressCtx(context.Background(), + NewDestinationAddress, + ) +} + +func (client *WANDSLLinkConfig1) SetFCSPreservedCtx( + ctx context.Context, + NewFCSPreserved bool, +) (err error) { + // Request structure. + request := &struct { + NewFCSPreserved string + }{} + // BEGIN Marshal arguments into request. + + if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetFCSPreserved is the legacy version of SetFCSPreservedCtx, but uses +// context.Background() as the context. +func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) { + return client.SetFCSPreservedCtx(context.Background(), + NewFCSPreserved, + ) +} + +// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANEthernetLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANEthernetLinkConfig1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANEthernetLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANEthernetLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANEthernetLinkConfig_1); err != nil { + return + } + clients = newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients) + return +} + +// NewWANEthernetLinkConfig1Clients is the legacy version of NewWANEthernetLinkConfig1ClientsCtx, but uses +// context.Background() as the context. +func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) { + return NewWANEthernetLinkConfig1ClientsCtx(context.Background()) +} + +// NewWANEthernetLinkConfig1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANEthernetLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANEthernetLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANEthernetLinkConfig_1) + if err != nil { + return nil, err + } + return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +// NewWANEthernetLinkConfig1ClientsByURL is the legacy version of NewWANEthernetLinkConfig1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANEthernetLinkConfig1ClientsByURL(loc *url.URL) ([]*WANEthernetLinkConfig1, error) { + return NewWANEthernetLinkConfig1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANEthernetLinkConfig1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANEthernetLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANEthernetLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANEthernetLinkConfig_1) + if err != nil { + return nil, err + } + return newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +func newWANEthernetLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANEthernetLinkConfig1 { + clients := make([]*WANEthernetLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANEthernetLinkConfig1{genericClients[i]} + } + return clients +} + +// +// Return values: +// +// * NewEthernetLinkStatus: allowed values: Up, Down +func (client *WANEthernetLinkConfig1) GetEthernetLinkStatusCtx( + ctx context.Context, +) (NewEthernetLinkStatus string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewEthernetLinkStatus string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetEthernetLinkStatus is the legacy version of GetEthernetLinkStatusCtx, but uses +// context.Background() as the context. +func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) { + return client.GetEthernetLinkStatusCtx(context.Background()) +} + +// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANIPConnection1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPConnection1ClientsCtx(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_1); err != nil { + return + } + clients = newWANIPConnection1ClientsFromGenericClients(genericClients) + return +} + +// NewWANIPConnection1Clients is the legacy version of NewWANIPConnection1ClientsCtx, but uses +// context.Background() as the context. +func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) { + return NewWANIPConnection1ClientsCtx(context.Background()) +} + +// NewWANIPConnection1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANIPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_1) + if err != nil { + return nil, err + } + return newWANIPConnection1ClientsFromGenericClients(genericClients), nil +} + +// NewWANIPConnection1ClientsByURL is the legacy version of NewWANIPConnection1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANIPConnection1ClientsByURL(loc *url.URL) ([]*WANIPConnection1, error) { + return NewWANIPConnection1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANIPConnection1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANIPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_1) + if err != nil { + return nil, err + } + return newWANIPConnection1ClientsFromGenericClients(genericClients), nil +} + +func newWANIPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPConnection1 { + clients := make([]*WANIPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPConnection1{genericClients[i]} + } + return clients +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection1) AddPortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, + NewInternalPort uint16, + NewInternalClient string, + NewEnabled bool, + NewPortMappingDescription string, + NewLeaseDuration uint32, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// AddPortMapping is the legacy version of AddPortMappingCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + return client.AddPortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + NewInternalPort, + NewInternalClient, + NewEnabled, + NewPortMappingDescription, + NewLeaseDuration, + ) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection1) DeletePortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeletePortMapping is the legacy version of DeletePortMappingCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + return client.DeletePortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +func (client *WANIPConnection1) ForceTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// ForceTermination is the legacy version of ForceTerminationCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) ForceTermination() (err error) { + return client.ForceTerminationCtx(context.Background()) +} + +func (client *WANIPConnection1) GetAutoDisconnectTimeCtx( + ctx context.Context, +) (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAutoDisconnectTime is the legacy version of GetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + return client.GetAutoDisconnectTimeCtx(context.Background()) +} + +// +// Return values: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged +func (client *WANIPConnection1) GetConnectionTypeInfoCtx( + ctx context.Context, +) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetConnectionTypeInfo is the legacy version of GetConnectionTypeInfoCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + return client.GetConnectionTypeInfoCtx(context.Background()) +} + +func (client *WANIPConnection1) GetExternalIPAddressCtx( + ctx context.Context, +) (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetExternalIPAddress is the legacy version of GetExternalIPAddressCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + return client.GetExternalIPAddressCtx(context.Background()) +} + +// +// Return values: +// +// * NewProtocol: allowed values: TCP, UDP +func (client *WANIPConnection1) GetGenericPortMappingEntryCtx( + ctx context.Context, + NewPortMappingIndex uint16, +) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetGenericPortMappingEntry is the legacy version of GetGenericPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetGenericPortMappingEntryCtx(context.Background(), + NewPortMappingIndex, + ) +} + +func (client *WANIPConnection1) GetIdleDisconnectTimeCtx( + ctx context.Context, +) (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetIdleDisconnectTime is the legacy version of GetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + return client.GetIdleDisconnectTimeCtx(context.Background()) +} + +func (client *WANIPConnection1) GetNATRSIPStatusCtx( + ctx context.Context, +) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetNATRSIPStatus is the legacy version of GetNATRSIPStatusCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + return client.GetNATRSIPStatusCtx(context.Background()) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection1) GetSpecificPortMappingEntryCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetSpecificPortMappingEntry is the legacy version of GetSpecificPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetSpecificPortMappingEntryCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +func (client *WANIPConnection1) GetStatusInfoCtx( + ctx context.Context, +) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + NewLastConnectionError string + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetStatusInfo is the legacy version of GetStatusInfoCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + return client.GetStatusInfoCtx(context.Background()) +} + +func (client *WANIPConnection1) GetWarnDisconnectDelayCtx( + ctx context.Context, +) (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetWarnDisconnectDelay is the legacy version of GetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + return client.GetWarnDisconnectDelayCtx(context.Background()) +} + +func (client *WANIPConnection1) RequestConnectionCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestConnection is the legacy version of RequestConnectionCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) RequestConnection() (err error) { + return client.RequestConnectionCtx(context.Background()) +} + +func (client *WANIPConnection1) RequestTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestTermination is the legacy version of RequestTerminationCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) RequestTermination() (err error) { + return client.RequestTerminationCtx(context.Background()) +} + +func (client *WANIPConnection1) SetAutoDisconnectTimeCtx( + ctx context.Context, + NewAutoDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetAutoDisconnectTime is the legacy version of SetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + return client.SetAutoDisconnectTimeCtx(context.Background(), + NewAutoDisconnectTime, + ) +} + +func (client *WANIPConnection1) SetConnectionTypeCtx( + ctx context.Context, + NewConnectionType string, +) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetConnectionType is the legacy version of SetConnectionTypeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) { + return client.SetConnectionTypeCtx(context.Background(), + NewConnectionType, + ) +} + +func (client *WANIPConnection1) SetIdleDisconnectTimeCtx( + ctx context.Context, + NewIdleDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetIdleDisconnectTime is the legacy version of SetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + return client.SetIdleDisconnectTimeCtx(context.Background(), + NewIdleDisconnectTime, + ) +} + +func (client *WANIPConnection1) SetWarnDisconnectDelayCtx( + ctx context.Context, + NewWarnDisconnectDelay uint32, +) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetWarnDisconnectDelay is the legacy version of SetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + return client.SetWarnDisconnectDelayCtx(context.Background(), + NewWarnDisconnectDelay, + ) +} + +// WANIPConnection2 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:2". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPConnection2 struct { + goupnp.ServiceClient +} + +// NewWANIPConnection2ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPConnection2ClientsCtx(ctx context.Context) (clients []*WANIPConnection2, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPConnection_2); err != nil { + return + } + clients = newWANIPConnection2ClientsFromGenericClients(genericClients) + return +} + +// NewWANIPConnection2Clients is the legacy version of NewWANIPConnection2ClientsCtx, but uses +// context.Background() as the context. +func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) { + return NewWANIPConnection2ClientsCtx(context.Background()) +} + +// NewWANIPConnection2ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANIPConnection2ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPConnection2, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPConnection_2) + if err != nil { + return nil, err + } + return newWANIPConnection2ClientsFromGenericClients(genericClients), nil +} + +// NewWANIPConnection2ClientsByURL is the legacy version of NewWANIPConnection2ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANIPConnection2ClientsByURL(loc *url.URL) ([]*WANIPConnection2, error) { + return NewWANIPConnection2ClientsByURLCtx(context.Background(), loc) +} + +// NewWANIPConnection2ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANIPConnection2ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection2, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPConnection_2) + if err != nil { + return nil, err + } + return newWANIPConnection2ClientsFromGenericClients(genericClients), nil +} + +func newWANIPConnection2ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPConnection2 { + clients := make([]*WANIPConnection2, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPConnection2{genericClients[i]} + } + return clients +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) AddAnyPortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, + NewInternalPort uint16, + NewInternalClient string, + NewEnabled bool, + NewPortMappingDescription string, + NewLeaseDuration uint32, +) (NewReservedPort uint16, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewReservedPort string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "AddAnyPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewReservedPort, err = soap.UnmarshalUi2(response.NewReservedPort); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// AddAnyPortMapping is the legacy version of AddAnyPortMappingCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) AddAnyPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) { + return client.AddAnyPortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + NewInternalPort, + NewInternalClient, + NewEnabled, + NewPortMappingDescription, + NewLeaseDuration, + ) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) AddPortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, + NewInternalPort uint16, + NewInternalClient string, + NewEnabled bool, + NewPortMappingDescription string, + NewLeaseDuration uint32, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// AddPortMapping is the legacy version of AddPortMappingCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + return client.AddPortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + NewInternalPort, + NewInternalClient, + NewEnabled, + NewPortMappingDescription, + NewLeaseDuration, + ) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) DeletePortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeletePortMapping is the legacy version of DeletePortMappingCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + return client.DeletePortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) DeletePortMappingRangeCtx( + ctx context.Context, + NewStartPort uint16, + NewEndPort uint16, + NewProtocol string, + NewManage bool, +) (err error) { + // Request structure. + request := &struct { + NewStartPort string + NewEndPort string + NewProtocol string + NewManage string + }{} + // BEGIN Marshal arguments into request. + + if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { + return + } + if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "DeletePortMappingRange", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeletePortMappingRange is the legacy version of DeletePortMappingRangeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) DeletePortMappingRange(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool) (err error) { + return client.DeletePortMappingRangeCtx(context.Background(), + NewStartPort, + NewEndPort, + NewProtocol, + NewManage, + ) +} + +func (client *WANIPConnection2) ForceTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// ForceTermination is the legacy version of ForceTerminationCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) ForceTermination() (err error) { + return client.ForceTerminationCtx(context.Background()) +} + +func (client *WANIPConnection2) GetAutoDisconnectTimeCtx( + ctx context.Context, +) (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAutoDisconnectTime is the legacy version of GetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + return client.GetAutoDisconnectTimeCtx(context.Background()) +} + +func (client *WANIPConnection2) GetConnectionTypeInfoCtx( + ctx context.Context, +) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetConnectionTypeInfo is the legacy version of GetConnectionTypeInfoCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + return client.GetConnectionTypeInfoCtx(context.Background()) +} + +func (client *WANIPConnection2) GetExternalIPAddressCtx( + ctx context.Context, +) (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetExternalIPAddress is the legacy version of GetExternalIPAddressCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + return client.GetExternalIPAddressCtx(context.Background()) +} + +// +// Return values: +// +// * NewProtocol: allowed values: TCP, UDP +func (client *WANIPConnection2) GetGenericPortMappingEntryCtx( + ctx context.Context, + NewPortMappingIndex uint16, +) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetGenericPortMappingEntry is the legacy version of GetGenericPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetGenericPortMappingEntryCtx(context.Background(), + NewPortMappingIndex, + ) +} + +func (client *WANIPConnection2) GetIdleDisconnectTimeCtx( + ctx context.Context, +) (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetIdleDisconnectTime is the legacy version of GetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + return client.GetIdleDisconnectTimeCtx(context.Background()) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) GetListOfPortMappingsCtx( + ctx context.Context, + NewStartPort uint16, + NewEndPort uint16, + NewProtocol string, + NewManage bool, + NewNumberOfPorts uint16, +) (NewPortListing string, err error) { + // Request structure. + request := &struct { + NewStartPort string + NewEndPort string + NewProtocol string + NewManage string + NewNumberOfPorts string + }{} + // BEGIN Marshal arguments into request. + + if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { + return + } + if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { + return + } + if request.NewNumberOfPorts, err = soap.MarshalUi2(NewNumberOfPorts); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPortListing string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetListOfPortMappings", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPortListing, err = soap.UnmarshalString(response.NewPortListing); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetListOfPortMappings is the legacy version of GetListOfPortMappingsCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) { + return client.GetListOfPortMappingsCtx(context.Background(), + NewStartPort, + NewEndPort, + NewProtocol, + NewManage, + NewNumberOfPorts, + ) +} + +func (client *WANIPConnection2) GetNATRSIPStatusCtx( + ctx context.Context, +) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetNATRSIPStatus is the legacy version of GetNATRSIPStatusCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + return client.GetNATRSIPStatusCtx(context.Background()) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANIPConnection2) GetSpecificPortMappingEntryCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetSpecificPortMappingEntry is the legacy version of GetSpecificPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetSpecificPortMappingEntryCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connecting, Connected, PendingDisconnect, Disconnecting, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE, ERROR_COMMAND_ABORTED, ERROR_NOT_ENABLED_FOR_INTERNET, ERROR_USER_DISCONNECT, ERROR_ISP_DISCONNECT, ERROR_IDLE_DISCONNECT, ERROR_FORCED_DISCONNECT, ERROR_NO_CARRIER, ERROR_IP_CONFIGURATION, ERROR_UNKNOWN +func (client *WANIPConnection2) GetStatusInfoCtx( + ctx context.Context, +) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + NewLastConnectionError string + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetStatusInfo is the legacy version of GetStatusInfoCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + return client.GetStatusInfoCtx(context.Background()) +} + +func (client *WANIPConnection2) GetWarnDisconnectDelayCtx( + ctx context.Context, +) (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetWarnDisconnectDelay is the legacy version of GetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + return client.GetWarnDisconnectDelayCtx(context.Background()) +} + +func (client *WANIPConnection2) RequestConnectionCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestConnection is the legacy version of RequestConnectionCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) RequestConnection() (err error) { + return client.RequestConnectionCtx(context.Background()) +} + +func (client *WANIPConnection2) RequestTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestTermination is the legacy version of RequestTerminationCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) RequestTermination() (err error) { + return client.RequestTerminationCtx(context.Background()) +} + +func (client *WANIPConnection2) SetAutoDisconnectTimeCtx( + ctx context.Context, + NewAutoDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetAutoDisconnectTime is the legacy version of SetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + return client.SetAutoDisconnectTimeCtx(context.Background(), + NewAutoDisconnectTime, + ) +} + +func (client *WANIPConnection2) SetConnectionTypeCtx( + ctx context.Context, + NewConnectionType string, +) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetConnectionType is the legacy version of SetConnectionTypeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) SetConnectionType(NewConnectionType string) (err error) { + return client.SetConnectionTypeCtx(context.Background(), + NewConnectionType, + ) +} + +func (client *WANIPConnection2) SetIdleDisconnectTimeCtx( + ctx context.Context, + NewIdleDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetIdleDisconnectTime is the legacy version of SetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + return client.SetIdleDisconnectTimeCtx(context.Background(), + NewIdleDisconnectTime, + ) +} + +func (client *WANIPConnection2) SetWarnDisconnectDelayCtx( + ctx context.Context, + NewWarnDisconnectDelay uint32, +) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPConnection_2, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetWarnDisconnectDelay is the legacy version of SetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANIPConnection2) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + return client.SetWarnDisconnectDelayCtx(context.Background(), + NewWarnDisconnectDelay, + ) +} + +// WANIPv6FirewallControl1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANIPv6FirewallControl1 struct { + goupnp.ServiceClient +} + +// NewWANIPv6FirewallControl1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANIPv6FirewallControl1ClientsCtx(ctx context.Context) (clients []*WANIPv6FirewallControl1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANIPv6FirewallControl_1); err != nil { + return + } + clients = newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients) + return +} + +// NewWANIPv6FirewallControl1Clients is the legacy version of NewWANIPv6FirewallControl1ClientsCtx, but uses +// context.Background() as the context. +func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) { + return NewWANIPv6FirewallControl1ClientsCtx(context.Background()) +} + +// NewWANIPv6FirewallControl1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANIPv6FirewallControl1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANIPv6FirewallControl1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANIPv6FirewallControl_1) + if err != nil { + return nil, err + } + return newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients), nil +} + +// NewWANIPv6FirewallControl1ClientsByURL is the legacy version of NewWANIPv6FirewallControl1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANIPv6FirewallControl1ClientsByURL(loc *url.URL) ([]*WANIPv6FirewallControl1, error) { + return NewWANIPv6FirewallControl1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANIPv6FirewallControl1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANIPv6FirewallControl1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPv6FirewallControl1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANIPv6FirewallControl_1) + if err != nil { + return nil, err + } + return newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients), nil +} + +func newWANIPv6FirewallControl1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPv6FirewallControl1 { + clients := make([]*WANIPv6FirewallControl1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANIPv6FirewallControl1{genericClients[i]} + } + return clients +} + +// +// Arguments: +// +// * LeaseTime: allowed value range: minimum=1, maximum=86400 + +func (client *WANIPv6FirewallControl1) AddPinholeCtx( + ctx context.Context, + RemoteHost string, + RemotePort uint16, + InternalClient string, + InternalPort uint16, + Protocol uint16, + LeaseTime uint32, +) (UniqueID uint16, err error) { + // Request structure. + request := &struct { + RemoteHost string + RemotePort string + InternalClient string + InternalPort string + Protocol string + LeaseTime string + }{} + // BEGIN Marshal arguments into request. + + if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { + return + } + if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { + return + } + if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { + return + } + if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { + return + } + if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { + return + } + if request.LeaseTime, err = soap.MarshalUi4(LeaseTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + UniqueID string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "AddPinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if UniqueID, err = soap.UnmarshalUi2(response.UniqueID); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// AddPinhole is the legacy version of AddPinholeCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16, LeaseTime uint32) (UniqueID uint16, err error) { + return client.AddPinholeCtx(context.Background(), + RemoteHost, + RemotePort, + InternalClient, + InternalPort, + Protocol, + LeaseTime, + ) +} + +func (client *WANIPv6FirewallControl1) CheckPinholeWorkingCtx( + ctx context.Context, + UniqueID uint16, +) (IsWorking bool, err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + IsWorking string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "CheckPinholeWorking", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if IsWorking, err = soap.UnmarshalBoolean(response.IsWorking); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// CheckPinholeWorking is the legacy version of CheckPinholeWorkingCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) CheckPinholeWorking(UniqueID uint16) (IsWorking bool, err error) { + return client.CheckPinholeWorkingCtx(context.Background(), + UniqueID, + ) +} + +func (client *WANIPv6FirewallControl1) DeletePinholeCtx( + ctx context.Context, + UniqueID uint16, +) (err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "DeletePinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeletePinhole is the legacy version of DeletePinholeCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) DeletePinhole(UniqueID uint16) (err error) { + return client.DeletePinholeCtx(context.Background(), + UniqueID, + ) +} + +func (client *WANIPv6FirewallControl1) GetFirewallStatusCtx( + ctx context.Context, +) (FirewallEnabled bool, InboundPinholeAllowed bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + FirewallEnabled string + InboundPinholeAllowed string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "GetFirewallStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if FirewallEnabled, err = soap.UnmarshalBoolean(response.FirewallEnabled); err != nil { + return + } + if InboundPinholeAllowed, err = soap.UnmarshalBoolean(response.InboundPinholeAllowed); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetFirewallStatus is the legacy version of GetFirewallStatusCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool, InboundPinholeAllowed bool, err error) { + return client.GetFirewallStatusCtx(context.Background()) +} + +func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeoutCtx( + ctx context.Context, + RemoteHost string, + RemotePort uint16, + InternalClient string, + InternalPort uint16, + Protocol uint16, +) (OutboundPinholeTimeout uint32, err error) { + // Request structure. + request := &struct { + RemoteHost string + RemotePort string + InternalClient string + InternalPort string + Protocol string + }{} + // BEGIN Marshal arguments into request. + + if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil { + return + } + if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil { + return + } + if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil { + return + } + if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil { + return + } + if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + OutboundPinholeTimeout string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "GetOutboundPinholeTimeout", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if OutboundPinholeTimeout, err = soap.UnmarshalUi4(response.OutboundPinholeTimeout); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetOutboundPinholeTimeout is the legacy version of GetOutboundPinholeTimeoutCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16) (OutboundPinholeTimeout uint32, err error) { + return client.GetOutboundPinholeTimeoutCtx(context.Background(), + RemoteHost, + RemotePort, + InternalClient, + InternalPort, + Protocol, + ) +} + +func (client *WANIPv6FirewallControl1) GetPinholePacketsCtx( + ctx context.Context, + UniqueID uint16, +) (PinholePackets uint32, err error) { + // Request structure. + request := &struct { + UniqueID string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + PinholePackets string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "GetPinholePackets", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if PinholePackets, err = soap.UnmarshalUi4(response.PinholePackets); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPinholePackets is the legacy version of GetPinholePacketsCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) GetPinholePackets(UniqueID uint16) (PinholePackets uint32, err error) { + return client.GetPinholePacketsCtx(context.Background(), + UniqueID, + ) +} + +// +// Arguments: +// +// * NewLeaseTime: allowed value range: minimum=1, maximum=86400 + +func (client *WANIPv6FirewallControl1) UpdatePinholeCtx( + ctx context.Context, + UniqueID uint16, + NewLeaseTime uint32, +) (err error) { + // Request structure. + request := &struct { + UniqueID string + NewLeaseTime string + }{} + // BEGIN Marshal arguments into request. + + if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil { + return + } + if request.NewLeaseTime, err = soap.MarshalUi4(NewLeaseTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANIPv6FirewallControl_1, "UpdatePinhole", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// UpdatePinhole is the legacy version of UpdatePinholeCtx, but uses +// context.Background() as the context. +func (client *WANIPv6FirewallControl1) UpdatePinhole(UniqueID uint16, NewLeaseTime uint32) (err error) { + return client.UpdatePinholeCtx(context.Background(), + UniqueID, + NewLeaseTime, + ) +} + +// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPOTSLinkConfig1 struct { + goupnp.ServiceClient +} + +// NewWANPOTSLinkConfig1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPOTSLinkConfig1ClientsCtx(ctx context.Context) (clients []*WANPOTSLinkConfig1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPOTSLinkConfig_1); err != nil { + return + } + clients = newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients) + return +} + +// NewWANPOTSLinkConfig1Clients is the legacy version of NewWANPOTSLinkConfig1ClientsCtx, but uses +// context.Background() as the context. +func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) { + return NewWANPOTSLinkConfig1ClientsCtx(context.Background()) +} + +// NewWANPOTSLinkConfig1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANPOTSLinkConfig1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPOTSLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPOTSLinkConfig_1) + if err != nil { + return nil, err + } + return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +// NewWANPOTSLinkConfig1ClientsByURL is the legacy version of NewWANPOTSLinkConfig1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANPOTSLinkConfig1ClientsByURL(loc *url.URL) ([]*WANPOTSLinkConfig1, error) { + return NewWANPOTSLinkConfig1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANPOTSLinkConfig1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANPOTSLinkConfig1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPOTSLinkConfig1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPOTSLinkConfig_1) + if err != nil { + return nil, err + } + return newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients), nil +} + +func newWANPOTSLinkConfig1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANPOTSLinkConfig1 { + clients := make([]*WANPOTSLinkConfig1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPOTSLinkConfig1{genericClients[i]} + } + return clients +} + +func (client *WANPOTSLinkConfig1) GetCallRetryInfoCtx( + ctx context.Context, +) (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewNumberOfRetries string + NewDelayBetweenRetries string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil { + return + } + if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetCallRetryInfo is the legacy version of GetCallRetryInfoCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) { + return client.GetCallRetryInfoCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) GetDataCompressionCtx( + ctx context.Context, +) (NewDataCompression string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataCompression string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDataCompression is the legacy version of GetDataCompressionCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) { + return client.GetDataCompressionCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) GetDataModulationSupportedCtx( + ctx context.Context, +) (NewDataModulationSupported string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataModulationSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDataModulationSupported is the legacy version of GetDataModulationSupportedCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) { + return client.GetDataModulationSupportedCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) GetDataProtocolCtx( + ctx context.Context, +) (NewDataProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewDataProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetDataProtocol is the legacy version of GetDataProtocolCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) { + return client.GetDataProtocolCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) GetFclassCtx( + ctx context.Context, +) (NewFclass string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewFclass string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetFclass is the legacy version of GetFclassCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) { + return client.GetFclassCtx(context.Background()) +} + +// +// Return values: +// +// * NewLinkType: allowed values: PPP_Dialup +func (client *WANPOTSLinkConfig1) GetISPInfoCtx( + ctx context.Context, +) (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewISPPhoneNumber string + NewISPInfo string + NewLinkType string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil { + return + } + if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil { + return + } + if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetISPInfo is the legacy version of GetISPInfoCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) { + return client.GetISPInfoCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupportedCtx( + ctx context.Context, +) (NewPlusVTRCommandSupported bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPlusVTRCommandSupported string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPlusVTRCommandSupported is the legacy version of GetPlusVTRCommandSupportedCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) { + return client.GetPlusVTRCommandSupportedCtx(context.Background()) +} + +func (client *WANPOTSLinkConfig1) SetCallRetryInfoCtx( + ctx context.Context, + NewNumberOfRetries uint32, + NewDelayBetweenRetries uint32, +) (err error) { + // Request structure. + request := &struct { + NewNumberOfRetries string + NewDelayBetweenRetries string + }{} + // BEGIN Marshal arguments into request. + + if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil { + return + } + if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetCallRetryInfo is the legacy version of SetCallRetryInfoCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { + return client.SetCallRetryInfoCtx(context.Background(), + NewNumberOfRetries, + NewDelayBetweenRetries, + ) +} + +// +// Arguments: +// +// * NewLinkType: allowed values: PPP_Dialup + +func (client *WANPOTSLinkConfig1) SetISPInfoCtx( + ctx context.Context, + NewISPPhoneNumber string, + NewISPInfo string, + NewLinkType string, +) (err error) { + // Request structure. + request := &struct { + NewISPPhoneNumber string + NewISPInfo string + NewLinkType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil { + return + } + if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil { + return + } + if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetISPInfo is the legacy version of SetISPInfoCtx, but uses +// context.Background() as the context. +func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) { + return client.SetISPInfoCtx(context.Background(), + NewISPPhoneNumber, + NewISPInfo, + NewLinkType, + ) +} + +// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See +// goupnp.ServiceClient, which contains RootDevice and Service attributes which +// are provided for informational value. +type WANPPPConnection1 struct { + goupnp.ServiceClient +} + +// NewWANPPPConnection1ClientsCtx discovers instances of the service on the network, +// and returns clients to any that are found. errors will contain an error for +// any devices that replied but which could not be queried, and err will be set +// if the discovery process failed outright. +// +// This is a typical entry calling point into this package. +func NewWANPPPConnection1ClientsCtx(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) { + var genericClients []goupnp.ServiceClient + if genericClients, errors, err = goupnp.NewServiceClientsCtx(ctx, URN_WANPPPConnection_1); err != nil { + return + } + clients = newWANPPPConnection1ClientsFromGenericClients(genericClients) + return +} + +// NewWANPPPConnection1Clients is the legacy version of NewWANPPPConnection1ClientsCtx, but uses +// context.Background() as the context. +func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) { + return NewWANPPPConnection1ClientsCtx(context.Background()) +} + +// NewWANPPPConnection1ClientsByURLCtx discovers instances of the service at the given +// URL, and returns clients to any that are found. An error is returned if +// there was an error probing the service. +// +// This is a typical entry calling point into this package when reusing an +// previously discovered service URL. +func NewWANPPPConnection1ClientsByURLCtx(ctx context.Context, loc *url.URL) ([]*WANPPPConnection1, error) { + genericClients, err := goupnp.NewServiceClientsByURLCtx(ctx, loc, URN_WANPPPConnection_1) + if err != nil { + return nil, err + } + return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil +} + +// NewWANPPPConnection1ClientsByURL is the legacy version of NewWANPPPConnection1ClientsByURLCtx, but uses +// context.Background() as the context. +func NewWANPPPConnection1ClientsByURL(loc *url.URL) ([]*WANPPPConnection1, error) { + return NewWANPPPConnection1ClientsByURLCtx(context.Background(), loc) +} + +// NewWANPPPConnection1ClientsFromRootDevice discovers instances of the service in +// a given root device, and returns clients to any that are found. An error is +// returned if there was not at least one instance of the service within the +// device. The location parameter is simply assigned to the Location attribute +// of the wrapped ServiceClient(s). +// +// This is a typical entry calling point into this package when reusing an +// previously discovered root device. +func NewWANPPPConnection1ClientsFromRootDevice(rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPPPConnection1, error) { + genericClients, err := goupnp.NewServiceClientsFromRootDevice(rootDevice, loc, URN_WANPPPConnection_1) + if err != nil { + return nil, err + } + return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil +} + +func newWANPPPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANPPPConnection1 { + clients := make([]*WANPPPConnection1, len(genericClients)) + for i := range genericClients { + clients[i] = &WANPPPConnection1{genericClients[i]} + } + return clients +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANPPPConnection1) AddPortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, + NewInternalPort uint16, + NewInternalClient string, + NewEnabled bool, + NewPortMappingDescription string, + NewLeaseDuration uint32, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { + return + } + if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { + return + } + if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { + return + } + if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { + return + } + if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// AddPortMapping is the legacy version of AddPortMappingCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { + return client.AddPortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + NewInternalPort, + NewInternalClient, + NewEnabled, + NewPortMappingDescription, + NewLeaseDuration, + ) +} + +func (client *WANPPPConnection1) ConfigureConnectionCtx( + ctx context.Context, + NewUserName string, + NewPassword string, +) (err error) { + // Request structure. + request := &struct { + NewUserName string + NewPassword string + }{} + // BEGIN Marshal arguments into request. + + if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { + return + } + if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// ConfigureConnection is the legacy version of ConfigureConnectionCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) { + return client.ConfigureConnectionCtx(context.Background(), + NewUserName, + NewPassword, + ) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANPPPConnection1) DeletePortMappingCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// DeletePortMapping is the legacy version of DeletePortMappingCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { + return client.DeletePortMappingCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +func (client *WANPPPConnection1) ForceTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// ForceTermination is the legacy version of ForceTerminationCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) ForceTermination() (err error) { + return client.ForceTerminationCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetAutoDisconnectTimeCtx( + ctx context.Context, +) (NewAutoDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewAutoDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetAutoDisconnectTime is the legacy version of GetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) { + return client.GetAutoDisconnectTimeCtx(context.Background()) +} + +// +// Return values: +// +// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay +func (client *WANPPPConnection1) GetConnectionTypeInfoCtx( + ctx context.Context, +) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionType string + NewPossibleConnectionTypes string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { + return + } + if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetConnectionTypeInfo is the legacy version of GetConnectionTypeInfoCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) { + return client.GetConnectionTypeInfoCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetExternalIPAddressCtx( + ctx context.Context, +) (NewExternalIPAddress string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewExternalIPAddress string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetExternalIPAddress is the legacy version of GetExternalIPAddressCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) { + return client.GetExternalIPAddressCtx(context.Background()) +} + +// +// Return values: +// +// * NewProtocol: allowed values: TCP, UDP +func (client *WANPPPConnection1) GetGenericPortMappingEntryCtx( + ctx context.Context, + NewPortMappingIndex uint16, +) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewPortMappingIndex string + }{} + // BEGIN Marshal arguments into request. + + if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { + return + } + if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { + return + } + if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { + return + } + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetGenericPortMappingEntry is the legacy version of GetGenericPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetGenericPortMappingEntryCtx(context.Background(), + NewPortMappingIndex, + ) +} + +func (client *WANPPPConnection1) GetIdleDisconnectTimeCtx( + ctx context.Context, +) (NewIdleDisconnectTime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewIdleDisconnectTime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetIdleDisconnectTime is the legacy version of GetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) { + return client.GetIdleDisconnectTimeCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetLinkLayerMaxBitRatesCtx( + ctx context.Context, +) (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUpstreamMaxBitRate string + NewDownstreamMaxBitRate string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { + return + } + if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetLinkLayerMaxBitRates is the legacy version of GetLinkLayerMaxBitRatesCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { + return client.GetLinkLayerMaxBitRatesCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetNATRSIPStatusCtx( + ctx context.Context, +) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewRSIPAvailable string + NewNATEnabled string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { + return + } + if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetNATRSIPStatus is the legacy version of GetNATRSIPStatusCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) { + return client.GetNATRSIPStatusCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetPPPAuthenticationProtocolCtx( + ctx context.Context, +) (NewPPPAuthenticationProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPAuthenticationProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPPPAuthenticationProtocol is the legacy version of GetPPPAuthenticationProtocolCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) { + return client.GetPPPAuthenticationProtocolCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetPPPCompressionProtocolCtx( + ctx context.Context, +) (NewPPPCompressionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPCompressionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPPPCompressionProtocol is the legacy version of GetPPPCompressionProtocolCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) { + return client.GetPPPCompressionProtocolCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetPPPEncryptionProtocolCtx( + ctx context.Context, +) (NewPPPEncryptionProtocol string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPPPEncryptionProtocol string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPPPEncryptionProtocol is the legacy version of GetPPPEncryptionProtocolCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) { + return client.GetPPPEncryptionProtocolCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetPasswordCtx( + ctx context.Context, +) (NewPassword string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewPassword string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetPassword is the legacy version of GetPasswordCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) { + return client.GetPasswordCtx(context.Background()) +} + +// +// Arguments: +// +// * NewProtocol: allowed values: TCP, UDP + +func (client *WANPPPConnection1) GetSpecificPortMappingEntryCtx( + ctx context.Context, + NewRemoteHost string, + NewExternalPort uint16, + NewProtocol string, +) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + // Request structure. + request := &struct { + NewRemoteHost string + NewExternalPort string + NewProtocol string + }{} + // BEGIN Marshal arguments into request. + + if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { + return + } + if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { + return + } + if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewInternalPort string + NewInternalClient string + NewEnabled string + NewPortMappingDescription string + NewLeaseDuration string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { + return + } + if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { + return + } + if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { + return + } + if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { + return + } + if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetSpecificPortMappingEntry is the legacy version of GetSpecificPortMappingEntryCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { + return client.GetSpecificPortMappingEntryCtx(context.Background(), + NewRemoteHost, + NewExternalPort, + NewProtocol, + ) +} + +// +// Return values: +// +// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected +// +// * NewLastConnectionError: allowed values: ERROR_NONE +func (client *WANPPPConnection1) GetStatusInfoCtx( + ctx context.Context, +) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewConnectionStatus string + NewLastConnectionError string + NewUptime string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { + return + } + if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { + return + } + if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetStatusInfo is the legacy version of GetStatusInfoCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { + return client.GetStatusInfoCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetUserNameCtx( + ctx context.Context, +) (NewUserName string, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewUserName string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetUserName is the legacy version of GetUserNameCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) { + return client.GetUserNameCtx(context.Background()) +} + +func (client *WANPPPConnection1) GetWarnDisconnectDelayCtx( + ctx context.Context, +) (NewWarnDisconnectDelay uint32, err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := &struct { + NewWarnDisconnectDelay string + }{} + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { + return + } + // END Unmarshal arguments from response. + return +} + +// GetWarnDisconnectDelay is the legacy version of GetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) { + return client.GetWarnDisconnectDelayCtx(context.Background()) +} + +func (client *WANPPPConnection1) RequestConnectionCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestConnection is the legacy version of RequestConnectionCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) RequestConnection() (err error) { + return client.RequestConnectionCtx(context.Background()) +} + +func (client *WANPPPConnection1) RequestTerminationCtx( + ctx context.Context, +) (err error) { + // Request structure. + request := interface{}(nil) + // BEGIN Marshal arguments into request. + + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// RequestTermination is the legacy version of RequestTerminationCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) RequestTermination() (err error) { + return client.RequestTerminationCtx(context.Background()) +} + +func (client *WANPPPConnection1) SetAutoDisconnectTimeCtx( + ctx context.Context, + NewAutoDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewAutoDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetAutoDisconnectTime is the legacy version of SetAutoDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) { + return client.SetAutoDisconnectTimeCtx(context.Background(), + NewAutoDisconnectTime, + ) +} + +func (client *WANPPPConnection1) SetConnectionTypeCtx( + ctx context.Context, + NewConnectionType string, +) (err error) { + // Request structure. + request := &struct { + NewConnectionType string + }{} + // BEGIN Marshal arguments into request. + + if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetConnectionType is the legacy version of SetConnectionTypeCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) { + return client.SetConnectionTypeCtx(context.Background(), + NewConnectionType, + ) +} + +func (client *WANPPPConnection1) SetIdleDisconnectTimeCtx( + ctx context.Context, + NewIdleDisconnectTime uint32, +) (err error) { + // Request structure. + request := &struct { + NewIdleDisconnectTime string + }{} + // BEGIN Marshal arguments into request. + + if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetIdleDisconnectTime is the legacy version of SetIdleDisconnectTimeCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) { + return client.SetIdleDisconnectTimeCtx(context.Background(), + NewIdleDisconnectTime, + ) +} + +func (client *WANPPPConnection1) SetWarnDisconnectDelayCtx( + ctx context.Context, + NewWarnDisconnectDelay uint32, +) (err error) { + // Request structure. + request := &struct { + NewWarnDisconnectDelay string + }{} + // BEGIN Marshal arguments into request. + + if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { + return + } + // END Marshal arguments into request. + + // Response structure. + response := interface{}(nil) + + // Perform the SOAP call. + if err = client.SOAPClient.PerformActionCtx(ctx, URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { + return + } + + // BEGIN Unmarshal arguments from response. + + // END Unmarshal arguments from response. + return +} + +// SetWarnDisconnectDelay is the legacy version of SetWarnDisconnectDelayCtx, but uses +// context.Background() as the context. +func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) { + return client.SetWarnDisconnectDelayCtx(context.Background(), + NewWarnDisconnectDelay, + ) +} diff --git a/vendor/github.com/tailscale/goupnp/device.go b/vendor/github.com/huin/goupnp/device.go similarity index 83% rename from vendor/github.com/tailscale/goupnp/device.go rename to vendor/github.com/huin/goupnp/device.go index 0e4362f..65f5635 100644 --- a/vendor/github.com/tailscale/goupnp/device.go +++ b/vendor/github.com/huin/goupnp/device.go @@ -7,11 +7,11 @@ import ( "encoding/xml" "errors" "fmt" - "net/http" "net/url" + "strings" - "github.com/tailscale/goupnp/scpd" - "github.com/tailscale/goupnp/soap" + "github.com/huin/goupnp/scpd" + "github.com/huin/goupnp/soap" ) const ( @@ -52,6 +52,7 @@ type Device struct { ModelDescription string `xml:"modelDescription"` ModelName string `xml:"modelName"` ModelNumber string `xml:"modelNumber"` + ModelType string `xml:"modelType"` ModelURL URLField `xml:"modelURL"` SerialNumber string `xml:"serialNumber"` UDN string `xml:"UDN"` @@ -84,7 +85,7 @@ func (device *Device) VisitServices(visitor func(*Service)) { // FindService finds all (if any) Services under the device and its descendents // that have the given ServiceType. -func (device *Device) FindService(ctx context.Context, serviceType string) []*Service { +func (device *Device) FindService(serviceType string) []*Service { var services []*Service device.VisitServices(func(s *Service) { if s.ServiceType == serviceType { @@ -149,9 +150,9 @@ func (srv *Service) String() string { return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) } -// RequestSCPD requests the SCPD (soap actions and state variables description) +// RequestSCPDCtx requests the SCPD (soap actions and state variables description) // for the service. -func (srv *Service) RequestSCPD(ctx context.Context) (*scpd.SCPD, error) { +func (srv *Service) RequestSCPDCtx(ctx context.Context) (*scpd.SCPD, error) { if !srv.SCPDURL.Ok { return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set") } @@ -162,14 +163,20 @@ func (srv *Service) RequestSCPD(ctx context.Context) (*scpd.SCPD, error) { return s, nil } -// NewSOAPClient returns a new SOAP client to the service's control -// URL, using the provided http.Client. -// If httpc is nil, http.DefaultClient is used. -func (srv *Service) NewSOAPClient(httpc *http.Client) *soap.SOAPClient { - if httpc == nil { - httpc = http.DefaultClient - } - return soap.NewSOAPClient(srv.ControlURL.URL, httpc) +// RequestSCPD is the legacy version of RequestSCPDCtx, but uses +// context.Background() as the context. +func (srv *Service) RequestSCPD() (*scpd.SCPD, error) { + return srv.RequestSCPDCtx(context.Background()) +} + +// RequestSCDP is for compatibility only, prefer RequestSCPD. This was a +// misspelling of RequestSCDP. +func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { + return srv.RequestSCPD() +} + +func (srv *Service) NewSOAPClient() *soap.SOAPClient { + return soap.NewSOAPClient(srv.ControlURL.URL) } // URLField is a URL that is part of a device description. @@ -180,7 +187,12 @@ type URLField struct { } func (uf *URLField) SetURLBase(urlBase *url.URL) { - refUrl, err := url.Parse(uf.Str) + str := uf.Str + if !strings.Contains(str, "://") && !strings.HasPrefix(str, "/") { + str = "/" + str + } + + refUrl, err := url.Parse(str) if err != nil { uf.URL = url.URL{} uf.Ok = false diff --git a/vendor/github.com/huin/goupnp/go.work b/vendor/github.com/huin/goupnp/go.work new file mode 100644 index 0000000..9b7d1ff --- /dev/null +++ b/vendor/github.com/huin/goupnp/go.work @@ -0,0 +1,6 @@ +go 1.18 + +use ( + . + ./v2alpha +) diff --git a/vendor/github.com/tailscale/goupnp/goupnp.go b/vendor/github.com/huin/goupnp/goupnp.go similarity index 64% rename from vendor/github.com/tailscale/goupnp/goupnp.go rename to vendor/github.com/huin/goupnp/goupnp.go index ed56feb..9fa8963 100644 --- a/vendor/github.com/tailscale/goupnp/goupnp.go +++ b/vendor/github.com/huin/goupnp/goupnp.go @@ -1,11 +1,11 @@ // goupnp is an implementation of a client for various UPnP services. // // For most uses, it is recommended to use the code-generated packages under -// github.com/tailscale/goupnp/dcps. Example use is shown at -// http://godoc.org/github.com/tailscale/goupnp/example +// github.com/huin/goupnp/dcps. Example use is shown at +// http://godoc.org/github.com/huin/goupnp/example // // A commonly used client is internetgateway1.WANPPPConnection1: -// http://godoc.org/github.com/tailscale/goupnp/dcps/internetgateway1#WANPPPConnection1 +// http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1 // // Currently only a couple of schemas have code generated for them from the // UPnP example XML specifications. Not all methods will work on these clients, @@ -19,10 +19,13 @@ import ( "encoding/xml" "fmt" "io" + "net" "net/http" "net/url" + "time" - "github.com/tailscale/goupnp/ssdp" + "github.com/huin/goupnp/httpu" + "github.com/huin/goupnp/ssdp" ) // ContextError is an error that wraps an error with some context information. @@ -32,7 +35,10 @@ type ContextError struct { } func ctxError(err error, msg string) ContextError { - return ContextError{Context: msg, Err: err} + return ContextError{ + Context: msg, + Err: err, + } } func ctxErrorf(err error, msg string, args ...interface{}) ContextError { @@ -48,7 +54,8 @@ func (err ContextError) Error() string { // MaybeRootDevice contains either a RootDevice or an error. type MaybeRootDevice struct { - // Identifier of the device. + // Identifier of the device. Note that this in combination with Location + // uniquely identifies a result from DiscoverDevices. USN string // Set iff Err == nil. @@ -59,23 +66,29 @@ type MaybeRootDevice struct { // the discovery of a device, regardless of if there was an error probing it. Location *url.URL + // The address from which the device was discovered (if known - otherwise nil). + LocalAddr net.IP + // Any error encountered probing a discovered device. Err error } -// DiscoverDevices attempts to find targets of the given type. This is +// DiscoverDevicesCtx attempts to find targets of the given type. This is // typically the entry-point for this package. searchTarget is typically a URN // in the form "urn:schemas-upnp-org:device:..." or // "urn:schemas-upnp-org:service:...". A single error is returned for errors // while attempting to send the query. An error or RootDevice is returned for // each discovered RootDevice. -func DiscoverDevices(ctx context.Context, searchTarget string) ([]MaybeRootDevice, error) { - hc, err := httpuClient() +func DiscoverDevicesCtx(ctx context.Context, searchTarget string) ([]MaybeRootDevice, error) { + hc, hcCleanup, err := httpuClient() if err != nil { return nil, err } - defer hc.Close() - responses, err := ssdp.SSDPRawSearch(ctx, hc, string(searchTarget), 3) + defer hcCleanup() + + searchCtx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + responses, err := ssdp.RawSearch(searchCtx, hc, string(searchTarget), 3) if err != nil { return nil, err } @@ -90,17 +103,26 @@ func DiscoverDevices(ctx context.Context, searchTarget string) ([]MaybeRootDevic continue } maybe.Location = loc - if root, err := DeviceByURL(ctx, loc); err != nil { + if root, err := DeviceByURLCtx(ctx, loc); err != nil { maybe.Err = err } else { maybe.Root = root } + if i := response.Header.Get(httpu.LocalAddressHeader); len(i) > 0 { + maybe.LocalAddr = net.ParseIP(i) + } } return results, nil } -func DeviceByURL(ctx context.Context, loc *url.URL) (*RootDevice, error) { +// DiscoverDevices is the legacy version of DiscoverDevicesCtx, but uses +// context.Background() as the context. +func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) { + return DiscoverDevicesCtx(context.Background(), searchTarget) +} + +func DeviceByURLCtx(ctx context.Context, loc *url.URL) (*RootDevice, error) { locStr := loc.String() root := new(RootDevice) if err := requestXml(ctx, locStr, DeviceXMLNamespace, root); err != nil { @@ -120,45 +142,42 @@ func DeviceByURL(ctx context.Context, loc *url.URL) (*RootDevice, error) { return root, nil } +func DeviceByURL(loc *url.URL) (*RootDevice, error) { + return DeviceByURLCtx(context.Background(), loc) +} + // CharsetReaderDefault specifies the charset reader used while decoding the output // from a UPnP server. It can be modified in an init function to allow for non-utf8 encodings, // but should not be changed after requesting clients. var CharsetReaderDefault func(charset string, input io.Reader) (io.Reader, error) -// contextKey is an unexported type which prevents construction of other contextKeys. -type httpContextKey struct{} +// HTTPClient specifies the http.Client object used when fetching the XML from the UPnP server. +// HTTPClient defaults the http.DefaultClient. This may be overridden by the importing application. +var HTTPClientDefault = http.DefaultClient -// WithHTTPClient returns a context wrapping ctx with the HTTP client set to c. -// If c is nil, http.DefaultClient is used. -func WithHTTPClient(ctx context.Context, c *http.Client) context.Context { - return context.WithValue(ctx, httpContextKey{}, c) -} +func requestXml(ctx context.Context, url string, defaultSpace string, doc interface{}) error { + ctx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() -func httpClient(ctx context.Context) *http.Client { - if c, _ := ctx.Value(httpContextKey{}).(*http.Client); c != nil { - return c - } - return http.DefaultClient -} - -func requestXml(ctx context.Context, url string, defaultSpace string, into interface{}) error { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return err } - resp, err := httpClient(ctx).Do(req) + + resp, err := HTTPClientDefault.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 { - return fmt.Errorf("goupnp: got response status %s from %q", resp.Status, url) + return fmt.Errorf("goupnp: got response status %s from %q", + resp.Status, url) } decoder := xml.NewDecoder(resp.Body) decoder.DefaultSpace = defaultSpace decoder.CharsetReader = CharsetReaderDefault - return decoder.Decode(into) + return decoder.Decode(doc) } diff --git a/vendor/github.com/huin/goupnp/goupnp.sublime-project b/vendor/github.com/huin/goupnp/goupnp.sublime-project new file mode 100644 index 0000000..24db303 --- /dev/null +++ b/vendor/github.com/huin/goupnp/goupnp.sublime-project @@ -0,0 +1,8 @@ +{ + "folders": + [ + { + "path": "." + } + ] +} diff --git a/vendor/github.com/tailscale/goupnp/httpu/httpu.go b/vendor/github.com/huin/goupnp/httpu/httpu.go similarity index 66% rename from vendor/github.com/tailscale/goupnp/httpu/httpu.go rename to vendor/github.com/huin/goupnp/httpu/httpu.go index cef24da..5bb8d67 100644 --- a/vendor/github.com/tailscale/goupnp/httpu/httpu.go +++ b/vendor/github.com/huin/goupnp/httpu/httpu.go @@ -3,9 +3,9 @@ package httpu import ( "bufio" "bytes" + "context" "errors" "fmt" - "io" "log" "net" "net/http" @@ -16,12 +16,36 @@ import ( // ClientInterface is the general interface provided to perform HTTP-over-UDP // requests. type ClientInterface interface { - io.Closer // Do performs a request. The timeout is how long to wait for before returning // the responses that were received. An error is only returned for failing to // send the request. Failures in receipt simply do not add to the resulting // responses. - Do(req *http.Request, numSends int) ([]*http.Response, error) + Do( + req *http.Request, + timeout time.Duration, + numSends int, + ) ([]*http.Response, error) +} + +// ClientInterfaceCtx is the equivalent of ClientInterface, except with methods +// taking a context.Context parameter. +type ClientInterfaceCtx interface { + // DoWithContext performs a request. If the input request has a + // deadline, then that value will be used as the timeout for how long + // to wait before returning the responses that were received. If the + // request's context is canceled, this method will return immediately. + // + // If the request's context is never canceled, and does not have a + // deadline, then this function WILL NEVER RETURN. You MUST set an + // appropriate deadline on the context, or otherwise cancel it when you + // want to finish an operation. + // + // An error is only returned for failing to send the request. Failures + // in receipt simply do not add to the resulting responses. + DoWithContext( + req *http.Request, + numSends int, + ) ([]*http.Response, error) } // HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical @@ -32,6 +56,7 @@ type HTTPUClient struct { } var _ ClientInterface = &HTTPUClient{} +var _ ClientInterfaceCtx = &HTTPUClient{} // NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the // purpose. @@ -70,6 +95,26 @@ func (httpu *HTTPUClient) Close() error { // Note that at present only one concurrent connection will happen per // HTTPUClient. func (httpu *HTTPUClient) Do( + req *http.Request, + timeout time.Duration, + numSends int, +) ([]*http.Response, error) { + ctx := req.Context() + if timeout > 0 { + var cancel func() + ctx, cancel = context.WithTimeout(ctx, timeout) + defer cancel() + req = req.WithContext(ctx) + } + + return httpu.DoWithContext(req, numSends) +} + +// DoWithContext implements ClientInterfaceCtx.DoWithContext. +// +// Make sure to read the documentation on the ClientInterfaceCtx interface +// regarding cancellation! +func (httpu *HTTPUClient) DoWithContext( req *http.Request, numSends int, ) ([]*http.Response, error) { @@ -98,25 +143,27 @@ func (httpu *HTTPUClient) Do( if err != nil { return nil, err } + + // Handle context deadline/timeout ctx := req.Context() deadline, ok := ctx.Deadline() - if !ok { - deadline = time.Now().Add(2 * time.Second) + if ok { + if err = httpu.conn.SetDeadline(deadline); err != nil { + return nil, err + } } - returned := make(chan struct{}) - defer close(returned) + // Handle context cancelation + done := make(chan struct{}) + defer close(done) go func() { select { case <-ctx.Done(): // if context is cancelled, stop any connections by setting time in the past. httpu.conn.SetDeadline(time.Now().Add(-time.Second)) - case <-returned: + case <-done: } }() - if err = httpu.conn.SetDeadline(deadline); err != nil { - return nil, err - } // Send request. for i := 0; i < numSends; i++ { @@ -156,9 +203,16 @@ func (httpu *HTTPUClient) Do( continue } + // Set the related local address used to discover the device. + if a, ok := httpu.conn.LocalAddr().(*net.UDPAddr); ok { + response.Header.Add(LocalAddressHeader, a.IP.String()) + } + responses = append(responses, response) } // Timeout reached - return discovered responses. return responses, nil } + +const LocalAddressHeader = "goupnp-local-address" diff --git a/vendor/github.com/huin/goupnp/httpu/multiclient.go b/vendor/github.com/huin/goupnp/httpu/multiclient.go new file mode 100644 index 0000000..5cc65e9 --- /dev/null +++ b/vendor/github.com/huin/goupnp/httpu/multiclient.go @@ -0,0 +1,132 @@ +package httpu + +import ( + "net/http" + "time" + + "golang.org/x/sync/errgroup" +) + +// MultiClient dispatches requests out to all the delegated clients. +type MultiClient struct { + // The HTTPU clients to delegate to. + delegates []ClientInterface +} + +var _ ClientInterface = &MultiClient{} + +// NewMultiClient creates a new MultiClient that delegates to all the given +// clients. +func NewMultiClient(delegates []ClientInterface) *MultiClient { + return &MultiClient{ + delegates: delegates, + } +} + +// Do implements ClientInterface.Do. +func (mc *MultiClient) Do( + req *http.Request, + timeout time.Duration, + numSends int, +) ([]*http.Response, error) { + tasks := &errgroup.Group{} + + results := make(chan []*http.Response) + tasks.Go(func() error { + defer close(results) + return mc.sendRequests(results, req, timeout, numSends) + }) + + var responses []*http.Response + tasks.Go(func() error { + for rs := range results { + responses = append(responses, rs...) + } + return nil + }) + + return responses, tasks.Wait() +} + +func (mc *MultiClient) sendRequests( + results chan<- []*http.Response, + req *http.Request, + timeout time.Duration, + numSends int, +) error { + tasks := &errgroup.Group{} + for _, d := range mc.delegates { + d := d // copy for closure + tasks.Go(func() error { + responses, err := d.Do(req, timeout, numSends) + if err != nil { + return err + } + results <- responses + return nil + }) + } + return tasks.Wait() +} + +// MultiClientCtx dispatches requests out to all the delegated clients. +type MultiClientCtx struct { + // The HTTPU clients to delegate to. + delegates []ClientInterfaceCtx +} + +var _ ClientInterfaceCtx = &MultiClientCtx{} + +// NewMultiClient creates a new MultiClient that delegates to all the given +// clients. +func NewMultiClientCtx(delegates []ClientInterfaceCtx) *MultiClientCtx { + return &MultiClientCtx{ + delegates: delegates, + } +} + +// DoWithContext implements ClientInterfaceCtx.DoWithContext. +func (mc *MultiClientCtx) DoWithContext( + req *http.Request, + numSends int, +) ([]*http.Response, error) { + tasks, ctx := errgroup.WithContext(req.Context()) + req = req.WithContext(ctx) // so we cancel if the errgroup errors + results := make(chan []*http.Response) + + // For each client, send the request to it and collect results. + tasks.Go(func() error { + defer close(results) + return mc.sendRequestsCtx(results, req, numSends) + }) + + var responses []*http.Response + tasks.Go(func() error { + for rs := range results { + responses = append(responses, rs...) + } + return nil + }) + + return responses, tasks.Wait() +} + +func (mc *MultiClientCtx) sendRequestsCtx( + results chan<- []*http.Response, + req *http.Request, + numSends int, +) error { + tasks := &errgroup.Group{} + for _, d := range mc.delegates { + d := d // copy for closure + tasks.Go(func() error { + responses, err := d.DoWithContext(req, numSends) + if err != nil { + return err + } + results <- responses + return nil + }) + } + return tasks.Wait() +} diff --git a/vendor/github.com/tailscale/goupnp/httpu/serve.go b/vendor/github.com/huin/goupnp/httpu/serve.go similarity index 91% rename from vendor/github.com/tailscale/goupnp/httpu/serve.go rename to vendor/github.com/huin/goupnp/httpu/serve.go index 9f67af8..bac3296 100644 --- a/vendor/github.com/tailscale/goupnp/httpu/serve.go +++ b/vendor/github.com/huin/goupnp/httpu/serve.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "regexp" + "sync" ) const ( @@ -73,20 +74,25 @@ func (srv *Server) Serve(l net.PacketConn) error { if srv.MaxMessageBytes != 0 { maxMessageBytes = srv.MaxMessageBytes } + + bufPool := &sync.Pool{ + New: func() interface{} { + return make([]byte, maxMessageBytes) + }, + } for { - buf := make([]byte, maxMessageBytes) + buf := bufPool.Get().([]byte) n, peerAddr, err := l.ReadFrom(buf) if err != nil { return err } - buf = buf[:n] - - go func(buf []byte, peerAddr net.Addr) { + go func() { + defer bufPool.Put(buf) // At least one router's UPnP implementation has added a trailing space // after "HTTP/1.1" - trim it. - buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf) + reqBuf := trailingWhitespaceRx.ReplaceAllLiteral(buf[:n], crlf) - req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf))) + req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(reqBuf))) if err != nil { log.Printf("httpu: Failed to parse request: %v", err) return @@ -94,7 +100,7 @@ func (srv *Server) Serve(l net.PacketConn) error { req.RemoteAddr = peerAddr.String() srv.Handler.ServeMessage(req) // No need to call req.Body.Close - underlying reader is bytes.Buffer. - }(buf, peerAddr) + }() } } diff --git a/vendor/github.com/tailscale/goupnp/network.go b/vendor/github.com/huin/goupnp/network.go similarity index 72% rename from vendor/github.com/tailscale/goupnp/network.go rename to vendor/github.com/huin/goupnp/network.go index f02f29f..a2c3a45 100644 --- a/vendor/github.com/tailscale/goupnp/network.go +++ b/vendor/github.com/huin/goupnp/network.go @@ -1,30 +1,40 @@ package goupnp import ( + "io" "net" - "github.com/tailscale/goupnp/httpu" + "github.com/huin/goupnp/httpu" ) // httpuClient creates a HTTPU client that multiplexes to all multicast-capable // IPv4 addresses on the host. Returns a function to clean up once the client is // no longer required. -func httpuClient() (*httpu.MultiClient, error) { +func httpuClient() (httpu.ClientInterfaceCtx, func(), error) { addrs, err := localIPv4MCastAddrs() if err != nil { - return nil, ctxError(err, "requesting host IPv4 addresses") + return nil, nil, ctxError(err, "requesting host IPv4 addresses") } - delegates := make([]httpu.ClientInterface, 0, len(addrs)) + closers := make([]io.Closer, 0, len(addrs)) + delegates := make([]httpu.ClientInterfaceCtx, 0, len(addrs)) for _, addr := range addrs { c, err := httpu.NewHTTPUClientAddr(addr) if err != nil { - return nil, ctxErrorf(err, "creating HTTPU client for address %s", addr) + return nil, nil, ctxErrorf(err, + "creating HTTPU client for address %s", addr) } + closers = append(closers, c) delegates = append(delegates, c) } - return httpu.NewMultiClient(delegates), nil + closer := func() { + for _, c := range closers { + c.Close() + } + } + + return httpu.NewMultiClientCtx(delegates), closer, nil } // localIPv2MCastAddrs returns the set of IPv4 addresses on multicast-able diff --git a/vendor/github.com/tailscale/goupnp/scpd/scpd.go b/vendor/github.com/huin/goupnp/scpd/scpd.go similarity index 94% rename from vendor/github.com/tailscale/goupnp/scpd/scpd.go rename to vendor/github.com/huin/goupnp/scpd/scpd.go index c9d2e69..59573cc 100644 --- a/vendor/github.com/tailscale/goupnp/scpd/scpd.go +++ b/vendor/github.com/huin/goupnp/scpd/scpd.go @@ -2,6 +2,7 @@ package scpd import ( "encoding/xml" + "sort" "strings" ) @@ -37,6 +38,14 @@ func (scpd *SCPD) Clean() { } } +func (scpd *SCPD) OrderedActions() []Action { + actions := append([]Action{}, scpd.Actions...) + sort.SliceStable(actions, func(i, j int) bool { + return actions[i].Name < actions[j].Name + }) + return actions +} + func (scpd *SCPD) GetStateVariable(variable string) *StateVariable { for i := range scpd.StateVariables { v := &scpd.StateVariables[i] diff --git a/vendor/github.com/huin/goupnp/service_client.go b/vendor/github.com/huin/goupnp/service_client.go new file mode 100644 index 0000000..cb65c19 --- /dev/null +++ b/vendor/github.com/huin/goupnp/service_client.go @@ -0,0 +1,118 @@ +package goupnp + +import ( + "context" + "fmt" + "net" + "net/url" + + "github.com/huin/goupnp/soap" +) + +// ServiceClient is a SOAP client, root device and the service for the SOAP +// client rolled into one value. The root device, location, and service are +// intended to be informational. Location can be used to later recreate a +// ServiceClient with NewServiceClientByURL if the service is still present; +// bypassing the discovery process. +type ServiceClient struct { + SOAPClient *soap.SOAPClient + RootDevice *RootDevice + Location *url.URL + Service *Service + localAddr net.IP +} + +// NewServiceClientsCtx discovers services, and returns clients for them. err will +// report any error with the discovery process (blocking any device/service +// discovery), errors reports errors on a per-root-device basis. +func NewServiceClientsCtx(ctx context.Context, searchTarget string) (clients []ServiceClient, errors []error, err error) { + var maybeRootDevices []MaybeRootDevice + if maybeRootDevices, err = DiscoverDevicesCtx(ctx, searchTarget); err != nil { + return + } + + clients = make([]ServiceClient, 0, len(maybeRootDevices)) + + for _, maybeRootDevice := range maybeRootDevices { + if maybeRootDevice.Err != nil { + errors = append(errors, maybeRootDevice.Err) + continue + } + + deviceClients, err := newServiceClientsFromRootDevice(maybeRootDevice.Root, maybeRootDevice.Location, searchTarget, maybeRootDevice.LocalAddr) + if err != nil { + errors = append(errors, err) + continue + } + clients = append(clients, deviceClients...) + } + + return +} + +// NewServiceClients is the legacy version of NewServiceClientsCtx, but uses +// context.Background() as the context. +func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) { + return NewServiceClientsCtx(context.Background(), searchTarget) +} + +// NewServiceClientsByURLCtx creates client(s) for the given service URN, for a +// root device at the given URL. +func NewServiceClientsByURLCtx(ctx context.Context, loc *url.URL, searchTarget string) ([]ServiceClient, error) { + rootDevice, err := DeviceByURLCtx(ctx, loc) + if err != nil { + return nil, err + } + return NewServiceClientsFromRootDevice(rootDevice, loc, searchTarget) +} + +// NewServiceClientsByURL is the legacy version of NewServiceClientsByURLCtx, but uses +// context.Background() as the context. +func NewServiceClientsByURL(loc *url.URL, searchTarget string) ([]ServiceClient, error) { + return NewServiceClientsByURLCtx(context.Background(), loc, searchTarget) +} + +// NewServiceClientsFromDevice creates client(s) for the given service URN, in +// a given root device. The loc parameter is simply assigned to the +// Location attribute of the returned ServiceClient(s). +func NewServiceClientsFromRootDevice(rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) { + return newServiceClientsFromRootDevice(rootDevice, loc, searchTarget, nil) +} + +func newServiceClientsFromRootDevice( + rootDevice *RootDevice, + loc *url.URL, + searchTarget string, + lAddr net.IP, +) ([]ServiceClient, error) { + device := &rootDevice.Device + srvs := device.FindService(searchTarget) + if len(srvs) == 0 { + return nil, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)", + searchTarget, device.FriendlyName, device.UDN) + } + + clients := make([]ServiceClient, 0, len(srvs)) + for _, srv := range srvs { + clients = append(clients, ServiceClient{ + SOAPClient: srv.NewSOAPClient(), + RootDevice: rootDevice, + Location: loc, + Service: srv, + localAddr: lAddr, + }) + } + return clients, nil +} + +// GetServiceClient returns the ServiceClient itself. This is provided so that the +// service client attributes can be accessed via an interface method on a +// wrapping type. +func (client *ServiceClient) GetServiceClient() *ServiceClient { + return client +} + +// LocalAddr returns the address from which the device was discovered (if known - otherwise empty). +func (client *ServiceClient) LocalAddr() net.IP { + return client.localAddr +} diff --git a/vendor/github.com/tailscale/goupnp/soap/soap.go b/vendor/github.com/huin/goupnp/soap/soap.go similarity index 77% rename from vendor/github.com/tailscale/goupnp/soap/soap.go rename to vendor/github.com/huin/goupnp/soap/soap.go index 0265fa1..689f2a4 100644 --- a/vendor/github.com/tailscale/goupnp/soap/soap.go +++ b/vendor/github.com/huin/goupnp/soap/soap.go @@ -11,7 +11,7 @@ import ( "net/http" "net/url" "reflect" - "strings" + "regexp" ) const ( @@ -22,25 +22,19 @@ const ( type SOAPClient struct { EndpointURL url.URL - HTTPClient *http.Client + HTTPClient http.Client } -// NewSoapClient creates a new soap client to a specific URL using a given http.Client. -// The http.Client must not be nil. -func NewSOAPClient(endpointURL url.URL, httpClient *http.Client) *SOAPClient { +func NewSOAPClient(endpointURL url.URL) *SOAPClient { return &SOAPClient{ EndpointURL: endpointURL, - HTTPClient: httpClient, } } // PerformSOAPAction makes a SOAP request, with the given action. // inAction and outAction must both be pointers to structs with string fields // only. -func (client *SOAPClient) PerformAction( - ctx context.Context, actionNamespace, actionName string, - inAction interface{}, outAction interface{}, -) error { +func (client *SOAPClient) PerformActionCtx(ctx context.Context, actionNamespace, actionName string, inAction interface{}, outAction interface{}) error { requestBytes, err := encodeRequestAction(actionNamespace, actionName, inAction) if err != nil { return err @@ -57,8 +51,8 @@ func (client *SOAPClient) PerformAction( // Set ContentLength to avoid chunked encoding - some servers might not support it. ContentLength: int64(len(requestBytes)), } - - response, err := client.HTTPClient.Do(req.WithContext(ctx)) + req = req.WithContext(ctx) + response, err := client.HTTPClient.Do(req) if err != nil { return fmt.Errorf("goupnp: error performing SOAP HTTP request: %v", err) } @@ -79,18 +73,26 @@ func (client *SOAPClient) PerformAction( return fmt.Errorf("goupnp: SOAP request got HTTP %s", response.Status) } - if outAction == nil { - return nil - } - if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { - return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction) + if outAction != nil { + if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil { + return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction) + } } + return nil } +// PerformAction is the legacy version of PerformActionCtx, which uses +// context.Background. +func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAction interface{}, outAction interface{}) error { + return client.PerformActionCtx(context.Background(), actionNamespace, actionName, inAction, outAction) +} + // newSOAPAction creates a soapEnvelope with the given action and arguments. func newSOAPEnvelope() *soapEnvelope { - return &soapEnvelope{EncodingStyle: soapEncodingStyle} + return &soapEnvelope{ + EncodingStyle: soapEncodingStyle, + } } // encodeRequestAction is a hacky way to create an encoded SOAP envelope @@ -136,7 +138,7 @@ func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { if value.Kind() != reflect.String { return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type()) } - elem := xml.StartElement{Name: xml.Name{Local: argName}} + elem := xml.StartElement{Name: xml.Name{Space: "", Local: argName}, Attr: nil} if err := enc.EncodeToken(elem); err != nil { return fmt.Errorf("goupnp: error encoding start element for SOAP arg %q: %v", argName, err) } @@ -154,7 +156,7 @@ func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { return nil } -var replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&") +var xmlCharRx = regexp.MustCompile("[<>&]") // escapeXMLText is used by generated code to escape text in XML, but only // escaping the characters `<`, `>`, and `&`. @@ -164,7 +166,19 @@ var replacer = strings.NewReplacer("<", "<", ">", ">", "&", "&") // that this can only be safely used for injecting into XML text, but not into // attributes or other contexts. func escapeXMLText(s string) string { - return replacer.Replace(s) + return xmlCharRx.ReplaceAllStringFunc(s, replaceEntity) +} + +func replaceEntity(s string) string { + switch s { + case "<": + return "<" + case ">": + return ">" + case "&": + return "&" + } + return s } type soapEnvelope struct { @@ -180,13 +194,18 @@ type soapBody struct { // SOAPFaultError implements error, and contains SOAP fault information. type SOAPFaultError struct { - FaultCode string `xml:"faultCode"` - FaultString string `xml:"faultString"` + FaultCode string `xml:"faultcode"` + FaultString string `xml:"faultstring"` Detail struct { + UPnPError struct { + Errorcode int `xml:"errorCode"` + ErrorDescription string `xml:"errorDescription"` + } `xml:"UPnPError"` Raw []byte `xml:",innerxml"` } `xml:"detail"` } func (err *SOAPFaultError) Error() string { - return fmt.Sprintf("SOAP fault: %s", err.FaultString) + return fmt.Sprintf("SOAP fault. Code: %s | Explanation: %s | Detail: %s", + err.FaultCode, err.FaultString, string(err.Detail.Raw)) } diff --git a/vendor/github.com/tailscale/goupnp/soap/types.go b/vendor/github.com/huin/goupnp/soap/types.go similarity index 68% rename from vendor/github.com/tailscale/goupnp/soap/types.go rename to vendor/github.com/huin/goupnp/soap/types.go index d2cb8aa..b54b216 100644 --- a/vendor/github.com/tailscale/goupnp/soap/types.go +++ b/vendor/github.com/huin/goupnp/soap/types.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/url" + "regexp" "strconv" "strings" "time" @@ -164,116 +165,122 @@ func parseInt(s string, err *error) int { return int(v) } -var dateLayouts = []string{ - "2006-01-02", - "20060102", - - "2006-01", - "200601", - - "2006", +var dateRegexps = []*regexp.Regexp{ + // yyyy[-mm[-dd]] + regexp.MustCompile(`^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$`), + // yyyy[mm[dd]] + regexp.MustCompile(`^(\d{4})(?:(\d{2})(?:(\d{2}))?)?$`), } func parseDateParts(s string) (year, month, day int, err error) { - var parsed time.Time - for _, layout := range dateLayouts { - parsed, err = time.Parse(layout, s) - if err == nil { + var parts []string + for _, re := range dateRegexps { + parts = re.FindStringSubmatch(s) + if parts != nil { break } } - if err != nil { + if parts == nil { err = fmt.Errorf("soap date: value %q is not in a recognized ISO8601 date format", s) return } - year = int(parsed.Year()) - month = int(parsed.Month()) - day = int(parsed.Day()) + + year = parseInt(parts[1], &err) + month = 1 + day = 1 + if len(parts[2]) != 0 { + month = parseInt(parts[2], &err) + if len(parts[3]) != 0 { + day = parseInt(parts[3], &err) + } + } + + if err != nil { + err = fmt.Errorf("soap date: %q: %v", s, err) + } + return } -var timeLayouts = []string{ - "15:04:05", - "150405", - - "15:04", - "1504", - - "15", +var timeRegexps = []*regexp.Regexp{ + // hh[:mm[:ss]] + regexp.MustCompile(`^(\d{2})(?::(\d{2})(?::(\d{2}))?)?$`), + // hh[mm[ss]] + regexp.MustCompile(`^(\d{2})(?:(\d{2})(?:(\d{2}))?)?$`), } func parseTimeParts(s string) (hour, minute, second int, err error) { - // special case 24 hour time limit - if s == "24:00:00" { - return 24, 0, 0, nil - } - var parsed time.Time - for _, layout := range timeLayouts { - parsed, err = time.Parse(layout, s) - if err == nil { + var parts []string + for _, re := range timeRegexps { + parts = re.FindStringSubmatch(s) + if parts != nil { break } } - if err != nil { + if parts == nil { err = fmt.Errorf("soap time: value %q is not in ISO8601 time format", s) return } - hour = parsed.Hour() - minute = parsed.Minute() - second = parsed.Second() + hour = parseInt(parts[1], &err) + if len(parts[2]) != 0 { + minute = parseInt(parts[2], &err) + if len(parts[3]) != 0 { + second = parseInt(parts[3], &err) + } + } + + if err != nil { + err = fmt.Errorf("soap time: %q: %v", s, err) + } + return } // (+|-)hh[[:]mm] -var timezoneLayouts = []string{ - "+07:00", - "-07:00", +var timezoneRegexp = regexp.MustCompile(`^([+-])(\d{2})(?::?(\d{2}))?$`) - "+0700", - "-0700", - - "+07", - "-07", -} - -func parseTimezone(s string) (loc *time.Location, err error) { +func parseTimezone(s string) (offset int, err error) { if s == "Z" { - return time.UTC, nil + return 0, nil } - var parsed time.Time - for _, layout := range timezoneLayouts { - parsed, err = time.Parse(layout, s) - if err == nil { - break - } - } - if err != nil { + parts := timezoneRegexp.FindStringSubmatch(s) + if parts == nil { err = fmt.Errorf("soap timezone: value %q is not in ISO8601 timezone format", s) return } - return parsed.Location(), nil + + offset = parseInt(parts[2], &err) * 3600 + if len(parts[3]) != 0 { + offset += parseInt(parts[3], &err) * 60 + } + if parts[1] == "-" { + offset = -offset + } + + if err != nil { + err = fmt.Errorf("soap timezone: %q: %v", s, err) + } + + return } +var completeDateTimeZoneRegexp = regexp.MustCompile(`^([^T]+)(?:T([^-+Z]+)(.+)?)?$`) + // splitCompleteDateTimeZone splits date, time and timezone apart from an // ISO8601 string. It does not ensure that the contents of each part are // correct, it merely splits on certain delimiters. // e.g "2010-09-08T12:15:10+0700" => "2010-09-08", "12:15:10", "+0700". // Timezone can only be present if time is also present. -func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string) { - dateIndex := strings.Index(s, "T") - if dateIndex == -1 { - dateStr = s +func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string, err error) { + parts := completeDateTimeZoneRegexp.FindStringSubmatch(s) + if parts == nil { + err = fmt.Errorf("soap date/time/zone: value %q is not in ISO8601 datetime format", s) return } - dateStr = s[:dateIndex] - zoneIndex := strings.IndexAny(s[dateIndex:], "Z+-") - if zoneIndex == -1 { - timeStr = s[dateIndex+1:] - return - } - timeStr = s[dateIndex+1 : dateIndex+zoneIndex] - zoneStr = s[dateIndex+zoneIndex:] + dateStr = parts[1] + timeStr = parts[2] + zoneStr = parts[3] return } @@ -300,10 +307,14 @@ type TimeOfDay struct { // Duration of time since midnight. FromMidnight time.Duration + // Set to true if Offset is specified. If false, then the timezone is + // unspecified (and by ISO8601 - implies some "local" time). + HasOffset bool + // Offset is non-zero only if time.tz is used. It is otherwise ignored. If // non-zero, then it is regarded as a UTC offset in seconds. Note that the // sub-minutes is ignored by the marshal function. - Location *time.Location + Offset int } // MarshalTimeOfDay marshals TimeOfDay to the "time" type. @@ -321,9 +332,9 @@ func MarshalTimeOfDay(v TimeOfDay) (string, error) { func UnmarshalTimeOfDay(s string) (TimeOfDay, error) { t, err := UnmarshalTimeOfDayTz(s) if err != nil { - return t, err - } else if t.Location != time.UTC { - return t, fmt.Errorf("soap time: value %q contains unexpected timezone", s) + return TimeOfDay{}, err + } else if t.HasOffset { + return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone", s) } return t, nil } @@ -335,24 +346,38 @@ func MarshalTimeOfDayTz(v TimeOfDay) (string, error) { d = d % 3600 minute := d / 60 second := d % 60 - if v.Location == nil { - t := time.Date(0, 0, 0, int(hour), int(minute), int(second), 0, time.UTC) - return t.Format("15:04:05"), nil + + tz := "" + if v.HasOffset { + if v.Offset == 0 { + tz = "Z" + } else { + offsetMins := v.Offset / 60 + sign := '+' + if offsetMins < 1 { + offsetMins = -offsetMins + sign = '-' + } + tz = fmt.Sprintf("%c%02d:%02d", sign, offsetMins/60, offsetMins%60) + } } - t := time.Date(0, 0, 0, int(hour), int(minute), int(second), 0, v.Location) - return t.Format("15:04:05Z07:00"), nil + + return fmt.Sprintf("%02d:%02d:%02d%s", hour, minute, second, tz), nil } // UnmarshalTimeOfDayTz unmarshals TimeOfDay from the "time.tz" type. func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) { zoneIndex := strings.IndexAny(s, "Z+-") var timePart string - loc := time.UTC + var hasOffset bool + var offset int if zoneIndex == -1 { + hasOffset = false timePart = s } else { + hasOffset = true timePart = s[:zoneIndex] - if loc, err = parseTimezone(s[zoneIndex:]); err != nil { + if offset, err = parseTimezone(s[zoneIndex:]); err != nil { return } } @@ -367,12 +392,13 @@ func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) { // ISO8601 special case - values up to 24:00:00 are allowed, so using // strictly greater-than for the maximum value. if fromMidnight > 24*time.Hour || minute >= 60 || second >= 60 { - return TimeOfDay{Location: localLoc}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s) + return TimeOfDay{}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s) } return TimeOfDay{ FromMidnight: time.Duration(hour*3600+minute*60+second) * time.Second, - Location: loc, + HasOffset: hasOffset, + Offset: offset, }, nil } @@ -385,7 +411,10 @@ func MarshalDateTime(v time.Time) (string, error) { // UnmarshalDateTime unmarshals time.Time from the SOAP "dateTime" type. This // returns a value in the local timezone. func UnmarshalDateTime(s string) (result time.Time, err error) { - dateStr, timeStr, zoneStr := splitCompleteDateTimeZone(s) + dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) + if err != nil { + return + } if len(zoneStr) != 0 { err = fmt.Errorf("soap datetime: unexpected timezone in %q", s) @@ -417,7 +446,10 @@ func MarshalDateTimeTz(v time.Time) (string, error) { // UnmarshalDateTimeTz unmarshals time.Time from the SOAP "dateTime.tz" type. // This returns a value in the local timezone when the timezone is unspecified. func UnmarshalDateTimeTz(s string) (result time.Time, err error) { - dateStr, timeStr, zoneStr := splitCompleteDateTimeZone(s) + dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s) + if err != nil { + return + } year, month, day, err := parseDateParts(dateStr) if err != nil { @@ -425,14 +457,20 @@ func UnmarshalDateTimeTz(s string) (result time.Time, err error) { } var hour, minute, second int - location := localLoc + var location *time.Location = localLoc if len(timeStr) != 0 { hour, minute, second, err = parseTimeParts(timeStr) if err != nil { return } if len(zoneStr) != 0 { - location, err = parseTimezone(zoneStr) + var offset int + offset, err = parseTimezone(zoneStr) + if offset == 0 { + location = time.UTC + } else { + location = time.FixedZone("", offset) + } } } @@ -488,3 +526,53 @@ func MarshalURI(v *url.URL) (string, error) { func UnmarshalURI(s string) (*url.URL, error) { return url.Parse(s) } + +// TypeData provides metadata about for marshalling and unmarshalling a SOAP +// type. +type TypeData struct { + funcSuffix string + goType string +} + +// GoTypeName returns the name of the Go type. +func (td TypeData) GoTypeName() string { + return td.goType +} + +// MarshalFunc returns the name of the function that marshals the type. +func (td TypeData) MarshalFunc() string { + return fmt.Sprintf("Marshal%s", td.funcSuffix) +} + +// UnmarshalFunc returns the name of the function that unmarshals the type. +func (td TypeData) UnmarshalFunc() string { + return fmt.Sprintf("Unmarshal%s", td.funcSuffix) +} + +// TypeDataMap maps from a SOAP type (e.g "fixed.14.4") to its type data. +var TypeDataMap = map[string]TypeData{ + "ui1": {"Ui1", "uint8"}, + "ui2": {"Ui2", "uint16"}, + "ui4": {"Ui4", "uint32"}, + "ui8": {"Ui8", "uint64"}, + "i1": {"I1", "int8"}, + "i2": {"I2", "int16"}, + "i4": {"I4", "int32"}, + "int": {"Int", "int64"}, + "r4": {"R4", "float32"}, + "r8": {"R8", "float64"}, + "number": {"R8", "float64"}, // Alias for r8. + "fixed.14.4": {"Fixed14_4", "float64"}, + "float": {"R8", "float64"}, + "char": {"Char", "rune"}, + "string": {"String", "string"}, + "date": {"Date", "time.Time"}, + "dateTime": {"DateTime", "time.Time"}, + "dateTime.tz": {"DateTimeTz", "time.Time"}, + "time": {"TimeOfDay", "soap.TimeOfDay"}, + "time.tz": {"TimeOfDayTz", "soap.TimeOfDay"}, + "boolean": {"Boolean", "bool"}, + "bin.base64": {"BinBase64", "[]byte"}, + "bin.hex": {"BinHex", "[]byte"}, + "uri": {"URI", "*url.URL"}, +} diff --git a/vendor/github.com/tailscale/goupnp/ssdp/registry.go b/vendor/github.com/huin/goupnp/ssdp/registry.go similarity index 99% rename from vendor/github.com/tailscale/goupnp/ssdp/registry.go rename to vendor/github.com/huin/goupnp/ssdp/registry.go index 2dada0f..d3bc114 100644 --- a/vendor/github.com/tailscale/goupnp/ssdp/registry.go +++ b/vendor/github.com/huin/goupnp/ssdp/registry.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "github.com/tailscale/goupnp/httpu" + "github.com/huin/goupnp/httpu" ) const ( diff --git a/vendor/github.com/huin/goupnp/ssdp/ssdp.go b/vendor/github.com/huin/goupnp/ssdp/ssdp.go new file mode 100644 index 0000000..2f318f3 --- /dev/null +++ b/vendor/github.com/huin/goupnp/ssdp/ssdp.go @@ -0,0 +1,174 @@ +package ssdp + +import ( + "context" + "errors" + "log" + "net/http" + "net/url" + "strconv" + "time" +) + +const ( + ssdpDiscover = `"ssdp:discover"` + ntsAlive = `ssdp:alive` + ntsByebye = `ssdp:byebye` + ntsUpdate = `ssdp:update` + ssdpUDP4Addr = "239.255.255.250:1900" + ssdpSearchPort = 1900 + methodSearch = "M-SEARCH" + methodNotify = "NOTIFY" + + // SSDPAll is a value for searchTarget that searches for all devices and services. + SSDPAll = "ssdp:all" + // UPNPRootDevice is a value for searchTarget that searches for all root devices. + UPNPRootDevice = "upnp:rootdevice" +) + +// HTTPUClient is the interface required to perform HTTP-over-UDP requests. +type HTTPUClient interface { + Do( + req *http.Request, + timeout time.Duration, + numSends int, + ) ([]*http.Response, error) +} + +// HTTPUClientCtx is an optional interface that will be used to perform +// HTTP-over-UDP requests if the client implements it. +type HTTPUClientCtx interface { + DoWithContext( + req *http.Request, + numSends int, + ) ([]*http.Response, error) +} + +// SSDPRawSearchCtx performs a fairly raw SSDP search request, and returns the +// unique response(s) that it receives. Each response has the requested +// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to +// wait for responses in seconds, and must be a minimum of 1 (the +// implementation waits an additional 100ms for responses to arrive), 2 is a +// reasonable value for this. numSends is the number of requests to send - 3 is +// a reasonable value for this. +func SSDPRawSearchCtx( + ctx context.Context, + httpu HTTPUClient, + searchTarget string, + maxWaitSeconds int, + numSends int, +) ([]*http.Response, error) { + req, err := prepareRequest(ctx, searchTarget, maxWaitSeconds) + if err != nil { + return nil, err + } + + allResponses, err := httpu.Do(req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends) + if err != nil { + return nil, err + } + return processSSDPResponses(searchTarget, allResponses) +} + +// RawSearch performs a fairly raw SSDP search request, and returns the +// unique response(s) that it receives. Each response has the requested +// searchTarget, a USN, and a valid location. If the provided context times out +// or is canceled, the search will be aborted. numSends is the number of +// requests to send - 3 is a reasonable value for this. +// +// The provided context should have a deadline, since the SSDP protocol +// requires the max wait time be included in search requests. If the context +// has no deadline, then a default deadline of 3 seconds will be applied. +func RawSearch( + ctx context.Context, + httpu HTTPUClientCtx, + searchTarget string, + numSends int, +) ([]*http.Response, error) { + // We need a timeout value to include in the SSDP request; get it by + // checking the deadline on the context. + var maxWaitSeconds int + if deadline, ok := ctx.Deadline(); ok { + maxWaitSeconds = int(deadline.Sub(time.Now()) / time.Second) + } else { + // Pick a default timeout of 3 seconds if none was provided. + maxWaitSeconds = 3 + + var cancel func() + ctx, cancel = context.WithTimeout(ctx, time.Duration(maxWaitSeconds)*time.Second) + defer cancel() + } + + req, err := prepareRequest(ctx, searchTarget, maxWaitSeconds) + if err != nil { + return nil, err + } + + allResponses, err := httpu.DoWithContext(req, numSends) + if err != nil { + return nil, err + } + return processSSDPResponses(searchTarget, allResponses) +} + +// prepareRequest checks the provided parameters and constructs a SSDP search +// request to be sent. +func prepareRequest(ctx context.Context, searchTarget string, maxWaitSeconds int) (*http.Request, error) { + if maxWaitSeconds < 1 { + return nil, errors.New("ssdp: request timeout must be at least 1s") + } + + req := (&http.Request{ + Method: methodSearch, + // TODO: Support both IPv4 and IPv6. + Host: ssdpUDP4Addr, + URL: &url.URL{Opaque: "*"}, + Header: http.Header{ + // Putting headers in here avoids them being title-cased. + // (The UPnP discovery protocol uses case-sensitive headers) + "HOST": []string{ssdpUDP4Addr}, + "MX": []string{strconv.FormatInt(int64(maxWaitSeconds), 10)}, + "MAN": []string{ssdpDiscover}, + "ST": []string{searchTarget}, + }, + }).WithContext(ctx) + return req, nil +} + +func processSSDPResponses( + searchTarget string, + allResponses []*http.Response, +) ([]*http.Response, error) { + isExactSearch := searchTarget != SSDPAll && searchTarget != UPNPRootDevice + + seenIDs := make(map[string]bool) + var responses []*http.Response + for _, response := range allResponses { + if response.StatusCode != 200 { + log.Printf("ssdp: got response status code %q in search response", response.Status) + continue + } + if st := response.Header.Get("ST"); isExactSearch && st != searchTarget { + continue + } + usn := response.Header.Get("USN") + loc, err := response.Location() + if err != nil { + // No usable location in search response - discard. + continue + } + id := loc.String() + "\x00" + usn + if _, alreadySeen := seenIDs[id]; !alreadySeen { + seenIDs[id] = true + responses = append(responses, response) + } + } + + return responses, nil +} + +// SSDPRawSearch is the legacy version of SSDPRawSearchCtx, but uses +// context.Background() as the context. +func SSDPRawSearch(httpu HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) { + return SSDPRawSearchCtx(context.Background(), httpu, searchTarget, maxWaitSeconds, numSends) +} diff --git a/vendor/github.com/huin/goupnp/workspace.code-workspace b/vendor/github.com/huin/goupnp/workspace.code-workspace new file mode 100644 index 0000000..7d337ca --- /dev/null +++ b/vendor/github.com/huin/goupnp/workspace.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "v2alpha" + } + ], + "settings": {} +} diff --git a/vendor/github.com/illarion/gonotify/v3/.gitignore b/vendor/github.com/illarion/gonotify/v3/.gitignore deleted file mode 100644 index 9e06621..0000000 --- a/vendor/github.com/illarion/gonotify/v3/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out diff --git a/vendor/github.com/illarion/gonotify/v3/LICENSE b/vendor/github.com/illarion/gonotify/v3/LICENSE deleted file mode 100644 index 4bf9bb3..0000000 --- a/vendor/github.com/illarion/gonotify/v3/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018-2023 Ilarion Kovalchuk - -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/illarion/gonotify/v3/README.md b/vendor/github.com/illarion/gonotify/v3/README.md deleted file mode 100644 index 3281cf6..0000000 --- a/vendor/github.com/illarion/gonotify/v3/README.md +++ /dev/null @@ -1,71 +0,0 @@ -## Gonotify - -Simple Golang inotify wrapper. - -[![GoDoc](https://godoc.org/github.com/illarion/gonotify/v3?status.svg)](https://godoc.org/github.com/illarion/gonotify/v3) - -### Provides following primitives: - -* Low level - * `Inotify` - wrapper around [inotify(7)](http://man7.org/linux/man-pages/man7/inotify.7.html) - * `InotifyEvent` - generated file/folder event. Contains `Name` (full path), `Wd` - watch descriptor and `Mask` that describes the event. - -* Higher level - * `FileWatcher` - higher level utility, helps to watch the list of files for changes, creation or removal - * `DirWatcher` - higher level utility, recursively watches given root folder for added, removed or changed files. - * `FileEvent` - embeds `InotifyEvent` and keeps additional field `Eof` to notify user that there will be no more events. - -Use `FileWatcher` and `DirWatcher` as an example and build your own utility classes. - -### Usage - -```go -package main - -import ( - "fmt" - "github.com/illarion/gonotify/v3" - "time" - "context" -) - -func main() { - - ctx, cancel := context.WithCancel(context.Background()) - - watcher, err := gonotify.NewDirWatcher(ctx, gonotify.IN_CREATE|gonotify.IN_CLOSE, "/tmp") - if err != nil { - panic(err) - } - - main: - for { - select { - case event := <-watcher.C: - fmt.Printf("Event: %s\n", event) - - if event.Is(gonotify.IN_CREATE) { - fmt.Printf("File created: %s\n", event.Name) - } - - if event.IsAny(gonotify.IN_CLOSE, gonotify.IN_CLOSE_WRITE) { - fmt.Printf("File closed: %s\n", event.Name) - } - - case <-time.After(5 * time.Second): - fmt.Println("Good bye!") - cancel() - break main - } - } - - // Wait for watcher to finish all internal goroutines - <-watcher.Done() - fmt.Println("Watcher is done") - -} -``` - -## License -MIT. See [LICENSE](LICENSE) file for more details. - diff --git a/vendor/github.com/illarion/gonotify/v3/dirwatcher.go b/vendor/github.com/illarion/gonotify/v3/dirwatcher.go deleted file mode 100644 index 30236c9..0000000 --- a/vendor/github.com/illarion/gonotify/v3/dirwatcher.go +++ /dev/null @@ -1,218 +0,0 @@ -package gonotify - -import ( - "context" - "os" - "path/filepath" - "sync" -) - -// DirWatcher recursively watches the given root folder, waiting for file events. -// Events can be masked by providing fileMask. DirWatcher does not generate events for -// folders or subfolders. -type DirWatcher struct { - C chan FileEvent - done chan struct{} -} - -// NewDirWatcher creates DirWatcher recursively waiting for events in the given root folder and -// emitting FileEvents in channel C, that correspond to fileMask. Folder events are ignored (having IN_ISDIR set to 1) -func NewDirWatcher(ctx context.Context, fileMask uint32, root string) (*DirWatcher, error) { - dw := &DirWatcher{ - C: make(chan FileEvent), - done: make(chan struct{}), - } - - i, err := NewInotify(ctx) - if err != nil { - return nil, err - } - - queue := make([]FileEvent, 0, 100) - - err = filepath.Walk(root, func(path string, f os.FileInfo, err error) error { - - if err != nil { - return nil - } - - if !f.IsDir() { - - //fake event for existing files - queue = append(queue, FileEvent{ - InotifyEvent: InotifyEvent{ - Name: path, - Mask: IN_CREATE, - }, - }) - - return nil - } - _, err = i.AddWatch(path, IN_ALL_EVENTS) - return err - }) - - if err != nil { - return nil, err - } - - events := make(chan FileEvent) - - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - - for _, event := range queue { - select { - case <-ctx.Done(): - close(events) - return - case events <- event: - - } - } - queue = nil - - for { - - select { - case <-ctx.Done(): - close(events) - return - default: - } - - raw, err := i.Read() - if err != nil { - close(events) - return - } - - select { - case <-ctx.Done(): - close(events) - return - default: - } - - for _, event := range raw { - - // Skip ignored events queued from removed watchers - if event.Mask&IN_IGNORED == IN_IGNORED { - continue - } - - // Add watch for folders created in watched folders (recursion) - if event.Mask&(IN_CREATE|IN_ISDIR) == IN_CREATE|IN_ISDIR { - - // After the watch for subfolder is added, it may be already late to detect files - // created there right after subfolder creation, so we should generate such events - // ourselves: - filepath.Walk(event.Name, func(path string, f os.FileInfo, err error) error { - if err != nil { - return nil - } - - if !f.IsDir() { - // fake event, but there can be duplicates of this event provided by real watcher - select { - case <-ctx.Done(): - return nil - case events <- FileEvent{ - InotifyEvent: InotifyEvent{ - Name: path, - Mask: IN_CREATE, - }, - }: //noop - } - } - - return nil - }) - - // Wait for further files to be added - i.AddWatch(event.Name, IN_ALL_EVENTS) - - continue - } - - // Remove watch for deleted folders - if event.Mask&IN_DELETE_SELF == IN_DELETE_SELF { - i.RmWd(event.Wd) - continue - } - - // Skip sub-folder events - if event.Mask&IN_ISDIR == IN_ISDIR { - continue - } - - select { - case <-ctx.Done(): - return - case events <- FileEvent{ - InotifyEvent: event, - }: //noop - } - } - } - }() - - wg.Add(1) - go func() { - defer wg.Done() - defer close(dw.C) - - for { - select { - case <-ctx.Done(): - // drain events - for { - select { - case _, ok := <-events: - if !ok { - return - } - default: - return - } - } - case event, ok := <-events: - if !ok { - select { - case <-ctx.Done(): - case dw.C <- FileEvent{ - Eof: true, - }: - } - return - } - - // Skip events not conforming with provided mask - if event.Mask&fileMask == 0 { - continue - } - - select { - case dw.C <- event: - case <-ctx.Done(): - return - } - } - } - }() - - go func() { - wg.Wait() - <-i.Done() - close(dw.done) - }() - - return dw, nil -} - -// Done returns a channel that is closed when DirWatcher is done -func (dw *DirWatcher) Done() <-chan struct{} { - return dw.done -} diff --git a/vendor/github.com/illarion/gonotify/v3/event.go b/vendor/github.com/illarion/gonotify/v3/event.go deleted file mode 100644 index e1caef0..0000000 --- a/vendor/github.com/illarion/gonotify/v3/event.go +++ /dev/null @@ -1,138 +0,0 @@ -//go:build linux -// +build linux - -package gonotify - -import ( - "fmt" - "strings" - "syscall" -) - -const ( - IN_ACCESS = uint32(syscall.IN_ACCESS) // File was accessed - IN_ATTRIB = uint32(syscall.IN_ATTRIB) // Metadata changed - IN_CLOSE_WRITE = uint32(syscall.IN_CLOSE_WRITE) // File opened for writing was closed. - IN_CLOSE_NOWRITE = uint32(syscall.IN_CLOSE_NOWRITE) // File or directory not opened for writing was closed. - IN_CREATE = uint32(syscall.IN_CREATE) // File/directory created in watched directory - IN_DELETE = uint32(syscall.IN_DELETE) // File/directory deleted from watched directory. - IN_DELETE_SELF = uint32(syscall.IN_DELETE_SELF) // Watched file/directory was itself deleted. - IN_MODIFY = uint32(syscall.IN_MODIFY) // File was modified - IN_MOVE_SELF = uint32(syscall.IN_MOVE_SELF) // Watched file/directory was itself moved. - IN_MOVED_FROM = uint32(syscall.IN_MOVED_FROM) // Generated for the directory containing the old filename when a file is renamed. - IN_MOVED_TO = uint32(syscall.IN_MOVED_TO) // Generated for the directory containing the new filename when a file is renamed. - IN_OPEN = uint32(syscall.IN_OPEN) // File or directory was opened. - - IN_ALL_EVENTS = uint32(syscall.IN_ALL_EVENTS) // bit mask of all of the above events. - IN_MOVE = uint32(syscall.IN_MOVE) // Equates to IN_MOVED_FROM | IN_MOVED_TO. - IN_CLOSE = uint32(syscall.IN_CLOSE) // Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE. - - /* The following further bits can be specified in mask when calling Inotify.AddWatch() */ - - IN_DONT_FOLLOW = uint32(syscall.IN_DONT_FOLLOW) // Don't dereference pathname if it is a symbolic link. - IN_EXCL_UNLINK = uint32(syscall.IN_EXCL_UNLINK) // Don't generate events for children if they have been unlinked from the directory. - IN_MASK_ADD = uint32(syscall.IN_MASK_ADD) // Add (OR) the events in mask to the watch mask - IN_ONESHOT = uint32(syscall.IN_ONESHOT) // Monitor the filesystem object corresponding to pathname for one event, then remove from watch list. - IN_ONLYDIR = uint32(syscall.IN_ONLYDIR) // Watch pathname only if it is a directory. - - /* The following bits may be set in the mask field returned by Inotify.Read() */ - - IN_IGNORED = uint32(syscall.IN_IGNORED) // Watch was removed explicitly or automatically - IN_ISDIR = uint32(syscall.IN_ISDIR) // Subject of this event is a directory. - IN_Q_OVERFLOW = uint32(syscall.IN_Q_OVERFLOW) // Event queue overflowed (wd is -1 for this event). - - IN_UNMOUNT = uint32(syscall.IN_UNMOUNT) // Filesystem containing watched object was unmounted. -) - -var in_mapping = map[uint32]string{ - IN_ACCESS: "IN_ACCESS", - IN_ATTRIB: "IN_ATTRIB", - IN_CLOSE_WRITE: "IN_CLOSE_WRITE", - IN_CLOSE_NOWRITE: "IN_CLOSE_NOWRITE", - IN_CREATE: "IN_CREATE", - IN_DELETE: "IN_DELETE", - IN_DELETE_SELF: "IN_DELETE_SELF", - IN_MODIFY: "IN_MODIFY", - IN_MOVE_SELF: "IN_MOVE_SELF", - IN_MOVED_FROM: "IN_MOVED_FROM", - IN_MOVED_TO: "IN_MOVED_TO", - IN_OPEN: "IN_OPEN", - IN_IGNORED: "IN_IGNORED", - IN_ISDIR: "IN_ISDIR", - IN_Q_OVERFLOW: "IN_Q_OVERFLOW", - IN_UNMOUNT: "IN_UNMOUNT", -} - -func InMaskToString(in_mask uint32) string { - sb := &strings.Builder{} - divide := false - for mask, str := range in_mapping { - if in_mask&mask == mask { - if divide { - sb.WriteString("|") - } - sb.WriteString(str) - divide = true - } - } - return sb.String() -} - -// InotifyEvent is the go representation of inotify_event found in sys/inotify.h -type InotifyEvent struct { - // Watch descriptor - Wd int - // File or directory name - Name string - // Contains bits that describe the event that occurred - Mask uint32 - // Usually 0, but if events (like IN_MOVED_FROM and IN_MOVED_TO) are linked then they will have equal cookie - Cookie uint32 -} - -func (i InotifyEvent) GoString() string { - return fmt.Sprintf("gonotify.InotifyEvent{Wd=%#v, Name=%s, Cookie=%#v, Mask=%#v=%s}", i.Wd, i.Name, i.Cookie, i.Mask, InMaskToString(i.Mask)) -} - -func (i InotifyEvent) String() string { - return fmt.Sprintf("{Wd=%d, Name=%s, Cookie=%d, Mask=%s}", i.Wd, i.Name, i.Cookie, InMaskToString(i.Mask)) -} - -// IsAny returns true if any of the in_mask is set in the event -func (i InotifyEvent) IsAny(in_mask ...uint32) bool { - for _, mask := range in_mask { - if i.Mask&mask == mask { - return true - } - } - return false -} - -// IsAll returns true if all the in_masks is set in the event -func (i InotifyEvent) IsAll(in_mask ...uint32) bool { - for _, mask := range in_mask { - if i.Mask&mask != mask { - return false - } - } - return true -} - -func (i InotifyEvent) Is(in_mask uint32) bool { - return i.Mask&in_mask == in_mask -} - -// FileEvent is the wrapper around InotifyEvent with additional Eof marker. Reading from -// FileEvents from DirWatcher.C or FileWatcher.C may end with Eof when underlying inotify is closed -type FileEvent struct { - InotifyEvent - Eof bool -} - -func (f FileEvent) GoString() string { - return fmt.Sprintf("gonotify.FileEvent{InotifyEvent=%#v, Eof=%#v}", f.InotifyEvent, f.Eof) -} - -func (f FileEvent) String() string { - return fmt.Sprintf("{InotifyEvent=%s, Eof=%v}", f.InotifyEvent, f.Eof) -} diff --git a/vendor/github.com/illarion/gonotify/v3/filewatcher.go b/vendor/github.com/illarion/gonotify/v3/filewatcher.go deleted file mode 100644 index e3ff468..0000000 --- a/vendor/github.com/illarion/gonotify/v3/filewatcher.go +++ /dev/null @@ -1,115 +0,0 @@ -package gonotify - -import ( - "context" - "path/filepath" - "sync" -) - -// FileWatcher waits for events generated by filesystem for a specific list of file paths, including -// IN_CREATE for not yet existing files and IN_DELETE for removed. -type FileWatcher struct { - C chan FileEvent - done chan struct{} -} - -// NewFileWatcher creates FileWatcher with provided inotify mask and list of files to wait events for. -func NewFileWatcher(ctx context.Context, mask uint32, files ...string) (*FileWatcher, error) { - - f := &FileWatcher{ - C: make(chan FileEvent), - done: make(chan struct{}), - } - - inotify, err := NewInotify(ctx) - if err != nil { - return nil, err - } - - expectedPaths := make(map[string]bool) - - for _, file := range files { - _, err := inotify.AddWatch(filepath.Dir(file), mask) - if err != nil { - return nil, err - } - expectedPaths[file] = true - } - - events := make(chan FileEvent) - - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - for { - - select { - case <-ctx.Done(): - close(events) - return - default: - } - - raw, err := inotify.Read() - if err != nil { - close(events) - return - } - - for _, event := range raw { - select { - case <-ctx.Done(): - return - case events <- FileEvent{ - InotifyEvent: event, - }: //noop - } - } - } - }() - - wg.Add(1) - go func() { - defer wg.Done() - defer close(f.C) - for { - select { - case <-ctx.Done(): - return - case event, ok := <-events: - - if !ok { - select { - case <-ctx.Done(): - case f.C <- FileEvent{Eof: true}: - } - return - } - - if !expectedPaths[event.Name] { - continue - } - - select { - case <-ctx.Done(): - return - case f.C <- event: - } - } - } - }() - - go func() { - <-inotify.Done() - wg.Wait() - close(f.done) - }() - - return f, nil -} - -// Done returns a channel that is closed when the FileWatcher is done. -func (f *FileWatcher) Done() <-chan struct{} { - return f.done -} diff --git a/vendor/github.com/illarion/gonotify/v3/inotify.go b/vendor/github.com/illarion/gonotify/v3/inotify.go deleted file mode 100644 index 4ff8025..0000000 --- a/vendor/github.com/illarion/gonotify/v3/inotify.go +++ /dev/null @@ -1,527 +0,0 @@ -//go:build linux -// +build linux - -package gonotify - -import ( - "context" - "errors" - "os" - "path/filepath" - "strings" - "sync" - "syscall" - "time" - "unsafe" - - "github.com/illarion/gonotify/v3/syscallf" -) - -const ( - // maxEvents is the maximum number of events to read in one syscall - maxEvents = 1024 -) - -type addWatchResult struct { - wd int - err error -} - -type addWatchRequest struct { - pathName string - mask uint32 - result chan addWatchResult -} - -type rmWdRequest struct { - wd int - ignored bool // if true, the watch was removed automatically - result chan error -} - -type rmPathRequest struct { - pathName string - result chan error -} - -type eventItem struct { - InotifyEvent - err error -} - -// Inotify is the low level wrapper around inotify_init(), inotify_add_watch() and inotify_rm_watch() -type Inotify struct { - ctx context.Context - done chan struct{} - addWatchIn chan addWatchRequest - rmByWdIn chan rmWdRequest - rmByPathIn chan rmPathRequest - eventsOut chan eventItem - - readMutex sync.Mutex -} - -// NewInotify creates new inotify instance -func NewInotify(ctx context.Context) (*Inotify, error) { - fd, err := syscall.InotifyInit1(syscall.IN_CLOEXEC | syscall.IN_NONBLOCK) - if err != nil { - return nil, err - } - - file := os.NewFile(uintptr(fd), "inotify") - - inotify := &Inotify{ - ctx: ctx, - done: make(chan struct{}), - addWatchIn: make(chan addWatchRequest), - rmByWdIn: make(chan rmWdRequest), - rmByPathIn: make(chan rmPathRequest), - eventsOut: make(chan eventItem, maxEvents), - } - - type getPathRequest struct { - wd int - result chan string - } - - getPathIn := make(chan getPathRequest) - - wg := sync.WaitGroup{} - - wg.Add(1) - go func() { - //defer cancel() - <-ctx.Done() - //file.Close() - wg.Done() - }() - - wg.Add(1) - // read events goroutine. Only this goroutine can read or close the inotify file descriptor - go func() { - defer wg.Done() - defer close(inotify.eventsOut) - - // reusable buffers for reading inotify events. Make sure they're not - // leaked into other goroutines, as they're not thread safe - buf := make([]byte, maxEvents*(syscall.SizeofInotifyEvent+syscall.NAME_MAX+1)) - - for { - - select { - case <-ctx.Done(): - return - default: - } - - var n int - - for { - - select { - case <-ctx.Done(): - return - default: - } - - n, err = file.Read(buf) - if err != nil { - - // if we got an error, we should return - select { - case inotify.eventsOut <- eventItem{ - InotifyEvent: InotifyEvent{}, - err: err, - }: - default: - } - - return - } - - if n > 0 { - break - } - } - - if n < syscall.SizeofInotifyEvent { - select { - case <-ctx.Done(): - return - default: - continue - } - } - - offset := 0 - for offset+syscall.SizeofInotifyEvent <= n { - event := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) - var name string - { - nameStart := offset + syscall.SizeofInotifyEvent - nameEnd := offset + syscall.SizeofInotifyEvent + int(event.Len) - - if nameEnd > n { - continue - } - - name = strings.TrimRight(string(buf[nameStart:nameEnd]), "\x00") - offset = nameEnd - } - - req := getPathRequest{wd: int(event.Wd), result: make(chan string)} - var watchName string - - select { - case <-ctx.Done(): - return - case getPathIn <- req: - - select { - case <-ctx.Done(): - return - case watchName = <-req.result: - } - - } - - if watchName == "" { - continue - } - - name = filepath.Join(watchName, name) - - inotifyEvent := InotifyEvent{ - Wd: int(event.Wd), - Name: name, - Mask: event.Mask, - Cookie: event.Cookie, - } - - // watch was removed explicitly or automatically - if inotifyEvent.Is(IN_IGNORED) { - - // remove watch - - result := make(chan error) - - select { - case <-ctx.Done(): - return - case inotify.rmByWdIn <- rmWdRequest{ - wd: int(event.Wd), - ignored: true, - result: result, - }: - case <-time.After(1 * time.Second): - } - - select { - case <-ctx.Done(): - return - case err := <-result: - if err != nil { - // TODO log error - } - } - - continue - - } - - select { - case <-ctx.Done(): - return - case inotify.eventsOut <- eventItem{ - InotifyEvent: inotifyEvent, - err: nil, - }: - } - - } - - } - - }() - - wg.Add(1) - // main goroutine (handle channels) - go func() { - //defer cancel() - defer wg.Done() - - watches := make(map[string]int) - paths := make(map[int]string) - - for { - select { - case <-ctx.Done(): - - // Handle pending requests - draining := true - - for draining { - select { - case req := <-inotify.addWatchIn: - // Send error to addWatch requests - select { - case req.result <- addWatchResult{ - wd: 0, - err: errors.New("Inotify instance closed"), - }: - default: - } - case <-inotify.rmByWdIn: - case <-inotify.addWatchIn: - case <-inotify.rmByPathIn: - case <-getPathIn: - - default: - draining = false - } - } - - for _, w := range watches { - _, err := syscallf.InotifyRmWatch(fd, w) - if err != nil { - continue - } - } - - return - case req := <-inotify.addWatchIn: - wd, err := syscall.InotifyAddWatch(fd, req.pathName, req.mask) - if err == nil { - watches[req.pathName] = wd - paths[wd] = req.pathName - } - select { - case req.result <- addWatchResult{wd: wd, err: err}: - case <-ctx.Done(): - } - case req := <-inotify.rmByWdIn: - pathName, ok := paths[req.wd] - if !ok { - continue - } - - if !req.ignored { - _, err = syscallf.InotifyRmWatch(fd, req.wd) - } - - delete(watches, pathName) - delete(paths, req.wd) - - select { - case req.result <- err: - case <-ctx.Done(): - } - case req := <-inotify.rmByPathIn: - wd, ok := watches[req.pathName] - if !ok { - continue - } - _, err := syscallf.InotifyRmWatch(fd, wd) - - delete(watches, req.pathName) - delete(paths, wd) - - select { - case req.result <- err: - case <-ctx.Done(): - } - case req := <-getPathIn: - wd := paths[req.wd] - select { - case req.result <- wd: - case <-ctx.Done(): - } - } - } - }() - - go func() { - //defer cancel() - wg.Wait() - close(inotify.done) - }() - - return inotify, nil -} - -// Done returns a channel that is closed when Inotify is done -func (i *Inotify) Done() <-chan struct{} { - return i.done -} - -// AddWatch adds given path to list of watched files / folders -func (i *Inotify) AddWatch(pathName string, mask uint32) (int, error) { - - req := addWatchRequest{ - pathName: pathName, - mask: mask, - result: make(chan addWatchResult), - } - - select { - case <-i.ctx.Done(): - return 0, i.ctx.Err() - case i.addWatchIn <- req: - - select { - case <-i.ctx.Done(): - return 0, i.ctx.Err() - case result := <-req.result: - return result.wd, result.err - } - } -} - -// RmWd removes watch by watch descriptor -func (i *Inotify) RmWd(wd int) error { - - req := rmWdRequest{ - wd: wd, - ignored: false, - result: make(chan error), - } - - select { - case <-i.ctx.Done(): - return i.ctx.Err() - case i.rmByWdIn <- req: - } - - select { - case <-i.ctx.Done(): - return i.ctx.Err() - case err := <-req.result: - return err - } - -} - -// RmWatch removes watch by pathName -func (i *Inotify) RmWatch(pathName string) error { - - req := rmPathRequest{ - pathName: pathName, - result: make(chan error), - } - - select { - case <-i.ctx.Done(): - return i.ctx.Err() - case i.rmByPathIn <- req: - } - - select { - case <-i.ctx.Done(): - return i.ctx.Err() - case err := <-req.result: - return err - } -} - -// Read reads portion of InotifyEvents and may fail with an error. If no events are available, it will -// wait forever, until context is cancelled. -func (i *Inotify) Read() ([]InotifyEvent, error) { - i.readMutex.Lock() - defer i.readMutex.Unlock() - - events := make([]InotifyEvent, 0, maxEvents) - - select { - case <-i.ctx.Done(): - return events, i.ctx.Err() - case <-i.Done(): - return events, errors.New("inotify closed") - case evt, ok := <-i.eventsOut: - - if !ok { - return events, errors.New("inotify closed") - } - if evt.err != nil { - return events, evt.err - } - - if evt.InotifyEvent.Wd != 0 { - // append first event - events = append(events, evt.InotifyEvent) - } - - if len(events) >= maxEvents { - return events, nil - } - - // read all available events - read: - for { - - select { - case <-i.ctx.Done(): - return events, i.ctx.Err() - case <-i.Done(): - return events, errors.New("inotify closed") - case evt, ok := <-i.eventsOut: - if !ok { - return events, errors.New("inotify closed") - } - if evt.err != nil { - return events, evt.err - } - - if evt.InotifyEvent.Wd != 0 { - // append event - events = append(events, evt.InotifyEvent) - } - - if len(events) >= maxEvents { - return events, nil - } - - default: - break read - } - - } - - } - - return events, nil -} - -// ReadDeadline waits for InotifyEvents until deadline is reached, or context is cancelled. If -// deadline is reached, it will return all events read until that point. -func (i *Inotify) ReadDeadline(deadline time.Time) ([]InotifyEvent, error) { - i.readMutex.Lock() - defer i.readMutex.Unlock() - - events := make([]InotifyEvent, 0, maxEvents) - - for { - select { - case <-i.ctx.Done(): - return events, i.ctx.Err() - case <-i.Done(): - return events, errors.New("Inotify closed") - case <-time.After(time.Until(deadline)): - return events, nil - case evt, ok := <-i.eventsOut: - if !ok { - return events, errors.New("Inotify closed") - } - if evt.err != nil { - return events, evt.err - } - - events = append(events, evt.InotifyEvent) - - if len(events) >= maxEvents { - return events, nil - } - - } - } - -} diff --git a/vendor/github.com/illarion/gonotify/v3/syscallf/rm_watch.go b/vendor/github.com/illarion/gonotify/v3/syscallf/rm_watch.go deleted file mode 100644 index 9024fb3..0000000 --- a/vendor/github.com/illarion/gonotify/v3/syscallf/rm_watch.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build linux - -package syscallf - -import "syscall" - -func InotifyRmWatch(fd int, watchdesc int) (int, error) { - var success int - var err error - - r0, _, e1 := syscall.RawSyscall(syscall.SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) - success = int(r0) - if e1 != 0 { - err = e1 - } - return success, err -} diff --git a/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md b/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md deleted file mode 100644 index a43fa79..0000000 --- a/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md +++ /dev/null @@ -1,10 +0,0 @@ -## 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 deleted file mode 100644 index c43d60d..0000000 --- a/vendor/github.com/insomniacslk/dhcp/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index dbe8fbc..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/bindtointerface.go +++ /dev/null @@ -1,10 +0,0 @@ -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 deleted file mode 100644 index 4faec2c..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/defaults.go +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index 6043cd9..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go +++ /dev/null @@ -1,831 +0,0 @@ -// 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 == requested { - 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) -} - -// 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) -} - -// 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 deleted file mode 100644 index 68da298..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go +++ /dev/null @@ -1,171 +0,0 @@ -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)) -} - -// 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/option_generic.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_generic.go deleted file mode 100644 index a54cdeb..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_generic.go +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index c573631..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip.go +++ /dev/null @@ -1,62 +0,0 @@ -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_ip_address_lease_time.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip_address_lease_time.go deleted file mode 100644 index 0b5cd30..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip_address_lease_time.go +++ /dev/null @@ -1,41 +0,0 @@ -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)} -} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go deleted file mode 100644 index e0ee4cd..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go +++ /dev/null @@ -1,103 +0,0 @@ -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 deleted file mode 100644 index f283023..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_maximum_dhcp_message_size.go +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index 1f4c14f..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_message_type.go +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index e91b34d..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_misc.go +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 72b447c..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_parameter_request_list.go +++ /dev/null @@ -1,72 +0,0 @@ -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 deleted file mode 100644 index 4f974dd..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_relay_agent_information.go +++ /dev/null @@ -1,92 +0,0 @@ -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 { - 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("%s (%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 deleted file mode 100644 index 8516629..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_routes.go +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index eb0cc2b..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_string.go +++ /dev/null @@ -1,84 +0,0 @@ -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 deleted file mode 100644 index a29baa5..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_strings.go +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index a2f9f62..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_subnet_mask.go +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 3900bf0..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_vivc.go +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 9d404b4..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/options.go +++ /dev/null @@ -1,368 +0,0 @@ -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") - - // ErrInvalidOptions is returned when invalid options data is - // encountered during parsing. The data could report an incorrect - // length or have trailing bytes which are not part of the option. - ErrInvalidOptions = errors.New("invalid options data") -) - -// 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 - 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 - } - - // Any bytes left must be padding. - var pad uint8 - for buf.Len() >= 1 { - pad = buf.Read8() - if pad != optPad && pad != optEnd { - return ErrInvalidOptions - } - } - 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 - for k := range o { - codes = append(codes, int(k)) - } - - sort.Ints(codes) - 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: - var s String - d = &s - - case OptionRelayAgentInformation: - d = &RelayOptions{} - - case OptionDNSDomainSearchList: - d = &rfc1035label.Labels{} - - case OptionIPAddressLeaseTime: - 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 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 deleted file mode 100644 index 7dddefd..0000000 --- a/vendor/github.com/insomniacslk/dhcp/dhcpv4/types.go +++ /dev/null @@ -1,463 +0,0 @@ -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 - // 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", - // 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 deleted file mode 100644 index d85870c..0000000 --- a/vendor/github.com/insomniacslk/dhcp/iana/archtype.go +++ /dev/null @@ -1,148 +0,0 @@ -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 deleted file mode 100644 index 6aa318c..0000000 --- a/vendor/github.com/insomniacslk/dhcp/iana/entid.go +++ /dev/null @@ -1,25 +0,0 @@ -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 deleted file mode 100644 index e6fb38b..0000000 --- a/vendor/github.com/insomniacslk/dhcp/iana/hwtypes.go +++ /dev/null @@ -1,91 +0,0 @@ -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 deleted file mode 100644 index e0d5956..0000000 --- a/vendor/github.com/insomniacslk/dhcp/iana/iana.go +++ /dev/null @@ -1,2 +0,0 @@ -// 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 deleted file mode 100644 index ee45820..0000000 --- a/vendor/github.com/insomniacslk/dhcp/iana/statuscodes.go +++ /dev/null @@ -1,77 +0,0 @@ -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 deleted file mode 100644 index 7dbfd3f..0000000 --- a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_bsd.go +++ /dev/null @@ -1,19 +0,0 @@ -// +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 deleted file mode 100644 index 5ddfc0e..0000000 --- a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_darwin.go +++ /dev/null @@ -1,19 +0,0 @@ -// +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 deleted file mode 100644 index 52c7177..0000000 --- a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_linux.go +++ /dev/null @@ -1,9 +0,0 @@ -// +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 deleted file mode 100644 index 6de9b4d..0000000 --- a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index 5761669..0000000 --- a/vendor/github.com/insomniacslk/dhcp/interfaces/interfaces.go +++ /dev/null @@ -1,41 +0,0 @@ -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 deleted file mode 100644 index f727ec6..0000000 --- a/vendor/github.com/insomniacslk/dhcp/rfc1035label/label.go +++ /dev/null @@ -1,173 +0,0 @@ -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/jmespath/go-jmespath/.gitignore b/vendor/github.com/jmespath/go-jmespath/.gitignore deleted file mode 100644 index 5091fb0..0000000 --- a/vendor/github.com/jmespath/go-jmespath/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/jpgo -jmespath-fuzz.zip -cpu.out -go-jmespath.test diff --git a/vendor/github.com/jmespath/go-jmespath/.travis.yml b/vendor/github.com/jmespath/go-jmespath/.travis.yml deleted file mode 100644 index c56f37c..0000000 --- a/vendor/github.com/jmespath/go-jmespath/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: go - -sudo: false - -go: - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - 1.10.x - - 1.11.x - - 1.12.x - - 1.13.x - - 1.14.x - - 1.15.x - - tip - -allow_failures: - - go: tip - -script: make build - -matrix: - include: - - language: go - go: 1.15.x - script: make test diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE deleted file mode 100644 index b03310a..0000000 --- a/vendor/github.com/jmespath/go-jmespath/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2015 James Saryerwinnie - -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. diff --git a/vendor/github.com/jmespath/go-jmespath/Makefile b/vendor/github.com/jmespath/go-jmespath/Makefile deleted file mode 100644 index fb38ec2..0000000 --- a/vendor/github.com/jmespath/go-jmespath/Makefile +++ /dev/null @@ -1,51 +0,0 @@ - -CMD = jpgo - -SRC_PKGS=./ ./cmd/... ./fuzz/... - -help: - @echo "Please use \`make ' where is one of" - @echo " test to run all the tests" - @echo " build to build the library and jp executable" - @echo " generate to run codegen" - - -generate: - go generate ${SRC_PKGS} - -build: - rm -f $(CMD) - go build ${SRC_PKGS} - rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./... - mv cmd/$(CMD)/$(CMD) . - -test: test-internal-testify - echo "making tests ${SRC_PKGS}" - go test -v ${SRC_PKGS} - -check: - go vet ${SRC_PKGS} - @echo "golint ${SRC_PKGS}" - @lint=`golint ${SRC_PKGS}`; \ - lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \ - echo "$$lint"; \ - if [ "$$lint" != "" ]; then exit 1; fi - -htmlc: - go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov - -buildfuzz: - go-fuzz-build github.com/jmespath/go-jmespath/fuzz - -fuzz: buildfuzz - go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/testdata - -bench: - go test -bench . -cpuprofile cpu.out - -pprof-cpu: - go tool pprof ./go-jmespath.test ./cpu.out - -test-internal-testify: - cd internal/testify && go test ./... - diff --git a/vendor/github.com/jmespath/go-jmespath/README.md b/vendor/github.com/jmespath/go-jmespath/README.md deleted file mode 100644 index 110ad79..0000000 --- a/vendor/github.com/jmespath/go-jmespath/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# go-jmespath - A JMESPath implementation in Go - -[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath) - - - -go-jmespath is a GO implementation of JMESPath, -which is a query language for JSON. It will take a JSON -document and transform it into another JSON document -through a JMESPath expression. - -Using go-jmespath is really easy. There's a single function -you use, `jmespath.search`: - - -```go -> import "github.com/jmespath/go-jmespath" -> -> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data -> var data interface{} -> err := json.Unmarshal(jsondata, &data) -> result, err := jmespath.Search("foo.bar.baz[2]", data) -result = 2 -``` - -In the example we gave the ``search`` function input data of -`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}` as well as the JMESPath -expression `foo.bar.baz[2]`, and the `search` function evaluated -the expression against the input data to produce the result ``2``. - -The JMESPath language can do a lot more than select an element -from a list. Here are a few more examples: - -```go -> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data -> var data interface{} -> err := json.Unmarshal(jsondata, &data) -> result, err := jmespath.search("foo.bar", data) -result = { "baz": [ 0, 1, 2, 3, 4 ] } - - -> var jsondata = []byte(`{"foo": [{"first": "a", "last": "b"}, - {"first": "c", "last": "d"}]}`) // your data -> var data interface{} -> err := json.Unmarshal(jsondata, &data) -> result, err := jmespath.search({"foo[*].first", data) -result [ 'a', 'c' ] - - -> var jsondata = []byte(`{"foo": [{"age": 20}, {"age": 25}, - {"age": 30}, {"age": 35}, - {"age": 40}]}`) // your data -> var data interface{} -> err := json.Unmarshal(jsondata, &data) -> result, err := jmespath.search("foo[?age > `30`]") -result = [ { age: 35 }, { age: 40 } ] -``` - -You can also pre-compile your query. This is usefull if -you are going to run multiple searches with it: - -```go - > var jsondata = []byte(`{"foo": "bar"}`) - > var data interface{} - > err := json.Unmarshal(jsondata, &data) - > precompiled, err := Compile("foo") - > if err != nil{ - > // ... handle the error - > } - > result, err := precompiled.Search(data) - result = "bar" -``` - -## More Resources - -The example above only show a small amount of what -a JMESPath expression can do. If you want to take a -tour of the language, the *best* place to go is the -[JMESPath Tutorial](http://jmespath.org/tutorial.html). - -One of the best things about JMESPath is that it is -implemented in many different programming languages including -python, ruby, php, lua, etc. To see a complete list of libraries, -check out the [JMESPath libraries page](http://jmespath.org/libraries.html). - -And finally, the full JMESPath specification can be found -on the [JMESPath site](http://jmespath.org/specification.html). diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go deleted file mode 100644 index 010efe9..0000000 --- a/vendor/github.com/jmespath/go-jmespath/api.go +++ /dev/null @@ -1,49 +0,0 @@ -package jmespath - -import "strconv" - -// JMESPath is the representation of a compiled JMES path query. A JMESPath is -// safe for concurrent use by multiple goroutines. -type JMESPath struct { - ast ASTNode - intr *treeInterpreter -} - -// Compile parses a JMESPath expression and returns, if successful, a JMESPath -// object that can be used to match against data. -func Compile(expression string) (*JMESPath, error) { - parser := NewParser() - ast, err := parser.Parse(expression) - if err != nil { - return nil, err - } - jmespath := &JMESPath{ast: ast, intr: newInterpreter()} - return jmespath, nil -} - -// MustCompile is like Compile but panics if the expression cannot be parsed. -// It simplifies safe initialization of global variables holding compiled -// JMESPaths. -func MustCompile(expression string) *JMESPath { - jmespath, err := Compile(expression) - if err != nil { - panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error()) - } - return jmespath -} - -// Search evaluates a JMESPath expression against input data and returns the result. -func (jp *JMESPath) Search(data interface{}) (interface{}, error) { - return jp.intr.Execute(jp.ast, data) -} - -// Search evaluates a JMESPath expression against input data and returns the result. -func Search(expression string, data interface{}) (interface{}, error) { - intr := newInterpreter() - parser := NewParser() - ast, err := parser.Parse(expression) - if err != nil { - return nil, err - } - return intr.Execute(ast, data) -} diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go deleted file mode 100644 index 1cd2d23..0000000 --- a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// generated by stringer -type astNodeType; DO NOT EDIT - -package jmespath - -import "fmt" - -const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection" - -var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307} - -func (i astNodeType) String() string { - if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) { - return fmt.Sprintf("astNodeType(%d)", i) - } - return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]] -} diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go deleted file mode 100644 index 9b7cd89..0000000 --- a/vendor/github.com/jmespath/go-jmespath/functions.go +++ /dev/null @@ -1,842 +0,0 @@ -package jmespath - -import ( - "encoding/json" - "errors" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "unicode/utf8" -) - -type jpFunction func(arguments []interface{}) (interface{}, error) - -type jpType string - -const ( - jpUnknown jpType = "unknown" - jpNumber jpType = "number" - jpString jpType = "string" - jpArray jpType = "array" - jpObject jpType = "object" - jpArrayNumber jpType = "array[number]" - jpArrayString jpType = "array[string]" - jpExpref jpType = "expref" - jpAny jpType = "any" -) - -type functionEntry struct { - name string - arguments []argSpec - handler jpFunction - hasExpRef bool -} - -type argSpec struct { - types []jpType - variadic bool -} - -type byExprString struct { - intr *treeInterpreter - node ASTNode - items []interface{} - hasError bool -} - -func (a *byExprString) Len() int { - return len(a.items) -} -func (a *byExprString) Swap(i, j int) { - a.items[i], a.items[j] = a.items[j], a.items[i] -} -func (a *byExprString) Less(i, j int) bool { - first, err := a.intr.Execute(a.node, a.items[i]) - if err != nil { - a.hasError = true - // Return a dummy value. - return true - } - ith, ok := first.(string) - if !ok { - a.hasError = true - return true - } - second, err := a.intr.Execute(a.node, a.items[j]) - if err != nil { - a.hasError = true - // Return a dummy value. - return true - } - jth, ok := second.(string) - if !ok { - a.hasError = true - return true - } - return ith < jth -} - -type byExprFloat struct { - intr *treeInterpreter - node ASTNode - items []interface{} - hasError bool -} - -func (a *byExprFloat) Len() int { - return len(a.items) -} -func (a *byExprFloat) Swap(i, j int) { - a.items[i], a.items[j] = a.items[j], a.items[i] -} -func (a *byExprFloat) Less(i, j int) bool { - first, err := a.intr.Execute(a.node, a.items[i]) - if err != nil { - a.hasError = true - // Return a dummy value. - return true - } - ith, ok := first.(float64) - if !ok { - a.hasError = true - return true - } - second, err := a.intr.Execute(a.node, a.items[j]) - if err != nil { - a.hasError = true - // Return a dummy value. - return true - } - jth, ok := second.(float64) - if !ok { - a.hasError = true - return true - } - return ith < jth -} - -type functionCaller struct { - functionTable map[string]functionEntry -} - -func newFunctionCaller() *functionCaller { - caller := &functionCaller{} - caller.functionTable = map[string]functionEntry{ - "length": { - name: "length", - arguments: []argSpec{ - {types: []jpType{jpString, jpArray, jpObject}}, - }, - handler: jpfLength, - }, - "starts_with": { - name: "starts_with", - arguments: []argSpec{ - {types: []jpType{jpString}}, - {types: []jpType{jpString}}, - }, - handler: jpfStartsWith, - }, - "abs": { - name: "abs", - arguments: []argSpec{ - {types: []jpType{jpNumber}}, - }, - handler: jpfAbs, - }, - "avg": { - name: "avg", - arguments: []argSpec{ - {types: []jpType{jpArrayNumber}}, - }, - handler: jpfAvg, - }, - "ceil": { - name: "ceil", - arguments: []argSpec{ - {types: []jpType{jpNumber}}, - }, - handler: jpfCeil, - }, - "contains": { - name: "contains", - arguments: []argSpec{ - {types: []jpType{jpArray, jpString}}, - {types: []jpType{jpAny}}, - }, - handler: jpfContains, - }, - "ends_with": { - name: "ends_with", - arguments: []argSpec{ - {types: []jpType{jpString}}, - {types: []jpType{jpString}}, - }, - handler: jpfEndsWith, - }, - "floor": { - name: "floor", - arguments: []argSpec{ - {types: []jpType{jpNumber}}, - }, - handler: jpfFloor, - }, - "map": { - name: "amp", - arguments: []argSpec{ - {types: []jpType{jpExpref}}, - {types: []jpType{jpArray}}, - }, - handler: jpfMap, - hasExpRef: true, - }, - "max": { - name: "max", - arguments: []argSpec{ - {types: []jpType{jpArrayNumber, jpArrayString}}, - }, - handler: jpfMax, - }, - "merge": { - name: "merge", - arguments: []argSpec{ - {types: []jpType{jpObject}, variadic: true}, - }, - handler: jpfMerge, - }, - "max_by": { - name: "max_by", - arguments: []argSpec{ - {types: []jpType{jpArray}}, - {types: []jpType{jpExpref}}, - }, - handler: jpfMaxBy, - hasExpRef: true, - }, - "sum": { - name: "sum", - arguments: []argSpec{ - {types: []jpType{jpArrayNumber}}, - }, - handler: jpfSum, - }, - "min": { - name: "min", - arguments: []argSpec{ - {types: []jpType{jpArrayNumber, jpArrayString}}, - }, - handler: jpfMin, - }, - "min_by": { - name: "min_by", - arguments: []argSpec{ - {types: []jpType{jpArray}}, - {types: []jpType{jpExpref}}, - }, - handler: jpfMinBy, - hasExpRef: true, - }, - "type": { - name: "type", - arguments: []argSpec{ - {types: []jpType{jpAny}}, - }, - handler: jpfType, - }, - "keys": { - name: "keys", - arguments: []argSpec{ - {types: []jpType{jpObject}}, - }, - handler: jpfKeys, - }, - "values": { - name: "values", - arguments: []argSpec{ - {types: []jpType{jpObject}}, - }, - handler: jpfValues, - }, - "sort": { - name: "sort", - arguments: []argSpec{ - {types: []jpType{jpArrayString, jpArrayNumber}}, - }, - handler: jpfSort, - }, - "sort_by": { - name: "sort_by", - arguments: []argSpec{ - {types: []jpType{jpArray}}, - {types: []jpType{jpExpref}}, - }, - handler: jpfSortBy, - hasExpRef: true, - }, - "join": { - name: "join", - arguments: []argSpec{ - {types: []jpType{jpString}}, - {types: []jpType{jpArrayString}}, - }, - handler: jpfJoin, - }, - "reverse": { - name: "reverse", - arguments: []argSpec{ - {types: []jpType{jpArray, jpString}}, - }, - handler: jpfReverse, - }, - "to_array": { - name: "to_array", - arguments: []argSpec{ - {types: []jpType{jpAny}}, - }, - handler: jpfToArray, - }, - "to_string": { - name: "to_string", - arguments: []argSpec{ - {types: []jpType{jpAny}}, - }, - handler: jpfToString, - }, - "to_number": { - name: "to_number", - arguments: []argSpec{ - {types: []jpType{jpAny}}, - }, - handler: jpfToNumber, - }, - "not_null": { - name: "not_null", - arguments: []argSpec{ - {types: []jpType{jpAny}, variadic: true}, - }, - handler: jpfNotNull, - }, - } - return caller -} - -func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) { - if len(e.arguments) == 0 { - return arguments, nil - } - if !e.arguments[len(e.arguments)-1].variadic { - if len(e.arguments) != len(arguments) { - return nil, errors.New("incorrect number of args") - } - for i, spec := range e.arguments { - userArg := arguments[i] - err := spec.typeCheck(userArg) - if err != nil { - return nil, err - } - } - return arguments, nil - } - if len(arguments) < len(e.arguments) { - return nil, errors.New("Invalid arity.") - } - return arguments, nil -} - -func (a *argSpec) typeCheck(arg interface{}) error { - for _, t := range a.types { - switch t { - case jpNumber: - if _, ok := arg.(float64); ok { - return nil - } - case jpString: - if _, ok := arg.(string); ok { - return nil - } - case jpArray: - if isSliceType(arg) { - return nil - } - case jpObject: - if _, ok := arg.(map[string]interface{}); ok { - return nil - } - case jpArrayNumber: - if _, ok := toArrayNum(arg); ok { - return nil - } - case jpArrayString: - if _, ok := toArrayStr(arg); ok { - return nil - } - case jpAny: - return nil - case jpExpref: - if _, ok := arg.(expRef); ok { - return nil - } - } - } - return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types) -} - -func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) { - entry, ok := f.functionTable[name] - if !ok { - return nil, errors.New("unknown function: " + name) - } - resolvedArgs, err := entry.resolveArgs(arguments) - if err != nil { - return nil, err - } - if entry.hasExpRef { - var extra []interface{} - extra = append(extra, intr) - resolvedArgs = append(extra, resolvedArgs...) - } - return entry.handler(resolvedArgs) -} - -func jpfAbs(arguments []interface{}) (interface{}, error) { - num := arguments[0].(float64) - return math.Abs(num), nil -} - -func jpfLength(arguments []interface{}) (interface{}, error) { - arg := arguments[0] - if c, ok := arg.(string); ok { - return float64(utf8.RuneCountInString(c)), nil - } else if isSliceType(arg) { - v := reflect.ValueOf(arg) - return float64(v.Len()), nil - } else if c, ok := arg.(map[string]interface{}); ok { - return float64(len(c)), nil - } - return nil, errors.New("could not compute length()") -} - -func jpfStartsWith(arguments []interface{}) (interface{}, error) { - search := arguments[0].(string) - prefix := arguments[1].(string) - return strings.HasPrefix(search, prefix), nil -} - -func jpfAvg(arguments []interface{}) (interface{}, error) { - // We've already type checked the value so we can safely use - // type assertions. - args := arguments[0].([]interface{}) - length := float64(len(args)) - numerator := 0.0 - for _, n := range args { - numerator += n.(float64) - } - return numerator / length, nil -} -func jpfCeil(arguments []interface{}) (interface{}, error) { - val := arguments[0].(float64) - return math.Ceil(val), nil -} -func jpfContains(arguments []interface{}) (interface{}, error) { - search := arguments[0] - el := arguments[1] - if searchStr, ok := search.(string); ok { - if elStr, ok := el.(string); ok { - return strings.Index(searchStr, elStr) != -1, nil - } - return false, nil - } - // Otherwise this is a generic contains for []interface{} - general := search.([]interface{}) - for _, item := range general { - if item == el { - return true, nil - } - } - return false, nil -} -func jpfEndsWith(arguments []interface{}) (interface{}, error) { - search := arguments[0].(string) - suffix := arguments[1].(string) - return strings.HasSuffix(search, suffix), nil -} -func jpfFloor(arguments []interface{}) (interface{}, error) { - val := arguments[0].(float64) - return math.Floor(val), nil -} -func jpfMap(arguments []interface{}) (interface{}, error) { - intr := arguments[0].(*treeInterpreter) - exp := arguments[1].(expRef) - node := exp.ref - arr := arguments[2].([]interface{}) - mapped := make([]interface{}, 0, len(arr)) - for _, value := range arr { - current, err := intr.Execute(node, value) - if err != nil { - return nil, err - } - mapped = append(mapped, current) - } - return mapped, nil -} -func jpfMax(arguments []interface{}) (interface{}, error) { - if items, ok := toArrayNum(arguments[0]); ok { - if len(items) == 0 { - return nil, nil - } - if len(items) == 1 { - return items[0], nil - } - best := items[0] - for _, item := range items[1:] { - if item > best { - best = item - } - } - return best, nil - } - // Otherwise we're dealing with a max() of strings. - items, _ := toArrayStr(arguments[0]) - if len(items) == 0 { - return nil, nil - } - if len(items) == 1 { - return items[0], nil - } - best := items[0] - for _, item := range items[1:] { - if item > best { - best = item - } - } - return best, nil -} -func jpfMerge(arguments []interface{}) (interface{}, error) { - final := make(map[string]interface{}) - for _, m := range arguments { - mapped := m.(map[string]interface{}) - for key, value := range mapped { - final[key] = value - } - } - return final, nil -} -func jpfMaxBy(arguments []interface{}) (interface{}, error) { - intr := arguments[0].(*treeInterpreter) - arr := arguments[1].([]interface{}) - exp := arguments[2].(expRef) - node := exp.ref - if len(arr) == 0 { - return nil, nil - } else if len(arr) == 1 { - return arr[0], nil - } - start, err := intr.Execute(node, arr[0]) - if err != nil { - return nil, err - } - switch t := start.(type) { - case float64: - bestVal := t - bestItem := arr[0] - for _, item := range arr[1:] { - result, err := intr.Execute(node, item) - if err != nil { - return nil, err - } - current, ok := result.(float64) - if !ok { - return nil, errors.New("invalid type, must be number") - } - if current > bestVal { - bestVal = current - bestItem = item - } - } - return bestItem, nil - case string: - bestVal := t - bestItem := arr[0] - for _, item := range arr[1:] { - result, err := intr.Execute(node, item) - if err != nil { - return nil, err - } - current, ok := result.(string) - if !ok { - return nil, errors.New("invalid type, must be string") - } - if current > bestVal { - bestVal = current - bestItem = item - } - } - return bestItem, nil - default: - return nil, errors.New("invalid type, must be number of string") - } -} -func jpfSum(arguments []interface{}) (interface{}, error) { - items, _ := toArrayNum(arguments[0]) - sum := 0.0 - for _, item := range items { - sum += item - } - return sum, nil -} - -func jpfMin(arguments []interface{}) (interface{}, error) { - if items, ok := toArrayNum(arguments[0]); ok { - if len(items) == 0 { - return nil, nil - } - if len(items) == 1 { - return items[0], nil - } - best := items[0] - for _, item := range items[1:] { - if item < best { - best = item - } - } - return best, nil - } - items, _ := toArrayStr(arguments[0]) - if len(items) == 0 { - return nil, nil - } - if len(items) == 1 { - return items[0], nil - } - best := items[0] - for _, item := range items[1:] { - if item < best { - best = item - } - } - return best, nil -} - -func jpfMinBy(arguments []interface{}) (interface{}, error) { - intr := arguments[0].(*treeInterpreter) - arr := arguments[1].([]interface{}) - exp := arguments[2].(expRef) - node := exp.ref - if len(arr) == 0 { - return nil, nil - } else if len(arr) == 1 { - return arr[0], nil - } - start, err := intr.Execute(node, arr[0]) - if err != nil { - return nil, err - } - if t, ok := start.(float64); ok { - bestVal := t - bestItem := arr[0] - for _, item := range arr[1:] { - result, err := intr.Execute(node, item) - if err != nil { - return nil, err - } - current, ok := result.(float64) - if !ok { - return nil, errors.New("invalid type, must be number") - } - if current < bestVal { - bestVal = current - bestItem = item - } - } - return bestItem, nil - } else if t, ok := start.(string); ok { - bestVal := t - bestItem := arr[0] - for _, item := range arr[1:] { - result, err := intr.Execute(node, item) - if err != nil { - return nil, err - } - current, ok := result.(string) - if !ok { - return nil, errors.New("invalid type, must be string") - } - if current < bestVal { - bestVal = current - bestItem = item - } - } - return bestItem, nil - } else { - return nil, errors.New("invalid type, must be number of string") - } -} -func jpfType(arguments []interface{}) (interface{}, error) { - arg := arguments[0] - if _, ok := arg.(float64); ok { - return "number", nil - } - if _, ok := arg.(string); ok { - return "string", nil - } - if _, ok := arg.([]interface{}); ok { - return "array", nil - } - if _, ok := arg.(map[string]interface{}); ok { - return "object", nil - } - if arg == nil { - return "null", nil - } - if arg == true || arg == false { - return "boolean", nil - } - return nil, errors.New("unknown type") -} -func jpfKeys(arguments []interface{}) (interface{}, error) { - arg := arguments[0].(map[string]interface{}) - collected := make([]interface{}, 0, len(arg)) - for key := range arg { - collected = append(collected, key) - } - return collected, nil -} -func jpfValues(arguments []interface{}) (interface{}, error) { - arg := arguments[0].(map[string]interface{}) - collected := make([]interface{}, 0, len(arg)) - for _, value := range arg { - collected = append(collected, value) - } - return collected, nil -} -func jpfSort(arguments []interface{}) (interface{}, error) { - if items, ok := toArrayNum(arguments[0]); ok { - d := sort.Float64Slice(items) - sort.Stable(d) - final := make([]interface{}, len(d)) - for i, val := range d { - final[i] = val - } - return final, nil - } - // Otherwise we're dealing with sort()'ing strings. - items, _ := toArrayStr(arguments[0]) - d := sort.StringSlice(items) - sort.Stable(d) - final := make([]interface{}, len(d)) - for i, val := range d { - final[i] = val - } - return final, nil -} -func jpfSortBy(arguments []interface{}) (interface{}, error) { - intr := arguments[0].(*treeInterpreter) - arr := arguments[1].([]interface{}) - exp := arguments[2].(expRef) - node := exp.ref - if len(arr) == 0 { - return arr, nil - } else if len(arr) == 1 { - return arr, nil - } - start, err := intr.Execute(node, arr[0]) - if err != nil { - return nil, err - } - if _, ok := start.(float64); ok { - sortable := &byExprFloat{intr, node, arr, false} - sort.Stable(sortable) - if sortable.hasError { - return nil, errors.New("error in sort_by comparison") - } - return arr, nil - } else if _, ok := start.(string); ok { - sortable := &byExprString{intr, node, arr, false} - sort.Stable(sortable) - if sortable.hasError { - return nil, errors.New("error in sort_by comparison") - } - return arr, nil - } else { - return nil, errors.New("invalid type, must be number of string") - } -} -func jpfJoin(arguments []interface{}) (interface{}, error) { - sep := arguments[0].(string) - // We can't just do arguments[1].([]string), we have to - // manually convert each item to a string. - arrayStr := []string{} - for _, item := range arguments[1].([]interface{}) { - arrayStr = append(arrayStr, item.(string)) - } - return strings.Join(arrayStr, sep), nil -} -func jpfReverse(arguments []interface{}) (interface{}, error) { - if s, ok := arguments[0].(string); ok { - r := []rune(s) - for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { - r[i], r[j] = r[j], r[i] - } - return string(r), nil - } - items := arguments[0].([]interface{}) - length := len(items) - reversed := make([]interface{}, length) - for i, item := range items { - reversed[length-(i+1)] = item - } - return reversed, nil -} -func jpfToArray(arguments []interface{}) (interface{}, error) { - if _, ok := arguments[0].([]interface{}); ok { - return arguments[0], nil - } - return arguments[:1:1], nil -} -func jpfToString(arguments []interface{}) (interface{}, error) { - if v, ok := arguments[0].(string); ok { - return v, nil - } - result, err := json.Marshal(arguments[0]) - if err != nil { - return nil, err - } - return string(result), nil -} -func jpfToNumber(arguments []interface{}) (interface{}, error) { - arg := arguments[0] - if v, ok := arg.(float64); ok { - return v, nil - } - if v, ok := arg.(string); ok { - conv, err := strconv.ParseFloat(v, 64) - if err != nil { - return nil, nil - } - return conv, nil - } - if _, ok := arg.([]interface{}); ok { - return nil, nil - } - if _, ok := arg.(map[string]interface{}); ok { - return nil, nil - } - if arg == nil { - return nil, nil - } - if arg == true || arg == false { - return nil, nil - } - return nil, errors.New("unknown type") -} -func jpfNotNull(arguments []interface{}) (interface{}, error) { - for _, arg := range arguments { - if arg != nil { - return arg, nil - } - } - return nil, nil -} diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go deleted file mode 100644 index 13c7460..0000000 --- a/vendor/github.com/jmespath/go-jmespath/interpreter.go +++ /dev/null @@ -1,418 +0,0 @@ -package jmespath - -import ( - "errors" - "reflect" - "unicode" - "unicode/utf8" -) - -/* This is a tree based interpreter. It walks the AST and directly - interprets the AST to search through a JSON document. -*/ - -type treeInterpreter struct { - fCall *functionCaller -} - -func newInterpreter() *treeInterpreter { - interpreter := treeInterpreter{} - interpreter.fCall = newFunctionCaller() - return &interpreter -} - -type expRef struct { - ref ASTNode -} - -// Execute takes an ASTNode and input data and interprets the AST directly. -// It will produce the result of applying the JMESPath expression associated -// with the ASTNode to the input data "value". -func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) { - switch node.nodeType { - case ASTComparator: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - right, err := intr.Execute(node.children[1], value) - if err != nil { - return nil, err - } - switch node.value { - case tEQ: - return objsEqual(left, right), nil - case tNE: - return !objsEqual(left, right), nil - } - leftNum, ok := left.(float64) - if !ok { - return nil, nil - } - rightNum, ok := right.(float64) - if !ok { - return nil, nil - } - switch node.value { - case tGT: - return leftNum > rightNum, nil - case tGTE: - return leftNum >= rightNum, nil - case tLT: - return leftNum < rightNum, nil - case tLTE: - return leftNum <= rightNum, nil - } - case ASTExpRef: - return expRef{ref: node.children[0]}, nil - case ASTFunctionExpression: - resolvedArgs := []interface{}{} - for _, arg := range node.children { - current, err := intr.Execute(arg, value) - if err != nil { - return nil, err - } - resolvedArgs = append(resolvedArgs, current) - } - return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr) - case ASTField: - if m, ok := value.(map[string]interface{}); ok { - key := node.value.(string) - return m[key], nil - } - return intr.fieldFromStruct(node.value.(string), value) - case ASTFilterProjection: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, nil - } - sliceType, ok := left.([]interface{}) - if !ok { - if isSliceType(left) { - return intr.filterProjectionWithReflection(node, left) - } - return nil, nil - } - compareNode := node.children[2] - collected := []interface{}{} - for _, element := range sliceType { - result, err := intr.Execute(compareNode, element) - if err != nil { - return nil, err - } - if !isFalse(result) { - current, err := intr.Execute(node.children[1], element) - if err != nil { - return nil, err - } - if current != nil { - collected = append(collected, current) - } - } - } - return collected, nil - case ASTFlatten: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, nil - } - sliceType, ok := left.([]interface{}) - if !ok { - // If we can't type convert to []interface{}, there's - // a chance this could still work via reflection if we're - // dealing with user provided types. - if isSliceType(left) { - return intr.flattenWithReflection(left) - } - return nil, nil - } - flattened := []interface{}{} - for _, element := range sliceType { - if elementSlice, ok := element.([]interface{}); ok { - flattened = append(flattened, elementSlice...) - } else if isSliceType(element) { - reflectFlat := []interface{}{} - v := reflect.ValueOf(element) - for i := 0; i < v.Len(); i++ { - reflectFlat = append(reflectFlat, v.Index(i).Interface()) - } - flattened = append(flattened, reflectFlat...) - } else { - flattened = append(flattened, element) - } - } - return flattened, nil - case ASTIdentity, ASTCurrentNode: - return value, nil - case ASTIndex: - if sliceType, ok := value.([]interface{}); ok { - index := node.value.(int) - if index < 0 { - index += len(sliceType) - } - if index < len(sliceType) && index >= 0 { - return sliceType[index], nil - } - return nil, nil - } - // Otherwise try via reflection. - rv := reflect.ValueOf(value) - if rv.Kind() == reflect.Slice { - index := node.value.(int) - if index < 0 { - index += rv.Len() - } - if index < rv.Len() && index >= 0 { - v := rv.Index(index) - return v.Interface(), nil - } - } - return nil, nil - case ASTKeyValPair: - return intr.Execute(node.children[0], value) - case ASTLiteral: - return node.value, nil - case ASTMultiSelectHash: - if value == nil { - return nil, nil - } - collected := make(map[string]interface{}) - for _, child := range node.children { - current, err := intr.Execute(child, value) - if err != nil { - return nil, err - } - key := child.value.(string) - collected[key] = current - } - return collected, nil - case ASTMultiSelectList: - if value == nil { - return nil, nil - } - collected := []interface{}{} - for _, child := range node.children { - current, err := intr.Execute(child, value) - if err != nil { - return nil, err - } - collected = append(collected, current) - } - return collected, nil - case ASTOrExpression: - matched, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - if isFalse(matched) { - matched, err = intr.Execute(node.children[1], value) - if err != nil { - return nil, err - } - } - return matched, nil - case ASTAndExpression: - matched, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - if isFalse(matched) { - return matched, nil - } - return intr.Execute(node.children[1], value) - case ASTNotExpression: - matched, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - if isFalse(matched) { - return true, nil - } - return false, nil - case ASTPipe: - result := value - var err error - for _, child := range node.children { - result, err = intr.Execute(child, result) - if err != nil { - return nil, err - } - } - return result, nil - case ASTProjection: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - sliceType, ok := left.([]interface{}) - if !ok { - if isSliceType(left) { - return intr.projectWithReflection(node, left) - } - return nil, nil - } - collected := []interface{}{} - var current interface{} - for _, element := range sliceType { - current, err = intr.Execute(node.children[1], element) - if err != nil { - return nil, err - } - if current != nil { - collected = append(collected, current) - } - } - return collected, nil - case ASTSubexpression, ASTIndexExpression: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, err - } - return intr.Execute(node.children[1], left) - case ASTSlice: - sliceType, ok := value.([]interface{}) - if !ok { - if isSliceType(value) { - return intr.sliceWithReflection(node, value) - } - return nil, nil - } - parts := node.value.([]*int) - sliceParams := make([]sliceParam, 3) - for i, part := range parts { - if part != nil { - sliceParams[i].Specified = true - sliceParams[i].N = *part - } - } - return slice(sliceType, sliceParams) - case ASTValueProjection: - left, err := intr.Execute(node.children[0], value) - if err != nil { - return nil, nil - } - mapType, ok := left.(map[string]interface{}) - if !ok { - return nil, nil - } - values := make([]interface{}, len(mapType)) - for _, value := range mapType { - values = append(values, value) - } - collected := []interface{}{} - for _, element := range values { - current, err := intr.Execute(node.children[1], element) - if err != nil { - return nil, err - } - if current != nil { - collected = append(collected, current) - } - } - return collected, nil - } - return nil, errors.New("Unknown AST node: " + node.nodeType.String()) -} - -func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) { - rv := reflect.ValueOf(value) - first, n := utf8.DecodeRuneInString(key) - fieldName := string(unicode.ToUpper(first)) + key[n:] - if rv.Kind() == reflect.Struct { - v := rv.FieldByName(fieldName) - if !v.IsValid() { - return nil, nil - } - return v.Interface(), nil - } else if rv.Kind() == reflect.Ptr { - // Handle multiple levels of indirection? - if rv.IsNil() { - return nil, nil - } - rv = rv.Elem() - v := rv.FieldByName(fieldName) - if !v.IsValid() { - return nil, nil - } - return v.Interface(), nil - } - return nil, nil -} - -func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) { - v := reflect.ValueOf(value) - flattened := []interface{}{} - for i := 0; i < v.Len(); i++ { - element := v.Index(i).Interface() - if reflect.TypeOf(element).Kind() == reflect.Slice { - // Then insert the contents of the element - // slice into the flattened slice, - // i.e flattened = append(flattened, mySlice...) - elementV := reflect.ValueOf(element) - for j := 0; j < elementV.Len(); j++ { - flattened = append( - flattened, elementV.Index(j).Interface()) - } - } else { - flattened = append(flattened, element) - } - } - return flattened, nil -} - -func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) { - v := reflect.ValueOf(value) - parts := node.value.([]*int) - sliceParams := make([]sliceParam, 3) - for i, part := range parts { - if part != nil { - sliceParams[i].Specified = true - sliceParams[i].N = *part - } - } - final := []interface{}{} - for i := 0; i < v.Len(); i++ { - element := v.Index(i).Interface() - final = append(final, element) - } - return slice(final, sliceParams) -} - -func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) { - compareNode := node.children[2] - collected := []interface{}{} - v := reflect.ValueOf(value) - for i := 0; i < v.Len(); i++ { - element := v.Index(i).Interface() - result, err := intr.Execute(compareNode, element) - if err != nil { - return nil, err - } - if !isFalse(result) { - current, err := intr.Execute(node.children[1], element) - if err != nil { - return nil, err - } - if current != nil { - collected = append(collected, current) - } - } - } - return collected, nil -} - -func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) { - collected := []interface{}{} - v := reflect.ValueOf(value) - for i := 0; i < v.Len(); i++ { - element := v.Index(i).Interface() - result, err := intr.Execute(node.children[1], element) - if err != nil { - return nil, err - } - if result != nil { - collected = append(collected, result) - } - } - return collected, nil -} diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go deleted file mode 100644 index 817900c..0000000 --- a/vendor/github.com/jmespath/go-jmespath/lexer.go +++ /dev/null @@ -1,420 +0,0 @@ -package jmespath - -import ( - "bytes" - "encoding/json" - "fmt" - "strconv" - "strings" - "unicode/utf8" -) - -type token struct { - tokenType tokType - value string - position int - length int -} - -type tokType int - -const eof = -1 - -// Lexer contains information about the expression being tokenized. -type Lexer struct { - expression string // The expression provided by the user. - currentPos int // The current position in the string. - lastWidth int // The width of the current rune. This - buf bytes.Buffer // Internal buffer used for building up values. -} - -// SyntaxError is the main error used whenever a lexing or parsing error occurs. -type SyntaxError struct { - msg string // Error message displayed to user - Expression string // Expression that generated a SyntaxError - Offset int // The location in the string where the error occurred -} - -func (e SyntaxError) Error() string { - // In the future, it would be good to underline the specific - // location where the error occurred. - return "SyntaxError: " + e.msg -} - -// HighlightLocation will show where the syntax error occurred. -// It will place a "^" character on a line below the expression -// at the point where the syntax error occurred. -func (e SyntaxError) HighlightLocation() string { - return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^" -} - -//go:generate stringer -type=tokType -const ( - tUnknown tokType = iota - tStar - tDot - tFilter - tFlatten - tLparen - tRparen - tLbracket - tRbracket - tLbrace - tRbrace - tOr - tPipe - tNumber - tUnquotedIdentifier - tQuotedIdentifier - tComma - tColon - tLT - tLTE - tGT - tGTE - tEQ - tNE - tJSONLiteral - tStringLiteral - tCurrent - tExpref - tAnd - tNot - tEOF -) - -var basicTokens = map[rune]tokType{ - '.': tDot, - '*': tStar, - ',': tComma, - ':': tColon, - '{': tLbrace, - '}': tRbrace, - ']': tRbracket, // tLbracket not included because it could be "[]" - '(': tLparen, - ')': tRparen, - '@': tCurrent, -} - -// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64. -// When using this bitmask just be sure to shift the rune down 64 bits -// before checking against identifierStartBits. -const identifierStartBits uint64 = 576460745995190270 - -// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s. -var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270} - -var whiteSpace = map[rune]bool{ - ' ': true, '\t': true, '\n': true, '\r': true, -} - -func (t token) String() string { - return fmt.Sprintf("Token{%+v, %s, %d, %d}", - t.tokenType, t.value, t.position, t.length) -} - -// NewLexer creates a new JMESPath lexer. -func NewLexer() *Lexer { - lexer := Lexer{} - return &lexer -} - -func (lexer *Lexer) next() rune { - if lexer.currentPos >= len(lexer.expression) { - lexer.lastWidth = 0 - return eof - } - r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:]) - lexer.lastWidth = w - lexer.currentPos += w - return r -} - -func (lexer *Lexer) back() { - lexer.currentPos -= lexer.lastWidth -} - -func (lexer *Lexer) peek() rune { - t := lexer.next() - lexer.back() - return t -} - -// tokenize takes an expression and returns corresponding tokens. -func (lexer *Lexer) tokenize(expression string) ([]token, error) { - var tokens []token - lexer.expression = expression - lexer.currentPos = 0 - lexer.lastWidth = 0 -loop: - for { - r := lexer.next() - if identifierStartBits&(1<<(uint64(r)-64)) > 0 { - t := lexer.consumeUnquotedIdentifier() - tokens = append(tokens, t) - } else if val, ok := basicTokens[r]; ok { - // Basic single char token. - t := token{ - tokenType: val, - value: string(r), - position: lexer.currentPos - lexer.lastWidth, - length: 1, - } - tokens = append(tokens, t) - } else if r == '-' || (r >= '0' && r <= '9') { - t := lexer.consumeNumber() - tokens = append(tokens, t) - } else if r == '[' { - t := lexer.consumeLBracket() - tokens = append(tokens, t) - } else if r == '"' { - t, err := lexer.consumeQuotedIdentifier() - if err != nil { - return tokens, err - } - tokens = append(tokens, t) - } else if r == '\'' { - t, err := lexer.consumeRawStringLiteral() - if err != nil { - return tokens, err - } - tokens = append(tokens, t) - } else if r == '`' { - t, err := lexer.consumeLiteral() - if err != nil { - return tokens, err - } - tokens = append(tokens, t) - } else if r == '|' { - t := lexer.matchOrElse(r, '|', tOr, tPipe) - tokens = append(tokens, t) - } else if r == '<' { - t := lexer.matchOrElse(r, '=', tLTE, tLT) - tokens = append(tokens, t) - } else if r == '>' { - t := lexer.matchOrElse(r, '=', tGTE, tGT) - tokens = append(tokens, t) - } else if r == '!' { - t := lexer.matchOrElse(r, '=', tNE, tNot) - tokens = append(tokens, t) - } else if r == '=' { - t := lexer.matchOrElse(r, '=', tEQ, tUnknown) - tokens = append(tokens, t) - } else if r == '&' { - t := lexer.matchOrElse(r, '&', tAnd, tExpref) - tokens = append(tokens, t) - } else if r == eof { - break loop - } else if _, ok := whiteSpace[r]; ok { - // Ignore whitespace - } else { - return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r))) - } - } - tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0}) - return tokens, nil -} - -// Consume characters until the ending rune "r" is reached. -// If the end of the expression is reached before seeing the -// terminating rune "r", then an error is returned. -// If no error occurs then the matching substring is returned. -// The returned string will not include the ending rune. -func (lexer *Lexer) consumeUntil(end rune) (string, error) { - start := lexer.currentPos - current := lexer.next() - for current != end && current != eof { - if current == '\\' && lexer.peek() != eof { - lexer.next() - } - current = lexer.next() - } - if lexer.lastWidth == 0 { - // Then we hit an EOF so we never reached the closing - // delimiter. - return "", SyntaxError{ - msg: "Unclosed delimiter: " + string(end), - Expression: lexer.expression, - Offset: len(lexer.expression), - } - } - return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil -} - -func (lexer *Lexer) consumeLiteral() (token, error) { - start := lexer.currentPos - value, err := lexer.consumeUntil('`') - if err != nil { - return token{}, err - } - value = strings.Replace(value, "\\`", "`", -1) - return token{ - tokenType: tJSONLiteral, - value: value, - position: start, - length: len(value), - }, nil -} - -func (lexer *Lexer) consumeRawStringLiteral() (token, error) { - start := lexer.currentPos - currentIndex := start - current := lexer.next() - for current != '\'' && lexer.peek() != eof { - if current == '\\' && lexer.peek() == '\'' { - chunk := lexer.expression[currentIndex : lexer.currentPos-1] - lexer.buf.WriteString(chunk) - lexer.buf.WriteString("'") - lexer.next() - currentIndex = lexer.currentPos - } - current = lexer.next() - } - if lexer.lastWidth == 0 { - // Then we hit an EOF so we never reached the closing - // delimiter. - return token{}, SyntaxError{ - msg: "Unclosed delimiter: '", - Expression: lexer.expression, - Offset: len(lexer.expression), - } - } - if currentIndex < lexer.currentPos { - lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1]) - } - value := lexer.buf.String() - // Reset the buffer so it can reused again. - lexer.buf.Reset() - return token{ - tokenType: tStringLiteral, - value: value, - position: start, - length: len(value), - }, nil -} - -func (lexer *Lexer) syntaxError(msg string) SyntaxError { - return SyntaxError{ - msg: msg, - Expression: lexer.expression, - Offset: lexer.currentPos - 1, - } -} - -// Checks for a two char token, otherwise matches a single character -// token. This is used whenever a two char token overlaps a single -// char token, e.g. "||" -> tPipe, "|" -> tOr. -func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token { - start := lexer.currentPos - lexer.lastWidth - nextRune := lexer.next() - var t token - if nextRune == second { - t = token{ - tokenType: matchedType, - value: string(first) + string(second), - position: start, - length: 2, - } - } else { - lexer.back() - t = token{ - tokenType: singleCharType, - value: string(first), - position: start, - length: 1, - } - } - return t -} - -func (lexer *Lexer) consumeLBracket() token { - // There's three options here: - // 1. A filter expression "[?" - // 2. A flatten operator "[]" - // 3. A bare rbracket "[" - start := lexer.currentPos - lexer.lastWidth - nextRune := lexer.next() - var t token - if nextRune == '?' { - t = token{ - tokenType: tFilter, - value: "[?", - position: start, - length: 2, - } - } else if nextRune == ']' { - t = token{ - tokenType: tFlatten, - value: "[]", - position: start, - length: 2, - } - } else { - t = token{ - tokenType: tLbracket, - value: "[", - position: start, - length: 1, - } - lexer.back() - } - return t -} - -func (lexer *Lexer) consumeQuotedIdentifier() (token, error) { - start := lexer.currentPos - value, err := lexer.consumeUntil('"') - if err != nil { - return token{}, err - } - var decoded string - asJSON := []byte("\"" + value + "\"") - if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil { - return token{}, err - } - return token{ - tokenType: tQuotedIdentifier, - value: decoded, - position: start - 1, - length: len(decoded), - }, nil -} - -func (lexer *Lexer) consumeUnquotedIdentifier() token { - // Consume runes until we reach the end of an unquoted - // identifier. - start := lexer.currentPos - lexer.lastWidth - for { - r := lexer.next() - if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 { - lexer.back() - break - } - } - value := lexer.expression[start:lexer.currentPos] - return token{ - tokenType: tUnquotedIdentifier, - value: value, - position: start, - length: lexer.currentPos - start, - } -} - -func (lexer *Lexer) consumeNumber() token { - // Consume runes until we reach something that's not a number. - start := lexer.currentPos - lexer.lastWidth - for { - r := lexer.next() - if r < '0' || r > '9' { - lexer.back() - break - } - } - value := lexer.expression[start:lexer.currentPos] - return token{ - tokenType: tNumber, - value: value, - position: start, - length: lexer.currentPos - start, - } -} diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go deleted file mode 100644 index 4abc303..0000000 --- a/vendor/github.com/jmespath/go-jmespath/parser.go +++ /dev/null @@ -1,603 +0,0 @@ -package jmespath - -import ( - "encoding/json" - "fmt" - "strconv" - "strings" -) - -type astNodeType int - -//go:generate stringer -type astNodeType -const ( - ASTEmpty astNodeType = iota - ASTComparator - ASTCurrentNode - ASTExpRef - ASTFunctionExpression - ASTField - ASTFilterProjection - ASTFlatten - ASTIdentity - ASTIndex - ASTIndexExpression - ASTKeyValPair - ASTLiteral - ASTMultiSelectHash - ASTMultiSelectList - ASTOrExpression - ASTAndExpression - ASTNotExpression - ASTPipe - ASTProjection - ASTSubexpression - ASTSlice - ASTValueProjection -) - -// ASTNode represents the abstract syntax tree of a JMESPath expression. -type ASTNode struct { - nodeType astNodeType - value interface{} - children []ASTNode -} - -func (node ASTNode) String() string { - return node.PrettyPrint(0) -} - -// PrettyPrint will pretty print the parsed AST. -// The AST is an implementation detail and this pretty print -// function is provided as a convenience method to help with -// debugging. You should not rely on its output as the internal -// structure of the AST may change at any time. -func (node ASTNode) PrettyPrint(indent int) string { - spaces := strings.Repeat(" ", indent) - output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType) - nextIndent := indent + 2 - if node.value != nil { - if converted, ok := node.value.(fmt.Stringer); ok { - // Account for things like comparator nodes - // that are enums with a String() method. - output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String()) - } else { - output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value) - } - } - lastIndex := len(node.children) - if lastIndex > 0 { - output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent)) - childIndent := nextIndent + 2 - for _, elem := range node.children { - output += elem.PrettyPrint(childIndent) - } - } - output += fmt.Sprintf("%s}\n", spaces) - return output -} - -var bindingPowers = map[tokType]int{ - tEOF: 0, - tUnquotedIdentifier: 0, - tQuotedIdentifier: 0, - tRbracket: 0, - tRparen: 0, - tComma: 0, - tRbrace: 0, - tNumber: 0, - tCurrent: 0, - tExpref: 0, - tColon: 0, - tPipe: 1, - tOr: 2, - tAnd: 3, - tEQ: 5, - tLT: 5, - tLTE: 5, - tGT: 5, - tGTE: 5, - tNE: 5, - tFlatten: 9, - tStar: 20, - tFilter: 21, - tDot: 40, - tNot: 45, - tLbrace: 50, - tLbracket: 55, - tLparen: 60, -} - -// Parser holds state about the current expression being parsed. -type Parser struct { - expression string - tokens []token - index int -} - -// NewParser creates a new JMESPath parser. -func NewParser() *Parser { - p := Parser{} - return &p -} - -// Parse will compile a JMESPath expression. -func (p *Parser) Parse(expression string) (ASTNode, error) { - lexer := NewLexer() - p.expression = expression - p.index = 0 - tokens, err := lexer.tokenize(expression) - if err != nil { - return ASTNode{}, err - } - p.tokens = tokens - parsed, err := p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - if p.current() != tEOF { - return ASTNode{}, p.syntaxError(fmt.Sprintf( - "Unexpected token at the end of the expression: %s", p.current())) - } - return parsed, nil -} - -func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) { - var err error - leftToken := p.lookaheadToken(0) - p.advance() - leftNode, err := p.nud(leftToken) - if err != nil { - return ASTNode{}, err - } - currentToken := p.current() - for bindingPower < bindingPowers[currentToken] { - p.advance() - leftNode, err = p.led(currentToken, leftNode) - if err != nil { - return ASTNode{}, err - } - currentToken = p.current() - } - return leftNode, nil -} - -func (p *Parser) parseIndexExpression() (ASTNode, error) { - if p.lookahead(0) == tColon || p.lookahead(1) == tColon { - return p.parseSliceExpression() - } - indexStr := p.lookaheadToken(0).value - parsedInt, err := strconv.Atoi(indexStr) - if err != nil { - return ASTNode{}, err - } - indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt} - p.advance() - if err := p.match(tRbracket); err != nil { - return ASTNode{}, err - } - return indexNode, nil -} - -func (p *Parser) parseSliceExpression() (ASTNode, error) { - parts := []*int{nil, nil, nil} - index := 0 - current := p.current() - for current != tRbracket && index < 3 { - if current == tColon { - index++ - p.advance() - } else if current == tNumber { - parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value) - if err != nil { - return ASTNode{}, err - } - parts[index] = &parsedInt - p.advance() - } else { - return ASTNode{}, p.syntaxError( - "Expected tColon or tNumber" + ", received: " + p.current().String()) - } - current = p.current() - } - if err := p.match(tRbracket); err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTSlice, - value: parts, - }, nil -} - -func (p *Parser) match(tokenType tokType) error { - if p.current() == tokenType { - p.advance() - return nil - } - return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String()) -} - -func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) { - switch tokenType { - case tDot: - if p.current() != tStar { - right, err := p.parseDotRHS(bindingPowers[tDot]) - return ASTNode{ - nodeType: ASTSubexpression, - children: []ASTNode{node, right}, - }, err - } - p.advance() - right, err := p.parseProjectionRHS(bindingPowers[tDot]) - return ASTNode{ - nodeType: ASTValueProjection, - children: []ASTNode{node, right}, - }, err - case tPipe: - right, err := p.parseExpression(bindingPowers[tPipe]) - return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err - case tOr: - right, err := p.parseExpression(bindingPowers[tOr]) - return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err - case tAnd: - right, err := p.parseExpression(bindingPowers[tAnd]) - return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err - case tLparen: - name := node.value - var args []ASTNode - for p.current() != tRparen { - expression, err := p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - if p.current() == tComma { - if err := p.match(tComma); err != nil { - return ASTNode{}, err - } - } - args = append(args, expression) - } - if err := p.match(tRparen); err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTFunctionExpression, - value: name, - children: args, - }, nil - case tFilter: - return p.parseFilter(node) - case tFlatten: - left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}} - right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) - return ASTNode{ - nodeType: ASTProjection, - children: []ASTNode{left, right}, - }, err - case tEQ, tNE, tGT, tGTE, tLT, tLTE: - right, err := p.parseExpression(bindingPowers[tokenType]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTComparator, - value: tokenType, - children: []ASTNode{node, right}, - }, nil - case tLbracket: - tokenType := p.current() - var right ASTNode - var err error - if tokenType == tNumber || tokenType == tColon { - right, err = p.parseIndexExpression() - if err != nil { - return ASTNode{}, err - } - return p.projectIfSlice(node, right) - } - // Otherwise this is a projection. - if err := p.match(tStar); err != nil { - return ASTNode{}, err - } - if err := p.match(tRbracket); err != nil { - return ASTNode{}, err - } - right, err = p.parseProjectionRHS(bindingPowers[tStar]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTProjection, - children: []ASTNode{node, right}, - }, nil - } - return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String()) -} - -func (p *Parser) nud(token token) (ASTNode, error) { - switch token.tokenType { - case tJSONLiteral: - var parsed interface{} - err := json.Unmarshal([]byte(token.value), &parsed) - if err != nil { - return ASTNode{}, err - } - return ASTNode{nodeType: ASTLiteral, value: parsed}, nil - case tStringLiteral: - return ASTNode{nodeType: ASTLiteral, value: token.value}, nil - case tUnquotedIdentifier: - return ASTNode{ - nodeType: ASTField, - value: token.value, - }, nil - case tQuotedIdentifier: - node := ASTNode{nodeType: ASTField, value: token.value} - if p.current() == tLparen { - return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token) - } - return node, nil - case tStar: - left := ASTNode{nodeType: ASTIdentity} - var right ASTNode - var err error - if p.current() == tRbracket { - right = ASTNode{nodeType: ASTIdentity} - } else { - right, err = p.parseProjectionRHS(bindingPowers[tStar]) - } - return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err - case tFilter: - return p.parseFilter(ASTNode{nodeType: ASTIdentity}) - case tLbrace: - return p.parseMultiSelectHash() - case tFlatten: - left := ASTNode{ - nodeType: ASTFlatten, - children: []ASTNode{{nodeType: ASTIdentity}}, - } - right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil - case tLbracket: - tokenType := p.current() - //var right ASTNode - if tokenType == tNumber || tokenType == tColon { - right, err := p.parseIndexExpression() - if err != nil { - return ASTNode{}, nil - } - return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right) - } else if tokenType == tStar && p.lookahead(1) == tRbracket { - p.advance() - p.advance() - right, err := p.parseProjectionRHS(bindingPowers[tStar]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTProjection, - children: []ASTNode{{nodeType: ASTIdentity}, right}, - }, nil - } else { - return p.parseMultiSelectList() - } - case tCurrent: - return ASTNode{nodeType: ASTCurrentNode}, nil - case tExpref: - expression, err := p.parseExpression(bindingPowers[tExpref]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil - case tNot: - expression, err := p.parseExpression(bindingPowers[tNot]) - if err != nil { - return ASTNode{}, err - } - return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil - case tLparen: - expression, err := p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - if err := p.match(tRparen); err != nil { - return ASTNode{}, err - } - return expression, nil - case tEOF: - return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token) - } - - return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token) -} - -func (p *Parser) parseMultiSelectList() (ASTNode, error) { - var expressions []ASTNode - for { - expression, err := p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - expressions = append(expressions, expression) - if p.current() == tRbracket { - break - } - err = p.match(tComma) - if err != nil { - return ASTNode{}, err - } - } - err := p.match(tRbracket) - if err != nil { - return ASTNode{}, err - } - return ASTNode{ - nodeType: ASTMultiSelectList, - children: expressions, - }, nil -} - -func (p *Parser) parseMultiSelectHash() (ASTNode, error) { - var children []ASTNode - for { - keyToken := p.lookaheadToken(0) - if err := p.match(tUnquotedIdentifier); err != nil { - if err := p.match(tQuotedIdentifier); err != nil { - return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier") - } - } - keyName := keyToken.value - err := p.match(tColon) - if err != nil { - return ASTNode{}, err - } - value, err := p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - node := ASTNode{ - nodeType: ASTKeyValPair, - value: keyName, - children: []ASTNode{value}, - } - children = append(children, node) - if p.current() == tComma { - err := p.match(tComma) - if err != nil { - return ASTNode{}, nil - } - } else if p.current() == tRbrace { - err := p.match(tRbrace) - if err != nil { - return ASTNode{}, nil - } - break - } - } - return ASTNode{ - nodeType: ASTMultiSelectHash, - children: children, - }, nil -} - -func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) { - indexExpr := ASTNode{ - nodeType: ASTIndexExpression, - children: []ASTNode{left, right}, - } - if right.nodeType == ASTSlice { - right, err := p.parseProjectionRHS(bindingPowers[tStar]) - return ASTNode{ - nodeType: ASTProjection, - children: []ASTNode{indexExpr, right}, - }, err - } - return indexExpr, nil -} -func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) { - var right, condition ASTNode - var err error - condition, err = p.parseExpression(0) - if err != nil { - return ASTNode{}, err - } - if err := p.match(tRbracket); err != nil { - return ASTNode{}, err - } - if p.current() == tFlatten { - right = ASTNode{nodeType: ASTIdentity} - } else { - right, err = p.parseProjectionRHS(bindingPowers[tFilter]) - if err != nil { - return ASTNode{}, err - } - } - - return ASTNode{ - nodeType: ASTFilterProjection, - children: []ASTNode{node, right, condition}, - }, nil -} - -func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) { - lookahead := p.current() - if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) { - return p.parseExpression(bindingPower) - } else if lookahead == tLbracket { - if err := p.match(tLbracket); err != nil { - return ASTNode{}, err - } - return p.parseMultiSelectList() - } else if lookahead == tLbrace { - if err := p.match(tLbrace); err != nil { - return ASTNode{}, err - } - return p.parseMultiSelectHash() - } - return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace") -} - -func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) { - current := p.current() - if bindingPowers[current] < 10 { - return ASTNode{nodeType: ASTIdentity}, nil - } else if current == tLbracket { - return p.parseExpression(bindingPower) - } else if current == tFilter { - return p.parseExpression(bindingPower) - } else if current == tDot { - err := p.match(tDot) - if err != nil { - return ASTNode{}, err - } - return p.parseDotRHS(bindingPower) - } else { - return ASTNode{}, p.syntaxError("Error") - } -} - -func (p *Parser) lookahead(number int) tokType { - return p.lookaheadToken(number).tokenType -} - -func (p *Parser) current() tokType { - return p.lookahead(0) -} - -func (p *Parser) lookaheadToken(number int) token { - return p.tokens[p.index+number] -} - -func (p *Parser) advance() { - p.index++ -} - -func tokensOneOf(elements []tokType, token tokType) bool { - for _, elem := range elements { - if elem == token { - return true - } - } - return false -} - -func (p *Parser) syntaxError(msg string) SyntaxError { - return SyntaxError{ - msg: msg, - Expression: p.expression, - Offset: p.lookaheadToken(0).position, - } -} - -// Create a SyntaxError based on the provided token. -// This differs from syntaxError() which creates a SyntaxError -// based on the current lookahead token. -func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError { - return SyntaxError{ - msg: msg, - Expression: p.expression, - Offset: t.position, - } -} diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go deleted file mode 100644 index dae79cb..0000000 --- a/vendor/github.com/jmespath/go-jmespath/toktype_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// generated by stringer -type=tokType; DO NOT EDIT - -package jmespath - -import "fmt" - -const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF" - -var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214} - -func (i tokType) String() string { - if i < 0 || i >= tokType(len(_tokType_index)-1) { - return fmt.Sprintf("tokType(%d)", i) - } - return _tokType_name[_tokType_index[i]:_tokType_index[i+1]] -} diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go deleted file mode 100644 index ddc1b7d..0000000 --- a/vendor/github.com/jmespath/go-jmespath/util.go +++ /dev/null @@ -1,185 +0,0 @@ -package jmespath - -import ( - "errors" - "reflect" -) - -// IsFalse determines if an object is false based on the JMESPath spec. -// JMESPath defines false values to be any of: -// - An empty string array, or hash. -// - The boolean value false. -// - nil -func isFalse(value interface{}) bool { - switch v := value.(type) { - case bool: - return !v - case []interface{}: - return len(v) == 0 - case map[string]interface{}: - return len(v) == 0 - case string: - return len(v) == 0 - case nil: - return true - } - // Try the reflection cases before returning false. - rv := reflect.ValueOf(value) - switch rv.Kind() { - case reflect.Struct: - // A struct type will never be false, even if - // all of its values are the zero type. - return false - case reflect.Slice, reflect.Map: - return rv.Len() == 0 - case reflect.Ptr: - if rv.IsNil() { - return true - } - // If it's a pointer type, we'll try to deref the pointer - // and evaluate the pointer value for isFalse. - element := rv.Elem() - return isFalse(element.Interface()) - } - return false -} - -// ObjsEqual is a generic object equality check. -// It will take two arbitrary objects and recursively determine -// if they are equal. -func objsEqual(left interface{}, right interface{}) bool { - return reflect.DeepEqual(left, right) -} - -// SliceParam refers to a single part of a slice. -// A slice consists of a start, a stop, and a step, similar to -// python slices. -type sliceParam struct { - N int - Specified bool -} - -// Slice supports [start:stop:step] style slicing that's supported in JMESPath. -func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) { - computed, err := computeSliceParams(len(slice), parts) - if err != nil { - return nil, err - } - start, stop, step := computed[0], computed[1], computed[2] - result := []interface{}{} - if step > 0 { - for i := start; i < stop; i += step { - result = append(result, slice[i]) - } - } else { - for i := start; i > stop; i += step { - result = append(result, slice[i]) - } - } - return result, nil -} - -func computeSliceParams(length int, parts []sliceParam) ([]int, error) { - var start, stop, step int - if !parts[2].Specified { - step = 1 - } else if parts[2].N == 0 { - return nil, errors.New("Invalid slice, step cannot be 0") - } else { - step = parts[2].N - } - var stepValueNegative bool - if step < 0 { - stepValueNegative = true - } else { - stepValueNegative = false - } - - if !parts[0].Specified { - if stepValueNegative { - start = length - 1 - } else { - start = 0 - } - } else { - start = capSlice(length, parts[0].N, step) - } - - if !parts[1].Specified { - if stepValueNegative { - stop = -1 - } else { - stop = length - } - } else { - stop = capSlice(length, parts[1].N, step) - } - return []int{start, stop, step}, nil -} - -func capSlice(length int, actual int, step int) int { - if actual < 0 { - actual += length - if actual < 0 { - if step < 0 { - actual = -1 - } else { - actual = 0 - } - } - } else if actual >= length { - if step < 0 { - actual = length - 1 - } else { - actual = length - } - } - return actual -} - -// ToArrayNum converts an empty interface type to a slice of float64. -// If any element in the array cannot be converted, then nil is returned -// along with a second value of false. -func toArrayNum(data interface{}) ([]float64, bool) { - // Is there a better way to do this with reflect? - if d, ok := data.([]interface{}); ok { - result := make([]float64, len(d)) - for i, el := range d { - item, ok := el.(float64) - if !ok { - return nil, false - } - result[i] = item - } - return result, true - } - return nil, false -} - -// ToArrayStr converts an empty interface type to a slice of strings. -// If any element in the array cannot be converted, then nil is returned -// along with a second value of false. If the input data could be entirely -// converted, then the converted data, along with a second value of true, -// will be returned. -func toArrayStr(data interface{}) ([]string, bool) { - // Is there a better way to do this with reflect? - if d, ok := data.([]interface{}); ok { - result := make([]string, len(d)) - for i, el := range d { - item, ok := el.(string) - if !ok { - return nil, false - } - result[i] = item - } - return result, true - } - return nil, false -} - -func isSliceType(v interface{}) bool { - if v == nil { - return false - } - return reflect.TypeOf(v).Kind() == reflect.Slice -} diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index de264c8..af2ef63 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -14,8 +14,47 @@ This package provides various compression algorithms. [![Go](https://github.com/klauspost/compress/actions/workflows/go.yml/badge.svg)](https://github.com/klauspost/compress/actions/workflows/go.yml) [![Sourcegraph Badge](https://sourcegraph.com/github.com/klauspost/compress/-/badge.svg)](https://sourcegraph.com/github.com/klauspost/compress?badge) +# package usage + +Use `go get github.com/klauspost/compress@latest` to add it to your project. + +This package will support the current Go version and 2 versions back. + +* Use the `nounsafe` tag to disable all use of the "unsafe" package. +* Use the `noasm` tag to disable all assembly across packages. + +Use the links above for more information on each. + # changelog +* Oct 20, 2025 - [1.18.1](https://github.com/klauspost/compress/releases/tag/v1.18.1) + * zstd: Add simple zstd EncodeTo/DecodeTo functions https://github.com/klauspost/compress/pull/1079 + * zstd: Fix incorrect buffer size in dictionary encodes https://github.com/klauspost/compress/pull/1059 + * s2: check for cap, not len of buffer in EncodeBetter/Best by @vdarulis in https://github.com/klauspost/compress/pull/1080 + * zlib: Avoiding extra allocation in zlib.reader.Reset by @travelpolicy in https://github.com/klauspost/compress/pull/1086 + * gzhttp: remove redundant err check in zstdReader by @ryanfowler in https://github.com/klauspost/compress/pull/1090 + * flate: Faster load+store https://github.com/klauspost/compress/pull/1104 + * flate: Simplify matchlen https://github.com/klauspost/compress/pull/1101 + * flate: Use exact sizes for huffman tables https://github.com/klauspost/compress/pull/1103 + +* Feb 19th, 2025 - [1.18.0](https://github.com/klauspost/compress/releases/tag/v1.18.0) + * Add unsafe little endian loaders https://github.com/klauspost/compress/pull/1036 + * fix: check `r.err != nil` but return a nil value error `err` by @alingse in https://github.com/klauspost/compress/pull/1028 + * flate: Simplify L4-6 loading https://github.com/klauspost/compress/pull/1043 + * flate: Simplify matchlen (remove asm) https://github.com/klauspost/compress/pull/1045 + * s2: Improve small block compression speed w/o asm https://github.com/klauspost/compress/pull/1048 + * flate: Fix matchlen L5+L6 https://github.com/klauspost/compress/pull/1049 + * flate: Cleanup & reduce casts https://github.com/klauspost/compress/pull/1050 + +

+ See changes to v1.17.x + +* Oct 11th, 2024 - [1.17.11](https://github.com/klauspost/compress/releases/tag/v1.17.11) + * zstd: Fix extra CRC written with multiple Close calls https://github.com/klauspost/compress/pull/1017 + * s2: Don't use stack for index tables https://github.com/klauspost/compress/pull/1014 + * gzhttp: No content-type on no body response code by @juliens in https://github.com/klauspost/compress/pull/1011 + * gzhttp: Do not set the content-type when response has no body by @kevinpollet in https://github.com/klauspost/compress/pull/1013 + * Sep 23rd, 2024 - [1.17.10](https://github.com/klauspost/compress/releases/tag/v1.17.10) * gzhttp: Add TransportAlwaysDecompress option. https://github.com/klauspost/compress/pull/978 * gzhttp: Add supported decompress request body by @mirecl in https://github.com/klauspost/compress/pull/1002 @@ -65,9 +104,9 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp * zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876 * Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1) - * s2: Fix S2 "best" dictionary wrong encoding by @klauspost in https://github.com/klauspost/compress/pull/871 + * s2: Fix S2 "best" dictionary wrong encoding https://github.com/klauspost/compress/pull/871 * flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869 - * s2: Fix EstimateBlockSize on 6&7 length input by @klauspost in https://github.com/klauspost/compress/pull/867 + * s2: Fix EstimateBlockSize on 6&7 length input https://github.com/klauspost/compress/pull/867 * Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0) * Add experimental dictionary builder https://github.com/klauspost/compress/pull/853 @@ -76,7 +115,8 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp * s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839 * flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837 * gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860 - + +
See changes to v1.16.x @@ -124,7 +164,7 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp See changes to v1.15.x * Jan 21st, 2023 (v1.15.15) - * deflate: Improve level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/739 + * deflate: Improve level 7-9 https://github.com/klauspost/compress/pull/739 * zstd: Add delta encoding support by @greatroar in https://github.com/klauspost/compress/pull/728 * zstd: Various speed improvements by @greatroar https://github.com/klauspost/compress/pull/741 https://github.com/klauspost/compress/pull/734 https://github.com/klauspost/compress/pull/736 https://github.com/klauspost/compress/pull/744 https://github.com/klauspost/compress/pull/743 https://github.com/klauspost/compress/pull/745 * gzhttp: Add SuffixETag() and DropETag() options to prevent ETag collisions on compressed responses by @willbicks in https://github.com/klauspost/compress/pull/740 @@ -167,7 +207,7 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp * zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645 * zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644 - * zstd: Allow single segments up to "max decoded size" by @klauspost in https://github.com/klauspost/compress/pull/643 + * zstd: Allow single segments up to "max decoded size" https://github.com/klauspost/compress/pull/643 * July 13, 2022 (v1.15.8) @@ -209,7 +249,7 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp * zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599 * zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593 * huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586 - * flate: Inplace hashing for level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/590 + * flate: Inplace hashing for level 7-9 https://github.com/klauspost/compress/pull/590 * May 11, 2022 (v1.15.4) @@ -236,12 +276,12 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp * zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523) * Mar 3, 2022 (v1.15.0) - * zstd: Refactor decoder by @klauspost in [#498](https://github.com/klauspost/compress/pull/498) - * zstd: Add stream encoding without goroutines by @klauspost in [#505](https://github.com/klauspost/compress/pull/505) + * zstd: Refactor decoder [#498](https://github.com/klauspost/compress/pull/498) + * zstd: Add stream encoding without goroutines [#505](https://github.com/klauspost/compress/pull/505) * huff0: Prevent single blocks exceeding 16 bits by @klauspost in[#507](https://github.com/klauspost/compress/pull/507) - * flate: Inline literal emission by @klauspost in [#509](https://github.com/klauspost/compress/pull/509) - * gzhttp: Add zstd to transport by @klauspost in [#400](https://github.com/klauspost/compress/pull/400) - * gzhttp: Make content-type optional by @klauspost in [#510](https://github.com/klauspost/compress/pull/510) + * flate: Inline literal emission [#509](https://github.com/klauspost/compress/pull/509) + * gzhttp: Add zstd to transport [#400](https://github.com/klauspost/compress/pull/400) + * gzhttp: Make content-type optional [#510](https://github.com/klauspost/compress/pull/510) Both compression and decompression now supports "synchronous" stream operations. This means that whenever "concurrency" is set to 1, they will operate without spawning goroutines. @@ -258,7 +298,7 @@ While the release has been extensively tested, it is recommended to testing when * flate: Fix rare huffman only (-2) corruption. [#503](https://github.com/klauspost/compress/pull/503) * zip: Update deprecated CreateHeaderRaw to correctly call CreateRaw by @saracen in [#502](https://github.com/klauspost/compress/pull/502) * zip: don't read data descriptor early by @saracen in [#501](https://github.com/klauspost/compress/pull/501) #501 - * huff0: Use static decompression buffer up to 30% faster by @klauspost in [#499](https://github.com/klauspost/compress/pull/499) [#500](https://github.com/klauspost/compress/pull/500) + * huff0: Use static decompression buffer up to 30% faster [#499](https://github.com/klauspost/compress/pull/499) [#500](https://github.com/klauspost/compress/pull/500) * Feb 17, 2022 (v1.14.3) * flate: Improve fastest levels compression speed ~10% more throughput. [#482](https://github.com/klauspost/compress/pull/482) [#489](https://github.com/klauspost/compress/pull/489) [#490](https://github.com/klauspost/compress/pull/490) [#491](https://github.com/klauspost/compress/pull/491) [#494](https://github.com/klauspost/compress/pull/494) [#478](https://github.com/klauspost/compress/pull/478) @@ -565,12 +605,14 @@ While the release has been extensively tested, it is recommended to testing when The packages are drop-in replacements for standard libraries. Simply replace the import path to use them: -| old import | new import | Documentation -|--------------------|-----------------------------------------|--------------------| -| `compress/gzip` | `github.com/klauspost/compress/gzip` | [gzip](https://pkg.go.dev/github.com/klauspost/compress/gzip?tab=doc) -| `compress/zlib` | `github.com/klauspost/compress/zlib` | [zlib](https://pkg.go.dev/github.com/klauspost/compress/zlib?tab=doc) -| `archive/zip` | `github.com/klauspost/compress/zip` | [zip](https://pkg.go.dev/github.com/klauspost/compress/zip?tab=doc) -| `compress/flate` | `github.com/klauspost/compress/flate` | [flate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc) +Typical speed is about 2x of the standard library packages. + +| old import | new import | Documentation | +|------------------|---------------------------------------|-------------------------------------------------------------------------| +| `compress/gzip` | `github.com/klauspost/compress/gzip` | [gzip](https://pkg.go.dev/github.com/klauspost/compress/gzip?tab=doc) | +| `compress/zlib` | `github.com/klauspost/compress/zlib` | [zlib](https://pkg.go.dev/github.com/klauspost/compress/zlib?tab=doc) | +| `archive/zip` | `github.com/klauspost/compress/zip` | [zip](https://pkg.go.dev/github.com/klauspost/compress/zip?tab=doc) | +| `compress/flate` | `github.com/klauspost/compress/flate` | [flate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc) | * Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib). @@ -625,84 +667,6 @@ This will only use up to 4KB in memory when the writer is idle. Compression is almost always worse than the fastest compression level and each write will allocate (a little) memory. -# Performance Update 2018 - -It has been a while since we have been looking at the speed of this package compared to the standard library, so I thought I would re-do my tests and give some overall recommendations based on the current state. All benchmarks have been performed with Go 1.10 on my Desktop Intel(R) Core(TM) i7-2600 CPU @3.40GHz. Since I last ran the tests, I have gotten more RAM, which means tests with big files are no longer limited by my SSD. - -The raw results are in my [updated spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing). Due to cgo changes and upstream updates i could not get the cgo version of gzip to compile. Instead I included the [zstd](https://github.com/datadog/zstd) cgo implementation. If I get cgo gzip to work again, I might replace the results in the sheet. - -The columns to take note of are: *MB/s* - the throughput. *Reduction* - the data size reduction in percent of the original. *Rel Speed* relative speed compared to the standard library at the same level. *Smaller* - how many percent smaller is the compressed output compared to stdlib. Negative means the output was bigger. *Loss* means the loss (or gain) in compression as a percentage difference of the input. - -The `gzstd` (standard library gzip) and `gzkp` (this package gzip) only uses one CPU core. [`pgzip`](https://github.com/klauspost/pgzip), [`bgzf`](https://github.com/biogo/hts/tree/master/bgzf) uses all 4 cores. [`zstd`](https://github.com/DataDog/zstd) uses one core, and is a beast (but not Go, yet). - - -## Overall differences. - -There appears to be a roughly 5-10% speed advantage over the standard library when comparing at similar compression levels. - -The biggest difference you will see is the result of [re-balancing](https://blog.klauspost.com/rebalancing-deflate-compression-levels/) the compression levels. I wanted by library to give a smoother transition between the compression levels than the standard library. - -This package attempts to provide a more smooth transition, where "1" is taking a lot of shortcuts, "5" is the reasonable trade-off and "9" is the "give me the best compression", and the values in between gives something reasonable in between. The standard library has big differences in levels 1-4, but levels 5-9 having no significant gains - often spending a lot more time than can be justified by the achieved compression. - -There are links to all the test data in the [spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) in the top left field on each tab. - -## Web Content - -This test set aims to emulate typical use in a web server. The test-set is 4GB data in 53k files, and is a mixture of (mostly) HTML, JS, CSS. - -Since level 1 and 9 are close to being the same code, they are quite close. But looking at the levels in-between the differences are quite big. - -Looking at level 6, this package is 88% faster, but will output about 6% more data. For a web server, this means you can serve 88% more data, but have to pay for 6% more bandwidth. You can draw your own conclusions on what would be the most expensive for your case. - -## Object files - -This test is for typical data files stored on a server. In this case it is a collection of Go precompiled objects. They are very compressible. - -The picture is similar to the web content, but with small differences since this is very compressible. Levels 2-3 offer good speed, but is sacrificing quite a bit of compression. - -The standard library seems suboptimal on level 3 and 4 - offering both worse compression and speed than level 6 & 7 of this package respectively. - -## Highly Compressible File - -This is a JSON file with very high redundancy. The reduction starts at 95% on level 1, so in real life terms we are dealing with something like a highly redundant stream of data, etc. - -It is definitely visible that we are dealing with specialized content here, so the results are very scattered. This package does not do very well at levels 1-4, but picks up significantly at level 5 and levels 7 and 8 offering great speed for the achieved compression. - -So if you know you content is extremely compressible you might want to go slightly higher than the defaults. The standard library has a huge gap between levels 3 and 4 in terms of speed (2.75x slowdown), so it offers little "middle ground". - -## Medium-High Compressible - -This is a pretty common test corpus: [enwik9](http://mattmahoney.net/dc/textdata.html). It contains the first 10^9 bytes of the English Wikipedia dump on Mar. 3, 2006. This is a very good test of typical text based compression and more data heavy streams. - -We see a similar picture here as in "Web Content". On equal levels some compression is sacrificed for more speed. Level 5 seems to be the best trade-off between speed and size, beating stdlib level 3 in both. - -## Medium Compressible - -I will combine two test sets, one [10GB file set](http://mattmahoney.net/dc/10gb.html) and a VM disk image (~8GB). Both contain different data types and represent a typical backup scenario. - -The most notable thing is how quickly the standard library drops to very low compression speeds around level 5-6 without any big gains in compression. Since this type of data is fairly common, this does not seem like good behavior. - - -## Un-compressible Content - -This is mainly a test of how good the algorithms are at detecting un-compressible input. The standard library only offers this feature with very conservative settings at level 1. Obviously there is no reason for the algorithms to try to compress input that cannot be compressed. The only downside is that it might skip some compressible data on false detections. - - -## Huffman only compression - -This compression library adds a special compression level, named `HuffmanOnly`, which allows near linear time compression. This is done by completely disabling matching of previous data, and only reduce the number of bits to represent each character. - -This means that often used characters, like 'e' and ' ' (space) in text use the fewest bits to represent, and rare characters like '¤' takes more bits to represent. For more information see [wikipedia](https://en.wikipedia.org/wiki/Huffman_coding) or this nice [video](https://youtu.be/ZdooBTdW5bM). - -Since this type of compression has much less variance, the compression speed is mostly unaffected by the input data, and is usually more than *180MB/s* for a single core. - -The downside is that the compression ratio is usually considerably worse than even the fastest conventional compression. The compression ratio can never be better than 8:1 (12.5%). - -The linear time compression can be used as a "better than nothing" mode, where you cannot risk the encoder to slow down on some content. For comparison, the size of the "Twain" text is *233460 bytes* (+29% vs. level 1) and encode speed is 144MB/s (4.5x level 1). So in this case you trade a 30% size increase for a 4 times speedup. - -For more information see my blog post on [Fast Linear Time Compression](http://blog.klauspost.com/constant-time-gzipzip-compression/). - -This is implemented on Go 1.7 as "Huffman Only" mode, though not exposed for gzip. # Other packages @@ -719,3 +683,4 @@ Here are other packages of good quality and pure Go (no cgo wrappers or autoconv # license This code is licensed under the same conditions as the original Go code. See LICENSE file. + diff --git a/vendor/github.com/klauspost/compress/fse/bitwriter.go b/vendor/github.com/klauspost/compress/fse/bitwriter.go index e82fa3b..d58b3fe 100644 --- a/vendor/github.com/klauspost/compress/fse/bitwriter.go +++ b/vendor/github.com/klauspost/compress/fse/bitwriter.go @@ -143,7 +143,7 @@ func (b *bitWriter) flush32() { // flushAlign will flush remaining full bytes and align to next byte boundary. func (b *bitWriter) flushAlign() { nbBytes := (b.nBits + 7) >> 3 - for i := uint8(0); i < nbBytes; i++ { + for i := range nbBytes { b.out = append(b.out, byte(b.bitContainer>>(i*8))) } b.nBits = 0 diff --git a/vendor/github.com/klauspost/compress/fse/compress.go b/vendor/github.com/klauspost/compress/fse/compress.go index 074018d..8c8baa4 100644 --- a/vendor/github.com/klauspost/compress/fse/compress.go +++ b/vendor/github.com/klauspost/compress/fse/compress.go @@ -396,7 +396,7 @@ func (s *Scratch) buildCTable() error { if v > largeLimit { s.zeroBits = true } - for nbOccurrences := int16(0); nbOccurrences < v; nbOccurrences++ { + for range v { tableSymbol[position] = symbol position = (position + step) & tableMask for position > highThreshold { diff --git a/vendor/github.com/klauspost/compress/huff0/bitreader.go b/vendor/github.com/klauspost/compress/huff0/bitreader.go index e36d974..bfc7a52 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitreader.go +++ b/vendor/github.com/klauspost/compress/huff0/bitreader.go @@ -6,10 +6,11 @@ package huff0 import ( - "encoding/binary" "errors" "fmt" "io" + + "github.com/klauspost/compress/internal/le" ) // bitReader reads a bitstream in reverse. @@ -46,7 +47,7 @@ func (b *bitReaderBytes) init(in []byte) error { return nil } -// peekBitsFast requires that at least one bit is requested every time. +// peekByteFast requires that at least one byte is requested every time. // There are no checks if the buffer is filled. func (b *bitReaderBytes) peekByteFast() uint8 { got := uint8(b.value >> 56) @@ -66,8 +67,7 @@ func (b *bitReaderBytes) fillFast() { } // 2 bounds checks. - v := b.in[b.off-4 : b.off] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + low := le.Load32(b.in, b.off-4) b.value |= uint64(low) << (b.bitsRead - 32) b.bitsRead -= 32 b.off -= 4 @@ -76,7 +76,7 @@ func (b *bitReaderBytes) fillFast() { // fillFastStart() assumes the bitReaderBytes is empty and there is at least 8 bytes to read. func (b *bitReaderBytes) fillFastStart() { // Do single re-slice to avoid bounds checks. - b.value = binary.LittleEndian.Uint64(b.in[b.off-8:]) + b.value = le.Load64(b.in, b.off-8) b.bitsRead = 0 b.off -= 8 } @@ -86,9 +86,8 @@ func (b *bitReaderBytes) fill() { if b.bitsRead < 32 { return } - if b.off > 4 { - v := b.in[b.off-4 : b.off] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + if b.off >= 4 { + low := le.Load32(b.in, b.off-4) b.value |= uint64(low) << (b.bitsRead - 32) b.bitsRead -= 32 b.off -= 4 @@ -175,9 +174,7 @@ func (b *bitReaderShifted) fillFast() { return } - // 2 bounds checks. - v := b.in[b.off-4 : b.off] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + low := le.Load32(b.in, b.off-4) b.value |= uint64(low) << ((b.bitsRead - 32) & 63) b.bitsRead -= 32 b.off -= 4 @@ -185,8 +182,7 @@ func (b *bitReaderShifted) fillFast() { // fillFastStart() assumes the bitReaderShifted is empty and there is at least 8 bytes to read. func (b *bitReaderShifted) fillFastStart() { - // Do single re-slice to avoid bounds checks. - b.value = binary.LittleEndian.Uint64(b.in[b.off-8:]) + b.value = le.Load64(b.in, b.off-8) b.bitsRead = 0 b.off -= 8 } @@ -197,8 +193,7 @@ func (b *bitReaderShifted) fill() { return } if b.off > 4 { - v := b.in[b.off-4 : b.off] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + low := le.Load32(b.in, b.off-4) b.value |= uint64(low) << ((b.bitsRead - 32) & 63) b.bitsRead -= 32 b.off -= 4 diff --git a/vendor/github.com/klauspost/compress/huff0/bitwriter.go b/vendor/github.com/klauspost/compress/huff0/bitwriter.go index 0ebc9aa..41db94c 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitwriter.go +++ b/vendor/github.com/klauspost/compress/huff0/bitwriter.go @@ -85,7 +85,7 @@ func (b *bitWriter) flush32() { // flushAlign will flush remaining full bytes and align to next byte boundary. func (b *bitWriter) flushAlign() { nbBytes := (b.nBits + 7) >> 3 - for i := uint8(0); i < nbBytes; i++ { + for i := range nbBytes { b.out = append(b.out, byte(b.bitContainer>>(i*8))) } b.nBits = 0 diff --git a/vendor/github.com/klauspost/compress/huff0/compress.go b/vendor/github.com/klauspost/compress/huff0/compress.go index 84aa3d1..a97cf1b 100644 --- a/vendor/github.com/klauspost/compress/huff0/compress.go +++ b/vendor/github.com/klauspost/compress/huff0/compress.go @@ -276,7 +276,7 @@ func (s *Scratch) compress4X(src []byte) ([]byte, error) { offsetIdx := len(s.Out) s.Out = append(s.Out, sixZeros[:]...) - for i := 0; i < 4; i++ { + for i := range 4 { toDo := src if len(toDo) > segmentSize { toDo = toDo[:segmentSize] @@ -312,7 +312,7 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) { segmentSize := (len(src) + 3) / 4 var wg sync.WaitGroup wg.Add(4) - for i := 0; i < 4; i++ { + for i := range 4 { toDo := src if len(toDo) > segmentSize { toDo = toDo[:segmentSize] @@ -326,7 +326,7 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) { }(i) } wg.Wait() - for i := 0; i < 4; i++ { + for i := range 4 { o := s.tmpOut[i] if len(o) > math.MaxUint16 { // We cannot store the size in the jump table diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go index 0f56b02..7d0efa8 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress.go @@ -626,7 +626,7 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { var br [4]bitReaderBytes start := 6 - for i := 0; i < 3; i++ { + for i := range 3 { length := int(src[i*2]) | (int(src[i*2+1]) << 8) if start+length >= len(src) { return nil, errors.New("truncated input (or invalid offset)") @@ -798,10 +798,7 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { remainBytes := dstEvery - (decoded / 4) for i := range br { offset := dstEvery * i - endsAt := offset + remainBytes - if endsAt > len(out) { - endsAt = len(out) - } + endsAt := min(offset+remainBytes, len(out)) br := &br[i] bitsLeft := br.remaining() for bitsLeft > 0 { @@ -864,7 +861,7 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { var br [4]bitReaderBytes start := 6 - for i := 0; i < 3; i++ { + for i := range 3 { length := int(src[i*2]) | (int(src[i*2+1]) << 8) if start+length >= len(src) { return nil, errors.New("truncated input (or invalid offset)") @@ -1035,10 +1032,7 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { remainBytes := dstEvery - (decoded / 4) for i := range br { offset := dstEvery * i - endsAt := offset + remainBytes - if endsAt > len(out) { - endsAt = len(out) - } + endsAt := min(offset+remainBytes, len(out)) br := &br[i] bitsLeft := br.remaining() for bitsLeft > 0 { diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index ba7e8e6..99ddd4a 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -58,7 +58,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { var br [4]bitReaderShifted // Decode "jump table" start := 6 - for i := 0; i < 3; i++ { + for i := range 3 { length := int(src[i*2]) | (int(src[i*2+1]) << 8) if start+length >= len(src) { return nil, errors.New("truncated input (or invalid offset)") @@ -109,10 +109,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { remainBytes := dstEvery - (decoded / 4) for i := range br { offset := dstEvery * i - endsAt := offset + remainBytes - if endsAt > len(out) { - endsAt = len(out) - } + endsAt := min(offset+remainBytes, len(out)) br := &br[i] bitsLeft := br.remaining() for bitsLeft > 0 { diff --git a/vendor/github.com/klauspost/compress/huff0/huff0.go b/vendor/github.com/klauspost/compress/huff0/huff0.go index 77ecd68..67d9e05 100644 --- a/vendor/github.com/klauspost/compress/huff0/huff0.go +++ b/vendor/github.com/klauspost/compress/huff0/huff0.go @@ -201,7 +201,7 @@ func (c cTable) write(s *Scratch) error { for i := range hist[:16] { hist[i] = 0 } - for n := uint8(0); n < maxSymbolValue; n++ { + for n := range maxSymbolValue { v := bitsToWeight[c[n].nBits] & 15 huffWeight[n] = v hist[v]++ @@ -271,7 +271,7 @@ func (c cTable) estTableSize(s *Scratch) (sz int, err error) { for i := range hist[:16] { hist[i] = 0 } - for n := uint8(0); n < maxSymbolValue; n++ { + for n := range maxSymbolValue { v := bitsToWeight[c[n].nBits] & 15 huffWeight[n] = v hist[v]++ diff --git a/vendor/github.com/klauspost/compress/internal/le/le.go b/vendor/github.com/klauspost/compress/internal/le/le.go new file mode 100644 index 0000000..e54909e --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/le/le.go @@ -0,0 +1,5 @@ +package le + +type Indexer interface { + int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 +} diff --git a/vendor/github.com/klauspost/compress/internal/le/unsafe_disabled.go b/vendor/github.com/klauspost/compress/internal/le/unsafe_disabled.go new file mode 100644 index 0000000..4f2a0d8 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/le/unsafe_disabled.go @@ -0,0 +1,42 @@ +//go:build !(amd64 || arm64 || ppc64le || riscv64) || nounsafe || purego || appengine + +package le + +import ( + "encoding/binary" +) + +// Load8 will load from b at index i. +func Load8[I Indexer](b []byte, i I) byte { + return b[i] +} + +// Load16 will load from b at index i. +func Load16[I Indexer](b []byte, i I) uint16 { + return binary.LittleEndian.Uint16(b[i:]) +} + +// Load32 will load from b at index i. +func Load32[I Indexer](b []byte, i I) uint32 { + return binary.LittleEndian.Uint32(b[i:]) +} + +// Load64 will load from b at index i. +func Load64[I Indexer](b []byte, i I) uint64 { + return binary.LittleEndian.Uint64(b[i:]) +} + +// Store16 will store v at b. +func Store16(b []byte, v uint16) { + binary.LittleEndian.PutUint16(b, v) +} + +// Store32 will store v at b. +func Store32(b []byte, v uint32) { + binary.LittleEndian.PutUint32(b, v) +} + +// Store64 will store v at b. +func Store64[I Indexer](b []byte, i I, v uint64) { + binary.LittleEndian.PutUint64(b[i:], v) +} diff --git a/vendor/github.com/klauspost/compress/internal/le/unsafe_enabled.go b/vendor/github.com/klauspost/compress/internal/le/unsafe_enabled.go new file mode 100644 index 0000000..218a38b --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/le/unsafe_enabled.go @@ -0,0 +1,52 @@ +// We enable 64 bit LE platforms: + +//go:build (amd64 || arm64 || ppc64le || riscv64) && !nounsafe && !purego && !appengine + +package le + +import ( + "unsafe" +) + +// Load8 will load from b at index i. +func Load8[I Indexer](b []byte, i I) byte { + //return binary.LittleEndian.Uint16(b[i:]) + //return *(*uint16)(unsafe.Pointer(&b[i])) + return *(*byte)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) +} + +// Load16 will load from b at index i. +func Load16[I Indexer](b []byte, i I) uint16 { + //return binary.LittleEndian.Uint16(b[i:]) + //return *(*uint16)(unsafe.Pointer(&b[i])) + return *(*uint16)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) +} + +// Load32 will load from b at index i. +func Load32[I Indexer](b []byte, i I) uint32 { + //return binary.LittleEndian.Uint32(b[i:]) + //return *(*uint32)(unsafe.Pointer(&b[i])) + return *(*uint32)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) +} + +// Load64 will load from b at index i. +func Load64[I Indexer](b []byte, i I) uint64 { + //return binary.LittleEndian.Uint64(b[i:]) + //return *(*uint64)(unsafe.Pointer(&b[i])) + return *(*uint64)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) +} + +// Store16 will store v at b. +func Store16(b []byte, v uint16) { + *(*uint16)(unsafe.Pointer(unsafe.SliceData(b))) = v +} + +// Store32 will store v at b. +func Store32(b []byte, v uint32) { + *(*uint32)(unsafe.Pointer(unsafe.SliceData(b))) = v +} + +// Store64 will store v at b[i:]. +func Store64[I Indexer](b []byte, i I, v uint64) { + *(*uint64)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i)) = v +} diff --git a/vendor/github.com/klauspost/compress/internal/snapref/decode.go b/vendor/github.com/klauspost/compress/internal/snapref/decode.go index 40796a4..a2c82fc 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/decode.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/decode.go @@ -209,7 +209,7 @@ func (r *Reader) fill() error { if !r.readFull(r.buf[:len(magicBody)], false) { return r.err } - for i := 0; i < len(magicBody); i++ { + for i := range len(magicBody) { if r.buf[i] != magicBody[i] { r.err = ErrCorrupt return r.err diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode.go b/vendor/github.com/klauspost/compress/internal/snapref/encode.go index 13c6040..860a994 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/encode.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode.go @@ -20,8 +20,10 @@ import ( func Encode(dst, src []byte) []byte { if n := MaxEncodedLen(len(src)); n < 0 { panic(ErrTooLarge) - } else if len(dst) < n { + } else if cap(dst) < n { dst = make([]byte, n) + } else { + dst = dst[:n] } // The block starts with the varint-encoded length of the decompressed bytes. diff --git a/vendor/github.com/klauspost/compress/s2sx.mod b/vendor/github.com/klauspost/compress/s2sx.mod index 5a4412f..81bda5e 100644 --- a/vendor/github.com/klauspost/compress/s2sx.mod +++ b/vendor/github.com/klauspost/compress/s2sx.mod @@ -1,4 +1,3 @@ module github.com/klauspost/compress -go 1.19 - +go 1.22 diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index 92e2347..c11d7fa 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -6,7 +6,7 @@ A high performance compression algorithm is implemented. For now focused on spee This package provides [compression](#Compressor) to and [decompression](#Decompressor) of Zstandard content. -This package is pure Go and without use of "unsafe". +This package is pure Go. Use `noasm` and `nounsafe` to disable relevant features. The `zstd` package is provided as open source software using a Go standard license. diff --git a/vendor/github.com/klauspost/compress/zstd/bitreader.go b/vendor/github.com/klauspost/compress/zstd/bitreader.go index 25ca983..d41e3e1 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitreader.go +++ b/vendor/github.com/klauspost/compress/zstd/bitreader.go @@ -5,11 +5,12 @@ package zstd import ( - "encoding/binary" "errors" "fmt" "io" "math/bits" + + "github.com/klauspost/compress/internal/le" ) // bitReader reads a bitstream in reverse. @@ -18,6 +19,7 @@ import ( type bitReader struct { in []byte value uint64 // Maybe use [16]byte, but shifting is awkward. + cursor int // offset where next read should end bitsRead uint8 } @@ -32,6 +34,7 @@ func (b *bitReader) init(in []byte) error { if v == 0 { return errors.New("corrupt stream, did not find end of stream") } + b.cursor = len(in) b.bitsRead = 64 b.value = 0 if len(in) >= 8 { @@ -67,18 +70,15 @@ func (b *bitReader) fillFast() { if b.bitsRead < 32 { return } - v := b.in[len(b.in)-4:] - b.in = b.in[:len(b.in)-4] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - b.value = (b.value << 32) | uint64(low) + b.cursor -= 4 + b.value = (b.value << 32) | uint64(le.Load32(b.in, b.cursor)) b.bitsRead -= 32 } // fillFastStart() assumes the bitreader is empty and there is at least 8 bytes to read. func (b *bitReader) fillFastStart() { - v := b.in[len(b.in)-8:] - b.in = b.in[:len(b.in)-8] - b.value = binary.LittleEndian.Uint64(v) + b.cursor -= 8 + b.value = le.Load64(b.in, b.cursor) b.bitsRead = 0 } @@ -87,25 +87,23 @@ func (b *bitReader) fill() { if b.bitsRead < 32 { return } - if len(b.in) >= 4 { - v := b.in[len(b.in)-4:] - b.in = b.in[:len(b.in)-4] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - b.value = (b.value << 32) | uint64(low) + if b.cursor >= 4 { + b.cursor -= 4 + b.value = (b.value << 32) | uint64(le.Load32(b.in, b.cursor)) b.bitsRead -= 32 return } - b.bitsRead -= uint8(8 * len(b.in)) - for len(b.in) > 0 { - b.value = (b.value << 8) | uint64(b.in[len(b.in)-1]) - b.in = b.in[:len(b.in)-1] + b.bitsRead -= uint8(8 * b.cursor) + for b.cursor > 0 { + b.cursor -= 1 + b.value = (b.value << 8) | uint64(b.in[b.cursor]) } } // finished returns true if all bits have been read from the bit stream. func (b *bitReader) finished() bool { - return len(b.in) == 0 && b.bitsRead >= 64 + return b.cursor == 0 && b.bitsRead >= 64 } // overread returns true if more bits have been requested than is on the stream. @@ -115,13 +113,14 @@ func (b *bitReader) overread() bool { // remain returns the number of bits remaining. func (b *bitReader) remain() uint { - return 8*uint(len(b.in)) + 64 - uint(b.bitsRead) + return 8*uint(b.cursor) + 64 - uint(b.bitsRead) } // close the bitstream and returns an error if out-of-buffer reads occurred. func (b *bitReader) close() error { // Release reference. b.in = nil + b.cursor = 0 if !b.finished() { return fmt.Errorf("%d extra bits on block, should be 0", b.remain()) } diff --git a/vendor/github.com/klauspost/compress/zstd/bitwriter.go b/vendor/github.com/klauspost/compress/zstd/bitwriter.go index 1952f17..b22b297 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitwriter.go +++ b/vendor/github.com/klauspost/compress/zstd/bitwriter.go @@ -88,7 +88,7 @@ func (b *bitWriter) flush32() { // flushAlign will flush remaining full bytes and align to next byte boundary. func (b *bitWriter) flushAlign() { nbBytes := (b.nBits + 7) >> 3 - for i := uint8(0); i < nbBytes; i++ { + for i := range nbBytes { b.out = append(b.out, byte(b.bitContainer>>(i*8))) } b.nBits = 0 diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 9c28840..2329e99 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -5,14 +5,10 @@ package zstd import ( - "bytes" - "encoding/binary" "errors" "fmt" "hash/crc32" "io" - "os" - "path/filepath" "sync" "github.com/klauspost/compress/huff0" @@ -58,11 +54,11 @@ const ( ) var ( - huffDecoderPool = sync.Pool{New: func() interface{} { + huffDecoderPool = sync.Pool{New: func() any { return &huff0.Scratch{} }} - fseDecoderPool = sync.Pool{New: func() interface{} { + fseDecoderPool = sync.Pool{New: func() any { return &fseDecoder{} }} ) @@ -557,7 +553,7 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) { if compMode&3 != 0 { return errors.New("corrupt block: reserved bits not zero") } - for i := uint(0); i < 3; i++ { + for i := range uint(3) { mode := seqCompMode((compMode >> (6 - i*2)) & 3) if debugDecoder { println("Table", tableIndex(i), "is", mode) @@ -648,21 +644,6 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) { println("initializing sequences:", err) return err } - // Extract blocks... - if false && hist.dict == nil { - fatalErr := func(err error) { - if err != nil { - panic(err) - } - } - fn := fmt.Sprintf("n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize) - var buf bytes.Buffer - fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse)) - fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse)) - fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse)) - buf.Write(in) - os.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm) - } return nil } diff --git a/vendor/github.com/klauspost/compress/zstd/blockenc.go b/vendor/github.com/klauspost/compress/zstd/blockenc.go index 32a7f40..fd35ea1 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockenc.go +++ b/vendor/github.com/klauspost/compress/zstd/blockenc.go @@ -9,6 +9,7 @@ import ( "fmt" "math" "math/bits" + "slices" "github.com/klauspost/compress/huff0" ) @@ -457,16 +458,7 @@ func fuzzFseEncoder(data []byte) int { // All 0 return 0 } - maxCount := func(a []uint32) int { - var max uint32 - for _, v := range a { - if v > max { - max = v - } - } - return int(max) - } - cnt := maxCount(hist[:maxSym]) + cnt := int(slices.Max(hist[:maxSym])) if cnt == len(data) { // RLE return 0 @@ -884,15 +876,6 @@ func (b *blockEnc) genCodes() { } } } - maxCount := func(a []uint32) int { - var max uint32 - for _, v := range a { - if v > max { - max = v - } - } - return int(max) - } if debugAsserts && mlMax > maxMatchLengthSymbol { panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d)", mlMax)) } @@ -903,7 +886,7 @@ func (b *blockEnc) genCodes() { panic(fmt.Errorf("llMax > maxLiteralLengthSymbol (%d)", llMax)) } - b.coders.mlEnc.HistogramFinished(mlMax, maxCount(mlH[:mlMax+1])) - b.coders.ofEnc.HistogramFinished(ofMax, maxCount(ofH[:ofMax+1])) - b.coders.llEnc.HistogramFinished(llMax, maxCount(llH[:llMax+1])) + b.coders.mlEnc.HistogramFinished(mlMax, int(slices.Max(mlH[:mlMax+1]))) + b.coders.ofEnc.HistogramFinished(ofMax, int(slices.Max(ofH[:ofMax+1]))) + b.coders.llEnc.HistogramFinished(llMax, int(slices.Max(llH[:llMax+1]))) } diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index bbca172..30df551 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -123,7 +123,7 @@ func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) { } // Read bytes from the decompressed stream into p. -// Returns the number of bytes written and any error that occurred. +// Returns the number of bytes read and any error that occurred. // When the stream is done, io.EOF will be returned. func (d *Decoder) Read(p []byte) (int, error) { var n int @@ -323,6 +323,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { frame.bBuf = nil if frame.history.decoders.br != nil { frame.history.decoders.br.in = nil + frame.history.decoders.br.cursor = 0 } d.decoders <- block }() @@ -372,11 +373,9 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { if cap(dst) == 0 && !d.o.limitToCap { // Allocate len(input) * 2 by default if nothing is provided // and we didn't get frame content size. - size := len(input) * 2 - // Cap to 1 MB. - if size > 1<<20 { - size = 1 << 20 - } + size := min( + // Cap to 1 MB. + len(input)*2, 1<<20) if uint64(size) > d.o.maxDecodedSize { size = int(d.o.maxDecodedSize) } diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go index b7b8316..2ffbfdf 100644 --- a/vendor/github.com/klauspost/compress/zstd/dict.go +++ b/vendor/github.com/klauspost/compress/zstd/dict.go @@ -194,17 +194,17 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { hist := o.History contents := o.Contents debug := o.DebugOut != nil - println := func(args ...interface{}) { + println := func(args ...any) { if o.DebugOut != nil { fmt.Fprintln(o.DebugOut, args...) } } - printf := func(s string, args ...interface{}) { + printf := func(s string, args ...any) { if o.DebugOut != nil { fmt.Fprintf(o.DebugOut, s, args...) } } - print := func(args ...interface{}) { + print := func(args ...any) { if o.DebugOut != nil { fmt.Fprint(o.DebugOut, args...) } @@ -424,16 +424,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { } // Literal table - avgSize := litTotal - if avgSize > huff0.BlockSizeMax/2 { - avgSize = huff0.BlockSizeMax / 2 - } + avgSize := min(litTotal, huff0.BlockSizeMax/2) huffBuff := make([]byte, 0, avgSize) // Target size - div := litTotal / avgSize - if div < 1 { - div = 1 - } + div := max(litTotal/avgSize, 1) if debug { println("Huffman weights:") } @@ -454,7 +448,7 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { huffBuff = append(huffBuff, 255) } scratch := &huff0.Scratch{TableLog: 11} - for tries := 0; tries < 255; tries++ { + for tries := range 255 { scratch = &huff0.Scratch{TableLog: 11} _, _, err = huff0.Compress1X(huffBuff, scratch) if err == nil { @@ -471,7 +465,7 @@ func BuildDict(o BuildDictOptions) ([]byte, error) { // Bail out.... Just generate something huffBuff = append(huffBuff, bytes.Repeat([]byte{255}, 10000)...) - for i := 0; i < 128; i++ { + for i := range 128 { huffBuff = append(huffBuff, byte(i)) } continue diff --git a/vendor/github.com/klauspost/compress/zstd/enc_base.go b/vendor/github.com/klauspost/compress/zstd/enc_base.go index 5ca4603..c1192ec 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_base.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_base.go @@ -8,7 +8,7 @@ import ( ) const ( - dictShardBits = 6 + dictShardBits = 7 ) type fastBase struct { @@ -41,11 +41,9 @@ func (e *fastBase) AppendCRC(dst []byte) []byte { // or a window size small enough to contain the input size, if > 0. func (e *fastBase) WindowSize(size int64) int32 { if size > 0 && size < int64(e.maxMatchOff) { - b := int32(1) << uint(bits.Len(uint(size))) - // Keep minimum window. - if b < 1024 { - b = 1024 - } + b := max( + // Keep minimum window. + int32(1)< e.maxMatchOff { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go index 4613724..c1581cf 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_best.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -158,11 +158,9 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) { // Use this to estimate literal cost. // Scaled by 10 bits. - bitsPerByte := int32((compress.ShannonEntropyBits(src) * 1024) / len(src)) - // Huffman can never go < 1 bit/byte - if bitsPerByte < 1024 { - bitsPerByte = 1024 - } + bitsPerByte := max( + // Huffman can never go < 1 bit/byte + int32((compress.ShannonEntropyBits(src)*1024)/len(src)), 1024) // Override src src = e.hist @@ -235,10 +233,7 @@ encodeLoop: // Extend candidate match backwards as far as possible. // Do not extend repeats as we can assume they are optimal // and offsets change if s == nextEmit. - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for offset > tMin && s > nextEmit && src[offset-1] == src[s-1] && l < maxMatchLength { s-- offset-- @@ -382,10 +377,7 @@ encodeLoop: nextEmit = s // Index skipped... - end := s - if s > sLimit+4 { - end = sLimit + 4 - } + end := min(s, sLimit+4) off := index0 + e.cur for index0 < end { cv0 := load6432(src, index0) @@ -444,10 +436,7 @@ encodeLoop: nextEmit = s // Index old s + 1 -> s - 1 or sLimit - end := s - if s > sLimit-4 { - end = sLimit - 4 - } + end := min(s, sLimit-4) off := index0 + e.cur for index0 < end { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index 84a79fd..85dcd28 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -190,10 +190,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -252,10 +249,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -480,10 +474,7 @@ encodeLoop: l := matched // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- @@ -719,10 +710,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -783,10 +771,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -1005,10 +990,7 @@ encodeLoop: l := matched // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index d36be7b..cf8cad0 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -13,7 +13,7 @@ const ( dFastLongLen = 8 // Bytes used for table hash dLongTableShardCnt = 1 << (dFastLongTableBits - dictShardBits) // Number of shards in the table - dLongTableShardSize = dFastLongTableSize / tableShardCnt // Size of an individual shard + dLongTableShardSize = dFastLongTableSize / dLongTableShardCnt // Size of an individual shard dFastShortTableBits = tableBits // Bits used in the short match table dFastShortTableSize = 1 << dFastShortTableBits // Size of the table @@ -149,10 +149,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -266,10 +263,7 @@ encodeLoop: l := e.matchlen(s+4, t+4, src) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- @@ -462,10 +456,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] { repIndex-- start-- @@ -576,10 +567,7 @@ encodeLoop: l := int32(matchLen(src[s+4:], src[t+4:])) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] { s-- t-- @@ -809,10 +797,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 { repIndex-- start-- @@ -927,10 +912,7 @@ encodeLoop: l := e.matchlen(s+4, t+4, src) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index f45a3da..9180a3a 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -143,10 +143,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - sMin := s - e.maxMatchOff - if sMin < 0 { - sMin = 0 - } + sMin := max(s-e.maxMatchOff, 0) for repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch { repIndex-- start-- @@ -223,10 +220,7 @@ encodeLoop: l := e.matchlen(s+4, t+4, src) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- @@ -387,10 +381,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - sMin := s - e.maxMatchOff - if sMin < 0 { - sMin = 0 - } + sMin := max(s-e.maxMatchOff, 0) for repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] { repIndex-- start-- @@ -469,10 +460,7 @@ encodeLoop: l := e.matchlen(s+4, t+4, src) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] { s-- t-- @@ -655,10 +643,7 @@ encodeLoop: // and have to do special offset treatment. startLimit := nextEmit + 1 - sMin := s - e.maxMatchOff - if sMin < 0 { - sMin = 0 - } + sMin := max(s-e.maxMatchOff, 0) for repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch { repIndex-- start-- @@ -735,10 +720,7 @@ encodeLoop: l := e.matchlen(s+4, t+4, src) + 4 // Extend backwards - tMin := s - e.maxMatchOff - if tMin < 0 { - tMin = 0 - } + tMin := max(s-e.maxMatchOff, 0) for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength { s-- t-- diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index e47af66..d88f067 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -238,10 +238,7 @@ func (d *frameDec) reset(br byteBuffer) error { if d.WindowSize == 0 && d.SingleSegment { // We may not need window in this case. - d.WindowSize = d.FrameContentSize - if d.WindowSize < MinWindowSize { - d.WindowSize = MinWindowSize - } + d.WindowSize = max(d.FrameContentSize, MinWindowSize) if d.WindowSize > d.o.maxDecodedSize { if debugDecoder { printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) diff --git a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go index ab26326..3a0f4e7 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go @@ -149,7 +149,7 @@ func (s *fseEncoder) buildCTable() error { if v > largeLimit { s.zeroBits = true } - for nbOccurrences := int16(0); nbOccurrences < v; nbOccurrences++ { + for range v { tableSymbol[position] = symbol position = (position + step) & tableMask for position > highThreshold { diff --git a/vendor/github.com/klauspost/compress/zstd/matchlen_generic.go b/vendor/github.com/klauspost/compress/zstd/matchlen_generic.go index 57b9c31..bea1779 100644 --- a/vendor/github.com/klauspost/compress/zstd/matchlen_generic.go +++ b/vendor/github.com/klauspost/compress/zstd/matchlen_generic.go @@ -7,20 +7,25 @@ package zstd import ( - "encoding/binary" "math/bits" + + "github.com/klauspost/compress/internal/le" ) // matchLen returns the maximum common prefix length of a and b. // a must be the shortest of the two. func matchLen(a, b []byte) (n int) { - for ; len(a) >= 8 && len(b) >= 8; a, b = a[8:], b[8:] { - diff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b) + left := len(a) + for left >= 8 { + diff := le.Load64(a, n) ^ le.Load64(b, n) if diff != 0 { return n + bits.TrailingZeros64(diff)>>3 } n += 8 + left -= 8 } + a = a[n:] + b = b[n:] for i := range a { if a[i] != b[i] { diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go index d7fe6d8..0bfb0e4 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go @@ -231,10 +231,7 @@ func (s *sequenceDecs) decodeSync(hist []byte) error { llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state out := s.out - maxBlockSize := maxCompressedBlockSize - if s.windowSize < maxBlockSize { - maxBlockSize = s.windowSize - } + maxBlockSize := min(s.windowSize, maxCompressedBlockSize) if debugDecoder { println("decodeSync: decoding", seqs, "sequences", br.remain(), "bits remain on stream") @@ -245,7 +242,7 @@ func (s *sequenceDecs) decodeSync(hist []byte) error { return io.ErrUnexpectedEOF } var ll, mo, ml int - if len(br.in) > 4+((maxOffsetBits+16+16)>>3) { + if br.cursor > 4+((maxOffsetBits+16+16)>>3) { // inlined function: // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go index c59f17e..1f8c3ce 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go @@ -79,10 +79,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { br := s.br - maxBlockSize := maxCompressedBlockSize - if s.windowSize < maxBlockSize { - maxBlockSize = s.windowSize - } + maxBlockSize := min(s.windowSize, maxCompressedBlockSize) ctx := decodeSyncAsmContext{ llTable: s.litLengths.fse.dt[:maxTablesize], @@ -237,10 +234,7 @@ func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmC func (s *sequenceDecs) decode(seqs []seqVals) error { br := s.br - maxBlockSize := maxCompressedBlockSize - if s.windowSize < maxBlockSize { - maxBlockSize = s.windowSize - } + maxBlockSize := min(s.windowSize, maxCompressedBlockSize) ctx := decodeAsmContext{ llTable: s.litLengths.fse.dt[:maxTablesize], diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s index f5591fa..a708ca6 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -7,9 +7,9 @@ TEXT ·sequenceDecs_decode_amd64(SB), $8-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX - MOVBQZX 32(CX), BX + MOVBQZX 40(CX), BX MOVQ (CX), AX - MOVQ 8(CX), SI + MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX @@ -299,8 +299,8 @@ sequenceDecs_decode_amd64_match_len_ofs_ok: MOVQ R13, 160(AX) MOVQ br+8(FP), AX MOVQ DX, 24(AX) - MOVB BL, 32(AX) - MOVQ SI, 8(AX) + MOVB BL, 40(AX) + MOVQ SI, 32(AX) // Return success MOVQ $0x00000000, ret+24(FP) @@ -335,9 +335,9 @@ error_overread: TEXT ·sequenceDecs_decode_56_amd64(SB), $8-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX - MOVBQZX 32(CX), BX + MOVBQZX 40(CX), BX MOVQ (CX), AX - MOVQ 8(CX), SI + MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX @@ -598,8 +598,8 @@ sequenceDecs_decode_56_amd64_match_len_ofs_ok: MOVQ R13, 160(AX) MOVQ br+8(FP), AX MOVQ DX, 24(AX) - MOVB BL, 32(AX) - MOVQ SI, 8(AX) + MOVB BL, 40(AX) + MOVQ SI, 32(AX) // Return success MOVQ $0x00000000, ret+24(FP) @@ -634,9 +634,9 @@ error_overread: TEXT ·sequenceDecs_decode_bmi2(SB), $8-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX - MOVBQZX 32(BX), DX + MOVBQZX 40(BX), DX MOVQ (BX), CX - MOVQ 8(BX), BX + MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX @@ -884,8 +884,8 @@ sequenceDecs_decode_bmi2_match_len_ofs_ok: MOVQ R12, 160(CX) MOVQ br+8(FP), CX MOVQ AX, 24(CX) - MOVB DL, 32(CX) - MOVQ BX, 8(CX) + MOVB DL, 40(CX) + MOVQ BX, 32(CX) // Return success MOVQ $0x00000000, ret+24(FP) @@ -920,9 +920,9 @@ error_overread: TEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX - MOVBQZX 32(BX), DX + MOVBQZX 40(BX), DX MOVQ (BX), CX - MOVQ 8(BX), BX + MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX @@ -1141,8 +1141,8 @@ sequenceDecs_decode_56_bmi2_match_len_ofs_ok: MOVQ R12, 160(CX) MOVQ br+8(FP), CX MOVQ AX, 24(CX) - MOVB DL, 32(CX) - MOVQ BX, 8(CX) + MOVB DL, 40(CX) + MOVQ BX, 32(CX) // Return success MOVQ $0x00000000, ret+24(FP) @@ -1787,9 +1787,9 @@ empty_seqs: TEXT ·sequenceDecs_decodeSync_amd64(SB), $64-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX - MOVBQZX 32(CX), BX + MOVBQZX 40(CX), BX MOVQ (CX), AX - MOVQ 8(CX), SI + MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX @@ -2281,8 +2281,8 @@ handle_loop: loop_finished: MOVQ br+8(FP), AX MOVQ DX, 24(AX) - MOVB BL, 32(AX) - MOVQ SI, 8(AX) + MOVB BL, 40(AX) + MOVQ SI, 32(AX) // Update the context MOVQ ctx+16(FP), AX @@ -2349,9 +2349,9 @@ error_not_enough_space: TEXT ·sequenceDecs_decodeSync_bmi2(SB), $64-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX - MOVBQZX 32(BX), DX + MOVBQZX 40(BX), DX MOVQ (BX), CX - MOVQ 8(BX), BX + MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX @@ -2801,8 +2801,8 @@ handle_loop: loop_finished: MOVQ br+8(FP), CX MOVQ AX, 24(CX) - MOVB DL, 32(CX) - MOVQ BX, 8(CX) + MOVB DL, 40(CX) + MOVQ BX, 32(CX) // Update the context MOVQ ctx+16(FP), AX @@ -2869,9 +2869,9 @@ error_not_enough_space: TEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $64-32 MOVQ br+8(FP), CX MOVQ 24(CX), DX - MOVBQZX 32(CX), BX + MOVBQZX 40(CX), BX MOVQ (CX), AX - MOVQ 8(CX), SI + MOVQ 32(CX), SI ADDQ SI, AX MOVQ AX, (SP) MOVQ ctx+16(FP), AX @@ -3465,8 +3465,8 @@ handle_loop: loop_finished: MOVQ br+8(FP), AX MOVQ DX, 24(AX) - MOVB BL, 32(AX) - MOVQ SI, 8(AX) + MOVB BL, 40(AX) + MOVQ SI, 32(AX) // Update the context MOVQ ctx+16(FP), AX @@ -3533,9 +3533,9 @@ error_not_enough_space: TEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $64-32 MOVQ br+8(FP), BX MOVQ 24(BX), AX - MOVBQZX 32(BX), DX + MOVBQZX 40(BX), DX MOVQ (BX), CX - MOVQ 8(BX), BX + MOVQ 32(BX), BX ADDQ BX, CX MOVQ CX, (SP) MOVQ ctx+16(FP), CX @@ -4087,8 +4087,8 @@ handle_loop: loop_finished: MOVQ br+8(FP), CX MOVQ AX, 24(CX) - MOVB DL, 32(CX) - MOVQ BX, 8(CX) + MOVB DL, 40(CX) + MOVQ BX, 32(CX) // Update the context MOVQ ctx+16(FP), AX diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go index 2fb35b7..7cec219 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go @@ -29,7 +29,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error { } for i := range seqs { var ll, mo, ml int - if len(br.in) > 4+((maxOffsetBits+16+16)>>3) { + if br.cursor > 4+((maxOffsetBits+16+16)>>3) { // inlined function: // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) diff --git a/vendor/github.com/klauspost/compress/zstd/seqenc.go b/vendor/github.com/klauspost/compress/zstd/seqenc.go index 8014174..65045ea 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqenc.go +++ b/vendor/github.com/klauspost/compress/zstd/seqenc.go @@ -69,7 +69,6 @@ var llBitsTable = [maxLLCode + 1]byte{ func llCode(litLength uint32) uint8 { const llDeltaCode = 19 if litLength <= 63 { - // Compiler insists on bounds check (Go 1.12) return llCodeTable[litLength&63] } return uint8(highBit(litLength)) + llDeltaCode @@ -102,7 +101,6 @@ var mlBitsTable = [maxMLCode + 1]byte{ func mlCode(mlBase uint32) uint8 { const mlDeltaCode = 36 if mlBase <= 127 { - // Compiler insists on bounds check (Go 1.12) return mlCodeTable[mlBase&127] } return uint8(highBit(mlBase)) + mlDeltaCode diff --git a/vendor/github.com/klauspost/compress/zstd/simple_go124.go b/vendor/github.com/klauspost/compress/zstd/simple_go124.go new file mode 100644 index 0000000..2efc049 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/simple_go124.go @@ -0,0 +1,56 @@ +// Copyright 2025+ Klaus Post. All rights reserved. +// License information can be found in the LICENSE file. + +//go:build go1.24 + +package zstd + +import ( + "errors" + "runtime" + "sync" + "weak" +) + +var weakMu sync.Mutex +var simpleEnc weak.Pointer[Encoder] +var simpleDec weak.Pointer[Decoder] + +// EncodeTo appends the encoded data from src to dst. +func EncodeTo(dst []byte, src []byte) []byte { + weakMu.Lock() + enc := simpleEnc.Value() + if enc == nil { + var err error + enc, err = NewWriter(nil, WithEncoderConcurrency(runtime.NumCPU()), WithWindowSize(1<<20), WithLowerEncoderMem(true), WithZeroFrames(true)) + if err != nil { + panic("failed to create simple encoder: " + err.Error()) + } + simpleEnc = weak.Make(enc) + } + weakMu.Unlock() + + return enc.EncodeAll(src, dst) +} + +// DecodeTo appends the decoded data from src to dst. +// The maximum decoded size is 1GiB, +// not including what may already be in dst. +func DecodeTo(dst []byte, src []byte) ([]byte, error) { + weakMu.Lock() + dec := simpleDec.Value() + if dec == nil { + var err error + dec, err = NewReader(nil, WithDecoderConcurrency(runtime.NumCPU()), WithDecoderLowmem(true), WithDecoderMaxMemory(1<<30)) + if err != nil { + weakMu.Unlock() + return nil, errors.New("failed to create simple decoder: " + err.Error()) + } + runtime.SetFinalizer(dec, func(d *Decoder) { + d.Close() + }) + simpleDec = weak.Make(dec) + } + weakMu.Unlock() + return dec.DecodeAll(src, dst) +} diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go index ec13594..336c288 100644 --- a/vendor/github.com/klauspost/compress/zstd/snappy.go +++ b/vendor/github.com/klauspost/compress/zstd/snappy.go @@ -197,7 +197,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) { n, r.err = w.Write(r.block.output) if r.err != nil { - return written, err + return written, r.err } written += int64(n) continue @@ -239,7 +239,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) { } n, r.err = w.Write(r.block.output) if r.err != nil { - return written, err + return written, r.err } written += int64(n) continue @@ -257,7 +257,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) { if !r.readFull(r.buf[:len(snappyMagicBody)], false) { return written, r.err } - for i := 0; i < len(snappyMagicBody); i++ { + for i := range len(snappyMagicBody) { if r.buf[i] != snappyMagicBody[i] { println("r.buf[i] != snappyMagicBody[i]", r.buf[i], snappyMagicBody[i], i) r.err = ErrSnappyCorrupt diff --git a/vendor/github.com/klauspost/compress/zstd/zip.go b/vendor/github.com/klauspost/compress/zstd/zip.go index 29c15c8..3198d71 100644 --- a/vendor/github.com/klauspost/compress/zstd/zip.go +++ b/vendor/github.com/klauspost/compress/zstd/zip.go @@ -19,7 +19,7 @@ const ZipMethodWinZip = 93 const ZipMethodPKWare = 20 // zipReaderPool is the default reader pool. -var zipReaderPool = sync.Pool{New: func() interface{} { +var zipReaderPool = sync.Pool{New: func() any { z, err := NewReader(nil, WithDecoderLowmem(true), WithDecoderMaxWindow(128<<20), WithDecoderConcurrency(1)) if err != nil { panic(err) diff --git a/vendor/github.com/klauspost/compress/zstd/zstd.go b/vendor/github.com/klauspost/compress/zstd/zstd.go index 066bef2..1a86971 100644 --- a/vendor/github.com/klauspost/compress/zstd/zstd.go +++ b/vendor/github.com/klauspost/compress/zstd/zstd.go @@ -5,10 +5,11 @@ package zstd import ( "bytes" - "encoding/binary" "errors" "log" "math" + + "github.com/klauspost/compress/internal/le" ) // enable debug printing @@ -97,24 +98,24 @@ var ( ErrDecoderNilInput = errors.New("nil input provided as reader") ) -func println(a ...interface{}) { +func println(a ...any) { if debug || debugDecoder || debugEncoder { log.Println(a...) } } -func printf(format string, a ...interface{}) { +func printf(format string, a ...any) { if debug || debugDecoder || debugEncoder { log.Printf(format, a...) } } func load3232(b []byte, i int32) uint32 { - return binary.LittleEndian.Uint32(b[:len(b):len(b)][i:]) + return le.Load32(b, i) } func load6432(b []byte, i int32) uint64 { - return binary.LittleEndian.Uint64(b[:len(b):len(b)][i:]) + return le.Load64(b, i) } type byter interface { diff --git a/vendor/github.com/kortschak/wol/LICENSE b/vendor/github.com/kortschak/wol/LICENSE deleted file mode 100644 index adf1102..0000000 --- a/vendor/github.com/kortschak/wol/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright ©2015 Dan Kortschak. 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. - * The name of the author may not 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/kortschak/wol/README.md b/vendor/github.com/kortschak/wol/README.md deleted file mode 100644 index 99cc19c..0000000 --- a/vendor/github.com/kortschak/wol/README.md +++ /dev/null @@ -1,15 +0,0 @@ -wol implements a very simple Wake On LAN client and supporting Wake function. - -## Installation - -wol requires a [Go](http://golang.org) installation. - -## Documentation - -http://godoc.org/github.com/kortschak/wol - -## License - -wol is distributed under a modified BSD license. - - diff --git a/vendor/github.com/kortschak/wol/wol.go b/vendor/github.com/kortschak/wol/wol.go deleted file mode 100644 index 0454f52..0000000 --- a/vendor/github.com/kortschak/wol/wol.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright ©2016 Dan Kortschak. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package wol provides a Wake On LAN function. -package wol - -import ( - "bytes" - "errors" - "io" - "net" -) - -const magicLen = 6 + 16*6 - -// Wake sends a Wake On LAN magic packet for the given MAC address -// at the given remote address. If local is not nil, it is used as -// the local address for the connection to send on. -func Wake(mac net.HardwareAddr, pass []byte, local, remote *net.UDPAddr) error { - if len(mac) != 6 { - return errors.New("wol: bad MAC address") - } - switch len(pass) { - default: - return errors.New("wol: bad password length") - case 0, 6: - } - var magic [magicLen + 6]byte - copy(magic[:], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}) - buf := bytes.NewBuffer(magic[:6]) - for i := 0; i < 16; i++ { - buf.Write(mac) - } - buf.Write(pass) - if buf.Len() != magicLen+len(pass) { - panic("wol: unexpected packet length") - } - - conn, err := net.DialUDP("udp", local, remote) - if err != nil { - return err - } - defer conn.Close() - - n, err := conn.Write(buf.Bytes()) - if err != nil { - return err - } - if n < magicLen+len(pass) { - return io.ErrShortWrite - } - return nil -} diff --git a/vendor/github.com/mdlayher/genetlink/CHANGELOG.md b/vendor/github.com/mdlayher/genetlink/CHANGELOG.md deleted file mode 100644 index 0f74636..0000000 --- a/vendor/github.com/mdlayher/genetlink/CHANGELOG.md +++ /dev/null @@ -1,37 +0,0 @@ -# CHANGELOG - -## v1.3.2 - -- [Improvement]: updated dependencies, test with Go 1.20. - -# v1.3.1 - -- [Improvement]: bump package netlink to pull in big endian architecture fixes. - -# v1.3.0 - -**This is the first release of package genetlink that only supports Go 1.18+. -Users on older versions of Go must use v1.2.0.** - -- [Improvement]: drop support for older versions of Go so we can begin using - modern versions of `x/sys` and other dependencies. - -## v1.2.0 - -**This is the last release of package genetlink that supports Go 1.17 and -below.** - -- [Improvement]: pruned Go module dependencies via package `netlink` v1.6.0 and - removing tool version pins. - -## v1.1.0 - -**This is the first release of package genetlink that only supports Go 1.12+. -Users on older versions must use v1.0.0.** - -- [Improvement]: modernization of various parts of the code and documentation in - prep for future work. - -## v1.0.0 - -- Initial stable commit. diff --git a/vendor/github.com/mdlayher/genetlink/LICENSE.md b/vendor/github.com/mdlayher/genetlink/LICENSE.md deleted file mode 100644 index 12f7105..0000000 --- a/vendor/github.com/mdlayher/genetlink/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -# MIT License - -Copyright (C) 2016-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/genetlink/README.md b/vendor/github.com/mdlayher/genetlink/README.md deleted file mode 100644 index 655b667..0000000 --- a/vendor/github.com/mdlayher/genetlink/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# genetlink [![Test Status](https://github.com/mdlayher/genetlink/workflows/Linux%20Test/badge.svg)](https://github.com/mdlayher/genetlink/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/mdlayher/genetlink.svg)](https://pkg.go.dev/github.com/mdlayher/genetlink) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/genetlink)](https://goreportcard.com/report/github.com/mdlayher/genetlink) - -Package `genetlink` implements generic netlink interactions and data types. -MIT Licensed. - -For more information about how netlink and generic netlink work, -check out my blog series on [Linux, Netlink, and Go](https://mdlayher.com/blog/linux-netlink-and-go-part-1-netlink/). - -If you have any questions or you'd like some guidance, please join us on -[Gophers Slack](https://invite.slack.golangbridge.org) in the `#networking` -channel! - -## 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. diff --git a/vendor/github.com/mdlayher/genetlink/conn.go b/vendor/github.com/mdlayher/genetlink/conn.go deleted file mode 100644 index 3651592..0000000 --- a/vendor/github.com/mdlayher/genetlink/conn.go +++ /dev/null @@ -1,220 +0,0 @@ -package genetlink - -import ( - "syscall" - "time" - - "github.com/mdlayher/netlink" - "golang.org/x/net/bpf" -) - -// Protocol is the netlink protocol constant used to specify generic netlink. -const Protocol = 0x10 // unix.NETLINK_GENERIC - -// A Conn is a generic netlink connection. A Conn can be used to send and -// receive generic netlink messages to and from netlink. -// -// A Conn is safe for concurrent use, but to avoid contention in -// high-throughput applications, the caller should almost certainly create a -// pool of Conns and distribute them among workers. -type Conn struct { - // Operating system-specific netlink connection. - c *netlink.Conn -} - -// Dial dials a generic netlink connection. Config specifies optional -// configuration for the underlying netlink connection. If config is -// nil, a default configuration will be used. -func Dial(config *netlink.Config) (*Conn, error) { - c, err := netlink.Dial(Protocol, config) - if err != nil { - return nil, err - } - - return NewConn(c), nil -} - -// NewConn creates a Conn that wraps an existing *netlink.Conn for -// generic netlink communications. -// -// NewConn is primarily useful for tests. Most applications should use -// Dial instead. -func NewConn(c *netlink.Conn) *Conn { - return &Conn{c: c} -} - -// Close closes the connection and unblocks any pending read operations. -func (c *Conn) Close() error { - return c.c.Close() -} - -// GetFamily retrieves a generic netlink family with the specified name. -// -// If the family does not exist, the error value can be checked using -// `errors.Is(err, os.ErrNotExist)`. -func (c *Conn) GetFamily(name string) (Family, error) { - return c.getFamily(name) -} - -// ListFamilies retrieves all registered generic netlink families. -func (c *Conn) ListFamilies() ([]Family, error) { - return c.listFamilies() -} - -// JoinGroup joins a netlink multicast group by its ID. -func (c *Conn) JoinGroup(group uint32) error { - return c.c.JoinGroup(group) -} - -// LeaveGroup leaves a netlink multicast group by its ID. -func (c *Conn) LeaveGroup(group uint32) error { - return c.c.LeaveGroup(group) -} - -// SetBPF attaches an assembled BPF program to a Conn. -func (c *Conn) SetBPF(filter []bpf.RawInstruction) error { - return c.c.SetBPF(filter) -} - -// RemoveBPF removes a BPF filter from a Conn. -func (c *Conn) RemoveBPF() error { - return c.c.RemoveBPF() -} - -// SetOption enables or disables a netlink socket option for the Conn. -func (c *Conn) SetOption(option netlink.ConnOption, enable bool) error { - return c.c.SetOption(option, enable) -} - -// SetReadBuffer sets the size of the operating system's receive buffer -// associated with the Conn. -func (c *Conn) SetReadBuffer(bytes int) error { - return c.c.SetReadBuffer(bytes) -} - -// SetWriteBuffer sets the size of the operating system's transmit buffer -// associated with the Conn. -func (c *Conn) SetWriteBuffer(bytes int) error { - return c.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 netlink socket's file descriptor. -// -// 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) { - return c.c.SyscallConn() -} - -// SetDeadline sets the read and write deadlines associated with the connection. -func (c *Conn) SetDeadline(t time.Time) error { - return c.c.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline associated with the connection. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.c.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline associated with the connection. -func (c *Conn) SetWriteDeadline(t time.Time) error { - return c.c.SetWriteDeadline(t) -} - -// Send sends a single Message to netlink, wrapping it in a netlink.Message -// using the specified generic netlink family and flags. On success, Send -// returns a copy of the netlink.Message with all parameters populated, for -// later validation. -func (c *Conn) Send(m Message, family uint16, flags netlink.HeaderFlags) (netlink.Message, error) { - nm, err := packMessage(m, family, flags) - if err != nil { - return netlink.Message{}, err - } - - reqnm, err := c.c.Send(nm) - if err != nil { - return netlink.Message{}, err - } - - return reqnm, nil -} - -// Receive receives one or more Messages from netlink. The netlink.Messages -// used to wrap each Message are available for later validation. -func (c *Conn) Receive() ([]Message, []netlink.Message, error) { - msgs, err := c.c.Receive() - if err != nil { - return nil, nil, err - } - - gmsgs, err := unpackMessages(msgs) - if err != nil { - return nil, nil, err - } - - return gmsgs, msgs, nil -} - -// Execute sends a single Message to netlink using Send, receives one or more -// replies using Receive, and then checks the validity of the replies against -// the request using netlink.Validate. -// -// Execute acquires a lock for the duration of the function call which blocks -// concurrent calls to Send and Receive, in order to ensure consistency between -// generic netlink request/reply messages. -// -// See the documentation of Send, Receive, and netlink.Validate for details -// about each function. -func (c *Conn) Execute(m Message, family uint16, flags netlink.HeaderFlags) ([]Message, error) { - nm, err := packMessage(m, family, flags) - if err != nil { - return nil, err - } - - // Locking behavior handled by netlink.Conn.Execute. - msgs, err := c.c.Execute(nm) - if err != nil { - return nil, err - } - - return unpackMessages(msgs) -} - -// packMessage packs a generic netlink Message into a netlink.Message with the -// appropriate generic netlink family and netlink flags. -func packMessage(m Message, family uint16, flags netlink.HeaderFlags) (netlink.Message, error) { - nm := netlink.Message{ - Header: netlink.Header{ - Type: netlink.HeaderType(family), - Flags: flags, - }, - } - - mb, err := m.MarshalBinary() - if err != nil { - return netlink.Message{}, err - } - nm.Data = mb - - return nm, nil -} - -// unpackMessages unpacks generic netlink Messages from a slice of netlink.Messages. -func unpackMessages(msgs []netlink.Message) ([]Message, error) { - gmsgs := make([]Message, 0, len(msgs)) - for _, nm := range msgs { - var gm Message - if err := (&gm).UnmarshalBinary(nm.Data); err != nil { - return nil, err - } - - gmsgs = append(gmsgs, gm) - } - - return gmsgs, nil -} diff --git a/vendor/github.com/mdlayher/genetlink/doc.go b/vendor/github.com/mdlayher/genetlink/doc.go deleted file mode 100644 index 9bc3530..0000000 --- a/vendor/github.com/mdlayher/genetlink/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package genetlink implements generic netlink interactions and data types. -// -// If you have any questions or you'd like some guidance, please join us on -// Gophers Slack (https://invite.slack.golangbridge.org) in the #networking -// channel! -package genetlink diff --git a/vendor/github.com/mdlayher/genetlink/family.go b/vendor/github.com/mdlayher/genetlink/family.go deleted file mode 100644 index 680f74f..0000000 --- a/vendor/github.com/mdlayher/genetlink/family.go +++ /dev/null @@ -1,17 +0,0 @@ -package genetlink - -// A Family is a generic netlink family. -type Family struct { - ID uint16 - Version uint8 - Name string - Groups []MulticastGroup -} - -// A MulticastGroup is a generic netlink multicast group, which can be joined -// for notifications from generic netlink families when specific events take -// place. -type MulticastGroup struct { - ID uint32 - Name string -} diff --git a/vendor/github.com/mdlayher/genetlink/family_linux.go b/vendor/github.com/mdlayher/genetlink/family_linux.go deleted file mode 100644 index 8c496f5..0000000 --- a/vendor/github.com/mdlayher/genetlink/family_linux.go +++ /dev/null @@ -1,150 +0,0 @@ -//go:build linux -// +build linux - -package genetlink - -import ( - "errors" - "fmt" - "math" - - "github.com/mdlayher/netlink" - "github.com/mdlayher/netlink/nlenc" - "golang.org/x/sys/unix" -) - -// errInvalidFamilyVersion is returned when a family's version is greater -// than an 8-bit integer. -var errInvalidFamilyVersion = errors.New("invalid family version attribute") - -// getFamily retrieves a generic netlink family with the specified name. -func (c *Conn) getFamily(name string) (Family, error) { - b, err := netlink.MarshalAttributes([]netlink.Attribute{{ - Type: unix.CTRL_ATTR_FAMILY_NAME, - Data: nlenc.Bytes(name), - }}) - if err != nil { - return Family{}, err - } - - req := Message{ - Header: Header{ - Command: unix.CTRL_CMD_GETFAMILY, - // TODO(mdlayher): grab nlctrl version? - Version: 1, - }, - Data: b, - } - - msgs, err := c.Execute(req, unix.GENL_ID_CTRL, netlink.Request) - if err != nil { - return Family{}, err - } - - // TODO(mdlayher): consider interpreting generic netlink header values - - families, err := buildFamilies(msgs) - if err != nil { - return Family{}, err - } - if len(families) != 1 { - // If this were to ever happen, netlink must be in a state where - // its answers cannot be trusted - panic(fmt.Sprintf("netlink returned multiple families for name: %q", name)) - } - - return families[0], nil -} - -// listFamilies retrieves all registered generic netlink families. -func (c *Conn) listFamilies() ([]Family, error) { - req := Message{ - Header: Header{ - Command: unix.CTRL_CMD_GETFAMILY, - // TODO(mdlayher): grab nlctrl version? - Version: 1, - }, - } - - msgs, err := c.Execute(req, unix.GENL_ID_CTRL, netlink.Request|netlink.Dump) - if err != nil { - return nil, err - } - - return buildFamilies(msgs) -} - -// buildFamilies builds a slice of Families by parsing attributes from the -// input Messages. -func buildFamilies(msgs []Message) ([]Family, error) { - families := make([]Family, 0, len(msgs)) - for _, m := range msgs { - f, err := parseFamily(m.Data) - if err != nil { - return nil, err - } - - families = append(families, f) - } - - return families, nil -} - -// parseFamily decodes netlink attributes into a Family. -func parseFamily(b []byte) (Family, error) { - ad, err := netlink.NewAttributeDecoder(b) - if err != nil { - return Family{}, err - } - - var f Family - for ad.Next() { - switch ad.Type() { - case unix.CTRL_ATTR_FAMILY_ID: - f.ID = ad.Uint16() - case unix.CTRL_ATTR_FAMILY_NAME: - f.Name = ad.String() - case unix.CTRL_ATTR_VERSION: - v := ad.Uint32() - if v > math.MaxUint8 { - return Family{}, errInvalidFamilyVersion - } - - f.Version = uint8(v) - case unix.CTRL_ATTR_MCAST_GROUPS: - ad.Nested(parseMulticastGroups(&f.Groups)) - } - } - - if err := ad.Err(); err != nil { - return Family{}, err - } - - return f, nil -} - -// parseMulticastGroups parses an array of multicast group nested attributes -// into a slice of MulticastGroups. -func parseMulticastGroups(groups *[]MulticastGroup) func(*netlink.AttributeDecoder) error { - return func(ad *netlink.AttributeDecoder) error { - *groups = make([]MulticastGroup, 0, ad.Len()) - for ad.Next() { - ad.Nested(func(nad *netlink.AttributeDecoder) error { - var g MulticastGroup - for nad.Next() { - switch nad.Type() { - case unix.CTRL_ATTR_MCAST_GRP_NAME: - g.Name = nad.String() - case unix.CTRL_ATTR_MCAST_GRP_ID: - g.ID = nad.Uint32() - } - } - - *groups = append(*groups, g) - return nil - }) - } - - return nil - } -} diff --git a/vendor/github.com/mdlayher/genetlink/family_others.go b/vendor/github.com/mdlayher/genetlink/family_others.go deleted file mode 100644 index ce2a8e7..0000000 --- a/vendor/github.com/mdlayher/genetlink/family_others.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build !linux -// +build !linux - -package genetlink - -import ( - "fmt" - "runtime" -) - -// errUnimplemented is returned by all functions on platforms that -// cannot make use of generic netlink. -var errUnimplemented = fmt.Errorf("generic netlink not implemented on %s/%s", - runtime.GOOS, runtime.GOARCH) - -// getFamily always returns an error. -func (c *Conn) getFamily(name string) (Family, error) { - return Family{}, errUnimplemented -} - -// listFamilies always returns an error. -func (c *Conn) listFamilies() ([]Family, error) { - return nil, errUnimplemented -} diff --git a/vendor/github.com/mdlayher/genetlink/fuzz.go b/vendor/github.com/mdlayher/genetlink/fuzz.go deleted file mode 100644 index 8270729..0000000 --- a/vendor/github.com/mdlayher/genetlink/fuzz.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package genetlink - -func Fuzz(data []byte) int { - return fuzzMessage(data) -} - -func fuzzMessage(data []byte) int { - var m Message - if err := (&m).UnmarshalBinary(data); err != nil { - return 0 - } - - if _, err := m.MarshalBinary(); err != nil { - panic(err) - } - - return 1 -} diff --git a/vendor/github.com/mdlayher/genetlink/message.go b/vendor/github.com/mdlayher/genetlink/message.go deleted file mode 100644 index 6b34044..0000000 --- a/vendor/github.com/mdlayher/genetlink/message.go +++ /dev/null @@ -1,61 +0,0 @@ -package genetlink - -import "errors" - -// errInvalidMessage is returned when a Message is malformed. -var errInvalidMessage = errors.New("generic netlink message is invalid or too short") - -// A Header is a generic netlink header. A Header is sent and received with -// each generic netlink message to indicate metadata regarding a Message. -type Header struct { - // Command specifies a command to issue to netlink. - Command uint8 - - // Version specifies the version of a command to use. - Version uint8 -} - -// headerLen is the length of a Header. -const headerLen = 4 // unix.GENL_HDRLEN - -// A Message is a generic netlink message. It contains a Header and an -// arbitrary byte payload, which may be decoded using information from the -// Header. -// -// Data is encoded using the native endianness of the host system. Use -// the netlink.AttributeDecoder and netlink.AttributeEncoder types to decode -// and encode data. -type Message struct { - Header Header - Data []byte -} - -// MarshalBinary marshals a Message into a byte slice. -func (m Message) MarshalBinary() ([]byte, error) { - b := make([]byte, headerLen) - - b[0] = m.Header.Command - b[1] = m.Header.Version - - // b[2] and b[3] are padding bytes and set to zero - - return append(b, m.Data...), nil -} - -// UnmarshalBinary unmarshals the contents of a byte slice into a Message. -func (m *Message) UnmarshalBinary(b []byte) error { - if len(b) < headerLen { - return errInvalidMessage - } - - // Don't allow reserved pad bytes to be set - if b[2] != 0 || b[3] != 0 { - return errInvalidMessage - } - - m.Header.Command = b[0] - m.Header.Version = b[1] - - m.Data = b[4:] - return nil -} diff --git a/vendor/github.com/mdlayher/netlink/nltest/errors_others.go b/vendor/github.com/mdlayher/netlink/nltest/errors_others.go deleted file mode 100644 index 3a29c9b..0000000 --- a/vendor/github.com/mdlayher/netlink/nltest/errors_others.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build plan9 || windows -// +build plan9 windows - -package nltest - -func isSyscallError(_ error) bool { - return false -} diff --git a/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go b/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go deleted file mode 100644 index f54403b..0000000 --- a/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !plan9 && !windows -// +build !plan9,!windows - -package nltest - -import "golang.org/x/sys/unix" - -func isSyscallError(err error) bool { - _, ok := err.(unix.Errno) - return ok -} diff --git a/vendor/github.com/mdlayher/netlink/nltest/nltest.go b/vendor/github.com/mdlayher/netlink/nltest/nltest.go deleted file mode 100644 index 2065bab..0000000 --- a/vendor/github.com/mdlayher/netlink/nltest/nltest.go +++ /dev/null @@ -1,207 +0,0 @@ -// Package nltest provides utilities for netlink testing. -package nltest - -import ( - "fmt" - "io" - "os" - - "github.com/mdlayher/netlink" - "github.com/mdlayher/netlink/nlenc" -) - -// PID is the netlink header PID value assigned by nltest. -const PID = 1 - -// MustMarshalAttributes marshals a slice of netlink.Attributes to their binary -// format, but panics if any errors occur. -func MustMarshalAttributes(attrs []netlink.Attribute) []byte { - b, err := netlink.MarshalAttributes(attrs) - if err != nil { - panic(fmt.Sprintf("failed to marshal attributes to binary: %v", err)) - } - - return b -} - -// Multipart sends a slice of netlink.Messages to the caller as a -// netlink multi-part message. If less than two messages are present, -// the messages are not altered. -func Multipart(msgs []netlink.Message) ([]netlink.Message, error) { - if len(msgs) < 2 { - return msgs, nil - } - - for i := range msgs { - // Last message has header type "done" in addition to multi-part flag. - if i == len(msgs)-1 { - msgs[i].Header.Type = netlink.Done - } - - msgs[i].Header.Flags |= netlink.Multi - } - - return msgs, nil -} - -// Error returns a netlink error to the caller with the specified error -// number, in the body of the specified request message. -func Error(number int, reqs []netlink.Message) ([]netlink.Message, error) { - req := reqs[0] - req.Header.Length += 4 - req.Header.Type = netlink.Error - - errno := -1 * int32(number) - req.Data = append(nlenc.Int32Bytes(errno), req.Data...) - - return []netlink.Message{req}, nil -} - -// A Func is a function that can be used to test netlink.Conn interactions. -// The function can choose to return zero or more netlink messages, or an -// error if needed. -// -// For a netlink request/response interaction, a request req is populated by -// netlink.Conn.Send and passed to the function. -// -// For multicast interactions, an empty request req is passed to the function -// when netlink.Conn.Receive is called. -// -// If a Func returns an error, the error will be returned as-is to the caller. -// If no messages and io.EOF are returned, no messages and no error will be -// returned to the caller, simulating a multi-part message with no data. -type Func func(req []netlink.Message) ([]netlink.Message, error) - -// Dial sets up a netlink.Conn for testing using the specified Func. All requests -// sent from the connection will be passed to the Func. The connection should be -// closed as usual when it is no longer needed. -func Dial(fn Func) *netlink.Conn { - sock := &socket{ - fn: fn, - } - - return netlink.NewConn(sock, PID) -} - -// CheckRequest returns a Func that verifies that each message in an incoming -// request has the specified netlink header type and flags in the same slice -// position index, and then passes the request through to fn. -// -// The length of the types and flags slices must match the number of requests -// passed to the returned Func, or CheckRequest will panic. -// -// As an example: -// - types[0] and flags[0] will be checked against reqs[0] -// - types[1] and flags[1] will be checked against reqs[1] -// - ... and so on -// -// If an element of types or flags is set to the zero value, that check will -// be skipped for the request message that occurs at the same index. -// -// As an example, if types[0] is 0 and reqs[0].Header.Type is 1, the check will -// succeed because types[0] was not specified. -func CheckRequest(types []netlink.HeaderType, flags []netlink.HeaderFlags, fn Func) Func { - if len(types) != len(flags) { - panicf("nltest: CheckRequest called with mismatched types and flags slice lengths: %d != %d", - len(types), len(flags)) - } - - return func(req []netlink.Message) ([]netlink.Message, error) { - if len(types) != len(req) { - panicf("nltest: CheckRequest function invoked types/flags and request message slice lengths: %d != %d", - len(types), len(req)) - } - - for i := range req { - if want, got := types[i], req[i].Header.Type; types[i] != 0 && want != got { - return nil, fmt.Errorf("nltest: unexpected netlink header type: %s, want: %s", got, want) - } - - if want, got := flags[i], req[i].Header.Flags; flags[i] != 0 && want != got { - return nil, fmt.Errorf("nltest: unexpected netlink header flags: %s, want: %s", got, want) - } - } - - return fn(req) - } -} - -// A socket is a netlink.Socket used for testing. -type socket struct { - fn Func - - msgs []netlink.Message - err error -} - -func (c *socket) Close() error { return nil } - -func (c *socket) SendMessages(messages []netlink.Message) error { - msgs, err := c.fn(messages) - c.msgs = append(c.msgs, msgs...) - c.err = err - return nil -} - -func (c *socket) Send(m netlink.Message) error { - c.msgs, c.err = c.fn([]netlink.Message{m}) - return nil -} - -func (c *socket) Receive() ([]netlink.Message, error) { - // No messages set by Send means that we are emulating a - // multicast response or an error occurred. - if len(c.msgs) == 0 { - switch c.err { - case nil: - // No error, simulate multicast, but also return EOF to simulate - // no replies if needed. - msgs, err := c.fn(nil) - if err == io.EOF { - err = nil - } - - return msgs, err - case io.EOF: - // EOF, simulate no replies in multi-part message. - return nil, nil - } - - // If the error is a system call error, wrap it in os.NewSyscallError - // to simulate what the Linux netlink.Conn does. - if isSyscallError(c.err) { - return nil, os.NewSyscallError("recvmsg", c.err) - } - - // Some generic error occurred and should be passed to the caller. - return nil, c.err - } - - // Detect multi-part messages. - var multi bool - for _, m := range c.msgs { - if m.Header.Flags&netlink.Multi != 0 && m.Header.Type != netlink.Done { - multi = true - } - } - - // When a multi-part message is detected, return all messages except for the - // final "multi-part done", so that a second call to Receive from netlink.Conn - // will drain that message. - if multi { - last := c.msgs[len(c.msgs)-1] - ret := c.msgs[:len(c.msgs)-1] - c.msgs = []netlink.Message{last} - - return ret, c.err - } - - msgs, err := c.msgs, c.err - c.msgs, c.err = nil, nil - - return msgs, err -} - -func panicf(format string, a ...interface{}) { - panic(fmt.Sprintf(format, a...)) -} diff --git a/vendor/github.com/mdlayher/sdnotify/LICENSE.md b/vendor/github.com/mdlayher/sdnotify/LICENSE.md deleted file mode 100644 index 5a9bfa6..0000000 --- a/vendor/github.com/mdlayher/sdnotify/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -# MIT License - -Copyright (C) 2020-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/sdnotify/README.md b/vendor/github.com/mdlayher/sdnotify/README.md deleted file mode 100644 index 5946ef9..0000000 --- a/vendor/github.com/mdlayher/sdnotify/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# sdnotify [![Test Status](https://github.com/mdlayher/sdnotify/workflows/Test/badge.svg)](https://github.com/mdlayher/sdnotify/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/mdlayher/sdnotify.svg)](https://pkg.go.dev/github.com/mdlayher/sdnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/sdnotify)](https://goreportcard.com/report/github.com/mdlayher/sdnotify) - -Package `sdnotify` implements systemd readiness notifications as described in -https://www.freedesktop.org/software/systemd/man/sd_notify.html. MIT Licensed. diff --git a/vendor/github.com/mdlayher/sdnotify/sdnotify.go b/vendor/github.com/mdlayher/sdnotify/sdnotify.go deleted file mode 100644 index a42d632..0000000 --- a/vendor/github.com/mdlayher/sdnotify/sdnotify.go +++ /dev/null @@ -1,96 +0,0 @@ -// Package sdnotify implements systemd readiness notifications as described in -// https://www.freedesktop.org/software/systemd/man/sd_notify.html. -package sdnotify - -import ( - "fmt" - "io" - "net" - "os" - "strings" -) - -// Socket is the predefined systemd notification socket environment variable. -const Socket = "NOTIFY_SOCKET" - -// Common notification values. For a description of each, see: -// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description. -const ( - Ready = "READY=1" - Reloading = "RELOADING=1" - Stopping = "STOPPING=1" -) - -// Statusf creates a formatted STATUS notification with the input format string -// and values. -func Statusf(format string, v ...interface{}) string { - return fmt.Sprintf("STATUS=%s", fmt.Sprintf(format, v...)) -} - -// A Notifier can notify systemd of service status and readiness. Any methods -// called on a nil Notifier will result in a no-op, allowing graceful -// functionality degradation when a Go program is not running under systemd -// supervision. -type Notifier struct{ wc io.WriteCloser } - -// New creates a Notifier which sends notifications to the UNIX socket specified -// by the NOTIFY_SOCKET environment variable. See Open for more details. -func New() (*Notifier, error) { - s := os.Getenv(Socket) - if s == "" { - // Don't bother stat'ing an empty socket, just return now. - return nil, os.ErrNotExist - } - - return Open(s) -} - -// Open creates a Notifier which sends notifications to the UNIX socket -// specified by sock. -// -// If sock does not exist or is unset (meaning the service is not running under -// systemd supervision, or is not using systemd unit Type=notify), Open will -// return an error which can be checked with 'errors.Is(err, os.ErrNotExist)'. -// Calling any of the resulting nil Notifier's methods will result in a no-op. -func Open(sock string) (*Notifier, error) { - // Don't stat Linux abstract namespace sockets, as would be created with a - // net.ListenPacket with no path. - if !strings.HasPrefix(sock, "@") { - if _, err := os.Stat(sock); err != nil { - return nil, fmt.Errorf("failed to stat notify socket: %w", err) - } - } - - c, err := net.Dial("unixgram", sock) - if err != nil { - return nil, err - } - - return &Notifier{wc: c}, nil -} - -// Notify sends zero or more notifications to systemd. See the package constants -// for a list of common notifications or use the Statusf function to create a -// STATUS notification. -// -// For advanced use cases, see: -// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description. -// -// If n is nil or no strings are specified, Notify is a no-op. -func (n *Notifier) Notify(s ...string) error { - if n == nil || len(s) == 0 { - return nil - } - - _, err := io.WriteString(n.wc, strings.Join(s, "\n")) - return err -} - -// Close closes the Notifier's socket. If n is nil, Close is a no-op. -func (n *Notifier) Close() error { - if n == nil { - return nil - } - - return n.wc.Close() -} diff --git a/vendor/github.com/miekg/dns/.codecov.yml b/vendor/github.com/miekg/dns/.codecov.yml deleted file mode 100644 index f91e5c1..0000000 --- a/vendor/github.com/miekg/dns/.codecov.yml +++ /dev/null @@ -1,8 +0,0 @@ -coverage: - status: - project: - default: - target: 40% - threshold: null - patch: false - changes: false diff --git a/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/miekg/dns/.gitignore deleted file mode 100644 index 776cd95..0000000 --- a/vendor/github.com/miekg/dns/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.6 -tags -test.out -a.out diff --git a/vendor/github.com/miekg/dns/AUTHORS b/vendor/github.com/miekg/dns/AUTHORS deleted file mode 100644 index 1965683..0000000 --- a/vendor/github.com/miekg/dns/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Miek Gieben diff --git a/vendor/github.com/miekg/dns/CODEOWNERS b/vendor/github.com/miekg/dns/CODEOWNERS deleted file mode 100644 index e091703..0000000 --- a/vendor/github.com/miekg/dns/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @miekg @tmthrgd diff --git a/vendor/github.com/miekg/dns/CONTRIBUTORS b/vendor/github.com/miekg/dns/CONTRIBUTORS deleted file mode 100644 index 5903779..0000000 --- a/vendor/github.com/miekg/dns/CONTRIBUTORS +++ /dev/null @@ -1,10 +0,0 @@ -Alex A. Skinner -Andrew Tunnell-Jones -Ask Bjørn Hansen -Dave Cheney -Dusty Wilson -Marek Majkowski -Peter van Dijk -Omri Bahumi -Alex Sergeyev -James Hartig diff --git a/vendor/github.com/miekg/dns/COPYRIGHT b/vendor/github.com/miekg/dns/COPYRIGHT deleted file mode 100644 index 35702b1..0000000 --- a/vendor/github.com/miekg/dns/COPYRIGHT +++ /dev/null @@ -1,9 +0,0 @@ -Copyright 2009 The Go Authors. All rights reserved. Use of this source code -is governed by a BSD-style license that can be found in the LICENSE file. -Extensions of the original work are copyright (c) 2011 Miek Gieben - -Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is -governed by a BSD-style license that can be found in the LICENSE file. - -Copyright 2014 CloudFlare. All rights reserved. Use of this source code is -governed by a BSD-style license that can be found in the LICENSE file. diff --git a/vendor/github.com/miekg/dns/LICENSE b/vendor/github.com/miekg/dns/LICENSE deleted file mode 100644 index 852ab9c..0000000 --- a/vendor/github.com/miekg/dns/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. 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. - -3. 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/miekg/dns/Makefile.fuzz b/vendor/github.com/miekg/dns/Makefile.fuzz deleted file mode 100644 index dc158c4..0000000 --- a/vendor/github.com/miekg/dns/Makefile.fuzz +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for fuzzing -# -# Use go-fuzz and needs the tools installed. -# See https://blog.cloudflare.com/dns-parser-meet-go-fuzzer/ -# -# Installing go-fuzz: -# $ make -f Makefile.fuzz get -# Installs: -# * github.com/dvyukov/go-fuzz/go-fuzz -# * get github.com/dvyukov/go-fuzz/go-fuzz-build - -all: build - -.PHONY: build -build: - go-fuzz-build -tags fuzz github.com/miekg/dns - -.PHONY: build-newrr -build-newrr: - go-fuzz-build -func FuzzNewRR -tags fuzz github.com/miekg/dns - -.PHONY: fuzz -fuzz: - go-fuzz -bin=dns-fuzz.zip -workdir=fuzz - -.PHONY: get -get: - go get github.com/dvyukov/go-fuzz/go-fuzz - go get github.com/dvyukov/go-fuzz/go-fuzz-build - -.PHONY: clean -clean: - rm *-fuzz.zip diff --git a/vendor/github.com/miekg/dns/Makefile.release b/vendor/github.com/miekg/dns/Makefile.release deleted file mode 100644 index a0ce9b7..0000000 --- a/vendor/github.com/miekg/dns/Makefile.release +++ /dev/null @@ -1,52 +0,0 @@ -# Makefile for releasing. -# -# The release is controlled from version.go. The version found there is -# used to tag the git repo, we're not building any artifacts so there is nothing -# to upload to github. -# -# * Up the version in version.go -# * Run: make -f Makefile.release release -# * will *commit* your change with 'Release $VERSION' -# * push to github -# - -define GO -//+build ignore - -package main - -import ( - "fmt" - - "github.com/miekg/dns" -) - -func main() { - fmt.Println(dns.Version.String()) -} -endef - -$(file > version_release.go,$(GO)) -VERSION:=$(shell go run version_release.go) -TAG="v$(VERSION)" - -all: - @echo Use the \'release\' target to start a release $(VERSION) - rm -f version_release.go - -.PHONY: release -release: commit push - @echo Released $(VERSION) - rm -f version_release.go - -.PHONY: commit -commit: - @echo Committing release $(VERSION) - git commit -am"Release $(VERSION)" - git tag $(TAG) - -.PHONY: push -push: - @echo Pushing release $(VERSION) to master - git push --tags - git push diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md deleted file mode 100644 index e57d86a..0000000 --- a/vendor/github.com/miekg/dns/README.md +++ /dev/null @@ -1,195 +0,0 @@ -[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) -[![Code Coverage](https://img.shields.io/codecov/c/github/miekg/dns/master.svg)](https://codecov.io/github/miekg/dns?branch=master) -[![Go Report Card](https://goreportcard.com/badge/github.com/miekg/dns)](https://goreportcard.com/report/miekg/dns) -[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns) - -# Alternative (more granular) approach to a DNS library - -> Less is more. - -Complete and usable DNS library. All Resource Records are supported, including the DNSSEC types. -It follows a lean and mean philosophy. If there is stuff you should know as a DNS programmer there -isn't a convenience function for it. Server side and client side programming is supported, i.e. you -can build servers and resolvers with it. - -We try to keep the "master" branch as sane as possible and at the bleeding edge of standards, -avoiding breaking changes wherever reasonable. We support the last two versions of Go. - -# Goals - -* KISS; -* Fast; -* Small API. If it's easy to code in Go, don't make a function for it. - -# Users - -A not-so-up-to-date-list-that-may-be-actually-current: - -* https://github.com/coredns/coredns -* https://github.com/abh/geodns -* https://github.com/baidu/bfe -* http://www.statdns.com/ -* http://www.dnsinspect.com/ -* https://github.com/chuangbo/jianbing-dictionary-dns -* http://www.dns-lg.com/ -* https://github.com/fcambus/rrda -* https://github.com/kenshinx/godns -* https://github.com/skynetservices/skydns -* https://github.com/hashicorp/consul -* https://github.com/DevelopersPL/godnsagent -* https://github.com/duedil-ltd/discodns -* https://github.com/StalkR/dns-reverse-proxy -* https://github.com/tianon/rawdns -* https://mesosphere.github.io/mesos-dns/ -* https://github.com/fcambus/statzone -* https://github.com/benschw/dns-clb-go -* https://github.com/corny/dnscheck for -* https://github.com/miekg/unbound -* https://github.com/miekg/exdns -* https://dnslookup.org -* https://github.com/looterz/grimd -* https://github.com/phamhongviet/serf-dns -* https://github.com/mehrdadrad/mylg -* https://github.com/bamarni/dockness -* https://github.com/fffaraz/microdns -* https://github.com/ipdcode/hades -* https://github.com/StackExchange/dnscontrol/ -* https://www.dnsperf.com/ -* https://dnssectest.net/ -* https://github.com/oif/apex -* https://github.com/jedisct1/dnscrypt-proxy -* https://github.com/jedisct1/rpdns -* https://github.com/xor-gate/sshfp -* https://github.com/rs/dnstrace -* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss)) -* https://render.com -* https://github.com/peterzen/goresolver -* https://github.com/folbricht/routedns -* https://domainr.com/ -* https://zonedb.org/ -* https://router7.org/ -* https://github.com/fortio/dnsping -* https://github.com/Luzilla/dnsbl_exporter -* https://github.com/bodgit/tsig -* https://github.com/v2fly/v2ray-core (test only) -* https://kuma.io/ -* https://www.misaka.io/services/dns -* https://ping.sx/dig -* https://fleetdeck.io/ -* https://github.com/markdingo/autoreverse -* https://github.com/slackhq/nebula -* https://addr.tools/ -* https://dnscheck.tools/ -* https://github.com/egbakou/domainverifier -* https://github.com/semihalev/sdns -* https://github.com/wintbiit/NineDNS - - -Send pull request if you want to be listed here. - -# Features - -* UDP/TCP queries, IPv4 and IPv6 -* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported -* Fast -* Server side programming (mimicking the net/http package) -* Client side programming -* DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA and Ed25519 -* EDNS0, NSID, Cookies -* AXFR/IXFR -* TSIG, SIG(0) -* DNS over TLS (DoT): encrypted connection between client and server over TCP -* DNS name compression - -Have fun! - -Miek Gieben - 2010-2012 - -DNS Authors 2012- - -# Building - -This library uses Go modules and uses semantic versioning. Building is done with the `go` tool, so -the following should work: - - go get github.com/miekg/dns - go build github.com/miekg/dns - -## Examples - -A short "how to use the API" is at the beginning of doc.go (this also will show when you call `godoc -github.com/miekg/dns`). - -Example programs can be found in the `github.com/miekg/exdns` repository. - -## Supported RFCs - -*all of them* - -* 103{4,5} - DNS standard -* 1183 - ISDN, X25 and other deprecated records -* 1348 - NSAP record (removed the record) -* 1982 - Serial Arithmetic -* 1876 - LOC record -* 1995 - IXFR -* 1996 - DNS notify -* 2136 - DNS Update (dynamic updates) -* 2181 - RRset definition - there is no RRset type though, just []RR -* 2537 - RSAMD5 DNS keys -* 2065 - DNSSEC (updated in later RFCs) -* 2671 - EDNS record -* 2782 - SRV record -* 2845 - TSIG record -* 2915 - NAPTR record -* 2929 - DNS IANA Considerations -* 3110 - RSASHA1 DNS keys -* 3123 - APL record -* 3225 - DO bit (DNSSEC OK) -* 340{1,2,3} - NAPTR record -* 3445 - Limiting the scope of (DNS)KEY -* 3597 - Unknown RRs -* 4025 - A Method for Storing IPsec Keying Material in DNS -* 403{3,4,5} - DNSSEC + validation functions -* 4255 - SSHFP record -* 4343 - Case insensitivity -* 4408 - SPF record -* 4509 - SHA256 Hash in DS -* 4592 - Wildcards in the DNS -* 4635 - HMAC SHA TSIG -* 4701 - DHCID -* 4892 - id.server -* 5001 - NSID -* 5155 - NSEC3 record -* 5205 - HIP record -* 5702 - SHA2 in the DNS -* 5936 - AXFR -* 5966 - TCP implementation recommendations -* 6605 - ECDSA -* 6725 - IANA Registry Update -* 6742 - ILNP DNS -* 6840 - Clarifications and Implementation Notes for DNS Security -* 6844 - CAA record -* 6891 - EDNS0 update -* 6895 - DNS IANA considerations -* 6944 - DNSSEC DNSKEY Algorithm Status -* 6975 - Algorithm Understanding in DNSSEC -* 7043 - EUI48/EUI64 records -* 7314 - DNS (EDNS) EXPIRE Option -* 7477 - CSYNC RR -* 7828 - edns-tcp-keepalive EDNS0 Option -* 7553 - URI record -* 7858 - DNS over TLS: Initiation and Performance Considerations -* 7871 - EDNS0 Client Subnet -* 7873 - Domain Name System (DNS) Cookies -* 8080 - EdDSA for DNSSEC -* 8499 - DNS Terminology -* 8659 - DNS Certification Authority Authorization (CAA) Resource Record -* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery -* 8914 - Extended DNS Errors -* 8976 - Message Digest for DNS Zones (ZONEMD RR) - -## Loosely Based Upon - -* ldns - -* NSD - -* Net::DNS - -* GRONG - diff --git a/vendor/github.com/miekg/dns/acceptfunc.go b/vendor/github.com/miekg/dns/acceptfunc.go deleted file mode 100644 index 1a59a85..0000000 --- a/vendor/github.com/miekg/dns/acceptfunc.go +++ /dev/null @@ -1,59 +0,0 @@ -package dns - -// MsgAcceptFunc is used early in the server code to accept or reject a message with RcodeFormatError. -// It returns a MsgAcceptAction to indicate what should happen with the message. -type MsgAcceptFunc func(dh Header) MsgAcceptAction - -// DefaultMsgAcceptFunc checks the request and will reject if: -// -// * isn't a request (don't respond in that case) -// -// * opcode isn't OpcodeQuery or OpcodeNotify -// -// * does not have exactly 1 question in the question section -// -// * has more than 1 RR in the Answer section -// -// * has more than 0 RRs in the Authority section -// -// * has more than 2 RRs in the Additional section -var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc - -// MsgAcceptAction represents the action to be taken. -type MsgAcceptAction int - -// Allowed returned values from a MsgAcceptFunc. -const ( - MsgAccept MsgAcceptAction = iota // Accept the message - MsgReject // Reject the message with a RcodeFormatError - MsgIgnore // Ignore the error and send nothing back. - MsgRejectNotImplemented // Reject the message with a RcodeNotImplemented -) - -func defaultMsgAcceptFunc(dh Header) MsgAcceptAction { - if isResponse := dh.Bits&_QR != 0; isResponse { - return MsgIgnore - } - - // Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs. - opcode := int(dh.Bits>>11) & 0xF - if opcode != OpcodeQuery && opcode != OpcodeNotify { - return MsgRejectNotImplemented - } - - if dh.Qdcount != 1 { - return MsgReject - } - // NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11. - if dh.Ancount > 1 { - return MsgReject - } - // IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3. - if dh.Nscount > 1 { - return MsgReject - } - if dh.Arcount > 2 { - return MsgReject - } - return MsgAccept -} diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go deleted file mode 100644 index 9549fa9..0000000 --- a/vendor/github.com/miekg/dns/client.go +++ /dev/null @@ -1,463 +0,0 @@ -package dns - -// A client implementation. - -import ( - "context" - "crypto/tls" - "encoding/binary" - "io" - "net" - "strings" - "time" -) - -const ( - dnsTimeout time.Duration = 2 * time.Second - tcpIdleTimeout time.Duration = 8 * time.Second -) - -func isPacketConn(c net.Conn) bool { - if _, ok := c.(net.PacketConn); !ok { - return false - } - - if ua, ok := c.LocalAddr().(*net.UnixAddr); ok { - return ua.Net == "unixgram" || ua.Net == "unixpacket" - } - - return true -} - -// A Conn represents a connection to a DNS server. -type Conn struct { - net.Conn // a net.Conn holding the connection - UDPSize uint16 // minimum receive buffer for UDP messages - TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) - TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations. - tsigRequestMAC string -} - -func (co *Conn) tsigProvider() TsigProvider { - if co.TsigProvider != nil { - return co.TsigProvider - } - // tsigSecretProvider will return ErrSecret if co.TsigSecret is nil. - return tsigSecretProvider(co.TsigSecret) -} - -// A Client defines parameters for a DNS client. -type Client struct { - Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP) - UDPSize uint16 // minimum receive buffer for UDP messages - TLSConfig *tls.Config // TLS connection configuration - Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more - // Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout, - // WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and - // Client.Dialer) or context.Context.Deadline (see ExchangeContext) - Timeout time.Duration - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero - TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) - TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations. - - // SingleInflight previously serialised multiple concurrent queries for the - // same Qname, Qtype and Qclass to ensure only one would be in flight at a - // time. - // - // Deprecated: This is a no-op. Callers should implement their own in flight - // query caching if needed. See github.com/miekg/dns/issues/1449. - SingleInflight bool -} - -// Exchange performs a synchronous UDP query. It sends the message m to the address -// contained in a and waits for a reply. Exchange does not retry a failed query, nor -// will it fall back to TCP in case of truncation. -// See client.Exchange for more information on setting larger buffer sizes. -func Exchange(m *Msg, a string) (r *Msg, err error) { - client := Client{Net: "udp"} - r, _, err = client.Exchange(m, a) - return r, err -} - -func (c *Client) dialTimeout() time.Duration { - if c.Timeout != 0 { - return c.Timeout - } - if c.DialTimeout != 0 { - return c.DialTimeout - } - return dnsTimeout -} - -func (c *Client) readTimeout() time.Duration { - if c.ReadTimeout != 0 { - return c.ReadTimeout - } - return dnsTimeout -} - -func (c *Client) writeTimeout() time.Duration { - if c.WriteTimeout != 0 { - return c.WriteTimeout - } - return dnsTimeout -} - -// Dial connects to the address on the named network. -func (c *Client) Dial(address string) (conn *Conn, err error) { - return c.DialContext(context.Background(), address) -} - -// DialContext connects to the address on the named network, with a context.Context. -func (c *Client) DialContext(ctx context.Context, address string) (conn *Conn, err error) { - // create a new dialer with the appropriate timeout - var d net.Dialer - if c.Dialer == nil { - d = net.Dialer{Timeout: c.getTimeoutForRequest(c.dialTimeout())} - } else { - d = *c.Dialer - } - - network := c.Net - if network == "" { - network = "udp" - } - - useTLS := strings.HasPrefix(network, "tcp") && strings.HasSuffix(network, "-tls") - - conn = new(Conn) - if useTLS { - network = strings.TrimSuffix(network, "-tls") - - tlsDialer := tls.Dialer{ - NetDialer: &d, - Config: c.TLSConfig, - } - conn.Conn, err = tlsDialer.DialContext(ctx, network, address) - } else { - conn.Conn, err = d.DialContext(ctx, network, address) - } - if err != nil { - return nil, err - } - conn.UDPSize = c.UDPSize - return conn, nil -} - -// Exchange performs a synchronous query. It sends the message m to the address -// contained in a and waits for a reply. Basic use pattern with a *dns.Client: -// -// c := new(dns.Client) -// in, rtt, err := c.Exchange(message, "127.0.0.1:53") -// -// Exchange does not retry a failed query, nor will it fall back to TCP in -// case of truncation. -// It is up to the caller to create a message that allows for larger responses to be -// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger -// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit -// of 512 bytes -// To specify a local address or a timeout, the caller has to set the `Client.Dialer` -// attribute appropriately -func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) { - co, err := c.Dial(address) - - if err != nil { - return nil, 0, err - } - defer co.Close() - return c.ExchangeWithConn(m, co) -} - -// ExchangeWithConn has the same behavior as Exchange, just with a predetermined connection -// that will be used instead of creating a new one. -// Usage pattern with a *dns.Client: -// -// c := new(dns.Client) -// // connection management logic goes here -// -// conn := c.Dial(address) -// in, rtt, err := c.ExchangeWithConn(message, conn) -// -// This allows users of the library to implement their own connection management, -// as opposed to Exchange, which will always use new connections and incur the added overhead -// that entails when using "tcp" and especially "tcp-tls" clients. -func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) { - return c.ExchangeWithConnContext(context.Background(), m, conn) -} - -// ExchangeWithConnContext has the same behaviour as ExchangeWithConn and -// additionally obeys deadlines from the passed Context. -func (c *Client) ExchangeWithConnContext(ctx context.Context, m *Msg, co *Conn) (r *Msg, rtt time.Duration, err error) { - opt := m.IsEdns0() - // If EDNS0 is used use that for size. - if opt != nil && opt.UDPSize() >= MinMsgSize { - co.UDPSize = opt.UDPSize() - } - // Otherwise use the client's configured UDP size. - if opt == nil && c.UDPSize >= MinMsgSize { - co.UDPSize = c.UDPSize - } - - // write with the appropriate write timeout - t := time.Now() - writeDeadline := t.Add(c.getTimeoutForRequest(c.writeTimeout())) - readDeadline := t.Add(c.getTimeoutForRequest(c.readTimeout())) - if deadline, ok := ctx.Deadline(); ok { - if deadline.Before(writeDeadline) { - writeDeadline = deadline - } - if deadline.Before(readDeadline) { - readDeadline = deadline - } - } - co.SetWriteDeadline(writeDeadline) - co.SetReadDeadline(readDeadline) - - co.TsigSecret, co.TsigProvider = c.TsigSecret, c.TsigProvider - - if err = co.WriteMsg(m); err != nil { - return nil, 0, err - } - - if isPacketConn(co.Conn) { - for { - r, err = co.ReadMsg() - // Ignore replies with mismatched IDs because they might be - // responses to earlier queries that timed out. - if err != nil || r.Id == m.Id { - break - } - } - } else { - r, err = co.ReadMsg() - if err == nil && r.Id != m.Id { - err = ErrId - } - } - rtt = time.Since(t) - return r, rtt, err -} - -// ReadMsg reads a message from the connection co. -// If the received message contains a TSIG record the transaction signature -// is verified. This method always tries to return the message, however if an -// error is returned there are no guarantees that the returned message is a -// valid representation of the packet read. -func (co *Conn) ReadMsg() (*Msg, error) { - p, err := co.ReadMsgHeader(nil) - if err != nil { - return nil, err - } - - m := new(Msg) - if err := m.Unpack(p); err != nil { - // If an error was returned, we still want to allow the user to use - // the message, but naively they can just check err if they don't want - // to use an erroneous message - return m, err - } - if t := m.IsTsig(); t != nil { - // Need to work on the original message p, as that was used to calculate the tsig. - err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false) - } - return m, err -} - -// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil). -// Returns message as a byte slice to be parsed with Msg.Unpack later on. -// Note that error handling on the message body is not possible as only the header is parsed. -func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) { - var ( - p []byte - n int - err error - ) - - if isPacketConn(co.Conn) { - if co.UDPSize > MinMsgSize { - p = make([]byte, co.UDPSize) - } else { - p = make([]byte, MinMsgSize) - } - n, err = co.Read(p) - } else { - var length uint16 - if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil { - return nil, err - } - - p = make([]byte, length) - n, err = io.ReadFull(co.Conn, p) - } - - if err != nil { - return nil, err - } else if n < headerSize { - return nil, ErrShortRead - } - - p = p[:n] - if hdr != nil { - dh, _, err := unpackMsgHdr(p, 0) - if err != nil { - return nil, err - } - *hdr = dh - } - return p, err -} - -// Read implements the net.Conn read method. -func (co *Conn) Read(p []byte) (n int, err error) { - if co.Conn == nil { - return 0, ErrConnEmpty - } - - if isPacketConn(co.Conn) { - // UDP connection - return co.Conn.Read(p) - } - - var length uint16 - if err := binary.Read(co.Conn, binary.BigEndian, &length); err != nil { - return 0, err - } - if int(length) > len(p) { - return 0, io.ErrShortBuffer - } - - return io.ReadFull(co.Conn, p[:length]) -} - -// WriteMsg sends a message through the connection co. -// If the message m contains a TSIG record the transaction -// signature is calculated. -func (co *Conn) WriteMsg(m *Msg) (err error) { - var out []byte - if t := m.IsTsig(); t != nil { - // Set tsigRequestMAC for the next read, although only used in zone transfers. - out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false) - } else { - out, err = m.Pack() - } - if err != nil { - return err - } - _, err = co.Write(out) - return err -} - -// Write implements the net.Conn Write method. -func (co *Conn) Write(p []byte) (int, error) { - if len(p) > MaxMsgSize { - return 0, &Error{err: "message too large"} - } - - if isPacketConn(co.Conn) { - return co.Conn.Write(p) - } - - msg := make([]byte, 2+len(p)) - binary.BigEndian.PutUint16(msg, uint16(len(p))) - copy(msg[2:], p) - return co.Conn.Write(msg) -} - -// Return the appropriate timeout for a specific request -func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration { - var requestTimeout time.Duration - if c.Timeout != 0 { - requestTimeout = c.Timeout - } else { - requestTimeout = timeout - } - // net.Dialer.Timeout has priority if smaller than the timeouts computed so - // far - if c.Dialer != nil && c.Dialer.Timeout != 0 { - if c.Dialer.Timeout < requestTimeout { - requestTimeout = c.Dialer.Timeout - } - } - return requestTimeout -} - -// Dial connects to the address on the named network. -func Dial(network, address string) (conn *Conn, err error) { - conn = new(Conn) - conn.Conn, err = net.Dial(network, address) - if err != nil { - return nil, err - } - return conn, nil -} - -// ExchangeContext performs a synchronous UDP query, like Exchange. It -// additionally obeys deadlines from the passed Context. -func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) { - client := Client{Net: "udp"} - r, _, err = client.ExchangeContext(ctx, m, a) - // ignoring rtt to leave the original ExchangeContext API unchanged, but - // this function will go away - return r, err -} - -// ExchangeConn performs a synchronous query. It sends the message m via the connection -// c and waits for a reply. The connection c is not closed by ExchangeConn. -// Deprecated: This function is going away, but can easily be mimicked: -// -// co := &dns.Conn{Conn: c} // c is your net.Conn -// co.WriteMsg(m) -// in, _ := co.ReadMsg() -// co.Close() -func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { - println("dns: ExchangeConn: this function is deprecated") - co := new(Conn) - co.Conn = c - if err = co.WriteMsg(m); err != nil { - return nil, err - } - r, err = co.ReadMsg() - if err == nil && r.Id != m.Id { - err = ErrId - } - return r, err -} - -// DialTimeout acts like Dial but takes a timeout. -func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) { - client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}} - return client.Dial(address) -} - -// DialWithTLS connects to the address on the named network with TLS. -func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) { - if !strings.HasSuffix(network, "-tls") { - network += "-tls" - } - client := Client{Net: network, TLSConfig: tlsConfig} - return client.Dial(address) -} - -// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout. -func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) { - if !strings.HasSuffix(network, "-tls") { - network += "-tls" - } - client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig} - return client.Dial(address) -} - -// ExchangeContext acts like Exchange, but honors the deadline on the provided -// context, if present. If there is both a context deadline and a configured -// timeout on the client, the earliest of the two takes effect. -func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) { - conn, err := c.DialContext(ctx, a) - if err != nil { - return nil, 0, err - } - defer conn.Close() - - return c.ExchangeWithConnContext(ctx, m, conn) -} diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go deleted file mode 100644 index d00ac62..0000000 --- a/vendor/github.com/miekg/dns/clientconfig.go +++ /dev/null @@ -1,135 +0,0 @@ -package dns - -import ( - "bufio" - "io" - "os" - "strconv" - "strings" -) - -// ClientConfig wraps the contents of the /etc/resolv.conf file. -type ClientConfig struct { - Servers []string // servers to use - Search []string // suffixes to append to local name - Port string // what port to use - Ndots int // number of dots in name to trigger absolute lookup - Timeout int // seconds before giving up on packet - Attempts int // lost packets before giving up on server, not used in the package dns -} - -// ClientConfigFromFile parses a resolv.conf(5) like file and returns -// a *ClientConfig. -func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { - file, err := os.Open(resolvconf) - if err != nil { - return nil, err - } - defer file.Close() - return ClientConfigFromReader(file) -} - -// ClientConfigFromReader works like ClientConfigFromFile but takes an io.Reader as argument -func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) { - c := new(ClientConfig) - scanner := bufio.NewScanner(resolvconf) - c.Servers = make([]string, 0) - c.Search = make([]string, 0) - c.Port = "53" - c.Ndots = 1 - c.Timeout = 5 - c.Attempts = 2 - - for scanner.Scan() { - if err := scanner.Err(); err != nil { - return nil, err - } - line := scanner.Text() - f := strings.Fields(line) - if len(f) < 1 { - continue - } - switch f[0] { - case "nameserver": // add one name server - if len(f) > 1 { - // One more check: make sure server name is - // just an IP address. Otherwise we need DNS - // to look it up. - name := f[1] - c.Servers = append(c.Servers, name) - } - - case "domain": // set search path to just this domain - if len(f) > 1 { - c.Search = make([]string, 1) - c.Search[0] = f[1] - } else { - c.Search = make([]string, 0) - } - - case "search": // set search path to given servers - c.Search = cloneSlice(f[1:]) - - case "options": // magic options - for _, s := range f[1:] { - switch { - case len(s) >= 6 && s[:6] == "ndots:": - n, _ := strconv.Atoi(s[6:]) - if n < 0 { - n = 0 - } else if n > 15 { - n = 15 - } - c.Ndots = n - case len(s) >= 8 && s[:8] == "timeout:": - n, _ := strconv.Atoi(s[8:]) - if n < 1 { - n = 1 - } - c.Timeout = n - case len(s) >= 9 && s[:9] == "attempts:": - n, _ := strconv.Atoi(s[9:]) - if n < 1 { - n = 1 - } - c.Attempts = n - case s == "rotate": - /* not imp */ - } - } - } - } - return c, nil -} - -// NameList returns all of the names that should be queried based on the -// config. It is based off of go's net/dns name building, but it does not -// check the length of the resulting names. -func (c *ClientConfig) NameList(name string) []string { - // if this domain is already fully qualified, no append needed. - if IsFqdn(name) { - return []string{name} - } - - // Check to see if the name has more labels than Ndots. Do this before making - // the domain fully qualified. - hasNdots := CountLabel(name) > c.Ndots - // Make the domain fully qualified. - name = Fqdn(name) - - // Make a list of names based off search. - names := []string{} - - // If name has enough dots, try that first. - if hasNdots { - names = append(names, name) - } - for _, s := range c.Search { - names = append(names, Fqdn(name+s)) - } - // If we didn't have enough dots, try after suffixes. - if !hasNdots { - names = append(names, name) - } - return names -} diff --git a/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/miekg/dns/dane.go deleted file mode 100644 index 8c4a14e..0000000 --- a/vendor/github.com/miekg/dns/dane.go +++ /dev/null @@ -1,43 +0,0 @@ -package dns - -import ( - "crypto/sha256" - "crypto/sha512" - "crypto/x509" - "encoding/hex" - "errors" -) - -// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records. -func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { - switch matchingType { - case 0: - switch selector { - case 0: - return hex.EncodeToString(cert.Raw), nil - case 1: - return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil - } - case 1: - h := sha256.New() - switch selector { - case 0: - h.Write(cert.Raw) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - h.Write(cert.RawSubjectPublicKeyInfo) - return hex.EncodeToString(h.Sum(nil)), nil - } - case 2: - h := sha512.New() - switch selector { - case 0: - h.Write(cert.Raw) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - h.Write(cert.RawSubjectPublicKeyInfo) - return hex.EncodeToString(h.Sum(nil)), nil - } - } - return "", errors.New("dns: bad MatchingType or Selector") -} diff --git a/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/miekg/dns/defaults.go deleted file mode 100644 index 02d9199..0000000 --- a/vendor/github.com/miekg/dns/defaults.go +++ /dev/null @@ -1,390 +0,0 @@ -package dns - -import ( - "errors" - "net" - "strconv" - "strings" -) - -const hexDigit = "0123456789abcdef" - -// Everything is assumed in ClassINET. - -// SetReply creates a reply message from a request message. -func (dns *Msg) SetReply(request *Msg) *Msg { - dns.Id = request.Id - dns.Response = true - dns.Opcode = request.Opcode - if dns.Opcode == OpcodeQuery { - dns.RecursionDesired = request.RecursionDesired // Copy rd bit - dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit - } - dns.Rcode = RcodeSuccess - if len(request.Question) > 0 { - dns.Question = []Question{request.Question[0]} - } - return dns -} - -// SetQuestion creates a question message, it sets the Question -// section, generates an Id and sets the RecursionDesired (RD) -// bit to true. -func (dns *Msg) SetQuestion(z string, t uint16) *Msg { - dns.Id = Id() - dns.RecursionDesired = true - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, t, ClassINET} - return dns -} - -// SetNotify creates a notify message, it sets the Question -// section, generates an Id and sets the Authoritative (AA) -// bit to true. -func (dns *Msg) SetNotify(z string) *Msg { - dns.Opcode = OpcodeNotify - dns.Authoritative = true - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeSOA, ClassINET} - return dns -} - -// SetRcode creates an error message suitable for the request. -func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg { - dns.SetReply(request) - dns.Rcode = rcode - return dns -} - -// SetRcodeFormatError creates a message with FormError set. -func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg { - dns.Rcode = RcodeFormatError - dns.Opcode = OpcodeQuery - dns.Response = true - dns.Authoritative = false - dns.Id = request.Id - return dns -} - -// SetUpdate makes the message a dynamic update message. It -// sets the ZONE section to: z, TypeSOA, ClassINET. -func (dns *Msg) SetUpdate(z string) *Msg { - dns.Id = Id() - dns.Response = false - dns.Opcode = OpcodeUpdate - dns.Compress = false // BIND9 cannot handle compression - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeSOA, ClassINET} - return dns -} - -// SetIxfr creates message for requesting an IXFR. -func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg { - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Ns = make([]RR, 1) - s := new(SOA) - s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0} - s.Serial = serial - s.Ns = ns - s.Mbox = mbox - dns.Question[0] = Question{z, TypeIXFR, ClassINET} - dns.Ns[0] = s - return dns -} - -// SetAxfr creates message for requesting an AXFR. -func (dns *Msg) SetAxfr(z string) *Msg { - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeAXFR, ClassINET} - return dns -} - -// SetTsig appends a TSIG RR to the message. -// This is only a skeleton TSIG RR that is added as the last RR in the -// additional section. The TSIG is calculated when the message is being send. -func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg { - t := new(TSIG) - t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0} - t.Algorithm = algo - t.Fudge = fudge - t.TimeSigned = uint64(timesigned) - t.OrigId = dns.Id - dns.Extra = append(dns.Extra, t) - return dns -} - -// SetEdns0 appends a EDNS0 OPT RR to the message. -// TSIG should always the last RR in a message. -func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg { - e := new(OPT) - e.Hdr.Name = "." - e.Hdr.Rrtype = TypeOPT - e.SetUDPSize(udpsize) - if do { - e.SetDo() - } - dns.Extra = append(dns.Extra, e) - return dns -} - -// IsTsig checks if the message has a TSIG record as the last record -// in the additional section. It returns the TSIG record found or nil. -func (dns *Msg) IsTsig() *TSIG { - if len(dns.Extra) > 0 { - if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG { - return dns.Extra[len(dns.Extra)-1].(*TSIG) - } - } - return nil -} - -// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0 -// record in the additional section will do. It returns the OPT record -// found or nil. -func (dns *Msg) IsEdns0() *OPT { - // RFC 6891, Section 6.1.1 allows the OPT record to appear - // anywhere in the additional record section, but it's usually at - // the end so start there. - for i := len(dns.Extra) - 1; i >= 0; i-- { - if dns.Extra[i].Header().Rrtype == TypeOPT { - return dns.Extra[i].(*OPT) - } - } - return nil -} - -// popEdns0 is like IsEdns0, but it removes the record from the message. -func (dns *Msg) popEdns0() *OPT { - // RFC 6891, Section 6.1.1 allows the OPT record to appear - // anywhere in the additional record section, but it's usually at - // the end so start there. - for i := len(dns.Extra) - 1; i >= 0; i-- { - if dns.Extra[i].Header().Rrtype == TypeOPT { - opt := dns.Extra[i].(*OPT) - dns.Extra = append(dns.Extra[:i], dns.Extra[i+1:]...) - return opt - } - } - return nil -} - -// IsDomainName checks if s is a valid domain name, it returns the number of -// labels and true, when a domain name is valid. Note that non fully qualified -// domain name is considered valid, in this case the last label is counted in -// the number of labels. When false is returned the number of labels is not -// defined. Also note that this function is extremely liberal; almost any -// string is a valid domain name as the DNS is 8 bit protocol. It checks if each -// label fits in 63 characters and that the entire name will fit into the 255 -// octet wire format limit. -func IsDomainName(s string) (labels int, ok bool) { - // XXX: The logic in this function was copied from packDomainName and - // should be kept in sync with that function. - - const lenmsg = 256 - - if len(s) == 0 { // Ok, for instance when dealing with update RR without any rdata. - return 0, false - } - - s = Fqdn(s) - - // Each dot ends a segment of the name. Except for escaped dots (\.), which - // are normal dots. - - var ( - off int - begin int - wasDot bool - ) - for i := 0; i < len(s); i++ { - switch s[i] { - case '\\': - if off+1 > lenmsg { - return labels, false - } - - // check for \DDD - if isDDD(s[i+1:]) { - i += 3 - begin += 3 - } else { - i++ - begin++ - } - - wasDot = false - case '.': - if i == 0 && len(s) > 1 { - // leading dots are not legal except for the root zone - return labels, false - } - - if wasDot { - // two dots back to back is not legal - return labels, false - } - wasDot = true - - labelLen := i - begin - if labelLen >= 1<<6 { // top two bits of length must be clear - return labels, false - } - - // off can already (we're in a loop) be bigger than lenmsg - // this happens when a name isn't fully qualified - off += 1 + labelLen - if off > lenmsg { - return labels, false - } - - labels++ - begin = i + 1 - default: - wasDot = false - } - } - - return labels, true -} - -// IsSubDomain checks if child is indeed a child of the parent. If child and parent -// are the same domain true is returned as well. -func IsSubDomain(parent, child string) bool { - // Entire child is contained in parent - return CompareDomainName(parent, child) == CountLabel(parent) -} - -// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet. -// The checking is performed on the binary payload. -func IsMsg(buf []byte) error { - // Header - if len(buf) < headerSize { - return errors.New("dns: bad message header") - } - // Header: Opcode - // TODO(miek): more checks here, e.g. check all header bits. - return nil -} - -// IsFqdn checks if a domain name is fully qualified. -func IsFqdn(s string) bool { - // Check for (and remove) a trailing dot, returning if there isn't one. - if s == "" || s[len(s)-1] != '.' { - return false - } - s = s[:len(s)-1] - - // If we don't have an escape sequence before the final dot, we know it's - // fully qualified and can return here. - if s == "" || s[len(s)-1] != '\\' { - return true - } - - // Otherwise we have to check if the dot is escaped or not by checking if - // there are an odd or even number of escape sequences before the dot. - i := strings.LastIndexFunc(s, func(r rune) bool { - return r != '\\' - }) - return (len(s)-i)%2 != 0 -} - -// IsRRset reports whether a set of RRs is a valid RRset as defined by RFC 2181. -// This means the RRs need to have the same type, name, and class. -func IsRRset(rrset []RR) bool { - if len(rrset) == 0 { - return false - } - - baseH := rrset[0].Header() - for _, rr := range rrset[1:] { - curH := rr.Header() - if curH.Rrtype != baseH.Rrtype || curH.Class != baseH.Class || curH.Name != baseH.Name { - // Mismatch between the records, so this is not a valid rrset for - // signing/verifying - return false - } - } - - return true -} - -// Fqdn return the fully qualified domain name from s. -// If s is already fully qualified, it behaves as the identity function. -func Fqdn(s string) string { - if IsFqdn(s) { - return s - } - return s + "." -} - -// CanonicalName returns the domain name in canonical form. A name in canonical -// form is lowercase and fully qualified. Only US-ASCII letters are affected. See -// Section 6.2 in RFC 4034. -func CanonicalName(s string) string { - return strings.Map(func(r rune) rune { - if r >= 'A' && r <= 'Z' { - r += 'a' - 'A' - } - return r - }, Fqdn(s)) -} - -// Copied from the official Go code. - -// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP -// address suitable for reverse DNS (PTR) record lookups or an error if it fails -// to parse the IP address. -func ReverseAddr(addr string) (arpa string, err error) { - ip := net.ParseIP(addr) - if ip == nil { - return "", &Error{err: "unrecognized address: " + addr} - } - if v4 := ip.To4(); v4 != nil { - buf := make([]byte, 0, net.IPv4len*4+len("in-addr.arpa.")) - // Add it, in reverse, to the buffer - for i := len(v4) - 1; i >= 0; i-- { - buf = strconv.AppendInt(buf, int64(v4[i]), 10) - buf = append(buf, '.') - } - // Append "in-addr.arpa." and return (buf already has the final .) - buf = append(buf, "in-addr.arpa."...) - return string(buf), nil - } - // Must be IPv6 - buf := make([]byte, 0, net.IPv6len*4+len("ip6.arpa.")) - // Add it, in reverse, to the buffer - for i := len(ip) - 1; i >= 0; i-- { - v := ip[i] - buf = append(buf, hexDigit[v&0xF], '.', hexDigit[v>>4], '.') - } - // Append "ip6.arpa." and return (buf already has the final .) - buf = append(buf, "ip6.arpa."...) - return string(buf), nil -} - -// String returns the string representation for the type t. -func (t Type) String() string { - if t1, ok := TypeToString[uint16(t)]; ok { - return t1 - } - return "TYPE" + strconv.Itoa(int(t)) -} - -// String returns the string representation for the class c. -func (c Class) String() string { - if s, ok := ClassToString[uint16(c)]; ok { - // Only emit mnemonics when they are unambiguous, specially ANY is in both. - if _, ok := StringToType[s]; !ok { - return s - } - } - return "CLASS" + strconv.Itoa(int(c)) -} - -// String returns the string representation for the name n. -func (n Name) String() string { - return sprintName(string(n)) -} diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go deleted file mode 100644 index a88484b..0000000 --- a/vendor/github.com/miekg/dns/dns.go +++ /dev/null @@ -1,158 +0,0 @@ -package dns - -import ( - "encoding/hex" - "strconv" -) - -const ( - year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. - defaultTtl = 3600 // Default internal TTL. - - // DefaultMsgSize is the standard default for messages larger than 512 bytes. - DefaultMsgSize = 4096 - // MinMsgSize is the minimal size of a DNS packet. - MinMsgSize = 512 - // MaxMsgSize is the largest possible DNS packet. - MaxMsgSize = 65535 -) - -// Error represents a DNS error. -type Error struct{ err string } - -func (e *Error) Error() string { - if e == nil { - return "dns: " - } - return "dns: " + e.err -} - -// An RR represents a resource record. -type RR interface { - // Header returns the header of an resource record. The header contains - // everything up to the rdata. - Header() *RR_Header - // String returns the text representation of the resource record. - String() string - - // copy returns a copy of the RR - copy() RR - - // len returns the length (in octets) of the compressed or uncompressed RR in wire format. - // - // If compression is nil, the uncompressed size will be returned, otherwise the compressed - // size will be returned and domain names will be added to the map for future compression. - len(off int, compression map[string]struct{}) int - - // pack packs the records RDATA into wire format. The header will - // already have been packed into msg. - pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) - - // unpack unpacks an RR from wire format. - // - // This will only be called on a new and empty RR type with only the header populated. It - // will only be called if the record's RDATA is non-empty. - unpack(msg []byte, off int) (off1 int, err error) - - // parse parses an RR from zone file format. - // - // This will only be called on a new and empty RR type with only the header populated. - parse(c *zlexer, origin string) *ParseError - - // isDuplicate returns whether the two RRs are duplicates. - isDuplicate(r2 RR) bool -} - -// RR_Header is the header all DNS resource records share. -type RR_Header struct { - Name string `dns:"cdomain-name"` - Rrtype uint16 - Class uint16 - Ttl uint32 - Rdlength uint16 // Length of data after header. -} - -// Header returns itself. This is here to make RR_Header implements the RR interface. -func (h *RR_Header) Header() *RR_Header { return h } - -// Just to implement the RR interface. -func (h *RR_Header) copy() RR { return nil } - -func (h *RR_Header) String() string { - var s string - - if h.Rrtype == TypeOPT { - s = ";" - // and maybe other things - } - - s += sprintName(h.Name) + "\t" - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" - s += Class(h.Class).String() + "\t" - s += Type(h.Rrtype).String() + "\t" - return s -} - -func (h *RR_Header) len(off int, compression map[string]struct{}) int { - l := domainNameLen(h.Name, off, compression, true) - l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2) - return l -} - -func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - // RR_Header has no RDATA to pack. - return off, nil -} - -func (h *RR_Header) unpack(msg []byte, off int) (int, error) { - panic("dns: internal error: unpack should never be called on RR_Header") -} - -func (h *RR_Header) parse(c *zlexer, origin string) *ParseError { - panic("dns: internal error: parse should never be called on RR_Header") -} - -// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. -func (rr *RFC3597) ToRFC3597(r RR) error { - buf := make([]byte, Len(r)) - headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false) - if err != nil { - return err - } - buf = buf[:off] - - *rr = RFC3597{Hdr: *r.Header()} - rr.Hdr.Rdlength = uint16(off - headerEnd) - - if noRdata(rr.Hdr) { - return nil - } - - _, err = rr.unpack(buf, headerEnd) - return err -} - -// fromRFC3597 converts an unknown RR representation from RFC 3597 to the known RR type. -func (rr *RFC3597) fromRFC3597(r RR) error { - hdr := r.Header() - *hdr = rr.Hdr - - // Can't overflow uint16 as the length of Rdata is validated in (*RFC3597).parse. - // We can only get here when rr was constructed with that method. - hdr.Rdlength = uint16(hex.DecodedLen(len(rr.Rdata))) - - if noRdata(*hdr) { - // Dynamic update. - return nil - } - - // rr.pack requires an extra allocation and a copy so we just decode Rdata - // manually, it's simpler anyway. - msg, err := hex.DecodeString(rr.Rdata) - if err != nil { - return err - } - - _, err = r.unpack(msg, 0) - return err -} diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go deleted file mode 100644 index 1be87ea..0000000 --- a/vendor/github.com/miekg/dns/dnssec.go +++ /dev/null @@ -1,745 +0,0 @@ -package dns - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - _ "crypto/sha1" // need its init function - _ "crypto/sha256" // need its init function - _ "crypto/sha512" // need its init function - "encoding/asn1" - "encoding/binary" - "encoding/hex" - "math/big" - "sort" - "strings" - "time" -) - -// DNSSEC encryption algorithm codes. -const ( - _ uint8 = iota - RSAMD5 - DH - DSA - _ // Skip 4, RFC 6725, section 2.1 - RSASHA1 - DSANSEC3SHA1 - RSASHA1NSEC3SHA1 - RSASHA256 - _ // Skip 9, RFC 6725, section 2.1 - RSASHA512 - _ // Skip 11, RFC 6725, section 2.1 - ECCGOST - ECDSAP256SHA256 - ECDSAP384SHA384 - ED25519 - ED448 - INDIRECT uint8 = 252 - PRIVATEDNS uint8 = 253 // Private (experimental keys) - PRIVATEOID uint8 = 254 -) - -// AlgorithmToString is a map of algorithm IDs to algorithm names. -var AlgorithmToString = map[uint8]string{ - RSAMD5: "RSAMD5", - DH: "DH", - DSA: "DSA", - RSASHA1: "RSASHA1", - DSANSEC3SHA1: "DSA-NSEC3-SHA1", - RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1", - RSASHA256: "RSASHA256", - RSASHA512: "RSASHA512", - ECCGOST: "ECC-GOST", - ECDSAP256SHA256: "ECDSAP256SHA256", - ECDSAP384SHA384: "ECDSAP384SHA384", - ED25519: "ED25519", - ED448: "ED448", - INDIRECT: "INDIRECT", - PRIVATEDNS: "PRIVATEDNS", - PRIVATEOID: "PRIVATEOID", -} - -// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's. -// For newer algorithm that do their own hashing (i.e. ED25519) the returned value -// is 0, implying no (external) hashing should occur. The non-exported identityHash is then -// used. -var AlgorithmToHash = map[uint8]crypto.Hash{ - RSAMD5: crypto.MD5, // Deprecated in RFC 6725 - DSA: crypto.SHA1, - RSASHA1: crypto.SHA1, - RSASHA1NSEC3SHA1: crypto.SHA1, - RSASHA256: crypto.SHA256, - ECDSAP256SHA256: crypto.SHA256, - ECDSAP384SHA384: crypto.SHA384, - RSASHA512: crypto.SHA512, - ED25519: 0, -} - -// DNSSEC hashing algorithm codes. -const ( - _ uint8 = iota - SHA1 // RFC 4034 - SHA256 // RFC 4509 - GOST94 // RFC 5933 - SHA384 // Experimental - SHA512 // Experimental -) - -// HashToString is a map of hash IDs to names. -var HashToString = map[uint8]string{ - SHA1: "SHA1", - SHA256: "SHA256", - GOST94: "GOST94", - SHA384: "SHA384", - SHA512: "SHA512", -} - -// DNSKEY flag values. -const ( - SEP = 1 - REVOKE = 1 << 7 - ZONE = 1 << 8 -) - -// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing. -type rrsigWireFmt struct { - TypeCovered uint16 - Algorithm uint8 - Labels uint8 - OrigTtl uint32 - Expiration uint32 - Inception uint32 - KeyTag uint16 - SignerName string `dns:"domain-name"` - /* No Signature */ -} - -// Used for converting DNSKEY's rdata to wirefmt. -type dnskeyWireFmt struct { - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` - /* Nothing is left out */ -} - -// KeyTag calculates the keytag (or key-id) of the DNSKEY. -func (k *DNSKEY) KeyTag() uint16 { - if k == nil { - return 0 - } - var keytag int - switch k.Algorithm { - case RSAMD5: - // This algorithm has been deprecated, but keep this key-tag calculation. - // Look at the bottom two bytes of the modules, which the last item in the pubkey. - // See https://www.rfc-editor.org/errata/eid193 . - modulus, _ := fromBase64([]byte(k.PublicKey)) - if len(modulus) > 1 { - x := binary.BigEndian.Uint16(modulus[len(modulus)-3:]) - keytag = int(x) - } - default: - keywire := new(dnskeyWireFmt) - keywire.Flags = k.Flags - keywire.Protocol = k.Protocol - keywire.Algorithm = k.Algorithm - keywire.PublicKey = k.PublicKey - wire := make([]byte, DefaultMsgSize) - n, err := packKeyWire(keywire, wire) - if err != nil { - return 0 - } - wire = wire[:n] - for i, v := range wire { - if i&1 != 0 { - keytag += int(v) // must be larger than uint32 - } else { - keytag += int(v) << 8 - } - } - keytag += keytag >> 16 & 0xFFFF - keytag &= 0xFFFF - } - return uint16(keytag) -} - -// ToDS converts a DNSKEY record to a DS record. -func (k *DNSKEY) ToDS(h uint8) *DS { - if k == nil { - return nil - } - ds := new(DS) - ds.Hdr.Name = k.Hdr.Name - ds.Hdr.Class = k.Hdr.Class - ds.Hdr.Rrtype = TypeDS - ds.Hdr.Ttl = k.Hdr.Ttl - ds.Algorithm = k.Algorithm - ds.DigestType = h - ds.KeyTag = k.KeyTag() - - keywire := new(dnskeyWireFmt) - keywire.Flags = k.Flags - keywire.Protocol = k.Protocol - keywire.Algorithm = k.Algorithm - keywire.PublicKey = k.PublicKey - wire := make([]byte, DefaultMsgSize) - n, err := packKeyWire(keywire, wire) - if err != nil { - return nil - } - wire = wire[:n] - - owner := make([]byte, 255) - off, err1 := PackDomainName(CanonicalName(k.Hdr.Name), owner, 0, nil, false) - if err1 != nil { - return nil - } - owner = owner[:off] - // RFC4034: - // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); - // "|" denotes concatenation - // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. - - var hash crypto.Hash - switch h { - case SHA1: - hash = crypto.SHA1 - case SHA256: - hash = crypto.SHA256 - case SHA384: - hash = crypto.SHA384 - case SHA512: - hash = crypto.SHA512 - default: - return nil - } - - s := hash.New() - s.Write(owner) - s.Write(wire) - ds.Digest = hex.EncodeToString(s.Sum(nil)) - return ds -} - -// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record. -func (k *DNSKEY) ToCDNSKEY() *CDNSKEY { - c := &CDNSKEY{DNSKEY: *k} - c.Hdr = k.Hdr - c.Hdr.Rrtype = TypeCDNSKEY - return c -} - -// ToCDS converts a DS record to a CDS record. -func (d *DS) ToCDS() *CDS { - c := &CDS{DS: *d} - c.Hdr = d.Hdr - c.Hdr.Rrtype = TypeCDS - return c -} - -// Sign signs an RRSet. The signature needs to be filled in with the values: -// Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied -// from the RRset. Sign returns a non-nill error when the signing went OK. -// There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non -// zero, it is used as-is, otherwise the TTL of the RRset is used as the -// OrigTTL. -func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { - if k == nil { - return ErrPrivKey - } - // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { - return ErrKey - } - - h0 := rrset[0].Header() - rr.Hdr.Rrtype = TypeRRSIG - rr.Hdr.Name = h0.Name - rr.Hdr.Class = h0.Class - if rr.OrigTtl == 0 { // If set don't override - rr.OrigTtl = h0.Ttl - } - rr.TypeCovered = h0.Rrtype - rr.Labels = uint8(CountLabel(h0.Name)) - - if strings.HasPrefix(h0.Name, "*") { - rr.Labels-- // wildcard, remove from label count - } - - sigwire := new(rrsigWireFmt) - sigwire.TypeCovered = rr.TypeCovered - sigwire.Algorithm = rr.Algorithm - sigwire.Labels = rr.Labels - sigwire.OrigTtl = rr.OrigTtl - sigwire.Expiration = rr.Expiration - sigwire.Inception = rr.Inception - sigwire.KeyTag = rr.KeyTag - // For signing, lowercase this name - sigwire.SignerName = CanonicalName(rr.SignerName) - - // Create the desired binary blob - signdata := make([]byte, DefaultMsgSize) - n, err := packSigWire(sigwire, signdata) - if err != nil { - return err - } - signdata = signdata[:n] - wire, err := rawSignatureData(rrset, rr) - if err != nil { - return err - } - - h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) - if err != nil { - return err - } - - switch rr.Algorithm { - case RSAMD5, DSA, DSANSEC3SHA1: - // See RFC 6944. - return ErrAlg - default: - h.Write(signdata) - h.Write(wire) - - signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm) - if err != nil { - return err - } - - rr.Signature = toBase64(signature) - return nil - } -} - -func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) { - signature, err := k.Sign(rand.Reader, hashed, hash) - if err != nil { - return nil, err - } - - switch alg { - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519: - return signature, nil - case ECDSAP256SHA256, ECDSAP384SHA384: - ecdsaSignature := &struct { - R, S *big.Int - }{} - if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil { - return nil, err - } - - var intlen int - switch alg { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - - signature := intToBytes(ecdsaSignature.R, intlen) - signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...) - return signature, nil - default: - return nil, ErrAlg - } -} - -// Verify validates an RRSet with the signature and key. This is only the -// cryptographic test, the signature validity period must be checked separately. -// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. -// It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY -// and that the Protocol field is set to 3 (RFC 4034 2.1.2). -func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { - // First the easy checks - if !IsRRset(rrset) { - return ErrRRset - } - if rr.KeyTag != k.KeyTag() { - return ErrKey - } - if rr.Hdr.Class != k.Hdr.Class { - return ErrKey - } - if rr.Algorithm != k.Algorithm { - return ErrKey - } - if !strings.EqualFold(rr.SignerName, k.Hdr.Name) { - return ErrKey - } - if k.Protocol != 3 { - return ErrKey - } - // RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some - // other type of DNS public key and MUST NOT be used to verify RRSIGs that - // cover RRsets. - if k.Flags&ZONE == 0 { - return ErrKey - } - - // IsRRset checked that we have at least one RR and that the RRs in - // the set have consistent type, class, and name. Also check that type and - // class matches the RRSIG record. - if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered { - return ErrRRset - } - - // RFC 4035 5.3.2. Reconstructing the Signed Data - // Copy the sig, except the rrsig data - sigwire := new(rrsigWireFmt) - sigwire.TypeCovered = rr.TypeCovered - sigwire.Algorithm = rr.Algorithm - sigwire.Labels = rr.Labels - sigwire.OrigTtl = rr.OrigTtl - sigwire.Expiration = rr.Expiration - sigwire.Inception = rr.Inception - sigwire.KeyTag = rr.KeyTag - sigwire.SignerName = CanonicalName(rr.SignerName) - // Create the desired binary blob - signeddata := make([]byte, DefaultMsgSize) - n, err := packSigWire(sigwire, signeddata) - if err != nil { - return err - } - signeddata = signeddata[:n] - wire, err := rawSignatureData(rrset, rr) - if err != nil { - return err - } - - sigbuf := rr.sigBuf() // Get the binary signature data - // TODO(miek) - // remove the domain name and assume its ours? - // if rr.Algorithm == PRIVATEDNS { // PRIVATEOID - // } - - h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) - if err != nil { - return err - } - - switch rr.Algorithm { - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: - // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere?? - pubkey := k.publicKeyRSA() // Get the key - if pubkey == nil { - return ErrKey - } - - h.Write(signeddata) - h.Write(wire) - return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf) - - case ECDSAP256SHA256, ECDSAP384SHA384: - pubkey := k.publicKeyECDSA() - if pubkey == nil { - return ErrKey - } - - // Split sigbuf into the r and s coordinates - r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2]) - s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:]) - - h.Write(signeddata) - h.Write(wire) - if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { - return nil - } - return ErrSig - - case ED25519: - pubkey := k.publicKeyED25519() - if pubkey == nil { - return ErrKey - } - - if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) { - return nil - } - return ErrSig - - default: - return ErrAlg - } -} - -// ValidityPeriod uses RFC1982 serial arithmetic to calculate -// if a signature period is valid. If t is the zero time, the -// current time is taken other t is. Returns true if the signature -// is valid at the given time, otherwise returns false. -func (rr *RRSIG) ValidityPeriod(t time.Time) bool { - var utc int64 - if t.IsZero() { - utc = time.Now().UTC().Unix() - } else { - utc = t.UTC().Unix() - } - modi := (int64(rr.Inception) - utc) / year68 - mode := (int64(rr.Expiration) - utc) / year68 - ti := int64(rr.Inception) + modi*year68 - te := int64(rr.Expiration) + mode*year68 - return ti <= utc && utc <= te -} - -// Return the signatures base64 encoding sigdata as a byte slice. -func (rr *RRSIG) sigBuf() []byte { - sigbuf, err := fromBase64([]byte(rr.Signature)) - if err != nil { - return nil - } - return sigbuf -} - -// publicKeyRSA returns the RSA public key from a DNSKEY record. -func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - - if len(keybuf) < 1+1+64 { - // Exponent must be at least 1 byte and modulus at least 64 - return nil - } - - // RFC 2537/3110, section 2. RSA Public KEY Resource Records - // Length is in the 0th byte, unless its zero, then it - // it in bytes 1 and 2 and its a 16 bit number - explen := uint16(keybuf[0]) - keyoff := 1 - if explen == 0 { - explen = uint16(keybuf[1])<<8 | uint16(keybuf[2]) - keyoff = 3 - } - - if explen > 4 || explen == 0 || keybuf[keyoff] == 0 { - // Exponent larger than supported by the crypto package, - // empty, or contains prohibited leading zero. - return nil - } - - modoff := keyoff + int(explen) - modlen := len(keybuf) - modoff - if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 { - // Modulus is too small, large, or contains prohibited leading zero. - return nil - } - - pubkey := new(rsa.PublicKey) - - var expo uint64 - // The exponent of length explen is between keyoff and modoff. - for _, v := range keybuf[keyoff:modoff] { - expo <<= 8 - expo |= uint64(v) - } - if expo > 1<<31-1 { - // Larger exponent than supported by the crypto package. - return nil - } - - pubkey.E = int(expo) - pubkey.N = new(big.Int).SetBytes(keybuf[modoff:]) - return pubkey -} - -// publicKeyECDSA returns the Curve public key from the DNSKEY record. -func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - pubkey := new(ecdsa.PublicKey) - switch k.Algorithm { - case ECDSAP256SHA256: - pubkey.Curve = elliptic.P256() - if len(keybuf) != 64 { - // wrongly encoded key - return nil - } - case ECDSAP384SHA384: - pubkey.Curve = elliptic.P384() - if len(keybuf) != 96 { - // Wrongly encoded key - return nil - } - } - pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2]) - pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:]) - return pubkey -} - -func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - if len(keybuf) != ed25519.PublicKeySize { - return nil - } - return keybuf -} - -type wireSlice [][]byte - -func (p wireSlice) Len() int { return len(p) } -func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p wireSlice) Less(i, j int) bool { - _, ioff, _ := UnpackDomainName(p[i], 0) - _, joff, _ := UnpackDomainName(p[j], 0) - return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0 -} - -// Return the raw signature data. -func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) { - wires := make(wireSlice, len(rrset)) - for i, r := range rrset { - r1 := r.copy() - h := r1.Header() - h.Ttl = s.OrigTtl - labels := SplitDomainName(h.Name) - // 6.2. Canonical RR Form. (4) - wildcards - if len(labels) > int(s.Labels) { - // Wildcard - h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "." - } - // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase - h.Name = CanonicalName(h.Name) - // 6.2. Canonical RR Form. (3) - domain rdata to lowercase. - // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR, - // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX, - // SRV, DNAME, A6 - // - // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC): - // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record - // that needs conversion to lowercase, and twice at that. Since HINFO - // records contain no domain names, they are not subject to case - // conversion. - switch x := r1.(type) { - case *NS: - x.Ns = CanonicalName(x.Ns) - case *MD: - x.Md = CanonicalName(x.Md) - case *MF: - x.Mf = CanonicalName(x.Mf) - case *CNAME: - x.Target = CanonicalName(x.Target) - case *SOA: - x.Ns = CanonicalName(x.Ns) - x.Mbox = CanonicalName(x.Mbox) - case *MB: - x.Mb = CanonicalName(x.Mb) - case *MG: - x.Mg = CanonicalName(x.Mg) - case *MR: - x.Mr = CanonicalName(x.Mr) - case *PTR: - x.Ptr = CanonicalName(x.Ptr) - case *MINFO: - x.Rmail = CanonicalName(x.Rmail) - x.Email = CanonicalName(x.Email) - case *MX: - x.Mx = CanonicalName(x.Mx) - case *RP: - x.Mbox = CanonicalName(x.Mbox) - x.Txt = CanonicalName(x.Txt) - case *AFSDB: - x.Hostname = CanonicalName(x.Hostname) - case *RT: - x.Host = CanonicalName(x.Host) - case *SIG: - x.SignerName = CanonicalName(x.SignerName) - case *PX: - x.Map822 = CanonicalName(x.Map822) - x.Mapx400 = CanonicalName(x.Mapx400) - case *NAPTR: - x.Replacement = CanonicalName(x.Replacement) - case *KX: - x.Exchanger = CanonicalName(x.Exchanger) - case *SRV: - x.Target = CanonicalName(x.Target) - case *DNAME: - x.Target = CanonicalName(x.Target) - } - // 6.2. Canonical RR Form. (5) - origTTL - wire := make([]byte, Len(r1)+1) // +1 to be safe(r) - off, err1 := PackRR(r1, wire, 0, nil, false) - if err1 != nil { - return nil, err1 - } - wire = wire[:off] - wires[i] = wire - } - sort.Sort(wires) - for i, wire := range wires { - if i > 0 && bytes.Equal(wire, wires[i-1]) { - continue - } - buf = append(buf, wire...) - } - return buf, nil -} - -func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) { - // copied from zmsg.go RRSIG packing - off, err := packUint16(sw.TypeCovered, msg, 0) - if err != nil { - return off, err - } - off, err = packUint8(sw.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(sw.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(sw.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(sw.SignerName, msg, off, nil, false) - if err != nil { - return off, err - } - return off, nil -} - -func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) { - // copied from zmsg.go DNSKEY packing - off, err := packUint16(dw.Flags, msg, 0) - if err != nil { - return off, err - } - off, err = packUint8(dw.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(dw.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(dw.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go deleted file mode 100644 index b8124b5..0000000 --- a/vendor/github.com/miekg/dns/dnssec_keygen.go +++ /dev/null @@ -1,139 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "math/big" -) - -// Generate generates a DNSKEY of the given bit size. -// The public part is put inside the DNSKEY record. -// The Algorithm in the key must be set as this will define -// what kind of DNSKEY will be generated. -// The ECDSA algorithms imply a fixed keysize, in that case -// bits should be set to the size of the algorithm. -func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) { - switch k.Algorithm { - case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1: - if bits < 512 || bits > 4096 { - return nil, ErrKeySize - } - case RSASHA512: - if bits < 1024 || bits > 4096 { - return nil, ErrKeySize - } - case ECDSAP256SHA256: - if bits != 256 { - return nil, ErrKeySize - } - case ECDSAP384SHA384: - if bits != 384 { - return nil, ErrKeySize - } - case ED25519: - if bits != 256 { - return nil, ErrKeySize - } - default: - return nil, ErrAlg - } - - switch k.Algorithm { - case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1: - priv, err := rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return nil, err - } - k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N) - return priv, nil - case ECDSAP256SHA256, ECDSAP384SHA384: - var c elliptic.Curve - switch k.Algorithm { - case ECDSAP256SHA256: - c = elliptic.P256() - case ECDSAP384SHA384: - c = elliptic.P384() - } - priv, err := ecdsa.GenerateKey(c, rand.Reader) - if err != nil { - return nil, err - } - k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y) - return priv, nil - case ED25519: - pub, priv, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, err - } - k.setPublicKeyED25519(pub) - return priv, nil - default: - return nil, ErrAlg - } -} - -// Set the public key (the value E and N) -func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool { - if _E == 0 || _N == nil { - return false - } - buf := exponentToBuf(_E) - buf = append(buf, _N.Bytes()...) - k.PublicKey = toBase64(buf) - return true -} - -// Set the public key for Elliptic Curves -func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool { - if _X == nil || _Y == nil { - return false - } - var intlen int - switch k.Algorithm { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen)) - return true -} - -// Set the public key for Ed25519 -func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool { - if _K == nil { - return false - } - k.PublicKey = toBase64(_K) - return true -} - -// Set the public key (the values E and N) for RSA -// RFC 3110: Section 2. RSA Public KEY Resource Records -func exponentToBuf(_E int) []byte { - var buf []byte - i := big.NewInt(int64(_E)).Bytes() - if len(i) < 256 { - buf = make([]byte, 1, 1+len(i)) - buf[0] = uint8(len(i)) - } else { - buf = make([]byte, 3, 3+len(i)) - buf[0] = 0 - buf[1] = uint8(len(i) >> 8) - buf[2] = uint8(len(i)) - } - buf = append(buf, i...) - return buf -} - -// Set the public key for X and Y for Curve. The two -// values are just concatenated. -func curveToBuf(_X, _Y *big.Int, intlen int) []byte { - buf := intToBytes(_X, intlen) - buf = append(buf, intToBytes(_Y, intlen)...) - return buf -} diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go deleted file mode 100644 index 9c9972d..0000000 --- a/vendor/github.com/miekg/dns/dnssec_keyscan.go +++ /dev/null @@ -1,310 +0,0 @@ -package dns - -import ( - "bufio" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "io" - "math/big" - "strconv" - "strings" -) - -// NewPrivateKey returns a PrivateKey by parsing the string s. -// s should be in the same form of the BIND private key files. -func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { - if s == "" || s[len(s)-1] != '\n' { // We need a closing newline - return k.ReadPrivateKey(strings.NewReader(s+"\n"), "") - } - return k.ReadPrivateKey(strings.NewReader(s), "") -} - -// ReadPrivateKey reads a private key from the io.Reader q. The string file is -// only used in error reporting. -// The public key must be known, because some cryptographic algorithms embed -// the public inside the privatekey. -func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) { - m, err := parseKey(q, file) - if m == nil { - return nil, err - } - if _, ok := m["private-key-format"]; !ok { - return nil, ErrPrivKey - } - if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" { - return nil, ErrPrivKey - } - // TODO(mg): check if the pubkey matches the private key - algoStr, _, _ := strings.Cut(m["algorithm"], " ") - algo, err := strconv.ParseUint(algoStr, 10, 8) - if err != nil { - return nil, ErrPrivKey - } - switch uint8(algo) { - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: - priv, err := readPrivateKeyRSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyRSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - case ECDSAP256SHA256, ECDSAP384SHA384: - priv, err := readPrivateKeyECDSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyECDSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - case ED25519: - return readPrivateKeyED25519(m) - default: - return nil, ErrAlg - } -} - -// Read a private key (file) string and create a public key. Return the private key. -func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) { - p := new(rsa.PrivateKey) - p.Primes = []*big.Int{nil, nil} - for k, v := range m { - switch k { - case "modulus", "publicexponent", "privateexponent", "prime1", "prime2": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - switch k { - case "modulus": - p.PublicKey.N = new(big.Int).SetBytes(v1) - case "publicexponent": - i := new(big.Int).SetBytes(v1) - p.PublicKey.E = int(i.Int64()) // int64 should be large enough - case "privateexponent": - p.D = new(big.Int).SetBytes(v1) - case "prime1": - p.Primes[0] = new(big.Int).SetBytes(v1) - case "prime2": - p.Primes[1] = new(big.Int).SetBytes(v1) - } - case "exponent1", "exponent2", "coefficient": - // not used in Go (yet) - case "created", "publish", "activate": - // not used in Go (yet) - } - } - return p, nil -} - -func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) { - p := new(ecdsa.PrivateKey) - p.D = new(big.Int) - // TODO: validate that the required flags are present - for k, v := range m { - switch k { - case "privatekey": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - p.D.SetBytes(v1) - case "created", "publish", "activate": - /* not used in Go (yet) */ - } - } - return p, nil -} - -func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) { - var p ed25519.PrivateKey - // TODO: validate that the required flags are present - for k, v := range m { - switch k { - case "privatekey": - p1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - if len(p1) != ed25519.SeedSize { - return nil, ErrPrivKey - } - p = ed25519.NewKeyFromSeed(p1) - case "created", "publish", "activate": - /* not used in Go (yet) */ - } - } - return p, nil -} - -// parseKey reads a private key from r. It returns a map[string]string, -// with the key-value pairs, or an error when the file is not correct. -func parseKey(r io.Reader, file string) (map[string]string, error) { - m := make(map[string]string) - var k string - - c := newKLexer(r) - - for l, ok := c.Next(); ok; l, ok = c.Next() { - // It should alternate - switch l.value { - case zKey: - k = l.token - case zValue: - if k == "" { - return nil, &ParseError{file: file, err: "no private key seen", lex: l} - } - - m[strings.ToLower(k)] = l.token - k = "" - } - } - - // Surface any read errors from r. - if err := c.Err(); err != nil { - return nil, &ParseError{file: file, err: err.Error()} - } - - return m, nil -} - -type klexer struct { - br io.ByteReader - - readErr error - - line int - column int - - key bool - - eol bool // end-of-line -} - -func newKLexer(r io.Reader) *klexer { - br, ok := r.(io.ByteReader) - if !ok { - br = bufio.NewReaderSize(r, 1024) - } - - return &klexer{ - br: br, - - line: 1, - - key: true, - } -} - -func (kl *klexer) Err() error { - if kl.readErr == io.EOF { - return nil - } - - return kl.readErr -} - -// readByte returns the next byte from the input -func (kl *klexer) readByte() (byte, bool) { - if kl.readErr != nil { - return 0, false - } - - c, err := kl.br.ReadByte() - if err != nil { - kl.readErr = err - return 0, false - } - - // delay the newline handling until the next token is delivered, - // fixes off-by-one errors when reporting a parse error. - if kl.eol { - kl.line++ - kl.column = 0 - kl.eol = false - } - - if c == '\n' { - kl.eol = true - } else { - kl.column++ - } - - return c, true -} - -func (kl *klexer) Next() (lex, bool) { - var ( - l lex - - str strings.Builder - - commt bool - ) - - for x, ok := kl.readByte(); ok; x, ok = kl.readByte() { - l.line, l.column = kl.line, kl.column - - switch x { - case ':': - if commt || !kl.key { - break - } - - kl.key = false - - // Next token is a space, eat it - kl.readByte() - - l.value = zKey - l.token = str.String() - return l, true - case ';': - commt = true - case '\n': - if commt { - // Reset a comment - commt = false - } - - if kl.key && str.Len() == 0 { - // ignore empty lines - break - } - - kl.key = true - - l.value = zValue - l.token = str.String() - return l, true - default: - if commt { - break - } - - str.WriteByte(x) - } - } - - if kl.readErr != nil && kl.readErr != io.EOF { - // Don't return any tokens after a read error occurs. - return lex{value: zEOF}, false - } - - if str.Len() > 0 { - // Send remainder - l.value = zValue - l.token = str.String() - return l, true - } - - return lex{value: zEOF}, false -} diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go deleted file mode 100644 index f160772..0000000 --- a/vendor/github.com/miekg/dns/dnssec_privkey.go +++ /dev/null @@ -1,77 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "math/big" - "strconv" -) - -const format = "Private-key-format: v1.3\n" - -var bigIntOne = big.NewInt(1) - -// PrivateKeyString converts a PrivateKey to a string. This string has the same -// format as the private-key-file of BIND9 (Private-key-format: v1.3). -// It needs some info from the key (the algorithm), so its a method of the DNSKEY. -// It supports *rsa.PrivateKey, *ecdsa.PrivateKey and ed25519.PrivateKey. -func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string { - algorithm := strconv.Itoa(int(r.Algorithm)) - algorithm += " (" + AlgorithmToString[r.Algorithm] + ")" - - switch p := p.(type) { - case *rsa.PrivateKey: - modulus := toBase64(p.PublicKey.N.Bytes()) - e := big.NewInt(int64(p.PublicKey.E)) - publicExponent := toBase64(e.Bytes()) - privateExponent := toBase64(p.D.Bytes()) - prime1 := toBase64(p.Primes[0].Bytes()) - prime2 := toBase64(p.Primes[1].Bytes()) - // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm - // and from: http://code.google.com/p/go/issues/detail?id=987 - p1 := new(big.Int).Sub(p.Primes[0], bigIntOne) - q1 := new(big.Int).Sub(p.Primes[1], bigIntOne) - exp1 := new(big.Int).Mod(p.D, p1) - exp2 := new(big.Int).Mod(p.D, q1) - coeff := new(big.Int).ModInverse(p.Primes[1], p.Primes[0]) - - exponent1 := toBase64(exp1.Bytes()) - exponent2 := toBase64(exp2.Bytes()) - coefficient := toBase64(coeff.Bytes()) - - return format + - "Algorithm: " + algorithm + "\n" + - "Modulus: " + modulus + "\n" + - "PublicExponent: " + publicExponent + "\n" + - "PrivateExponent: " + privateExponent + "\n" + - "Prime1: " + prime1 + "\n" + - "Prime2: " + prime2 + "\n" + - "Exponent1: " + exponent1 + "\n" + - "Exponent2: " + exponent2 + "\n" + - "Coefficient: " + coefficient + "\n" - - case *ecdsa.PrivateKey: - var intlen int - switch r.Algorithm { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - private := toBase64(intToBytes(p.D, intlen)) - return format + - "Algorithm: " + algorithm + "\n" + - "PrivateKey: " + private + "\n" - - case ed25519.PrivateKey: - private := toBase64(p.Seed()) - return format + - "Algorithm: " + algorithm + "\n" + - "PrivateKey: " + private + "\n" - - default: - return "" - } -} diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go deleted file mode 100644 index 586ab69..0000000 --- a/vendor/github.com/miekg/dns/doc.go +++ /dev/null @@ -1,292 +0,0 @@ -/* -Package dns implements a full featured interface to the Domain Name System. -Both server- and client-side programming is supported. The package allows -complete control over what is sent out to the DNS. The API follows the -less-is-more principle, by presenting a small, clean interface. - -It supports (asynchronous) querying/replying, incoming/outgoing zone transfers, -TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing. - -Note that domain names MUST be fully qualified before sending them, unqualified -names in a message will result in a packing failure. - -Resource records are native types. They are not stored in wire format. Basic -usage pattern for creating a new resource record: - - r := new(dns.MX) - r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600} - r.Preference = 10 - r.Mx = "mx.miek.nl." - -Or directly from a string: - - mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.") - -Or when the default origin (.) and TTL (3600) and class (IN) suit you: - - mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl") - -Or even: - - mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek") - -In the DNS messages are exchanged, these messages contain resource records -(sets). Use pattern for creating a message: - - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - -Or when not certain if the domain name is fully qualified: - - m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX) - -The message m is now a message with the question section set to ask the MX -records for the miek.nl. zone. - -The following is slightly more verbose, but more flexible: - - m1 := new(dns.Msg) - m1.Id = dns.Id() - m1.RecursionDesired = true - m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET} - -After creating a message it can be sent. Basic use pattern for synchronous -querying the DNS at a server configured on 127.0.0.1 and port 53: - - c := new(dns.Client) - in, rtt, err := c.Exchange(m1, "127.0.0.1:53") - -Suppressing multiple outstanding queries (with the same question, type and -class) is as easy as setting: - - c.SingleInflight = true - -More advanced options are available using a net.Dialer and the corresponding API. -For example it is possible to set a timeout, or to specify a source IP address -and port to use for the connection: - - c := new(dns.Client) - laddr := net.UDPAddr{ - IP: net.ParseIP("[::1]"), - Port: 12345, - Zone: "", - } - c.Dialer = &net.Dialer{ - Timeout: 200 * time.Millisecond, - LocalAddr: &laddr, - } - in, rtt, err := c.Exchange(m1, "8.8.8.8:53") - -If these "advanced" features are not needed, a simple UDP query can be sent, -with: - - in, err := dns.Exchange(m1, "127.0.0.1:53") - -When this functions returns you will get DNS message. A DNS message consists -out of four sections. -The question section: in.Question, the answer section: in.Answer, -the authority section: in.Ns and the additional section: in.Extra. - -Each of these sections (except the Question section) contain a []RR. Basic -use pattern for accessing the rdata of a TXT RR as the first RR in -the Answer section: - - if t, ok := in.Answer[0].(*dns.TXT); ok { - // do something with t.Txt - } - -# Domain Name and TXT Character String Representations - -Both domain names and TXT character strings are converted to presentation form -both when unpacked and when converted to strings. - -For TXT character strings, tabs, carriage returns and line feeds will be -converted to \t, \r and \n respectively. Back slashes and quotations marks will -be escaped. Bytes below 32 and above 127 will be converted to \DDD form. - -For domain names, in addition to the above rules brackets, periods, spaces, -semicolons and the at symbol are escaped. - -# DNSSEC - -DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses -public key cryptography to sign resource records. The public keys are stored in -DNSKEY records and the signatures in RRSIG records. - -Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) -bit to a request. - - m := new(dns.Msg) - m.SetEdns0(4096, true) - -Signature generation, signature verification and key generation are all supported. - -# DYNAMIC UPDATES - -Dynamic updates reuses the DNS message format, but renames three of the -sections. Question is Zone, Answer is Prerequisite, Authority is Update, only -the Additional is not renamed. See RFC 2136 for the gory details. - -You can set a rather complex set of rules for the existence of absence of -certain resource records or names in a zone to specify if resource records -should be added or removed. The table from RFC 2136 supplemented with the Go -DNS function shows which functions exist to specify the prerequisites. - - 3.2.4 - Table Of Metavalues Used In Prerequisite Section - - CLASS TYPE RDATA Meaning Function - -------------------------------------------------------------- - ANY ANY empty Name is in use dns.NameUsed - ANY rrset empty RRset exists (value indep) dns.RRsetUsed - NONE ANY empty Name is not in use dns.NameNotUsed - NONE rrset empty RRset does not exist dns.RRsetNotUsed - zone rrset rr RRset exists (value dep) dns.Used - -The prerequisite section can also be left empty. If you have decided on the -prerequisites you can tell what RRs should be added or deleted. The next table -shows the options you have and what functions to call. - - 3.4.2.6 - Table Of Metavalues Used In Update Section - - CLASS TYPE RDATA Meaning Function - --------------------------------------------------------------- - ANY ANY empty Delete all RRsets from name dns.RemoveName - ANY rrset empty Delete an RRset dns.RemoveRRset - NONE rrset rr Delete an RR from RRset dns.Remove - zone rrset rr Add to an RRset dns.Insert - -# TRANSACTION SIGNATURE - -An TSIG or transaction signature adds a HMAC TSIG record to each message sent. -The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512. - -Basic use pattern when querying with a TSIG name "axfr." (note that these key names -must be fully qualified - as they are domain names) and the base64 secret -"so6ZGir4GPAqINNh9U5c3A==": - -If an incoming message contains a TSIG record it MUST be the last record in -the additional section (RFC2845 3.2). This means that you should make the -call to SetTsig last, right before executing the query. If you make any -changes to the RRset after calling SetTsig() the signature will be incorrect. - - c := new(dns.Client) - c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix()) - ... - // When sending the TSIG RR is calculated and filled in before sending - -When requesting an zone transfer (almost all TSIG usage is when requesting zone -transfers), with TSIG, this is the basic use pattern. In this example we -request an AXFR for miek.nl. with TSIG key named "axfr." and secret -"so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54: - - t := new(dns.Transfer) - m := new(dns.Msg) - t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - m.SetAxfr("miek.nl.") - m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix()) - c, err := t.In(m, "176.58.119.54:53") - for r := range c { ... } - -You can now read the records from the transfer as they come in. Each envelope -is checked with TSIG. If something is not correct an error is returned. - -A custom TSIG implementation can be used. This requires additional code to -perform any session establishment and signature generation/verification. The -client must be configured with an implementation of the TsigProvider interface: - - type Provider struct{} - - func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) { - // Use tsig.Hdr.Name and tsig.Algorithm in your code to - // generate the MAC using msg as the payload. - } - - func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error { - // Use tsig.Hdr.Name and tsig.Algorithm in your code to verify - // that msg matches the value in tsig.MAC. - } - - c := new(dns.Client) - c.TsigProvider = new(Provider) - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - m.SetTsig(keyname, dns.HmacSHA256, 300, time.Now().Unix()) - ... - // TSIG RR is calculated by calling your Generate method - -Basic use pattern validating and replying to a message that has TSIG set. - - server := &dns.Server{Addr: ":53", Net: "udp"} - server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - go server.ListenAndServe() - dns.HandleFunc(".", handleRequest) - - func handleRequest(w dns.ResponseWriter, r *dns.Msg) { - m := new(dns.Msg) - m.SetReply(r) - if r.IsTsig() != nil { - if w.TsigStatus() == nil { - // *Msg r has an TSIG record and it was validated - m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix()) - } else { - // *Msg r has an TSIG records and it was not validated - } - } - w.WriteMsg(m) - } - -# PRIVATE RRS - -RFC 6895 sets aside a range of type codes for private use. This range is 65,280 -- 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these -can be used, before requesting an official type code from IANA. - -See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more -information. - -# EDNS0 - -EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by -RFC 6891. It defines a new RR type, the OPT RR, which is then completely -abused. - -Basic use pattern for creating an (empty) OPT RR: - - o := new(dns.OPT) - o.Hdr.Name = "." // MUST be the root zone, per definition. - o.Hdr.Rrtype = dns.TypeOPT - -The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces. -Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and -EDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR. -Basic use pattern for a server to check if (and which) options are set: - - // o is a dns.OPT - for _, s := range o.Option { - switch e := s.(type) { - case *dns.EDNS0_NSID: - // do stuff with e.Nsid - case *dns.EDNS0_SUBNET: - // access e.Family, e.Address, etc. - } - } - -SIG(0) - -From RFC 2931: - - SIG(0) provides protection for DNS transactions and requests .... - ... protection for glue records, DNS requests, protection for message headers - on requests and responses, and protection of the overall integrity of a response. - -It works like TSIG, except that SIG(0) uses public key cryptography, instead of -the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256, -ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512. - -Signing subsequent messages in multi-message sessions is not implemented. -*/ -package dns diff --git a/vendor/github.com/miekg/dns/duplicate.go b/vendor/github.com/miekg/dns/duplicate.go deleted file mode 100644 index d21ae1c..0000000 --- a/vendor/github.com/miekg/dns/duplicate.go +++ /dev/null @@ -1,37 +0,0 @@ -package dns - -//go:generate go run duplicate_generate.go - -// IsDuplicate checks of r1 and r2 are duplicates of each other, excluding the TTL. -// So this means the header data is equal *and* the RDATA is the same. Returns true -// if so, otherwise false. It's a protocol violation to have identical RRs in a message. -func IsDuplicate(r1, r2 RR) bool { - // Check whether the record header is identical. - if !r1.Header().isDuplicate(r2.Header()) { - return false - } - - // Check whether the RDATA is identical. - return r1.isDuplicate(r2) -} - -func (r1 *RR_Header) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RR_Header) - if !ok { - return false - } - if r1.Class != r2.Class { - return false - } - if r1.Rrtype != r2.Rrtype { - return false - } - if !isDuplicateName(r1.Name, r2.Name) { - return false - } - // ignore TTL - return true -} - -// isDuplicateName checks if the domain names s1 and s2 are equal. -func isDuplicateName(s1, s2 string) bool { return equal(s1, s2) } diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go deleted file mode 100644 index 1b58e8f..0000000 --- a/vendor/github.com/miekg/dns/edns.go +++ /dev/null @@ -1,844 +0,0 @@ -package dns - -import ( - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "net" - "strconv" -) - -// EDNS0 Option codes. -const ( - EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 - EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt - EDNS0NSID = 0x3 // nsid (See RFC 5001) - EDNS0ESU = 0x4 // ENUM Source-URI draft: https://datatracker.ietf.org/doc/html/draft-kaplan-enum-source-uri-00 - EDNS0DAU = 0x5 // DNSSEC Algorithm Understood - EDNS0DHU = 0x6 // DS Hash Understood - EDNS0N3U = 0x7 // NSEC3 Hash Understood - EDNS0SUBNET = 0x8 // client-subnet (See RFC 7871) - EDNS0EXPIRE = 0x9 // EDNS0 expire - EDNS0COOKIE = 0xa // EDNS0 Cookie - EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (See RFC 7828) - EDNS0PADDING = 0xc // EDNS0 padding (See RFC 7830) - EDNS0EDE = 0xf // EDNS0 extended DNS errors (See RFC 8914) - EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (See RFC 6891) - EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (See RFC 6891) - _DO = 1 << 15 // DNSSEC OK -) - -// makeDataOpt is used to unpack the EDNS0 option(s) from a message. -func makeDataOpt(code uint16) EDNS0 { - // All the EDNS0.* constants above need to be in this switch. - switch code { - case EDNS0LLQ: - return new(EDNS0_LLQ) - case EDNS0UL: - return new(EDNS0_UL) - case EDNS0NSID: - return new(EDNS0_NSID) - case EDNS0DAU: - return new(EDNS0_DAU) - case EDNS0DHU: - return new(EDNS0_DHU) - case EDNS0N3U: - return new(EDNS0_N3U) - case EDNS0SUBNET: - return new(EDNS0_SUBNET) - case EDNS0EXPIRE: - return new(EDNS0_EXPIRE) - case EDNS0COOKIE: - return new(EDNS0_COOKIE) - case EDNS0TCPKEEPALIVE: - return new(EDNS0_TCP_KEEPALIVE) - case EDNS0PADDING: - return new(EDNS0_PADDING) - case EDNS0EDE: - return new(EDNS0_EDE) - case EDNS0ESU: - return &EDNS0_ESU{Code: EDNS0ESU} - default: - e := new(EDNS0_LOCAL) - e.Code = code - return e - } -} - -// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. -// See RFC 6891. -type OPT struct { - Hdr RR_Header - Option []EDNS0 `dns:"opt"` -} - -func (rr *OPT) String() string { - s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; " - if rr.Do() { - s += "flags: do; " - } else { - s += "flags:; " - } - if rr.Hdr.Ttl&0x7FFF != 0 { - s += fmt.Sprintf("MBZ: 0x%04x, ", rr.Hdr.Ttl&0x7FFF) - } - s += "udp: " + strconv.Itoa(int(rr.UDPSize())) - - for _, o := range rr.Option { - switch o.(type) { - case *EDNS0_NSID: - s += "\n; NSID: " + o.String() - h, e := o.pack() - var r string - if e == nil { - for _, c := range h { - r += "(" + string(c) + ")" - } - s += " " + r - } - case *EDNS0_SUBNET: - s += "\n; SUBNET: " + o.String() - case *EDNS0_COOKIE: - s += "\n; COOKIE: " + o.String() - case *EDNS0_EXPIRE: - s += "\n; EXPIRE: " + o.String() - case *EDNS0_TCP_KEEPALIVE: - s += "\n; KEEPALIVE: " + o.String() - case *EDNS0_UL: - s += "\n; UPDATE LEASE: " + o.String() - case *EDNS0_LLQ: - s += "\n; LONG LIVED QUERIES: " + o.String() - case *EDNS0_DAU: - s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String() - case *EDNS0_DHU: - s += "\n; DS HASH UNDERSTOOD: " + o.String() - case *EDNS0_N3U: - s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String() - case *EDNS0_LOCAL: - s += "\n; LOCAL OPT: " + o.String() - case *EDNS0_PADDING: - s += "\n; PADDING: " + o.String() - case *EDNS0_EDE: - s += "\n; EDE: " + o.String() - case *EDNS0_ESU: - s += "\n; ESU: " + o.String() - } - } - return s -} - -func (rr *OPT) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, o := range rr.Option { - l += 4 // Account for 2-byte option code and 2-byte option length. - lo, _ := o.pack() - l += len(lo) - } - return l -} - -func (*OPT) parse(c *zlexer, origin string) *ParseError { - return &ParseError{err: "OPT records do not have a presentation format"} -} - -func (rr *OPT) isDuplicate(r2 RR) bool { return false } - -// return the old value -> delete SetVersion? - -// Version returns the EDNS version used. Only zero is defined. -func (rr *OPT) Version() uint8 { - return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16) -} - -// SetVersion sets the version of EDNS. This is usually zero. -func (rr *OPT) SetVersion(v uint8) { - rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16 -} - -// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL). -func (rr *OPT) ExtendedRcode() int { - return int(rr.Hdr.Ttl&0xFF000000>>24) << 4 -} - -// SetExtendedRcode sets the EDNS extended RCODE field. -// -// If the RCODE is not an extended RCODE, will reset the extended RCODE field to 0. -func (rr *OPT) SetExtendedRcode(v uint16) { - rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v>>4)<<24 -} - -// UDPSize returns the UDP buffer size. -func (rr *OPT) UDPSize() uint16 { - return rr.Hdr.Class -} - -// SetUDPSize sets the UDP buffer size. -func (rr *OPT) SetUDPSize(size uint16) { - rr.Hdr.Class = size -} - -// Do returns the value of the DO (DNSSEC OK) bit. -func (rr *OPT) Do() bool { - return rr.Hdr.Ttl&_DO == _DO -} - -// SetDo sets the DO (DNSSEC OK) bit. -// If we pass an argument, set the DO bit to that value. -// It is possible to pass 2 or more arguments, but they will be ignored. -func (rr *OPT) SetDo(do ...bool) { - if len(do) == 1 { - if do[0] { - rr.Hdr.Ttl |= _DO - } else { - rr.Hdr.Ttl &^= _DO - } - } else { - rr.Hdr.Ttl |= _DO - } -} - -// Z returns the Z part of the OPT RR as a uint16 with only the 15 least significant bits used. -func (rr *OPT) Z() uint16 { - return uint16(rr.Hdr.Ttl & 0x7FFF) -} - -// SetZ sets the Z part of the OPT RR, note only the 15 least significant bits of z are used. -func (rr *OPT) SetZ(z uint16) { - rr.Hdr.Ttl = rr.Hdr.Ttl&^0x7FFF | uint32(z&0x7FFF) -} - -// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it. -type EDNS0 interface { - // Option returns the option code for the option. - Option() uint16 - // pack returns the bytes of the option data. - pack() ([]byte, error) - // unpack sets the data as found in the buffer. Is also sets - // the length of the slice as the length of the option data. - unpack([]byte) error - // String returns the string representation of the option. - String() string - // copy returns a deep-copy of the option. - copy() EDNS0 -} - -// EDNS0_NSID option is used to retrieve a nameserver -// identifier. When sending a request Nsid must be set to the empty string -// The identifier is an opaque string encoded as hex. -// Basic use pattern for creating an nsid option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_NSID) -// e.Code = dns.EDNS0NSID -// e.Nsid = "AA" -// o.Option = append(o.Option, e) -type EDNS0_NSID struct { - Code uint16 // Always EDNS0NSID - Nsid string // This string needs to be hex encoded -} - -func (e *EDNS0_NSID) pack() ([]byte, error) { - h, err := hex.DecodeString(e.Nsid) - if err != nil { - return nil, err - } - return h, nil -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } // Option returns the option code. -func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil } -func (e *EDNS0_NSID) String() string { return e.Nsid } -func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} } - -// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver -// an idea of where the client lives. See RFC 7871. It can then give back a different -// answer depending on the location or network topology. -// Basic use pattern for creating an subnet option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_SUBNET) -// e.Code = dns.EDNS0SUBNET // by default this is filled in through unpacking OPT packets (unpackDataOpt) -// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 -// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6 -// e.SourceScope = 0 -// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 -// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 -// o.Option = append(o.Option, e) -// -// This code will parse all the available bits when unpacking (up to optlen). -// When packing it will apply SourceNetmask. If you need more advanced logic, -// patches welcome and good luck. -type EDNS0_SUBNET struct { - Code uint16 // Always EDNS0SUBNET - Family uint16 // 1 for IP, 2 for IP6 - SourceNetmask uint8 - SourceScope uint8 - Address net.IP -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET } - -func (e *EDNS0_SUBNET) pack() ([]byte, error) { - b := make([]byte, 4) - binary.BigEndian.PutUint16(b[0:], e.Family) - b[2] = e.SourceNetmask - b[3] = e.SourceScope - switch e.Family { - case 0: - // "dig" sets AddressFamily to 0 if SourceNetmask is also 0 - // We might don't need to complain either - if e.SourceNetmask != 0 { - return nil, errors.New("dns: bad address family") - } - case 1: - if e.SourceNetmask > net.IPv4len*8 { - return nil, errors.New("dns: bad netmask") - } - if len(e.Address.To4()) != net.IPv4len { - return nil, errors.New("dns: bad address") - } - ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8)) - needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up - b = append(b, ip[:needLength]...) - case 2: - if e.SourceNetmask > net.IPv6len*8 { - return nil, errors.New("dns: bad netmask") - } - if len(e.Address) != net.IPv6len { - return nil, errors.New("dns: bad address") - } - ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8)) - needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up - b = append(b, ip[:needLength]...) - default: - return nil, errors.New("dns: bad address family") - } - return b, nil -} - -func (e *EDNS0_SUBNET) unpack(b []byte) error { - if len(b) < 4 { - return ErrBuf - } - e.Family = binary.BigEndian.Uint16(b) - e.SourceNetmask = b[2] - e.SourceScope = b[3] - switch e.Family { - case 0: - // "dig" sets AddressFamily to 0 if SourceNetmask is also 0 - // It's okay to accept such a packet - if e.SourceNetmask != 0 { - return errors.New("dns: bad address family") - } - e.Address = net.IPv4(0, 0, 0, 0) - case 1: - if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 { - return errors.New("dns: bad netmask") - } - addr := make(net.IP, net.IPv4len) - copy(addr, b[4:]) - e.Address = addr.To16() - case 2: - if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 { - return errors.New("dns: bad netmask") - } - addr := make(net.IP, net.IPv6len) - copy(addr, b[4:]) - e.Address = addr - default: - return errors.New("dns: bad address family") - } - return nil -} - -func (e *EDNS0_SUBNET) String() (s string) { - if e.Address == nil { - s = "" - } else if e.Address.To4() != nil { - s = e.Address.String() - } else { - s = "[" + e.Address.String() + "]" - } - s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope)) - return -} - -func (e *EDNS0_SUBNET) copy() EDNS0 { - return &EDNS0_SUBNET{ - e.Code, - e.Family, - e.SourceNetmask, - e.SourceScope, - e.Address, - } -} - -// The EDNS0_COOKIE option is used to add a DNS Cookie to a message. -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_COOKIE) -// e.Code = dns.EDNS0COOKIE -// e.Cookie = "24a5ac.." -// o.Option = append(o.Option, e) -// -// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is -// always 8 bytes. It may then optionally be followed by the server cookie. The server -// cookie is of variable length, 8 to a maximum of 32 bytes. In other words: -// -// cCookie := o.Cookie[:16] -// sCookie := o.Cookie[16:] -// -// There is no guarantee that the Cookie string has a specific length. -type EDNS0_COOKIE struct { - Code uint16 // Always EDNS0COOKIE - Cookie string // Hex-encoded cookie data -} - -func (e *EDNS0_COOKIE) pack() ([]byte, error) { - h, err := hex.DecodeString(e.Cookie) - if err != nil { - return nil, err - } - return h, nil -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE } -func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil } -func (e *EDNS0_COOKIE) String() string { return e.Cookie } -func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} } - -// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set -// an expiration on an update RR. This is helpful for clients that cannot clean -// up after themselves. This is a draft RFC and more information can be found at -// https://tools.ietf.org/html/draft-sekar-dns-ul-02 -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_UL) -// e.Code = dns.EDNS0UL -// e.Lease = 120 // in seconds -// o.Option = append(o.Option, e) -type EDNS0_UL struct { - Code uint16 // Always EDNS0UL - Lease uint32 - KeyLease uint32 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_UL) Option() uint16 { return EDNS0UL } -func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) } -func (e *EDNS0_UL) copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} } - -// Copied: http://golang.org/src/pkg/net/dnsmsg.go -func (e *EDNS0_UL) pack() ([]byte, error) { - var b []byte - if e.KeyLease == 0 { - b = make([]byte, 4) - } else { - b = make([]byte, 8) - binary.BigEndian.PutUint32(b[4:], e.KeyLease) - } - binary.BigEndian.PutUint32(b, e.Lease) - return b, nil -} - -func (e *EDNS0_UL) unpack(b []byte) error { - switch len(b) { - case 4: - e.KeyLease = 0 - case 8: - e.KeyLease = binary.BigEndian.Uint32(b[4:]) - default: - return ErrBuf - } - e.Lease = binary.BigEndian.Uint32(b) - return nil -} - -// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 -// Implemented for completeness, as the EDNS0 type code is assigned. -type EDNS0_LLQ struct { - Code uint16 // Always EDNS0LLQ - Version uint16 - Opcode uint16 - Error uint16 - Id uint64 - LeaseLife uint32 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ } - -func (e *EDNS0_LLQ) pack() ([]byte, error) { - b := make([]byte, 18) - binary.BigEndian.PutUint16(b[0:], e.Version) - binary.BigEndian.PutUint16(b[2:], e.Opcode) - binary.BigEndian.PutUint16(b[4:], e.Error) - binary.BigEndian.PutUint64(b[6:], e.Id) - binary.BigEndian.PutUint32(b[14:], e.LeaseLife) - return b, nil -} - -func (e *EDNS0_LLQ) unpack(b []byte) error { - if len(b) < 18 { - return ErrBuf - } - e.Version = binary.BigEndian.Uint16(b[0:]) - e.Opcode = binary.BigEndian.Uint16(b[2:]) - e.Error = binary.BigEndian.Uint16(b[4:]) - e.Id = binary.BigEndian.Uint64(b[6:]) - e.LeaseLife = binary.BigEndian.Uint32(b[14:]) - return nil -} - -func (e *EDNS0_LLQ) String() string { - s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) + - " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) + - " " + strconv.FormatUint(uint64(e.LeaseLife), 10) - return s -} - -func (e *EDNS0_LLQ) copy() EDNS0 { - return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife} -} - -// EDNS0_DAU implements the EDNS0 "DNSSEC Algorithm Understood" option. See RFC 6975. -type EDNS0_DAU struct { - Code uint16 // Always EDNS0DAU - AlgCode []uint8 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU } -func (e *EDNS0_DAU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } -func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } - -func (e *EDNS0_DAU) String() string { - s := "" - for _, alg := range e.AlgCode { - if a, ok := AlgorithmToString[alg]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(alg)) - } - } - return s -} -func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} } - -// EDNS0_DHU implements the EDNS0 "DS Hash Understood" option. See RFC 6975. -type EDNS0_DHU struct { - Code uint16 // Always EDNS0DHU - AlgCode []uint8 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU } -func (e *EDNS0_DHU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } -func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } - -func (e *EDNS0_DHU) String() string { - s := "" - for _, alg := range e.AlgCode { - if a, ok := HashToString[alg]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(alg)) - } - } - return s -} -func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} } - -// EDNS0_N3U implements the EDNS0 "NSEC3 Hash Understood" option. See RFC 6975. -type EDNS0_N3U struct { - Code uint16 // Always EDNS0N3U - AlgCode []uint8 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U } -func (e *EDNS0_N3U) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil } -func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil } - -func (e *EDNS0_N3U) String() string { - // Re-use the hash map - s := "" - for _, alg := range e.AlgCode { - if a, ok := HashToString[alg]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(alg)) - } - } - return s -} -func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} } - -// EDNS0_EXPIRE implements the EDNS0 option as described in RFC 7314. -type EDNS0_EXPIRE struct { - Code uint16 // Always EDNS0EXPIRE - Expire uint32 - Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire. -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE } -func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} } - -func (e *EDNS0_EXPIRE) pack() ([]byte, error) { - if e.Empty { - return []byte{}, nil - } - b := make([]byte, 4) - binary.BigEndian.PutUint32(b, e.Expire) - return b, nil -} - -func (e *EDNS0_EXPIRE) unpack(b []byte) error { - if len(b) == 0 { - // zero-length EXPIRE query, see RFC 7314 Section 2 - e.Empty = true - return nil - } - if len(b) < 4 { - return ErrBuf - } - e.Expire = binary.BigEndian.Uint32(b) - e.Empty = false - return nil -} - -func (e *EDNS0_EXPIRE) String() (s string) { - if e.Empty { - return "" - } - return strconv.FormatUint(uint64(e.Expire), 10) -} - -// The EDNS0_LOCAL option is used for local/experimental purposes. The option -// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND] -// (RFC6891), although any unassigned code can actually be used. The content of -// the option is made available in Data, unaltered. -// Basic use pattern for creating a local option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_LOCAL) -// e.Code = dns.EDNS0LOCALSTART -// e.Data = []byte{72, 82, 74} -// o.Option = append(o.Option, e) -type EDNS0_LOCAL struct { - Code uint16 - Data []byte -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_LOCAL) Option() uint16 { return e.Code } - -func (e *EDNS0_LOCAL) String() string { - return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data) -} - -func (e *EDNS0_LOCAL) copy() EDNS0 { - return &EDNS0_LOCAL{e.Code, cloneSlice(e.Data)} -} - -func (e *EDNS0_LOCAL) pack() ([]byte, error) { - return cloneSlice(e.Data), nil -} - -func (e *EDNS0_LOCAL) unpack(b []byte) error { - e.Data = cloneSlice(b) - return nil -} - -// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep -// the TCP connection alive. See RFC 7828. -type EDNS0_TCP_KEEPALIVE struct { - Code uint16 // Always EDNSTCPKEEPALIVE - - // Timeout is an idle timeout value for the TCP connection, specified in - // units of 100 milliseconds, encoded in network byte order. If set to 0, - // pack will return a nil slice. - Timeout uint16 - - // Length is the option's length. - // Deprecated: this field is deprecated and is always equal to 0. - Length uint16 -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE } - -func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) { - if e.Timeout > 0 { - b := make([]byte, 2) - binary.BigEndian.PutUint16(b, e.Timeout) - return b, nil - } - return nil, nil -} - -func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error { - switch len(b) { - case 0: - case 2: - e.Timeout = binary.BigEndian.Uint16(b) - default: - return fmt.Errorf("dns: length mismatch, want 0/2 but got %d", len(b)) - } - return nil -} - -func (e *EDNS0_TCP_KEEPALIVE) String() string { - s := "use tcp keep-alive" - if e.Timeout == 0 { - s += ", timeout omitted" - } else { - s += fmt.Sprintf(", timeout %dms", e.Timeout*100) - } - return s -} - -func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Timeout, e.Length} } - -// EDNS0_PADDING option is used to add padding to a request/response. The default -// value of padding SHOULD be 0x0 but other values MAY be used, for instance if -// compression is applied before encryption which may break signatures. -type EDNS0_PADDING struct { - Padding []byte -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING } -func (e *EDNS0_PADDING) pack() ([]byte, error) { return cloneSlice(e.Padding), nil } -func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = cloneSlice(b); return nil } -func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) } -func (e *EDNS0_PADDING) copy() EDNS0 { return &EDNS0_PADDING{cloneSlice(e.Padding)} } - -// Extended DNS Error Codes (RFC 8914). -const ( - ExtendedErrorCodeOther uint16 = iota - ExtendedErrorCodeUnsupportedDNSKEYAlgorithm - ExtendedErrorCodeUnsupportedDSDigestType - ExtendedErrorCodeStaleAnswer - ExtendedErrorCodeForgedAnswer - ExtendedErrorCodeDNSSECIndeterminate - ExtendedErrorCodeDNSBogus - ExtendedErrorCodeSignatureExpired - ExtendedErrorCodeSignatureNotYetValid - ExtendedErrorCodeDNSKEYMissing - ExtendedErrorCodeRRSIGsMissing - ExtendedErrorCodeNoZoneKeyBitSet - ExtendedErrorCodeNSECMissing - ExtendedErrorCodeCachedError - ExtendedErrorCodeNotReady - ExtendedErrorCodeBlocked - ExtendedErrorCodeCensored - ExtendedErrorCodeFiltered - ExtendedErrorCodeProhibited - ExtendedErrorCodeStaleNXDOMAINAnswer - ExtendedErrorCodeNotAuthoritative - ExtendedErrorCodeNotSupported - ExtendedErrorCodeNoReachableAuthority - ExtendedErrorCodeNetworkError - ExtendedErrorCodeInvalidData -) - -// ExtendedErrorCodeToString maps extended error info codes to a human readable -// description. -var ExtendedErrorCodeToString = map[uint16]string{ - ExtendedErrorCodeOther: "Other", - ExtendedErrorCodeUnsupportedDNSKEYAlgorithm: "Unsupported DNSKEY Algorithm", - ExtendedErrorCodeUnsupportedDSDigestType: "Unsupported DS Digest Type", - ExtendedErrorCodeStaleAnswer: "Stale Answer", - ExtendedErrorCodeForgedAnswer: "Forged Answer", - ExtendedErrorCodeDNSSECIndeterminate: "DNSSEC Indeterminate", - ExtendedErrorCodeDNSBogus: "DNSSEC Bogus", - ExtendedErrorCodeSignatureExpired: "Signature Expired", - ExtendedErrorCodeSignatureNotYetValid: "Signature Not Yet Valid", - ExtendedErrorCodeDNSKEYMissing: "DNSKEY Missing", - ExtendedErrorCodeRRSIGsMissing: "RRSIGs Missing", - ExtendedErrorCodeNoZoneKeyBitSet: "No Zone Key Bit Set", - ExtendedErrorCodeNSECMissing: "NSEC Missing", - ExtendedErrorCodeCachedError: "Cached Error", - ExtendedErrorCodeNotReady: "Not Ready", - ExtendedErrorCodeBlocked: "Blocked", - ExtendedErrorCodeCensored: "Censored", - ExtendedErrorCodeFiltered: "Filtered", - ExtendedErrorCodeProhibited: "Prohibited", - ExtendedErrorCodeStaleNXDOMAINAnswer: "Stale NXDOMAIN Answer", - ExtendedErrorCodeNotAuthoritative: "Not Authoritative", - ExtendedErrorCodeNotSupported: "Not Supported", - ExtendedErrorCodeNoReachableAuthority: "No Reachable Authority", - ExtendedErrorCodeNetworkError: "Network Error", - ExtendedErrorCodeInvalidData: "Invalid Data", -} - -// StringToExtendedErrorCode is a map from human readable descriptions to -// extended error info codes. -var StringToExtendedErrorCode = reverseInt16(ExtendedErrorCodeToString) - -// EDNS0_EDE option is used to return additional information about the cause of -// DNS errors. -type EDNS0_EDE struct { - InfoCode uint16 - ExtraText string -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_EDE) Option() uint16 { return EDNS0EDE } -func (e *EDNS0_EDE) copy() EDNS0 { return &EDNS0_EDE{e.InfoCode, e.ExtraText} } - -func (e *EDNS0_EDE) String() string { - info := strconv.FormatUint(uint64(e.InfoCode), 10) - if s, ok := ExtendedErrorCodeToString[e.InfoCode]; ok { - info += fmt.Sprintf(" (%s)", s) - } - return fmt.Sprintf("%s: (%s)", info, e.ExtraText) -} - -func (e *EDNS0_EDE) pack() ([]byte, error) { - b := make([]byte, 2+len(e.ExtraText)) - binary.BigEndian.PutUint16(b[0:], e.InfoCode) - copy(b[2:], e.ExtraText) - return b, nil -} - -func (e *EDNS0_EDE) unpack(b []byte) error { - if len(b) < 2 { - return ErrBuf - } - e.InfoCode = binary.BigEndian.Uint16(b[0:]) - e.ExtraText = string(b[2:]) - return nil -} - -// The EDNS0_ESU option for ENUM Source-URI Extension -type EDNS0_ESU struct { - Code uint16 - Uri string -} - -// Option implements the EDNS0 interface. -func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU } -func (e *EDNS0_ESU) String() string { return e.Uri } -func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} } -func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil } -func (e *EDNS0_ESU) unpack(b []byte) error { - e.Uri = string(b) - return nil -} diff --git a/vendor/github.com/miekg/dns/format.go b/vendor/github.com/miekg/dns/format.go deleted file mode 100644 index 0ec79f2..0000000 --- a/vendor/github.com/miekg/dns/format.go +++ /dev/null @@ -1,93 +0,0 @@ -package dns - -import ( - "net" - "reflect" - "strconv" -) - -// NumField returns the number of rdata fields r has. -func NumField(r RR) int { - return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header -} - -// Field returns the rdata field i as a string. Fields are indexed starting from 1. -// RR types that holds slice data, for instance the NSEC type bitmap will return a single -// string where the types are concatenated using a space. -// Accessing non existing fields will cause a panic. -func Field(r RR, i int) string { - if i == 0 { - return "" - } - d := reflect.ValueOf(r).Elem().Field(i) - switch d.Kind() { - case reflect.String: - return d.String() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(d.Int(), 10) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.FormatUint(d.Uint(), 10) - case reflect.Slice: - switch reflect.ValueOf(r).Elem().Type().Field(i).Tag { - case `dns:"a"`: - // TODO(miek): Hmm store this as 16 bytes - if d.Len() < net.IPv4len { - return "" - } - if d.Len() < net.IPv6len { - return net.IPv4(byte(d.Index(0).Uint()), - byte(d.Index(1).Uint()), - byte(d.Index(2).Uint()), - byte(d.Index(3).Uint())).String() - } - return net.IPv4(byte(d.Index(12).Uint()), - byte(d.Index(13).Uint()), - byte(d.Index(14).Uint()), - byte(d.Index(15).Uint())).String() - case `dns:"aaaa"`: - if d.Len() < net.IPv6len { - return "" - } - return net.IP{ - byte(d.Index(0).Uint()), - byte(d.Index(1).Uint()), - byte(d.Index(2).Uint()), - byte(d.Index(3).Uint()), - byte(d.Index(4).Uint()), - byte(d.Index(5).Uint()), - byte(d.Index(6).Uint()), - byte(d.Index(7).Uint()), - byte(d.Index(8).Uint()), - byte(d.Index(9).Uint()), - byte(d.Index(10).Uint()), - byte(d.Index(11).Uint()), - byte(d.Index(12).Uint()), - byte(d.Index(13).Uint()), - byte(d.Index(14).Uint()), - byte(d.Index(15).Uint()), - }.String() - case `dns:"nsec"`: - if d.Len() == 0 { - return "" - } - s := Type(d.Index(0).Uint()).String() - for i := 1; i < d.Len(); i++ { - s += " " + Type(d.Index(i).Uint()).String() - } - return s - default: - // if it does not have a tag its a string slice - fallthrough - case `dns:"txt"`: - if d.Len() == 0 { - return "" - } - s := d.Index(0).String() - for i := 1; i < d.Len(); i++ { - s += " " + d.Index(i).String() - } - return s - } - } - return "" -} diff --git a/vendor/github.com/miekg/dns/fuzz.go b/vendor/github.com/miekg/dns/fuzz.go deleted file mode 100644 index 505ae43..0000000 --- a/vendor/github.com/miekg/dns/fuzz.go +++ /dev/null @@ -1,33 +0,0 @@ -//go:build fuzz -// +build fuzz - -package dns - -import "strings" - -func Fuzz(data []byte) int { - msg := new(Msg) - - if err := msg.Unpack(data); err != nil { - return 0 - } - if _, err := msg.Pack(); err != nil { - return 0 - } - - return 1 -} - -func FuzzNewRR(data []byte) int { - str := string(data) - // Do not fuzz lines that include the $INCLUDE keyword and hint the fuzzer - // at avoiding them. - // See GH#1025 for context. - if strings.Contains(strings.ToUpper(str), "$INCLUDE") { - return -1 - } - if _, err := NewRR(str); err != nil { - return 0 - } - return 1 -} diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go deleted file mode 100644 index a81d2bc..0000000 --- a/vendor/github.com/miekg/dns/generate.go +++ /dev/null @@ -1,248 +0,0 @@ -package dns - -import ( - "bytes" - "fmt" - "io" - "strconv" - "strings" -) - -// Parse the $GENERATE statement as used in BIND9 zones. -// See http://www.zytrax.com/books/dns/ch8/generate.html for instance. -// We are called after '$GENERATE '. After which we expect: -// * the range (12-24/2) -// * lhs (ownername) -// * [[ttl][class]] -// * type -// * rhs (rdata) -// But we are lazy here, only the range is parsed *all* occurrences -// of $ after that are interpreted. -func (zp *ZoneParser) generate(l lex) (RR, bool) { - token := l.token - step := int64(1) - if i := strings.IndexByte(token, '/'); i >= 0 { - if i+1 == len(token) { - return zp.setParseError("bad step in $GENERATE range", l) - } - - s, err := strconv.ParseInt(token[i+1:], 10, 64) - if err != nil || s <= 0 { - return zp.setParseError("bad step in $GENERATE range", l) - } - - step = s - token = token[:i] - } - - startStr, endStr, ok := strings.Cut(token, "-") - if !ok { - return zp.setParseError("bad start-stop in $GENERATE range", l) - } - - start, err := strconv.ParseInt(startStr, 10, 64) - if err != nil { - return zp.setParseError("bad start in $GENERATE range", l) - } - - end, err := strconv.ParseInt(endStr, 10, 64) - if err != nil { - return zp.setParseError("bad stop in $GENERATE range", l) - } - if end < 0 || start < 0 || end < start || (end-start)/step > 65535 { - return zp.setParseError("bad range in $GENERATE range", l) - } - - // _BLANK - l, ok = zp.c.Next() - if !ok || l.value != zBlank { - return zp.setParseError("garbage after $GENERATE range", l) - } - - // Create a complete new string, which we then parse again. - var s string - for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() { - if l.err { - return zp.setParseError("bad data in $GENERATE directive", l) - } - if l.value == zNewline { - break - } - - s += l.token - } - - r := &generateReader{ - s: s, - - cur: start, - start: start, - end: end, - step: step, - - file: zp.file, - lex: &l, - } - zp.sub = NewZoneParser(r, zp.origin, zp.file) - zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed - zp.sub.generateDisallowed = true - zp.sub.SetDefaultTTL(defaultTtl) - return zp.subNext() -} - -type generateReader struct { - s string - si int - - cur int64 - start int64 - end int64 - step int64 - - mod bytes.Buffer - - escape bool - - eof bool - - file string - lex *lex -} - -func (r *generateReader) parseError(msg string, end int) *ParseError { - r.eof = true // Make errors sticky. - - l := *r.lex - l.token = r.s[r.si-1 : end] - l.column += r.si // l.column starts one zBLANK before r.s - - return &ParseError{file: r.file, err: msg, lex: l} -} - -func (r *generateReader) Read(p []byte) (int, error) { - // NewZLexer, through NewZoneParser, should use ReadByte and - // not end up here. - - panic("not implemented") -} - -func (r *generateReader) ReadByte() (byte, error) { - if r.eof { - return 0, io.EOF - } - if r.mod.Len() > 0 { - return r.mod.ReadByte() - } - - if r.si >= len(r.s) { - r.si = 0 - r.cur += r.step - - r.eof = r.cur > r.end || r.cur < 0 - return '\n', nil - } - - si := r.si - r.si++ - - switch r.s[si] { - case '\\': - if r.escape { - r.escape = false - return '\\', nil - } - - r.escape = true - return r.ReadByte() - case '$': - if r.escape { - r.escape = false - return '$', nil - } - - mod := "%d" - - if si >= len(r.s)-1 { - // End of the string - fmt.Fprintf(&r.mod, mod, r.cur) - return r.mod.ReadByte() - } - - if r.s[si+1] == '$' { - r.si++ - return '$', nil - } - - var offset int64 - - // Search for { and } - if r.s[si+1] == '{' { - // Modifier block - sep := strings.Index(r.s[si+2:], "}") - if sep < 0 { - return 0, r.parseError("bad modifier in $GENERATE", len(r.s)) - } - - var errMsg string - mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep]) - if errMsg != "" { - return 0, r.parseError(errMsg, si+3+sep) - } - if r.start+offset < 0 || r.end+offset > 1<<31-1 { - return 0, r.parseError("bad offset in $GENERATE", si+3+sep) - } - - r.si += 2 + sep // Jump to it - } - - fmt.Fprintf(&r.mod, mod, r.cur+offset) - return r.mod.ReadByte() - default: - if r.escape { // Pretty useless here - r.escape = false - return r.ReadByte() - } - - return r.s[si], nil - } -} - -// Convert a $GENERATE modifier 0,0,d to something Printf can deal with. -func modToPrintf(s string) (string, int64, string) { - // Modifier is { offset [ ,width [ ,base ] ] } - provide default - // values for optional width and type, if necessary. - offStr, s, ok0 := strings.Cut(s, ",") - widthStr, s, ok1 := strings.Cut(s, ",") - base, _, ok2 := strings.Cut(s, ",") - if !ok0 { - widthStr = "0" - } - if !ok1 { - base = "d" - } - if ok2 { - return "", 0, "bad modifier in $GENERATE" - } - - switch base { - case "o", "d", "x", "X": - default: - return "", 0, "bad base in $GENERATE" - } - - offset, err := strconv.ParseInt(offStr, 10, 64) - if err != nil { - return "", 0, "bad offset in $GENERATE" - } - - width, err := strconv.ParseUint(widthStr, 10, 8) - if err != nil { - return "", 0, "bad width in $GENERATE" - } - - if width == 0 { - return "%" + base, offset, "" - } - - return "%0" + widthStr + base, offset, "" -} diff --git a/vendor/github.com/miekg/dns/hash.go b/vendor/github.com/miekg/dns/hash.go deleted file mode 100644 index 7d4183e..0000000 --- a/vendor/github.com/miekg/dns/hash.go +++ /dev/null @@ -1,31 +0,0 @@ -package dns - -import ( - "bytes" - "crypto" - "hash" -) - -// identityHash will not hash, it only buffers the data written into it and returns it as-is. -type identityHash struct { - b *bytes.Buffer -} - -// Implement the hash.Hash interface. - -func (i identityHash) Write(b []byte) (int, error) { return i.b.Write(b) } -func (i identityHash) Size() int { return i.b.Len() } -func (i identityHash) BlockSize() int { return 1024 } -func (i identityHash) Reset() { i.b.Reset() } -func (i identityHash) Sum(b []byte) []byte { return append(b, i.b.Bytes()...) } - -func hashFromAlgorithm(alg uint8) (hash.Hash, crypto.Hash, error) { - hashnumber, ok := AlgorithmToHash[alg] - if !ok { - return nil, 0, ErrAlg - } - if hashnumber == 0 { - return identityHash{b: &bytes.Buffer{}}, hashnumber, nil - } - return hashnumber.New(), hashnumber, nil -} diff --git a/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/miekg/dns/labels.go deleted file mode 100644 index cd498d2..0000000 --- a/vendor/github.com/miekg/dns/labels.go +++ /dev/null @@ -1,212 +0,0 @@ -package dns - -// Holds a bunch of helper functions for dealing with labels. - -// SplitDomainName splits a name string into it's labels. -// www.miek.nl. returns []string{"www", "miek", "nl"} -// .www.miek.nl. returns []string{"", "www", "miek", "nl"}, -// The root label (.) returns nil. Note that using -// strings.Split(s) will work in most cases, but does not handle -// escaped dots (\.) for instance. -// s must be a syntactically valid domain name, see IsDomainName. -func SplitDomainName(s string) (labels []string) { - if s == "" { - return nil - } - fqdnEnd := 0 // offset of the final '.' or the length of the name - idx := Split(s) - begin := 0 - if IsFqdn(s) { - fqdnEnd = len(s) - 1 - } else { - fqdnEnd = len(s) - } - - switch len(idx) { - case 0: - return nil - case 1: - // no-op - default: - for _, end := range idx[1:] { - labels = append(labels, s[begin:end-1]) - begin = end - } - } - - return append(labels, s[begin:fqdnEnd]) -} - -// CompareDomainName compares the names s1 and s2 and -// returns how many labels they have in common starting from the *right*. -// The comparison stops at the first inequality. The names are downcased -// before the comparison. -// -// www.miek.nl. and miek.nl. have two labels in common: miek and nl -// www.miek.nl. and www.bla.nl. have one label in common: nl -// -// s1 and s2 must be syntactically valid domain names. -func CompareDomainName(s1, s2 string) (n int) { - // the first check: root label - if s1 == "." || s2 == "." { - return 0 - } - - l1 := Split(s1) - l2 := Split(s2) - - j1 := len(l1) - 1 // end - i1 := len(l1) - 2 // start - j2 := len(l2) - 1 - i2 := len(l2) - 2 - // the second check can be done here: last/only label - // before we fall through into the for-loop below - if equal(s1[l1[j1]:], s2[l2[j2]:]) { - n++ - } else { - return - } - for { - if i1 < 0 || i2 < 0 { - break - } - if equal(s1[l1[i1]:l1[j1]], s2[l2[i2]:l2[j2]]) { - n++ - } else { - break - } - j1-- - i1-- - j2-- - i2-- - } - return -} - -// CountLabel counts the number of labels in the string s. -// s must be a syntactically valid domain name. -func CountLabel(s string) (labels int) { - if s == "." { - return - } - off := 0 - end := false - for { - off, end = NextLabel(s, off) - labels++ - if end { - return - } - } -} - -// Split splits a name s into its label indexes. -// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}. -// The root name (.) returns nil. Also see SplitDomainName. -// s must be a syntactically valid domain name. -func Split(s string) []int { - if s == "." { - return nil - } - idx := make([]int, 1, 3) - off := 0 - end := false - - for { - off, end = NextLabel(s, off) - if end { - return idx - } - idx = append(idx, off) - } -} - -// NextLabel returns the index of the start of the next label in the -// string s starting at offset. A negative offset will cause a panic. -// The bool end is true when the end of the string has been reached. -// Also see PrevLabel. -func NextLabel(s string, offset int) (i int, end bool) { - if s == "" { - return 0, true - } - for i = offset; i < len(s)-1; i++ { - if s[i] != '.' { - continue - } - j := i - 1 - for j >= 0 && s[j] == '\\' { - j-- - } - - if (j-i)%2 == 0 { - continue - } - - return i + 1, false - } - return i + 1, true -} - -// PrevLabel returns the index of the label when starting from the right and -// jumping n labels to the left. -// The bool start is true when the start of the string has been overshot. -// Also see NextLabel. -func PrevLabel(s string, n int) (i int, start bool) { - if s == "" { - return 0, true - } - if n == 0 { - return len(s), false - } - - l := len(s) - 1 - if s[l] == '.' { - l-- - } - - for ; l >= 0 && n > 0; l-- { - if s[l] != '.' { - continue - } - j := l - 1 - for j >= 0 && s[j] == '\\' { - j-- - } - - if (j-l)%2 == 0 { - continue - } - - n-- - if n == 0 { - return l + 1, false - } - } - - return 0, n > 1 -} - -// equal compares a and b while ignoring case. It returns true when equal otherwise false. -func equal(a, b string) bool { - // might be lifted into API function. - la := len(a) - lb := len(b) - if la != lb { - return false - } - - for i := la - 1; i >= 0; i-- { - ai := a[i] - bi := b[i] - if ai >= 'A' && ai <= 'Z' { - ai |= 'a' - 'A' - } - if bi >= 'A' && bi <= 'Z' { - bi |= 'a' - 'A' - } - if ai != bi { - return false - } - } - return true -} diff --git a/vendor/github.com/miekg/dns/listen_no_reuseport.go b/vendor/github.com/miekg/dns/listen_no_reuseport.go deleted file mode 100644 index 8cebb2f..0000000 --- a/vendor/github.com/miekg/dns/listen_no_reuseport.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd -// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd - -package dns - -import "net" - -const supportsReusePort = false - -func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, error) { - if reuseport || reuseaddr { - // TODO(tmthrgd): return an error? - } - - return net.Listen(network, addr) -} - -const supportsReuseAddr = false - -func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, error) { - if reuseport || reuseaddr { - // TODO(tmthrgd): return an error? - } - - return net.ListenPacket(network, addr) -} diff --git a/vendor/github.com/miekg/dns/listen_reuseport.go b/vendor/github.com/miekg/dns/listen_reuseport.go deleted file mode 100644 index 41326f2..0000000 --- a/vendor/github.com/miekg/dns/listen_reuseport.go +++ /dev/null @@ -1,66 +0,0 @@ -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd -// +build aix darwin dragonfly freebsd linux netbsd openbsd - -package dns - -import ( - "context" - "net" - "syscall" - - "golang.org/x/sys/unix" -) - -const supportsReusePort = true - -func reuseportControl(network, address string, c syscall.RawConn) error { - var opErr error - err := c.Control(func(fd uintptr) { - opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) - }) - if err != nil { - return err - } - - return opErr -} - -const supportsReuseAddr = true - -func reuseaddrControl(network, address string, c syscall.RawConn) error { - var opErr error - err := c.Control(func(fd uintptr) { - opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) - }) - if err != nil { - return err - } - - return opErr -} - -func listenTCP(network, addr string, reuseport, reuseaddr bool) (net.Listener, error) { - var lc net.ListenConfig - switch { - case reuseaddr && reuseport: - case reuseport: - lc.Control = reuseportControl - case reuseaddr: - lc.Control = reuseaddrControl - } - - return lc.Listen(context.Background(), network, addr) -} - -func listenUDP(network, addr string, reuseport, reuseaddr bool) (net.PacketConn, error) { - var lc net.ListenConfig - switch { - case reuseaddr && reuseport: - case reuseport: - lc.Control = reuseportControl - case reuseaddr: - lc.Control = reuseaddrControl - } - - return lc.ListenPacket(context.Background(), network, addr) -} diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go deleted file mode 100644 index 8294d03..0000000 --- a/vendor/github.com/miekg/dns/msg.go +++ /dev/null @@ -1,1218 +0,0 @@ -// DNS packet assembly, see RFC 1035. Converting from - Unpack() - -// and to - Pack() - wire format. -// All the packers and unpackers take a (msg []byte, off int) -// and return (off1 int, ok bool). If they return ok==false, they -// also return off1==len(msg), so that the next unpacker will -// also fail. This lets us avoid checks of ok until the end of a -// packing sequence. - -package dns - -//go:generate go run msg_generate.go - -import ( - "crypto/rand" - "encoding/binary" - "fmt" - "math/big" - "strconv" - "strings" -) - -const ( - maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer - maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4 - - // This is the maximum number of compression pointers that should occur in a - // semantically valid message. Each label in a domain name must be at least one - // octet and is separated by a period. The root label won't be represented by a - // compression pointer to a compression pointer, hence the -2 to exclude the - // smallest valid root label. - // - // It is possible to construct a valid message that has more compression pointers - // than this, and still doesn't loop, by pointing to a previous pointer. This is - // not something a well written implementation should ever do, so we leave them - // to trip the maximum compression pointer check. - maxCompressionPointers = (maxDomainNameWireOctets+1)/2 - 2 - - // This is the maximum length of a domain name in presentation format. The - // maximum wire length of a domain name is 255 octets (see above), with the - // maximum label length being 63. The wire format requires one extra byte over - // the presentation format, reducing the number of octets by 1. Each label in - // the name will be separated by a single period, with each octet in the label - // expanding to at most 4 bytes (\DDD). If all other labels are of the maximum - // length, then the final label can only be 61 octets long to not exceed the - // maximum allowed wire length. - maxDomainNamePresentationLength = 61*4 + 1 + 63*4 + 1 + 63*4 + 1 + 63*4 + 1 -) - -// Errors defined in this package. -var ( - ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm. - ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication. - ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message. - ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized. - ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ... - ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot. - ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID. - ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid. - ErrKey error = &Error{err: "bad key"} - ErrKeySize error = &Error{err: "bad key size"} - ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)} - ErrNoSig error = &Error{err: "no signature found"} - ErrPrivKey error = &Error{err: "bad private key"} - ErrRcode error = &Error{err: "bad rcode"} - ErrRdata error = &Error{err: "bad rdata"} - ErrRRset error = &Error{err: "bad rrset"} - ErrSecret error = &Error{err: "no secrets defined"} - ErrShortRead error = &Error{err: "short read"} - ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated. - ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers. - ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication. -) - -// Id by default returns a 16-bit random number to be used as a message id. The -// number is drawn from a cryptographically secure random number generator. -// This being a variable the function can be reassigned to a custom function. -// For instance, to make it return a static value for testing: -// -// dns.Id = func() uint16 { return 3 } -var Id = id - -// id returns a 16 bits random number to be used as a -// message id. The random provided should be good enough. -func id() uint16 { - var output uint16 - err := binary.Read(rand.Reader, binary.BigEndian, &output) - if err != nil { - panic("dns: reading random id failed: " + err.Error()) - } - return output -} - -// MsgHdr is a a manually-unpacked version of (id, bits). -type MsgHdr struct { - Id uint16 - Response bool - Opcode int - Authoritative bool - Truncated bool - RecursionDesired bool - RecursionAvailable bool - Zero bool - AuthenticatedData bool - CheckingDisabled bool - Rcode int -} - -// Msg contains the layout of a DNS message. -type Msg struct { - MsgHdr - Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. - Question []Question // Holds the RR(s) of the question section. - Answer []RR // Holds the RR(s) of the answer section. - Ns []RR // Holds the RR(s) of the authority section. - Extra []RR // Holds the RR(s) of the additional section. -} - -// ClassToString is a maps Classes to strings for each CLASS wire type. -var ClassToString = map[uint16]string{ - ClassINET: "IN", - ClassCSNET: "CS", - ClassCHAOS: "CH", - ClassHESIOD: "HS", - ClassNONE: "NONE", - ClassANY: "ANY", -} - -// OpcodeToString maps Opcodes to strings. -var OpcodeToString = map[int]string{ - OpcodeQuery: "QUERY", - OpcodeIQuery: "IQUERY", - OpcodeStatus: "STATUS", - OpcodeNotify: "NOTIFY", - OpcodeUpdate: "UPDATE", -} - -// RcodeToString maps Rcodes to strings. -var RcodeToString = map[int]string{ - RcodeSuccess: "NOERROR", - RcodeFormatError: "FORMERR", - RcodeServerFailure: "SERVFAIL", - RcodeNameError: "NXDOMAIN", - RcodeNotImplemented: "NOTIMP", - RcodeRefused: "REFUSED", - RcodeYXDomain: "YXDOMAIN", // See RFC 2136 - RcodeYXRrset: "YXRRSET", - RcodeNXRrset: "NXRRSET", - RcodeNotAuth: "NOTAUTH", - RcodeNotZone: "NOTZONE", - RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891 - // RcodeBadVers: "BADVERS", - RcodeBadKey: "BADKEY", - RcodeBadTime: "BADTIME", - RcodeBadMode: "BADMODE", - RcodeBadName: "BADNAME", - RcodeBadAlg: "BADALG", - RcodeBadTrunc: "BADTRUNC", - RcodeBadCookie: "BADCOOKIE", -} - -// compressionMap is used to allow a more efficient compression map -// to be used for internal packDomainName calls without changing the -// signature or functionality of public API. -// -// In particular, map[string]uint16 uses 25% less per-entry memory -// than does map[string]int. -type compressionMap struct { - ext map[string]int // external callers - int map[string]uint16 // internal callers -} - -func (m compressionMap) valid() bool { - return m.int != nil || m.ext != nil -} - -func (m compressionMap) insert(s string, pos int) { - if m.ext != nil { - m.ext[s] = pos - } else { - m.int[s] = uint16(pos) - } -} - -func (m compressionMap) find(s string) (int, bool) { - if m.ext != nil { - pos, ok := m.ext[s] - return pos, ok - } - - pos, ok := m.int[s] - return int(pos), ok -} - -// Domain names are a sequence of counted strings -// split at the dots. They end with a zero-length string. - -// PackDomainName packs a domain name s into msg[off:]. -// If compression is wanted compress must be true and the compression -// map needs to hold a mapping between domain names and offsets -// pointing into msg. -func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - return packDomainName(s, msg, off, compressionMap{ext: compression}, compress) -} - -func packDomainName(s string, msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - // XXX: A logical copy of this function exists in IsDomainName and - // should be kept in sync with this function. - - ls := len(s) - if ls == 0 { // Ok, for instance when dealing with update RR without any rdata. - return off, nil - } - - // If not fully qualified, error out. - if !IsFqdn(s) { - return len(msg), ErrFqdn - } - - // Each dot ends a segment of the name. - // We trade each dot byte for a length byte. - // Except for escaped dots (\.), which are normal dots. - // There is also a trailing zero. - - // Compression - pointer := -1 - - // Emit sequence of counted strings, chopping at dots. - var ( - begin int - compBegin int - compOff int - bs []byte - wasDot bool - ) -loop: - for i := 0; i < ls; i++ { - var c byte - if bs == nil { - c = s[i] - } else { - c = bs[i] - } - - switch c { - case '\\': - if off+1 > len(msg) { - return len(msg), ErrBuf - } - - if bs == nil { - bs = []byte(s) - } - - // check for \DDD - if isDDD(bs[i+1:]) { - bs[i] = dddToByte(bs[i+1:]) - copy(bs[i+1:ls-3], bs[i+4:]) - ls -= 3 - compOff += 3 - } else { - copy(bs[i:ls-1], bs[i+1:]) - ls-- - compOff++ - } - - wasDot = false - case '.': - if i == 0 && len(s) > 1 { - // leading dots are not legal except for the root zone - return len(msg), ErrRdata - } - - if wasDot { - // two dots back to back is not legal - return len(msg), ErrRdata - } - wasDot = true - - labelLen := i - begin - if labelLen >= 1<<6 { // top two bits of length must be clear - return len(msg), ErrRdata - } - - // off can already (we're in a loop) be bigger than len(msg) - // this happens when a name isn't fully qualified - if off+1+labelLen > len(msg) { - return len(msg), ErrBuf - } - - // Don't try to compress '.' - // We should only compress when compress is true, but we should also still pick - // up names that can be used for *future* compression(s). - if compression.valid() && !isRootLabel(s, bs, begin, ls) { - if p, ok := compression.find(s[compBegin:]); ok { - // The first hit is the longest matching dname - // keep the pointer offset we get back and store - // the offset of the current name, because that's - // where we need to insert the pointer later - - // If compress is true, we're allowed to compress this dname - if compress { - pointer = p // Where to point to - break loop - } - } else if off < maxCompressionOffset { - // Only offsets smaller than maxCompressionOffset can be used. - compression.insert(s[compBegin:], off) - } - } - - // The following is covered by the length check above. - msg[off] = byte(labelLen) - - if bs == nil { - copy(msg[off+1:], s[begin:i]) - } else { - copy(msg[off+1:], bs[begin:i]) - } - off += 1 + labelLen - - begin = i + 1 - compBegin = begin + compOff - default: - wasDot = false - } - } - - // Root label is special - if isRootLabel(s, bs, 0, ls) { - return off, nil - } - - // If we did compression and we find something add the pointer here - if pointer != -1 { - // We have two bytes (14 bits) to put the pointer in - binary.BigEndian.PutUint16(msg[off:], uint16(pointer^0xC000)) - return off + 2, nil - } - - if off < len(msg) { - msg[off] = 0 - } - - return off + 1, nil -} - -// isRootLabel returns whether s or bs, from off to end, is the root -// label ".". -// -// If bs is nil, s will be checked, otherwise bs will be checked. -func isRootLabel(s string, bs []byte, off, end int) bool { - if bs == nil { - return s[off:end] == "." - } - - return end-off == 1 && bs[off] == '.' -} - -// Unpack a domain name. -// In addition to the simple sequences of counted strings above, -// domain names are allowed to refer to strings elsewhere in the -// packet, to avoid repeating common suffixes when returning -// many entries in a single domain. The pointers are marked -// by a length byte with the top two bits set. Ignoring those -// two bits, that byte and the next give a 14 bit offset from msg[0] -// where we should pick up the trail. -// Note that if we jump elsewhere in the packet, -// we return off1 == the offset after the first pointer we found, -// which is where the next record will start. -// In theory, the pointers are only allowed to jump backward. -// We let them jump anywhere and stop jumping after a while. - -// UnpackDomainName unpacks a domain name into a string. It returns -// the name, the new offset into msg and any error that occurred. -// -// When an error is encountered, the unpacked name will be discarded -// and len(msg) will be returned as the offset. -func UnpackDomainName(msg []byte, off int) (string, int, error) { - s := make([]byte, 0, maxDomainNamePresentationLength) - off1 := 0 - lenmsg := len(msg) - budget := maxDomainNameWireOctets - ptr := 0 // number of pointers followed -Loop: - for { - if off >= lenmsg { - return "", lenmsg, ErrBuf - } - c := int(msg[off]) - off++ - switch c & 0xC0 { - case 0x00: - if c == 0x00 { - // end of name - break Loop - } - // literal string - if off+c > lenmsg { - return "", lenmsg, ErrBuf - } - budget -= c + 1 // +1 for the label separator - if budget <= 0 { - return "", lenmsg, ErrLongDomain - } - for _, b := range msg[off : off+c] { - if isDomainNameLabelSpecial(b) { - s = append(s, '\\', b) - } else if b < ' ' || b > '~' { - s = append(s, escapeByte(b)...) - } else { - s = append(s, b) - } - } - s = append(s, '.') - off += c - case 0xC0: - // pointer to somewhere else in msg. - // remember location after first ptr, - // since that's how many bytes we consumed. - // also, don't follow too many pointers -- - // maybe there's a loop. - if off >= lenmsg { - return "", lenmsg, ErrBuf - } - c1 := msg[off] - off++ - if ptr == 0 { - off1 = off - } - if ptr++; ptr > maxCompressionPointers { - return "", lenmsg, &Error{err: "too many compression pointers"} - } - // pointer should guarantee that it advances and points forwards at least - // but the condition on previous three lines guarantees that it's - // at least loop-free - off = (c^0xC0)<<8 | int(c1) - default: - // 0x80 and 0x40 are reserved - return "", lenmsg, ErrRdata - } - } - if ptr == 0 { - off1 = off - } - if len(s) == 0 { - return ".", off1, nil - } - return string(s), off1, nil -} - -func packTxt(txt []string, msg []byte, offset int) (int, error) { - if len(txt) == 0 { - if offset >= len(msg) { - return offset, ErrBuf - } - msg[offset] = 0 - return offset, nil - } - var err error - for _, s := range txt { - offset, err = packTxtString(s, msg, offset) - if err != nil { - return offset, err - } - } - return offset, nil -} - -func packTxtString(s string, msg []byte, offset int) (int, error) { - lenByteOffset := offset - if offset >= len(msg) || len(s) > 256*4+1 /* If all \DDD */ { - return offset, ErrBuf - } - offset++ - for i := 0; i < len(s); i++ { - if len(msg) <= offset { - return offset, ErrBuf - } - if s[i] == '\\' { - i++ - if i == len(s) { - break - } - // check for \DDD - if isDDD(s[i:]) { - msg[offset] = dddToByte(s[i:]) - i += 2 - } else { - msg[offset] = s[i] - } - } else { - msg[offset] = s[i] - } - offset++ - } - l := offset - lenByteOffset - 1 - if l > 255 { - return offset, &Error{err: "string exceeded 255 bytes in txt"} - } - msg[lenByteOffset] = byte(l) - return offset, nil -} - -func packOctetString(s string, msg []byte, offset int) (int, error) { - if offset >= len(msg) || len(s) > 256*4+1 { - return offset, ErrBuf - } - for i := 0; i < len(s); i++ { - if len(msg) <= offset { - return offset, ErrBuf - } - if s[i] == '\\' { - i++ - if i == len(s) { - break - } - // check for \DDD - if isDDD(s[i:]) { - msg[offset] = dddToByte(s[i:]) - i += 2 - } else { - msg[offset] = s[i] - } - } else { - msg[offset] = s[i] - } - offset++ - } - return offset, nil -} - -func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) { - off = off0 - var s string - for off < len(msg) && err == nil { - s, off, err = unpackString(msg, off) - if err == nil { - ss = append(ss, s) - } - } - return -} - -// Helpers for dealing with escaped bytes -func isDigit(b byte) bool { return b >= '0' && b <= '9' } - -func isDDD[T ~[]byte | ~string](s T) bool { - return len(s) >= 3 && isDigit(s[0]) && isDigit(s[1]) && isDigit(s[2]) -} - -func dddToByte[T ~[]byte | ~string](s T) byte { - _ = s[2] // bounds check hint to compiler; see golang.org/issue/14808 - return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) -} - -// Helper function for packing and unpacking -func intToBytes(i *big.Int, length int) []byte { - buf := i.Bytes() - if len(buf) < length { - b := make([]byte, length) - copy(b[length-len(buf):], buf) - return b - } - return buf -} - -// PackRR packs a resource record rr into msg[off:]. -// See PackDomainName for documentation about the compression. -func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - headerEnd, off1, err := packRR(rr, msg, off, compressionMap{ext: compression}, compress) - if err == nil { - // packRR no longer sets the Rdlength field on the rr, but - // callers might be expecting it so we set it here. - rr.Header().Rdlength = uint16(off1 - headerEnd) - } - return off1, err -} - -func packRR(rr RR, msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error) { - if rr == nil { - return len(msg), len(msg), &Error{err: "nil rr"} - } - - headerEnd, err = rr.Header().packHeader(msg, off, compression, compress) - if err != nil { - return headerEnd, len(msg), err - } - - off1, err = rr.pack(msg, headerEnd, compression, compress) - if err != nil { - return headerEnd, len(msg), err - } - - rdlength := off1 - headerEnd - if int(uint16(rdlength)) != rdlength { // overflow - return headerEnd, len(msg), ErrRdata - } - - // The RDLENGTH field is the last field in the header and we set it here. - binary.BigEndian.PutUint16(msg[headerEnd-2:], uint16(rdlength)) - return headerEnd, off1, nil -} - -// UnpackRR unpacks msg[off:] into an RR. -func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) { - h, off, msg, err := unpackHeader(msg, off) - if err != nil { - return nil, len(msg), err - } - - return UnpackRRWithHeader(h, msg, off) -} - -// UnpackRRWithHeader unpacks the record type specific payload given an existing -// RR_Header. -func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err error) { - if newFn, ok := TypeToRR[h.Rrtype]; ok { - rr = newFn() - *rr.Header() = h - } else { - rr = &RFC3597{Hdr: h} - } - - if off < 0 || off > len(msg) { - return &h, off, &Error{err: "bad off"} - } - - end := off + int(h.Rdlength) - if end < off || end > len(msg) { - return &h, end, &Error{err: "bad rdlength"} - } - - if noRdata(h) { - return rr, off, nil - } - - off, err = rr.unpack(msg, off) - if err != nil { - return nil, end, err - } - if off != end { - return &h, end, &Error{err: "bad rdlength"} - } - - return rr, off, nil -} - -// unpackRRslice unpacks msg[off:] into an []RR. -// If we cannot unpack the whole array, then it will return nil -func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) { - var r RR - // Don't pre-allocate, l may be under attacker control - var dst []RR - for i := 0; i < l; i++ { - off1 := off - r, off, err = UnpackRR(msg, off) - if err != nil { - off = len(msg) - break - } - // If offset does not increase anymore, l is a lie - if off1 == off { - break - } - dst = append(dst, r) - } - if err != nil && off == len(msg) { - dst = nil - } - return dst, off, err -} - -// Convert a MsgHdr to a string, with dig-like headers: -// -// ;; opcode: QUERY, status: NOERROR, id: 48404 -// -// ;; flags: qr aa rd ra; -func (h *MsgHdr) String() string { - if h == nil { - return " MsgHdr" - } - - s := ";; opcode: " + OpcodeToString[h.Opcode] - s += ", status: " + RcodeToString[h.Rcode] - s += ", id: " + strconv.Itoa(int(h.Id)) + "\n" - - s += ";; flags:" - if h.Response { - s += " qr" - } - if h.Authoritative { - s += " aa" - } - if h.Truncated { - s += " tc" - } - if h.RecursionDesired { - s += " rd" - } - if h.RecursionAvailable { - s += " ra" - } - if h.Zero { // Hmm - s += " z" - } - if h.AuthenticatedData { - s += " ad" - } - if h.CheckingDisabled { - s += " cd" - } - - s += ";" - return s -} - -// Pack packs a Msg: it is converted to to wire format. -// If the dns.Compress is true the message will be in compressed wire format. -func (dns *Msg) Pack() (msg []byte, err error) { - return dns.PackBuffer(nil) -} - -// PackBuffer packs a Msg, using the given buffer buf. If buf is too small a new buffer is allocated. -func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) { - // If this message can't be compressed, avoid filling the - // compression map and creating garbage. - if dns.Compress && dns.isCompressible() { - compression := make(map[string]uint16) // Compression pointer mappings. - return dns.packBufferWithCompressionMap(buf, compressionMap{int: compression}, true) - } - - return dns.packBufferWithCompressionMap(buf, compressionMap{}, false) -} - -// packBufferWithCompressionMap packs a Msg, using the given buffer buf. -func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression compressionMap, compress bool) (msg []byte, err error) { - if dns.Rcode < 0 || dns.Rcode > 0xFFF { - return nil, ErrRcode - } - - // Set extended rcode unconditionally if we have an opt, this will allow - // resetting the extended rcode bits if they need to. - if opt := dns.IsEdns0(); opt != nil { - opt.SetExtendedRcode(uint16(dns.Rcode)) - } else if dns.Rcode > 0xF { - // If Rcode is an extended one and opt is nil, error out. - return nil, ErrExtendedRcode - } - - // Convert convenient Msg into wire-like Header. - var dh Header - dh.Id = dns.Id - dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode&0xF) - if dns.Response { - dh.Bits |= _QR - } - if dns.Authoritative { - dh.Bits |= _AA - } - if dns.Truncated { - dh.Bits |= _TC - } - if dns.RecursionDesired { - dh.Bits |= _RD - } - if dns.RecursionAvailable { - dh.Bits |= _RA - } - if dns.Zero { - dh.Bits |= _Z - } - if dns.AuthenticatedData { - dh.Bits |= _AD - } - if dns.CheckingDisabled { - dh.Bits |= _CD - } - - dh.Qdcount = uint16(len(dns.Question)) - dh.Ancount = uint16(len(dns.Answer)) - dh.Nscount = uint16(len(dns.Ns)) - dh.Arcount = uint16(len(dns.Extra)) - - // We need the uncompressed length here, because we first pack it and then compress it. - msg = buf - uncompressedLen := msgLenWithCompressionMap(dns, nil) - if packLen := uncompressedLen + 1; len(msg) < packLen { - msg = make([]byte, packLen) - } - - // Pack it in: header and then the pieces. - off := 0 - off, err = dh.pack(msg, off, compression, compress) - if err != nil { - return nil, err - } - for _, r := range dns.Question { - off, err = r.pack(msg, off, compression, compress) - if err != nil { - return nil, err - } - } - for _, r := range dns.Answer { - _, off, err = packRR(r, msg, off, compression, compress) - if err != nil { - return nil, err - } - } - for _, r := range dns.Ns { - _, off, err = packRR(r, msg, off, compression, compress) - if err != nil { - return nil, err - } - } - for _, r := range dns.Extra { - _, off, err = packRR(r, msg, off, compression, compress) - if err != nil { - return nil, err - } - } - return msg[:off], nil -} - -func (dns *Msg) unpack(dh Header, msg []byte, off int) (err error) { - // If we are at the end of the message we should return *just* the - // header. This can still be useful to the caller. 9.9.9.9 sends these - // when responding with REFUSED for instance. - if off == len(msg) { - // reset sections before returning - dns.Question, dns.Answer, dns.Ns, dns.Extra = nil, nil, nil, nil - return nil - } - - // Qdcount, Ancount, Nscount, Arcount can't be trusted, as they are - // attacker controlled. This means we can't use them to pre-allocate - // slices. - dns.Question = nil - for i := 0; i < int(dh.Qdcount); i++ { - off1 := off - var q Question - q, off, err = unpackQuestion(msg, off) - if err != nil { - return err - } - if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie! - dh.Qdcount = uint16(i) - break - } - dns.Question = append(dns.Question, q) - } - - dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off) - // The header counts might have been wrong so we need to update it - dh.Ancount = uint16(len(dns.Answer)) - if err == nil { - dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off) - } - // The header counts might have been wrong so we need to update it - dh.Nscount = uint16(len(dns.Ns)) - if err == nil { - dns.Extra, _, err = unpackRRslice(int(dh.Arcount), msg, off) - } - // The header counts might have been wrong so we need to update it - dh.Arcount = uint16(len(dns.Extra)) - - // Set extended Rcode - if opt := dns.IsEdns0(); opt != nil { - dns.Rcode |= opt.ExtendedRcode() - } - - // TODO(miek) make this an error? - // use PackOpt to let people tell how detailed the error reporting should be? - // if off != len(msg) { - // // println("dns: extra bytes in dns packet", off, "<", len(msg)) - // } - return err - -} - -// Unpack unpacks a binary message to a Msg structure. -func (dns *Msg) Unpack(msg []byte) (err error) { - dh, off, err := unpackMsgHdr(msg, 0) - if err != nil { - return err - } - - dns.setHdr(dh) - return dns.unpack(dh, msg, off) -} - -// Convert a complete message to a string with dig-like output. -func (dns *Msg) String() string { - if dns == nil { - return " MsgHdr" - } - s := dns.MsgHdr.String() + " " - if dns.MsgHdr.Opcode == OpcodeUpdate { - s += "ZONE: " + strconv.Itoa(len(dns.Question)) + ", " - s += "PREREQ: " + strconv.Itoa(len(dns.Answer)) + ", " - s += "UPDATE: " + strconv.Itoa(len(dns.Ns)) + ", " - s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n" - } else { - s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", " - s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", " - s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", " - s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n" - } - opt := dns.IsEdns0() - if opt != nil { - // OPT PSEUDOSECTION - s += opt.String() + "\n" - } - if len(dns.Question) > 0 { - if dns.MsgHdr.Opcode == OpcodeUpdate { - s += "\n;; ZONE SECTION:\n" - } else { - s += "\n;; QUESTION SECTION:\n" - } - for _, r := range dns.Question { - s += r.String() + "\n" - } - } - if len(dns.Answer) > 0 { - if dns.MsgHdr.Opcode == OpcodeUpdate { - s += "\n;; PREREQUISITE SECTION:\n" - } else { - s += "\n;; ANSWER SECTION:\n" - } - for _, r := range dns.Answer { - if r != nil { - s += r.String() + "\n" - } - } - } - if len(dns.Ns) > 0 { - if dns.MsgHdr.Opcode == OpcodeUpdate { - s += "\n;; UPDATE SECTION:\n" - } else { - s += "\n;; AUTHORITY SECTION:\n" - } - for _, r := range dns.Ns { - if r != nil { - s += r.String() + "\n" - } - } - } - if len(dns.Extra) > 0 && (opt == nil || len(dns.Extra) > 1) { - s += "\n;; ADDITIONAL SECTION:\n" - for _, r := range dns.Extra { - if r != nil && r.Header().Rrtype != TypeOPT { - s += r.String() + "\n" - } - } - } - return s -} - -// isCompressible returns whether the msg may be compressible. -func (dns *Msg) isCompressible() bool { - // If we only have one question, there is nothing we can ever compress. - return len(dns.Question) > 1 || len(dns.Answer) > 0 || - len(dns.Ns) > 0 || len(dns.Extra) > 0 -} - -// Len returns the message length when in (un)compressed wire format. -// If dns.Compress is true compression it is taken into account. Len() -// is provided to be a faster way to get the size of the resulting packet, -// than packing it, measuring the size and discarding the buffer. -func (dns *Msg) Len() int { - // If this message can't be compressed, avoid filling the - // compression map and creating garbage. - if dns.Compress && dns.isCompressible() { - compression := make(map[string]struct{}) - return msgLenWithCompressionMap(dns, compression) - } - - return msgLenWithCompressionMap(dns, nil) -} - -func msgLenWithCompressionMap(dns *Msg, compression map[string]struct{}) int { - l := headerSize - - for _, r := range dns.Question { - l += r.len(l, compression) - } - for _, r := range dns.Answer { - if r != nil { - l += r.len(l, compression) - } - } - for _, r := range dns.Ns { - if r != nil { - l += r.len(l, compression) - } - } - for _, r := range dns.Extra { - if r != nil { - l += r.len(l, compression) - } - } - - return l -} - -func domainNameLen(s string, off int, compression map[string]struct{}, compress bool) int { - if s == "" || s == "." { - return 1 - } - - escaped := strings.Contains(s, "\\") - - if compression != nil && (compress || off < maxCompressionOffset) { - // compressionLenSearch will insert the entry into the compression - // map if it doesn't contain it. - if l, ok := compressionLenSearch(compression, s, off); ok && compress { - if escaped { - return escapedNameLen(s[:l]) + 2 - } - - return l + 2 - } - } - - if escaped { - return escapedNameLen(s) + 1 - } - - return len(s) + 1 -} - -func escapedNameLen(s string) int { - nameLen := len(s) - for i := 0; i < len(s); i++ { - if s[i] != '\\' { - continue - } - - if isDDD(s[i+1:]) { - nameLen -= 3 - i += 3 - } else { - nameLen-- - i++ - } - } - - return nameLen -} - -func compressionLenSearch(c map[string]struct{}, s string, msgOff int) (int, bool) { - for off, end := 0, false; !end; off, end = NextLabel(s, off) { - if _, ok := c[s[off:]]; ok { - return off, true - } - - if msgOff+off < maxCompressionOffset { - c[s[off:]] = struct{}{} - } - } - - return 0, false -} - -// Copy returns a new RR which is a deep-copy of r. -func Copy(r RR) RR { return r.copy() } - -// Len returns the length (in octets) of the uncompressed RR in wire format. -func Len(r RR) int { return r.len(0, nil) } - -// Copy returns a new *Msg which is a deep-copy of dns. -func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) } - -// CopyTo copies the contents to the provided message using a deep-copy and returns the copy. -func (dns *Msg) CopyTo(r1 *Msg) *Msg { - r1.MsgHdr = dns.MsgHdr - r1.Compress = dns.Compress - - if len(dns.Question) > 0 { - // TODO(miek): Question is an immutable value, ok to do a shallow-copy - r1.Question = cloneSlice(dns.Question) - } - - rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra)) - r1.Answer, rrArr = rrArr[:0:len(dns.Answer)], rrArr[len(dns.Answer):] - r1.Ns, rrArr = rrArr[:0:len(dns.Ns)], rrArr[len(dns.Ns):] - r1.Extra = rrArr[:0:len(dns.Extra)] - - for _, r := range dns.Answer { - r1.Answer = append(r1.Answer, r.copy()) - } - - for _, r := range dns.Ns { - r1.Ns = append(r1.Ns, r.copy()) - } - - for _, r := range dns.Extra { - r1.Extra = append(r1.Extra, r.copy()) - } - - return r1 -} - -func (q *Question) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := packDomainName(q.Name, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packUint16(q.Qtype, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(q.Qclass, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func unpackQuestion(msg []byte, off int) (Question, int, error) { - var ( - q Question - err error - ) - q.Name, off, err = UnpackDomainName(msg, off) - if err != nil { - return q, off, err - } - if off == len(msg) { - return q, off, nil - } - q.Qtype, off, err = unpackUint16(msg, off) - if err != nil { - return q, off, err - } - if off == len(msg) { - return q, off, nil - } - q.Qclass, off, err = unpackUint16(msg, off) - if off == len(msg) { - return q, off, nil - } - return q, off, err -} - -func (dh *Header) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := packUint16(dh.Id, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Bits, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Qdcount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Ancount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Nscount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Arcount, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func unpackMsgHdr(msg []byte, off int) (Header, int, error) { - var ( - dh Header - err error - ) - dh.Id, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Bits, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Qdcount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Ancount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Nscount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Arcount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - return dh, off, nil -} - -// setHdr set the header in the dns using the binary data in dh. -func (dns *Msg) setHdr(dh Header) { - dns.Id = dh.Id - dns.Response = dh.Bits&_QR != 0 - dns.Opcode = int(dh.Bits>>11) & 0xF - dns.Authoritative = dh.Bits&_AA != 0 - dns.Truncated = dh.Bits&_TC != 0 - dns.RecursionDesired = dh.Bits&_RD != 0 - dns.RecursionAvailable = dh.Bits&_RA != 0 - dns.Zero = dh.Bits&_Z != 0 // _Z covers the zero bit, which should be zero; not sure why we set it to the opposite. - dns.AuthenticatedData = dh.Bits&_AD != 0 - dns.CheckingDisabled = dh.Bits&_CD != 0 - dns.Rcode = int(dh.Bits & 0xF) -} diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go deleted file mode 100644 index acec21f..0000000 --- a/vendor/github.com/miekg/dns/msg_helpers.go +++ /dev/null @@ -1,834 +0,0 @@ -package dns - -import ( - "encoding/base32" - "encoding/base64" - "encoding/binary" - "encoding/hex" - "net" - "sort" - "strings" -) - -// helper functions called from the generated zmsg.go - -// These function are named after the tag to help pack/unpack, if there is no tag it is the name -// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or -// packDataDomainName. - -func unpackDataA(msg []byte, off int) (net.IP, int, error) { - if off+net.IPv4len > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking a"} - } - return cloneSlice(msg[off : off+net.IPv4len]), off + net.IPv4len, nil -} - -func packDataA(a net.IP, msg []byte, off int) (int, error) { - switch len(a) { - case net.IPv4len, net.IPv6len: - // It must be a slice of 4, even if it is 16, we encode only the first 4 - if off+net.IPv4len > len(msg) { - return len(msg), &Error{err: "overflow packing a"} - } - - copy(msg[off:], a.To4()) - off += net.IPv4len - case 0: - // Allowed, for dynamic updates. - default: - return len(msg), &Error{err: "overflow packing a"} - } - return off, nil -} - -func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) { - if off+net.IPv6len > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking aaaa"} - } - return cloneSlice(msg[off : off+net.IPv6len]), off + net.IPv6len, nil -} - -func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) { - switch len(aaaa) { - case net.IPv6len: - if off+net.IPv6len > len(msg) { - return len(msg), &Error{err: "overflow packing aaaa"} - } - - copy(msg[off:], aaaa) - off += net.IPv6len - case 0: - // Allowed, dynamic updates. - default: - return len(msg), &Error{err: "overflow packing aaaa"} - } - return off, nil -} - -// unpackHeader unpacks an RR header, returning the offset to the end of the header and a -// re-sliced msg according to the expected length of the RR. -func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) { - hdr := RR_Header{} - if off == len(msg) { - return hdr, off, msg, nil - } - - hdr.Name, off, err = UnpackDomainName(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Rrtype, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Class, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Ttl, off, err = unpackUint32(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Rdlength, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength) - return hdr, off, msg, err -} - -// packHeader packs an RR header, returning the offset to the end of the header. -// See PackDomainName for documentation about the compression. -func (hdr RR_Header) packHeader(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - if off == len(msg) { - return off, nil - } - - off, err := packDomainName(hdr.Name, msg, off, compression, compress) - if err != nil { - return len(msg), err - } - off, err = packUint16(hdr.Rrtype, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint16(hdr.Class, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint32(hdr.Ttl, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR. - if err != nil { - return len(msg), err - } - return off, nil -} - -// helper helper functions. - -// truncateMsgFromRdLength truncates msg to match the expected length of the RR. -// Returns an error if msg is smaller than the expected size. -func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) { - lenrd := off + int(rdlength) - if lenrd > len(msg) { - return msg, &Error{err: "overflowing header size"} - } - return msg[:lenrd], nil -} - -var base32HexNoPadEncoding = base32.HexEncoding.WithPadding(base32.NoPadding) - -func fromBase32(s []byte) (buf []byte, err error) { - for i, b := range s { - if b >= 'a' && b <= 'z' { - s[i] = b - 32 - } - } - buflen := base32HexNoPadEncoding.DecodedLen(len(s)) - buf = make([]byte, buflen) - n, err := base32HexNoPadEncoding.Decode(buf, s) - buf = buf[:n] - return -} - -func toBase32(b []byte) string { - return base32HexNoPadEncoding.EncodeToString(b) -} - -func fromBase64(s []byte) (buf []byte, err error) { - buflen := base64.StdEncoding.DecodedLen(len(s)) - buf = make([]byte, buflen) - n, err := base64.StdEncoding.Decode(buf, s) - buf = buf[:n] - return -} - -func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } - -// dynamicUpdate returns true if the Rdlength is zero. -func noRdata(h RR_Header) bool { return h.Rdlength == 0 } - -func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) { - if off+1 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint8"} - } - return msg[off], off + 1, nil -} - -func packUint8(i uint8, msg []byte, off int) (off1 int, err error) { - if off+1 > len(msg) { - return len(msg), &Error{err: "overflow packing uint8"} - } - msg[off] = i - return off + 1, nil -} - -func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) { - if off+2 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint16"} - } - return binary.BigEndian.Uint16(msg[off:]), off + 2, nil -} - -func packUint16(i uint16, msg []byte, off int) (off1 int, err error) { - if off+2 > len(msg) { - return len(msg), &Error{err: "overflow packing uint16"} - } - binary.BigEndian.PutUint16(msg[off:], i) - return off + 2, nil -} - -func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) { - if off+4 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint32"} - } - return binary.BigEndian.Uint32(msg[off:]), off + 4, nil -} - -func packUint32(i uint32, msg []byte, off int) (off1 int, err error) { - if off+4 > len(msg) { - return len(msg), &Error{err: "overflow packing uint32"} - } - binary.BigEndian.PutUint32(msg[off:], i) - return off + 4, nil -} - -func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) { - if off+6 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"} - } - // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes) - i = uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 | - uint64(msg[off+4])<<8 | uint64(msg[off+5]) - off += 6 - return i, off, nil -} - -func packUint48(i uint64, msg []byte, off int) (off1 int, err error) { - if off+6 > len(msg) { - return len(msg), &Error{err: "overflow packing uint64 as uint48"} - } - msg[off] = byte(i >> 40) - msg[off+1] = byte(i >> 32) - msg[off+2] = byte(i >> 24) - msg[off+3] = byte(i >> 16) - msg[off+4] = byte(i >> 8) - msg[off+5] = byte(i) - off += 6 - return off, nil -} - -func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) { - if off+8 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint64"} - } - return binary.BigEndian.Uint64(msg[off:]), off + 8, nil -} - -func packUint64(i uint64, msg []byte, off int) (off1 int, err error) { - if off+8 > len(msg) { - return len(msg), &Error{err: "overflow packing uint64"} - } - binary.BigEndian.PutUint64(msg[off:], i) - off += 8 - return off, nil -} - -func unpackString(msg []byte, off int) (string, int, error) { - if off+1 > len(msg) { - return "", off, &Error{err: "overflow unpacking txt"} - } - l := int(msg[off]) - off++ - if off+l > len(msg) { - return "", off, &Error{err: "overflow unpacking txt"} - } - var s strings.Builder - consumed := 0 - for i, b := range msg[off : off+l] { - switch { - case b == '"' || b == '\\': - if consumed == 0 { - s.Grow(l * 2) - } - s.Write(msg[off+consumed : off+i]) - s.WriteByte('\\') - s.WriteByte(b) - consumed = i + 1 - case b < ' ' || b > '~': // unprintable - if consumed == 0 { - s.Grow(l * 2) - } - s.Write(msg[off+consumed : off+i]) - s.WriteString(escapeByte(b)) - consumed = i + 1 - } - } - if consumed == 0 { // no escaping needed - return string(msg[off : off+l]), off + l, nil - } - s.Write(msg[off+consumed : off+l]) - return s.String(), off + l, nil -} - -func packString(s string, msg []byte, off int) (int, error) { - off, err := packTxtString(s, msg, off) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackStringBase32(msg []byte, off, end int) (string, int, error) { - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking base32"} - } - s := toBase32(msg[off:end]) - return s, end, nil -} - -func packStringBase32(s string, msg []byte, off int) (int, error) { - b32, err := fromBase32([]byte(s)) - if err != nil { - return len(msg), err - } - if off+len(b32) > len(msg) { - return len(msg), &Error{err: "overflow packing base32"} - } - copy(msg[off:off+len(b32)], b32) - off += len(b32) - return off, nil -} - -func unpackStringBase64(msg []byte, off, end int) (string, int, error) { - // Rest of the RR is base64 encoded value, so we don't need an explicit length - // to be set. Thus far all RR's that have base64 encoded fields have those as their - // last one. What we do need is the end of the RR! - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking base64"} - } - s := toBase64(msg[off:end]) - return s, end, nil -} - -func packStringBase64(s string, msg []byte, off int) (int, error) { - b64, err := fromBase64([]byte(s)) - if err != nil { - return len(msg), err - } - if off+len(b64) > len(msg) { - return len(msg), &Error{err: "overflow packing base64"} - } - copy(msg[off:off+len(b64)], b64) - off += len(b64) - return off, nil -} - -func unpackStringHex(msg []byte, off, end int) (string, int, error) { - // Rest of the RR is hex encoded value, so we don't need an explicit length - // to be set. NSEC and TSIG have hex fields with a length field. - // What we do need is the end of the RR! - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking hex"} - } - - s := hex.EncodeToString(msg[off:end]) - return s, end, nil -} - -func packStringHex(s string, msg []byte, off int) (int, error) { - h, err := hex.DecodeString(s) - if err != nil { - return len(msg), err - } - if off+len(h) > len(msg) { - return len(msg), &Error{err: "overflow packing hex"} - } - copy(msg[off:off+len(h)], h) - off += len(h) - return off, nil -} - -func unpackStringAny(msg []byte, off, end int) (string, int, error) { - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking anything"} - } - return string(msg[off:end]), end, nil -} - -func packStringAny(s string, msg []byte, off int) (int, error) { - if off+len(s) > len(msg) { - return len(msg), &Error{err: "overflow packing anything"} - } - copy(msg[off:off+len(s)], s) - off += len(s) - return off, nil -} - -func unpackStringTxt(msg []byte, off int) ([]string, int, error) { - txt, off, err := unpackTxt(msg, off) - if err != nil { - return nil, len(msg), err - } - return txt, off, nil -} - -func packStringTxt(s []string, msg []byte, off int) (int, error) { - off, err := packTxt(s, msg, off) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { - var edns []EDNS0 - for off < len(msg) { - if off+4 > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking opt"} - } - code := binary.BigEndian.Uint16(msg[off:]) - off += 2 - optlen := binary.BigEndian.Uint16(msg[off:]) - off += 2 - if off+int(optlen) > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking opt"} - } - opt := makeDataOpt(code) - if err := opt.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, opt) - off += int(optlen) - } - return edns, off, nil -} - -func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { - for _, el := range options { - b, err := el.pack() - if err != nil || off+4 > len(msg) { - return len(msg), &Error{err: "overflow packing opt"} - } - binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code - binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length - off += 4 - if off+len(b) > len(msg) { - return len(msg), &Error{err: "overflow packing opt"} - } - // Actual data - copy(msg[off:off+len(b)], b) - off += len(b) - } - return off, nil -} - -func unpackStringOctet(msg []byte, off int) (string, int, error) { - s := string(msg[off:]) - return s, len(msg), nil -} - -func packStringOctet(s string, msg []byte, off int) (int, error) { - off, err := packOctetString(s, msg, off) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { - var nsec []uint16 - length, window, lastwindow := 0, 0, -1 - for off < len(msg) { - if off+2 > len(msg) { - return nsec, len(msg), &Error{err: "overflow unpacking NSEC(3)"} - } - window = int(msg[off]) - length = int(msg[off+1]) - off += 2 - if window <= lastwindow { - // RFC 4034: Blocks are present in the NSEC RR RDATA in - // increasing numerical order. - return nsec, len(msg), &Error{err: "out of order NSEC(3) block in type bitmap"} - } - if length == 0 { - // RFC 4034: Blocks with no types present MUST NOT be included. - return nsec, len(msg), &Error{err: "empty NSEC(3) block in type bitmap"} - } - if length > 32 { - return nsec, len(msg), &Error{err: "NSEC(3) block too long in type bitmap"} - } - if off+length > len(msg) { - return nsec, len(msg), &Error{err: "overflowing NSEC(3) block in type bitmap"} - } - - // Walk the bytes in the window and extract the type bits - for j, b := range msg[off : off+length] { - // Check the bits one by one, and set the type - if b&0x80 == 0x80 { - nsec = append(nsec, uint16(window*256+j*8+0)) - } - if b&0x40 == 0x40 { - nsec = append(nsec, uint16(window*256+j*8+1)) - } - if b&0x20 == 0x20 { - nsec = append(nsec, uint16(window*256+j*8+2)) - } - if b&0x10 == 0x10 { - nsec = append(nsec, uint16(window*256+j*8+3)) - } - if b&0x8 == 0x8 { - nsec = append(nsec, uint16(window*256+j*8+4)) - } - if b&0x4 == 0x4 { - nsec = append(nsec, uint16(window*256+j*8+5)) - } - if b&0x2 == 0x2 { - nsec = append(nsec, uint16(window*256+j*8+6)) - } - if b&0x1 == 0x1 { - nsec = append(nsec, uint16(window*256+j*8+7)) - } - } - off += length - lastwindow = window - } - return nsec, off, nil -} - -// typeBitMapLen is a helper function which computes the "maximum" length of -// a the NSEC Type BitMap field. -func typeBitMapLen(bitmap []uint16) int { - var l int - var lastwindow, lastlength uint16 - for _, t := range bitmap { - window := t / 256 - length := (t-window*256)/8 + 1 - if window > lastwindow && lastlength != 0 { // New window, jump to the new offset - l += int(lastlength) + 2 - lastlength = 0 - } - if window < lastwindow || length < lastlength { - // packDataNsec would return Error{err: "nsec bits out of order"} here, but - // when computing the length, we want do be liberal. - continue - } - lastwindow, lastlength = window, length - } - l += int(lastlength) + 2 - return l -} - -func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { - if len(bitmap) == 0 { - return off, nil - } - if off > len(msg) { - return off, &Error{err: "overflow packing nsec"} - } - toZero := msg[off:] - if maxLen := typeBitMapLen(bitmap); maxLen < len(toZero) { - toZero = toZero[:maxLen] - } - for i := range toZero { - toZero[i] = 0 - } - var lastwindow, lastlength uint16 - for _, t := range bitmap { - window := t / 256 - length := (t-window*256)/8 + 1 - if window > lastwindow && lastlength != 0 { // New window, jump to the new offset - off += int(lastlength) + 2 - lastlength = 0 - } - if window < lastwindow || length < lastlength { - return len(msg), &Error{err: "nsec bits out of order"} - } - if off+2+int(length) > len(msg) { - return len(msg), &Error{err: "overflow packing nsec"} - } - // Setting the window # - msg[off] = byte(window) - // Setting the octets length - msg[off+1] = byte(length) - // Setting the bit value for the type in the right octet - msg[off+1+int(length)] |= byte(1 << (7 - t%8)) - lastwindow, lastlength = window, length - } - off += int(lastlength) + 2 - return off, nil -} - -func unpackDataSVCB(msg []byte, off int) ([]SVCBKeyValue, int, error) { - var xs []SVCBKeyValue - var code uint16 - var length uint16 - var err error - for off < len(msg) { - code, off, err = unpackUint16(msg, off) - if err != nil { - return nil, len(msg), &Error{err: "overflow unpacking SVCB"} - } - length, off, err = unpackUint16(msg, off) - if err != nil || off+int(length) > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking SVCB"} - } - e := makeSVCBKeyValue(SVCBKey(code)) - if e == nil { - return nil, len(msg), &Error{err: "bad SVCB key"} - } - if err := e.unpack(msg[off : off+int(length)]); err != nil { - return nil, len(msg), err - } - if len(xs) > 0 && e.Key() <= xs[len(xs)-1].Key() { - return nil, len(msg), &Error{err: "SVCB keys not in strictly increasing order"} - } - xs = append(xs, e) - off += int(length) - } - return xs, off, nil -} - -func packDataSVCB(pairs []SVCBKeyValue, msg []byte, off int) (int, error) { - pairs = cloneSlice(pairs) - sort.Slice(pairs, func(i, j int) bool { - return pairs[i].Key() < pairs[j].Key() - }) - prev := svcb_RESERVED - for _, el := range pairs { - if el.Key() == prev { - return len(msg), &Error{err: "repeated SVCB keys are not allowed"} - } - prev = el.Key() - packed, err := el.pack() - if err != nil { - return len(msg), err - } - off, err = packUint16(uint16(el.Key()), msg, off) - if err != nil { - return len(msg), &Error{err: "overflow packing SVCB"} - } - off, err = packUint16(uint16(len(packed)), msg, off) - if err != nil || off+len(packed) > len(msg) { - return len(msg), &Error{err: "overflow packing SVCB"} - } - copy(msg[off:off+len(packed)], packed) - off += len(packed) - } - return off, nil -} - -func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { - var ( - servers []string - s string - err error - ) - if end > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking domain names"} - } - for off < end { - s, off, err = UnpackDomainName(msg, off) - if err != nil { - return servers, len(msg), err - } - servers = append(servers, s) - } - return servers, off, nil -} - -func packDataDomainNames(names []string, msg []byte, off int, compression compressionMap, compress bool) (int, error) { - var err error - for _, name := range names { - off, err = packDomainName(name, msg, off, compression, compress) - if err != nil { - return len(msg), err - } - } - return off, nil -} - -func packDataApl(data []APLPrefix, msg []byte, off int) (int, error) { - var err error - for i := range data { - off, err = packDataAplPrefix(&data[i], msg, off) - if err != nil { - return len(msg), err - } - } - return off, nil -} - -func packDataAplPrefix(p *APLPrefix, msg []byte, off int) (int, error) { - if len(p.Network.IP) != len(p.Network.Mask) { - return len(msg), &Error{err: "address and mask lengths don't match"} - } - - var err error - prefix, _ := p.Network.Mask.Size() - addr := p.Network.IP.Mask(p.Network.Mask)[:(prefix+7)/8] - - switch len(p.Network.IP) { - case net.IPv4len: - off, err = packUint16(1, msg, off) - case net.IPv6len: - off, err = packUint16(2, msg, off) - default: - err = &Error{err: "unrecognized address family"} - } - if err != nil { - return len(msg), err - } - - off, err = packUint8(uint8(prefix), msg, off) - if err != nil { - return len(msg), err - } - - var n uint8 - if p.Negation { - n = 0x80 - } - - // trim trailing zero bytes as specified in RFC3123 Sections 4.1 and 4.2. - i := len(addr) - 1 - for ; i >= 0 && addr[i] == 0; i-- { - } - addr = addr[:i+1] - - adflen := uint8(len(addr)) & 0x7f - off, err = packUint8(n|adflen, msg, off) - if err != nil { - return len(msg), err - } - - if off+len(addr) > len(msg) { - return len(msg), &Error{err: "overflow packing APL prefix"} - } - off += copy(msg[off:], addr) - - return off, nil -} - -func unpackDataApl(msg []byte, off int) ([]APLPrefix, int, error) { - var result []APLPrefix - for off < len(msg) { - prefix, end, err := unpackDataAplPrefix(msg, off) - if err != nil { - return nil, len(msg), err - } - off = end - result = append(result, prefix) - } - return result, off, nil -} - -func unpackDataAplPrefix(msg []byte, off int) (APLPrefix, int, error) { - family, off, err := unpackUint16(msg, off) - if err != nil { - return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} - } - prefix, off, err := unpackUint8(msg, off) - if err != nil { - return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} - } - nlen, off, err := unpackUint8(msg, off) - if err != nil { - return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL prefix"} - } - - var ip []byte - switch family { - case 1: - ip = make([]byte, net.IPv4len) - case 2: - ip = make([]byte, net.IPv6len) - default: - return APLPrefix{}, len(msg), &Error{err: "unrecognized APL address family"} - } - if int(prefix) > 8*len(ip) { - return APLPrefix{}, len(msg), &Error{err: "APL prefix too long"} - } - afdlen := int(nlen & 0x7f) - if afdlen > len(ip) { - return APLPrefix{}, len(msg), &Error{err: "APL length too long"} - } - if off+afdlen > len(msg) { - return APLPrefix{}, len(msg), &Error{err: "overflow unpacking APL address"} - } - - // Address MUST NOT contain trailing zero bytes per RFC3123 Sections 4.1 and 4.2. - off += copy(ip, msg[off:off+afdlen]) - if afdlen > 0 { - last := ip[afdlen-1] - if last == 0 { - return APLPrefix{}, len(msg), &Error{err: "extra APL address bits"} - } - } - ipnet := net.IPNet{ - IP: ip, - Mask: net.CIDRMask(int(prefix), 8*len(ip)), - } - - return APLPrefix{ - Negation: (nlen & 0x80) != 0, - Network: ipnet, - }, off, nil -} - -func unpackIPSECGateway(msg []byte, off int, gatewayType uint8) (net.IP, string, int, error) { - var retAddr net.IP - var retString string - var err error - - switch gatewayType { - case IPSECGatewayNone: // do nothing - case IPSECGatewayIPv4: - retAddr, off, err = unpackDataA(msg, off) - case IPSECGatewayIPv6: - retAddr, off, err = unpackDataAAAA(msg, off) - case IPSECGatewayHost: - retString, off, err = UnpackDomainName(msg, off) - } - - return retAddr, retString, off, err -} - -func packIPSECGateway(gatewayAddr net.IP, gatewayString string, msg []byte, off int, gatewayType uint8, compression compressionMap, compress bool) (int, error) { - var err error - - switch gatewayType { - case IPSECGatewayNone: // do nothing - case IPSECGatewayIPv4: - off, err = packDataA(gatewayAddr, msg, off) - case IPSECGatewayIPv6: - off, err = packDataAAAA(gatewayAddr, msg, off) - case IPSECGatewayHost: - off, err = packDomainName(gatewayString, msg, off, compression, compress) - } - - return off, err -} diff --git a/vendor/github.com/miekg/dns/msg_truncate.go b/vendor/github.com/miekg/dns/msg_truncate.go deleted file mode 100644 index 2ddc9a7..0000000 --- a/vendor/github.com/miekg/dns/msg_truncate.go +++ /dev/null @@ -1,117 +0,0 @@ -package dns - -// Truncate ensures the reply message will fit into the requested buffer -// size by removing records that exceed the requested size. -// -// It will first check if the reply fits without compression and then with -// compression. If it won't fit with compression, Truncate then walks the -// record adding as many records as possible without exceeding the -// requested buffer size. -// -// If the message fits within the requested size without compression, -// Truncate will set the message's Compress attribute to false. It is -// the caller's responsibility to set it back to true if they wish to -// compress the payload regardless of size. -// -// The TC bit will be set if any records were excluded from the message. -// If the TC bit is already set on the message it will be retained. -// TC indicates that the client should retry over TCP. -// -// According to RFC 2181, the TC bit should only be set if not all of the -// "required" RRs can be included in the response. Unfortunately, we have -// no way of knowing which RRs are required so we set the TC bit if any RR -// had to be omitted from the response. -// -// The appropriate buffer size can be retrieved from the requests OPT -// record, if present, and is transport specific otherwise. dns.MinMsgSize -// should be used for UDP requests without an OPT record, and -// dns.MaxMsgSize for TCP requests without an OPT record. -func (dns *Msg) Truncate(size int) { - if dns.IsTsig() != nil { - // To simplify this implementation, we don't perform - // truncation on responses with a TSIG record. - return - } - - // RFC 6891 mandates that the payload size in an OPT record - // less than 512 (MinMsgSize) bytes must be treated as equal to 512 bytes. - // - // For ease of use, we impose that restriction here. - if size < MinMsgSize { - size = MinMsgSize - } - - l := msgLenWithCompressionMap(dns, nil) // uncompressed length - if l <= size { - // Don't waste effort compressing this message. - dns.Compress = false - return - } - - dns.Compress = true - - edns0 := dns.popEdns0() - if edns0 != nil { - // Account for the OPT record that gets added at the end, - // by subtracting that length from our budget. - // - // The EDNS(0) OPT record must have the root domain and - // it's length is thus unaffected by compression. - size -= Len(edns0) - } - - compression := make(map[string]struct{}) - - l = headerSize - for _, r := range dns.Question { - l += r.len(l, compression) - } - - var numAnswer int - if l < size { - l, numAnswer = truncateLoop(dns.Answer, size, l, compression) - } - - var numNS int - if l < size { - l, numNS = truncateLoop(dns.Ns, size, l, compression) - } - - var numExtra int - if l < size { - _, numExtra = truncateLoop(dns.Extra, size, l, compression) - } - - // See the function documentation for when we set this. - dns.Truncated = dns.Truncated || len(dns.Answer) > numAnswer || - len(dns.Ns) > numNS || len(dns.Extra) > numExtra - - dns.Answer = dns.Answer[:numAnswer] - dns.Ns = dns.Ns[:numNS] - dns.Extra = dns.Extra[:numExtra] - - if edns0 != nil { - // Add the OPT record back onto the additional section. - dns.Extra = append(dns.Extra, edns0) - } -} - -func truncateLoop(rrs []RR, size, l int, compression map[string]struct{}) (int, int) { - for i, r := range rrs { - if r == nil { - continue - } - - l += r.len(l, compression) - if l > size { - // Return size, rather than l prior to this record, - // to prevent any further records being added. - return size, i - } - if l == size { - return l, i + 1 - } - } - - return l, len(rrs) -} diff --git a/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/miekg/dns/nsecx.go deleted file mode 100644 index f882681..0000000 --- a/vendor/github.com/miekg/dns/nsecx.go +++ /dev/null @@ -1,95 +0,0 @@ -package dns - -import ( - "crypto/sha1" - "encoding/hex" - "strings" -) - -// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase. -func HashName(label string, ha uint8, iter uint16, salt string) string { - if ha != SHA1 { - return "" - } - - wireSalt := make([]byte, hex.DecodedLen(len(salt))) - n, err := packStringHex(salt, wireSalt, 0) - if err != nil { - return "" - } - wireSalt = wireSalt[:n] - - name := make([]byte, 255) - off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false) - if err != nil { - return "" - } - name = name[:off] - - s := sha1.New() - // k = 0 - s.Write(name) - s.Write(wireSalt) - nsec3 := s.Sum(nil) - - // k > 0 - for k := uint16(0); k < iter; k++ { - s.Reset() - s.Write(nsec3) - s.Write(wireSalt) - nsec3 = s.Sum(nsec3[:0]) - } - - return toBase32(nsec3) -} - -// Cover returns true if a name is covered by the NSEC3 record. -func (rr *NSEC3) Cover(name string) bool { - nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) - owner := strings.ToUpper(rr.Hdr.Name) - labelIndices := Split(owner) - if len(labelIndices) < 2 { - return false - } - ownerHash := owner[:labelIndices[1]-1] - ownerZone := owner[labelIndices[1]:] - if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone - return false - } - - nextHash := rr.NextDomain - - // if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash - if ownerHash == nextHash && nameHash != ownerHash { // empty interval - return true - } - if ownerHash > nextHash { // end of zone - if nameHash > ownerHash { // covered since there is nothing after ownerHash - return true - } - return nameHash < nextHash // if nameHash is before beginning of zone it is covered - } - if nameHash < ownerHash { // nameHash is before ownerHash, not covered - return false - } - return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash) -} - -// Match returns true if a name matches the NSEC3 record -func (rr *NSEC3) Match(name string) bool { - nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) - owner := strings.ToUpper(rr.Hdr.Name) - labelIndices := Split(owner) - if len(labelIndices) < 2 { - return false - } - ownerHash := owner[:labelIndices[1]-1] - ownerZone := owner[labelIndices[1]:] - if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone - return false - } - if ownerHash == nameHash { - return true - } - return false -} diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go deleted file mode 100644 index 350ea5a..0000000 --- a/vendor/github.com/miekg/dns/privaterr.go +++ /dev/null @@ -1,113 +0,0 @@ -package dns - -import "strings" - -// PrivateRdata is an interface used for implementing "Private Use" RR types, see -// RFC 6895. This allows one to experiment with new RR types, without requesting an -// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove. -type PrivateRdata interface { - // String returns the text presentation of the Rdata of the Private RR. - String() string - // Parse parses the Rdata of the private RR. - Parse([]string) error - // Pack is used when packing a private RR into a buffer. - Pack([]byte) (int, error) - // Unpack is used when unpacking a private RR from a buffer. - Unpack([]byte) (int, error) - // Copy copies the Rdata into the PrivateRdata argument. - Copy(PrivateRdata) error - // Len returns the length in octets of the Rdata. - Len() int -} - -// PrivateRR represents an RR that uses a PrivateRdata user-defined type. -// It mocks normal RRs and implements dns.RR interface. -type PrivateRR struct { - Hdr RR_Header - Data PrivateRdata - - generator func() PrivateRdata // for copy -} - -// Header return the RR header of r. -func (r *PrivateRR) Header() *RR_Header { return &r.Hdr } - -func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() } - -// Private len and copy parts to satisfy RR interface. -func (r *PrivateRR) len(off int, compression map[string]struct{}) int { - l := r.Hdr.len(off, compression) - l += r.Data.Len() - return l -} - -func (r *PrivateRR) copy() RR { - // make new RR like this: - rr := &PrivateRR{r.Hdr, r.generator(), r.generator} - - if err := r.Data.Copy(rr.Data); err != nil { - panic("dns: got value that could not be used to copy Private rdata: " + err.Error()) - } - - return rr -} - -func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - n, err := r.Data.Pack(msg[off:]) - if err != nil { - return len(msg), err - } - off += n - return off, nil -} - -func (r *PrivateRR) unpack(msg []byte, off int) (int, error) { - off1, err := r.Data.Unpack(msg[off:]) - off += off1 - return off, err -} - -func (r *PrivateRR) parse(c *zlexer, origin string) *ParseError { - var l lex - text := make([]string, 0, 2) // could be 0..N elements, median is probably 1 -Fetch: - for { - // TODO(miek): we could also be returning _QUOTE, this might or might not - // be an issue (basically parsing TXT becomes hard) - switch l, _ = c.Next(); l.value { - case zNewline, zEOF: - break Fetch - case zString: - text = append(text, l.token) - } - } - - err := r.Data.Parse(text) - if err != nil { - return &ParseError{wrappedErr: err, lex: l} - } - - return nil -} - -func (r *PrivateRR) isDuplicate(r2 RR) bool { return false } - -// PrivateHandle registers a private resource record type. It requires -// string and numeric representation of private RR type and generator function as argument. -func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) { - rtypestr = strings.ToUpper(rtypestr) - - TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator(), generator} } - TypeToString[rtype] = rtypestr - StringToType[rtypestr] = rtype -} - -// PrivateHandleRemove removes definitions required to support private RR type. -func PrivateHandleRemove(rtype uint16) { - rtypestr, ok := TypeToString[rtype] - if ok { - delete(TypeToRR, rtype) - delete(TypeToString, rtype) - delete(StringToType, rtypestr) - } -} diff --git a/vendor/github.com/miekg/dns/reverse.go b/vendor/github.com/miekg/dns/reverse.go deleted file mode 100644 index 28151af..0000000 --- a/vendor/github.com/miekg/dns/reverse.go +++ /dev/null @@ -1,52 +0,0 @@ -package dns - -// StringToType is the reverse of TypeToString, needed for string parsing. -var StringToType = reverseInt16(TypeToString) - -// StringToClass is the reverse of ClassToString, needed for string parsing. -var StringToClass = reverseInt16(ClassToString) - -// StringToOpcode is a map of opcodes to strings. -var StringToOpcode = reverseInt(OpcodeToString) - -// StringToRcode is a map of rcodes to strings. -var StringToRcode = reverseInt(RcodeToString) - -func init() { - // Preserve previous NOTIMP typo, see github.com/miekg/dns/issues/733. - StringToRcode["NOTIMPL"] = RcodeNotImplemented -} - -// StringToAlgorithm is the reverse of AlgorithmToString. -var StringToAlgorithm = reverseInt8(AlgorithmToString) - -// StringToHash is a map of names to hash IDs. -var StringToHash = reverseInt8(HashToString) - -// StringToCertType is the reverseof CertTypeToString. -var StringToCertType = reverseInt16(CertTypeToString) - -// Reverse a map -func reverseInt8(m map[uint8]string) map[string]uint8 { - n := make(map[string]uint8, len(m)) - for u, s := range m { - n[s] = u - } - return n -} - -func reverseInt16(m map[uint16]string) map[string]uint16 { - n := make(map[string]uint16, len(m)) - for u, s := range m { - n[s] = u - } - return n -} - -func reverseInt(m map[int]string) map[string]int { - n := make(map[string]int, len(m)) - for u, s := range m { - n[s] = u - } - return n -} diff --git a/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/miekg/dns/sanitize.go deleted file mode 100644 index a638e86..0000000 --- a/vendor/github.com/miekg/dns/sanitize.go +++ /dev/null @@ -1,86 +0,0 @@ -package dns - -// Dedup removes identical RRs from rrs. It preserves the original ordering. -// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies -// rrs. -// m is used to store the RRs temporary. If it is nil a new map will be allocated. -func Dedup(rrs []RR, m map[string]RR) []RR { - - if m == nil { - m = make(map[string]RR) - } - // Save the keys, so we don't have to call normalizedString twice. - keys := make([]*string, 0, len(rrs)) - - for _, r := range rrs { - key := normalizedString(r) - keys = append(keys, &key) - if mr, ok := m[key]; ok { - // Shortest TTL wins. - rh, mrh := r.Header(), mr.Header() - if mrh.Ttl > rh.Ttl { - mrh.Ttl = rh.Ttl - } - continue - } - - m[key] = r - } - // If the length of the result map equals the amount of RRs we got, - // it means they were all different. We can then just return the original rrset. - if len(m) == len(rrs) { - return rrs - } - - j := 0 - for i, r := range rrs { - // If keys[i] lives in the map, we should copy and remove it. - if _, ok := m[*keys[i]]; ok { - delete(m, *keys[i]) - rrs[j] = r - j++ - } - - if len(m) == 0 { - break - } - } - - return rrs[:j] -} - -// normalizedString returns a normalized string from r. The TTL -// is removed and the domain name is lowercased. We go from this: -// DomainNameTTLCLASSTYPERDATA to: -// lowercasenameCLASSTYPE... -func normalizedString(r RR) string { - // A string Go DNS makes has: domainnameTTL... - b := []byte(r.String()) - - // find the first non-escaped tab, then another, so we capture where the TTL lives. - esc := false - ttlStart, ttlEnd := 0, 0 - for i := 0; i < len(b) && ttlEnd == 0; i++ { - switch { - case b[i] == '\\': - esc = !esc - case b[i] == '\t' && !esc: - if ttlStart == 0 { - ttlStart = i - continue - } - if ttlEnd == 0 { - ttlEnd = i - } - case b[i] >= 'A' && b[i] <= 'Z' && !esc: - b[i] += 32 - default: - esc = false - } - } - - // remove TTL. - copy(b[ttlStart:], b[ttlEnd:]) - cut := ttlEnd - ttlStart - return string(b[:len(b)-cut]) -} diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go deleted file mode 100644 index 1f92ae4..0000000 --- a/vendor/github.com/miekg/dns/scan.go +++ /dev/null @@ -1,1404 +0,0 @@ -package dns - -import ( - "bufio" - "fmt" - "io" - "io/fs" - "os" - "path" - "path/filepath" - "strconv" - "strings" -) - -const maxTok = 512 // Token buffer start size, and growth size amount. - -// The maximum depth of $INCLUDE directives supported by the -// ZoneParser API. -const maxIncludeDepth = 7 - -// Tokenize a RFC 1035 zone file. The tokenizer will normalize it: -// * Add ownernames if they are left blank; -// * Suppress sequences of spaces; -// * Make each RR fit on one line (_NEWLINE is send as last) -// * Handle comments: ; -// * Handle braces - anywhere. -const ( - // Zonefile - zEOF = iota - zString - zBlank - zQuote - zNewline - zRrtpe - zOwner - zClass - zDirOrigin // $ORIGIN - zDirTTL // $TTL - zDirInclude // $INCLUDE - zDirGenerate // $GENERATE - - // Privatekey file - zValue - zKey - - zExpectOwnerDir // Ownername - zExpectOwnerBl // Whitespace after the ownername - zExpectAny // Expect rrtype, ttl or class - zExpectAnyNoClass // Expect rrtype or ttl - zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS - zExpectAnyNoTTL // Expect rrtype or class - zExpectAnyNoTTLBl // Whitespace after _EXPECT_ANY_NOTTL - zExpectRrtype // Expect rrtype - zExpectRrtypeBl // Whitespace BEFORE rrtype - zExpectRdata // The first element of the rdata - zExpectDirTTLBl // Space after directive $TTL - zExpectDirTTL // Directive $TTL - zExpectDirOriginBl // Space after directive $ORIGIN - zExpectDirOrigin // Directive $ORIGIN - zExpectDirIncludeBl // Space after directive $INCLUDE - zExpectDirInclude // Directive $INCLUDE - zExpectDirGenerate // Directive $GENERATE - zExpectDirGenerateBl // Space after directive $GENERATE -) - -// ParseError is a parsing error. It contains the parse error and the location in the io.Reader -// where the error occurred. -type ParseError struct { - file string - err string - wrappedErr error - lex lex -} - -func (e *ParseError) Error() (s string) { - if e.file != "" { - s = e.file + ": " - } - if e.err == "" && e.wrappedErr != nil { - e.err = e.wrappedErr.Error() - } - s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " + - strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column) - return -} - -func (e *ParseError) Unwrap() error { return e.wrappedErr } - -type lex struct { - token string // text of the token - err bool // when true, token text has lexer error - value uint8 // value: zString, _BLANK, etc. - torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar - line int // line in the file - column int // column in the file -} - -// ttlState describes the state necessary to fill in an omitted RR TTL -type ttlState struct { - ttl uint32 // ttl is the current default TTL - isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive -} - -// NewRR reads the RR contained in the string s. Only the first RR is returned. -// If s contains no records, NewRR will return nil with no error. -// -// The class defaults to IN and TTL defaults to 3600. The full zone file syntax -// like $TTL, $ORIGIN, etc. is supported. All fields of the returned RR are -// set, except RR.Header().Rdlength which is set to 0. -func NewRR(s string) (RR, error) { - if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline - return ReadRR(strings.NewReader(s+"\n"), "") - } - return ReadRR(strings.NewReader(s), "") -} - -// ReadRR reads the RR contained in r. -// -// The string file is used in error reporting and to resolve relative -// $INCLUDE directives. -// -// See NewRR for more documentation. -func ReadRR(r io.Reader, file string) (RR, error) { - zp := NewZoneParser(r, ".", file) - zp.SetDefaultTTL(defaultTtl) - zp.SetIncludeAllowed(true) - rr, _ := zp.Next() - return rr, zp.Err() -} - -// ZoneParser is a parser for an RFC 1035 style zonefile. -// -// Each parsed RR in the zone is returned sequentially from Next. An -// optional comment can be retrieved with Comment. -// -// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are all -// supported. Although $INCLUDE is disabled by default. -// Note that $GENERATE's range support up to a maximum of 65535 steps. -// -// Basic usage pattern when reading from a string (z) containing the -// zone data: -// -// zp := NewZoneParser(strings.NewReader(z), "", "") -// -// for rr, ok := zp.Next(); ok; rr, ok = zp.Next() { -// // Do something with rr -// } -// -// if err := zp.Err(); err != nil { -// // log.Println(err) -// } -// -// Comments specified after an RR (and on the same line!) are -// returned too: -// -// foo. IN A 10.0.0.1 ; this is a comment -// -// The text "; this is comment" is returned from Comment. Comments inside -// the RR are returned concatenated along with the RR. Comments on a line -// by themselves are discarded. -// -// Callers should not assume all returned data in an Resource Record is -// syntactically correct, e.g. illegal base64 in RRSIGs will be returned as-is. -type ZoneParser struct { - c *zlexer - - parseErr *ParseError - - origin string - file string - - defttl *ttlState - - h RR_Header - - // sub is used to parse $INCLUDE files and $GENERATE directives. - // Next, by calling subNext, forwards the resulting RRs from this - // sub parser to the calling code. - sub *ZoneParser - r io.Reader - fsys fs.FS - - includeDepth uint8 - - includeAllowed bool - generateDisallowed bool -} - -// NewZoneParser returns an RFC 1035 style zonefile parser that reads -// from r. -// -// The string file is used in error reporting and to resolve relative -// $INCLUDE directives. The string origin is used as the initial -// origin, as if the file would start with an $ORIGIN directive. -func NewZoneParser(r io.Reader, origin, file string) *ZoneParser { - var pe *ParseError - if origin != "" { - origin = Fqdn(origin) - if _, ok := IsDomainName(origin); !ok { - pe = &ParseError{file: file, err: "bad initial origin name"} - } - } - - return &ZoneParser{ - c: newZLexer(r), - - parseErr: pe, - - origin: origin, - file: file, - } -} - -// SetDefaultTTL sets the parsers default TTL to ttl. -func (zp *ZoneParser) SetDefaultTTL(ttl uint32) { - zp.defttl = &ttlState{ttl, false} -} - -// SetIncludeAllowed controls whether $INCLUDE directives are -// allowed. $INCLUDE directives are not supported by default. -// -// The $INCLUDE directive will open and read from a user controlled -// file on the system. Even if the file is not a valid zonefile, the -// contents of the file may be revealed in error messages, such as: -// -// /etc/passwd: dns: not a TTL: "root:x:0:0:root:/root:/bin/bash" at line: 1:31 -// /etc/shadow: dns: not a TTL: "root:$6$::0:99999:7:::" at line: 1:125 -func (zp *ZoneParser) SetIncludeAllowed(v bool) { - zp.includeAllowed = v -} - -// SetIncludeFS provides an [fs.FS] to use when looking for the target of -// $INCLUDE directives. ($INCLUDE must still be enabled separately by calling -// [ZoneParser.SetIncludeAllowed].) If fsys is nil, [os.Open] will be used. -// -// When fsys is an on-disk FS, the ability of $INCLUDE to reach files from -// outside its root directory depends upon the FS implementation. For -// instance, [os.DirFS] will refuse to open paths like "../../etc/passwd", -// however it will still follow links which may point anywhere on the system. -// -// FS paths are slash-separated on all systems, even Windows. $INCLUDE paths -// containing other characters such as backslash and colon may be accepted as -// valid, but those characters will never be interpreted by an FS -// implementation as path element separators. See [fs.ValidPath] for more -// details. -func (zp *ZoneParser) SetIncludeFS(fsys fs.FS) { - zp.fsys = fsys -} - -// Err returns the first non-EOF error that was encountered by the -// ZoneParser. -func (zp *ZoneParser) Err() error { - if zp.parseErr != nil { - return zp.parseErr - } - - if zp.sub != nil { - if err := zp.sub.Err(); err != nil { - return err - } - } - - return zp.c.Err() -} - -func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) { - zp.parseErr = &ParseError{file: zp.file, err: err, lex: l} - return nil, false -} - -// Comment returns an optional text comment that occurred alongside -// the RR. -func (zp *ZoneParser) Comment() string { - if zp.parseErr != nil { - return "" - } - - if zp.sub != nil { - return zp.sub.Comment() - } - - return zp.c.Comment() -} - -func (zp *ZoneParser) subNext() (RR, bool) { - if rr, ok := zp.sub.Next(); ok { - return rr, true - } - - if zp.sub.r != nil { - if c, ok := zp.sub.r.(io.Closer); ok { - c.Close() - } - zp.sub.r = nil - } - - if zp.sub.Err() != nil { - // We have errors to surface. - return nil, false - } - - zp.sub = nil - return zp.Next() -} - -// Next advances the parser to the next RR in the zonefile and -// returns the (RR, true). It will return (nil, false) when the -// parsing stops, either by reaching the end of the input or an -// error. After Next returns (nil, false), the Err method will return -// any error that occurred during parsing. -func (zp *ZoneParser) Next() (RR, bool) { - if zp.parseErr != nil { - return nil, false - } - if zp.sub != nil { - return zp.subNext() - } - - // 6 possible beginnings of a line (_ is a space): - // - // 0. zRRTYPE -> all omitted until the rrtype - // 1. zOwner _ zRrtype -> class/ttl omitted - // 2. zOwner _ zString _ zRrtype -> class omitted - // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class - // 4. zOwner _ zClass _ zRrtype -> ttl omitted - // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed) - // - // After detecting these, we know the zRrtype so we can jump to functions - // handling the rdata for each of these types. - - st := zExpectOwnerDir // initial state - h := &zp.h - - for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() { - // zlexer spotted an error already - if l.err { - return zp.setParseError(l.token, l) - } - - switch st { - case zExpectOwnerDir: - // We can also expect a directive, like $TTL or $ORIGIN - if zp.defttl != nil { - h.Ttl = zp.defttl.ttl - } - - h.Class = ClassINET - - switch l.value { - case zNewline: - st = zExpectOwnerDir - case zOwner: - name, ok := toAbsoluteName(l.token, zp.origin) - if !ok { - return zp.setParseError("bad owner name", l) - } - - h.Name = name - - st = zExpectOwnerBl - case zDirTTL: - st = zExpectDirTTLBl - case zDirOrigin: - st = zExpectDirOriginBl - case zDirInclude: - st = zExpectDirIncludeBl - case zDirGenerate: - st = zExpectDirGenerateBl - case zRrtpe: - h.Rrtype = l.torc - - st = zExpectRdata - case zClass: - h.Class = l.torc - - st = zExpectAnyNoClassBl - case zBlank: - // Discard, can happen when there is nothing on the - // line except the RR type - case zString: - ttl, ok := stringToTTL(l.token) - if !ok { - return zp.setParseError("not a TTL", l) - } - - h.Ttl = ttl - - if zp.defttl == nil || !zp.defttl.isByDirective { - zp.defttl = &ttlState{ttl, false} - } - - st = zExpectAnyNoTTLBl - default: - return zp.setParseError("syntax error at beginning", l) - } - case zExpectDirIncludeBl: - if l.value != zBlank { - return zp.setParseError("no blank after $INCLUDE-directive", l) - } - - st = zExpectDirInclude - case zExpectDirInclude: - if l.value != zString { - return zp.setParseError("expecting $INCLUDE value, not this...", l) - } - - neworigin := zp.origin // There may be optionally a new origin set after the filename, if not use current one - switch l, _ := zp.c.Next(); l.value { - case zBlank: - l, _ := zp.c.Next() - if l.value == zString { - name, ok := toAbsoluteName(l.token, zp.origin) - if !ok { - return zp.setParseError("bad origin name", l) - } - - neworigin = name - } - case zNewline, zEOF: - // Ok - default: - return zp.setParseError("garbage after $INCLUDE", l) - } - - if !zp.includeAllowed { - return zp.setParseError("$INCLUDE directive not allowed", l) - } - if zp.includeDepth >= maxIncludeDepth { - return zp.setParseError("too deeply nested $INCLUDE", l) - } - - // Start with the new file - includePath := l.token - var r1 io.Reader - var e1 error - if zp.fsys != nil { - // fs.FS always uses / as separator, even on Windows, so use - // path instead of filepath here: - if !path.IsAbs(includePath) { - includePath = path.Join(path.Dir(zp.file), includePath) - } - - // os.DirFS, and probably others, expect all paths to be - // relative, so clean the path and remove leading / if - // present: - includePath = strings.TrimLeft(path.Clean(includePath), "/") - - r1, e1 = zp.fsys.Open(includePath) - } else { - if !filepath.IsAbs(includePath) { - includePath = filepath.Join(filepath.Dir(zp.file), includePath) - } - r1, e1 = os.Open(includePath) - } - if e1 != nil { - var as string - if includePath != l.token { - as = fmt.Sprintf(" as `%s'", includePath) - } - zp.parseErr = &ParseError{ - file: zp.file, - wrappedErr: fmt.Errorf("failed to open `%s'%s: %w", l.token, as, e1), - lex: l, - } - return nil, false - } - - zp.sub = NewZoneParser(r1, neworigin, includePath) - zp.sub.defttl, zp.sub.includeDepth, zp.sub.r = zp.defttl, zp.includeDepth+1, r1 - zp.sub.SetIncludeAllowed(true) - zp.sub.SetIncludeFS(zp.fsys) - return zp.subNext() - case zExpectDirTTLBl: - if l.value != zBlank { - return zp.setParseError("no blank after $TTL-directive", l) - } - - st = zExpectDirTTL - case zExpectDirTTL: - if l.value != zString { - return zp.setParseError("expecting $TTL value, not this...", l) - } - - if err := slurpRemainder(zp.c); err != nil { - return zp.setParseError(err.err, err.lex) - } - - ttl, ok := stringToTTL(l.token) - if !ok { - return zp.setParseError("expecting $TTL value, not this...", l) - } - - zp.defttl = &ttlState{ttl, true} - - st = zExpectOwnerDir - case zExpectDirOriginBl: - if l.value != zBlank { - return zp.setParseError("no blank after $ORIGIN-directive", l) - } - - st = zExpectDirOrigin - case zExpectDirOrigin: - if l.value != zString { - return zp.setParseError("expecting $ORIGIN value, not this...", l) - } - - if err := slurpRemainder(zp.c); err != nil { - return zp.setParseError(err.err, err.lex) - } - - name, ok := toAbsoluteName(l.token, zp.origin) - if !ok { - return zp.setParseError("bad origin name", l) - } - - zp.origin = name - - st = zExpectOwnerDir - case zExpectDirGenerateBl: - if l.value != zBlank { - return zp.setParseError("no blank after $GENERATE-directive", l) - } - - st = zExpectDirGenerate - case zExpectDirGenerate: - if zp.generateDisallowed { - return zp.setParseError("nested $GENERATE directive not allowed", l) - } - if l.value != zString { - return zp.setParseError("expecting $GENERATE value, not this...", l) - } - - return zp.generate(l) - case zExpectOwnerBl: - if l.value != zBlank { - return zp.setParseError("no blank after owner", l) - } - - st = zExpectAny - case zExpectAny: - switch l.value { - case zRrtpe: - if zp.defttl == nil { - return zp.setParseError("missing TTL with no previous value", l) - } - - h.Rrtype = l.torc - - st = zExpectRdata - case zClass: - h.Class = l.torc - - st = zExpectAnyNoClassBl - case zString: - ttl, ok := stringToTTL(l.token) - if !ok { - return zp.setParseError("not a TTL", l) - } - - h.Ttl = ttl - - if zp.defttl == nil || !zp.defttl.isByDirective { - zp.defttl = &ttlState{ttl, false} - } - - st = zExpectAnyNoTTLBl - default: - return zp.setParseError("expecting RR type, TTL or class, not this...", l) - } - case zExpectAnyNoClassBl: - if l.value != zBlank { - return zp.setParseError("no blank before class", l) - } - - st = zExpectAnyNoClass - case zExpectAnyNoTTLBl: - if l.value != zBlank { - return zp.setParseError("no blank before TTL", l) - } - - st = zExpectAnyNoTTL - case zExpectAnyNoTTL: - switch l.value { - case zClass: - h.Class = l.torc - - st = zExpectRrtypeBl - case zRrtpe: - h.Rrtype = l.torc - - st = zExpectRdata - default: - return zp.setParseError("expecting RR type or class, not this...", l) - } - case zExpectAnyNoClass: - switch l.value { - case zString: - ttl, ok := stringToTTL(l.token) - if !ok { - return zp.setParseError("not a TTL", l) - } - - h.Ttl = ttl - - if zp.defttl == nil || !zp.defttl.isByDirective { - zp.defttl = &ttlState{ttl, false} - } - - st = zExpectRrtypeBl - case zRrtpe: - h.Rrtype = l.torc - - st = zExpectRdata - default: - return zp.setParseError("expecting RR type or TTL, not this...", l) - } - case zExpectRrtypeBl: - if l.value != zBlank { - return zp.setParseError("no blank before RR type", l) - } - - st = zExpectRrtype - case zExpectRrtype: - if l.value != zRrtpe { - return zp.setParseError("unknown RR type", l) - } - - h.Rrtype = l.torc - - st = zExpectRdata - case zExpectRdata: - var ( - rr RR - parseAsRFC3597 bool - ) - if newFn, ok := TypeToRR[h.Rrtype]; ok { - rr = newFn() - *rr.Header() = *h - - // We may be parsing a known RR type using the RFC3597 format. - // If so, we handle that here in a generic way. - // - // This is also true for PrivateRR types which will have the - // RFC3597 parsing done for them and the Unpack method called - // to populate the RR instead of simply deferring to Parse. - if zp.c.Peek().token == "\\#" { - parseAsRFC3597 = true - } - } else { - rr = &RFC3597{Hdr: *h} - } - - _, isPrivate := rr.(*PrivateRR) - if !isPrivate && zp.c.Peek().token == "" { - // This is a dynamic update rr. - - if err := slurpRemainder(zp.c); err != nil { - return zp.setParseError(err.err, err.lex) - } - - return rr, true - } else if l.value == zNewline { - return zp.setParseError("unexpected newline", l) - } - - parseAsRR := rr - if parseAsRFC3597 { - parseAsRR = &RFC3597{Hdr: *h} - } - - if err := parseAsRR.parse(zp.c, zp.origin); err != nil { - // err is a concrete *ParseError without the file field set. - // The setParseError call below will construct a new - // *ParseError with file set to zp.file. - - // err.lex may be nil in which case we substitute our current - // lex token. - if err.lex == (lex{}) { - return zp.setParseError(err.err, l) - } - - return zp.setParseError(err.err, err.lex) - } - - if parseAsRFC3597 { - err := parseAsRR.(*RFC3597).fromRFC3597(rr) - if err != nil { - return zp.setParseError(err.Error(), l) - } - } - - return rr, true - } - } - - // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this - // is not an error, because an empty zone file is still a zone file. - return nil, false -} - -type zlexer struct { - br io.ByteReader - - readErr error - - line int - column int - - comBuf string - comment string - - l lex - cachedL *lex - - brace int - quote bool - space bool - commt bool - rrtype bool - owner bool - - nextL bool - - eol bool // end-of-line -} - -func newZLexer(r io.Reader) *zlexer { - br, ok := r.(io.ByteReader) - if !ok { - br = bufio.NewReaderSize(r, 1024) - } - - return &zlexer{ - br: br, - - line: 1, - - owner: true, - } -} - -func (zl *zlexer) Err() error { - if zl.readErr == io.EOF { - return nil - } - - return zl.readErr -} - -// readByte returns the next byte from the input -func (zl *zlexer) readByte() (byte, bool) { - if zl.readErr != nil { - return 0, false - } - - c, err := zl.br.ReadByte() - if err != nil { - zl.readErr = err - return 0, false - } - - // delay the newline handling until the next token is delivered, - // fixes off-by-one errors when reporting a parse error. - if zl.eol { - zl.line++ - zl.column = 0 - zl.eol = false - } - - if c == '\n' { - zl.eol = true - } else { - zl.column++ - } - - return c, true -} - -func (zl *zlexer) Peek() lex { - if zl.nextL { - return zl.l - } - - l, ok := zl.Next() - if !ok { - return l - } - - if zl.nextL { - // Cache l. Next returns zl.cachedL then zl.l. - zl.cachedL = &l - } else { - // In this case l == zl.l, so we just tell Next to return zl.l. - zl.nextL = true - } - - return l -} - -func (zl *zlexer) Next() (lex, bool) { - l := &zl.l - switch { - case zl.cachedL != nil: - l, zl.cachedL = zl.cachedL, nil - return *l, true - case zl.nextL: - zl.nextL = false - return *l, true - case l.err: - // Parsing errors should be sticky. - return lex{value: zEOF}, false - } - - var ( - str = make([]byte, maxTok) // Hold string text - com = make([]byte, maxTok) // Hold comment text - - stri int // Offset in str (0 means empty) - comi int // Offset in com (0 means empty) - - escape bool - ) - - if zl.comBuf != "" { - comi = copy(com[:], zl.comBuf) - zl.comBuf = "" - } - - zl.comment = "" - - for x, ok := zl.readByte(); ok; x, ok = zl.readByte() { - l.line, l.column = zl.line, zl.column - - if stri >= len(str) { - // if buffer length is insufficient, increase it. - str = append(str[:], make([]byte, maxTok)...) - } - if comi >= len(com) { - // if buffer length is insufficient, increase it. - com = append(com[:], make([]byte, maxTok)...) - } - - switch x { - case ' ', '\t': - if escape || zl.quote { - // Inside quotes or escaped this is legal. - str[stri] = x - stri++ - - escape = false - break - } - - if zl.commt { - com[comi] = x - comi++ - break - } - - var retL lex - if stri == 0 { - // Space directly in the beginning, handled in the grammar - } else if zl.owner { - // If we have a string and it's the first, make it an owner - l.value = zOwner - l.token = string(str[:stri]) - - // escape $... start with a \ not a $, so this will work - switch strings.ToUpper(l.token) { - case "$TTL": - l.value = zDirTTL - case "$ORIGIN": - l.value = zDirOrigin - case "$INCLUDE": - l.value = zDirInclude - case "$GENERATE": - l.value = zDirGenerate - } - - retL = *l - } else { - l.value = zString - l.token = string(str[:stri]) - - if !zl.rrtype { - tokenUpper := strings.ToUpper(l.token) - if t, ok := StringToType[tokenUpper]; ok { - l.value = zRrtpe - l.torc = t - - zl.rrtype = true - } else if strings.HasPrefix(tokenUpper, "TYPE") { - t, ok := typeToInt(l.token) - if !ok { - l.token = "unknown RR type" - l.err = true - return *l, true - } - - l.value = zRrtpe - l.torc = t - - zl.rrtype = true - } - - if t, ok := StringToClass[tokenUpper]; ok { - l.value = zClass - l.torc = t - } else if strings.HasPrefix(tokenUpper, "CLASS") { - t, ok := classToInt(l.token) - if !ok { - l.token = "unknown class" - l.err = true - return *l, true - } - - l.value = zClass - l.torc = t - } - } - - retL = *l - } - - zl.owner = false - - if !zl.space { - zl.space = true - - l.value = zBlank - l.token = " " - - if retL == (lex{}) { - return *l, true - } - - zl.nextL = true - } - - if retL != (lex{}) { - return retL, true - } - case ';': - if escape || zl.quote { - // Inside quotes or escaped this is legal. - str[stri] = x - stri++ - - escape = false - break - } - - zl.commt = true - zl.comBuf = "" - - if comi > 1 { - // A newline was previously seen inside a comment that - // was inside braces and we delayed adding it until now. - com[comi] = ' ' // convert newline to space - comi++ - if comi >= len(com) { - l.token = "comment length insufficient for parsing" - l.err = true - return *l, true - } - } - - com[comi] = ';' - comi++ - - if stri > 0 { - zl.comBuf = string(com[:comi]) - - l.value = zString - l.token = string(str[:stri]) - return *l, true - } - case '\r': - escape = false - - if zl.quote { - str[stri] = x - stri++ - } - - // discard if outside of quotes - case '\n': - escape = false - - // Escaped newline - if zl.quote { - str[stri] = x - stri++ - break - } - - if zl.commt { - // Reset a comment - zl.commt = false - zl.rrtype = false - - // If not in a brace this ends the comment AND the RR - if zl.brace == 0 { - zl.owner = true - - l.value = zNewline - l.token = "\n" - zl.comment = string(com[:comi]) - return *l, true - } - - zl.comBuf = string(com[:comi]) - break - } - - if zl.brace == 0 { - // If there is previous text, we should output it here - var retL lex - if stri != 0 { - l.value = zString - l.token = string(str[:stri]) - - if !zl.rrtype { - tokenUpper := strings.ToUpper(l.token) - if t, ok := StringToType[tokenUpper]; ok { - zl.rrtype = true - - l.value = zRrtpe - l.torc = t - } - } - - retL = *l - } - - l.value = zNewline - l.token = "\n" - - zl.comment = zl.comBuf - zl.comBuf = "" - zl.rrtype = false - zl.owner = true - - if retL != (lex{}) { - zl.nextL = true - return retL, true - } - - return *l, true - } - case '\\': - // comments do not get escaped chars, everything is copied - if zl.commt { - com[comi] = x - comi++ - break - } - - // something already escaped must be in string - if escape { - str[stri] = x - stri++ - - escape = false - break - } - - // something escaped outside of string gets added to string - str[stri] = x - stri++ - - escape = true - case '"': - if zl.commt { - com[comi] = x - comi++ - break - } - - if escape { - str[stri] = x - stri++ - - escape = false - break - } - - zl.space = false - - // send previous gathered text and the quote - var retL lex - if stri != 0 { - l.value = zString - l.token = string(str[:stri]) - - retL = *l - } - - // send quote itself as separate token - l.value = zQuote - l.token = "\"" - - zl.quote = !zl.quote - - if retL != (lex{}) { - zl.nextL = true - return retL, true - } - - return *l, true - case '(', ')': - if zl.commt { - com[comi] = x - comi++ - break - } - - if escape || zl.quote { - // Inside quotes or escaped this is legal. - str[stri] = x - stri++ - - escape = false - break - } - - switch x { - case ')': - zl.brace-- - - if zl.brace < 0 { - l.token = "extra closing brace" - l.err = true - return *l, true - } - case '(': - zl.brace++ - } - default: - escape = false - - if zl.commt { - com[comi] = x - comi++ - break - } - - str[stri] = x - stri++ - - zl.space = false - } - } - - if zl.readErr != nil && zl.readErr != io.EOF { - // Don't return any tokens after a read error occurs. - return lex{value: zEOF}, false - } - - var retL lex - if stri > 0 { - // Send remainder of str - l.value = zString - l.token = string(str[:stri]) - retL = *l - - if comi <= 0 { - return retL, true - } - } - - if comi > 0 { - // Send remainder of com - l.value = zNewline - l.token = "\n" - zl.comment = string(com[:comi]) - - if retL != (lex{}) { - zl.nextL = true - return retL, true - } - - return *l, true - } - - if zl.brace != 0 { - l.token = "unbalanced brace" - l.err = true - return *l, true - } - - return lex{value: zEOF}, false -} - -func (zl *zlexer) Comment() string { - if zl.l.err { - return "" - } - - return zl.comment -} - -// Extract the class number from CLASSxx -func classToInt(token string) (uint16, bool) { - offset := 5 - if len(token) < offset+1 { - return 0, false - } - class, err := strconv.ParseUint(token[offset:], 10, 16) - if err != nil { - return 0, false - } - return uint16(class), true -} - -// Extract the rr number from TYPExxx -func typeToInt(token string) (uint16, bool) { - offset := 4 - if len(token) < offset+1 { - return 0, false - } - typ, err := strconv.ParseUint(token[offset:], 10, 16) - if err != nil { - return 0, false - } - return uint16(typ), true -} - -// stringToTTL parses things like 2w, 2m, etc, and returns the time in seconds. -func stringToTTL(token string) (uint32, bool) { - var s, i uint32 - for _, c := range token { - switch c { - case 's', 'S': - s += i - i = 0 - case 'm', 'M': - s += i * 60 - i = 0 - case 'h', 'H': - s += i * 60 * 60 - i = 0 - case 'd', 'D': - s += i * 60 * 60 * 24 - i = 0 - case 'w', 'W': - s += i * 60 * 60 * 24 * 7 - i = 0 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - i *= 10 - i += uint32(c) - '0' - default: - return 0, false - } - } - return s + i, true -} - -// Parse LOC records' [.][mM] into a -// mantissa exponent format. Token should contain the entire -// string (i.e. no spaces allowed) -func stringToCm(token string) (e, m uint8, ok bool) { - if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' { - token = token[0 : len(token)-1] - } - - var ( - meters, cmeters, val int - err error - ) - mStr, cmStr, hasCM := strings.Cut(token, ".") - if hasCM { - // There's no point in having more than 2 digits in this part, and would rather make the implementation complicated ('123' should be treated as '12'). - // So we simply reject it. - // We also make sure the first character is a digit to reject '+-' signs. - cmeters, err = strconv.Atoi(cmStr) - if err != nil || len(cmStr) > 2 || cmStr[0] < '0' || cmStr[0] > '9' { - return - } - if len(cmStr) == 1 { - // 'nn.1' must be treated as 'nn-meters and 10cm, not 1cm. - cmeters *= 10 - } - } - // This slighly ugly condition will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm). - if !hasCM || mStr != "" { - meters, err = strconv.Atoi(mStr) - // RFC1876 states the max value is 90000000.00. The latter two conditions enforce it. - if err != nil || mStr[0] < '0' || mStr[0] > '9' || meters > 90000000 || (meters == 90000000 && cmeters != 0) { - return - } - } - - if meters > 0 { - e = 2 - val = meters - } else { - e = 0 - val = cmeters - } - for val >= 10 { - e++ - val /= 10 - } - return e, uint8(val), true -} - -func toAbsoluteName(name, origin string) (absolute string, ok bool) { - // check for an explicit origin reference - if name == "@" { - // require a nonempty origin - if origin == "" { - return "", false - } - return origin, true - } - - // require a valid domain name - _, ok = IsDomainName(name) - if !ok || name == "" { - return "", false - } - - // check if name is already absolute - if IsFqdn(name) { - return name, true - } - - // require a nonempty origin - if origin == "" { - return "", false - } - return appendOrigin(name, origin), true -} - -func appendOrigin(name, origin string) string { - if origin == "." { - return name + origin - } - return name + "." + origin -} - -// LOC record helper function -func locCheckNorth(token string, latitude uint32) (uint32, bool) { - if latitude > 90*1000*60*60 { - return latitude, false - } - switch token { - case "n", "N": - return LOC_EQUATOR + latitude, true - case "s", "S": - return LOC_EQUATOR - latitude, true - } - return latitude, false -} - -// LOC record helper function -func locCheckEast(token string, longitude uint32) (uint32, bool) { - if longitude > 180*1000*60*60 { - return longitude, false - } - switch token { - case "e", "E": - return LOC_EQUATOR + longitude, true - case "w", "W": - return LOC_EQUATOR - longitude, true - } - return longitude, false -} - -// "Eat" the rest of the "line" -func slurpRemainder(c *zlexer) *ParseError { - l, _ := c.Next() - switch l.value { - case zBlank: - l, _ = c.Next() - if l.value != zNewline && l.value != zEOF { - return &ParseError{err: "garbage after rdata", lex: l} - } - case zNewline: - case zEOF: - default: - return &ParseError{err: "garbage after rdata", lex: l} - } - return nil -} - -// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64" -// Used for NID and L64 record. -func stringToNodeID(l lex) (uint64, *ParseError) { - if len(l.token) < 19 { - return 0, &ParseError{file: l.token, err: "bad NID/L64 NodeID/Locator64", lex: l} - } - // There must be three colons at fixes positions, if not its a parse error - if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' { - return 0, &ParseError{file: l.token, err: "bad NID/L64 NodeID/Locator64", lex: l} - } - s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19] - u, err := strconv.ParseUint(s, 16, 64) - if err != nil { - return 0, &ParseError{file: l.token, err: "bad NID/L64 NodeID/Locator64", lex: l} - } - return u, nil -} diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go deleted file mode 100644 index 1a90c61..0000000 --- a/vendor/github.com/miekg/dns/scan_rr.go +++ /dev/null @@ -1,1922 +0,0 @@ -package dns - -import ( - "encoding/base64" - "errors" - "fmt" - "net" - "strconv" - "strings" -) - -// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces) -// or an error -func endingToString(c *zlexer, errstr string) (string, *ParseError) { - var s strings.Builder - l, _ := c.Next() // zString - for l.value != zNewline && l.value != zEOF { - if l.err { - return s.String(), &ParseError{err: errstr, lex: l} - } - switch l.value { - case zString: - s.WriteString(l.token) - case zBlank: // Ok - default: - return "", &ParseError{err: errstr, lex: l} - } - l, _ = c.Next() - } - - return s.String(), nil -} - -// A remainder of the rdata with embedded spaces, split on unquoted whitespace -// and return the parsed string slice or an error -func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) { - // Get the remaining data until we see a zNewline - l, _ := c.Next() - if l.err { - return nil, &ParseError{err: errstr, lex: l} - } - - // Build the slice - s := make([]string, 0) - quote := false - empty := false - for l.value != zNewline && l.value != zEOF { - if l.err { - return nil, &ParseError{err: errstr, lex: l} - } - switch l.value { - case zString: - empty = false - if len(l.token) > 255 { - // split up tokens that are larger than 255 into 255-chunks - sx := []string{} - p, i := 0, 255 - for { - if i <= len(l.token) { - sx = append(sx, l.token[p:i]) - } else { - sx = append(sx, l.token[p:]) - break - - } - p, i = p+255, i+255 - } - s = append(s, sx...) - break - } - - s = append(s, l.token) - case zBlank: - if quote { - // zBlank can only be seen in between txt parts. - return nil, &ParseError{err: errstr, lex: l} - } - case zQuote: - if empty && quote { - s = append(s, "") - } - quote = !quote - empty = true - default: - return nil, &ParseError{err: errstr, lex: l} - } - l, _ = c.Next() - } - - if quote { - return nil, &ParseError{err: errstr, lex: l} - } - - return s, nil -} - -func (rr *A) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - rr.A = net.ParseIP(l.token) - // IPv4 addresses cannot include ":". - // We do this rather than use net.IP's To4() because - // To4() treats IPv4-mapped IPv6 addresses as being - // IPv4. - isIPv4 := !strings.Contains(l.token, ":") - if rr.A == nil || !isIPv4 || l.err { - return &ParseError{err: "bad A A", lex: l} - } - return slurpRemainder(c) -} - -func (rr *AAAA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - rr.AAAA = net.ParseIP(l.token) - // IPv6 addresses must include ":", and IPv4 - // addresses cannot include ":". - isIPv6 := strings.Contains(l.token, ":") - if rr.AAAA == nil || !isIPv6 || l.err { - return &ParseError{err: "bad AAAA AAAA", lex: l} - } - return slurpRemainder(c) -} - -func (rr *NS) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad NS Ns", lex: l} - } - rr.Ns = name - return slurpRemainder(c) -} - -func (rr *PTR) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad PTR Ptr", lex: l} - } - rr.Ptr = name - return slurpRemainder(c) -} - -func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad NSAP-PTR Ptr", lex: l} - } - rr.Ptr = name - return slurpRemainder(c) -} - -func (rr *RP) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - mbox, mboxOk := toAbsoluteName(l.token, o) - if l.err || !mboxOk { - return &ParseError{err: "bad RP Mbox", lex: l} - } - rr.Mbox = mbox - - c.Next() // zBlank - l, _ = c.Next() - rr.Txt = l.token - - txt, txtOk := toAbsoluteName(l.token, o) - if l.err || !txtOk { - return &ParseError{err: "bad RP Txt", lex: l} - } - rr.Txt = txt - - return slurpRemainder(c) -} - -func (rr *MR) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MR Mr", lex: l} - } - rr.Mr = name - return slurpRemainder(c) -} - -func (rr *MB) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MB Mb", lex: l} - } - rr.Mb = name - return slurpRemainder(c) -} - -func (rr *MG) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MG Mg", lex: l} - } - rr.Mg = name - return slurpRemainder(c) -} - -func (rr *HINFO) parse(c *zlexer, o string) *ParseError { - chunks, e := endingToTxtSlice(c, "bad HINFO Fields") - if e != nil { - return e - } - - if ln := len(chunks); ln == 0 { - return nil - } else if ln == 1 { - // Can we split it? - if out := strings.Fields(chunks[0]); len(out) > 1 { - chunks = out - } else { - chunks = append(chunks, "") - } - } - - rr.Cpu = chunks[0] - rr.Os = strings.Join(chunks[1:], " ") - return nil -} - -// according to RFC 1183 the parsing is identical to HINFO, so just use that code. -func (rr *ISDN) parse(c *zlexer, o string) *ParseError { - chunks, e := endingToTxtSlice(c, "bad ISDN Fields") - if e != nil { - return e - } - - if ln := len(chunks); ln == 0 { - return nil - } else if ln == 1 { - // Can we split it? - if out := strings.Fields(chunks[0]); len(out) > 1 { - chunks = out - } else { - chunks = append(chunks, "") - } - } - - rr.Address = chunks[0] - rr.SubAddress = strings.Join(chunks[1:], " ") - - return nil -} - -func (rr *MINFO) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - rmail, rmailOk := toAbsoluteName(l.token, o) - if l.err || !rmailOk { - return &ParseError{err: "bad MINFO Rmail", lex: l} - } - rr.Rmail = rmail - - c.Next() // zBlank - l, _ = c.Next() - rr.Email = l.token - - email, emailOk := toAbsoluteName(l.token, o) - if l.err || !emailOk { - return &ParseError{err: "bad MINFO Email", lex: l} - } - rr.Email = email - - return slurpRemainder(c) -} - -func (rr *MF) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MF Mf", lex: l} - } - rr.Mf = name - return slurpRemainder(c) -} - -func (rr *MD) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MD Md", lex: l} - } - rr.Md = name - return slurpRemainder(c) -} - -func (rr *MX) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad MX Pref", lex: l} - } - rr.Preference = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Mx = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad MX Mx", lex: l} - } - rr.Mx = name - - return slurpRemainder(c) -} - -func (rr *RT) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil { - return &ParseError{err: "bad RT Preference", lex: l} - } - rr.Preference = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Host = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad RT Host", lex: l} - } - rr.Host = name - - return slurpRemainder(c) -} - -func (rr *AFSDB) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad AFSDB Subtype", lex: l} - } - rr.Subtype = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Hostname = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad AFSDB Hostname", lex: l} - } - rr.Hostname = name - return slurpRemainder(c) -} - -func (rr *X25) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - if l.err { - return &ParseError{err: "bad X25 PSDNAddress", lex: l} - } - rr.PSDNAddress = l.token - return slurpRemainder(c) -} - -func (rr *KX) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad KX Pref", lex: l} - } - rr.Preference = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Exchanger = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad KX Exchanger", lex: l} - } - rr.Exchanger = name - return slurpRemainder(c) -} - -func (rr *CNAME) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad CNAME Target", lex: l} - } - rr.Target = name - return slurpRemainder(c) -} - -func (rr *DNAME) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad DNAME Target", lex: l} - } - rr.Target = name - return slurpRemainder(c) -} - -func (rr *SOA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - ns, nsOk := toAbsoluteName(l.token, o) - if l.err || !nsOk { - return &ParseError{err: "bad SOA Ns", lex: l} - } - rr.Ns = ns - - c.Next() // zBlank - l, _ = c.Next() - rr.Mbox = l.token - - mbox, mboxOk := toAbsoluteName(l.token, o) - if l.err || !mboxOk { - return &ParseError{err: "bad SOA Mbox", lex: l} - } - rr.Mbox = mbox - - c.Next() // zBlank - - var ( - v uint32 - ok bool - ) - for i := 0; i < 5; i++ { - l, _ = c.Next() - if l.err { - return &ParseError{err: "bad SOA zone parameter", lex: l} - } - if j, err := strconv.ParseUint(l.token, 10, 32); err != nil { - if i == 0 { - // Serial must be a number - return &ParseError{err: "bad SOA zone parameter", lex: l} - } - // We allow other fields to be unitful duration strings - if v, ok = stringToTTL(l.token); !ok { - return &ParseError{err: "bad SOA zone parameter", lex: l} - - } - } else { - v = uint32(j) - } - switch i { - case 0: - rr.Serial = v - c.Next() // zBlank - case 1: - rr.Refresh = v - c.Next() // zBlank - case 2: - rr.Retry = v - c.Next() // zBlank - case 3: - rr.Expire = v - c.Next() // zBlank - case 4: - rr.Minttl = v - } - } - return slurpRemainder(c) -} - -func (rr *SRV) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad SRV Priority", lex: l} - } - rr.Priority = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - i, e1 := strconv.ParseUint(l.token, 10, 16) - if e1 != nil || l.err { - return &ParseError{err: "bad SRV Weight", lex: l} - } - rr.Weight = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - i, e2 := strconv.ParseUint(l.token, 10, 16) - if e2 != nil || l.err { - return &ParseError{err: "bad SRV Port", lex: l} - } - rr.Port = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Target = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad SRV Target", lex: l} - } - rr.Target = name - return slurpRemainder(c) -} - -func (rr *NAPTR) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad NAPTR Order", lex: l} - } - rr.Order = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - i, e1 := strconv.ParseUint(l.token, 10, 16) - if e1 != nil || l.err { - return &ParseError{err: "bad NAPTR Preference", lex: l} - } - rr.Preference = uint16(i) - - // Flags - c.Next() // zBlank - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Flags", lex: l} - } - l, _ = c.Next() // Either String or Quote - if l.value == zString { - rr.Flags = l.token - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Flags", lex: l} - } - } else if l.value == zQuote { - rr.Flags = "" - } else { - return &ParseError{err: "bad NAPTR Flags", lex: l} - } - - // Service - c.Next() // zBlank - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Service", lex: l} - } - l, _ = c.Next() // Either String or Quote - if l.value == zString { - rr.Service = l.token - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Service", lex: l} - } - } else if l.value == zQuote { - rr.Service = "" - } else { - return &ParseError{err: "bad NAPTR Service", lex: l} - } - - // Regexp - c.Next() // zBlank - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Regexp", lex: l} - } - l, _ = c.Next() // Either String or Quote - if l.value == zString { - rr.Regexp = l.token - l, _ = c.Next() // _QUOTE - if l.value != zQuote { - return &ParseError{err: "bad NAPTR Regexp", lex: l} - } - } else if l.value == zQuote { - rr.Regexp = "" - } else { - return &ParseError{err: "bad NAPTR Regexp", lex: l} - } - - // After quote no space?? - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Replacement = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad NAPTR Replacement", lex: l} - } - rr.Replacement = name - return slurpRemainder(c) -} - -func (rr *TALINK) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - previousName, previousNameOk := toAbsoluteName(l.token, o) - if l.err || !previousNameOk { - return &ParseError{err: "bad TALINK PreviousName", lex: l} - } - rr.PreviousName = previousName - - c.Next() // zBlank - l, _ = c.Next() - rr.NextName = l.token - - nextName, nextNameOk := toAbsoluteName(l.token, o) - if l.err || !nextNameOk { - return &ParseError{err: "bad TALINK NextName", lex: l} - } - rr.NextName = nextName - - return slurpRemainder(c) -} - -func (rr *LOC) parse(c *zlexer, o string) *ParseError { - // Non zero defaults for LOC record, see RFC 1876, Section 3. - rr.Size = 0x12 // 1e2 cm (1m) - rr.HorizPre = 0x16 // 1e6 cm (10000m) - rr.VertPre = 0x13 // 1e3 cm (10m) - ok := false - - // North - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err || i > 90 { - return &ParseError{err: "bad LOC Latitude", lex: l} - } - rr.Latitude = 1000 * 60 * 60 * uint32(i) - - c.Next() // zBlank - // Either number, 'N' or 'S' - l, _ = c.Next() - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { - goto East - } - if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 { - return &ParseError{err: "bad LOC Latitude minutes", lex: l} - } else { - rr.Latitude += 1000 * 60 * uint32(i) - } - - c.Next() // zBlank - l, _ = c.Next() - if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 { - return &ParseError{err: "bad LOC Latitude seconds", lex: l} - } else { - rr.Latitude += uint32(1000 * i) - } - c.Next() // zBlank - // Either number, 'N' or 'S' - l, _ = c.Next() - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { - goto East - } - // If still alive, flag an error - return &ParseError{err: "bad LOC Latitude North/South", lex: l} - -East: - // East - c.Next() // zBlank - l, _ = c.Next() - if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 180 { - return &ParseError{err: "bad LOC Longitude", lex: l} - } else { - rr.Longitude = 1000 * 60 * 60 * uint32(i) - } - c.Next() // zBlank - // Either number, 'E' or 'W' - l, _ = c.Next() - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { - goto Altitude - } - if i, err := strconv.ParseUint(l.token, 10, 32); err != nil || l.err || i > 59 { - return &ParseError{err: "bad LOC Longitude minutes", lex: l} - } else { - rr.Longitude += 1000 * 60 * uint32(i) - } - c.Next() // zBlank - l, _ = c.Next() - if i, err := strconv.ParseFloat(l.token, 64); err != nil || l.err || i < 0 || i >= 60 { - return &ParseError{err: "bad LOC Longitude seconds", lex: l} - } else { - rr.Longitude += uint32(1000 * i) - } - c.Next() // zBlank - // Either number, 'E' or 'W' - l, _ = c.Next() - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { - goto Altitude - } - // If still alive, flag an error - return &ParseError{err: "bad LOC Longitude East/West", lex: l} - -Altitude: - c.Next() // zBlank - l, _ = c.Next() - if l.token == "" || l.err { - return &ParseError{err: "bad LOC Altitude", lex: l} - } - if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' { - l.token = l.token[0 : len(l.token)-1] - } - if i, err := strconv.ParseFloat(l.token, 64); err != nil { - return &ParseError{err: "bad LOC Altitude", lex: l} - } else { - rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5) - } - - // And now optionally the other values - l, _ = c.Next() - count := 0 - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zString: - switch count { - case 0: // Size - exp, m, ok := stringToCm(l.token) - if !ok { - return &ParseError{err: "bad LOC Size", lex: l} - } - rr.Size = exp&0x0f | m<<4&0xf0 - case 1: // HorizPre - exp, m, ok := stringToCm(l.token) - if !ok { - return &ParseError{err: "bad LOC HorizPre", lex: l} - } - rr.HorizPre = exp&0x0f | m<<4&0xf0 - case 2: // VertPre - exp, m, ok := stringToCm(l.token) - if !ok { - return &ParseError{err: "bad LOC VertPre", lex: l} - } - rr.VertPre = exp&0x0f | m<<4&0xf0 - } - count++ - case zBlank: - // Ok - default: - return &ParseError{err: "bad LOC Size, HorizPre or VertPre", lex: l} - } - l, _ = c.Next() - } - return nil -} - -func (rr *HIP) parse(c *zlexer, o string) *ParseError { - // HitLength is not represented - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad HIP PublicKeyAlgorithm", lex: l} - } - rr.PublicKeyAlgorithm = uint8(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - if l.token == "" || l.err { - return &ParseError{err: "bad HIP Hit", lex: l} - } - rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6. - rr.HitLength = uint8(len(rr.Hit)) / 2 - - c.Next() // zBlank - l, _ = c.Next() // zString - if l.token == "" || l.err { - return &ParseError{err: "bad HIP PublicKey", lex: l} - } - rr.PublicKey = l.token // This cannot contain spaces - decodedPK, decodedPKerr := base64.StdEncoding.DecodeString(rr.PublicKey) - if decodedPKerr != nil { - return &ParseError{err: "bad HIP PublicKey", lex: l} - } - rr.PublicKeyLength = uint16(len(decodedPK)) - - // RendezvousServers (if any) - l, _ = c.Next() - var xs []string - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zString: - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad HIP RendezvousServers", lex: l} - } - xs = append(xs, name) - case zBlank: - // Ok - default: - return &ParseError{err: "bad HIP RendezvousServers", lex: l} - } - l, _ = c.Next() - } - - rr.RendezvousServers = xs - return nil -} - -func (rr *CERT) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - if v, ok := StringToCertType[l.token]; ok { - rr.Type = v - } else if i, err := strconv.ParseUint(l.token, 10, 16); err != nil { - return &ParseError{err: "bad CERT Type", lex: l} - } else { - rr.Type = uint16(i) - } - c.Next() // zBlank - l, _ = c.Next() // zString - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad CERT KeyTag", lex: l} - } - rr.KeyTag = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - if v, ok := StringToAlgorithm[l.token]; ok { - rr.Algorithm = v - } else if i, err := strconv.ParseUint(l.token, 10, 8); err != nil { - return &ParseError{err: "bad CERT Algorithm", lex: l} - } else { - rr.Algorithm = uint8(i) - } - s, e1 := endingToString(c, "bad CERT Certificate") - if e1 != nil { - return e1 - } - rr.Certificate = s - return nil -} - -func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError { - s, e := endingToString(c, "bad OPENPGPKEY PublicKey") - if e != nil { - return e - } - rr.PublicKey = s - return nil -} - -func (rr *CSYNC) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - j, e := strconv.ParseUint(l.token, 10, 32) - if e != nil { - // Serial must be a number - return &ParseError{err: "bad CSYNC serial", lex: l} - } - rr.Serial = uint32(j) - - c.Next() // zBlank - - l, _ = c.Next() - j, e1 := strconv.ParseUint(l.token, 10, 16) - if e1 != nil { - // Serial must be a number - return &ParseError{err: "bad CSYNC flags", lex: l} - } - rr.Flags = uint16(j) - - rr.TypeBitMap = make([]uint16, 0) - var ( - k uint16 - ok bool - ) - l, _ = c.Next() - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zBlank: - // Ok - case zString: - tokenUpper := strings.ToUpper(l.token) - if k, ok = StringToType[tokenUpper]; !ok { - if k, ok = typeToInt(l.token); !ok { - return &ParseError{err: "bad CSYNC TypeBitMap", lex: l} - } - } - rr.TypeBitMap = append(rr.TypeBitMap, k) - default: - return &ParseError{err: "bad CSYNC TypeBitMap", lex: l} - } - l, _ = c.Next() - } - return nil -} - -func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return &ParseError{err: "bad ZONEMD Serial", lex: l} - } - rr.Serial = uint32(i) - - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad ZONEMD Scheme", lex: l} - } - rr.Scheme = uint8(i) - - c.Next() // zBlank - l, _ = c.Next() - i, err := strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad ZONEMD Hash Algorithm", lex: l} - } - rr.Hash = uint8(i) - - s, e2 := endingToString(c, "bad ZONEMD Digest") - if e2 != nil { - return e2 - } - rr.Digest = s - return nil -} - -func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG.parse(c, o) } - -func (rr *RRSIG) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - tokenUpper := strings.ToUpper(l.token) - if t, ok := StringToType[tokenUpper]; !ok { - if strings.HasPrefix(tokenUpper, "TYPE") { - t, ok = typeToInt(l.token) - if !ok { - return &ParseError{err: "bad RRSIG Typecovered", lex: l} - } - rr.TypeCovered = t - } else { - return &ParseError{err: "bad RRSIG Typecovered", lex: l} - } - } else { - rr.TypeCovered = t - } - - c.Next() // zBlank - l, _ = c.Next() - if l.err { - return &ParseError{err: "bad RRSIG Algorithm", lex: l} - } - i, e := strconv.ParseUint(l.token, 10, 8) - rr.Algorithm = uint8(i) // if 0 we'll check the mnemonic in the if - if e != nil { - v, ok := StringToAlgorithm[l.token] - if !ok { - return &ParseError{err: "bad RRSIG Algorithm", lex: l} - } - rr.Algorithm = v - } - - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad RRSIG Labels", lex: l} - } - rr.Labels = uint8(i) - - c.Next() // zBlank - l, _ = c.Next() - i, e2 := strconv.ParseUint(l.token, 10, 32) - if e2 != nil || l.err { - return &ParseError{err: "bad RRSIG OrigTtl", lex: l} - } - rr.OrigTtl = uint32(i) - - c.Next() // zBlank - l, _ = c.Next() - if i, err := StringToTime(l.token); err != nil { - // Try to see if all numeric and use it as epoch - if i, err := strconv.ParseUint(l.token, 10, 32); err == nil { - rr.Expiration = uint32(i) - } else { - return &ParseError{err: "bad RRSIG Expiration", lex: l} - } - } else { - rr.Expiration = i - } - - c.Next() // zBlank - l, _ = c.Next() - if i, err := StringToTime(l.token); err != nil { - if i, err := strconv.ParseUint(l.token, 10, 32); err == nil { - rr.Inception = uint32(i) - } else { - return &ParseError{err: "bad RRSIG Inception", lex: l} - } - } else { - rr.Inception = i - } - - c.Next() // zBlank - l, _ = c.Next() - i, e3 := strconv.ParseUint(l.token, 10, 16) - if e3 != nil || l.err { - return &ParseError{err: "bad RRSIG KeyTag", lex: l} - } - rr.KeyTag = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() - rr.SignerName = l.token - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad RRSIG SignerName", lex: l} - } - rr.SignerName = name - - s, e4 := endingToString(c, "bad RRSIG Signature") - if e4 != nil { - return e4 - } - rr.Signature = s - - return nil -} - -func (rr *NXT) parse(c *zlexer, o string) *ParseError { return rr.NSEC.parse(c, o) } - -func (rr *NSEC) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad NSEC NextDomain", lex: l} - } - rr.NextDomain = name - - rr.TypeBitMap = make([]uint16, 0) - var ( - k uint16 - ok bool - ) - l, _ = c.Next() - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zBlank: - // Ok - case zString: - tokenUpper := strings.ToUpper(l.token) - if k, ok = StringToType[tokenUpper]; !ok { - if k, ok = typeToInt(l.token); !ok { - return &ParseError{err: "bad NSEC TypeBitMap", lex: l} - } - } - rr.TypeBitMap = append(rr.TypeBitMap, k) - default: - return &ParseError{err: "bad NSEC TypeBitMap", lex: l} - } - l, _ = c.Next() - } - return nil -} - -func (rr *NSEC3) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad NSEC3 Hash", lex: l} - } - rr.Hash = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad NSEC3 Flags", lex: l} - } - rr.Flags = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e2 := strconv.ParseUint(l.token, 10, 16) - if e2 != nil || l.err { - return &ParseError{err: "bad NSEC3 Iterations", lex: l} - } - rr.Iterations = uint16(i) - c.Next() - l, _ = c.Next() - if l.token == "" || l.err { - return &ParseError{err: "bad NSEC3 Salt", lex: l} - } - if l.token != "-" { - rr.SaltLength = uint8(len(l.token)) / 2 - rr.Salt = l.token - } - - c.Next() - l, _ = c.Next() - if l.token == "" || l.err { - return &ParseError{err: "bad NSEC3 NextDomain", lex: l} - } - rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) - rr.NextDomain = l.token - - rr.TypeBitMap = make([]uint16, 0) - var ( - k uint16 - ok bool - ) - l, _ = c.Next() - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zBlank: - // Ok - case zString: - tokenUpper := strings.ToUpper(l.token) - if k, ok = StringToType[tokenUpper]; !ok { - if k, ok = typeToInt(l.token); !ok { - return &ParseError{err: "bad NSEC3 TypeBitMap", lex: l} - } - } - rr.TypeBitMap = append(rr.TypeBitMap, k) - default: - return &ParseError{err: "bad NSEC3 TypeBitMap", lex: l} - } - l, _ = c.Next() - } - return nil -} - -func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad NSEC3PARAM Hash", lex: l} - } - rr.Hash = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad NSEC3PARAM Flags", lex: l} - } - rr.Flags = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e2 := strconv.ParseUint(l.token, 10, 16) - if e2 != nil || l.err { - return &ParseError{err: "bad NSEC3PARAM Iterations", lex: l} - } - rr.Iterations = uint16(i) - c.Next() - l, _ = c.Next() - if l.token != "-" { - rr.SaltLength = uint8(len(l.token) / 2) - rr.Salt = l.token - } - return slurpRemainder(c) -} - -func (rr *EUI48) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - if len(l.token) != 17 || l.err { - return &ParseError{err: "bad EUI48 Address", lex: l} - } - addr := make([]byte, 12) - dash := 0 - for i := 0; i < 10; i += 2 { - addr[i] = l.token[i+dash] - addr[i+1] = l.token[i+1+dash] - dash++ - if l.token[i+1+dash] != '-' { - return &ParseError{err: "bad EUI48 Address", lex: l} - } - } - addr[10] = l.token[15] - addr[11] = l.token[16] - - i, e := strconv.ParseUint(string(addr), 16, 48) - if e != nil { - return &ParseError{err: "bad EUI48 Address", lex: l} - } - rr.Address = i - return slurpRemainder(c) -} - -func (rr *EUI64) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - if len(l.token) != 23 || l.err { - return &ParseError{err: "bad EUI64 Address", lex: l} - } - addr := make([]byte, 16) - dash := 0 - for i := 0; i < 14; i += 2 { - addr[i] = l.token[i+dash] - addr[i+1] = l.token[i+1+dash] - dash++ - if l.token[i+1+dash] != '-' { - return &ParseError{err: "bad EUI64 Address", lex: l} - } - } - addr[14] = l.token[21] - addr[15] = l.token[22] - - i, e := strconv.ParseUint(string(addr), 16, 64) - if e != nil { - return &ParseError{err: "bad EUI68 Address", lex: l} - } - rr.Address = i - return slurpRemainder(c) -} - -func (rr *SSHFP) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad SSHFP Algorithm", lex: l} - } - rr.Algorithm = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad SSHFP Type", lex: l} - } - rr.Type = uint8(i) - c.Next() // zBlank - s, e2 := endingToString(c, "bad SSHFP Fingerprint") - if e2 != nil { - return e2 - } - rr.FingerPrint = s - return nil -} - -func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad " + typ + " Flags", lex: l} - } - rr.Flags = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad " + typ + " Protocol", lex: l} - } - rr.Protocol = uint8(i) - c.Next() // zBlank - l, _ = c.Next() // zString - i, e2 := strconv.ParseUint(l.token, 10, 8) - if e2 != nil || l.err { - return &ParseError{err: "bad " + typ + " Algorithm", lex: l} - } - rr.Algorithm = uint8(i) - s, e3 := endingToString(c, "bad "+typ+" PublicKey") - if e3 != nil { - return e3 - } - rr.PublicKey = s - return nil -} - -func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "DNSKEY") } -func (rr *KEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "KEY") } -func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "CDNSKEY") } -func (rr *DS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DS") } -func (rr *DLV) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "DLV") } -func (rr *CDS) parse(c *zlexer, o string) *ParseError { return rr.parseDS(c, o, "CDS") } - -func (rr *IPSECKEY) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - num, err := strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad IPSECKEY value", lex: l} - } - rr.Precedence = uint8(num) - c.Next() // zBlank - - l, _ = c.Next() - num, err = strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad IPSECKEY value", lex: l} - } - rr.GatewayType = uint8(num) - c.Next() // zBlank - - l, _ = c.Next() - num, err = strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad IPSECKEY value", lex: l} - } - rr.Algorithm = uint8(num) - c.Next() // zBlank - - l, _ = c.Next() - if l.err { - return &ParseError{err: "bad IPSECKEY gateway", lex: l} - } - - rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType) - if err != nil { - return &ParseError{wrappedErr: fmt.Errorf("IPSECKEY %w", err), lex: l} - } - - c.Next() // zBlank - - s, pErr := endingToString(c, "bad IPSECKEY PublicKey") - if pErr != nil { - return pErr - } - rr.PublicKey = s - return slurpRemainder(c) -} - -func (rr *AMTRELAY) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - num, err := strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad AMTRELAY value", lex: l} - } - rr.Precedence = uint8(num) - c.Next() // zBlank - - l, _ = c.Next() - if l.err || !(l.token == "0" || l.token == "1") { - return &ParseError{err: "bad discovery value", lex: l} - } - if l.token == "1" { - rr.GatewayType = 0x80 - } - - c.Next() // zBlank - - l, _ = c.Next() - num, err = strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return &ParseError{err: "bad AMTRELAY value", lex: l} - } - rr.GatewayType |= uint8(num) - c.Next() // zBlank - - l, _ = c.Next() - if l.err { - return &ParseError{err: "bad AMTRELAY gateway", lex: l} - } - - rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType&0x7f) - if err != nil { - return &ParseError{wrappedErr: fmt.Errorf("AMTRELAY %w", err), lex: l} - } - - return slurpRemainder(c) -} - -// same constants and parsing between IPSECKEY and AMTRELAY -func parseAddrHostUnion(token, o string, gatewayType uint8) (addr net.IP, host string, err error) { - switch gatewayType { - case IPSECGatewayNone: - if token != "." { - return addr, host, errors.New("gateway type none with gateway set") - } - case IPSECGatewayIPv4, IPSECGatewayIPv6: - addr = net.ParseIP(token) - if addr == nil { - return addr, host, errors.New("gateway IP invalid") - } - if (addr.To4() == nil) == (gatewayType == IPSECGatewayIPv4) { - return addr, host, errors.New("gateway IP family mismatch") - } - case IPSECGatewayHost: - var ok bool - host, ok = toAbsoluteName(token, o) - if !ok { - return addr, host, errors.New("invalid gateway host") - } - } - - return addr, host, nil -} - -func (rr *RKEY) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad RKEY Flags", lex: l} - } - rr.Flags = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad RKEY Protocol", lex: l} - } - rr.Protocol = uint8(i) - c.Next() // zBlank - l, _ = c.Next() // zString - i, e2 := strconv.ParseUint(l.token, 10, 8) - if e2 != nil || l.err { - return &ParseError{err: "bad RKEY Algorithm", lex: l} - } - rr.Algorithm = uint8(i) - s, e3 := endingToString(c, "bad RKEY PublicKey") - if e3 != nil { - return e3 - } - rr.PublicKey = s - return nil -} - -func (rr *EID) parse(c *zlexer, o string) *ParseError { - s, e := endingToString(c, "bad EID Endpoint") - if e != nil { - return e - } - rr.Endpoint = s - return nil -} - -func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError { - s, e := endingToString(c, "bad NIMLOC Locator") - if e != nil { - return e - } - rr.Locator = s - return nil -} - -func (rr *GPOS) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - _, e := strconv.ParseFloat(l.token, 64) - if e != nil || l.err { - return &ParseError{err: "bad GPOS Longitude", lex: l} - } - rr.Longitude = l.token - c.Next() // zBlank - l, _ = c.Next() - _, e1 := strconv.ParseFloat(l.token, 64) - if e1 != nil || l.err { - return &ParseError{err: "bad GPOS Latitude", lex: l} - } - rr.Latitude = l.token - c.Next() // zBlank - l, _ = c.Next() - _, e2 := strconv.ParseFloat(l.token, 64) - if e2 != nil || l.err { - return &ParseError{err: "bad GPOS Altitude", lex: l} - } - rr.Altitude = l.token - return slurpRemainder(c) -} - -func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad " + typ + " KeyTag", lex: l} - } - rr.KeyTag = uint16(i) - c.Next() // zBlank - l, _ = c.Next() - if i, err := strconv.ParseUint(l.token, 10, 8); err != nil { - tokenUpper := strings.ToUpper(l.token) - i, ok := StringToAlgorithm[tokenUpper] - if !ok || l.err { - return &ParseError{err: "bad " + typ + " Algorithm", lex: l} - } - rr.Algorithm = i - } else { - rr.Algorithm = uint8(i) - } - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad " + typ + " DigestType", lex: l} - } - rr.DigestType = uint8(i) - s, e2 := endingToString(c, "bad "+typ+" Digest") - if e2 != nil { - return e2 - } - rr.Digest = s - return nil -} - -func (rr *TA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad TA KeyTag", lex: l} - } - rr.KeyTag = uint16(i) - c.Next() // zBlank - l, _ = c.Next() - if i, err := strconv.ParseUint(l.token, 10, 8); err != nil { - tokenUpper := strings.ToUpper(l.token) - i, ok := StringToAlgorithm[tokenUpper] - if !ok || l.err { - return &ParseError{err: "bad TA Algorithm", lex: l} - } - rr.Algorithm = i - } else { - rr.Algorithm = uint8(i) - } - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad TA DigestType", lex: l} - } - rr.DigestType = uint8(i) - s, e2 := endingToString(c, "bad TA Digest") - if e2 != nil { - return e2 - } - rr.Digest = s - return nil -} - -func (rr *TLSA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad TLSA Usage", lex: l} - } - rr.Usage = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad TLSA Selector", lex: l} - } - rr.Selector = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e2 := strconv.ParseUint(l.token, 10, 8) - if e2 != nil || l.err { - return &ParseError{err: "bad TLSA MatchingType", lex: l} - } - rr.MatchingType = uint8(i) - // So this needs be e2 (i.e. different than e), because...??t - s, e3 := endingToString(c, "bad TLSA Certificate") - if e3 != nil { - return e3 - } - rr.Certificate = s - return nil -} - -func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad SMIMEA Usage", lex: l} - } - rr.Usage = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad SMIMEA Selector", lex: l} - } - rr.Selector = uint8(i) - c.Next() // zBlank - l, _ = c.Next() - i, e2 := strconv.ParseUint(l.token, 10, 8) - if e2 != nil || l.err { - return &ParseError{err: "bad SMIMEA MatchingType", lex: l} - } - rr.MatchingType = uint8(i) - // So this needs be e2 (i.e. different than e), because...??t - s, e3 := endingToString(c, "bad SMIMEA Certificate") - if e3 != nil { - return e3 - } - rr.Certificate = s - return nil -} - -func (rr *RFC3597) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - if l.token != "\\#" { - return &ParseError{err: "bad RFC3597 Rdata", lex: l} - } - - c.Next() // zBlank - l, _ = c.Next() - rdlength, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad RFC3597 Rdata ", lex: l} - } - - s, e1 := endingToString(c, "bad RFC3597 Rdata") - if e1 != nil { - return e1 - } - if int(rdlength)*2 != len(s) { - return &ParseError{err: "bad RFC3597 Rdata", lex: l} - } - rr.Rdata = s - return nil -} - -func (rr *SPF) parse(c *zlexer, o string) *ParseError { - s, e := endingToTxtSlice(c, "bad SPF Txt") - if e != nil { - return e - } - rr.Txt = s - return nil -} - -func (rr *AVC) parse(c *zlexer, o string) *ParseError { - s, e := endingToTxtSlice(c, "bad AVC Txt") - if e != nil { - return e - } - rr.Txt = s - return nil -} - -func (rr *TXT) parse(c *zlexer, o string) *ParseError { - // no zBlank reading here, because all this rdata is TXT - s, e := endingToTxtSlice(c, "bad TXT Txt") - if e != nil { - return e - } - rr.Txt = s - return nil -} - -// identical to setTXT -func (rr *NINFO) parse(c *zlexer, o string) *ParseError { - s, e := endingToTxtSlice(c, "bad NINFO ZSData") - if e != nil { - return e - } - rr.ZSData = s - return nil -} - -func (rr *URI) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad URI Priority", lex: l} - } - rr.Priority = uint16(i) - c.Next() // zBlank - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 16) - if e1 != nil || l.err { - return &ParseError{err: "bad URI Weight", lex: l} - } - rr.Weight = uint16(i) - - c.Next() // zBlank - s, e2 := endingToTxtSlice(c, "bad URI Target") - if e2 != nil { - return e2 - } - if len(s) != 1 { - return &ParseError{err: "bad URI Target", lex: l} - } - rr.Target = s[0] - return nil -} - -func (rr *DHCID) parse(c *zlexer, o string) *ParseError { - // awesome record to parse! - s, e := endingToString(c, "bad DHCID Digest") - if e != nil { - return e - } - rr.Digest = s - return nil -} - -func (rr *NID) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad NID Preference", lex: l} - } - rr.Preference = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - u, e1 := stringToNodeID(l) - if e1 != nil || l.err { - return e1 - } - rr.NodeID = u - return slurpRemainder(c) -} - -func (rr *L32) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad L32 Preference", lex: l} - } - rr.Preference = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Locator32 = net.ParseIP(l.token) - if rr.Locator32 == nil || l.err { - return &ParseError{err: "bad L32 Locator", lex: l} - } - return slurpRemainder(c) -} - -func (rr *LP) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad LP Preference", lex: l} - } - rr.Preference = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Fqdn = l.token - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{err: "bad LP Fqdn", lex: l} - } - rr.Fqdn = name - return slurpRemainder(c) -} - -func (rr *L64) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad L64 Preference", lex: l} - } - rr.Preference = uint16(i) - c.Next() // zBlank - l, _ = c.Next() // zString - u, e1 := stringToNodeID(l) - if e1 != nil || l.err { - return e1 - } - rr.Locator64 = u - return slurpRemainder(c) -} - -func (rr *UID) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return &ParseError{err: "bad UID Uid", lex: l} - } - rr.Uid = uint32(i) - return slurpRemainder(c) -} - -func (rr *GID) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return &ParseError{err: "bad GID Gid", lex: l} - } - rr.Gid = uint32(i) - return slurpRemainder(c) -} - -func (rr *UINFO) parse(c *zlexer, o string) *ParseError { - s, e := endingToTxtSlice(c, "bad UINFO Uinfo") - if e != nil { - return e - } - if ln := len(s); ln == 0 { - return nil - } - rr.Uinfo = s[0] // silently discard anything after the first character-string - return nil -} - -func (rr *PX) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{err: "bad PX Preference", lex: l} - } - rr.Preference = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Map822 = l.token - map822, map822Ok := toAbsoluteName(l.token, o) - if l.err || !map822Ok { - return &ParseError{err: "bad PX Map822", lex: l} - } - rr.Map822 = map822 - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Mapx400 = l.token - mapx400, mapx400Ok := toAbsoluteName(l.token, o) - if l.err || !mapx400Ok { - return &ParseError{err: "bad PX Mapx400", lex: l} - } - rr.Mapx400 = mapx400 - return slurpRemainder(c) -} - -func (rr *CAA) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad CAA Flag", lex: l} - } - rr.Flag = uint8(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - if l.value != zString { - return &ParseError{err: "bad CAA Tag", lex: l} - } - rr.Tag = l.token - - c.Next() // zBlank - s, e1 := endingToTxtSlice(c, "bad CAA Value") - if e1 != nil { - return e1 - } - if len(s) != 1 { - return &ParseError{err: "bad CAA Value", lex: l} - } - rr.Value = s[0] - return nil -} - -func (rr *TKEY) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - - // Algorithm - if l.value != zString { - return &ParseError{err: "bad TKEY algorithm", lex: l} - } - rr.Algorithm = l.token - c.Next() // zBlank - - // Get the key length and key values - l, _ = c.Next() - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return &ParseError{err: "bad TKEY key length", lex: l} - } - rr.KeySize = uint16(i) - c.Next() // zBlank - l, _ = c.Next() - if l.value != zString { - return &ParseError{err: "bad TKEY key", lex: l} - } - rr.Key = l.token - c.Next() // zBlank - - // Get the otherdata length and string data - l, _ = c.Next() - i, e1 := strconv.ParseUint(l.token, 10, 8) - if e1 != nil || l.err { - return &ParseError{err: "bad TKEY otherdata length", lex: l} - } - rr.OtherLen = uint16(i) - c.Next() // zBlank - l, _ = c.Next() - if l.value != zString { - return &ParseError{err: "bad TKEY otherday", lex: l} - } - rr.OtherData = l.token - return nil -} - -func (rr *APL) parse(c *zlexer, o string) *ParseError { - var prefixes []APLPrefix - - for { - l, _ := c.Next() - if l.value == zNewline || l.value == zEOF { - break - } - if l.value == zBlank && prefixes != nil { - continue - } - if l.value != zString { - return &ParseError{err: "unexpected APL field", lex: l} - } - - // Expected format: [!]afi:address/prefix - - colon := strings.IndexByte(l.token, ':') - if colon == -1 { - return &ParseError{err: "missing colon in APL field", lex: l} - } - - family, cidr := l.token[:colon], l.token[colon+1:] - - var negation bool - if family != "" && family[0] == '!' { - negation = true - family = family[1:] - } - - afi, e := strconv.ParseUint(family, 10, 16) - if e != nil { - return &ParseError{wrappedErr: fmt.Errorf("failed to parse APL family: %w", e), lex: l} - } - var addrLen int - switch afi { - case 1: - addrLen = net.IPv4len - case 2: - addrLen = net.IPv6len - default: - return &ParseError{err: "unrecognized APL family", lex: l} - } - - ip, subnet, e1 := net.ParseCIDR(cidr) - if e1 != nil { - return &ParseError{wrappedErr: fmt.Errorf("failed to parse APL address: %w", e1), lex: l} - } - if !ip.Equal(subnet.IP) { - return &ParseError{err: "extra bits in APL address", lex: l} - } - - if len(subnet.IP) != addrLen { - return &ParseError{err: "address mismatch with the APL family", lex: l} - } - - prefixes = append(prefixes, APLPrefix{ - Negation: negation, - Network: *subnet, - }) - } - - rr.Prefixes = prefixes - return nil -} diff --git a/vendor/github.com/miekg/dns/serve_mux.go b/vendor/github.com/miekg/dns/serve_mux.go deleted file mode 100644 index e7f36e2..0000000 --- a/vendor/github.com/miekg/dns/serve_mux.go +++ /dev/null @@ -1,122 +0,0 @@ -package dns - -import ( - "sync" -) - -// ServeMux is an DNS request multiplexer. It matches the zone name of -// each incoming request against a list of registered patterns add calls -// the handler for the pattern that most closely matches the zone name. -// -// ServeMux is DNSSEC aware, meaning that queries for the DS record are -// redirected to the parent zone (if that is also registered), otherwise -// the child gets the query. -// -// ServeMux is also safe for concurrent access from multiple goroutines. -// -// The zero ServeMux is empty and ready for use. -type ServeMux struct { - z map[string]Handler - m sync.RWMutex -} - -// NewServeMux allocates and returns a new ServeMux. -func NewServeMux() *ServeMux { - return new(ServeMux) -} - -// DefaultServeMux is the default ServeMux used by Serve. -var DefaultServeMux = NewServeMux() - -func (mux *ServeMux) match(q string, t uint16) Handler { - mux.m.RLock() - defer mux.m.RUnlock() - if mux.z == nil { - return nil - } - - q = CanonicalName(q) - - var handler Handler - for off, end := 0, false; !end; off, end = NextLabel(q, off) { - if h, ok := mux.z[q[off:]]; ok { - if t != TypeDS { - return h - } - // Continue for DS to see if we have a parent too, if so delegate to the parent - handler = h - } - } - - // Wildcard match, if we have found nothing try the root zone as a last resort. - if h, ok := mux.z["."]; ok { - return h - } - - return handler -} - -// Handle adds a handler to the ServeMux for pattern. -func (mux *ServeMux) Handle(pattern string, handler Handler) { - if pattern == "" { - panic("dns: invalid pattern " + pattern) - } - mux.m.Lock() - if mux.z == nil { - mux.z = make(map[string]Handler) - } - mux.z[CanonicalName(pattern)] = handler - mux.m.Unlock() -} - -// HandleFunc adds a handler function to the ServeMux for pattern. -func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { - mux.Handle(pattern, HandlerFunc(handler)) -} - -// HandleRemove deregisters the handler specific for pattern from the ServeMux. -func (mux *ServeMux) HandleRemove(pattern string) { - if pattern == "" { - panic("dns: invalid pattern " + pattern) - } - mux.m.Lock() - delete(mux.z, CanonicalName(pattern)) - mux.m.Unlock() -} - -// ServeDNS dispatches the request to the handler whose pattern most -// closely matches the request message. -// -// ServeDNS is DNSSEC aware, meaning that queries for the DS record -// are redirected to the parent zone (if that is also registered), -// otherwise the child gets the query. -// -// If no handler is found, or there is no question, a standard REFUSED -// message is returned -func (mux *ServeMux) ServeDNS(w ResponseWriter, req *Msg) { - var h Handler - if len(req.Question) >= 1 { // allow more than one question - h = mux.match(req.Question[0].Name, req.Question[0].Qtype) - } - - if h != nil { - h.ServeDNS(w, req) - } else { - handleRefused(w, req) - } -} - -// Handle registers the handler with the given pattern -// in the DefaultServeMux. The documentation for -// ServeMux explains how patterns are matched. -func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } - -// HandleRemove deregisters the handle with the given pattern -// in the DefaultServeMux. -func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) } - -// HandleFunc registers the handler function with the given pattern -// in the DefaultServeMux. -func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { - DefaultServeMux.HandleFunc(pattern, handler) -} diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go deleted file mode 100644 index 0207d6d..0000000 --- a/vendor/github.com/miekg/dns/server.go +++ /dev/null @@ -1,840 +0,0 @@ -// DNS server implementation. - -package dns - -import ( - "context" - "crypto/tls" - "encoding/binary" - "errors" - "io" - "net" - "strings" - "sync" - "time" -) - -// Default maximum number of TCP queries before we close the socket. -const maxTCPQueries = 128 - -// aLongTimeAgo is a non-zero time, far in the past, used for -// immediate cancellation of network operations. -var aLongTimeAgo = time.Unix(1, 0) - -// Handler is implemented by any value that implements ServeDNS. -type Handler interface { - ServeDNS(w ResponseWriter, r *Msg) -} - -// The HandlerFunc type is an adapter to allow the use of -// ordinary functions as DNS handlers. If f is a function -// with the appropriate signature, HandlerFunc(f) is a -// Handler object that calls f. -type HandlerFunc func(ResponseWriter, *Msg) - -// ServeDNS calls f(w, r). -func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) { - f(w, r) -} - -// A ResponseWriter interface is used by an DNS handler to -// construct an DNS response. -type ResponseWriter interface { - // LocalAddr returns the net.Addr of the server - LocalAddr() net.Addr - // RemoteAddr returns the net.Addr of the client that sent the current request. - RemoteAddr() net.Addr - // WriteMsg writes a reply back to the client. - WriteMsg(*Msg) error - // Write writes a raw buffer back to the client. - Write([]byte) (int, error) - // Close closes the connection. - Close() error - // TsigStatus returns the status of the Tsig. - TsigStatus() error - // TsigTimersOnly sets the tsig timers only boolean. - TsigTimersOnly(bool) - // Hijack lets the caller take over the connection. - // After a call to Hijack(), the DNS package will not do anything with the connection. - Hijack() -} - -// A ConnectionStater interface is used by a DNS Handler to access TLS connection state -// when available. -type ConnectionStater interface { - ConnectionState() *tls.ConnectionState -} - -type response struct { - closed bool // connection has been closed - hijacked bool // connection has been hijacked by handler - tsigTimersOnly bool - tsigStatus error - tsigRequestMAC string - tsigProvider TsigProvider - udp net.PacketConn // i/o connection if UDP was used - tcp net.Conn // i/o connection if TCP was used - udpSession *SessionUDP // oob data to get egress interface right - pcSession net.Addr // address to use when writing to a generic net.PacketConn - writer Writer // writer to output the raw DNS bits -} - -// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets. -func handleRefused(w ResponseWriter, r *Msg) { - m := new(Msg) - m.SetRcode(r, RcodeRefused) - w.WriteMsg(m) -} - -// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets. -// Deprecated: This function is going away. -func HandleFailed(w ResponseWriter, r *Msg) { - m := new(Msg) - m.SetRcode(r, RcodeServerFailure) - // does not matter if this write fails - w.WriteMsg(m) -} - -// ListenAndServe Starts a server on address and network specified Invoke handler -// for incoming queries. -func ListenAndServe(addr string, network string, handler Handler) error { - server := &Server{Addr: addr, Net: network, Handler: handler} - return server.ListenAndServe() -} - -// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in -// http://golang.org/pkg/net/http/#ListenAndServeTLS -func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return err - } - - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - server := &Server{ - Addr: addr, - Net: "tcp-tls", - TLSConfig: &config, - Handler: handler, - } - - return server.ListenAndServe() -} - -// ActivateAndServe activates a server with a listener from systemd, -// l and p should not both be non-nil. -// If both l and p are not nil only p will be used. -// Invoke handler for incoming queries. -func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error { - server := &Server{Listener: l, PacketConn: p, Handler: handler} - return server.ActivateAndServe() -} - -// Writer writes raw DNS messages; each call to Write should send an entire message. -type Writer interface { - io.Writer -} - -// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message. -type Reader interface { - // ReadTCP reads a raw message from a TCP connection. Implementations may alter - // connection properties, for example the read-deadline. - ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) - // ReadUDP reads a raw message from a UDP connection. Implementations may alter - // connection properties, for example the read-deadline. - ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) -} - -// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns. -type PacketConnReader interface { - Reader - - // ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may - // alter connection properties, for example the read-deadline. - ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) -} - -// defaultReader is an adapter for the Server struct that implements the Reader and -// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs -// of the embedded Server. -type defaultReader struct { - *Server -} - -var _ PacketConnReader = defaultReader{} - -func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { - return dr.readTCP(conn, timeout) -} - -func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { - return dr.readUDP(conn, timeout) -} - -func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) { - return dr.readPacketConn(conn, timeout) -} - -// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader. -// Implementations should never return a nil Reader. -// Readers should also implement the optional PacketConnReader interface. -// PacketConnReader is required to use a generic net.PacketConn. -type DecorateReader func(Reader) Reader - -// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer. -// Implementations should never return a nil Writer. -type DecorateWriter func(Writer) Writer - -// A Server defines parameters for running an DNS server. -type Server struct { - // Address to listen on, ":dns" if empty. - Addr string - // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one - Net string - // TCP Listener to use, this is to aid in systemd's socket activation. - Listener net.Listener - // TLS connection configuration - TLSConfig *tls.Config - // UDP "Listener" to use, this is to aid in systemd's socket activation. - PacketConn net.PacketConn - // Handler to invoke, dns.DefaultServeMux if nil. - Handler Handler - // Default buffer size to use to read incoming UDP messages. If not set - // it defaults to MinMsgSize (512 B). - UDPSize int - // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second. - ReadTimeout time.Duration - // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second. - WriteTimeout time.Duration - // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966). - IdleTimeout func() time.Duration - // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations. - TsigProvider TsigProvider - // Secret(s) for Tsig map[]. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2). - TsigSecret map[string]string - // If NotifyStartedFunc is set it is called once the server has started listening. - NotifyStartedFunc func() - // DecorateReader is optional, allows customization of the process that reads raw DNS messages. - DecorateReader DecorateReader - // DecorateWriter is optional, allows customization of the process that writes raw DNS messages. - DecorateWriter DecorateWriter - // Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1). - MaxTCPQueries int - // Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address. - // It is only supported on certain GOOSes and when using ListenAndServe. - ReusePort bool - // Whether to set the SO_REUSEADDR socket option, allowing multiple listeners to be bound to a single address. - // Crucially this allows binding when an existing server is listening on `0.0.0.0` or `::`. - // It is only supported on certain GOOSes and when using ListenAndServe. - ReuseAddr bool - // AcceptMsgFunc will check the incoming message and will reject it early in the process. - // By default DefaultMsgAcceptFunc will be used. - MsgAcceptFunc MsgAcceptFunc - - // Shutdown handling - lock sync.RWMutex - started bool - shutdown chan struct{} - conns map[net.Conn]struct{} - - // A pool for UDP message buffers. - udpPool sync.Pool -} - -func (srv *Server) tsigProvider() TsigProvider { - if srv.TsigProvider != nil { - return srv.TsigProvider - } - if srv.TsigSecret != nil { - return tsigSecretProvider(srv.TsigSecret) - } - return nil -} - -func (srv *Server) isStarted() bool { - srv.lock.RLock() - started := srv.started - srv.lock.RUnlock() - return started -} - -func makeUDPBuffer(size int) func() interface{} { - return func() interface{} { - return make([]byte, size) - } -} - -func (srv *Server) init() { - srv.shutdown = make(chan struct{}) - srv.conns = make(map[net.Conn]struct{}) - - if srv.UDPSize == 0 { - srv.UDPSize = MinMsgSize - } - if srv.MsgAcceptFunc == nil { - srv.MsgAcceptFunc = DefaultMsgAcceptFunc - } - if srv.Handler == nil { - srv.Handler = DefaultServeMux - } - - srv.udpPool.New = makeUDPBuffer(srv.UDPSize) -} - -func unlockOnce(l sync.Locker) func() { - var once sync.Once - return func() { once.Do(l.Unlock) } -} - -// ListenAndServe starts a nameserver on the configured address in *Server. -func (srv *Server) ListenAndServe() error { - unlock := unlockOnce(&srv.lock) - srv.lock.Lock() - defer unlock() - - if srv.started { - return &Error{err: "server already started"} - } - - addr := srv.Addr - if addr == "" { - addr = ":domain" - } - - srv.init() - - switch srv.Net { - case "tcp", "tcp4", "tcp6": - l, err := listenTCP(srv.Net, addr, srv.ReusePort, srv.ReuseAddr) - if err != nil { - return err - } - srv.Listener = l - srv.started = true - unlock() - return srv.serveTCP(l) - case "tcp-tls", "tcp4-tls", "tcp6-tls": - if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) { - return errors.New("dns: neither Certificates nor GetCertificate set in Config") - } - network := strings.TrimSuffix(srv.Net, "-tls") - l, err := listenTCP(network, addr, srv.ReusePort, srv.ReuseAddr) - if err != nil { - return err - } - l = tls.NewListener(l, srv.TLSConfig) - srv.Listener = l - srv.started = true - unlock() - return srv.serveTCP(l) - case "udp", "udp4", "udp6": - l, err := listenUDP(srv.Net, addr, srv.ReusePort, srv.ReuseAddr) - if err != nil { - return err - } - u := l.(*net.UDPConn) - if e := setUDPSocketOptions(u); e != nil { - u.Close() - return e - } - srv.PacketConn = l - srv.started = true - unlock() - return srv.serveUDP(u) - } - return &Error{err: "bad network"} -} - -// ActivateAndServe starts a nameserver with the PacketConn or Listener -// configured in *Server. Its main use is to start a server from systemd. -func (srv *Server) ActivateAndServe() error { - unlock := unlockOnce(&srv.lock) - srv.lock.Lock() - defer unlock() - - if srv.started { - return &Error{err: "server already started"} - } - - srv.init() - - if srv.PacketConn != nil { - // Check PacketConn interface's type is valid and value - // is not nil - if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil { - if e := setUDPSocketOptions(t); e != nil { - return e - } - } - srv.started = true - unlock() - return srv.serveUDP(srv.PacketConn) - } - if srv.Listener != nil { - srv.started = true - unlock() - return srv.serveTCP(srv.Listener) - } - return &Error{err: "bad listeners"} -} - -// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and -// ActivateAndServe will return. -func (srv *Server) Shutdown() error { - return srv.ShutdownContext(context.Background()) -} - -// ShutdownContext shuts down a server. After a call to ShutdownContext, -// ListenAndServe and ActivateAndServe will return. -// -// A context.Context may be passed to limit how long to wait for connections -// to terminate. -func (srv *Server) ShutdownContext(ctx context.Context) error { - srv.lock.Lock() - if !srv.started { - srv.lock.Unlock() - return &Error{err: "server not started"} - } - - srv.started = false - - if srv.PacketConn != nil { - srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads - } - - if srv.Listener != nil { - srv.Listener.Close() - } - - for rw := range srv.conns { - rw.SetReadDeadline(aLongTimeAgo) // Unblock reads - } - - srv.lock.Unlock() - - if testShutdownNotify != nil { - testShutdownNotify.Broadcast() - } - - var ctxErr error - select { - case <-srv.shutdown: - case <-ctx.Done(): - ctxErr = ctx.Err() - } - - if srv.PacketConn != nil { - srv.PacketConn.Close() - } - - return ctxErr -} - -var testShutdownNotify *sync.Cond - -// getReadTimeout is a helper func to use system timeout if server did not intend to change it. -func (srv *Server) getReadTimeout() time.Duration { - if srv.ReadTimeout != 0 { - return srv.ReadTimeout - } - return dnsTimeout -} - -// serveTCP starts a TCP listener for the server. -func (srv *Server) serveTCP(l net.Listener) error { - defer l.Close() - - if srv.NotifyStartedFunc != nil { - srv.NotifyStartedFunc() - } - - var wg sync.WaitGroup - defer func() { - wg.Wait() - close(srv.shutdown) - }() - - for srv.isStarted() { - rw, err := l.Accept() - if err != nil { - if !srv.isStarted() { - return nil - } - if neterr, ok := err.(net.Error); ok && neterr.Temporary() { - continue - } - return err - } - srv.lock.Lock() - // Track the connection to allow unblocking reads on shutdown. - srv.conns[rw] = struct{}{} - srv.lock.Unlock() - wg.Add(1) - go srv.serveTCPConn(&wg, rw) - } - - return nil -} - -// serveUDP starts a UDP listener for the server. -func (srv *Server) serveUDP(l net.PacketConn) error { - defer l.Close() - - reader := Reader(defaultReader{srv}) - if srv.DecorateReader != nil { - reader = srv.DecorateReader(reader) - } - - lUDP, isUDP := l.(*net.UDPConn) - readerPC, canPacketConn := reader.(PacketConnReader) - if !isUDP && !canPacketConn { - return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"} - } - - if srv.NotifyStartedFunc != nil { - srv.NotifyStartedFunc() - } - - var wg sync.WaitGroup - defer func() { - wg.Wait() - close(srv.shutdown) - }() - - rtimeout := srv.getReadTimeout() - // deadline is not used here - for srv.isStarted() { - var ( - m []byte - sPC net.Addr - sUDP *SessionUDP - err error - ) - if isUDP { - m, sUDP, err = reader.ReadUDP(lUDP, rtimeout) - } else { - m, sPC, err = readerPC.ReadPacketConn(l, rtimeout) - } - if err != nil { - if !srv.isStarted() { - return nil - } - if netErr, ok := err.(net.Error); ok && netErr.Temporary() { - continue - } - return err - } - if len(m) < headerSize { - if cap(m) == srv.UDPSize { - srv.udpPool.Put(m[:srv.UDPSize]) - } - continue - } - wg.Add(1) - go srv.serveUDPPacket(&wg, m, l, sUDP, sPC) - } - - return nil -} - -// Serve a new TCP connection. -func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) { - w := &response{tsigProvider: srv.tsigProvider(), tcp: rw} - if srv.DecorateWriter != nil { - w.writer = srv.DecorateWriter(w) - } else { - w.writer = w - } - - reader := Reader(defaultReader{srv}) - if srv.DecorateReader != nil { - reader = srv.DecorateReader(reader) - } - - idleTimeout := tcpIdleTimeout - if srv.IdleTimeout != nil { - idleTimeout = srv.IdleTimeout() - } - - timeout := srv.getReadTimeout() - - limit := srv.MaxTCPQueries - if limit == 0 { - limit = maxTCPQueries - } - - for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ { - m, err := reader.ReadTCP(w.tcp, timeout) - if err != nil { - // TODO(tmthrgd): handle error - break - } - srv.serveDNS(m, w) - if w.closed { - break // Close() was called - } - if w.hijacked { - break // client will call Close() themselves - } - // The first read uses the read timeout, the rest use the - // idle timeout. - timeout = idleTimeout - } - - if !w.hijacked { - w.Close() - } - - srv.lock.Lock() - delete(srv.conns, w.tcp) - srv.lock.Unlock() - - wg.Done() -} - -// Serve a new UDP request. -func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn, udpSession *SessionUDP, pcSession net.Addr) { - w := &response{tsigProvider: srv.tsigProvider(), udp: u, udpSession: udpSession, pcSession: pcSession} - if srv.DecorateWriter != nil { - w.writer = srv.DecorateWriter(w) - } else { - w.writer = w - } - - srv.serveDNS(m, w) - wg.Done() -} - -func (srv *Server) serveDNS(m []byte, w *response) { - dh, off, err := unpackMsgHdr(m, 0) - if err != nil { - // Let client hang, they are sending crap; any reply can be used to amplify. - return - } - - req := new(Msg) - req.setHdr(dh) - - switch action := srv.MsgAcceptFunc(dh); action { - case MsgAccept: - if req.unpack(dh, m, off) == nil { - break - } - - fallthrough - case MsgReject, MsgRejectNotImplemented: - opcode := req.Opcode - req.SetRcodeFormatError(req) - req.Zero = false - if action == MsgRejectNotImplemented { - req.Opcode = opcode - req.Rcode = RcodeNotImplemented - } - - // Are we allowed to delete any OPT records here? - req.Ns, req.Answer, req.Extra = nil, nil, nil - - w.WriteMsg(req) - fallthrough - case MsgIgnore: - if w.udp != nil && cap(m) == srv.UDPSize { - srv.udpPool.Put(m[:srv.UDPSize]) - } - - return - } - - w.tsigStatus = nil - if w.tsigProvider != nil { - if t := req.IsTsig(); t != nil { - w.tsigStatus = TsigVerifyWithProvider(m, w.tsigProvider, "", false) - w.tsigTimersOnly = false - w.tsigRequestMAC = t.MAC - } - } - - if w.udp != nil && cap(m) == srv.UDPSize { - srv.udpPool.Put(m[:srv.UDPSize]) - } - - srv.Handler.ServeDNS(w, req) // Writes back to the client -} - -func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { - // If we race with ShutdownContext, the read deadline may - // have been set in the distant past to unblock the read - // below. We must not override it, otherwise we may block - // ShutdownContext. - srv.lock.RLock() - if srv.started { - conn.SetReadDeadline(time.Now().Add(timeout)) - } - srv.lock.RUnlock() - - var length uint16 - if err := binary.Read(conn, binary.BigEndian, &length); err != nil { - return nil, err - } - - m := make([]byte, length) - if _, err := io.ReadFull(conn, m); err != nil { - return nil, err - } - - return m, nil -} - -func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { - srv.lock.RLock() - if srv.started { - // See the comment in readTCP above. - conn.SetReadDeadline(time.Now().Add(timeout)) - } - srv.lock.RUnlock() - - m := srv.udpPool.Get().([]byte) - n, s, err := ReadFromSessionUDP(conn, m) - if err != nil { - srv.udpPool.Put(m) - return nil, nil, err - } - m = m[:n] - return m, s, nil -} - -func (srv *Server) readPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) { - srv.lock.RLock() - if srv.started { - // See the comment in readTCP above. - conn.SetReadDeadline(time.Now().Add(timeout)) - } - srv.lock.RUnlock() - - m := srv.udpPool.Get().([]byte) - n, addr, err := conn.ReadFrom(m) - if err != nil { - srv.udpPool.Put(m) - return nil, nil, err - } - m = m[:n] - return m, addr, nil -} - -// WriteMsg implements the ResponseWriter.WriteMsg method. -func (w *response) WriteMsg(m *Msg) (err error) { - if w.closed { - return &Error{err: "WriteMsg called after Close"} - } - - var data []byte - if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check) - if t := m.IsTsig(); t != nil { - data, w.tsigRequestMAC, err = TsigGenerateWithProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly) - if err != nil { - return err - } - _, err = w.writer.Write(data) - return err - } - } - data, err = m.Pack() - if err != nil { - return err - } - _, err = w.writer.Write(data) - return err -} - -// Write implements the ResponseWriter.Write method. -func (w *response) Write(m []byte) (int, error) { - if w.closed { - return 0, &Error{err: "Write called after Close"} - } - - switch { - case w.udp != nil: - if u, ok := w.udp.(*net.UDPConn); ok { - return WriteToSessionUDP(u, m, w.udpSession) - } - return w.udp.WriteTo(m, w.pcSession) - case w.tcp != nil: - if len(m) > MaxMsgSize { - return 0, &Error{err: "message too large"} - } - - msg := make([]byte, 2+len(m)) - binary.BigEndian.PutUint16(msg, uint16(len(m))) - copy(msg[2:], m) - return w.tcp.Write(msg) - default: - panic("dns: internal error: udp and tcp both nil") - } -} - -// LocalAddr implements the ResponseWriter.LocalAddr method. -func (w *response) LocalAddr() net.Addr { - switch { - case w.udp != nil: - return w.udp.LocalAddr() - case w.tcp != nil: - return w.tcp.LocalAddr() - default: - panic("dns: internal error: udp and tcp both nil") - } -} - -// RemoteAddr implements the ResponseWriter.RemoteAddr method. -func (w *response) RemoteAddr() net.Addr { - switch { - case w.udpSession != nil: - return w.udpSession.RemoteAddr() - case w.pcSession != nil: - return w.pcSession - case w.tcp != nil: - return w.tcp.RemoteAddr() - default: - panic("dns: internal error: udpSession, pcSession and tcp are all nil") - } -} - -// TsigStatus implements the ResponseWriter.TsigStatus method. -func (w *response) TsigStatus() error { return w.tsigStatus } - -// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method. -func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b } - -// Hijack implements the ResponseWriter.Hijack method. -func (w *response) Hijack() { w.hijacked = true } - -// Close implements the ResponseWriter.Close method -func (w *response) Close() error { - if w.closed { - return &Error{err: "connection already closed"} - } - w.closed = true - - switch { - case w.udp != nil: - // Can't close the udp conn, as that is actually the listener. - return nil - case w.tcp != nil: - return w.tcp.Close() - default: - panic("dns: internal error: udp and tcp both nil") - } -} - -// ConnectionState() implements the ConnectionStater.ConnectionState() interface. -func (w *response) ConnectionState() *tls.ConnectionState { - type tlsConnectionStater interface { - ConnectionState() tls.ConnectionState - } - if v, ok := w.tcp.(tlsConnectionStater); ok { - t := v.ConnectionState() - return &t - } - return nil -} diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go deleted file mode 100644 index 2c4b103..0000000 --- a/vendor/github.com/miekg/dns/sig0.go +++ /dev/null @@ -1,194 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "encoding/binary" - "math/big" - "strings" - "time" -) - -// Sign signs a dns.Msg. It fills the signature with the appropriate data. -// The SIG record should have the SignerName, KeyTag, Algorithm, Inception -// and Expiration set. -func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) { - if k == nil { - return nil, ErrPrivKey - } - if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 { - return nil, ErrKey - } - - rr.Hdr = RR_Header{Name: ".", Rrtype: TypeSIG, Class: ClassANY, Ttl: 0} - rr.OrigTtl, rr.TypeCovered, rr.Labels = 0, 0, 0 - - buf := make([]byte, m.Len()+Len(rr)) - mbuf, err := m.PackBuffer(buf) - if err != nil { - return nil, err - } - if &buf[0] != &mbuf[0] { - return nil, ErrBuf - } - off, err := PackRR(rr, buf, len(mbuf), nil, false) - if err != nil { - return nil, err - } - buf = buf[:off:cap(buf)] - - h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) - if err != nil { - return nil, err - } - - // Write SIG rdata - h.Write(buf[len(mbuf)+1+2+2+4+2:]) - // Write message - h.Write(buf[:len(mbuf)]) - - signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm) - if err != nil { - return nil, err - } - - rr.Signature = toBase64(signature) - - buf = append(buf, signature...) - if len(buf) > int(^uint16(0)) { - return nil, ErrBuf - } - // Adjust sig data length - rdoff := len(mbuf) + 1 + 2 + 2 + 4 - rdlen := binary.BigEndian.Uint16(buf[rdoff:]) - rdlen += uint16(len(signature)) - binary.BigEndian.PutUint16(buf[rdoff:], rdlen) - // Adjust additional count - adc := binary.BigEndian.Uint16(buf[10:]) - adc++ - binary.BigEndian.PutUint16(buf[10:], adc) - return buf, nil -} - -// Verify validates the message buf using the key k. -// It's assumed that buf is a valid message from which rr was unpacked. -func (rr *SIG) Verify(k *KEY, buf []byte) error { - if k == nil { - return ErrKey - } - if rr.KeyTag == 0 || rr.SignerName == "" || rr.Algorithm == 0 { - return ErrKey - } - - h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) - if err != nil { - return err - } - - buflen := len(buf) - qdc := binary.BigEndian.Uint16(buf[4:]) - anc := binary.BigEndian.Uint16(buf[6:]) - auc := binary.BigEndian.Uint16(buf[8:]) - adc := binary.BigEndian.Uint16(buf[10:]) - offset := headerSize - for i := uint16(0); i < qdc && offset < buflen; i++ { - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip past Type and Class - offset += 2 + 2 - } - for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ { - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip past Type, Class and TTL - offset += 2 + 2 + 4 - if offset+1 >= buflen { - continue - } - rdlen := binary.BigEndian.Uint16(buf[offset:]) - offset += 2 - offset += int(rdlen) - } - if offset >= buflen { - return &Error{err: "overflowing unpacking signed message"} - } - - // offset should be just prior to SIG - bodyend := offset - // owner name SHOULD be root - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip Type, Class, TTL, RDLen - offset += 2 + 2 + 4 + 2 - sigstart := offset - // Skip Type Covered, Algorithm, Labels, Original TTL - offset += 2 + 1 + 1 + 4 - if offset+4+4 >= buflen { - return &Error{err: "overflow unpacking signed message"} - } - expire := binary.BigEndian.Uint32(buf[offset:]) - offset += 4 - incept := binary.BigEndian.Uint32(buf[offset:]) - offset += 4 - now := uint32(time.Now().Unix()) - if now < incept || now > expire { - return ErrTime - } - // Skip key tag - offset += 2 - var signername string - signername, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // If key has come from the DNS name compression might - // have mangled the case of the name - if !strings.EqualFold(signername, k.Header().Name) { - return &Error{err: "signer name doesn't match key name"} - } - sigend := offset - h.Write(buf[sigstart:sigend]) - h.Write(buf[:10]) - h.Write([]byte{ - byte((adc - 1) << 8), - byte(adc - 1), - }) - h.Write(buf[12:bodyend]) - - hashed := h.Sum(nil) - sig := buf[sigend:] - switch k.Algorithm { - case RSASHA1, RSASHA256, RSASHA512: - pk := k.publicKeyRSA() - if pk != nil { - return rsa.VerifyPKCS1v15(pk, cryptohash, hashed, sig) - } - case ECDSAP256SHA256, ECDSAP384SHA384: - pk := k.publicKeyECDSA() - r := new(big.Int).SetBytes(sig[:len(sig)/2]) - s := new(big.Int).SetBytes(sig[len(sig)/2:]) - if pk != nil { - if ecdsa.Verify(pk, hashed, r, s) { - return nil - } - return ErrSig - } - case ED25519: - pk := k.publicKeyED25519() - if pk != nil { - if ed25519.Verify(pk, hashed, sig) { - return nil - } - return ErrSig - } - } - return ErrKeyAlg -} diff --git a/vendor/github.com/miekg/dns/smimea.go b/vendor/github.com/miekg/dns/smimea.go deleted file mode 100644 index 89f09f0..0000000 --- a/vendor/github.com/miekg/dns/smimea.go +++ /dev/null @@ -1,44 +0,0 @@ -package dns - -import ( - "crypto/sha256" - "crypto/x509" - "encoding/hex" -) - -// Sign creates a SMIMEA record from an SSL certificate. -func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { - r.Hdr.Rrtype = TypeSMIMEA - r.Usage = uint8(usage) - r.Selector = uint8(selector) - r.MatchingType = uint8(matchingType) - - r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) - return err -} - -// Verify verifies a SMIMEA record against an SSL certificate. If it is OK -// a nil error is returned. -func (r *SMIMEA) Verify(cert *x509.Certificate) error { - c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err // Not also ErrSig? - } - if r.Certificate == c { - return nil - } - return ErrSig // ErrSig, really? -} - -// SMIMEAName returns the ownername of a SMIMEA resource record as per the -// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3 -func SMIMEAName(email, domain string) (string, error) { - hasher := sha256.New() - hasher.Write([]byte(email)) - - // RFC Section 3: "The local-part is hashed using the SHA2-256 - // algorithm with the hash truncated to 28 octets and - // represented in its hexadecimal representation to become the - // left-most label in the prepared domain name" - return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil -} diff --git a/vendor/github.com/miekg/dns/svcb.go b/vendor/github.com/miekg/dns/svcb.go deleted file mode 100644 index c1a740b..0000000 --- a/vendor/github.com/miekg/dns/svcb.go +++ /dev/null @@ -1,935 +0,0 @@ -package dns - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "net" - "sort" - "strconv" - "strings" -) - -// SVCBKey is the type of the keys used in the SVCB RR. -type SVCBKey uint16 - -// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2. -const ( - SVCB_MANDATORY SVCBKey = iota - SVCB_ALPN - SVCB_NO_DEFAULT_ALPN - SVCB_PORT - SVCB_IPV4HINT - SVCB_ECHCONFIG - SVCB_IPV6HINT - SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9 - - svcb_RESERVED SVCBKey = 65535 -) - -var svcbKeyToStringMap = map[SVCBKey]string{ - SVCB_MANDATORY: "mandatory", - SVCB_ALPN: "alpn", - SVCB_NO_DEFAULT_ALPN: "no-default-alpn", - SVCB_PORT: "port", - SVCB_IPV4HINT: "ipv4hint", - SVCB_ECHCONFIG: "ech", - SVCB_IPV6HINT: "ipv6hint", - SVCB_DOHPATH: "dohpath", -} - -var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap) - -func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey { - n := make(map[string]SVCBKey, len(m)) - for u, s := range m { - n[s] = u - } - return n -} - -// String takes the numerical code of an SVCB key and returns its name. -// Returns an empty string for reserved keys. -// Accepts unassigned keys as well as experimental/private keys. -func (key SVCBKey) String() string { - if x := svcbKeyToStringMap[key]; x != "" { - return x - } - if key == svcb_RESERVED { - return "" - } - return "key" + strconv.FormatUint(uint64(key), 10) -} - -// svcbStringToKey returns the numerical code of an SVCB key. -// Returns svcb_RESERVED for reserved/invalid keys. -// Accepts unassigned keys as well as experimental/private keys. -func svcbStringToKey(s string) SVCBKey { - if strings.HasPrefix(s, "key") { - a, err := strconv.ParseUint(s[3:], 10, 16) - // no leading zeros - // key shouldn't be registered - if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" { - return svcb_RESERVED - } - return SVCBKey(a) - } - if key, ok := svcbStringToKeyMap[s]; ok { - return key - } - return svcb_RESERVED -} - -func (rr *SVCB) parse(c *zlexer, o string) *ParseError { - l, _ := c.Next() - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return &ParseError{file: l.token, err: "bad SVCB priority", lex: l} - } - rr.Priority = uint16(i) - - c.Next() // zBlank - l, _ = c.Next() // zString - rr.Target = l.token - - name, nameOk := toAbsoluteName(l.token, o) - if l.err || !nameOk { - return &ParseError{file: l.token, err: "bad SVCB Target", lex: l} - } - rr.Target = name - - // Values (if any) - l, _ = c.Next() - var xs []SVCBKeyValue - // Helps require whitespace between pairs. - // Prevents key1000="a"key1001=... - canHaveNextKey := true - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zString: - if !canHaveNextKey { - // The key we can now read was probably meant to be - // a part of the last value. - return &ParseError{file: l.token, err: "bad SVCB value quotation", lex: l} - } - - // In key=value pairs, value does not have to be quoted unless value - // contains whitespace. And keys don't need to have values. - // Similarly, keys with an equality signs after them don't need values. - // l.token includes at least up to the first equality sign. - idx := strings.IndexByte(l.token, '=') - var key, value string - if idx < 0 { - // Key with no value and no equality sign - key = l.token - } else if idx == 0 { - return &ParseError{file: l.token, err: "bad SVCB key", lex: l} - } else { - key, value = l.token[:idx], l.token[idx+1:] - - if value == "" { - // We have a key and an equality sign. Maybe we have nothing - // after "=" or we have a double quote. - l, _ = c.Next() - if l.value == zQuote { - // Only needed when value ends with double quotes. - // Any value starting with zQuote ends with it. - canHaveNextKey = false - - l, _ = c.Next() - switch l.value { - case zString: - // We have a value in double quotes. - value = l.token - l, _ = c.Next() - if l.value != zQuote { - return &ParseError{file: l.token, err: "SVCB unterminated value", lex: l} - } - case zQuote: - // There's nothing in double quotes. - default: - return &ParseError{file: l.token, err: "bad SVCB value", lex: l} - } - } - } - } - kv := makeSVCBKeyValue(svcbStringToKey(key)) - if kv == nil { - return &ParseError{file: l.token, err: "bad SVCB key", lex: l} - } - if err := kv.parse(value); err != nil { - return &ParseError{file: l.token, wrappedErr: err, lex: l} - } - xs = append(xs, kv) - case zQuote: - return &ParseError{file: l.token, err: "SVCB key can't contain double quotes", lex: l} - case zBlank: - canHaveNextKey = true - default: - return &ParseError{file: l.token, err: "bad SVCB values", lex: l} - } - l, _ = c.Next() - } - - // "In AliasMode, records SHOULD NOT include any SvcParams, and recipients MUST - // ignore any SvcParams that are present." - // However, we don't check rr.Priority == 0 && len(xs) > 0 here - // It is the responsibility of the user of the library to check this. - // This is to encourage the fixing of the source of this error. - - rr.Value = xs - return nil -} - -// makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys. -func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue { - switch key { - case SVCB_MANDATORY: - return new(SVCBMandatory) - case SVCB_ALPN: - return new(SVCBAlpn) - case SVCB_NO_DEFAULT_ALPN: - return new(SVCBNoDefaultAlpn) - case SVCB_PORT: - return new(SVCBPort) - case SVCB_IPV4HINT: - return new(SVCBIPv4Hint) - case SVCB_ECHCONFIG: - return new(SVCBECHConfig) - case SVCB_IPV6HINT: - return new(SVCBIPv6Hint) - case SVCB_DOHPATH: - return new(SVCBDoHPath) - case svcb_RESERVED: - return nil - default: - e := new(SVCBLocal) - e.KeyCode = key - return e - } -} - -// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-08). -// -// NOTE: The HTTPS/SVCB RFCs are in the draft stage. -// The API, including constants and types related to SVCBKeyValues, may -// change in future versions in accordance with the latest drafts. -type SVCB struct { - Hdr RR_Header - Priority uint16 // If zero, Value must be empty or discarded by the user of this library - Target string `dns:"domain-name"` - Value []SVCBKeyValue `dns:"pairs"` -} - -// HTTPS RR. Everything valid for SVCB applies to HTTPS as well. -// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols. -// -// NOTE: The HTTPS/SVCB RFCs are in the draft stage. -// The API, including constants and types related to SVCBKeyValues, may -// change in future versions in accordance with the latest drafts. -type HTTPS struct { - SVCB -} - -func (rr *HTTPS) String() string { - return rr.SVCB.String() -} - -func (rr *HTTPS) parse(c *zlexer, o string) *ParseError { - return rr.SVCB.parse(c, o) -} - -// SVCBKeyValue defines a key=value pair for the SVCB RR type. -// An SVCB RR can have multiple SVCBKeyValues appended to it. -type SVCBKeyValue interface { - Key() SVCBKey // Key returns the numerical key code. - pack() ([]byte, error) // pack returns the encoded value. - unpack([]byte) error // unpack sets the value. - String() string // String returns the string representation of the value. - parse(string) error // parse sets the value to the given string representation of the value. - copy() SVCBKeyValue // copy returns a deep-copy of the pair. - len() int // len returns the length of value in the wire format. -} - -// SVCBMandatory pair adds to required keys that must be interpreted for the RR -// to be functional. If ignored, the whole RRSet must be ignored. -// "port" and "no-default-alpn" are mandatory by default if present, -// so they shouldn't be included here. -// -// It is incumbent upon the user of this library to reject the RRSet if -// or avoid constructing such an RRSet that: -// - "mandatory" is included as one of the keys of mandatory -// - no key is listed multiple times in mandatory -// - all keys listed in mandatory are present -// - escape sequences are not used in mandatory -// - mandatory, when present, lists at least one key -// -// Basic use pattern for creating a mandatory option: -// -// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} -// e := new(dns.SVCBMandatory) -// e.Code = []uint16{dns.SVCB_ALPN} -// s.Value = append(s.Value, e) -// t := new(dns.SVCBAlpn) -// t.Alpn = []string{"xmpp-client"} -// s.Value = append(s.Value, t) -type SVCBMandatory struct { - Code []SVCBKey -} - -func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY } - -func (s *SVCBMandatory) String() string { - str := make([]string, len(s.Code)) - for i, e := range s.Code { - str[i] = e.String() - } - return strings.Join(str, ",") -} - -func (s *SVCBMandatory) pack() ([]byte, error) { - codes := cloneSlice(s.Code) - sort.Slice(codes, func(i, j int) bool { - return codes[i] < codes[j] - }) - b := make([]byte, 2*len(codes)) - for i, e := range codes { - binary.BigEndian.PutUint16(b[2*i:], uint16(e)) - } - return b, nil -} - -func (s *SVCBMandatory) unpack(b []byte) error { - if len(b)%2 != 0 { - return errors.New("dns: svcbmandatory: value length is not a multiple of 2") - } - codes := make([]SVCBKey, 0, len(b)/2) - for i := 0; i < len(b); i += 2 { - // We assume strictly increasing order. - codes = append(codes, SVCBKey(binary.BigEndian.Uint16(b[i:]))) - } - s.Code = codes - return nil -} - -func (s *SVCBMandatory) parse(b string) error { - codes := make([]SVCBKey, 0, strings.Count(b, ",")+1) - for len(b) > 0 { - var key string - key, b, _ = strings.Cut(b, ",") - codes = append(codes, svcbStringToKey(key)) - } - s.Code = codes - return nil -} - -func (s *SVCBMandatory) len() int { - return 2 * len(s.Code) -} - -func (s *SVCBMandatory) copy() SVCBKeyValue { - return &SVCBMandatory{cloneSlice(s.Code)} -} - -// SVCBAlpn pair is used to list supported connection protocols. -// The user of this library must ensure that at least one protocol is listed when alpn is present. -// Protocol IDs can be found at: -// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids -// Basic use pattern for creating an alpn option: -// -// h := new(dns.HTTPS) -// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} -// e := new(dns.SVCBAlpn) -// e.Alpn = []string{"h2", "http/1.1"} -// h.Value = append(h.Value, e) -type SVCBAlpn struct { - Alpn []string -} - -func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN } - -func (s *SVCBAlpn) String() string { - // An ALPN value is a comma-separated list of values, each of which can be - // an arbitrary binary value. In order to allow parsing, the comma and - // backslash characters are themselves escaped. - // - // However, this escaping is done in addition to the normal escaping which - // happens in zone files, meaning that these values must be - // double-escaped. This looks terrible, so if you see a never-ending - // sequence of backslash in a zone file this may be why. - // - // https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08#appendix-A.1 - var str strings.Builder - for i, alpn := range s.Alpn { - // 4*len(alpn) is the worst case where we escape every character in the alpn as \123, plus 1 byte for the ',' separating the alpn from others - str.Grow(4*len(alpn) + 1) - if i > 0 { - str.WriteByte(',') - } - for j := 0; j < len(alpn); j++ { - e := alpn[j] - if ' ' > e || e > '~' { - str.WriteString(escapeByte(e)) - continue - } - switch e { - // We escape a few characters which may confuse humans or parsers. - case '"', ';', ' ': - str.WriteByte('\\') - str.WriteByte(e) - // The comma and backslash characters themselves must be - // doubly-escaped. We use `\\` for the first backslash and - // the escaped numeric value for the other value. We especially - // don't want a comma in the output. - case ',': - str.WriteString(`\\\044`) - case '\\': - str.WriteString(`\\\092`) - default: - str.WriteByte(e) - } - } - } - return str.String() -} - -func (s *SVCBAlpn) pack() ([]byte, error) { - // Liberally estimate the size of an alpn as 10 octets - b := make([]byte, 0, 10*len(s.Alpn)) - for _, e := range s.Alpn { - if e == "" { - return nil, errors.New("dns: svcbalpn: empty alpn-id") - } - if len(e) > 255 { - return nil, errors.New("dns: svcbalpn: alpn-id too long") - } - b = append(b, byte(len(e))) - b = append(b, e...) - } - return b, nil -} - -func (s *SVCBAlpn) unpack(b []byte) error { - // Estimate the size of the smallest alpn as 4 bytes - alpn := make([]string, 0, len(b)/4) - for i := 0; i < len(b); { - length := int(b[i]) - i++ - if i+length > len(b) { - return errors.New("dns: svcbalpn: alpn array overflowing") - } - alpn = append(alpn, string(b[i:i+length])) - i += length - } - s.Alpn = alpn - return nil -} - -func (s *SVCBAlpn) parse(b string) error { - if len(b) == 0 { - s.Alpn = []string{} - return nil - } - - alpn := []string{} - a := []byte{} - for p := 0; p < len(b); { - c, q := nextByte(b, p) - if q == 0 { - return errors.New("dns: svcbalpn: unterminated escape") - } - p += q - // If we find a comma, we have finished reading an alpn. - if c == ',' { - if len(a) == 0 { - return errors.New("dns: svcbalpn: empty protocol identifier") - } - alpn = append(alpn, string(a)) - a = []byte{} - continue - } - // If it's a backslash, we need to handle a comma-separated list. - if c == '\\' { - dc, dq := nextByte(b, p) - if dq == 0 { - return errors.New("dns: svcbalpn: unterminated escape decoding comma-separated list") - } - if dc != '\\' && dc != ',' { - return errors.New("dns: svcbalpn: bad escaped character decoding comma-separated list") - } - p += dq - c = dc - } - a = append(a, c) - } - // Add the final alpn. - if len(a) == 0 { - return errors.New("dns: svcbalpn: last protocol identifier empty") - } - s.Alpn = append(alpn, string(a)) - return nil -} - -func (s *SVCBAlpn) len() int { - var l int - for _, e := range s.Alpn { - l += 1 + len(e) - } - return l -} - -func (s *SVCBAlpn) copy() SVCBKeyValue { - return &SVCBAlpn{cloneSlice(s.Alpn)} -} - -// SVCBNoDefaultAlpn pair signifies no support for default connection protocols. -// Should be used in conjunction with alpn. -// Basic use pattern for creating a no-default-alpn option: -// -// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} -// t := new(dns.SVCBAlpn) -// t.Alpn = []string{"xmpp-client"} -// s.Value = append(s.Value, t) -// e := new(dns.SVCBNoDefaultAlpn) -// s.Value = append(s.Value, e) -type SVCBNoDefaultAlpn struct{} - -func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN } -func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} } -func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil } -func (*SVCBNoDefaultAlpn) String() string { return "" } -func (*SVCBNoDefaultAlpn) len() int { return 0 } - -func (*SVCBNoDefaultAlpn) unpack(b []byte) error { - if len(b) != 0 { - return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value") - } - return nil -} - -func (*SVCBNoDefaultAlpn) parse(b string) error { - if b != "" { - return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value") - } - return nil -} - -// SVCBPort pair defines the port for connection. -// Basic use pattern for creating a port option: -// -// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}} -// e := new(dns.SVCBPort) -// e.Port = 80 -// s.Value = append(s.Value, e) -type SVCBPort struct { - Port uint16 -} - -func (*SVCBPort) Key() SVCBKey { return SVCB_PORT } -func (*SVCBPort) len() int { return 2 } -func (s *SVCBPort) String() string { return strconv.FormatUint(uint64(s.Port), 10) } -func (s *SVCBPort) copy() SVCBKeyValue { return &SVCBPort{s.Port} } - -func (s *SVCBPort) unpack(b []byte) error { - if len(b) != 2 { - return errors.New("dns: svcbport: port length is not exactly 2 octets") - } - s.Port = binary.BigEndian.Uint16(b) - return nil -} - -func (s *SVCBPort) pack() ([]byte, error) { - b := make([]byte, 2) - binary.BigEndian.PutUint16(b, s.Port) - return b, nil -} - -func (s *SVCBPort) parse(b string) error { - port, err := strconv.ParseUint(b, 10, 16) - if err != nil { - return errors.New("dns: svcbport: port out of range") - } - s.Port = uint16(port) - return nil -} - -// SVCBIPv4Hint pair suggests an IPv4 address which may be used to open connections -// if A and AAAA record responses for SVCB's Target domain haven't been received. -// In that case, optionally, A and AAAA requests can be made, after which the connection -// to the hinted IP address may be terminated and a new connection may be opened. -// Basic use pattern for creating an ipv4hint option: -// -// h := new(dns.HTTPS) -// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} -// e := new(dns.SVCBIPv4Hint) -// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()} -// -// Or -// -// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()} -// h.Value = append(h.Value, e) -type SVCBIPv4Hint struct { - Hint []net.IP -} - -func (*SVCBIPv4Hint) Key() SVCBKey { return SVCB_IPV4HINT } -func (s *SVCBIPv4Hint) len() int { return 4 * len(s.Hint) } - -func (s *SVCBIPv4Hint) pack() ([]byte, error) { - b := make([]byte, 0, 4*len(s.Hint)) - for _, e := range s.Hint { - x := e.To4() - if x == nil { - return nil, errors.New("dns: svcbipv4hint: expected ipv4, hint is ipv6") - } - b = append(b, x...) - } - return b, nil -} - -func (s *SVCBIPv4Hint) unpack(b []byte) error { - if len(b) == 0 || len(b)%4 != 0 { - return errors.New("dns: svcbipv4hint: ipv4 address byte array length is not a multiple of 4") - } - b = cloneSlice(b) - x := make([]net.IP, 0, len(b)/4) - for i := 0; i < len(b); i += 4 { - x = append(x, net.IP(b[i:i+4])) - } - s.Hint = x - return nil -} - -func (s *SVCBIPv4Hint) String() string { - str := make([]string, len(s.Hint)) - for i, e := range s.Hint { - x := e.To4() - if x == nil { - return "" - } - str[i] = x.String() - } - return strings.Join(str, ",") -} - -func (s *SVCBIPv4Hint) parse(b string) error { - if b == "" { - return errors.New("dns: svcbipv4hint: empty hint") - } - if strings.Contains(b, ":") { - return errors.New("dns: svcbipv4hint: expected ipv4, got ipv6") - } - - hint := make([]net.IP, 0, strings.Count(b, ",")+1) - for len(b) > 0 { - var e string - e, b, _ = strings.Cut(b, ",") - ip := net.ParseIP(e).To4() - if ip == nil { - return errors.New("dns: svcbipv4hint: bad ip") - } - hint = append(hint, ip) - } - s.Hint = hint - return nil -} - -func (s *SVCBIPv4Hint) copy() SVCBKeyValue { - hint := make([]net.IP, len(s.Hint)) - for i, ip := range s.Hint { - hint[i] = cloneSlice(ip) - } - return &SVCBIPv4Hint{Hint: hint} -} - -// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx]. -// Basic use pattern for creating an ech option: -// -// h := new(dns.HTTPS) -// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} -// e := new(dns.SVCBECHConfig) -// e.ECH = []byte{0xfe, 0x08, ...} -// h.Value = append(h.Value, e) -type SVCBECHConfig struct { - ECH []byte // Specifically ECHConfigList including the redundant length prefix -} - -func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG } -func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) } -func (s *SVCBECHConfig) len() int { return len(s.ECH) } - -func (s *SVCBECHConfig) pack() ([]byte, error) { - return cloneSlice(s.ECH), nil -} - -func (s *SVCBECHConfig) copy() SVCBKeyValue { - return &SVCBECHConfig{cloneSlice(s.ECH)} -} - -func (s *SVCBECHConfig) unpack(b []byte) error { - s.ECH = cloneSlice(b) - return nil -} - -func (s *SVCBECHConfig) parse(b string) error { - x, err := fromBase64([]byte(b)) - if err != nil { - return errors.New("dns: svcbech: bad base64 ech") - } - s.ECH = x - return nil -} - -// SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections -// if A and AAAA record responses for SVCB's Target domain haven't been received. -// In that case, optionally, A and AAAA requests can be made, after which the -// connection to the hinted IP address may be terminated and a new connection may be opened. -// Basic use pattern for creating an ipv6hint option: -// -// h := new(dns.HTTPS) -// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} -// e := new(dns.SVCBIPv6Hint) -// e.Hint = []net.IP{net.ParseIP("2001:db8::1")} -// h.Value = append(h.Value, e) -type SVCBIPv6Hint struct { - Hint []net.IP -} - -func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT } -func (s *SVCBIPv6Hint) len() int { return 16 * len(s.Hint) } - -func (s *SVCBIPv6Hint) pack() ([]byte, error) { - b := make([]byte, 0, 16*len(s.Hint)) - for _, e := range s.Hint { - if len(e) != net.IPv6len || e.To4() != nil { - return nil, errors.New("dns: svcbipv6hint: expected ipv6, hint is ipv4") - } - b = append(b, e...) - } - return b, nil -} - -func (s *SVCBIPv6Hint) unpack(b []byte) error { - if len(b) == 0 || len(b)%16 != 0 { - return errors.New("dns: svcbipv6hint: ipv6 address byte array length not a multiple of 16") - } - b = cloneSlice(b) - x := make([]net.IP, 0, len(b)/16) - for i := 0; i < len(b); i += 16 { - ip := net.IP(b[i : i+16]) - if ip.To4() != nil { - return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4") - } - x = append(x, ip) - } - s.Hint = x - return nil -} - -func (s *SVCBIPv6Hint) String() string { - str := make([]string, len(s.Hint)) - for i, e := range s.Hint { - if x := e.To4(); x != nil { - return "" - } - str[i] = e.String() - } - return strings.Join(str, ",") -} - -func (s *SVCBIPv6Hint) parse(b string) error { - if b == "" { - return errors.New("dns: svcbipv6hint: empty hint") - } - - hint := make([]net.IP, 0, strings.Count(b, ",")+1) - for len(b) > 0 { - var e string - e, b, _ = strings.Cut(b, ",") - ip := net.ParseIP(e) - if ip == nil { - return errors.New("dns: svcbipv6hint: bad ip") - } - if ip.To4() != nil { - return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4-mapped-ipv6") - } - hint = append(hint, ip) - } - s.Hint = hint - return nil -} - -func (s *SVCBIPv6Hint) copy() SVCBKeyValue { - hint := make([]net.IP, len(s.Hint)) - for i, ip := range s.Hint { - hint[i] = cloneSlice(ip) - } - return &SVCBIPv6Hint{Hint: hint} -} - -// SVCBDoHPath pair is used to indicate the URI template that the -// clients may use to construct a DNS over HTTPS URI. -// -// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02) -// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06). -// -// A basic example of using the dohpath option together with the alpn -// option to indicate support for DNS over HTTPS on a certain path: -// -// s := new(dns.SVCB) -// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET} -// e := new(dns.SVCBAlpn) -// e.Alpn = []string{"h2", "h3"} -// p := new(dns.SVCBDoHPath) -// p.Template = "/dns-query{?dns}" -// s.Value = append(s.Value, e, p) -// -// The parsing currently doesn't validate that Template is a valid -// RFC 6570 URI template. -type SVCBDoHPath struct { - Template string -} - -func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH } -func (s *SVCBDoHPath) String() string { return svcbParamToStr([]byte(s.Template)) } -func (s *SVCBDoHPath) len() int { return len(s.Template) } -func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Template), nil } - -func (s *SVCBDoHPath) unpack(b []byte) error { - s.Template = string(b) - return nil -} - -func (s *SVCBDoHPath) parse(b string) error { - template, err := svcbParseParam(b) - if err != nil { - return fmt.Errorf("dns: svcbdohpath: %w", err) - } - s.Template = string(template) - return nil -} - -func (s *SVCBDoHPath) copy() SVCBKeyValue { - return &SVCBDoHPath{ - Template: s.Template, - } -} - -// SVCBLocal pair is intended for experimental/private use. The key is recommended -// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER]. -// Basic use pattern for creating a keyNNNNN option: -// -// h := new(dns.HTTPS) -// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET} -// e := new(dns.SVCBLocal) -// e.KeyCode = 65400 -// e.Data = []byte("abc") -// h.Value = append(h.Value, e) -type SVCBLocal struct { - KeyCode SVCBKey // Never 65535 or any assigned keys. - Data []byte // All byte sequences are allowed. -} - -func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode } -func (s *SVCBLocal) String() string { return svcbParamToStr(s.Data) } -func (s *SVCBLocal) pack() ([]byte, error) { return cloneSlice(s.Data), nil } -func (s *SVCBLocal) len() int { return len(s.Data) } - -func (s *SVCBLocal) unpack(b []byte) error { - s.Data = cloneSlice(b) - return nil -} - -func (s *SVCBLocal) parse(b string) error { - data, err := svcbParseParam(b) - if err != nil { - return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err) - } - s.Data = data - return nil -} - -func (s *SVCBLocal) copy() SVCBKeyValue { - return &SVCBLocal{s.KeyCode, cloneSlice(s.Data)} -} - -func (rr *SVCB) String() string { - s := rr.Hdr.String() + - strconv.Itoa(int(rr.Priority)) + " " + - sprintName(rr.Target) - for _, e := range rr.Value { - s += " " + e.Key().String() + "=\"" + e.String() + "\"" - } - return s -} - -// areSVCBPairArraysEqual checks if SVCBKeyValue arrays are equal after sorting their -// copies. arrA and arrB have equal lengths, otherwise zduplicate.go wouldn't call this function. -func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool { - a = cloneSlice(a) - b = cloneSlice(b) - sort.Slice(a, func(i, j int) bool { return a[i].Key() < a[j].Key() }) - sort.Slice(b, func(i, j int) bool { return b[i].Key() < b[j].Key() }) - for i, e := range a { - if e.Key() != b[i].Key() { - return false - } - b1, err1 := e.pack() - b2, err2 := b[i].pack() - if err1 != nil || err2 != nil || !bytes.Equal(b1, b2) { - return false - } - } - return true -} - -// svcbParamStr converts the value of an SVCB parameter into a DNS presentation-format string. -func svcbParamToStr(s []byte) string { - var str strings.Builder - str.Grow(4 * len(s)) - for _, e := range s { - if ' ' <= e && e <= '~' { - switch e { - case '"', ';', ' ', '\\': - str.WriteByte('\\') - str.WriteByte(e) - default: - str.WriteByte(e) - } - } else { - str.WriteString(escapeByte(e)) - } - } - return str.String() -} - -// svcbParseParam parses a DNS presentation-format string into an SVCB parameter value. -func svcbParseParam(b string) ([]byte, error) { - data := make([]byte, 0, len(b)) - for i := 0; i < len(b); { - if b[i] != '\\' { - data = append(data, b[i]) - i++ - continue - } - if i+1 == len(b) { - return nil, errors.New("escape unterminated") - } - if isDigit(b[i+1]) { - if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) { - a, err := strconv.ParseUint(b[i+1:i+4], 10, 8) - if err == nil { - i += 4 - data = append(data, byte(a)) - continue - } - } - return nil, errors.New("bad escaped octet") - } else { - data = append(data, b[i+1]) - i += 2 - } - } - return data, nil -} diff --git a/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/miekg/dns/tlsa.go deleted file mode 100644 index 4e07983..0000000 --- a/vendor/github.com/miekg/dns/tlsa.go +++ /dev/null @@ -1,44 +0,0 @@ -package dns - -import ( - "crypto/x509" - "net" - "strconv" -) - -// Sign creates a TLSA record from an SSL certificate. -func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { - r.Hdr.Rrtype = TypeTLSA - r.Usage = uint8(usage) - r.Selector = uint8(selector) - r.MatchingType = uint8(matchingType) - - r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) - return err -} - -// Verify verifies a TLSA record against an SSL certificate. If it is OK -// a nil error is returned. -func (r *TLSA) Verify(cert *x509.Certificate) error { - c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err // Not also ErrSig? - } - if r.Certificate == c { - return nil - } - return ErrSig // ErrSig, really? -} - -// TLSAName returns the ownername of a TLSA resource record as per the -// rules specified in RFC 6698, Section 3. -func TLSAName(name, service, network string) (string, error) { - if !IsFqdn(name) { - return "", ErrFqdn - } - p, err := net.LookupPort(network, service) - if err != nil { - return "", err - } - return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil -} diff --git a/vendor/github.com/miekg/dns/tools.go b/vendor/github.com/miekg/dns/tools.go deleted file mode 100644 index ccf8f6b..0000000 --- a/vendor/github.com/miekg/dns/tools.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build tools -// +build tools - -// We include our tool dependencies for `go generate` here to ensure they're -// properly tracked by the go tool. See the Go Wiki for the rationale behind this: -// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module. - -package dns - -import _ "golang.org/x/tools/go/packages" diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go deleted file mode 100644 index debfe2d..0000000 --- a/vendor/github.com/miekg/dns/tsig.go +++ /dev/null @@ -1,456 +0,0 @@ -package dns - -import ( - "crypto/hmac" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "encoding/binary" - "encoding/hex" - "hash" - "strconv" - "strings" - "time" -) - -// HMAC hashing codes. These are transmitted as domain names. -const ( - HmacSHA1 = "hmac-sha1." - HmacSHA224 = "hmac-sha224." - HmacSHA256 = "hmac-sha256." - HmacSHA384 = "hmac-sha384." - HmacSHA512 = "hmac-sha512." - - HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported. -) - -// TsigProvider provides the API to plug-in a custom TSIG implementation. -type TsigProvider interface { - // Generate is passed the DNS message to be signed and the partial TSIG RR. It returns the signature and nil, otherwise an error. - Generate(msg []byte, t *TSIG) ([]byte, error) - // Verify is passed the DNS message to be verified and the TSIG RR. If the signature is valid it will return nil, otherwise an error. - Verify(msg []byte, t *TSIG) error -} - -type tsigHMACProvider string - -func (key tsigHMACProvider) Generate(msg []byte, t *TSIG) ([]byte, error) { - // If we barf here, the caller is to blame - rawsecret, err := fromBase64([]byte(key)) - if err != nil { - return nil, err - } - var h hash.Hash - switch CanonicalName(t.Algorithm) { - case HmacSHA1: - h = hmac.New(sha1.New, rawsecret) - case HmacSHA224: - h = hmac.New(sha256.New224, rawsecret) - case HmacSHA256: - h = hmac.New(sha256.New, rawsecret) - case HmacSHA384: - h = hmac.New(sha512.New384, rawsecret) - case HmacSHA512: - h = hmac.New(sha512.New, rawsecret) - default: - return nil, ErrKeyAlg - } - h.Write(msg) - return h.Sum(nil), nil -} - -func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error { - b, err := key.Generate(msg, t) - if err != nil { - return err - } - mac, err := hex.DecodeString(t.MAC) - if err != nil { - return err - } - if !hmac.Equal(b, mac) { - return ErrSig - } - return nil -} - -type tsigSecretProvider map[string]string - -func (ts tsigSecretProvider) Generate(msg []byte, t *TSIG) ([]byte, error) { - key, ok := ts[t.Hdr.Name] - if !ok { - return nil, ErrSecret - } - return tsigHMACProvider(key).Generate(msg, t) -} - -func (ts tsigSecretProvider) Verify(msg []byte, t *TSIG) error { - key, ok := ts[t.Hdr.Name] - if !ok { - return ErrSecret - } - return tsigHMACProvider(key).Verify(msg, t) -} - -// TSIG is the RR the holds the transaction signature of a message. -// See RFC 2845 and RFC 4635. -type TSIG struct { - Hdr RR_Header - Algorithm string `dns:"domain-name"` - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 - MACSize uint16 - MAC string `dns:"size-hex:MACSize"` - OrigId uint16 - Error uint16 - OtherLen uint16 - OtherData string `dns:"size-hex:OtherLen"` -} - -// TSIG has no official presentation format, but this will suffice. - -func (rr *TSIG) String() string { - s := "\n;; TSIG PSEUDOSECTION:\n; " // add another semi-colon to signify TSIG does not have a presentation format - s += rr.Hdr.String() + - " " + rr.Algorithm + - " " + tsigTimeToString(rr.TimeSigned) + - " " + strconv.Itoa(int(rr.Fudge)) + - " " + strconv.Itoa(int(rr.MACSize)) + - " " + strings.ToUpper(rr.MAC) + - " " + strconv.Itoa(int(rr.OrigId)) + - " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR - " " + strconv.Itoa(int(rr.OtherLen)) + - " " + rr.OtherData - return s -} - -func (*TSIG) parse(c *zlexer, origin string) *ParseError { - return &ParseError{err: "TSIG records do not have a presentation format"} -} - -// The following values must be put in wireformat, so that the MAC can be calculated. -// RFC 2845, section 3.4.2. TSIG Variables. -type tsigWireFmt struct { - // From RR_Header - Name string `dns:"domain-name"` - Class uint16 - Ttl uint32 - // Rdata of the TSIG - Algorithm string `dns:"domain-name"` - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 - // MACSize, MAC and OrigId excluded - Error uint16 - OtherLen uint16 - OtherData string `dns:"size-hex:OtherLen"` -} - -// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC -type macWireFmt struct { - MACSize uint16 - MAC string `dns:"size-hex:MACSize"` -} - -// 3.3. Time values used in TSIG calculations -type timerWireFmt struct { - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 -} - -// TsigGenerate fills out the TSIG record attached to the message. -// The message should contain a "stub" TSIG RR with the algorithm, key name -// (owner name of the RR), time fudge (defaults to 300 seconds) and the current -// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for -// the first time requestMAC should be set to the empty string and timersOnly to -// false. -func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { - return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly) -} - -// TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider. -func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) { - if m.IsTsig() == nil { - panic("dns: TSIG not last RR in additional") - } - - rr := m.Extra[len(m.Extra)-1].(*TSIG) - m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg - mbuf, err := m.Pack() - if err != nil { - return nil, "", err - } - - buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly) - if err != nil { - return nil, "", err - } - - t := new(TSIG) - // Copy all TSIG fields except MAC, its size, and time signed which are filled when signing. - *t = *rr - t.TimeSigned = 0 - t.MAC = "" - t.MACSize = 0 - - // Sign unless there is a key or MAC validation error (RFC 8945 5.3.2) - if rr.Error != RcodeBadKey && rr.Error != RcodeBadSig { - mac, err := provider.Generate(buf, rr) - if err != nil { - return nil, "", err - } - t.TimeSigned = rr.TimeSigned - t.MAC = hex.EncodeToString(mac) - t.MACSize = uint16(len(t.MAC) / 2) // Size is half! - } - - tbuf := make([]byte, Len(t)) - off, err := PackRR(t, tbuf, 0, nil, false) - if err != nil { - return nil, "", err - } - mbuf = append(mbuf, tbuf[:off]...) - // Update the ArCount directly in the buffer. - binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1)) - - return mbuf, t.MAC, nil -} - -// TsigVerify verifies the TSIG on a message. If the signature does not -// validate the returned error contains the cause. If the signature is OK, the -// error is nil. -func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error { - return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix())) -} - -// TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider. -func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error { - return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix())) -} - -// actual implementation of TsigVerify, taking the current time ('now') as a parameter for the convenience of tests. -func tsigVerify(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool, now uint64) error { - // Strip the TSIG from the incoming msg - stripped, tsig, err := stripTsig(msg) - if err != nil { - return err - } - - buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly) - if err != nil { - return err - } - - if err := provider.Verify(buf, tsig); err != nil { - return err - } - - // Fudge factor works both ways. A message can arrive before it was signed because - // of clock skew. - // We check this after verifying the signature, following draft-ietf-dnsop-rfc2845bis - // instead of RFC2845, in order to prevent a security vulnerability as reported in CVE-2017-3142/3143. - ti := now - tsig.TimeSigned - if now < tsig.TimeSigned { - ti = tsig.TimeSigned - now - } - if uint64(tsig.Fudge) < ti { - return ErrTime - } - - return nil -} - -// Create a wiredata buffer for the MAC calculation. -func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) ([]byte, error) { - var buf []byte - if rr.TimeSigned == 0 { - rr.TimeSigned = uint64(time.Now().Unix()) - } - if rr.Fudge == 0 { - rr.Fudge = 300 // Standard (RFC) default. - } - - // Replace message ID in header with original ID from TSIG - binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId) - - if requestMAC != "" { - m := new(macWireFmt) - m.MACSize = uint16(len(requestMAC) / 2) - m.MAC = requestMAC - buf = make([]byte, len(requestMAC)) // long enough - n, err := packMacWire(m, buf) - if err != nil { - return nil, err - } - buf = buf[:n] - } - - tsigvar := make([]byte, DefaultMsgSize) - if timersOnly { - tsig := new(timerWireFmt) - tsig.TimeSigned = rr.TimeSigned - tsig.Fudge = rr.Fudge - n, err := packTimerWire(tsig, tsigvar) - if err != nil { - return nil, err - } - tsigvar = tsigvar[:n] - } else { - tsig := new(tsigWireFmt) - tsig.Name = CanonicalName(rr.Hdr.Name) - tsig.Class = ClassANY - tsig.Ttl = rr.Hdr.Ttl - tsig.Algorithm = CanonicalName(rr.Algorithm) - tsig.TimeSigned = rr.TimeSigned - tsig.Fudge = rr.Fudge - tsig.Error = rr.Error - tsig.OtherLen = rr.OtherLen - tsig.OtherData = rr.OtherData - n, err := packTsigWire(tsig, tsigvar) - if err != nil { - return nil, err - } - tsigvar = tsigvar[:n] - } - - if requestMAC != "" { - x := append(buf, msgbuf...) - buf = append(x, tsigvar...) - } else { - buf = append(msgbuf, tsigvar...) - } - return buf, nil -} - -// Strip the TSIG from the raw message. -func stripTsig(msg []byte) ([]byte, *TSIG, error) { - // Copied from msg.go's Unpack() Header, but modified. - var ( - dh Header - err error - ) - off, tsigoff := 0, 0 - - if dh, off, err = unpackMsgHdr(msg, off); err != nil { - return nil, nil, err - } - if dh.Arcount == 0 { - return nil, nil, ErrNoSig - } - - // Rcode, see msg.go Unpack() - if int(dh.Bits&0xF) == RcodeNotAuth { - return nil, nil, ErrAuth - } - - for i := 0; i < int(dh.Qdcount); i++ { - _, off, err = unpackQuestion(msg, off) - if err != nil { - return nil, nil, err - } - } - - _, off, err = unpackRRslice(int(dh.Ancount), msg, off) - if err != nil { - return nil, nil, err - } - _, off, err = unpackRRslice(int(dh.Nscount), msg, off) - if err != nil { - return nil, nil, err - } - - rr := new(TSIG) - var extra RR - for i := 0; i < int(dh.Arcount); i++ { - tsigoff = off - extra, off, err = UnpackRR(msg, off) - if err != nil { - return nil, nil, err - } - if extra.Header().Rrtype == TypeTSIG { - rr = extra.(*TSIG) - // Adjust Arcount. - arcount := binary.BigEndian.Uint16(msg[10:]) - binary.BigEndian.PutUint16(msg[10:], arcount-1) - break - } - } - if rr == nil { - return nil, nil, ErrNoSig - } - return msg[:tsigoff], rr, nil -} - -// Translate the TSIG time signed into a date. There is no -// need for RFC1982 calculations as this date is 48 bits. -func tsigTimeToString(t uint64) string { - ti := time.Unix(int64(t), 0).UTC() - return ti.Format("20060102150405") -} - -func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) { - // copied from zmsg.go TSIG packing - // RR_Header - off, err := PackDomainName(tw.Name, msg, 0, nil, false) - if err != nil { - return off, err - } - off, err = packUint16(tw.Class, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(tw.Ttl, msg, off) - if err != nil { - return off, err - } - - off, err = PackDomainName(tw.Algorithm, msg, off, nil, false) - if err != nil { - return off, err - } - off, err = packUint48(tw.TimeSigned, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(tw.Fudge, msg, off) - if err != nil { - return off, err - } - - off, err = packUint16(tw.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(tw.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(tw.OtherData, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func packMacWire(mw *macWireFmt, msg []byte) (int, error) { - off, err := packUint16(mw.MACSize, msg, 0) - if err != nil { - return off, err - } - off, err = packStringHex(mw.MAC, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) { - off, err := packUint48(tw.TimeSigned, msg, 0) - if err != nil { - return off, err - } - off, err = packUint16(tw.Fudge, msg, off) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go deleted file mode 100644 index 8e3129c..0000000 --- a/vendor/github.com/miekg/dns/types.go +++ /dev/null @@ -1,1664 +0,0 @@ -package dns - -import ( - "bytes" - "fmt" - "net" - "strconv" - "strings" - "time" -) - -type ( - // Type is a DNS type. - Type uint16 - // Class is a DNS class. - Class uint16 - // Name is a DNS domain name. - Name string -) - -// Packet formats - -// Wire constants and supported types. -const ( - // valid RR_Header.Rrtype and Question.qtype - - TypeNone uint16 = 0 - TypeA uint16 = 1 - TypeNS uint16 = 2 - TypeMD uint16 = 3 - TypeMF uint16 = 4 - TypeCNAME uint16 = 5 - TypeSOA uint16 = 6 - TypeMB uint16 = 7 - TypeMG uint16 = 8 - TypeMR uint16 = 9 - TypeNULL uint16 = 10 - TypePTR uint16 = 12 - TypeHINFO uint16 = 13 - TypeMINFO uint16 = 14 - TypeMX uint16 = 15 - TypeTXT uint16 = 16 - TypeRP uint16 = 17 - TypeAFSDB uint16 = 18 - TypeX25 uint16 = 19 - TypeISDN uint16 = 20 - TypeRT uint16 = 21 - TypeNSAPPTR uint16 = 23 - TypeSIG uint16 = 24 - TypeKEY uint16 = 25 - TypePX uint16 = 26 - TypeGPOS uint16 = 27 - TypeAAAA uint16 = 28 - TypeLOC uint16 = 29 - TypeNXT uint16 = 30 - TypeEID uint16 = 31 - TypeNIMLOC uint16 = 32 - TypeSRV uint16 = 33 - TypeATMA uint16 = 34 - TypeNAPTR uint16 = 35 - TypeKX uint16 = 36 - TypeCERT uint16 = 37 - TypeDNAME uint16 = 39 - TypeOPT uint16 = 41 // EDNS - TypeAPL uint16 = 42 - TypeDS uint16 = 43 - TypeSSHFP uint16 = 44 - TypeIPSECKEY uint16 = 45 - TypeRRSIG uint16 = 46 - TypeNSEC uint16 = 47 - TypeDNSKEY uint16 = 48 - TypeDHCID uint16 = 49 - TypeNSEC3 uint16 = 50 - TypeNSEC3PARAM uint16 = 51 - TypeTLSA uint16 = 52 - TypeSMIMEA uint16 = 53 - TypeHIP uint16 = 55 - TypeNINFO uint16 = 56 - TypeRKEY uint16 = 57 - TypeTALINK uint16 = 58 - TypeCDS uint16 = 59 - TypeCDNSKEY uint16 = 60 - TypeOPENPGPKEY uint16 = 61 - TypeCSYNC uint16 = 62 - TypeZONEMD uint16 = 63 - TypeSVCB uint16 = 64 - TypeHTTPS uint16 = 65 - TypeSPF uint16 = 99 - TypeUINFO uint16 = 100 - TypeUID uint16 = 101 - TypeGID uint16 = 102 - TypeUNSPEC uint16 = 103 - TypeNID uint16 = 104 - TypeL32 uint16 = 105 - TypeL64 uint16 = 106 - TypeLP uint16 = 107 - TypeEUI48 uint16 = 108 - TypeEUI64 uint16 = 109 - TypeURI uint16 = 256 - TypeCAA uint16 = 257 - TypeAVC uint16 = 258 - TypeAMTRELAY uint16 = 260 - - TypeTKEY uint16 = 249 - TypeTSIG uint16 = 250 - - // valid Question.Qtype only - TypeIXFR uint16 = 251 - TypeAXFR uint16 = 252 - TypeMAILB uint16 = 253 - TypeMAILA uint16 = 254 - TypeANY uint16 = 255 - - TypeTA uint16 = 32768 - TypeDLV uint16 = 32769 - TypeReserved uint16 = 65535 - - // valid Question.Qclass - ClassINET = 1 - ClassCSNET = 2 - ClassCHAOS = 3 - ClassHESIOD = 4 - ClassNONE = 254 - ClassANY = 255 - - // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml - RcodeSuccess = 0 // NoError - No Error [DNS] - RcodeFormatError = 1 // FormErr - Format Error [DNS] - RcodeServerFailure = 2 // ServFail - Server Failure [DNS] - RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS] - RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS] - RcodeRefused = 5 // Refused - Query Refused [DNS] - RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update] - RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update] - RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update] - RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update] - RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG] - RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG] https://www.rfc-editor.org/rfc/rfc6895.html#section-2.3 - RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0] https://www.rfc-editor.org/rfc/rfc6895.html#section-2.3 - RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG] - RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG] - RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY] - RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY] - RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY] - RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG] - RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies] - - // Message Opcodes. There is no 3. - OpcodeQuery = 0 - OpcodeIQuery = 1 - OpcodeStatus = 2 - OpcodeNotify = 4 - OpcodeUpdate = 5 -) - -// Used in ZONEMD https://tools.ietf.org/html/rfc8976 -const ( - ZoneMDSchemeSimple = 1 - - ZoneMDHashAlgSHA384 = 1 - ZoneMDHashAlgSHA512 = 2 -) - -// Used in IPSEC https://datatracker.ietf.org/doc/html/rfc4025#section-2.3 -const ( - IPSECGatewayNone uint8 = iota - IPSECGatewayIPv4 - IPSECGatewayIPv6 - IPSECGatewayHost -) - -// Used in AMTRELAY https://datatracker.ietf.org/doc/html/rfc8777#section-4.2.3 -const ( - AMTRELAYNone = IPSECGatewayNone - AMTRELAYIPv4 = IPSECGatewayIPv4 - AMTRELAYIPv6 = IPSECGatewayIPv6 - AMTRELAYHost = IPSECGatewayHost -) - -// Header is the wire format for the DNS packet header. -type Header struct { - Id uint16 - Bits uint16 - Qdcount, Ancount, Nscount, Arcount uint16 -} - -const ( - headerSize = 12 - - // Header.Bits - _QR = 1 << 15 // query/response (response=1) - _AA = 1 << 10 // authoritative - _TC = 1 << 9 // truncated - _RD = 1 << 8 // recursion desired - _RA = 1 << 7 // recursion available - _Z = 1 << 6 // Z - _AD = 1 << 5 // authenticated data - _CD = 1 << 4 // checking disabled -) - -// Various constants used in the LOC RR. See RFC 1876. -const ( - LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2. - LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2. - LOC_HOURS = 60 * 1000 - LOC_DEGREES = 60 * LOC_HOURS - LOC_ALTITUDEBASE = 100000 -) - -// Different Certificate Types, see RFC 4398, Section 2.1 -const ( - CertPKIX = 1 + iota - CertSPKI - CertPGP - CertIPIX - CertISPKI - CertIPGP - CertACPKIX - CertIACPKIX - CertURI = 253 - CertOID = 254 -) - -// CertTypeToString converts the Cert Type to its string representation. -// See RFC 4398 and RFC 6944. -var CertTypeToString = map[uint16]string{ - CertPKIX: "PKIX", - CertSPKI: "SPKI", - CertPGP: "PGP", - CertIPIX: "IPIX", - CertISPKI: "ISPKI", - CertIPGP: "IPGP", - CertACPKIX: "ACPKIX", - CertIACPKIX: "IACPKIX", - CertURI: "URI", - CertOID: "OID", -} - -// Prefix for IPv4 encoded as IPv6 address -const ipv4InIPv6Prefix = "::ffff:" - -//go:generate go run types_generate.go - -// Question holds a DNS question. Usually there is just one. While the -// original DNS RFCs allow multiple questions in the question section of a -// message, in practice it never works. Because most DNS servers see multiple -// questions as an error, it is recommended to only have one question per -// message. -type Question struct { - Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed) - Qtype uint16 - Qclass uint16 -} - -func (q *Question) len(off int, compression map[string]struct{}) int { - l := domainNameLen(q.Name, off, compression, true) - l += 2 + 2 - return l -} - -func (q *Question) String() (s string) { - // prefix with ; (as in dig) - s = ";" + sprintName(q.Name) + "\t" - s += Class(q.Qclass).String() + "\t" - s += " " + Type(q.Qtype).String() - return s -} - -// ANY is a wild card record. See RFC 1035, Section 3.2.3. ANY -// is named "*" there. -type ANY struct { - Hdr RR_Header - // Does not have any rdata -} - -func (rr *ANY) String() string { return rr.Hdr.String() } - -func (*ANY) parse(c *zlexer, origin string) *ParseError { - return &ParseError{err: "ANY records do not have a presentation format"} -} - -// NULL RR. See RFC 1035. -type NULL struct { - Hdr RR_Header - Data string `dns:"any"` -} - -func (rr *NULL) String() string { - // There is no presentation format; prefix string with a comment. - return ";" + rr.Hdr.String() + rr.Data -} - -func (*NULL) parse(c *zlexer, origin string) *ParseError { - return &ParseError{err: "NULL records do not have a presentation format"} -} - -// CNAME RR. See RFC 1034. -type CNAME struct { - Hdr RR_Header - Target string `dns:"cdomain-name"` -} - -func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) } - -// HINFO RR. See RFC 1034. -type HINFO struct { - Hdr RR_Header - Cpu string - Os string -} - -func (rr *HINFO) String() string { - return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os}) -} - -// MB RR. See RFC 1035. -type MB struct { - Hdr RR_Header - Mb string `dns:"cdomain-name"` -} - -func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) } - -// MG RR. See RFC 1035. -type MG struct { - Hdr RR_Header - Mg string `dns:"cdomain-name"` -} - -func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) } - -// MINFO RR. See RFC 1035. -type MINFO struct { - Hdr RR_Header - Rmail string `dns:"cdomain-name"` - Email string `dns:"cdomain-name"` -} - -func (rr *MINFO) String() string { - return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email) -} - -// MR RR. See RFC 1035. -type MR struct { - Hdr RR_Header - Mr string `dns:"cdomain-name"` -} - -func (rr *MR) String() string { - return rr.Hdr.String() + sprintName(rr.Mr) -} - -// MF RR. See RFC 1035. -type MF struct { - Hdr RR_Header - Mf string `dns:"cdomain-name"` -} - -func (rr *MF) String() string { - return rr.Hdr.String() + sprintName(rr.Mf) -} - -// MD RR. See RFC 1035. -type MD struct { - Hdr RR_Header - Md string `dns:"cdomain-name"` -} - -func (rr *MD) String() string { - return rr.Hdr.String() + sprintName(rr.Md) -} - -// MX RR. See RFC 1035. -type MX struct { - Hdr RR_Header - Preference uint16 - Mx string `dns:"cdomain-name"` -} - -func (rr *MX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx) -} - -// AFSDB RR. See RFC 1183. -type AFSDB struct { - Hdr RR_Header - Subtype uint16 - Hostname string `dns:"domain-name"` -} - -func (rr *AFSDB) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname) -} - -// X25 RR. See RFC 1183, Section 3.1. -type X25 struct { - Hdr RR_Header - PSDNAddress string -} - -func (rr *X25) String() string { - return rr.Hdr.String() + rr.PSDNAddress -} - -// ISDN RR. See RFC 1183, Section 3.2. -type ISDN struct { - Hdr RR_Header - Address string - SubAddress string -} - -func (rr *ISDN) String() string { - return rr.Hdr.String() + sprintTxt([]string{rr.Address, rr.SubAddress}) -} - -// RT RR. See RFC 1183, Section 3.3. -type RT struct { - Hdr RR_Header - Preference uint16 - Host string `dns:"domain-name"` // RFC 3597 prohibits compressing records not defined in RFC 1035. -} - -func (rr *RT) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host) -} - -// NS RR. See RFC 1035. -type NS struct { - Hdr RR_Header - Ns string `dns:"cdomain-name"` -} - -func (rr *NS) String() string { - return rr.Hdr.String() + sprintName(rr.Ns) -} - -// PTR RR. See RFC 1035. -type PTR struct { - Hdr RR_Header - Ptr string `dns:"cdomain-name"` -} - -func (rr *PTR) String() string { - return rr.Hdr.String() + sprintName(rr.Ptr) -} - -// RP RR. See RFC 1138, Section 2.2. -type RP struct { - Hdr RR_Header - Mbox string `dns:"domain-name"` - Txt string `dns:"domain-name"` -} - -func (rr *RP) String() string { - return rr.Hdr.String() + sprintName(rr.Mbox) + " " + sprintName(rr.Txt) -} - -// SOA RR. See RFC 1035. -type SOA struct { - Hdr RR_Header - Ns string `dns:"cdomain-name"` - Mbox string `dns:"cdomain-name"` - Serial uint32 - Refresh uint32 - Retry uint32 - Expire uint32 - Minttl uint32 -} - -func (rr *SOA) String() string { - return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) + - " " + strconv.FormatInt(int64(rr.Serial), 10) + - " " + strconv.FormatInt(int64(rr.Refresh), 10) + - " " + strconv.FormatInt(int64(rr.Retry), 10) + - " " + strconv.FormatInt(int64(rr.Expire), 10) + - " " + strconv.FormatInt(int64(rr.Minttl), 10) -} - -// TXT RR. See RFC 1035. -type TXT struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -func sprintName(s string) string { - var dst strings.Builder - - for i := 0; i < len(s); { - if s[i] == '.' { - if dst.Len() != 0 { - dst.WriteByte('.') - } - i++ - continue - } - - b, n := nextByte(s, i) - if n == 0 { - // Drop "dangling" incomplete escapes. - if dst.Len() == 0 { - return s[:i] - } - break - } - if isDomainNameLabelSpecial(b) { - if dst.Len() == 0 { - dst.Grow(len(s) * 2) - dst.WriteString(s[:i]) - } - dst.WriteByte('\\') - dst.WriteByte(b) - } else if b < ' ' || b > '~' { // unprintable, use \DDD - if dst.Len() == 0 { - dst.Grow(len(s) * 2) - dst.WriteString(s[:i]) - } - dst.WriteString(escapeByte(b)) - } else { - if dst.Len() != 0 { - dst.WriteByte(b) - } - } - i += n - } - if dst.Len() == 0 { - return s - } - return dst.String() -} - -func sprintTxtOctet(s string) string { - var dst strings.Builder - dst.Grow(2 + len(s)) - dst.WriteByte('"') - for i := 0; i < len(s); { - if i+1 < len(s) && s[i] == '\\' && s[i+1] == '.' { - dst.WriteString(s[i : i+2]) - i += 2 - continue - } - - b, n := nextByte(s, i) - if n == 0 { - i++ // dangling back slash - } else { - writeTXTStringByte(&dst, b) - } - i += n - } - dst.WriteByte('"') - return dst.String() -} - -func sprintTxt(txt []string) string { - var out strings.Builder - for i, s := range txt { - out.Grow(3 + len(s)) - if i > 0 { - out.WriteString(` "`) - } else { - out.WriteByte('"') - } - for j := 0; j < len(s); { - b, n := nextByte(s, j) - if n == 0 { - break - } - writeTXTStringByte(&out, b) - j += n - } - out.WriteByte('"') - } - return out.String() -} - -func writeTXTStringByte(s *strings.Builder, b byte) { - switch { - case b == '"' || b == '\\': - s.WriteByte('\\') - s.WriteByte(b) - case b < ' ' || b > '~': - s.WriteString(escapeByte(b)) - default: - s.WriteByte(b) - } -} - -const ( - escapedByteSmall = "" + - `\000\001\002\003\004\005\006\007\008\009` + - `\010\011\012\013\014\015\016\017\018\019` + - `\020\021\022\023\024\025\026\027\028\029` + - `\030\031` - escapedByteLarge = `\127\128\129` + - `\130\131\132\133\134\135\136\137\138\139` + - `\140\141\142\143\144\145\146\147\148\149` + - `\150\151\152\153\154\155\156\157\158\159` + - `\160\161\162\163\164\165\166\167\168\169` + - `\170\171\172\173\174\175\176\177\178\179` + - `\180\181\182\183\184\185\186\187\188\189` + - `\190\191\192\193\194\195\196\197\198\199` + - `\200\201\202\203\204\205\206\207\208\209` + - `\210\211\212\213\214\215\216\217\218\219` + - `\220\221\222\223\224\225\226\227\228\229` + - `\230\231\232\233\234\235\236\237\238\239` + - `\240\241\242\243\244\245\246\247\248\249` + - `\250\251\252\253\254\255` -) - -// escapeByte returns the \DDD escaping of b which must -// satisfy b < ' ' || b > '~'. -func escapeByte(b byte) string { - if b < ' ' { - return escapedByteSmall[b*4 : b*4+4] - } - - b -= '~' + 1 - // The cast here is needed as b*4 may overflow byte. - return escapedByteLarge[int(b)*4 : int(b)*4+4] -} - -// isDomainNameLabelSpecial returns true if -// a domain name label byte should be prefixed -// with an escaping backslash. -func isDomainNameLabelSpecial(b byte) bool { - switch b { - case '.', ' ', '\'', '@', ';', '(', ')', '"', '\\': - return true - } - return false -} - -func nextByte(s string, offset int) (byte, int) { - if offset >= len(s) { - return 0, 0 - } - if s[offset] != '\\' { - // not an escape sequence - return s[offset], 1 - } - switch len(s) - offset { - case 1: // dangling escape - return 0, 0 - case 2, 3: // too short to be \ddd - default: // maybe \ddd - if isDDD(s[offset+1:]) { - return dddToByte(s[offset+1:]), 4 - } - } - // not \ddd, just an RFC 1035 "quoted" character - return s[offset+1], 2 -} - -// SPF RR. See RFC 4408, Section 3.1.1. -type SPF struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -// AVC RR. See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template. -type AVC struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -// SRV RR. See RFC 2782. -type SRV struct { - Hdr RR_Header - Priority uint16 - Weight uint16 - Port uint16 - Target string `dns:"domain-name"` -} - -func (rr *SRV) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Priority)) + " " + - strconv.Itoa(int(rr.Weight)) + " " + - strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target) -} - -// NAPTR RR. See RFC 2915. -type NAPTR struct { - Hdr RR_Header - Order uint16 - Preference uint16 - Flags string - Service string - Regexp string - Replacement string `dns:"domain-name"` -} - -func (rr *NAPTR) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Order)) + " " + - strconv.Itoa(int(rr.Preference)) + " " + - "\"" + rr.Flags + "\" " + - "\"" + rr.Service + "\" " + - "\"" + rr.Regexp + "\" " + - rr.Replacement -} - -// CERT RR. See RFC 4398. -type CERT struct { - Hdr RR_Header - Type uint16 - KeyTag uint16 - Algorithm uint8 - Certificate string `dns:"base64"` -} - -func (rr *CERT) String() string { - var ( - ok bool - certtype, algorithm string - ) - if certtype, ok = CertTypeToString[rr.Type]; !ok { - certtype = strconv.Itoa(int(rr.Type)) - } - if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok { - algorithm = strconv.Itoa(int(rr.Algorithm)) - } - return rr.Hdr.String() + certtype + - " " + strconv.Itoa(int(rr.KeyTag)) + - " " + algorithm + - " " + rr.Certificate -} - -// DNAME RR. See RFC 2672. -type DNAME struct { - Hdr RR_Header - Target string `dns:"domain-name"` -} - -func (rr *DNAME) String() string { - return rr.Hdr.String() + sprintName(rr.Target) -} - -// A RR. See RFC 1035. -type A struct { - Hdr RR_Header - A net.IP `dns:"a"` -} - -func (rr *A) String() string { - if rr.A == nil { - return rr.Hdr.String() - } - return rr.Hdr.String() + rr.A.String() -} - -// AAAA RR. See RFC 3596. -type AAAA struct { - Hdr RR_Header - AAAA net.IP `dns:"aaaa"` -} - -func (rr *AAAA) String() string { - if rr.AAAA == nil { - return rr.Hdr.String() - } - - if rr.AAAA.To4() != nil { - return rr.Hdr.String() + ipv4InIPv6Prefix + rr.AAAA.String() - } - - return rr.Hdr.String() + rr.AAAA.String() -} - -// PX RR. See RFC 2163. -type PX struct { - Hdr RR_Header - Preference uint16 - Map822 string `dns:"domain-name"` - Mapx400 string `dns:"domain-name"` -} - -func (rr *PX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400) -} - -// GPOS RR. See RFC 1712. -type GPOS struct { - Hdr RR_Header - Longitude string - Latitude string - Altitude string -} - -func (rr *GPOS) String() string { - return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude -} - -// LOC RR. See RFC 1876. -type LOC struct { - Hdr RR_Header - Version uint8 - Size uint8 - HorizPre uint8 - VertPre uint8 - Latitude uint32 - Longitude uint32 - Altitude uint32 -} - -// cmToM takes a cm value expressed in RFC 1876 SIZE mantissa/exponent -// format and returns a string in m (two decimals for the cm). -func cmToM(x uint8) string { - m := x & 0xf0 >> 4 - e := x & 0x0f - - if e < 2 { - if e == 1 { - m *= 10 - } - - return fmt.Sprintf("0.%02d", m) - } - - s := fmt.Sprintf("%d", m) - for e > 2 { - s += "0" - e-- - } - return s -} - -func (rr *LOC) String() string { - s := rr.Hdr.String() - - lat := rr.Latitude - ns := "N" - if lat > LOC_EQUATOR { - lat = lat - LOC_EQUATOR - } else { - ns = "S" - lat = LOC_EQUATOR - lat - } - h := lat / LOC_DEGREES - lat = lat % LOC_DEGREES - m := lat / LOC_HOURS - lat = lat % LOC_HOURS - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lat)/1000, ns) - - lon := rr.Longitude - ew := "E" - if lon > LOC_PRIMEMERIDIAN { - lon = lon - LOC_PRIMEMERIDIAN - } else { - ew = "W" - lon = LOC_PRIMEMERIDIAN - lon - } - h = lon / LOC_DEGREES - lon = lon % LOC_DEGREES - m = lon / LOC_HOURS - lon = lon % LOC_HOURS - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lon)/1000, ew) - - var alt = float64(rr.Altitude) / 100 - alt -= LOC_ALTITUDEBASE - if rr.Altitude%100 != 0 { - s += fmt.Sprintf("%.2fm ", alt) - } else { - s += fmt.Sprintf("%.0fm ", alt) - } - - s += cmToM(rr.Size) + "m " - s += cmToM(rr.HorizPre) + "m " - s += cmToM(rr.VertPre) + "m" - return s -} - -// SIG RR. See RFC 2535. The SIG RR is identical to RRSIG and nowadays only used for SIG(0), See RFC 2931. -type SIG struct { - RRSIG -} - -// RRSIG RR. See RFC 4034 and RFC 3755. -type RRSIG struct { - Hdr RR_Header - TypeCovered uint16 - Algorithm uint8 - Labels uint8 - OrigTtl uint32 - Expiration uint32 - Inception uint32 - KeyTag uint16 - SignerName string `dns:"domain-name"` - Signature string `dns:"base64"` -} - -func (rr *RRSIG) String() string { - s := rr.Hdr.String() - s += Type(rr.TypeCovered).String() - s += " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.Labels)) + - " " + strconv.FormatInt(int64(rr.OrigTtl), 10) + - " " + TimeToString(rr.Expiration) + - " " + TimeToString(rr.Inception) + - " " + strconv.Itoa(int(rr.KeyTag)) + - " " + sprintName(rr.SignerName) + - " " + rr.Signature - return s -} - -// NXT RR. See RFC 2535. -type NXT struct { - NSEC -} - -// NSEC RR. See RFC 4034 and RFC 3755. -type NSEC struct { - Hdr RR_Header - NextDomain string `dns:"domain-name"` - TypeBitMap []uint16 `dns:"nsec"` -} - -func (rr *NSEC) String() string { - s := rr.Hdr.String() + sprintName(rr.NextDomain) - for _, t := range rr.TypeBitMap { - s += " " + Type(t).String() - } - return s -} - -func (rr *NSEC) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.NextDomain, off+l, compression, false) - l += typeBitMapLen(rr.TypeBitMap) - return l -} - -// DLV RR. See RFC 4431. -type DLV struct{ DS } - -// CDS RR. See RFC 7344. -type CDS struct{ DS } - -// DS RR. See RFC 4034 and RFC 3658. -type DS struct { - Hdr RR_Header - KeyTag uint16 - Algorithm uint8 - DigestType uint8 - Digest string `dns:"hex"` -} - -func (rr *DS) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.DigestType)) + - " " + strings.ToUpper(rr.Digest) -} - -// KX RR. See RFC 2230. -type KX struct { - Hdr RR_Header - Preference uint16 - Exchanger string `dns:"domain-name"` -} - -func (rr *KX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + - " " + sprintName(rr.Exchanger) -} - -// TA RR. See http://www.watson.org/~weiler/INI1999-19.pdf. -type TA struct { - Hdr RR_Header - KeyTag uint16 - Algorithm uint8 - DigestType uint8 - Digest string `dns:"hex"` -} - -func (rr *TA) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.DigestType)) + - " " + strings.ToUpper(rr.Digest) -} - -// TALINK RR. See https://www.iana.org/assignments/dns-parameters/TALINK/talink-completed-template. -type TALINK struct { - Hdr RR_Header - PreviousName string `dns:"domain-name"` - NextName string `dns:"domain-name"` -} - -func (rr *TALINK) String() string { - return rr.Hdr.String() + - sprintName(rr.PreviousName) + " " + sprintName(rr.NextName) -} - -// SSHFP RR. See RFC 4255. -type SSHFP struct { - Hdr RR_Header - Algorithm uint8 - Type uint8 - FingerPrint string `dns:"hex"` -} - -func (rr *SSHFP) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.Type)) + - " " + strings.ToUpper(rr.FingerPrint) -} - -// KEY RR. See RFC 2535. -type KEY struct { - DNSKEY -} - -// CDNSKEY RR. See RFC 7344. -type CDNSKEY struct { - DNSKEY -} - -// DNSKEY RR. See RFC 4034 and RFC 3755. -type DNSKEY struct { - Hdr RR_Header - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` -} - -func (rr *DNSKEY) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Protocol)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + rr.PublicKey -} - -// IPSECKEY RR. See RFC 4025. -type IPSECKEY struct { - Hdr RR_Header - Precedence uint8 - GatewayType uint8 - Algorithm uint8 - GatewayAddr net.IP `dns:"-"` // packing/unpacking/parsing/etc handled together with GatewayHost - GatewayHost string `dns:"ipsechost"` - PublicKey string `dns:"base64"` -} - -func (rr *IPSECKEY) String() string { - var gateway string - switch rr.GatewayType { - case IPSECGatewayIPv4, IPSECGatewayIPv6: - gateway = rr.GatewayAddr.String() - case IPSECGatewayHost: - gateway = rr.GatewayHost - case IPSECGatewayNone: - fallthrough - default: - gateway = "." - } - - return rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) + - " " + strconv.Itoa(int(rr.GatewayType)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + gateway + - " " + rr.PublicKey -} - -// AMTRELAY RR. See RFC 8777. -type AMTRELAY struct { - Hdr RR_Header - Precedence uint8 - GatewayType uint8 // discovery is packed in here at bit 0x80 - GatewayAddr net.IP `dns:"-"` // packing/unpacking/parsing/etc handled together with GatewayHost - GatewayHost string `dns:"amtrelayhost"` -} - -func (rr *AMTRELAY) String() string { - var gateway string - switch rr.GatewayType & 0x7f { - case AMTRELAYIPv4, AMTRELAYIPv6: - gateway = rr.GatewayAddr.String() - case AMTRELAYHost: - gateway = rr.GatewayHost - case AMTRELAYNone: - fallthrough - default: - gateway = "." - } - boolS := "0" - if rr.GatewayType&0x80 == 0x80 { - boolS = "1" - } - - return rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) + - " " + boolS + - " " + strconv.Itoa(int(rr.GatewayType&0x7f)) + - " " + gateway -} - -// RKEY RR. See https://www.iana.org/assignments/dns-parameters/RKEY/rkey-completed-template. -type RKEY struct { - Hdr RR_Header - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` -} - -func (rr *RKEY) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Protocol)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + rr.PublicKey -} - -// NSAPPTR RR. See RFC 1348. -type NSAPPTR struct { - Hdr RR_Header - Ptr string `dns:"domain-name"` -} - -func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) } - -// NSEC3 RR. See RFC 5155. -type NSEC3 struct { - Hdr RR_Header - Hash uint8 - Flags uint8 - Iterations uint16 - SaltLength uint8 - Salt string `dns:"size-hex:SaltLength"` - HashLength uint8 - NextDomain string `dns:"size-base32:HashLength"` - TypeBitMap []uint16 `dns:"nsec"` -} - -func (rr *NSEC3) String() string { - s := rr.Hdr.String() - s += strconv.Itoa(int(rr.Hash)) + - " " + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Iterations)) + - " " + saltToString(rr.Salt) + - " " + rr.NextDomain - for _, t := range rr.TypeBitMap { - s += " " + Type(t).String() - } - return s -} - -func (rr *NSEC3) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1 - l += typeBitMapLen(rr.TypeBitMap) - return l -} - -// NSEC3PARAM RR. See RFC 5155. -type NSEC3PARAM struct { - Hdr RR_Header - Hash uint8 - Flags uint8 - Iterations uint16 - SaltLength uint8 - Salt string `dns:"size-hex:SaltLength"` -} - -func (rr *NSEC3PARAM) String() string { - s := rr.Hdr.String() - s += strconv.Itoa(int(rr.Hash)) + - " " + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Iterations)) + - " " + saltToString(rr.Salt) - return s -} - -// TKEY RR. See RFC 2930. -type TKEY struct { - Hdr RR_Header - Algorithm string `dns:"domain-name"` - Inception uint32 - Expiration uint32 - Mode uint16 - Error uint16 - KeySize uint16 - Key string `dns:"size-hex:KeySize"` - OtherLen uint16 - OtherData string `dns:"size-hex:OtherLen"` -} - -// TKEY has no official presentation format, but this will suffice. -func (rr *TKEY) String() string { - s := ";" + rr.Hdr.String() + - " " + rr.Algorithm + - " " + TimeToString(rr.Inception) + - " " + TimeToString(rr.Expiration) + - " " + strconv.Itoa(int(rr.Mode)) + - " " + strconv.Itoa(int(rr.Error)) + - " " + strconv.Itoa(int(rr.KeySize)) + - " " + rr.Key + - " " + strconv.Itoa(int(rr.OtherLen)) + - " " + rr.OtherData - return s -} - -// RFC3597 represents an unknown/generic RR. See RFC 3597. -type RFC3597 struct { - Hdr RR_Header - Rdata string `dns:"hex"` -} - -func (rr *RFC3597) String() string { - // Let's call it a hack - s := rfc3597Header(rr.Hdr) - - s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata - return s -} - -func rfc3597Header(h RR_Header) string { - var s string - - s += sprintName(h.Name) + "\t" - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" - s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t" - s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t" - return s -} - -// URI RR. See RFC 7553. -type URI struct { - Hdr RR_Header - Priority uint16 - Weight uint16 - Target string `dns:"octet"` -} - -// rr.Target to be parsed as a sequence of character encoded octets according to RFC 3986 -func (rr *URI) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) + - " " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target) -} - -// DHCID RR. See RFC 4701. -type DHCID struct { - Hdr RR_Header - Digest string `dns:"base64"` -} - -func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest } - -// TLSA RR. See RFC 6698. -type TLSA struct { - Hdr RR_Header - Usage uint8 - Selector uint8 - MatchingType uint8 - Certificate string `dns:"hex"` -} - -func (rr *TLSA) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Usage)) + - " " + strconv.Itoa(int(rr.Selector)) + - " " + strconv.Itoa(int(rr.MatchingType)) + - " " + rr.Certificate -} - -// SMIMEA RR. See RFC 8162. -type SMIMEA struct { - Hdr RR_Header - Usage uint8 - Selector uint8 - MatchingType uint8 - Certificate string `dns:"hex"` -} - -func (rr *SMIMEA) String() string { - s := rr.Hdr.String() + - strconv.Itoa(int(rr.Usage)) + - " " + strconv.Itoa(int(rr.Selector)) + - " " + strconv.Itoa(int(rr.MatchingType)) - - // Every Nth char needs a space on this output. If we output - // this as one giant line, we can't read it can in because in some cases - // the cert length overflows scan.maxTok (2048). - sx := splitN(rr.Certificate, 1024) // conservative value here - s += " " + strings.Join(sx, " ") - return s -} - -// HIP RR. See RFC 8005. -type HIP struct { - Hdr RR_Header - HitLength uint8 - PublicKeyAlgorithm uint8 - PublicKeyLength uint16 - Hit string `dns:"size-hex:HitLength"` - PublicKey string `dns:"size-base64:PublicKeyLength"` - RendezvousServers []string `dns:"domain-name"` -} - -func (rr *HIP) String() string { - s := rr.Hdr.String() + - strconv.Itoa(int(rr.PublicKeyAlgorithm)) + - " " + rr.Hit + - " " + rr.PublicKey - for _, d := range rr.RendezvousServers { - s += " " + sprintName(d) - } - return s -} - -// NINFO RR. See https://www.iana.org/assignments/dns-parameters/NINFO/ninfo-completed-template. -type NINFO struct { - Hdr RR_Header - ZSData []string `dns:"txt"` -} - -func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) } - -// NID RR. See RFC 6742. -type NID struct { - Hdr RR_Header - Preference uint16 - NodeID uint64 -} - -func (rr *NID) String() string { - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - node := fmt.Sprintf("%0.16x", rr.NodeID) - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] - return s -} - -// L32 RR, See RFC 6742. -type L32 struct { - Hdr RR_Header - Preference uint16 - Locator32 net.IP `dns:"a"` -} - -func (rr *L32) String() string { - if rr.Locator32 == nil { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - } - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + - " " + rr.Locator32.String() -} - -// L64 RR, See RFC 6742. -type L64 struct { - Hdr RR_Header - Preference uint16 - Locator64 uint64 -} - -func (rr *L64) String() string { - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - node := fmt.Sprintf("%0.16X", rr.Locator64) - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] - return s -} - -// LP RR. See RFC 6742. -type LP struct { - Hdr RR_Header - Preference uint16 - Fqdn string `dns:"domain-name"` -} - -func (rr *LP) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn) -} - -// EUI48 RR. See RFC 7043. -type EUI48 struct { - Hdr RR_Header - Address uint64 `dns:"uint48"` -} - -func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) } - -// EUI64 RR. See RFC 7043. -type EUI64 struct { - Hdr RR_Header - Address uint64 -} - -func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) } - -// CAA RR. See RFC 6844. -type CAA struct { - Hdr RR_Header - Flag uint8 - Tag string - Value string `dns:"octet"` -} - -// rr.Value Is the character-string encoding of the value field as specified in RFC 1035, Section 5.1. -func (rr *CAA) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value) -} - -// UID RR. Deprecated, IANA-Reserved. -type UID struct { - Hdr RR_Header - Uid uint32 -} - -func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) } - -// GID RR. Deprecated, IANA-Reserved. -type GID struct { - Hdr RR_Header - Gid uint32 -} - -func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) } - -// UINFO RR. Deprecated, IANA-Reserved. -type UINFO struct { - Hdr RR_Header - Uinfo string -} - -func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) } - -// EID RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt. -type EID struct { - Hdr RR_Header - Endpoint string `dns:"hex"` -} - -func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) } - -// NIMLOC RR. See http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt. -type NIMLOC struct { - Hdr RR_Header - Locator string `dns:"hex"` -} - -func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) } - -// OPENPGPKEY RR. See RFC 7929. -type OPENPGPKEY struct { - Hdr RR_Header - PublicKey string `dns:"base64"` -} - -func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey } - -// CSYNC RR. See RFC 7477. -type CSYNC struct { - Hdr RR_Header - Serial uint32 - Flags uint16 - TypeBitMap []uint16 `dns:"nsec"` -} - -func (rr *CSYNC) String() string { - s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Serial), 10) + " " + strconv.Itoa(int(rr.Flags)) - - for _, t := range rr.TypeBitMap { - s += " " + Type(t).String() - } - return s -} - -func (rr *CSYNC) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 4 + 2 - l += typeBitMapLen(rr.TypeBitMap) - return l -} - -// ZONEMD RR, from draft-ietf-dnsop-dns-zone-digest -type ZONEMD struct { - Hdr RR_Header - Serial uint32 - Scheme uint8 - Hash uint8 - Digest string `dns:"hex"` -} - -func (rr *ZONEMD) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Serial)) + - " " + strconv.Itoa(int(rr.Scheme)) + - " " + strconv.Itoa(int(rr.Hash)) + - " " + rr.Digest -} - -// APL RR. See RFC 3123. -type APL struct { - Hdr RR_Header - Prefixes []APLPrefix `dns:"apl"` -} - -// APLPrefix is an address prefix hold by an APL record. -type APLPrefix struct { - Negation bool - Network net.IPNet -} - -// String returns presentation form of the APL record. -func (rr *APL) String() string { - var sb strings.Builder - sb.WriteString(rr.Hdr.String()) - for i, p := range rr.Prefixes { - if i > 0 { - sb.WriteByte(' ') - } - sb.WriteString(p.str()) - } - return sb.String() -} - -// str returns presentation form of the APL prefix. -func (a *APLPrefix) str() string { - var sb strings.Builder - if a.Negation { - sb.WriteByte('!') - } - - switch len(a.Network.IP) { - case net.IPv4len: - sb.WriteByte('1') - case net.IPv6len: - sb.WriteByte('2') - } - - sb.WriteByte(':') - - switch len(a.Network.IP) { - case net.IPv4len: - sb.WriteString(a.Network.IP.String()) - case net.IPv6len: - // add prefix for IPv4-mapped IPv6 - if v4 := a.Network.IP.To4(); v4 != nil { - sb.WriteString(ipv4InIPv6Prefix) - } - sb.WriteString(a.Network.IP.String()) - } - - sb.WriteByte('/') - - prefix, _ := a.Network.Mask.Size() - sb.WriteString(strconv.Itoa(prefix)) - - return sb.String() -} - -// equals reports whether two APL prefixes are identical. -func (a *APLPrefix) equals(b *APLPrefix) bool { - return a.Negation == b.Negation && - a.Network.IP.Equal(b.Network.IP) && - bytes.Equal(a.Network.Mask, b.Network.Mask) -} - -// copy returns a copy of the APL prefix. -func (a *APLPrefix) copy() APLPrefix { - return APLPrefix{ - Negation: a.Negation, - Network: copyNet(a.Network), - } -} - -// len returns size of the prefix in wire format. -func (a *APLPrefix) len() int { - // 4-byte header and the network address prefix (see Section 4 of RFC 3123) - prefix, _ := a.Network.Mask.Size() - return 4 + (prefix+7)/8 -} - -// TimeToString translates the RRSIG's incep. and expir. times to the -// string representation used when printing the record. -// It takes serial arithmetic (RFC 1982) into account. -func TimeToString(t uint32) string { - mod := (int64(t)-time.Now().Unix())/year68 - 1 - if mod < 0 { - mod = 0 - } - ti := time.Unix(int64(t)-mod*year68, 0).UTC() - return ti.Format("20060102150405") -} - -// StringToTime translates the RRSIG's incep. and expir. times from -// string values like "20110403154150" to an 32 bit integer. -// It takes serial arithmetic (RFC 1982) into account. -func StringToTime(s string) (uint32, error) { - t, err := time.Parse("20060102150405", s) - if err != nil { - return 0, err - } - mod := t.Unix()/year68 - 1 - if mod < 0 { - mod = 0 - } - return uint32(t.Unix() - mod*year68), nil -} - -// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty. -func saltToString(s string) string { - if s == "" { - return "-" - } - return strings.ToUpper(s) -} - -func euiToString(eui uint64, bits int) (hex string) { - switch bits { - case 64: - hex = fmt.Sprintf("%16.16x", eui) - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + - "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16] - case 48: - hex = fmt.Sprintf("%12.12x", eui) - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + - "-" + hex[8:10] + "-" + hex[10:12] - } - return -} - -// cloneSlice returns a shallow copy of s. -func cloneSlice[E any, S ~[]E](s S) S { - if s == nil { - return nil - } - return append(S(nil), s...) -} - -// copyNet returns a copy of a subnet. -func copyNet(n net.IPNet) net.IPNet { - return net.IPNet{ - IP: cloneSlice(n.IP), - Mask: cloneSlice(n.Mask), - } -} - -// SplitN splits a string into N sized string chunks. -// This might become an exported function once. -func splitN(s string, n int) []string { - if len(s) < n { - return []string{s} - } - sx := []string{} - p, i := 0, n - for { - if i <= len(s) { - sx = append(sx, s[p:i]) - } else { - sx = append(sx, s[p:]) - break - - } - p, i = p+n, i+n - } - - return sx -} diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go deleted file mode 100644 index c018ad4..0000000 --- a/vendor/github.com/miekg/dns/udp.go +++ /dev/null @@ -1,103 +0,0 @@ -//go:build !windows -// +build !windows - -package dns - -import ( - "net" - - "golang.org/x/net/ipv4" - "golang.org/x/net/ipv6" -) - -// This is the required size of the OOB buffer to pass to ReadMsgUDP. -var udpOOBSize = func() int { - // We can't know whether we'll get an IPv4 control message or an - // IPv6 control message ahead of time. To get around this, we size - // the buffer equal to the largest of the two. - - oob4 := ipv4.NewControlMessage(ipv4.FlagDst | ipv4.FlagInterface) - oob6 := ipv6.NewControlMessage(ipv6.FlagDst | ipv6.FlagInterface) - - if len(oob4) > len(oob6) { - return len(oob4) - } - - return len(oob6) -}() - -// SessionUDP holds the remote address and the associated -// out-of-band data. -type SessionUDP struct { - raddr *net.UDPAddr - context []byte -} - -// RemoteAddr returns the remote network address. -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } - -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a -// net.UDPAddr. -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { - oob := make([]byte, udpOOBSize) - n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) - if err != nil { - return n, nil, err - } - return n, &SessionUDP{raddr, oob[:oobn]}, err -} - -// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr. -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { - oob := correctSource(session.context) - n, _, err := conn.WriteMsgUDP(b, oob, session.raddr) - return n, err -} - -func setUDPSocketOptions(conn *net.UDPConn) error { - // Try setting the flags for both families and ignore the errors unless they - // both error. - err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true) - err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true) - if err6 != nil && err4 != nil { - return err4 - } - return nil -} - -// parseDstFromOOB takes oob data and returns the destination IP. -func parseDstFromOOB(oob []byte) net.IP { - // Start with IPv6 and then fallback to IPv4 - // TODO(fastest963): Figure out a way to prefer one or the other. Looking at - // the lvl of the header for a 0 or 41 isn't cross-platform. - cm6 := new(ipv6.ControlMessage) - if cm6.Parse(oob) == nil && cm6.Dst != nil { - return cm6.Dst - } - cm4 := new(ipv4.ControlMessage) - if cm4.Parse(oob) == nil && cm4.Dst != nil { - return cm4.Dst - } - return nil -} - -// correctSource takes oob data and returns new oob data with the Src equal to the Dst -func correctSource(oob []byte) []byte { - dst := parseDstFromOOB(oob) - if dst == nil { - return nil - } - // If the dst is definitely an IPv6, then use ipv6's ControlMessage to - // respond otherwise use ipv4's because ipv6's marshal ignores ipv4 - // addresses. - if dst.To4() == nil { - cm := new(ipv6.ControlMessage) - cm.Src = dst - oob = cm.Marshal() - } else { - cm := new(ipv4.ControlMessage) - cm.Src = dst - oob = cm.Marshal() - } - return oob -} diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go deleted file mode 100644 index a259b67..0000000 --- a/vendor/github.com/miekg/dns/udp_windows.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build windows -// +build windows - -// TODO(tmthrgd): Remove this Windows-specific code if go.dev/issue/7175 and -// go.dev/issue/7174 are ever fixed. - -package dns - -import "net" - -// SessionUDP holds the remote address -type SessionUDP struct { - raddr *net.UDPAddr -} - -// RemoteAddr returns the remote network address. -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } - -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a -// net.UDPAddr. -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { - n, raddr, err := conn.ReadFrom(b) - if err != nil { - return n, nil, err - } - return n, &SessionUDP{raddr.(*net.UDPAddr)}, err -} - -// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr. -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { - return conn.WriteTo(b, session.raddr) -} - -func setUDPSocketOptions(*net.UDPConn) error { return nil } -func parseDstFromOOB([]byte, net.IP) net.IP { return nil } diff --git a/vendor/github.com/miekg/dns/update.go b/vendor/github.com/miekg/dns/update.go deleted file mode 100644 index 16f9ee8..0000000 --- a/vendor/github.com/miekg/dns/update.go +++ /dev/null @@ -1,112 +0,0 @@ -package dns - -// NameUsed sets the RRs in the prereq section to -// "Name is in use" RRs. RFC 2136 section 2.4.4. -func (u *Msg) NameUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) - } -} - -// NameNotUsed sets the RRs in the prereq section to -// "Name is in not use" RRs. RFC 2136 section 2.4.5. -func (u *Msg) NameNotUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}}) - } -} - -// Used sets the RRs in the prereq section to -// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2. -func (u *Msg) Used(rr []RR) { - if len(u.Question) == 0 { - panic("dns: empty question section") - } - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - hdr := r.Header() - hdr.Class = u.Question[0].Qclass - hdr.Ttl = 0 - u.Answer = append(u.Answer, r) - } -} - -// RRsetUsed sets the RRs in the prereq section to -// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1. -func (u *Msg) RRsetUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - h := r.Header() - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}}) - } -} - -// RRsetNotUsed sets the RRs in the prereq section to -// "RRset does not exist" RRs. RFC 2136 section 2.4.3. -func (u *Msg) RRsetNotUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - h := r.Header() - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}}) - } -} - -// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1. -func (u *Msg) Insert(rr []RR) { - if len(u.Question) == 0 { - panic("dns: empty question section") - } - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - r.Header().Class = u.Question[0].Qclass - u.Ns = append(u.Ns, r) - } -} - -// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2. -func (u *Msg) RemoveRRset(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - h := r.Header() - u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}}) - } -} - -// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3 -func (u *Msg) RemoveName(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) - } -} - -// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4 -func (u *Msg) Remove(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - h := r.Header() - h.Class = ClassNONE - h.Ttl = 0 - u.Ns = append(u.Ns, r) - } -} diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go deleted file mode 100644 index dc34e59..0000000 --- a/vendor/github.com/miekg/dns/version.go +++ /dev/null @@ -1,15 +0,0 @@ -package dns - -import "fmt" - -// Version is current version of this library. -var Version = v{1, 1, 58} - -// v holds the version of this library. -type v struct { - Major, Minor, Patch int -} - -func (v v) String() string { - return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) -} diff --git a/vendor/github.com/miekg/dns/xfr.go b/vendor/github.com/miekg/dns/xfr.go deleted file mode 100644 index 05b3c5a..0000000 --- a/vendor/github.com/miekg/dns/xfr.go +++ /dev/null @@ -1,280 +0,0 @@ -package dns - -import ( - "fmt" - "time" -) - -// Envelope is used when doing a zone transfer with a remote server. -type Envelope struct { - RR []RR // The set of RRs in the answer section of the xfr reply message. - Error error // If something went wrong, this contains the error. -} - -// A Transfer defines parameters that are used during a zone transfer. -type Transfer struct { - *Conn - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations. - TsigSecret map[string]string // Secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2) - tsigTimersOnly bool -} - -func (t *Transfer) tsigProvider() TsigProvider { - if t.TsigProvider != nil { - return t.TsigProvider - } - if t.TsigSecret != nil { - return tsigSecretProvider(t.TsigSecret) - } - return nil -} - -// TODO: Think we need to away to stop the transfer - -// In performs an incoming transfer with the server in a. -// If you would like to set the source IP, or some other attribute -// of a Dialer for a Transfer, you can do so by specifying the attributes -// in the Transfer.Conn: -// -// d := net.Dialer{LocalAddr: transfer_source} -// con, err := d.Dial("tcp", master) -// dnscon := &dns.Conn{Conn:con} -// transfer = &dns.Transfer{Conn: dnscon} -// channel, err := transfer.In(message, master) -func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) { - switch q.Question[0].Qtype { - case TypeAXFR, TypeIXFR: - default: - return nil, &Error{"unsupported question type"} - } - - timeout := dnsTimeout - if t.DialTimeout != 0 { - timeout = t.DialTimeout - } - - if t.Conn == nil { - t.Conn, err = DialTimeout("tcp", a, timeout) - if err != nil { - return nil, err - } - } - - if err := t.WriteMsg(q); err != nil { - return nil, err - } - - env = make(chan *Envelope) - switch q.Question[0].Qtype { - case TypeAXFR: - go t.inAxfr(q, env) - case TypeIXFR: - go t.inIxfr(q, env) - } - - return env, nil -} - -func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) { - first := true - defer func() { - // First close the connection, then the channel. This allows functions blocked on - // the channel to assume that the connection is closed and no further operations are - // pending when they resume. - t.Close() - close(c) - }() - timeout := dnsTimeout - if t.ReadTimeout != 0 { - timeout = t.ReadTimeout - } - for { - t.Conn.SetReadDeadline(time.Now().Add(timeout)) - in, err := t.ReadMsg() - if err != nil { - c <- &Envelope{nil, err} - return - } - if q.Id != in.Id { - c <- &Envelope{in.Answer, ErrId} - return - } - if first { - if in.Rcode != RcodeSuccess { - c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} - return - } - if !isSOAFirst(in) { - c <- &Envelope{in.Answer, ErrSoa} - return - } - first = !first - // only one answer that is SOA, receive more - if len(in.Answer) == 1 { - t.tsigTimersOnly = true - c <- &Envelope{in.Answer, nil} - continue - } - } - - if !first { - t.tsigTimersOnly = true // Subsequent envelopes use this. - if isSOALast(in) { - c <- &Envelope{in.Answer, nil} - return - } - c <- &Envelope{in.Answer, nil} - } - } -} - -func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) { - var serial uint32 // The first serial seen is the current server serial - axfr := true - n := 0 - qser := q.Ns[0].(*SOA).Serial - defer func() { - // First close the connection, then the channel. This allows functions blocked on - // the channel to assume that the connection is closed and no further operations are - // pending when they resume. - t.Close() - close(c) - }() - timeout := dnsTimeout - if t.ReadTimeout != 0 { - timeout = t.ReadTimeout - } - for { - t.SetReadDeadline(time.Now().Add(timeout)) - in, err := t.ReadMsg() - if err != nil { - c <- &Envelope{nil, err} - return - } - if q.Id != in.Id { - c <- &Envelope{in.Answer, ErrId} - return - } - if in.Rcode != RcodeSuccess { - c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} - return - } - if n == 0 { - // Check if the returned answer is ok - if !isSOAFirst(in) { - c <- &Envelope{in.Answer, ErrSoa} - return - } - // This serial is important - serial = in.Answer[0].(*SOA).Serial - // Check if there are no changes in zone - if qser >= serial { - c <- &Envelope{in.Answer, nil} - return - } - } - // Now we need to check each message for SOA records, to see what we need to do - t.tsigTimersOnly = true - for _, rr := range in.Answer { - if v, ok := rr.(*SOA); ok { - if v.Serial == serial { - n++ - // quit if it's a full axfr or the the servers' SOA is repeated the third time - if axfr && n == 2 || n == 3 { - c <- &Envelope{in.Answer, nil} - return - } - } else if axfr { - // it's an ixfr - axfr = false - } - } - } - c <- &Envelope{in.Answer, nil} - } -} - -// Out performs an outgoing transfer with the client connecting in w. -// Basic use pattern: -// -// ch := make(chan *dns.Envelope) -// tr := new(dns.Transfer) -// var wg sync.WaitGroup -// go func() { -// tr.Out(w, r, ch) -// wg.Done() -// }() -// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}} -// close(ch) -// wg.Wait() // wait until everything is written out -// w.Close() // close connection -// -// The server is responsible for sending the correct sequence of RRs through the channel ch. -func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error { - for x := range ch { - r := new(Msg) - // Compress? - r.SetReply(q) - r.Authoritative = true - // assume it fits TODO(miek): fix - r.Answer = append(r.Answer, x.RR...) - if tsig := q.IsTsig(); tsig != nil && w.TsigStatus() == nil { - r.SetTsig(tsig.Hdr.Name, tsig.Algorithm, tsig.Fudge, time.Now().Unix()) - } - if err := w.WriteMsg(r); err != nil { - return err - } - w.TsigTimersOnly(true) - } - return nil -} - -// ReadMsg reads a message from the transfer connection t. -func (t *Transfer) ReadMsg() (*Msg, error) { - m := new(Msg) - p := make([]byte, MaxMsgSize) - n, err := t.Read(p) - if err != nil && n == 0 { - return nil, err - } - p = p[:n] - if err := m.Unpack(p); err != nil { - return nil, err - } - if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil { - // Need to work on the original message p, as that was used to calculate the tsig. - err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly) - t.tsigRequestMAC = ts.MAC - } - return m, err -} - -// WriteMsg writes a message through the transfer connection t. -func (t *Transfer) WriteMsg(m *Msg) (err error) { - var out []byte - if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil { - out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly) - } else { - out, err = m.Pack() - } - if err != nil { - return err - } - _, err = t.Write(out) - return err -} - -func isSOAFirst(in *Msg) bool { - return len(in.Answer) > 0 && - in.Answer[0].Header().Rrtype == TypeSOA -} - -func isSOALast(in *Msg) bool { - return len(in.Answer) > 0 && - in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA -} - -const errXFR = "bad xfr rcode: %d" diff --git a/vendor/github.com/miekg/dns/zduplicate.go b/vendor/github.com/miekg/dns/zduplicate.go deleted file mode 100644 index 03029fb..0000000 --- a/vendor/github.com/miekg/dns/zduplicate.go +++ /dev/null @@ -1,1433 +0,0 @@ -// Code generated by "go run duplicate_generate.go"; DO NOT EDIT. - -package dns - -// isDuplicate() functions - -func (r1 *A) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*A) - if !ok { - return false - } - _ = r2 - if !r1.A.Equal(r2.A) { - return false - } - return true -} - -func (r1 *AAAA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*AAAA) - if !ok { - return false - } - _ = r2 - if !r1.AAAA.Equal(r2.AAAA) { - return false - } - return true -} - -func (r1 *AFSDB) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*AFSDB) - if !ok { - return false - } - _ = r2 - if r1.Subtype != r2.Subtype { - return false - } - if !isDuplicateName(r1.Hostname, r2.Hostname) { - return false - } - return true -} - -func (r1 *AMTRELAY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*AMTRELAY) - if !ok { - return false - } - _ = r2 - if r1.Precedence != r2.Precedence { - return false - } - if r1.GatewayType != r2.GatewayType { - return false - } - switch r1.GatewayType { - case IPSECGatewayIPv4, IPSECGatewayIPv6: - if !r1.GatewayAddr.Equal(r2.GatewayAddr) { - return false - } - case IPSECGatewayHost: - if !isDuplicateName(r1.GatewayHost, r2.GatewayHost) { - return false - } - } - - return true -} - -func (r1 *ANY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*ANY) - if !ok { - return false - } - _ = r2 - return true -} - -func (r1 *APL) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*APL) - if !ok { - return false - } - _ = r2 - if len(r1.Prefixes) != len(r2.Prefixes) { - return false - } - for i := 0; i < len(r1.Prefixes); i++ { - if !r1.Prefixes[i].equals(&r2.Prefixes[i]) { - return false - } - } - return true -} - -func (r1 *AVC) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*AVC) - if !ok { - return false - } - _ = r2 - if len(r1.Txt) != len(r2.Txt) { - return false - } - for i := 0; i < len(r1.Txt); i++ { - if r1.Txt[i] != r2.Txt[i] { - return false - } - } - return true -} - -func (r1 *CAA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CAA) - if !ok { - return false - } - _ = r2 - if r1.Flag != r2.Flag { - return false - } - if r1.Tag != r2.Tag { - return false - } - if r1.Value != r2.Value { - return false - } - return true -} - -func (r1 *CDNSKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CDNSKEY) - if !ok { - return false - } - _ = r2 - if r1.Flags != r2.Flags { - return false - } - if r1.Protocol != r2.Protocol { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *CDS) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CDS) - if !ok { - return false - } - _ = r2 - if r1.KeyTag != r2.KeyTag { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.DigestType != r2.DigestType { - return false - } - if r1.Digest != r2.Digest { - return false - } - return true -} - -func (r1 *CERT) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CERT) - if !ok { - return false - } - _ = r2 - if r1.Type != r2.Type { - return false - } - if r1.KeyTag != r2.KeyTag { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.Certificate != r2.Certificate { - return false - } - return true -} - -func (r1 *CNAME) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CNAME) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Target, r2.Target) { - return false - } - return true -} - -func (r1 *CSYNC) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*CSYNC) - if !ok { - return false - } - _ = r2 - if r1.Serial != r2.Serial { - return false - } - if r1.Flags != r2.Flags { - return false - } - if len(r1.TypeBitMap) != len(r2.TypeBitMap) { - return false - } - for i := 0; i < len(r1.TypeBitMap); i++ { - if r1.TypeBitMap[i] != r2.TypeBitMap[i] { - return false - } - } - return true -} - -func (r1 *DHCID) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*DHCID) - if !ok { - return false - } - _ = r2 - if r1.Digest != r2.Digest { - return false - } - return true -} - -func (r1 *DLV) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*DLV) - if !ok { - return false - } - _ = r2 - if r1.KeyTag != r2.KeyTag { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.DigestType != r2.DigestType { - return false - } - if r1.Digest != r2.Digest { - return false - } - return true -} - -func (r1 *DNAME) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*DNAME) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Target, r2.Target) { - return false - } - return true -} - -func (r1 *DNSKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*DNSKEY) - if !ok { - return false - } - _ = r2 - if r1.Flags != r2.Flags { - return false - } - if r1.Protocol != r2.Protocol { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *DS) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*DS) - if !ok { - return false - } - _ = r2 - if r1.KeyTag != r2.KeyTag { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.DigestType != r2.DigestType { - return false - } - if r1.Digest != r2.Digest { - return false - } - return true -} - -func (r1 *EID) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*EID) - if !ok { - return false - } - _ = r2 - if r1.Endpoint != r2.Endpoint { - return false - } - return true -} - -func (r1 *EUI48) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*EUI48) - if !ok { - return false - } - _ = r2 - if r1.Address != r2.Address { - return false - } - return true -} - -func (r1 *EUI64) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*EUI64) - if !ok { - return false - } - _ = r2 - if r1.Address != r2.Address { - return false - } - return true -} - -func (r1 *GID) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*GID) - if !ok { - return false - } - _ = r2 - if r1.Gid != r2.Gid { - return false - } - return true -} - -func (r1 *GPOS) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*GPOS) - if !ok { - return false - } - _ = r2 - if r1.Longitude != r2.Longitude { - return false - } - if r1.Latitude != r2.Latitude { - return false - } - if r1.Altitude != r2.Altitude { - return false - } - return true -} - -func (r1 *HINFO) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*HINFO) - if !ok { - return false - } - _ = r2 - if r1.Cpu != r2.Cpu { - return false - } - if r1.Os != r2.Os { - return false - } - return true -} - -func (r1 *HIP) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*HIP) - if !ok { - return false - } - _ = r2 - if r1.HitLength != r2.HitLength { - return false - } - if r1.PublicKeyAlgorithm != r2.PublicKeyAlgorithm { - return false - } - if r1.PublicKeyLength != r2.PublicKeyLength { - return false - } - if r1.Hit != r2.Hit { - return false - } - if r1.PublicKey != r2.PublicKey { - return false - } - if len(r1.RendezvousServers) != len(r2.RendezvousServers) { - return false - } - for i := 0; i < len(r1.RendezvousServers); i++ { - if !isDuplicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) { - return false - } - } - return true -} - -func (r1 *HTTPS) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*HTTPS) - if !ok { - return false - } - _ = r2 - if r1.Priority != r2.Priority { - return false - } - if !isDuplicateName(r1.Target, r2.Target) { - return false - } - if len(r1.Value) != len(r2.Value) { - return false - } - if !areSVCBPairArraysEqual(r1.Value, r2.Value) { - return false - } - return true -} - -func (r1 *IPSECKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*IPSECKEY) - if !ok { - return false - } - _ = r2 - if r1.Precedence != r2.Precedence { - return false - } - if r1.GatewayType != r2.GatewayType { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - switch r1.GatewayType { - case IPSECGatewayIPv4, IPSECGatewayIPv6: - if !r1.GatewayAddr.Equal(r2.GatewayAddr) { - return false - } - case IPSECGatewayHost: - if !isDuplicateName(r1.GatewayHost, r2.GatewayHost) { - return false - } - } - - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *ISDN) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*ISDN) - if !ok { - return false - } - _ = r2 - if r1.Address != r2.Address { - return false - } - if r1.SubAddress != r2.SubAddress { - return false - } - return true -} - -func (r1 *KEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*KEY) - if !ok { - return false - } - _ = r2 - if r1.Flags != r2.Flags { - return false - } - if r1.Protocol != r2.Protocol { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *KX) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*KX) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !isDuplicateName(r1.Exchanger, r2.Exchanger) { - return false - } - return true -} - -func (r1 *L32) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*L32) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !r1.Locator32.Equal(r2.Locator32) { - return false - } - return true -} - -func (r1 *L64) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*L64) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if r1.Locator64 != r2.Locator64 { - return false - } - return true -} - -func (r1 *LOC) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*LOC) - if !ok { - return false - } - _ = r2 - if r1.Version != r2.Version { - return false - } - if r1.Size != r2.Size { - return false - } - if r1.HorizPre != r2.HorizPre { - return false - } - if r1.VertPre != r2.VertPre { - return false - } - if r1.Latitude != r2.Latitude { - return false - } - if r1.Longitude != r2.Longitude { - return false - } - if r1.Altitude != r2.Altitude { - return false - } - return true -} - -func (r1 *LP) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*LP) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !isDuplicateName(r1.Fqdn, r2.Fqdn) { - return false - } - return true -} - -func (r1 *MB) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MB) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Mb, r2.Mb) { - return false - } - return true -} - -func (r1 *MD) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MD) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Md, r2.Md) { - return false - } - return true -} - -func (r1 *MF) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MF) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Mf, r2.Mf) { - return false - } - return true -} - -func (r1 *MG) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MG) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Mg, r2.Mg) { - return false - } - return true -} - -func (r1 *MINFO) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MINFO) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Rmail, r2.Rmail) { - return false - } - if !isDuplicateName(r1.Email, r2.Email) { - return false - } - return true -} - -func (r1 *MR) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MR) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Mr, r2.Mr) { - return false - } - return true -} - -func (r1 *MX) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*MX) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !isDuplicateName(r1.Mx, r2.Mx) { - return false - } - return true -} - -func (r1 *NAPTR) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NAPTR) - if !ok { - return false - } - _ = r2 - if r1.Order != r2.Order { - return false - } - if r1.Preference != r2.Preference { - return false - } - if r1.Flags != r2.Flags { - return false - } - if r1.Service != r2.Service { - return false - } - if r1.Regexp != r2.Regexp { - return false - } - if !isDuplicateName(r1.Replacement, r2.Replacement) { - return false - } - return true -} - -func (r1 *NID) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NID) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if r1.NodeID != r2.NodeID { - return false - } - return true -} - -func (r1 *NIMLOC) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NIMLOC) - if !ok { - return false - } - _ = r2 - if r1.Locator != r2.Locator { - return false - } - return true -} - -func (r1 *NINFO) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NINFO) - if !ok { - return false - } - _ = r2 - if len(r1.ZSData) != len(r2.ZSData) { - return false - } - for i := 0; i < len(r1.ZSData); i++ { - if r1.ZSData[i] != r2.ZSData[i] { - return false - } - } - return true -} - -func (r1 *NS) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NS) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Ns, r2.Ns) { - return false - } - return true -} - -func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NSAPPTR) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Ptr, r2.Ptr) { - return false - } - return true -} - -func (r1 *NSEC) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NSEC) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.NextDomain, r2.NextDomain) { - return false - } - if len(r1.TypeBitMap) != len(r2.TypeBitMap) { - return false - } - for i := 0; i < len(r1.TypeBitMap); i++ { - if r1.TypeBitMap[i] != r2.TypeBitMap[i] { - return false - } - } - return true -} - -func (r1 *NSEC3) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NSEC3) - if !ok { - return false - } - _ = r2 - if r1.Hash != r2.Hash { - return false - } - if r1.Flags != r2.Flags { - return false - } - if r1.Iterations != r2.Iterations { - return false - } - if r1.SaltLength != r2.SaltLength { - return false - } - if r1.Salt != r2.Salt { - return false - } - if r1.HashLength != r2.HashLength { - return false - } - if r1.NextDomain != r2.NextDomain { - return false - } - if len(r1.TypeBitMap) != len(r2.TypeBitMap) { - return false - } - for i := 0; i < len(r1.TypeBitMap); i++ { - if r1.TypeBitMap[i] != r2.TypeBitMap[i] { - return false - } - } - return true -} - -func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NSEC3PARAM) - if !ok { - return false - } - _ = r2 - if r1.Hash != r2.Hash { - return false - } - if r1.Flags != r2.Flags { - return false - } - if r1.Iterations != r2.Iterations { - return false - } - if r1.SaltLength != r2.SaltLength { - return false - } - if r1.Salt != r2.Salt { - return false - } - return true -} - -func (r1 *NULL) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NULL) - if !ok { - return false - } - _ = r2 - if r1.Data != r2.Data { - return false - } - return true -} - -func (r1 *NXT) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*NXT) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.NextDomain, r2.NextDomain) { - return false - } - if len(r1.TypeBitMap) != len(r2.TypeBitMap) { - return false - } - for i := 0; i < len(r1.TypeBitMap); i++ { - if r1.TypeBitMap[i] != r2.TypeBitMap[i] { - return false - } - } - return true -} - -func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*OPENPGPKEY) - if !ok { - return false - } - _ = r2 - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *PTR) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*PTR) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Ptr, r2.Ptr) { - return false - } - return true -} - -func (r1 *PX) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*PX) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !isDuplicateName(r1.Map822, r2.Map822) { - return false - } - if !isDuplicateName(r1.Mapx400, r2.Mapx400) { - return false - } - return true -} - -func (r1 *RFC3597) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RFC3597) - if !ok { - return false - } - _ = r2 - if r1.Rdata != r2.Rdata { - return false - } - return true -} - -func (r1 *RKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RKEY) - if !ok { - return false - } - _ = r2 - if r1.Flags != r2.Flags { - return false - } - if r1.Protocol != r2.Protocol { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.PublicKey != r2.PublicKey { - return false - } - return true -} - -func (r1 *RP) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RP) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Mbox, r2.Mbox) { - return false - } - if !isDuplicateName(r1.Txt, r2.Txt) { - return false - } - return true -} - -func (r1 *RRSIG) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RRSIG) - if !ok { - return false - } - _ = r2 - if r1.TypeCovered != r2.TypeCovered { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.Labels != r2.Labels { - return false - } - if r1.OrigTtl != r2.OrigTtl { - return false - } - if r1.Expiration != r2.Expiration { - return false - } - if r1.Inception != r2.Inception { - return false - } - if r1.KeyTag != r2.KeyTag { - return false - } - if !isDuplicateName(r1.SignerName, r2.SignerName) { - return false - } - if r1.Signature != r2.Signature { - return false - } - return true -} - -func (r1 *RT) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*RT) - if !ok { - return false - } - _ = r2 - if r1.Preference != r2.Preference { - return false - } - if !isDuplicateName(r1.Host, r2.Host) { - return false - } - return true -} - -func (r1 *SIG) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SIG) - if !ok { - return false - } - _ = r2 - if r1.TypeCovered != r2.TypeCovered { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.Labels != r2.Labels { - return false - } - if r1.OrigTtl != r2.OrigTtl { - return false - } - if r1.Expiration != r2.Expiration { - return false - } - if r1.Inception != r2.Inception { - return false - } - if r1.KeyTag != r2.KeyTag { - return false - } - if !isDuplicateName(r1.SignerName, r2.SignerName) { - return false - } - if r1.Signature != r2.Signature { - return false - } - return true -} - -func (r1 *SMIMEA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SMIMEA) - if !ok { - return false - } - _ = r2 - if r1.Usage != r2.Usage { - return false - } - if r1.Selector != r2.Selector { - return false - } - if r1.MatchingType != r2.MatchingType { - return false - } - if r1.Certificate != r2.Certificate { - return false - } - return true -} - -func (r1 *SOA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SOA) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Ns, r2.Ns) { - return false - } - if !isDuplicateName(r1.Mbox, r2.Mbox) { - return false - } - if r1.Serial != r2.Serial { - return false - } - if r1.Refresh != r2.Refresh { - return false - } - if r1.Retry != r2.Retry { - return false - } - if r1.Expire != r2.Expire { - return false - } - if r1.Minttl != r2.Minttl { - return false - } - return true -} - -func (r1 *SPF) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SPF) - if !ok { - return false - } - _ = r2 - if len(r1.Txt) != len(r2.Txt) { - return false - } - for i := 0; i < len(r1.Txt); i++ { - if r1.Txt[i] != r2.Txt[i] { - return false - } - } - return true -} - -func (r1 *SRV) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SRV) - if !ok { - return false - } - _ = r2 - if r1.Priority != r2.Priority { - return false - } - if r1.Weight != r2.Weight { - return false - } - if r1.Port != r2.Port { - return false - } - if !isDuplicateName(r1.Target, r2.Target) { - return false - } - return true -} - -func (r1 *SSHFP) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SSHFP) - if !ok { - return false - } - _ = r2 - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.Type != r2.Type { - return false - } - if r1.FingerPrint != r2.FingerPrint { - return false - } - return true -} - -func (r1 *SVCB) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*SVCB) - if !ok { - return false - } - _ = r2 - if r1.Priority != r2.Priority { - return false - } - if !isDuplicateName(r1.Target, r2.Target) { - return false - } - if len(r1.Value) != len(r2.Value) { - return false - } - if !areSVCBPairArraysEqual(r1.Value, r2.Value) { - return false - } - return true -} - -func (r1 *TA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TA) - if !ok { - return false - } - _ = r2 - if r1.KeyTag != r2.KeyTag { - return false - } - if r1.Algorithm != r2.Algorithm { - return false - } - if r1.DigestType != r2.DigestType { - return false - } - if r1.Digest != r2.Digest { - return false - } - return true -} - -func (r1 *TALINK) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TALINK) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.PreviousName, r2.PreviousName) { - return false - } - if !isDuplicateName(r1.NextName, r2.NextName) { - return false - } - return true -} - -func (r1 *TKEY) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TKEY) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Algorithm, r2.Algorithm) { - return false - } - if r1.Inception != r2.Inception { - return false - } - if r1.Expiration != r2.Expiration { - return false - } - if r1.Mode != r2.Mode { - return false - } - if r1.Error != r2.Error { - return false - } - if r1.KeySize != r2.KeySize { - return false - } - if r1.Key != r2.Key { - return false - } - if r1.OtherLen != r2.OtherLen { - return false - } - if r1.OtherData != r2.OtherData { - return false - } - return true -} - -func (r1 *TLSA) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TLSA) - if !ok { - return false - } - _ = r2 - if r1.Usage != r2.Usage { - return false - } - if r1.Selector != r2.Selector { - return false - } - if r1.MatchingType != r2.MatchingType { - return false - } - if r1.Certificate != r2.Certificate { - return false - } - return true -} - -func (r1 *TSIG) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TSIG) - if !ok { - return false - } - _ = r2 - if !isDuplicateName(r1.Algorithm, r2.Algorithm) { - return false - } - if r1.TimeSigned != r2.TimeSigned { - return false - } - if r1.Fudge != r2.Fudge { - return false - } - if r1.MACSize != r2.MACSize { - return false - } - if r1.MAC != r2.MAC { - return false - } - if r1.OrigId != r2.OrigId { - return false - } - if r1.Error != r2.Error { - return false - } - if r1.OtherLen != r2.OtherLen { - return false - } - if r1.OtherData != r2.OtherData { - return false - } - return true -} - -func (r1 *TXT) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*TXT) - if !ok { - return false - } - _ = r2 - if len(r1.Txt) != len(r2.Txt) { - return false - } - for i := 0; i < len(r1.Txt); i++ { - if r1.Txt[i] != r2.Txt[i] { - return false - } - } - return true -} - -func (r1 *UID) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*UID) - if !ok { - return false - } - _ = r2 - if r1.Uid != r2.Uid { - return false - } - return true -} - -func (r1 *UINFO) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*UINFO) - if !ok { - return false - } - _ = r2 - if r1.Uinfo != r2.Uinfo { - return false - } - return true -} - -func (r1 *URI) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*URI) - if !ok { - return false - } - _ = r2 - if r1.Priority != r2.Priority { - return false - } - if r1.Weight != r2.Weight { - return false - } - if r1.Target != r2.Target { - return false - } - return true -} - -func (r1 *X25) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*X25) - if !ok { - return false - } - _ = r2 - if r1.PSDNAddress != r2.PSDNAddress { - return false - } - return true -} - -func (r1 *ZONEMD) isDuplicate(_r2 RR) bool { - r2, ok := _r2.(*ZONEMD) - if !ok { - return false - } - _ = r2 - if r1.Serial != r2.Serial { - return false - } - if r1.Scheme != r2.Scheme { - return false - } - if r1.Hash != r2.Hash { - return false - } - if r1.Digest != r2.Digest { - return false - } - return true -} diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go deleted file mode 100644 index 39b3bc8..0000000 --- a/vendor/github.com/miekg/dns/zmsg.go +++ /dev/null @@ -1,3045 +0,0 @@ -// Code generated by "go run msg_generate.go"; DO NOT EDIT. - -package dns - -// pack*() functions - -func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDataA(rr.A, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDataAAAA(rr.AAAA, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Subtype, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Hostname, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AMTRELAY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Precedence, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.GatewayType, msg, off) - if err != nil { - return off, err - } - off, err = packIPSECGateway(rr.GatewayAddr, rr.GatewayHost, msg, off, rr.GatewayType, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - return off, nil -} - -func (rr *APL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDataApl(rr.Prefixes, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Flag, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Tag, msg, off) - if err != nil { - return off, err - } - off, err = packStringOctet(rr.Value, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Type, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Certificate, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Target, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint32(rr.Serial, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringBase64(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringHex(rr.Endpoint, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint48(rr.Address, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint64(rr.Address, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint32(rr.Gid, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packString(rr.Longitude, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Latitude, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Altitude, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packString(rr.Cpu, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Os, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.HitLength, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.PublicKeyAlgorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.PublicKeyLength, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Hit, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDataSVCB(rr.Value, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *IPSECKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Precedence, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.GatewayType, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packIPSECGateway(rr.GatewayAddr, rr.GatewayHost, msg, off, rr.GatewayType, compression, false) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ISDN) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packString(rr.Address, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.SubAddress, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Exchanger, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDataA(rr.Locator32, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packUint64(rr.Locator64, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Version, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Size, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.HorizPre, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.VertPre, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Latitude, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Longitude, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Altitude, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Fqdn, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Mb, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Md, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Mf, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Mg, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Rmail, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Email, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Mr, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Mx, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Order, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Service, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Regexp, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Replacement, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packUint64(rr.NodeID, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringHex(rr.Locator, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringTxt(rr.ZSData, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Ns, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Ptr, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.NextDomain, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Hash, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Iterations, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.SaltLength, msg, off) - if err != nil { - return off, err - } - // Only pack salt if value is not "-", i.e. empty - if rr.Salt != "-" { - off, err = packStringHex(rr.Salt, msg, off) - if err != nil { - return off, err - } - } - off, err = packUint8(rr.HashLength, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase32(rr.NextDomain, msg, off) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Hash, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Iterations, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.SaltLength, msg, off) - if err != nil { - return off, err - } - // Only pack salt if value is not "-", i.e. empty - if rr.Salt != "-" { - off, err = packStringHex(rr.Salt, msg, off) - if err != nil { - return off, err - } - } - return off, nil -} - -func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringAny(rr.Data, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.NextDomain, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDataOpt(rr.Option, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *PTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Ptr, msg, off, compression, compress) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Map822, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Mapx400, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringHex(rr.Rdata, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Mbox, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Txt, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.TypeCovered, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.SignerName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Signature, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Host, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.TypeCovered, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.SignerName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Signature, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Usage, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Selector, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.MatchingType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Certificate, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Ns, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Mbox, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packUint32(rr.Serial, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Refresh, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Retry, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expire, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Minttl, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SRV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Weight, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Port, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Type, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.FingerPrint, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SVCB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDataSVCB(rr.Value, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.PreviousName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDomainName(rr.NextName, msg, off, compression, false) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Algorithm, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Mode, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeySize, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Key, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.OtherData, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint8(rr.Usage, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Selector, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.MatchingType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Certificate, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packDomainName(rr.Algorithm, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packUint48(rr.TimeSigned, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Fudge, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.MACSize, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.MAC, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OrigId, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.OtherData, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint32(rr.Uid, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packString(rr.Uinfo, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *URI) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Weight, msg, off) - if err != nil { - return off, err - } - off, err = packStringOctet(rr.Target, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packString(rr.PSDNAddress, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ZONEMD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { - off, err = packUint32(rr.Serial, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Scheme, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Hash, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -// unpack*() functions - -func (rr *A) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.A, off, err = unpackDataA(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AAAA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.AAAA, off, err = unpackDataAAAA(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Subtype, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Hostname, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AMTRELAY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Precedence, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.GatewayType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - if off == len(msg) { - return off, nil - } - rr.GatewayAddr, rr.GatewayHost, off, err = unpackIPSECGateway(msg, off, rr.GatewayType) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - return off, nil -} - -func (rr *APL) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Prefixes, off, err = unpackDataApl(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *AVC) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CAA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Flag, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Tag, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Value, off, err = unpackStringOctet(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CDNSKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CDS) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CERT) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Type, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CNAME) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *CSYNC) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Serial, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DHCID) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DLV) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DNAME) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DNSKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *DS) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EID) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EUI48) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Address, off, err = unpackUint48(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *EUI64) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Address, off, err = unpackUint64(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *GID) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Gid, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *GPOS) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Longitude, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Latitude, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Altitude, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HINFO) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Cpu, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Os, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.HitLength, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKeyLength, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength)) - if err != nil { - return off, err - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength)) - if err != nil { - return off, err - } - rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Value, off, err = unpackDataSVCB(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *IPSECKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Precedence, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.GatewayType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - if off == len(msg) { - return off, nil - } - rr.GatewayAddr, rr.GatewayHost, off, err = unpackIPSECGateway(msg, off, rr.GatewayType) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ISDN) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Address, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.SubAddress, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *KX) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Exchanger, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *L32) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Locator32, off, err = unpackDataA(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *L64) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Locator64, off, err = unpackUint64(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *LOC) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Version, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Size, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.HorizPre, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.VertPre, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Latitude, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Longitude, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Altitude, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *LP) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Fqdn, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MB) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Mb, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MD) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Md, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MF) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Mf, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MG) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Mg, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MINFO) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Rmail, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Email, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MR) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Mr, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *MX) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Mx, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NAPTR) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Order, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Flags, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Service, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Regexp, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Replacement, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NID) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.NodeID, off, err = unpackUint64(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NIMLOC) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NINFO) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.ZSData, off, err = unpackStringTxt(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NS) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Ns, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSAPPTR) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Ptr, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.NextDomain, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC3) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Hash, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Flags, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Iterations, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.SaltLength, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) - if err != nil { - return off, err - } - rr.HashLength, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength)) - if err != nil { - return off, err - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NSEC3PARAM) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Hash, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Flags, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Iterations, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.SaltLength, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Data, off, err = unpackStringAny(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *NXT) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.NextDomain, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *OPENPGPKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *OPT) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Option, off, err = unpackDataOpt(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *PTR) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Ptr, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *PX) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Map822, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Mapx400, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RFC3597) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RP) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Mbox, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Txt, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RRSIG) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.TypeCovered, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Labels, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.OrigTtl, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.SignerName, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *RT) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Host, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SIG) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.TypeCovered, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Labels, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.OrigTtl, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.SignerName, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SMIMEA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Usage, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Selector, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.MatchingType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SOA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Ns, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Mbox, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Serial, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Refresh, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Retry, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Expire, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Minttl, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SPF) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SRV) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Weight, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Port, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Type, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *SVCB) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Value, off, err = unpackDataSVCB(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TALINK) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.PreviousName, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.NextName, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TKEY) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Mode, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Error, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.KeySize, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Key, off, err = unpackStringHex(msg, off, off+int(rr.KeySize)) - if err != nil { - return off, err - } - rr.OtherLen, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TLSA) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Usage, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Selector, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.MatchingType, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TSIG) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = UnpackDomainName(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.TimeSigned, off, err = unpackUint48(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Fudge, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.MACSize, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize)) - if err != nil { - return off, err - } - rr.OrigId, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Error, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.OtherLen, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen)) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *TXT) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *UID) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Uid, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *UINFO) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Uinfo, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *URI) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Weight, off, err = unpackUint16(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Target, off, err = unpackStringOctet(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.PSDNAddress, off, err = unpackString(msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func (rr *ZONEMD) unpack(msg []byte, off int) (off1 int, err error) { - rdStart := off - _ = rdStart - - rr.Serial, off, err = unpackUint32(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Scheme, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Hash, off, err = unpackUint8(msg, off) - if err != nil { - return off, err - } - if off == len(msg) { - return off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go deleted file mode 100644 index 2c70fc4..0000000 --- a/vendor/github.com/miekg/dns/ztypes.go +++ /dev/null @@ -1,1326 +0,0 @@ -// Code generated by "go run types_generate.go"; DO NOT EDIT. - -package dns - -import ( - "encoding/base64" - "net" -) - -// TypeToRR is a map of constructors for each RR type. -var TypeToRR = map[uint16]func() RR{ - TypeA: func() RR { return new(A) }, - TypeAAAA: func() RR { return new(AAAA) }, - TypeAFSDB: func() RR { return new(AFSDB) }, - TypeAMTRELAY: func() RR { return new(AMTRELAY) }, - TypeANY: func() RR { return new(ANY) }, - TypeAPL: func() RR { return new(APL) }, - TypeAVC: func() RR { return new(AVC) }, - TypeCAA: func() RR { return new(CAA) }, - TypeCDNSKEY: func() RR { return new(CDNSKEY) }, - TypeCDS: func() RR { return new(CDS) }, - TypeCERT: func() RR { return new(CERT) }, - TypeCNAME: func() RR { return new(CNAME) }, - TypeCSYNC: func() RR { return new(CSYNC) }, - TypeDHCID: func() RR { return new(DHCID) }, - TypeDLV: func() RR { return new(DLV) }, - TypeDNAME: func() RR { return new(DNAME) }, - TypeDNSKEY: func() RR { return new(DNSKEY) }, - TypeDS: func() RR { return new(DS) }, - TypeEID: func() RR { return new(EID) }, - TypeEUI48: func() RR { return new(EUI48) }, - TypeEUI64: func() RR { return new(EUI64) }, - TypeGID: func() RR { return new(GID) }, - TypeGPOS: func() RR { return new(GPOS) }, - TypeHINFO: func() RR { return new(HINFO) }, - TypeHIP: func() RR { return new(HIP) }, - TypeHTTPS: func() RR { return new(HTTPS) }, - TypeIPSECKEY: func() RR { return new(IPSECKEY) }, - TypeISDN: func() RR { return new(ISDN) }, - TypeKEY: func() RR { return new(KEY) }, - TypeKX: func() RR { return new(KX) }, - TypeL32: func() RR { return new(L32) }, - TypeL64: func() RR { return new(L64) }, - TypeLOC: func() RR { return new(LOC) }, - TypeLP: func() RR { return new(LP) }, - TypeMB: func() RR { return new(MB) }, - TypeMD: func() RR { return new(MD) }, - TypeMF: func() RR { return new(MF) }, - TypeMG: func() RR { return new(MG) }, - TypeMINFO: func() RR { return new(MINFO) }, - TypeMR: func() RR { return new(MR) }, - TypeMX: func() RR { return new(MX) }, - TypeNAPTR: func() RR { return new(NAPTR) }, - TypeNID: func() RR { return new(NID) }, - TypeNIMLOC: func() RR { return new(NIMLOC) }, - TypeNINFO: func() RR { return new(NINFO) }, - TypeNS: func() RR { return new(NS) }, - TypeNSAPPTR: func() RR { return new(NSAPPTR) }, - TypeNSEC: func() RR { return new(NSEC) }, - TypeNSEC3: func() RR { return new(NSEC3) }, - TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) }, - TypeNULL: func() RR { return new(NULL) }, - TypeNXT: func() RR { return new(NXT) }, - TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) }, - TypeOPT: func() RR { return new(OPT) }, - TypePTR: func() RR { return new(PTR) }, - TypePX: func() RR { return new(PX) }, - TypeRKEY: func() RR { return new(RKEY) }, - TypeRP: func() RR { return new(RP) }, - TypeRRSIG: func() RR { return new(RRSIG) }, - TypeRT: func() RR { return new(RT) }, - TypeSIG: func() RR { return new(SIG) }, - TypeSMIMEA: func() RR { return new(SMIMEA) }, - TypeSOA: func() RR { return new(SOA) }, - TypeSPF: func() RR { return new(SPF) }, - TypeSRV: func() RR { return new(SRV) }, - TypeSSHFP: func() RR { return new(SSHFP) }, - TypeSVCB: func() RR { return new(SVCB) }, - TypeTA: func() RR { return new(TA) }, - TypeTALINK: func() RR { return new(TALINK) }, - TypeTKEY: func() RR { return new(TKEY) }, - TypeTLSA: func() RR { return new(TLSA) }, - TypeTSIG: func() RR { return new(TSIG) }, - TypeTXT: func() RR { return new(TXT) }, - TypeUID: func() RR { return new(UID) }, - TypeUINFO: func() RR { return new(UINFO) }, - TypeURI: func() RR { return new(URI) }, - TypeX25: func() RR { return new(X25) }, - TypeZONEMD: func() RR { return new(ZONEMD) }, -} - -// TypeToString is a map of strings for each RR type. -var TypeToString = map[uint16]string{ - TypeA: "A", - TypeAAAA: "AAAA", - TypeAFSDB: "AFSDB", - TypeAMTRELAY: "AMTRELAY", - TypeANY: "ANY", - TypeAPL: "APL", - TypeATMA: "ATMA", - TypeAVC: "AVC", - TypeAXFR: "AXFR", - TypeCAA: "CAA", - TypeCDNSKEY: "CDNSKEY", - TypeCDS: "CDS", - TypeCERT: "CERT", - TypeCNAME: "CNAME", - TypeCSYNC: "CSYNC", - TypeDHCID: "DHCID", - TypeDLV: "DLV", - TypeDNAME: "DNAME", - TypeDNSKEY: "DNSKEY", - TypeDS: "DS", - TypeEID: "EID", - TypeEUI48: "EUI48", - TypeEUI64: "EUI64", - TypeGID: "GID", - TypeGPOS: "GPOS", - TypeHINFO: "HINFO", - TypeHIP: "HIP", - TypeHTTPS: "HTTPS", - TypeIPSECKEY: "IPSECKEY", - TypeISDN: "ISDN", - TypeIXFR: "IXFR", - TypeKEY: "KEY", - TypeKX: "KX", - TypeL32: "L32", - TypeL64: "L64", - TypeLOC: "LOC", - TypeLP: "LP", - TypeMAILA: "MAILA", - TypeMAILB: "MAILB", - TypeMB: "MB", - TypeMD: "MD", - TypeMF: "MF", - TypeMG: "MG", - TypeMINFO: "MINFO", - TypeMR: "MR", - TypeMX: "MX", - TypeNAPTR: "NAPTR", - TypeNID: "NID", - TypeNIMLOC: "NIMLOC", - TypeNINFO: "NINFO", - TypeNS: "NS", - TypeNSEC: "NSEC", - TypeNSEC3: "NSEC3", - TypeNSEC3PARAM: "NSEC3PARAM", - TypeNULL: "NULL", - TypeNXT: "NXT", - TypeNone: "None", - TypeOPENPGPKEY: "OPENPGPKEY", - TypeOPT: "OPT", - TypePTR: "PTR", - TypePX: "PX", - TypeRKEY: "RKEY", - TypeRP: "RP", - TypeRRSIG: "RRSIG", - TypeRT: "RT", - TypeReserved: "Reserved", - TypeSIG: "SIG", - TypeSMIMEA: "SMIMEA", - TypeSOA: "SOA", - TypeSPF: "SPF", - TypeSRV: "SRV", - TypeSSHFP: "SSHFP", - TypeSVCB: "SVCB", - TypeTA: "TA", - TypeTALINK: "TALINK", - TypeTKEY: "TKEY", - TypeTLSA: "TLSA", - TypeTSIG: "TSIG", - TypeTXT: "TXT", - TypeUID: "UID", - TypeUINFO: "UINFO", - TypeUNSPEC: "UNSPEC", - TypeURI: "URI", - TypeX25: "X25", - TypeZONEMD: "ZONEMD", - TypeNSAPPTR: "NSAP-PTR", -} - -func (rr *A) Header() *RR_Header { return &rr.Hdr } -func (rr *AAAA) Header() *RR_Header { return &rr.Hdr } -func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr } -func (rr *AMTRELAY) Header() *RR_Header { return &rr.Hdr } -func (rr *ANY) Header() *RR_Header { return &rr.Hdr } -func (rr *APL) Header() *RR_Header { return &rr.Hdr } -func (rr *AVC) Header() *RR_Header { return &rr.Hdr } -func (rr *CAA) Header() *RR_Header { return &rr.Hdr } -func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *CDS) Header() *RR_Header { return &rr.Hdr } -func (rr *CERT) Header() *RR_Header { return &rr.Hdr } -func (rr *CNAME) Header() *RR_Header { return &rr.Hdr } -func (rr *CSYNC) Header() *RR_Header { return &rr.Hdr } -func (rr *DHCID) Header() *RR_Header { return &rr.Hdr } -func (rr *DLV) Header() *RR_Header { return &rr.Hdr } -func (rr *DNAME) Header() *RR_Header { return &rr.Hdr } -func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *DS) Header() *RR_Header { return &rr.Hdr } -func (rr *EID) Header() *RR_Header { return &rr.Hdr } -func (rr *EUI48) Header() *RR_Header { return &rr.Hdr } -func (rr *EUI64) Header() *RR_Header { return &rr.Hdr } -func (rr *GID) Header() *RR_Header { return &rr.Hdr } -func (rr *GPOS) Header() *RR_Header { return &rr.Hdr } -func (rr *HINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *HIP) Header() *RR_Header { return &rr.Hdr } -func (rr *HTTPS) Header() *RR_Header { return &rr.Hdr } -func (rr *IPSECKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *ISDN) Header() *RR_Header { return &rr.Hdr } -func (rr *KEY) Header() *RR_Header { return &rr.Hdr } -func (rr *KX) Header() *RR_Header { return &rr.Hdr } -func (rr *L32) Header() *RR_Header { return &rr.Hdr } -func (rr *L64) Header() *RR_Header { return &rr.Hdr } -func (rr *LOC) Header() *RR_Header { return &rr.Hdr } -func (rr *LP) Header() *RR_Header { return &rr.Hdr } -func (rr *MB) Header() *RR_Header { return &rr.Hdr } -func (rr *MD) Header() *RR_Header { return &rr.Hdr } -func (rr *MF) Header() *RR_Header { return &rr.Hdr } -func (rr *MG) Header() *RR_Header { return &rr.Hdr } -func (rr *MINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *MR) Header() *RR_Header { return &rr.Hdr } -func (rr *MX) Header() *RR_Header { return &rr.Hdr } -func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr } -func (rr *NID) Header() *RR_Header { return &rr.Hdr } -func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr } -func (rr *NINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *NS) Header() *RR_Header { return &rr.Hdr } -func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr } -func (rr *NULL) Header() *RR_Header { return &rr.Hdr } -func (rr *NXT) Header() *RR_Header { return &rr.Hdr } -func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *OPT) Header() *RR_Header { return &rr.Hdr } -func (rr *PTR) Header() *RR_Header { return &rr.Hdr } -func (rr *PX) Header() *RR_Header { return &rr.Hdr } -func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr } -func (rr *RKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *RP) Header() *RR_Header { return &rr.Hdr } -func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr } -func (rr *RT) Header() *RR_Header { return &rr.Hdr } -func (rr *SIG) Header() *RR_Header { return &rr.Hdr } -func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr } -func (rr *SOA) Header() *RR_Header { return &rr.Hdr } -func (rr *SPF) Header() *RR_Header { return &rr.Hdr } -func (rr *SRV) Header() *RR_Header { return &rr.Hdr } -func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr } -func (rr *SVCB) Header() *RR_Header { return &rr.Hdr } -func (rr *TA) Header() *RR_Header { return &rr.Hdr } -func (rr *TALINK) Header() *RR_Header { return &rr.Hdr } -func (rr *TKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *TLSA) Header() *RR_Header { return &rr.Hdr } -func (rr *TSIG) Header() *RR_Header { return &rr.Hdr } -func (rr *TXT) Header() *RR_Header { return &rr.Hdr } -func (rr *UID) Header() *RR_Header { return &rr.Hdr } -func (rr *UINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *URI) Header() *RR_Header { return &rr.Hdr } -func (rr *X25) Header() *RR_Header { return &rr.Hdr } -func (rr *ZONEMD) Header() *RR_Header { return &rr.Hdr } - -// len() functions -func (rr *A) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - if len(rr.A) != 0 { - l += net.IPv4len - } - return l -} - -func (rr *AAAA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - if len(rr.AAAA) != 0 { - l += net.IPv6len - } - return l -} - -func (rr *AFSDB) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Subtype - l += domainNameLen(rr.Hostname, off+l, compression, false) - return l -} - -func (rr *AMTRELAY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Precedence - l++ // GatewayType - switch rr.GatewayType { - case AMTRELAYIPv4: - l += net.IPv4len - case AMTRELAYIPv6: - l += net.IPv6len - case AMTRELAYHost: - l += len(rr.GatewayHost) + 1 - } - return l -} - -func (rr *ANY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - return l -} - -func (rr *APL) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, x := range rr.Prefixes { - l += x.len() - } - return l -} - -func (rr *AVC) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} - -func (rr *CAA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Flag - l += len(rr.Tag) + 1 - l += len(rr.Value) - return l -} - -func (rr *CERT) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Type - l += 2 // KeyTag - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.Certificate)) - return l -} - -func (rr *CNAME) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Target, off+l, compression, true) - return l -} - -func (rr *DHCID) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += base64.StdEncoding.DecodedLen(len(rr.Digest)) - return l -} - -func (rr *DNAME) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Target, off+l, compression, false) - return l -} - -func (rr *DNSKEY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Flags - l++ // Protocol - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} - -func (rr *DS) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // KeyTag - l++ // Algorithm - l++ // DigestType - l += len(rr.Digest) / 2 - return l -} - -func (rr *EID) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Endpoint) / 2 - return l -} - -func (rr *EUI48) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 6 // Address - return l -} - -func (rr *EUI64) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 8 // Address - return l -} - -func (rr *GID) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 4 // Gid - return l -} - -func (rr *GPOS) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Longitude) + 1 - l += len(rr.Latitude) + 1 - l += len(rr.Altitude) + 1 - return l -} - -func (rr *HINFO) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Cpu) + 1 - l += len(rr.Os) + 1 - return l -} - -func (rr *HIP) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // HitLength - l++ // PublicKeyAlgorithm - l += 2 // PublicKeyLength - l += len(rr.Hit) / 2 - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - for _, x := range rr.RendezvousServers { - l += domainNameLen(x, off+l, compression, false) - } - return l -} - -func (rr *IPSECKEY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Precedence - l++ // GatewayType - l++ // Algorithm - switch rr.GatewayType { - case IPSECGatewayIPv4: - l += net.IPv4len - case IPSECGatewayIPv6: - l += net.IPv6len - case IPSECGatewayHost: - l += len(rr.GatewayHost) + 1 - } - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} - -func (rr *ISDN) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Address) + 1 - l += len(rr.SubAddress) + 1 - return l -} - -func (rr *KX) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += domainNameLen(rr.Exchanger, off+l, compression, false) - return l -} - -func (rr *L32) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - if len(rr.Locator32) != 0 { - l += net.IPv4len - } - return l -} - -func (rr *L64) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += 8 // Locator64 - return l -} - -func (rr *LOC) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Version - l++ // Size - l++ // HorizPre - l++ // VertPre - l += 4 // Latitude - l += 4 // Longitude - l += 4 // Altitude - return l -} - -func (rr *LP) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += domainNameLen(rr.Fqdn, off+l, compression, false) - return l -} - -func (rr *MB) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Mb, off+l, compression, true) - return l -} - -func (rr *MD) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Md, off+l, compression, true) - return l -} - -func (rr *MF) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Mf, off+l, compression, true) - return l -} - -func (rr *MG) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Mg, off+l, compression, true) - return l -} - -func (rr *MINFO) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Rmail, off+l, compression, true) - l += domainNameLen(rr.Email, off+l, compression, true) - return l -} - -func (rr *MR) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Mr, off+l, compression, true) - return l -} - -func (rr *MX) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += domainNameLen(rr.Mx, off+l, compression, true) - return l -} - -func (rr *NAPTR) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Order - l += 2 // Preference - l += len(rr.Flags) + 1 - l += len(rr.Service) + 1 - l += len(rr.Regexp) + 1 - l += domainNameLen(rr.Replacement, off+l, compression, false) - return l -} - -func (rr *NID) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += 8 // NodeID - return l -} - -func (rr *NIMLOC) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Locator) / 2 - return l -} - -func (rr *NINFO) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, x := range rr.ZSData { - l += len(x) + 1 - } - return l -} - -func (rr *NS) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Ns, off+l, compression, true) - return l -} - -func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Ptr, off+l, compression, false) - return l -} - -func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Hash - l++ // Flags - l += 2 // Iterations - l++ // SaltLength - l += len(rr.Salt) / 2 - return l -} - -func (rr *NULL) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Data) - return l -} - -func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} - -func (rr *PTR) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Ptr, off+l, compression, true) - return l -} - -func (rr *PX) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += domainNameLen(rr.Map822, off+l, compression, false) - l += domainNameLen(rr.Mapx400, off+l, compression, false) - return l -} - -func (rr *RFC3597) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Rdata) / 2 - return l -} - -func (rr *RKEY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Flags - l++ // Protocol - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} - -func (rr *RP) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Mbox, off+l, compression, false) - l += domainNameLen(rr.Txt, off+l, compression, false) - return l -} - -func (rr *RRSIG) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // TypeCovered - l++ // Algorithm - l++ // Labels - l += 4 // OrigTtl - l += 4 // Expiration - l += 4 // Inception - l += 2 // KeyTag - l += domainNameLen(rr.SignerName, off+l, compression, false) - l += base64.StdEncoding.DecodedLen(len(rr.Signature)) - return l -} - -func (rr *RT) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Preference - l += domainNameLen(rr.Host, off+l, compression, false) - return l -} - -func (rr *SMIMEA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Usage - l++ // Selector - l++ // MatchingType - l += len(rr.Certificate) / 2 - return l -} - -func (rr *SOA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Ns, off+l, compression, true) - l += domainNameLen(rr.Mbox, off+l, compression, true) - l += 4 // Serial - l += 4 // Refresh - l += 4 // Retry - l += 4 // Expire - l += 4 // Minttl - return l -} - -func (rr *SPF) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} - -func (rr *SRV) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Priority - l += 2 // Weight - l += 2 // Port - l += domainNameLen(rr.Target, off+l, compression, false) - return l -} - -func (rr *SSHFP) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Algorithm - l++ // Type - l += len(rr.FingerPrint) / 2 - return l -} - -func (rr *SVCB) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Priority - l += domainNameLen(rr.Target, off+l, compression, false) - for _, x := range rr.Value { - l += 4 + int(x.len()) - } - return l -} - -func (rr *TA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // KeyTag - l++ // Algorithm - l++ // DigestType - l += len(rr.Digest) / 2 - return l -} - -func (rr *TALINK) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.PreviousName, off+l, compression, false) - l += domainNameLen(rr.NextName, off+l, compression, false) - return l -} - -func (rr *TKEY) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Algorithm, off+l, compression, false) - l += 4 // Inception - l += 4 // Expiration - l += 2 // Mode - l += 2 // Error - l += 2 // KeySize - l += len(rr.Key) / 2 - l += 2 // OtherLen - l += len(rr.OtherData) / 2 - return l -} - -func (rr *TLSA) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l++ // Usage - l++ // Selector - l++ // MatchingType - l += len(rr.Certificate) / 2 - return l -} - -func (rr *TSIG) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += domainNameLen(rr.Algorithm, off+l, compression, false) - l += 6 // TimeSigned - l += 2 // Fudge - l += 2 // MACSize - l += len(rr.MAC) / 2 - l += 2 // OrigId - l += 2 // Error - l += 2 // OtherLen - l += len(rr.OtherData) / 2 - return l -} - -func (rr *TXT) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} - -func (rr *UID) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 4 // Uid - return l -} - -func (rr *UINFO) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.Uinfo) + 1 - return l -} - -func (rr *URI) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 2 // Priority - l += 2 // Weight - l += len(rr.Target) - return l -} - -func (rr *X25) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += len(rr.PSDNAddress) + 1 - return l -} - -func (rr *ZONEMD) len(off int, compression map[string]struct{}) int { - l := rr.Hdr.len(off, compression) - l += 4 // Serial - l++ // Scheme - l++ // Hash - l += len(rr.Digest) / 2 - return l -} - -// copy() functions -func (rr *A) copy() RR { - return &A{rr.Hdr, cloneSlice(rr.A)} -} - -func (rr *AAAA) copy() RR { - return &AAAA{rr.Hdr, cloneSlice(rr.AAAA)} -} - -func (rr *AFSDB) copy() RR { - return &AFSDB{rr.Hdr, rr.Subtype, rr.Hostname} -} - -func (rr *AMTRELAY) copy() RR { - return &AMTRELAY{ - rr.Hdr, - rr.Precedence, - rr.GatewayType, - cloneSlice(rr.GatewayAddr), - rr.GatewayHost, - } -} - -func (rr *ANY) copy() RR { - return &ANY{rr.Hdr} -} - -func (rr *APL) copy() RR { - Prefixes := make([]APLPrefix, len(rr.Prefixes)) - for i, e := range rr.Prefixes { - Prefixes[i] = e.copy() - } - return &APL{rr.Hdr, Prefixes} -} - -func (rr *AVC) copy() RR { - return &AVC{rr.Hdr, cloneSlice(rr.Txt)} -} - -func (rr *CAA) copy() RR { - return &CAA{ - rr.Hdr, - rr.Flag, - rr.Tag, - rr.Value, - } -} - -func (rr *CDNSKEY) copy() RR { - return &CDNSKEY{*rr.DNSKEY.copy().(*DNSKEY)} -} - -func (rr *CDS) copy() RR { - return &CDS{*rr.DS.copy().(*DS)} -} - -func (rr *CERT) copy() RR { - return &CERT{ - rr.Hdr, - rr.Type, - rr.KeyTag, - rr.Algorithm, - rr.Certificate, - } -} - -func (rr *CNAME) copy() RR { - return &CNAME{rr.Hdr, rr.Target} -} - -func (rr *CSYNC) copy() RR { - return &CSYNC{ - rr.Hdr, - rr.Serial, - rr.Flags, - cloneSlice(rr.TypeBitMap), - } -} - -func (rr *DHCID) copy() RR { - return &DHCID{rr.Hdr, rr.Digest} -} - -func (rr *DLV) copy() RR { - return &DLV{*rr.DS.copy().(*DS)} -} - -func (rr *DNAME) copy() RR { - return &DNAME{rr.Hdr, rr.Target} -} - -func (rr *DNSKEY) copy() RR { - return &DNSKEY{ - rr.Hdr, - rr.Flags, - rr.Protocol, - rr.Algorithm, - rr.PublicKey, - } -} - -func (rr *DS) copy() RR { - return &DS{ - rr.Hdr, - rr.KeyTag, - rr.Algorithm, - rr.DigestType, - rr.Digest, - } -} - -func (rr *EID) copy() RR { - return &EID{rr.Hdr, rr.Endpoint} -} - -func (rr *EUI48) copy() RR { - return &EUI48{rr.Hdr, rr.Address} -} - -func (rr *EUI64) copy() RR { - return &EUI64{rr.Hdr, rr.Address} -} - -func (rr *GID) copy() RR { - return &GID{rr.Hdr, rr.Gid} -} - -func (rr *GPOS) copy() RR { - return &GPOS{ - rr.Hdr, - rr.Longitude, - rr.Latitude, - rr.Altitude, - } -} - -func (rr *HINFO) copy() RR { - return &HINFO{rr.Hdr, rr.Cpu, rr.Os} -} - -func (rr *HIP) copy() RR { - return &HIP{ - rr.Hdr, - rr.HitLength, - rr.PublicKeyAlgorithm, - rr.PublicKeyLength, - rr.Hit, - rr.PublicKey, - cloneSlice(rr.RendezvousServers), - } -} - -func (rr *HTTPS) copy() RR { - return &HTTPS{*rr.SVCB.copy().(*SVCB)} -} - -func (rr *IPSECKEY) copy() RR { - return &IPSECKEY{ - rr.Hdr, - rr.Precedence, - rr.GatewayType, - rr.Algorithm, - cloneSlice(rr.GatewayAddr), - rr.GatewayHost, - rr.PublicKey, - } -} - -func (rr *ISDN) copy() RR { - return &ISDN{rr.Hdr, rr.Address, rr.SubAddress} -} - -func (rr *KEY) copy() RR { - return &KEY{*rr.DNSKEY.copy().(*DNSKEY)} -} - -func (rr *KX) copy() RR { - return &KX{rr.Hdr, rr.Preference, rr.Exchanger} -} - -func (rr *L32) copy() RR { - return &L32{rr.Hdr, rr.Preference, cloneSlice(rr.Locator32)} -} - -func (rr *L64) copy() RR { - return &L64{rr.Hdr, rr.Preference, rr.Locator64} -} - -func (rr *LOC) copy() RR { - return &LOC{ - rr.Hdr, - rr.Version, - rr.Size, - rr.HorizPre, - rr.VertPre, - rr.Latitude, - rr.Longitude, - rr.Altitude, - } -} - -func (rr *LP) copy() RR { - return &LP{rr.Hdr, rr.Preference, rr.Fqdn} -} - -func (rr *MB) copy() RR { - return &MB{rr.Hdr, rr.Mb} -} - -func (rr *MD) copy() RR { - return &MD{rr.Hdr, rr.Md} -} - -func (rr *MF) copy() RR { - return &MF{rr.Hdr, rr.Mf} -} - -func (rr *MG) copy() RR { - return &MG{rr.Hdr, rr.Mg} -} - -func (rr *MINFO) copy() RR { - return &MINFO{rr.Hdr, rr.Rmail, rr.Email} -} - -func (rr *MR) copy() RR { - return &MR{rr.Hdr, rr.Mr} -} - -func (rr *MX) copy() RR { - return &MX{rr.Hdr, rr.Preference, rr.Mx} -} - -func (rr *NAPTR) copy() RR { - return &NAPTR{ - rr.Hdr, - rr.Order, - rr.Preference, - rr.Flags, - rr.Service, - rr.Regexp, - rr.Replacement, - } -} - -func (rr *NID) copy() RR { - return &NID{rr.Hdr, rr.Preference, rr.NodeID} -} - -func (rr *NIMLOC) copy() RR { - return &NIMLOC{rr.Hdr, rr.Locator} -} - -func (rr *NINFO) copy() RR { - return &NINFO{rr.Hdr, cloneSlice(rr.ZSData)} -} - -func (rr *NS) copy() RR { - return &NS{rr.Hdr, rr.Ns} -} - -func (rr *NSAPPTR) copy() RR { - return &NSAPPTR{rr.Hdr, rr.Ptr} -} - -func (rr *NSEC) copy() RR { - return &NSEC{rr.Hdr, rr.NextDomain, cloneSlice(rr.TypeBitMap)} -} - -func (rr *NSEC3) copy() RR { - return &NSEC3{ - rr.Hdr, - rr.Hash, - rr.Flags, - rr.Iterations, - rr.SaltLength, - rr.Salt, - rr.HashLength, - rr.NextDomain, - cloneSlice(rr.TypeBitMap), - } -} - -func (rr *NSEC3PARAM) copy() RR { - return &NSEC3PARAM{ - rr.Hdr, - rr.Hash, - rr.Flags, - rr.Iterations, - rr.SaltLength, - rr.Salt, - } -} - -func (rr *NULL) copy() RR { - return &NULL{rr.Hdr, rr.Data} -} - -func (rr *NXT) copy() RR { - return &NXT{*rr.NSEC.copy().(*NSEC)} -} - -func (rr *OPENPGPKEY) copy() RR { - return &OPENPGPKEY{rr.Hdr, rr.PublicKey} -} - -func (rr *OPT) copy() RR { - Option := make([]EDNS0, len(rr.Option)) - for i, e := range rr.Option { - Option[i] = e.copy() - } - return &OPT{rr.Hdr, Option} -} - -func (rr *PTR) copy() RR { - return &PTR{rr.Hdr, rr.Ptr} -} - -func (rr *PX) copy() RR { - return &PX{ - rr.Hdr, - rr.Preference, - rr.Map822, - rr.Mapx400, - } -} - -func (rr *RFC3597) copy() RR { - return &RFC3597{rr.Hdr, rr.Rdata} -} - -func (rr *RKEY) copy() RR { - return &RKEY{ - rr.Hdr, - rr.Flags, - rr.Protocol, - rr.Algorithm, - rr.PublicKey, - } -} - -func (rr *RP) copy() RR { - return &RP{rr.Hdr, rr.Mbox, rr.Txt} -} - -func (rr *RRSIG) copy() RR { - return &RRSIG{ - rr.Hdr, - rr.TypeCovered, - rr.Algorithm, - rr.Labels, - rr.OrigTtl, - rr.Expiration, - rr.Inception, - rr.KeyTag, - rr.SignerName, - rr.Signature, - } -} - -func (rr *RT) copy() RR { - return &RT{rr.Hdr, rr.Preference, rr.Host} -} - -func (rr *SIG) copy() RR { - return &SIG{*rr.RRSIG.copy().(*RRSIG)} -} - -func (rr *SMIMEA) copy() RR { - return &SMIMEA{ - rr.Hdr, - rr.Usage, - rr.Selector, - rr.MatchingType, - rr.Certificate, - } -} - -func (rr *SOA) copy() RR { - return &SOA{ - rr.Hdr, - rr.Ns, - rr.Mbox, - rr.Serial, - rr.Refresh, - rr.Retry, - rr.Expire, - rr.Minttl, - } -} - -func (rr *SPF) copy() RR { - return &SPF{rr.Hdr, cloneSlice(rr.Txt)} -} - -func (rr *SRV) copy() RR { - return &SRV{ - rr.Hdr, - rr.Priority, - rr.Weight, - rr.Port, - rr.Target, - } -} - -func (rr *SSHFP) copy() RR { - return &SSHFP{ - rr.Hdr, - rr.Algorithm, - rr.Type, - rr.FingerPrint, - } -} - -func (rr *SVCB) copy() RR { - Value := make([]SVCBKeyValue, len(rr.Value)) - for i, e := range rr.Value { - Value[i] = e.copy() - } - return &SVCB{ - rr.Hdr, - rr.Priority, - rr.Target, - Value, - } -} - -func (rr *TA) copy() RR { - return &TA{ - rr.Hdr, - rr.KeyTag, - rr.Algorithm, - rr.DigestType, - rr.Digest, - } -} - -func (rr *TALINK) copy() RR { - return &TALINK{rr.Hdr, rr.PreviousName, rr.NextName} -} - -func (rr *TKEY) copy() RR { - return &TKEY{ - rr.Hdr, - rr.Algorithm, - rr.Inception, - rr.Expiration, - rr.Mode, - rr.Error, - rr.KeySize, - rr.Key, - rr.OtherLen, - rr.OtherData, - } -} - -func (rr *TLSA) copy() RR { - return &TLSA{ - rr.Hdr, - rr.Usage, - rr.Selector, - rr.MatchingType, - rr.Certificate, - } -} - -func (rr *TSIG) copy() RR { - return &TSIG{ - rr.Hdr, - rr.Algorithm, - rr.TimeSigned, - rr.Fudge, - rr.MACSize, - rr.MAC, - rr.OrigId, - rr.Error, - rr.OtherLen, - rr.OtherData, - } -} - -func (rr *TXT) copy() RR { - return &TXT{rr.Hdr, cloneSlice(rr.Txt)} -} - -func (rr *UID) copy() RR { - return &UID{rr.Hdr, rr.Uid} -} - -func (rr *UINFO) copy() RR { - return &UINFO{rr.Hdr, rr.Uinfo} -} - -func (rr *URI) copy() RR { - return &URI{ - rr.Hdr, - rr.Priority, - rr.Weight, - rr.Target, - } -} - -func (rr *X25) copy() RR { - return &X25{rr.Hdr, rr.PSDNAddress} -} - -func (rr *ZONEMD) copy() RR { - return &ZONEMD{ - rr.Hdr, - rr.Serial, - rr.Scheme, - rr.Hash, - rr.Digest, - } -} diff --git a/vendor/github.com/pierrec/lz4/v4/.gitignore b/vendor/github.com/pierrec/lz4/v4/.gitignore deleted file mode 100644 index 5d7e88d..0000000 --- a/vendor/github.com/pierrec/lz4/v4/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# 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 deleted file mode 100644 index bd899d8..0000000 --- a/vendor/github.com/pierrec/lz4/v4/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index dee7754..0000000 --- a/vendor/github.com/pierrec/lz4/v4/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# 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 deleted file mode 100644 index 8df0dc7..0000000 --- a/vendor/github.com/pierrec/lz4/v4/compressing_reader.go +++ /dev/null @@ -1,222 +0,0 @@ -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 deleted file mode 100644 index fec8adb..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/block.go +++ /dev/null @@ -1,481 +0,0 @@ -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 deleted file mode 100644 index 138083d..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/blocks.go +++ /dev/null @@ -1,87 +0,0 @@ -// 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 deleted file mode 100644 index 1d00133..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_amd64.s +++ /dev/null @@ -1,448 +0,0 @@ -// +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 deleted file mode 100644 index 20b21fc..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm.s +++ /dev/null @@ -1,231 +0,0 @@ -// +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 deleted file mode 100644 index d2fe11b..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm64.s +++ /dev/null @@ -1,241 +0,0 @@ -// +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 deleted file mode 100644 index 8d9023d..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_asm.go +++ /dev/null @@ -1,10 +0,0 @@ -//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 deleted file mode 100644 index 9f568fb..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_other.go +++ /dev/null @@ -1,139 +0,0 @@ -//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 deleted file mode 100644 index 710ea42..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4errors/errors.go +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index e964654..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/block.go +++ /dev/null @@ -1,348 +0,0 @@ -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 deleted file mode 100644 index 18192a9..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame.go +++ /dev/null @@ -1,204 +0,0 @@ -// 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 deleted file mode 100644 index d33a6be..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame_gen.go +++ /dev/null @@ -1,103 +0,0 @@ -// 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 deleted file mode 100644 index 651d10c..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero.go +++ /dev/null @@ -1,212 +0,0 @@ -// 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 deleted file mode 100644 index 0978b26..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.go +++ /dev/null @@ -1,11 +0,0 @@ -// +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 deleted file mode 100644 index c18ffd5..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.s +++ /dev/null @@ -1,251 +0,0 @@ -// +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 deleted file mode 100644 index c96b59b..0000000 --- a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_other.go +++ /dev/null @@ -1,10 +0,0 @@ -// +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 deleted file mode 100644 index a62022e..0000000 --- a/vendor/github.com/pierrec/lz4/v4/lz4.go +++ /dev/null @@ -1,157 +0,0 @@ -// 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 deleted file mode 100644 index 57a44e7..0000000 --- a/vendor/github.com/pierrec/lz4/v4/options.go +++ /dev/null @@ -1,242 +0,0 @@ -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 deleted file mode 100644 index 2de8149..0000000 --- a/vendor/github.com/pierrec/lz4/v4/options_gen.go +++ /dev/null @@ -1,92 +0,0 @@ -// 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 deleted file mode 100644 index 275daad..0000000 --- a/vendor/github.com/pierrec/lz4/v4/reader.go +++ /dev/null @@ -1,275 +0,0 @@ -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 deleted file mode 100644 index d94f04d..0000000 --- a/vendor/github.com/pierrec/lz4/v4/state.go +++ /dev/null @@ -1,75 +0,0 @@ -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 deleted file mode 100644 index 75fb828..0000000 --- a/vendor/github.com/pierrec/lz4/v4/state_gen.go +++ /dev/null @@ -1,28 +0,0 @@ -// 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 deleted file mode 100644 index 4358ade..0000000 --- a/vendor/github.com/pierrec/lz4/v4/writer.go +++ /dev/null @@ -1,242 +0,0 @@ -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/pires/go-proxyproto/.gitignore b/vendor/github.com/pires/go-proxyproto/.gitignore new file mode 100644 index 0000000..a2d2c30 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/.gitignore @@ -0,0 +1,11 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +.idea +bin +pkg + +*.out diff --git a/vendor/github.com/google/nftables/LICENSE b/vendor/github.com/pires/go-proxyproto/LICENSE similarity index 99% rename from vendor/github.com/google/nftables/LICENSE rename to vendor/github.com/pires/go-proxyproto/LICENSE index d645695..a65c05a 100644 --- a/vendor/github.com/google/nftables/LICENSE +++ b/vendor/github.com/pires/go-proxyproto/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -179,7 +178,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -187,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2016 Paulo Pires Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/pires/go-proxyproto/README.md b/vendor/github.com/pires/go-proxyproto/README.md new file mode 100644 index 0000000..982707c --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/README.md @@ -0,0 +1,162 @@ +# go-proxyproto + +[![Actions Status](https://github.com/pires/go-proxyproto/workflows/test/badge.svg)](https://github.com/pires/go-proxyproto/actions) +[![Coverage Status](https://coveralls.io/repos/github/pires/go-proxyproto/badge.svg?branch=master)](https://coveralls.io/github/pires/go-proxyproto?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/pires/go-proxyproto)](https://goreportcard.com/report/github.com/pires/go-proxyproto) +[![](https://godoc.org/github.com/pires/go-proxyproto?status.svg)](https://pkg.go.dev/github.com/pires/go-proxyproto?tab=doc) + + +A Go library implementation of the [PROXY protocol, versions 1 and 2](https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt), +which provides, as per specification: +> (...) a convenient way to safely transport connection +> information such as a client's address across multiple layers of NAT or TCP +> proxies. It is designed to require little changes to existing components and +> to limit the performance impact caused by the processing of the transported +> information. + +This library is to be used in one of or both proxy clients and proxy servers that need to support said protocol. +Both protocol versions, 1 (text-based) and 2 (binary-based) are supported. + +## Installation + +```shell +$ go get -u github.com/pires/go-proxyproto +``` + +## Usage + +### Client + +```go +package main + +import ( + "io" + "log" + "net" + + proxyproto "github.com/pires/go-proxyproto" +) + +func chkErr(err error) { + if err != nil { + log.Fatalf("Error: %s", err.Error()) + } +} + +func main() { + // Dial some proxy listener e.g. https://github.com/mailgun/proxyproto + target, err := net.ResolveTCPAddr("tcp", "127.0.0.1:2319") + chkErr(err) + + conn, err := net.DialTCP("tcp", nil, target) + chkErr(err) + + defer conn.Close() + + // Create a proxyprotocol header or use HeaderProxyFromAddrs() if you + // have two conn's + header := &proxyproto.Header{ + Version: 1, + Command: proxyproto.PROXY, + TransportProtocol: proxyproto.TCPv4, + SourceAddr: &net.TCPAddr{ + IP: net.ParseIP("10.1.1.1"), + Port: 1000, + }, + DestinationAddr: &net.TCPAddr{ + IP: net.ParseIP("20.2.2.2"), + Port: 2000, + }, + } + // After the connection was created write the proxy headers first + _, err = header.WriteTo(conn) + chkErr(err) + // Then your data... e.g.: + _, err = io.WriteString(conn, "HELO") + chkErr(err) +} +``` + +### Server + +```go +package main + +import ( + "log" + "net" + + proxyproto "github.com/pires/go-proxyproto" +) + +func main() { + // Create a listener + addr := "localhost:9876" + list, err := net.Listen("tcp", addr) + if err != nil { + log.Fatalf("couldn't listen to %q: %q\n", addr, err.Error()) + } + + // Wrap listener in a proxyproto listener + proxyListener := &proxyproto.Listener{Listener: list} + defer proxyListener.Close() + + // Wait for a connection and accept it + conn, err := proxyListener.Accept() + defer conn.Close() + + // Print connection details + if conn.LocalAddr() == nil { + log.Fatal("couldn't retrieve local address") + } + log.Printf("local address: %q", conn.LocalAddr().String()) + + if conn.RemoteAddr() == nil { + log.Fatal("couldn't retrieve remote address") + } + log.Printf("remote address: %q", conn.RemoteAddr().String()) +} +``` + +### HTTP Server +```go +package main + +import ( + "net" + "net/http" + "time" + + "github.com/pires/go-proxyproto" +) + +func main() { + server := http.Server{ + Addr: ":8080", + } + + ln, err := net.Listen("tcp", server.Addr) + if err != nil { + panic(err) + } + + proxyListener := &proxyproto.Listener{ + Listener: ln, + ReadHeaderTimeout: 10 * time.Second, + } + defer proxyListener.Close() + + server.Serve(proxyListener) +} +``` + +## Special notes + +### AWS + +AWS Network Load Balancer (NLB) does not push the PPV2 header until the client starts sending the data. This is a problem if your server speaks first. e.g. SMTP, FTP, SSH etc. + +By default, NLB target group attribute `proxy_protocol_v2.client_to_server.header_placement` has the value `on_first_ack_with_payload`. You need to contact AWS support to change it to `on_first_ack`, instead. + +Just to be clear, you need this fix only if your server is designed to speak first. diff --git a/vendor/github.com/pires/go-proxyproto/addr_proto.go b/vendor/github.com/pires/go-proxyproto/addr_proto.go new file mode 100644 index 0000000..d254fc4 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/addr_proto.go @@ -0,0 +1,62 @@ +package proxyproto + +// AddressFamilyAndProtocol represents address family and transport protocol. +type AddressFamilyAndProtocol byte + +const ( + UNSPEC AddressFamilyAndProtocol = '\x00' + TCPv4 AddressFamilyAndProtocol = '\x11' + UDPv4 AddressFamilyAndProtocol = '\x12' + TCPv6 AddressFamilyAndProtocol = '\x21' + UDPv6 AddressFamilyAndProtocol = '\x22' + UnixStream AddressFamilyAndProtocol = '\x31' + UnixDatagram AddressFamilyAndProtocol = '\x32' +) + +// IsIPv4 returns true if the address family is IPv4 (AF_INET4), false otherwise. +func (ap AddressFamilyAndProtocol) IsIPv4() bool { + return ap&0xF0 == 0x10 +} + +// IsIPv6 returns true if the address family is IPv6 (AF_INET6), false otherwise. +func (ap AddressFamilyAndProtocol) IsIPv6() bool { + return ap&0xF0 == 0x20 +} + +// IsUnix returns true if the address family is UNIX (AF_UNIX), false otherwise. +func (ap AddressFamilyAndProtocol) IsUnix() bool { + return ap&0xF0 == 0x30 +} + +// IsStream returns true if the transport protocol is TCP or STREAM (SOCK_STREAM), false otherwise. +func (ap AddressFamilyAndProtocol) IsStream() bool { + return ap&0x0F == 0x01 +} + +// IsDatagram returns true if the transport protocol is UDP or DGRAM (SOCK_DGRAM), false otherwise. +func (ap AddressFamilyAndProtocol) IsDatagram() bool { + return ap&0x0F == 0x02 +} + +// IsUnspec returns true if the transport protocol or address family is unspecified, false otherwise. +func (ap AddressFamilyAndProtocol) IsUnspec() bool { + return (ap&0xF0 == 0x00) || (ap&0x0F == 0x00) +} + +func (ap AddressFamilyAndProtocol) toByte() byte { + if ap.IsIPv4() && ap.IsStream() { + return byte(TCPv4) + } else if ap.IsIPv4() && ap.IsDatagram() { + return byte(UDPv4) + } else if ap.IsIPv6() && ap.IsStream() { + return byte(TCPv6) + } else if ap.IsIPv6() && ap.IsDatagram() { + return byte(UDPv6) + } else if ap.IsUnix() && ap.IsStream() { + return byte(UnixStream) + } else if ap.IsUnix() && ap.IsDatagram() { + return byte(UnixDatagram) + } + + return byte(UNSPEC) +} diff --git a/vendor/github.com/pires/go-proxyproto/header.go b/vendor/github.com/pires/go-proxyproto/header.go new file mode 100644 index 0000000..209c2cc --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/header.go @@ -0,0 +1,280 @@ +// Package proxyproto implements Proxy Protocol (v1 and v2) parser and writer, as per specification: +// https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt +package proxyproto + +import ( + "bufio" + "bytes" + "errors" + "io" + "net" + "time" +) + +var ( + // Protocol + SIGV1 = []byte{'\x50', '\x52', '\x4F', '\x58', '\x59'} + SIGV2 = []byte{'\x0D', '\x0A', '\x0D', '\x0A', '\x00', '\x0D', '\x0A', '\x51', '\x55', '\x49', '\x54', '\x0A'} + + ErrCantReadVersion1Header = errors.New("proxyproto: can't read version 1 header") + ErrVersion1HeaderTooLong = errors.New("proxyproto: version 1 header must be 107 bytes or less") + ErrLineMustEndWithCrlf = errors.New("proxyproto: version 1 header is invalid, must end with \\r\\n") + ErrCantReadProtocolVersionAndCommand = errors.New("proxyproto: can't read proxy protocol version and command") + ErrCantReadAddressFamilyAndProtocol = errors.New("proxyproto: can't read address family or protocol") + ErrCantReadLength = errors.New("proxyproto: can't read length") + ErrCantResolveSourceUnixAddress = errors.New("proxyproto: can't resolve source Unix address") + ErrCantResolveDestinationUnixAddress = errors.New("proxyproto: can't resolve destination Unix address") + ErrNoProxyProtocol = errors.New("proxyproto: proxy protocol signature not present") + ErrUnknownProxyProtocolVersion = errors.New("proxyproto: unknown proxy protocol version") + ErrUnsupportedProtocolVersionAndCommand = errors.New("proxyproto: unsupported proxy protocol version and command") + ErrUnsupportedAddressFamilyAndProtocol = errors.New("proxyproto: unsupported address family and protocol") + ErrInvalidLength = errors.New("proxyproto: invalid length") + ErrInvalidAddress = errors.New("proxyproto: invalid address") + ErrInvalidPortNumber = errors.New("proxyproto: invalid port number") + ErrSuperfluousProxyHeader = errors.New("proxyproto: upstream connection sent PROXY header but isn't allowed to send one") +) + +// Header is the placeholder for proxy protocol header. +type Header struct { + Version byte + Command ProtocolVersionAndCommand + TransportProtocol AddressFamilyAndProtocol + SourceAddr net.Addr + DestinationAddr net.Addr + rawTLVs []byte +} + +// HeaderProxyFromAddrs creates a new PROXY header from a source and a +// destination address. If version is zero, the latest protocol version is +// used. +// +// The header is filled on a best-effort basis: if hints cannot be inferred +// from the provided addresses, the header will be left unspecified. +func HeaderProxyFromAddrs(version byte, sourceAddr, destAddr net.Addr) *Header { + if version < 1 || version > 2 { + version = 2 + } + h := &Header{ + Version: version, + Command: LOCAL, + TransportProtocol: UNSPEC, + } + switch sourceAddr := sourceAddr.(type) { + case *net.TCPAddr: + if _, ok := destAddr.(*net.TCPAddr); !ok { + break + } + if len(sourceAddr.IP.To4()) == net.IPv4len { + h.TransportProtocol = TCPv4 + } else if len(sourceAddr.IP) == net.IPv6len { + h.TransportProtocol = TCPv6 + } + case *net.UDPAddr: + if _, ok := destAddr.(*net.UDPAddr); !ok { + break + } + if len(sourceAddr.IP.To4()) == net.IPv4len { + h.TransportProtocol = UDPv4 + } else if len(sourceAddr.IP) == net.IPv6len { + h.TransportProtocol = UDPv6 + } + case *net.UnixAddr: + if _, ok := destAddr.(*net.UnixAddr); !ok { + break + } + switch sourceAddr.Net { + case "unix": + h.TransportProtocol = UnixStream + case "unixgram": + h.TransportProtocol = UnixDatagram + } + } + if h.TransportProtocol != UNSPEC { + h.Command = PROXY + h.SourceAddr = sourceAddr + h.DestinationAddr = destAddr + } + return h +} + +func (header *Header) TCPAddrs() (sourceAddr, destAddr *net.TCPAddr, ok bool) { + if !header.TransportProtocol.IsStream() { + return nil, nil, false + } + sourceAddr, sourceOK := header.SourceAddr.(*net.TCPAddr) + destAddr, destOK := header.DestinationAddr.(*net.TCPAddr) + return sourceAddr, destAddr, sourceOK && destOK +} + +func (header *Header) UDPAddrs() (sourceAddr, destAddr *net.UDPAddr, ok bool) { + if !header.TransportProtocol.IsDatagram() { + return nil, nil, false + } + sourceAddr, sourceOK := header.SourceAddr.(*net.UDPAddr) + destAddr, destOK := header.DestinationAddr.(*net.UDPAddr) + return sourceAddr, destAddr, sourceOK && destOK +} + +func (header *Header) UnixAddrs() (sourceAddr, destAddr *net.UnixAddr, ok bool) { + if !header.TransportProtocol.IsUnix() { + return nil, nil, false + } + sourceAddr, sourceOK := header.SourceAddr.(*net.UnixAddr) + destAddr, destOK := header.DestinationAddr.(*net.UnixAddr) + return sourceAddr, destAddr, sourceOK && destOK +} + +func (header *Header) IPs() (sourceIP, destIP net.IP, ok bool) { + if sourceAddr, destAddr, ok := header.TCPAddrs(); ok { + return sourceAddr.IP, destAddr.IP, true + } else if sourceAddr, destAddr, ok := header.UDPAddrs(); ok { + return sourceAddr.IP, destAddr.IP, true + } else { + return nil, nil, false + } +} + +func (header *Header) Ports() (sourcePort, destPort int, ok bool) { + if sourceAddr, destAddr, ok := header.TCPAddrs(); ok { + return sourceAddr.Port, destAddr.Port, true + } else if sourceAddr, destAddr, ok := header.UDPAddrs(); ok { + return sourceAddr.Port, destAddr.Port, true + } else { + return 0, 0, false + } +} + +// EqualTo returns true if headers are equivalent, false otherwise. +// Deprecated: use EqualsTo instead. This method will eventually be removed. +func (header *Header) EqualTo(otherHeader *Header) bool { + return header.EqualsTo(otherHeader) +} + +// EqualsTo returns true if headers are equivalent, false otherwise. +func (header *Header) EqualsTo(otherHeader *Header) bool { + if otherHeader == nil { + return false + } + if header.Version != otherHeader.Version || header.Command != otherHeader.Command || header.TransportProtocol != otherHeader.TransportProtocol { + return false + } + // TLVs only exist for version 2 + if header.Version == 2 && !bytes.Equal(header.rawTLVs, otherHeader.rawTLVs) { + return false + } + // Return early for header with LOCAL command, which contains no address information + if header.Command == LOCAL { + return true + } + return header.SourceAddr.String() == otherHeader.SourceAddr.String() && + header.DestinationAddr.String() == otherHeader.DestinationAddr.String() +} + +// WriteTo renders a proxy protocol header in a format and writes it to an io.Writer. +func (header *Header) WriteTo(w io.Writer) (int64, error) { + buf, err := header.Format() + if err != nil { + return 0, err + } + + return bytes.NewBuffer(buf).WriteTo(w) +} + +// Format renders a proxy protocol header in a format to write over the wire. +func (header *Header) Format() ([]byte, error) { + switch header.Version { + case 1: + return header.formatVersion1() + case 2: + return header.formatVersion2() + default: + return nil, ErrUnknownProxyProtocolVersion + } +} + +// TLVs returns the TLVs stored into this header, if they exist. TLVs are optional for v2 of the protocol. +func (header *Header) TLVs() ([]TLV, error) { + return SplitTLVs(header.rawTLVs) +} + +// SetTLVs sets the TLVs stored in this header. This method replaces any +// previous TLV. +func (header *Header) SetTLVs(tlvs []TLV) error { + raw, err := JoinTLVs(tlvs) + if err != nil { + return err + } + header.rawTLVs = raw + return nil +} + +// Read identifies the proxy protocol version and reads the remaining of +// the header, accordingly. +// +// If proxy protocol header signature is not present, the reader buffer remains untouched +// and is safe for reading outside of this code. +// +// If proxy protocol header signature is present but an error is raised while processing +// the remaining header, assume the reader buffer to be in a corrupt state. +// Also, this operation will block until enough bytes are available for peeking. +func Read(reader *bufio.Reader) (*Header, error) { + // In order to improve speed for small non-PROXYed packets, take a peek at the first byte alone. + b1, err := reader.Peek(1) + if err != nil { + if err == io.EOF { + return nil, ErrNoProxyProtocol + } + return nil, err + } + + if bytes.Equal(b1[:1], SIGV1[:1]) || bytes.Equal(b1[:1], SIGV2[:1]) { + signature, err := reader.Peek(5) + if err != nil { + if err == io.EOF { + return nil, ErrNoProxyProtocol + } + return nil, err + } + if bytes.Equal(signature[:5], SIGV1) { + return parseVersion1(reader) + } + + signature, err = reader.Peek(12) + if err != nil { + if err == io.EOF { + return nil, ErrNoProxyProtocol + } + return nil, err + } + if bytes.Equal(signature[:12], SIGV2) { + return parseVersion2(reader) + } + } + + return nil, ErrNoProxyProtocol +} + +// ReadTimeout acts as Read but takes a timeout. If that timeout is reached, it's assumed +// there's no proxy protocol header. +func ReadTimeout(reader *bufio.Reader, timeout time.Duration) (*Header, error) { + type header struct { + h *Header + e error + } + read := make(chan *header, 1) + + go func() { + h := &header{} + h.h, h.e = Read(reader) + read <- h + }() + + timer := time.NewTimer(timeout) + select { + case result := <-read: + timer.Stop() + return result.h, result.e + case <-timer.C: + return nil, ErrNoProxyProtocol + } +} diff --git a/vendor/github.com/pires/go-proxyproto/policy.go b/vendor/github.com/pires/go-proxyproto/policy.go new file mode 100644 index 0000000..ebef8b9 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/policy.go @@ -0,0 +1,206 @@ +package proxyproto + +import ( + "fmt" + "net" + "strings" +) + +// PolicyFunc can be used to decide whether to trust the PROXY info from +// upstream. If set, the connecting address is passed in as an argument. +// +// See below for the different policies. +// +// In case an error is returned the connection is denied. +type PolicyFunc func(upstream net.Addr) (Policy, error) + +// ConnPolicyFunc can be used to decide whether to trust the PROXY info +// based on connection policy options. If set, the connecting addresses +// (remote and local) are passed in as argument. +// +// See below for the different policies. +// +// In case an error is returned the connection is denied. +type ConnPolicyFunc func(connPolicyOptions ConnPolicyOptions) (Policy, error) + +// ConnPolicyOptions contains the remote and local addresses of a connection. +type ConnPolicyOptions struct { + Upstream net.Addr + Downstream net.Addr +} + +// Policy defines how a connection with a PROXY header address is treated. +type Policy int + +const ( + // USE address from PROXY header + USE Policy = iota + // IGNORE address from PROXY header, but accept connection + IGNORE + // REJECT connection when PROXY header is sent + // Note: even though the first read on the connection returns an error if + // a PROXY header is present, subsequent reads do not. It is the task of + // the code using the connection to handle that case properly. + REJECT + // REQUIRE connection to send PROXY header, reject if not present + // Note: even though the first read on the connection returns an error if + // a PROXY header is not present, subsequent reads do not. It is the task + // of the code using the connection to handle that case properly. + REQUIRE + // SKIP accepts a connection without requiring the PROXY header + // Note: an example usage can be found in the SkipProxyHeaderForCIDR + // function. + SKIP +) + +// SkipProxyHeaderForCIDR returns a PolicyFunc which can be used to accept a +// connection from a skipHeaderCIDR without requiring a PROXY header, e.g. +// Kubernetes pods local traffic. The def is a policy to use when an upstream +// address doesn't match the skipHeaderCIDR. +func SkipProxyHeaderForCIDR(skipHeaderCIDR *net.IPNet, def Policy) PolicyFunc { + return func(upstream net.Addr) (Policy, error) { + ip, err := ipFromAddr(upstream) + if err != nil { + return def, err + } + + if skipHeaderCIDR != nil && skipHeaderCIDR.Contains(ip) { + return SKIP, nil + } + + return def, nil + } +} + +// WithPolicy adds given policy to a connection when passed as option to NewConn() +func WithPolicy(p Policy) func(*Conn) { + return func(c *Conn) { + c.ProxyHeaderPolicy = p + } +} + +// LaxWhiteListPolicy returns a PolicyFunc which decides whether the +// upstream ip is allowed to send a proxy header based on a list of allowed +// IP addresses and IP ranges. In case upstream IP is not in list the proxy +// header will be ignored. If one of the provided IP addresses or IP ranges +// is invalid it will return an error instead of a PolicyFunc. +func LaxWhiteListPolicy(allowed []string) (PolicyFunc, error) { + allowFrom, err := parse(allowed) + if err != nil { + return nil, err + } + + return whitelistPolicy(allowFrom, IGNORE), nil +} + +// MustLaxWhiteListPolicy returns a LaxWhiteListPolicy but will panic if one +// of the provided IP addresses or IP ranges is invalid. +func MustLaxWhiteListPolicy(allowed []string) PolicyFunc { + pfunc, err := LaxWhiteListPolicy(allowed) + if err != nil { + panic(err) + } + + return pfunc +} + +// StrictWhiteListPolicy returns a PolicyFunc which decides whether the +// upstream ip is allowed to send a proxy header based on a list of allowed +// IP addresses and IP ranges. In case upstream IP is not in list reading on +// the connection will be refused on the first read. Please note: subsequent +// reads do not error. It is the task of the code using the connection to +// handle that case properly. If one of the provided IP addresses or IP +// ranges is invalid it will return an error instead of a PolicyFunc. +func StrictWhiteListPolicy(allowed []string) (PolicyFunc, error) { + allowFrom, err := parse(allowed) + if err != nil { + return nil, err + } + + return whitelistPolicy(allowFrom, REJECT), nil +} + +// MustStrictWhiteListPolicy returns a StrictWhiteListPolicy but will panic +// if one of the provided IP addresses or IP ranges is invalid. +func MustStrictWhiteListPolicy(allowed []string) PolicyFunc { + pfunc, err := StrictWhiteListPolicy(allowed) + if err != nil { + panic(err) + } + + return pfunc +} + +func whitelistPolicy(allowed []func(net.IP) bool, def Policy) PolicyFunc { + return func(upstream net.Addr) (Policy, error) { + upstreamIP, err := ipFromAddr(upstream) + if err != nil { + // something is wrong with the source IP, better reject the connection + return REJECT, err + } + + for _, allowFrom := range allowed { + if allowFrom(upstreamIP) { + return USE, nil + } + } + + return def, nil + } +} + +func parse(allowed []string) ([]func(net.IP) bool, error) { + a := make([]func(net.IP) bool, len(allowed)) + for i, allowFrom := range allowed { + if strings.LastIndex(allowFrom, "/") > 0 { + _, ipRange, err := net.ParseCIDR(allowFrom) + if err != nil { + return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP range: %v", allowFrom, err) + } + + a[i] = ipRange.Contains + } else { + allowed := net.ParseIP(allowFrom) + if allowed == nil { + return nil, fmt.Errorf("proxyproto: given string %q is not a valid IP address", allowFrom) + } + + a[i] = allowed.Equal + } + } + + return a, nil +} + +func ipFromAddr(upstream net.Addr) (net.IP, error) { + upstreamString, _, err := net.SplitHostPort(upstream.String()) + if err != nil { + return nil, err + } + + upstreamIP := net.ParseIP(upstreamString) + if nil == upstreamIP { + return nil, fmt.Errorf("proxyproto: invalid IP address") + } + + return upstreamIP, nil +} + +// IgnoreProxyHeaderNotOnInterface retuns a ConnPolicyFunc which can be used to +// decide whether to use or ignore PROXY headers depending on the connection +// being made on a specific interface. This policy can be used when the server +// is bound to multiple interfaces but wants to allow on only one interface. +func IgnoreProxyHeaderNotOnInterface(allowedIP net.IP) ConnPolicyFunc { + return func(connOpts ConnPolicyOptions) (Policy, error) { + ip, err := ipFromAddr(connOpts.Downstream) + if err != nil { + return REJECT, err + } + + if allowedIP.Equal(ip) { + return USE, nil + } + + return IGNORE, nil + } +} diff --git a/vendor/github.com/pires/go-proxyproto/protocol.go b/vendor/github.com/pires/go-proxyproto/protocol.go new file mode 100644 index 0000000..93cf7c4 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/protocol.go @@ -0,0 +1,389 @@ +package proxyproto + +import ( + "bufio" + "errors" + "fmt" + "io" + "net" + "sync" + "sync/atomic" + "time" +) + +var ( + // DefaultReadHeaderTimeout is how long header processing waits for header to + // be read from the wire, if Listener.ReaderHeaderTimeout is not set. + // It's kept as a global variable so to make it easier to find and override, + // e.g. go build -ldflags -X "github.com/pires/go-proxyproto.DefaultReadHeaderTimeout=1s" + DefaultReadHeaderTimeout = 10 * time.Second + + // ErrInvalidUpstream should be returned when an upstream connection address + // is not trusted, and therefore is invalid. + ErrInvalidUpstream = fmt.Errorf("proxyproto: upstream connection address not trusted for PROXY information") +) + +// Listener is used to wrap an underlying listener, +// whose connections may be using the HAProxy Proxy Protocol. +// If the connection is using the protocol, the RemoteAddr() will return +// the correct client address. ReadHeaderTimeout will be applied to all +// connections in order to prevent blocking operations. If no ReadHeaderTimeout +// is set, a default of 10s will be used. This can be disabled by setting the +// timeout to < 0. +// +// Only one of Policy or ConnPolicy should be provided. If both are provided then +// a panic would occur during accept. +type Listener struct { + Listener net.Listener + // Deprecated: use ConnPolicyFunc instead. This will be removed in future release. + Policy PolicyFunc + ConnPolicy ConnPolicyFunc + ValidateHeader Validator + ReadHeaderTimeout time.Duration +} + +// Conn is used to wrap and underlying connection which +// may be speaking the Proxy Protocol. If it is, the RemoteAddr() will +// return the address of the client instead of the proxy address. Each connection +// will have its own readHeaderTimeout and readDeadline set by the Accept() call. +type Conn struct { + readDeadline atomic.Value // time.Time + once sync.Once + readErr error + conn net.Conn + bufReader *bufio.Reader + reader io.Reader + header *Header + ProxyHeaderPolicy Policy + Validate Validator + readHeaderTimeout time.Duration +} + +// Validator receives a header and decides whether it is a valid one +// In case the header is not deemed valid it should return an error. +type Validator func(*Header) error + +// ValidateHeader adds given validator for proxy headers to a connection when passed as option to NewConn() +func ValidateHeader(v Validator) func(*Conn) { + return func(c *Conn) { + if v != nil { + c.Validate = v + } + } +} + +// SetReadHeaderTimeout sets the readHeaderTimeout for a connection when passed as option to NewConn() +func SetReadHeaderTimeout(t time.Duration) func(*Conn) { + return func(c *Conn) { + if t >= 0 { + c.readHeaderTimeout = t + } + } +} + +// Accept waits for and returns the next valid connection to the listener. +func (p *Listener) Accept() (net.Conn, error) { + for { + // Get the underlying connection + conn, err := p.Listener.Accept() + if err != nil { + return nil, err + } + + proxyHeaderPolicy := USE + if p.Policy != nil && p.ConnPolicy != nil { + panic("only one of policy or connpolicy must be provided.") + } + if p.Policy != nil || p.ConnPolicy != nil { + if p.Policy != nil { + proxyHeaderPolicy, err = p.Policy(conn.RemoteAddr()) + } else { + proxyHeaderPolicy, err = p.ConnPolicy(ConnPolicyOptions{ + Upstream: conn.RemoteAddr(), + Downstream: conn.LocalAddr(), + }) + } + if err != nil { + // can't decide the policy, we can't accept the connection + conn.Close() + + if errors.Is(err, ErrInvalidUpstream) { + // keep listening for other connections + continue + } + + return nil, err + } + // Handle a connection as a regular one + if proxyHeaderPolicy == SKIP { + return conn, nil + } + } + + newConn := NewConn( + conn, + WithPolicy(proxyHeaderPolicy), + ValidateHeader(p.ValidateHeader), + ) + + // If the ReadHeaderTimeout for the listener is unset, use the default timeout. + if p.ReadHeaderTimeout == 0 { + p.ReadHeaderTimeout = DefaultReadHeaderTimeout + } + + // Set the readHeaderTimeout of the new conn to the value of the listener + newConn.readHeaderTimeout = p.ReadHeaderTimeout + + return newConn, nil + } +} + +// Close closes the underlying listener. +func (p *Listener) Close() error { + return p.Listener.Close() +} + +// Addr returns the underlying listener's network address. +func (p *Listener) Addr() net.Addr { + return p.Listener.Addr() +} + +// NewConn is used to wrap a net.Conn that may be speaking +// the proxy protocol into a proxyproto.Conn +func NewConn(conn net.Conn, opts ...func(*Conn)) *Conn { + // For v1 the header length is at most 108 bytes. + // For v2 the header length is at most 52 bytes plus the length of the TLVs. + // We use 256 bytes to be safe. + const bufSize = 256 + br := bufio.NewReaderSize(conn, bufSize) + + pConn := &Conn{ + bufReader: br, + reader: io.MultiReader(br, conn), + conn: conn, + } + + for _, opt := range opts { + opt(pConn) + } + + return pConn +} + +// Read is check for the proxy protocol header when doing +// the initial scan. If there is an error parsing the header, +// it is returned and the socket is closed. +func (p *Conn) Read(b []byte) (int, error) { + p.once.Do(func() { + p.readErr = p.readHeader() + }) + if p.readErr != nil { + return 0, p.readErr + } + + return p.reader.Read(b) +} + +// Write wraps original conn.Write +func (p *Conn) Write(b []byte) (int, error) { + return p.conn.Write(b) +} + +// Close wraps original conn.Close +func (p *Conn) Close() error { + return p.conn.Close() +} + +// ProxyHeader returns the proxy protocol header, if any. If an error occurs +// while reading the proxy header, nil is returned. +func (p *Conn) ProxyHeader() *Header { + p.once.Do(func() { p.readErr = p.readHeader() }) + return p.header +} + +// LocalAddr returns the address of the server if the proxy +// protocol is being used, otherwise just returns the address of +// the socket server. In case an error happens on reading the +// proxy header the original LocalAddr is returned, not the one +// from the proxy header even if the proxy header itself is +// syntactically correct. +func (p *Conn) LocalAddr() net.Addr { + p.once.Do(func() { p.readErr = p.readHeader() }) + if p.header == nil || p.header.Command.IsLocal() || p.readErr != nil { + return p.conn.LocalAddr() + } + + return p.header.DestinationAddr +} + +// RemoteAddr returns the address of the client if the proxy +// protocol is being used, otherwise just returns the address of +// the socket peer. In case an error happens on reading the +// proxy header the original RemoteAddr is returned, not the one +// from the proxy header even if the proxy header itself is +// syntactically correct. +func (p *Conn) RemoteAddr() net.Addr { + p.once.Do(func() { p.readErr = p.readHeader() }) + if p.header == nil || p.header.Command.IsLocal() || p.readErr != nil { + return p.conn.RemoteAddr() + } + + return p.header.SourceAddr +} + +// Raw returns the underlying connection which can be casted to +// a concrete type, allowing access to specialized functions. +// +// Use this ONLY if you know exactly what you are doing. +func (p *Conn) Raw() net.Conn { + return p.conn +} + +// TCPConn returns the underlying TCP connection, +// allowing access to specialized functions. +// +// Use this ONLY if you know exactly what you are doing. +func (p *Conn) TCPConn() (conn *net.TCPConn, ok bool) { + conn, ok = p.conn.(*net.TCPConn) + return +} + +// UnixConn returns the underlying Unix socket connection, +// allowing access to specialized functions. +// +// Use this ONLY if you know exactly what you are doing. +func (p *Conn) UnixConn() (conn *net.UnixConn, ok bool) { + conn, ok = p.conn.(*net.UnixConn) + return +} + +// UDPConn returns the underlying UDP connection, +// allowing access to specialized functions. +// +// Use this ONLY if you know exactly what you are doing. +func (p *Conn) UDPConn() (conn *net.UDPConn, ok bool) { + conn, ok = p.conn.(*net.UDPConn) + return +} + +// SetDeadline wraps original conn.SetDeadline +func (p *Conn) SetDeadline(t time.Time) error { + p.readDeadline.Store(t) + return p.conn.SetDeadline(t) +} + +// SetReadDeadline wraps original conn.SetReadDeadline +func (p *Conn) SetReadDeadline(t time.Time) error { + // Set a local var that tells us the desired deadline. This is + // needed in order to reset the read deadline to the one that is + // desired by the user, rather than an empty deadline. + p.readDeadline.Store(t) + return p.conn.SetReadDeadline(t) +} + +// SetWriteDeadline wraps original conn.SetWriteDeadline +func (p *Conn) SetWriteDeadline(t time.Time) error { + return p.conn.SetWriteDeadline(t) +} + +func (p *Conn) readHeader() error { + // If the connection's readHeaderTimeout is more than 0, + // push our deadline back to now plus the timeout. This should only + // run on the connection, as we don't want to override the previous + // read deadline the user may have used. + if p.readHeaderTimeout > 0 { + if err := p.conn.SetReadDeadline(time.Now().Add(p.readHeaderTimeout)); err != nil { + return err + } + } + + header, err := Read(p.bufReader) + + // If the connection's readHeaderTimeout is more than 0, undo the change to the + // deadline that we made above. Because we retain the readDeadline as part of our + // SetReadDeadline override, we know the user's desired deadline so we use that. + // Therefore, we check whether the error is a net.Timeout and if it is, we decide + // the proxy proto does not exist and set the error accordingly. + if p.readHeaderTimeout > 0 { + t := p.readDeadline.Load() + if t == nil { + t = time.Time{} + } + if err := p.conn.SetReadDeadline(t.(time.Time)); err != nil { + return err + } + if netErr, ok := err.(net.Error); ok && netErr.Timeout() { + err = ErrNoProxyProtocol + } + } + + // For the purpose of this wrapper shamefully stolen from armon/go-proxyproto + // let's act as if there was no error when PROXY protocol is not present. + if err == ErrNoProxyProtocol { + // but not if it is required that the connection has one + if p.ProxyHeaderPolicy == REQUIRE { + return err + } + + return nil + } + + // proxy protocol header was found + if err == nil && header != nil { + switch p.ProxyHeaderPolicy { + case REJECT: + // this connection is not allowed to send one + return ErrSuperfluousProxyHeader + case USE, REQUIRE: + if p.Validate != nil { + err = p.Validate(header) + if err != nil { + return err + } + } + + p.header = header + } + } + + return err +} + +// ReadFrom implements the io.ReaderFrom ReadFrom method +func (p *Conn) ReadFrom(r io.Reader) (int64, error) { + if rf, ok := p.conn.(io.ReaderFrom); ok { + return rf.ReadFrom(r) + } + return io.Copy(p.conn, r) +} + +// WriteTo implements io.WriterTo +func (p *Conn) WriteTo(w io.Writer) (int64, error) { + p.once.Do(func() { p.readErr = p.readHeader() }) + if p.readErr != nil { + return 0, p.readErr + } + + b := make([]byte, p.bufReader.Buffered()) + if _, err := p.bufReader.Read(b); err != nil { + return 0, err // this should never as we read buffered data + } + + var n int64 + { + nn, err := w.Write(b) + n += int64(nn) + if err != nil { + return n, err + } + } + { + nn, err := io.Copy(w, p.conn) + n += nn + if err != nil { + return n, err + } + } + + return n, nil +} diff --git a/vendor/github.com/pires/go-proxyproto/tlv.go b/vendor/github.com/pires/go-proxyproto/tlv.go new file mode 100644 index 0000000..7cc2fb3 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/tlv.go @@ -0,0 +1,132 @@ +// Type-Length-Value splitting and parsing for proxy protocol V2 +// See spec https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt sections 2.2 to 2.7 and + +package proxyproto + +import ( + "encoding/binary" + "errors" + "fmt" + "math" +) + +const ( + // Section 2.2 + PP2_TYPE_ALPN PP2Type = 0x01 + PP2_TYPE_AUTHORITY PP2Type = 0x02 + PP2_TYPE_CRC32C PP2Type = 0x03 + PP2_TYPE_NOOP PP2Type = 0x04 + PP2_TYPE_UNIQUE_ID PP2Type = 0x05 + PP2_TYPE_SSL PP2Type = 0x20 + PP2_SUBTYPE_SSL_VERSION PP2Type = 0x21 + PP2_SUBTYPE_SSL_CN PP2Type = 0x22 + PP2_SUBTYPE_SSL_CIPHER PP2Type = 0x23 + PP2_SUBTYPE_SSL_SIG_ALG PP2Type = 0x24 + PP2_SUBTYPE_SSL_KEY_ALG PP2Type = 0x25 + PP2_TYPE_NETNS PP2Type = 0x30 + + // Section 2.2.7, reserved types + PP2_TYPE_MIN_CUSTOM PP2Type = 0xE0 + PP2_TYPE_MAX_CUSTOM PP2Type = 0xEF + PP2_TYPE_MIN_EXPERIMENT PP2Type = 0xF0 + PP2_TYPE_MAX_EXPERIMENT PP2Type = 0xF7 + PP2_TYPE_MIN_FUTURE PP2Type = 0xF8 + PP2_TYPE_MAX_FUTURE PP2Type = 0xFF +) + +var ( + ErrTruncatedTLV = errors.New("proxyproto: truncated TLV") + ErrMalformedTLV = errors.New("proxyproto: malformed TLV Value") + ErrIncompatibleTLV = errors.New("proxyproto: incompatible TLV type") +) + +// PP2Type is the proxy protocol v2 type +type PP2Type byte + +// TLV is a uninterpreted Type-Length-Value for V2 protocol, see section 2.2 +type TLV struct { + Type PP2Type + Value []byte +} + +// SplitTLVs splits the Type-Length-Value vector, returns the vector or an error. +func SplitTLVs(raw []byte) ([]TLV, error) { + var tlvs []TLV + for i := 0; i < len(raw); { + tlv := TLV{ + Type: PP2Type(raw[i]), + } + if len(raw)-i <= 2 { + return nil, ErrTruncatedTLV + } + tlvLen := int(binary.BigEndian.Uint16(raw[i+1 : i+3])) // Max length = 65K + i += 3 + if i+tlvLen > len(raw) { + return nil, ErrTruncatedTLV + } + // Ignore no-op padding + if tlv.Type != PP2_TYPE_NOOP { + tlv.Value = make([]byte, tlvLen) + copy(tlv.Value, raw[i:i+tlvLen]) + } + i += tlvLen + tlvs = append(tlvs, tlv) + } + return tlvs, nil +} + +// JoinTLVs joins multiple Type-Length-Value records. +func JoinTLVs(tlvs []TLV) ([]byte, error) { + var raw []byte + for _, tlv := range tlvs { + if len(tlv.Value) > math.MaxUint16 { + return nil, fmt.Errorf("proxyproto: cannot format TLV %v with length %d", tlv.Type, len(tlv.Value)) + } + var length [2]byte + binary.BigEndian.PutUint16(length[:], uint16(len(tlv.Value))) + raw = append(raw, byte(tlv.Type)) + raw = append(raw, length[:]...) + raw = append(raw, tlv.Value...) + } + return raw, nil +} + +// Registered is true if the type is registered in the spec, see section 2.2 +func (p PP2Type) Registered() bool { + switch p { + case PP2_TYPE_ALPN, + PP2_TYPE_AUTHORITY, + PP2_TYPE_CRC32C, + PP2_TYPE_NOOP, + PP2_TYPE_UNIQUE_ID, + PP2_TYPE_SSL, + PP2_SUBTYPE_SSL_VERSION, + PP2_SUBTYPE_SSL_CN, + PP2_SUBTYPE_SSL_CIPHER, + PP2_SUBTYPE_SSL_SIG_ALG, + PP2_SUBTYPE_SSL_KEY_ALG, + PP2_TYPE_NETNS: + return true + } + return false +} + +// App is true if the type is reserved for application specific data, see section 2.2.7 +func (p PP2Type) App() bool { + return p >= PP2_TYPE_MIN_CUSTOM && p <= PP2_TYPE_MAX_CUSTOM +} + +// Experiment is true if the type is reserved for temporary experimental use by application developers, see section 2.2.7 +func (p PP2Type) Experiment() bool { + return p >= PP2_TYPE_MIN_EXPERIMENT && p <= PP2_TYPE_MAX_EXPERIMENT +} + +// Future is true is the type is reserved for future use, see section 2.2.7 +func (p PP2Type) Future() bool { + return p >= PP2_TYPE_MIN_FUTURE +} + +// Spec is true if the type is covered by the spec, see section 2.2 and 2.2.7 +func (p PP2Type) Spec() bool { + return p.Registered() || p.App() || p.Experiment() || p.Future() +} diff --git a/vendor/github.com/pires/go-proxyproto/v1.go b/vendor/github.com/pires/go-proxyproto/v1.go new file mode 100644 index 0000000..0d34ba5 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/v1.go @@ -0,0 +1,243 @@ +package proxyproto + +import ( + "bufio" + "bytes" + "fmt" + "net" + "net/netip" + "strconv" + "strings" +) + +const ( + crlf = "\r\n" + separator = " " +) + +func initVersion1() *Header { + header := new(Header) + header.Version = 1 + // Command doesn't exist in v1 + header.Command = PROXY + return header +} + +func parseVersion1(reader *bufio.Reader) (*Header, error) { + //The header cannot be more than 107 bytes long. Per spec: + // + // (...) + // - worst case (optional fields set to 0xff) : + // "PROXY UNKNOWN ffff:f...f:ffff ffff:f...f:ffff 65535 65535\r\n" + // => 5 + 1 + 7 + 1 + 39 + 1 + 39 + 1 + 5 + 1 + 5 + 2 = 107 chars + // + // So a 108-byte buffer is always enough to store all the line and a + // trailing zero for string processing. + // + // It must also be CRLF terminated, as above. The header does not otherwise + // contain a CR or LF byte. + // + // ISSUE #69 + // We can't use Peek here as it will block trying to fill the buffer, which + // will never happen if the header is TCP4 or TCP6 (max. 56 and 104 bytes + // respectively) and the server is expected to speak first. + // + // Similarly, we can't use ReadString or ReadBytes as these will keep reading + // until the delimiter is found; an abusive client could easily disrupt a + // server by sending a large amount of data that do not contain a LF byte. + // Another means of attack would be to start connections and simply not send + // data after the initial PROXY signature bytes, accumulating a large + // number of blocked goroutines on the server. ReadSlice will also block for + // a delimiter when the internal buffer does not fill up. + // + // A plain Read is also problematic since we risk reading past the end of the + // header without being able to easily put the excess bytes back into the reader's + // buffer (with the current implementation's design). + // + // So we use a ReadByte loop, which solves the overflow problem and avoids + // reading beyond the end of the header. However, we need one more trick to harden + // against partial header attacks (slow loris) - per spec: + // + // (..) The sender must always ensure that the header is sent at once, so that + // the transport layer maintains atomicity along the path to the receiver. The + // receiver may be tolerant to partial headers or may simply drop the connection + // when receiving a partial header. Recommendation is to be tolerant, but + // implementation constraints may not always easily permit this. + // + // We are subject to such implementation constraints. So we return an error if + // the header cannot be fully extracted with a single read of the underlying + // reader. + buf := make([]byte, 0, 107) + for { + b, err := reader.ReadByte() + if err != nil { + return nil, fmt.Errorf(ErrCantReadVersion1Header.Error()+": %v", err) + } + buf = append(buf, b) + if b == '\n' { + // End of header found + break + } + if len(buf) == 107 { + // No delimiter in first 107 bytes + return nil, ErrVersion1HeaderTooLong + } + if reader.Buffered() == 0 { + // Header was not buffered in a single read. Since we can't + // differentiate between genuine slow writers and DoS agents, + // we abort. On healthy networks, this should never happen. + return nil, ErrCantReadVersion1Header + } + } + + // Check for CR before LF. + if len(buf) < 2 || buf[len(buf)-2] != '\r' { + return nil, ErrLineMustEndWithCrlf + } + + // Check full signature. + tokens := strings.Split(string(buf[:len(buf)-2]), separator) + + // Expect at least 2 tokens: "PROXY" and the transport protocol. + if len(tokens) < 2 { + return nil, ErrCantReadAddressFamilyAndProtocol + } + + // Read address family and protocol + var transportProtocol AddressFamilyAndProtocol + switch tokens[1] { + case "TCP4": + transportProtocol = TCPv4 + case "TCP6": + transportProtocol = TCPv6 + case "UNKNOWN": + transportProtocol = UNSPEC // doesn't exist in v1 but fits UNKNOWN + default: + return nil, ErrCantReadAddressFamilyAndProtocol + } + + // Expect 6 tokens only when UNKNOWN is not present. + if transportProtocol != UNSPEC && len(tokens) < 6 { + return nil, ErrCantReadAddressFamilyAndProtocol + } + + // When a signature is found, allocate a v1 header with Command set to PROXY. + // Command doesn't exist in v1 but set it for other parts of this library + // to rely on it for determining connection details. + header := initVersion1() + + // Transport protocol has been processed already. + header.TransportProtocol = transportProtocol + + // When UNKNOWN, set the command to LOCAL and return early + if header.TransportProtocol == UNSPEC { + header.Command = LOCAL + return header, nil + } + + // Otherwise, continue to read addresses and ports + sourceIP, err := parseV1IPAddress(header.TransportProtocol, tokens[2]) + if err != nil { + return nil, err + } + destIP, err := parseV1IPAddress(header.TransportProtocol, tokens[3]) + if err != nil { + return nil, err + } + sourcePort, err := parseV1PortNumber(tokens[4]) + if err != nil { + return nil, err + } + destPort, err := parseV1PortNumber(tokens[5]) + if err != nil { + return nil, err + } + header.SourceAddr = &net.TCPAddr{ + IP: sourceIP, + Port: sourcePort, + } + header.DestinationAddr = &net.TCPAddr{ + IP: destIP, + Port: destPort, + } + + return header, nil +} + +func (header *Header) formatVersion1() ([]byte, error) { + // As of version 1, only "TCP4" ( \x54 \x43 \x50 \x34 ) for TCP over IPv4, + // and "TCP6" ( \x54 \x43 \x50 \x36 ) for TCP over IPv6 are allowed. + var proto string + switch header.TransportProtocol { + case TCPv4: + proto = "TCP4" + case TCPv6: + proto = "TCP6" + default: + // Unknown connection (short form) + return []byte("PROXY UNKNOWN" + crlf), nil + } + + sourceAddr, sourceOK := header.SourceAddr.(*net.TCPAddr) + destAddr, destOK := header.DestinationAddr.(*net.TCPAddr) + if !sourceOK || !destOK { + return nil, ErrInvalidAddress + } + + sourceIP, destIP := sourceAddr.IP, destAddr.IP + switch header.TransportProtocol { + case TCPv4: + sourceIP = sourceIP.To4() + destIP = destIP.To4() + case TCPv6: + sourceIP = sourceIP.To16() + destIP = destIP.To16() + } + if sourceIP == nil || destIP == nil { + return nil, ErrInvalidAddress + } + + buf := bytes.NewBuffer(make([]byte, 0, 108)) + buf.Write(SIGV1) + buf.WriteString(separator) + buf.WriteString(proto) + buf.WriteString(separator) + buf.WriteString(sourceIP.String()) + buf.WriteString(separator) + buf.WriteString(destIP.String()) + buf.WriteString(separator) + buf.WriteString(strconv.Itoa(sourceAddr.Port)) + buf.WriteString(separator) + buf.WriteString(strconv.Itoa(destAddr.Port)) + buf.WriteString(crlf) + + return buf.Bytes(), nil +} + +func parseV1PortNumber(portStr string) (int, error) { + port, err := strconv.Atoi(portStr) + if err != nil || port < 0 || port > 65535 { + return 0, ErrInvalidPortNumber + } + return port, nil +} + +func parseV1IPAddress(protocol AddressFamilyAndProtocol, addrStr string) (net.IP, error) { + addr, err := netip.ParseAddr(addrStr) + if err != nil { + return nil, ErrInvalidAddress + } + + switch protocol { + case TCPv4: + if addr.Is4() { + return net.IP(addr.AsSlice()), nil + } + case TCPv6: + if addr.Is6() || addr.Is4In6() { + return net.IP(addr.AsSlice()), nil + } + } + + return nil, ErrInvalidAddress +} diff --git a/vendor/github.com/pires/go-proxyproto/v2.go b/vendor/github.com/pires/go-proxyproto/v2.go new file mode 100644 index 0000000..74bf3f0 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/v2.go @@ -0,0 +1,285 @@ +package proxyproto + +import ( + "bufio" + "bytes" + "encoding/binary" + "errors" + "io" + "net" +) + +var ( + lengthUnspec = uint16(0) + lengthV4 = uint16(12) + lengthV6 = uint16(36) + lengthUnix = uint16(216) + lengthUnspecBytes = func() []byte { + a := make([]byte, 2) + binary.BigEndian.PutUint16(a, lengthUnspec) + return a + }() + lengthV4Bytes = func() []byte { + a := make([]byte, 2) + binary.BigEndian.PutUint16(a, lengthV4) + return a + }() + lengthV6Bytes = func() []byte { + a := make([]byte, 2) + binary.BigEndian.PutUint16(a, lengthV6) + return a + }() + lengthUnixBytes = func() []byte { + a := make([]byte, 2) + binary.BigEndian.PutUint16(a, lengthUnix) + return a + }() + errUint16Overflow = errors.New("proxyproto: uint16 overflow") +) + +type _ports struct { + SrcPort uint16 + DstPort uint16 +} + +type _addr4 struct { + Src [4]byte + Dst [4]byte + SrcPort uint16 + DstPort uint16 +} + +type _addr6 struct { + Src [16]byte + Dst [16]byte + _ports +} + +type _addrUnix struct { + Src [108]byte + Dst [108]byte +} + +func parseVersion2(reader *bufio.Reader) (header *Header, err error) { + // Skip first 12 bytes (signature) + for i := 0; i < 12; i++ { + if _, err = reader.ReadByte(); err != nil { + return nil, ErrCantReadProtocolVersionAndCommand + } + } + + header = new(Header) + header.Version = 2 + + // Read the 13th byte, protocol version and command + b13, err := reader.ReadByte() + if err != nil { + return nil, ErrCantReadProtocolVersionAndCommand + } + header.Command = ProtocolVersionAndCommand(b13) + if _, ok := supportedCommand[header.Command]; !ok { + return nil, ErrUnsupportedProtocolVersionAndCommand + } + + // Read the 14th byte, address family and protocol + b14, err := reader.ReadByte() + if err != nil { + return nil, ErrCantReadAddressFamilyAndProtocol + } + header.TransportProtocol = AddressFamilyAndProtocol(b14) + // UNSPEC is only supported when LOCAL is set. + if header.TransportProtocol == UNSPEC && header.Command != LOCAL { + return nil, ErrUnsupportedAddressFamilyAndProtocol + } + + // Make sure there are bytes available as specified in length + var length uint16 + if err := binary.Read(io.LimitReader(reader, 2), binary.BigEndian, &length); err != nil { + return nil, ErrCantReadLength + } + if !header.validateLength(length) { + return nil, ErrInvalidLength + } + + // Return early if the length is zero, which means that + // there's no address information and TLVs present for UNSPEC. + if length == 0 { + return header, nil + } + + if _, err := reader.Peek(int(length)); err != nil { + return nil, ErrInvalidLength + } + + // Length-limited reader for payload section + payloadReader := io.LimitReader(reader, int64(length)).(*io.LimitedReader) + + // Read addresses and ports for protocols other than UNSPEC. + // Ignore address information for UNSPEC, and skip straight to read TLVs, + // since the length is greater than zero. + if header.TransportProtocol != UNSPEC { + if header.TransportProtocol.IsIPv4() { + var addr _addr4 + if err := binary.Read(payloadReader, binary.BigEndian, &addr); err != nil { + return nil, ErrInvalidAddress + } + header.SourceAddr = newIPAddr(header.TransportProtocol, addr.Src[:], addr.SrcPort) + header.DestinationAddr = newIPAddr(header.TransportProtocol, addr.Dst[:], addr.DstPort) + } else if header.TransportProtocol.IsIPv6() { + var addr _addr6 + if err := binary.Read(payloadReader, binary.BigEndian, &addr); err != nil { + return nil, ErrInvalidAddress + } + header.SourceAddr = newIPAddr(header.TransportProtocol, addr.Src[:], addr.SrcPort) + header.DestinationAddr = newIPAddr(header.TransportProtocol, addr.Dst[:], addr.DstPort) + } else if header.TransportProtocol.IsUnix() { + var addr _addrUnix + if err := binary.Read(payloadReader, binary.BigEndian, &addr); err != nil { + return nil, ErrInvalidAddress + } + + network := "unix" + if header.TransportProtocol.IsDatagram() { + network = "unixgram" + } + + header.SourceAddr = &net.UnixAddr{ + Net: network, + Name: parseUnixName(addr.Src[:]), + } + header.DestinationAddr = &net.UnixAddr{ + Net: network, + Name: parseUnixName(addr.Dst[:]), + } + } + } + + // Copy bytes for optional Type-Length-Value vector + header.rawTLVs = make([]byte, payloadReader.N) // Allocate minimum size slice + if _, err = io.ReadFull(payloadReader, header.rawTLVs); err != nil && err != io.EOF { + return nil, err + } + + return header, nil +} + +func (header *Header) formatVersion2() ([]byte, error) { + var buf bytes.Buffer + buf.Write(SIGV2) + buf.WriteByte(header.Command.toByte()) + buf.WriteByte(header.TransportProtocol.toByte()) + if header.TransportProtocol.IsUnspec() { + // For UNSPEC, write no addresses and ports but only TLVs if they are present + hdrLen, err := addTLVLen(lengthUnspecBytes, len(header.rawTLVs)) + if err != nil { + return nil, err + } + buf.Write(hdrLen) + } else { + var addrSrc, addrDst []byte + if header.TransportProtocol.IsIPv4() { + hdrLen, err := addTLVLen(lengthV4Bytes, len(header.rawTLVs)) + if err != nil { + return nil, err + } + buf.Write(hdrLen) + sourceIP, destIP, _ := header.IPs() + addrSrc = sourceIP.To4() + addrDst = destIP.To4() + } else if header.TransportProtocol.IsIPv6() { + hdrLen, err := addTLVLen(lengthV6Bytes, len(header.rawTLVs)) + if err != nil { + return nil, err + } + buf.Write(hdrLen) + sourceIP, destIP, _ := header.IPs() + addrSrc = sourceIP.To16() + addrDst = destIP.To16() + } else if header.TransportProtocol.IsUnix() { + buf.Write(lengthUnixBytes) + sourceAddr, destAddr, ok := header.UnixAddrs() + if !ok { + return nil, ErrInvalidAddress + } + addrSrc = formatUnixName(sourceAddr.Name) + addrDst = formatUnixName(destAddr.Name) + } + + if addrSrc == nil || addrDst == nil { + return nil, ErrInvalidAddress + } + buf.Write(addrSrc) + buf.Write(addrDst) + + if sourcePort, destPort, ok := header.Ports(); ok { + portBytes := make([]byte, 2) + + binary.BigEndian.PutUint16(portBytes, uint16(sourcePort)) + buf.Write(portBytes) + + binary.BigEndian.PutUint16(portBytes, uint16(destPort)) + buf.Write(portBytes) + } + } + + if len(header.rawTLVs) > 0 { + buf.Write(header.rawTLVs) + } + + return buf.Bytes(), nil +} + +func (header *Header) validateLength(length uint16) bool { + if header.TransportProtocol.IsIPv4() { + return length >= lengthV4 + } else if header.TransportProtocol.IsIPv6() { + return length >= lengthV6 + } else if header.TransportProtocol.IsUnix() { + return length >= lengthUnix + } else if header.TransportProtocol.IsUnspec() { + return length >= lengthUnspec + } + return false +} + +// addTLVLen adds the length of the TLV to the header length or errors on uint16 overflow. +func addTLVLen(cur []byte, tlvLen int) ([]byte, error) { + if tlvLen == 0 { + return cur, nil + } + curLen := binary.BigEndian.Uint16(cur) + newLen := int(curLen) + tlvLen + if newLen >= 1<<16 { + return nil, errUint16Overflow + } + a := make([]byte, 2) + binary.BigEndian.PutUint16(a, uint16(newLen)) + return a, nil +} + +func newIPAddr(transport AddressFamilyAndProtocol, ip net.IP, port uint16) net.Addr { + if transport.IsStream() { + return &net.TCPAddr{IP: ip, Port: int(port)} + } else if transport.IsDatagram() { + return &net.UDPAddr{IP: ip, Port: int(port)} + } else { + return nil + } +} + +func parseUnixName(b []byte) string { + i := bytes.IndexByte(b, 0) + if i < 0 { + return string(b) + } + return string(b[:i]) +} + +func formatUnixName(name string) []byte { + n := int(lengthUnix) / 2 + if len(name) >= n { + return []byte(name[:n]) + } + pad := make([]byte, n-len(name)) + return append([]byte(name), pad...) +} diff --git a/vendor/github.com/pires/go-proxyproto/version_cmd.go b/vendor/github.com/pires/go-proxyproto/version_cmd.go new file mode 100644 index 0000000..59f2042 --- /dev/null +++ b/vendor/github.com/pires/go-proxyproto/version_cmd.go @@ -0,0 +1,47 @@ +package proxyproto + +// ProtocolVersionAndCommand represents the command in proxy protocol v2. +// Command doesn't exist in v1 but it should be set since other parts of +// this library may rely on it for determining connection details. +type ProtocolVersionAndCommand byte + +const ( + // LOCAL represents the LOCAL command in v2 or UNKNOWN transport in v1, + // in which case no address information is expected. + LOCAL ProtocolVersionAndCommand = '\x20' + // PROXY represents the PROXY command in v2 or transport is not UNKNOWN in v1, + // in which case valid local/remote address and port information is expected. + PROXY ProtocolVersionAndCommand = '\x21' +) + +var supportedCommand = map[ProtocolVersionAndCommand]bool{ + LOCAL: true, + PROXY: true, +} + +// IsLocal returns true if the command in v2 is LOCAL or the transport in v1 is UNKNOWN, +// i.e. when no address information is expected, false otherwise. +func (pvc ProtocolVersionAndCommand) IsLocal() bool { + return LOCAL == pvc +} + +// IsProxy returns true if the command in v2 is PROXY or the transport in v1 is not UNKNOWN, +// i.e. when valid local/remote address and port information is expected, false otherwise. +func (pvc ProtocolVersionAndCommand) IsProxy() bool { + return PROXY == pvc +} + +// IsUnspec returns true if the command is unspecified, false otherwise. +func (pvc ProtocolVersionAndCommand) IsUnspec() bool { + return !(pvc.IsLocal() || pvc.IsProxy()) +} + +func (pvc ProtocolVersionAndCommand) toByte() byte { + if pvc.IsLocal() { + return byte(LOCAL) + } else if pvc.IsProxy() { + return byte(PROXY) + } + + return byte(LOCAL) +} diff --git a/vendor/github.com/tailscale/goupnp/.gitignore b/vendor/github.com/tailscale/goupnp/.gitignore deleted file mode 100644 index 7a6e0eb..0000000 --- a/vendor/github.com/tailscale/goupnp/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.zip -*.sublime-workspace \ No newline at end of file diff --git a/vendor/github.com/tailscale/goupnp/README.md b/vendor/github.com/tailscale/goupnp/README.md deleted file mode 100644 index c67b9f3..0000000 --- a/vendor/github.com/tailscale/goupnp/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# tailscale/goupnp - -This repo is a temporary fork of [huin/goupnp](https://github.com/huin/goupnp)(A UPnP client -library for Go), customized for UPnP support in Tailscale. - -## Installation - -Run `go get -u github.com/tailscale/goupnp`. - -## Documentation - -See [GUIDE.md](GUIDE.md) for a quick start on the most common use case for this -library. - -Supported DCPs (you probably want to start with one of these): - -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) av1](https://godoc.org/github.com/tailscale/goupnp/dcps/av1) - Client for UPnP Device Control Protocol MediaServer v1 and MediaRenderer v1. -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) internetgateway1](https://godoc.org/github.com/tailscale/goupnp/dcps/internetgateway1) - Client for UPnP Device Control Protocol Internet Gateway Device v1. -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) internetgateway2](https://godoc.org/github.com/tailscale/goupnp/dcps/internetgateway2) - Client for UPnP Device Control Protocol Internet Gateway Device v2. - -Core components: - -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) (goupnp)](https://godoc.org/github.com/tailscale/goupnp) core library - contains datastructures and utilities typically used by the implemented DCPs. -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) httpu](https://godoc.org/github.com/tailscale/goupnp/httpu) HTTPU implementation, underlies SSDP. -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) ssdp](https://godoc.org/github.com/tailscale/goupnp/ssdp) SSDP client implementation (simple service discovery protocol) - used to discover UPnP services on a network. -- [![GoDoc](https://godoc.org/github.com/tailscale/goupnp?status.svg) soap](https://godoc.org/github.com/tailscale/goupnp/soap) SOAP client implementation (simple object access protocol) - used to communicate with discovered services. - -## Regenerating dcps generated source code: - -1. Build code generator: - - `go get -u github.com/tailscale/goupnp/cmd/goupnpdcpgen` - -2. Regenerate the code: - - `go generate ./...` - -## Supporting additional UPnP devices and services: - -Supporting additional services is, in the trivial case, simply a matter of -adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`, -regenerating the source code (see above), and committing that source code. - -However, it would be helpful if anyone needing such a service could test the -service against the service they have, and then reporting any trouble -encountered as an [issue on this -project](https://github.com/tailscale/goupnp/issues/new). If it just works, then -please report at least minimal working functionality as an issue, and -optionally contribute the metadata upstream. - -## Migrating due to Breaking Changes - -- \#40 introduced a breaking change to handling non-utf8 encodings, but removes a heavy - dependency on `golang.org/x/net` with charset encodings. If this breaks your usage of this - library, you can return to the old behavior by modifying the exported variable and importing - the package yourself: - -```go -import ( - "golang.org/x/net/html/charset" - "github.com/tailscale/goupnp" -) - -func init() { - // should be modified before goupnp libraries are in use. - goupnp.CharsetReaderFault = charset.NewReaderLabel -} -``` diff --git a/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/gen.go b/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/gen.go deleted file mode 100644 index 752058b..0000000 --- a/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/gen.go +++ /dev/null @@ -1,2 +0,0 @@ -//go:generate goupnpdcpgen -dcp_name internetgateway2 -package internetgateway2 diff --git a/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/internetgateway2.go b/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/internetgateway2.go deleted file mode 100644 index d679da4..0000000 --- a/vendor/github.com/tailscale/goupnp/dcps/internetgateway2/internetgateway2.go +++ /dev/null @@ -1,2351 +0,0 @@ -// Client for UPnP Device Control Protocol Internet Gateway Device v2. -// -// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf -// -// Typically, use one of the New* functions to create clients for services. -package internetgateway2 - -// *********************************************************** -// GENERATED FILE - DO NOT EDIT BY HAND. See README.md -// *********************************************************** - -import ( - "context" - "net/url" - "time" - - "github.com/tailscale/goupnp" - "github.com/tailscale/goupnp/soap" -) - -// Hack to avoid Go complaining if time isn't used. -var _ time.Time - -// Device URNs: -const ( - URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1" - URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1" - URN_WANConnectionDevice_2 = "urn:schemas-upnp-org:device:WANConnectionDevice:2" - URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1" - URN_WANDevice_2 = "urn:schemas-upnp-org:device:WANDevice:2" -) - -// Service URNs: -const ( - URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1" - URN_WANIPConnection_2 = "urn:schemas-upnp-org:service:WANIPConnection:2" - URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1" -) - -// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANIPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPConnection1Clients(ctx context.Context) (clients []*WANIPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(ctx, URN_WANIPConnection_1); err != nil { - return - } - clients = newWANIPConnection1ClientsFromGenericClients(genericClients) - return -} - -// NewWANIPConnection1ClientsByURL discovers instances of the service at the given -// URL, and returns clients to any that are found. An error is returned if -// there was an error probing the service. -// -// This is a typical entry calling point into this package when reusing an -// previously discovered service URL. -func NewWANIPConnection1ClientsByURL(ctx context.Context, loc *url.URL) ([]*WANIPConnection1, error) { - genericClients, err := goupnp.NewServiceClientsByURL(ctx, loc, URN_WANIPConnection_1) - if err != nil { - return nil, err - } - return newWANIPConnection1ClientsFromGenericClients(genericClients), nil -} - -// NewWANIPConnection1ClientsFromRootDevice discovers instances of the service in -// a given root device, and returns clients to any that are found. An error is -// returned if there was not at least one instance of the service within the -// device. The location parameter is simply assigned to the Location attribute -// of the wrapped ServiceClient(s). -// -// This is a typical entry calling point into this package when reusing an -// previously discovered root device. -func NewWANIPConnection1ClientsFromRootDevice(ctx context.Context, rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection1, error) { - genericClients, err := goupnp.NewServiceClientsFromRootDevice(ctx, rootDevice, loc, URN_WANIPConnection_1) - if err != nil { - return nil, err - } - return newWANIPConnection1ClientsFromGenericClients(genericClients), nil -} - -func newWANIPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPConnection1 { - clients := make([]*WANIPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPConnection1{genericClients[i]} - } - return clients -} - -func (client *WANIPConnection1) SetConnectionType(ctx context.Context, NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged -func (client *WANIPConnection1) GetConnectionTypeInfo(ctx context.Context) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) RequestConnection(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) RequestTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) ForceTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) SetAutoDisconnectTime(ctx context.Context, NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) SetIdleDisconnectTime(ctx context.Context, NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) SetWarnDisconnectDelay(ctx context.Context, NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -func (client *WANIPConnection1) GetStatusInfo(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - NewLastConnectionError string - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) GetAutoDisconnectTime(ctx context.Context) (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) GetIdleDisconnectTime(ctx context.Context) (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) GetWarnDisconnectDelay(ctx context.Context) (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) GetNATRSIPStatus(ctx context.Context) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewProtocol: allowed values: TCP, UDP -func (client *WANIPConnection1) GetGenericPortMappingEntry(ctx context.Context, NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection1) GetSpecificPortMappingEntry(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection1) AddPortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection1) DeletePortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection1) GetExternalIPAddress(ctx context.Context) (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANIPConnection2 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:2". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANIPConnection2 struct { - goupnp.ServiceClient -} - -// NewWANIPConnection2Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANIPConnection2Clients(ctx context.Context) (clients []*WANIPConnection2, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(ctx, URN_WANIPConnection_2); err != nil { - return - } - clients = newWANIPConnection2ClientsFromGenericClients(genericClients) - return -} - -// NewWANIPConnection2ClientsByURL discovers instances of the service at the given -// URL, and returns clients to any that are found. An error is returned if -// there was an error probing the service. -// -// This is a typical entry calling point into this package when reusing an -// previously discovered service URL. -func NewWANIPConnection2ClientsByURL(ctx context.Context, loc *url.URL) ([]*WANIPConnection2, error) { - genericClients, err := goupnp.NewServiceClientsByURL(ctx, loc, URN_WANIPConnection_2) - if err != nil { - return nil, err - } - return newWANIPConnection2ClientsFromGenericClients(genericClients), nil -} - -// NewWANIPConnection2ClientsFromRootDevice discovers instances of the service in -// a given root device, and returns clients to any that are found. An error is -// returned if there was not at least one instance of the service within the -// device. The location parameter is simply assigned to the Location attribute -// of the wrapped ServiceClient(s). -// -// This is a typical entry calling point into this package when reusing an -// previously discovered root device. -func NewWANIPConnection2ClientsFromRootDevice(ctx context.Context, rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANIPConnection2, error) { - genericClients, err := goupnp.NewServiceClientsFromRootDevice(ctx, rootDevice, loc, URN_WANIPConnection_2) - if err != nil { - return nil, err - } - return newWANIPConnection2ClientsFromGenericClients(genericClients), nil -} - -func newWANIPConnection2ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANIPConnection2 { - clients := make([]*WANIPConnection2, len(genericClients)) - for i := range genericClients { - clients[i] = &WANIPConnection2{genericClients[i]} - } - return clients -} - -func (client *WANIPConnection2) SetConnectionType(ctx context.Context, NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetConnectionTypeInfo(ctx context.Context) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) RequestConnection(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) RequestTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) ForceTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) SetAutoDisconnectTime(ctx context.Context, NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) SetIdleDisconnectTime(ctx context.Context, NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) SetWarnDisconnectDelay(ctx context.Context, NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connecting, Connected, PendingDisconnect, Disconnecting, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE, ERROR_COMMAND_ABORTED, ERROR_NOT_ENABLED_FOR_INTERNET, ERROR_USER_DISCONNECT, ERROR_ISP_DISCONNECT, ERROR_IDLE_DISCONNECT, ERROR_FORCED_DISCONNECT, ERROR_NO_CARRIER, ERROR_IP_CONFIGURATION, ERROR_UNKNOWN -func (client *WANIPConnection2) GetStatusInfo(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - NewLastConnectionError string - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetAutoDisconnectTime(ctx context.Context) (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetIdleDisconnectTime(ctx context.Context) (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetWarnDisconnectDelay(ctx context.Context) (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetNATRSIPStatus(ctx context.Context) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewProtocol: allowed values: TCP, UDP -func (client *WANIPConnection2) GetGenericPortMappingEntry(ctx context.Context, NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) GetSpecificPortMappingEntry(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) AddPortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) DeletePortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) DeletePortMappingRange(ctx context.Context, NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool) (err error) { - // Request structure. - request := &struct { - NewStartPort string - NewEndPort string - NewProtocol string - NewManage string - }{} - // BEGIN Marshal arguments into request. - - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { - return - } - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "DeletePortMappingRange", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANIPConnection2) GetExternalIPAddress(ctx context.Context) (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) GetListOfPortMappings(ctx context.Context, NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) { - // Request structure. - request := &struct { - NewStartPort string - NewEndPort string - NewProtocol string - NewManage string - NewNumberOfPorts string - }{} - // BEGIN Marshal arguments into request. - - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil { - return - } - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil { - return - } - if request.NewNumberOfPorts, err = soap.MarshalUi2(NewNumberOfPorts); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPortListing string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "GetListOfPortMappings", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPortListing, err = soap.UnmarshalString(response.NewPortListing); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANIPConnection2) AddAnyPortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewReservedPort string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANIPConnection_2, "AddAnyPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewReservedPort, err = soap.UnmarshalUi2(response.NewReservedPort); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See -// goupnp.ServiceClient, which contains RootDevice and Service attributes which -// are provided for informational value. -type WANPPPConnection1 struct { - goupnp.ServiceClient -} - -// NewWANPPPConnection1Clients discovers instances of the service on the network, -// and returns clients to any that are found. errors will contain an error for -// any devices that replied but which could not be queried, and err will be set -// if the discovery process failed outright. -// -// This is a typical entry calling point into this package. -func NewWANPPPConnection1Clients(ctx context.Context) (clients []*WANPPPConnection1, errors []error, err error) { - var genericClients []goupnp.ServiceClient - if genericClients, errors, err = goupnp.NewServiceClients(ctx, URN_WANPPPConnection_1); err != nil { - return - } - clients = newWANPPPConnection1ClientsFromGenericClients(genericClients) - return -} - -// NewWANPPPConnection1ClientsByURL discovers instances of the service at the given -// URL, and returns clients to any that are found. An error is returned if -// there was an error probing the service. -// -// This is a typical entry calling point into this package when reusing an -// previously discovered service URL. -func NewWANPPPConnection1ClientsByURL(ctx context.Context, loc *url.URL) ([]*WANPPPConnection1, error) { - genericClients, err := goupnp.NewServiceClientsByURL(ctx, loc, URN_WANPPPConnection_1) - if err != nil { - return nil, err - } - return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil -} - -// NewWANPPPConnection1ClientsFromRootDevice discovers instances of the service in -// a given root device, and returns clients to any that are found. An error is -// returned if there was not at least one instance of the service within the -// device. The location parameter is simply assigned to the Location attribute -// of the wrapped ServiceClient(s). -// -// This is a typical entry calling point into this package when reusing an -// previously discovered root device. -func NewWANPPPConnection1ClientsFromRootDevice(ctx context.Context, rootDevice *goupnp.RootDevice, loc *url.URL) ([]*WANPPPConnection1, error) { - genericClients, err := goupnp.NewServiceClientsFromRootDevice(ctx, rootDevice, loc, URN_WANPPPConnection_1) - if err != nil { - return nil, err - } - return newWANPPPConnection1ClientsFromGenericClients(genericClients), nil -} - -func newWANPPPConnection1ClientsFromGenericClients(genericClients []goupnp.ServiceClient) []*WANPPPConnection1 { - clients := make([]*WANPPPConnection1, len(genericClients)) - for i := range genericClients { - clients[i] = &WANPPPConnection1{genericClients[i]} - } - return clients -} - -func (client *WANPPPConnection1) SetConnectionType(ctx context.Context, NewConnectionType string) (err error) { - // Request structure. - request := &struct { - NewConnectionType string - }{} - // BEGIN Marshal arguments into request. - - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay -func (client *WANPPPConnection1) GetConnectionTypeInfo(ctx context.Context) (NewConnectionType string, NewPossibleConnectionTypes string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionType string - NewPossibleConnectionTypes string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil { - return - } - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) ConfigureConnection(ctx context.Context, NewUserName string, NewPassword string) (err error) { - // Request structure. - request := &struct { - NewUserName string - NewPassword string - }{} - // BEGIN Marshal arguments into request. - - if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil { - return - } - if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) RequestConnection(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) RequestTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) ForceTermination(ctx context.Context) (err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) SetAutoDisconnectTime(ctx context.Context, NewAutoDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewAutoDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) SetIdleDisconnectTime(ctx context.Context, NewIdleDisconnectTime uint32) (err error) { - // Request structure. - request := &struct { - NewIdleDisconnectTime string - }{} - // BEGIN Marshal arguments into request. - - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) SetWarnDisconnectDelay(ctx context.Context, NewWarnDisconnectDelay uint32) (err error) { - // Request structure. - request := &struct { - NewWarnDisconnectDelay string - }{} - // BEGIN Marshal arguments into request. - - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected -// -// * NewLastConnectionError: allowed values: ERROR_NONE -func (client *WANPPPConnection1) GetStatusInfo(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewConnectionStatus string - NewLastConnectionError string - NewUptime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil { - return - } - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil { - return - } - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetLinkLayerMaxBitRates(ctx context.Context) (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUpstreamMaxBitRate string - NewDownstreamMaxBitRate string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil { - return - } - if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetPPPEncryptionProtocol(ctx context.Context) (NewPPPEncryptionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPEncryptionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetPPPCompressionProtocol(ctx context.Context) (NewPPPCompressionProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPCompressionProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetPPPAuthenticationProtocol(ctx context.Context) (NewPPPAuthenticationProtocol string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPPPAuthenticationProtocol string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetUserName(ctx context.Context) (NewUserName string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewUserName string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetUserName", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetPassword(ctx context.Context) (NewPassword string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewPassword string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetPassword", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetAutoDisconnectTime(ctx context.Context) (NewAutoDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewAutoDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetIdleDisconnectTime(ctx context.Context) (NewIdleDisconnectTime uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewIdleDisconnectTime string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetWarnDisconnectDelay(ctx context.Context) (NewWarnDisconnectDelay uint32, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewWarnDisconnectDelay string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetNATRSIPStatus(ctx context.Context) (NewRSIPAvailable bool, NewNATEnabled bool, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRSIPAvailable string - NewNATEnabled string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil { - return - } - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Return values: -// -// * NewProtocol: allowed values: TCP, UDP -func (client *WANPPPConnection1) GetGenericPortMappingEntry(ctx context.Context, NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewPortMappingIndex string - }{} - // BEGIN Marshal arguments into request. - - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil { - return - } - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil { - return - } - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil { - return - } - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANPPPConnection1) GetSpecificPortMappingEntry(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil { - return - } - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil { - return - } - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil { - return - } - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil { - return - } - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil { - return - } - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANPPPConnection1) AddPortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - NewInternalPort string - NewInternalClient string - NewEnabled string - NewPortMappingDescription string - NewLeaseDuration string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil { - return - } - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil { - return - } - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil { - return - } - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil { - return - } - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -// -// Arguments: -// -// * NewProtocol: allowed values: TCP, UDP - -func (client *WANPPPConnection1) DeletePortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { - // Request structure. - request := &struct { - NewRemoteHost string - NewExternalPort string - NewProtocol string - }{} - // BEGIN Marshal arguments into request. - - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil { - return - } - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil { - return - } - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil { - return - } - // END Marshal arguments into request. - - // Response structure. - response := interface{}(nil) - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - // END Unmarshal arguments from response. - return -} - -func (client *WANPPPConnection1) GetExternalIPAddress(ctx context.Context) (NewExternalIPAddress string, err error) { - // Request structure. - request := interface{}(nil) - // BEGIN Marshal arguments into request. - - // END Marshal arguments into request. - - // Response structure. - response := &struct { - NewExternalIPAddress string - }{} - - // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { - return - } - - // BEGIN Unmarshal arguments from response. - - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil { - return - } - // END Unmarshal arguments from response. - return -} diff --git a/vendor/github.com/tailscale/goupnp/httpu/multiclient.go b/vendor/github.com/tailscale/goupnp/httpu/multiclient.go deleted file mode 100644 index 9a8acd8..0000000 --- a/vendor/github.com/tailscale/goupnp/httpu/multiclient.go +++ /dev/null @@ -1,72 +0,0 @@ -package httpu - -import ( - "net/http" - - "golang.org/x/sync/errgroup" -) - -// MultiClient dispatches requests out to all the delegated clients. -type MultiClient struct { - // The HTTPU clients to delegate to. - delegates []ClientInterface -} - -var _ ClientInterface = &MultiClient{} - -// NewMultiClient creates a new MultiClient that delegates to all the given -// clients. -func NewMultiClient(delegates []ClientInterface) *MultiClient { - return &MultiClient{delegates: delegates} -} - -func (mc *MultiClient) Close() error { - for _, d := range mc.delegates { - d.Close() - } - return nil -} - -// Do implements ClientInterface.Do. -func (mc *MultiClient) Do( - req *http.Request, - numSends int, -) ([]*http.Response, error) { - tasks := &errgroup.Group{} - - results := make(chan []*http.Response) - tasks.Go(func() error { - defer close(results) - return mc.sendRequests(results, req, numSends) - }) - - var responses []*http.Response - tasks.Go(func() error { - for rs := range results { - responses = append(responses, rs...) - } - return nil - }) - - return responses, tasks.Wait() -} - -func (mc *MultiClient) sendRequests( - results chan<- []*http.Response, - req *http.Request, - numSends int, -) error { - tasks := &errgroup.Group{} - for _, d := range mc.delegates { - d := d // copy for closure - tasks.Go(func() error { - responses, err := d.Do(req, numSends) - if err != nil { - return err - } - results <- responses - return nil - }) - } - return tasks.Wait() -} diff --git a/vendor/github.com/tailscale/goupnp/service_client.go b/vendor/github.com/tailscale/goupnp/service_client.go deleted file mode 100644 index c858ed1..0000000 --- a/vendor/github.com/tailscale/goupnp/service_client.go +++ /dev/null @@ -1,88 +0,0 @@ -package goupnp - -import ( - "context" - "fmt" - "net/url" - - "github.com/tailscale/goupnp/soap" -) - -// ServiceClient is a SOAP client, root device and the service for the SOAP -// client rolled into one value. The root device, location, and service are -// intended to be informational. Location can be used to later recreate a -// ServiceClient with NewServiceClientByURL if the service is still present; -// bypassing the discovery process. -type ServiceClient struct { - SOAPClient *soap.SOAPClient - RootDevice *RootDevice - Location *url.URL - Service *Service -} - -// NewServiceClients discovers services, and returns clients for them. err will -// report any error with the discovery process (blocking any device/service -// discovery), errors reports errors on a per-root-device basis. -func NewServiceClients(ctx context.Context, searchTarget string) (clients []ServiceClient, errors []error, err error) { - var maybeRootDevices []MaybeRootDevice - if maybeRootDevices, err = DiscoverDevices(ctx, searchTarget); err != nil { - return - } - - clients = make([]ServiceClient, 0, len(maybeRootDevices)) - - for _, maybeRootDevice := range maybeRootDevices { - if maybeRootDevice.Err != nil { - errors = append(errors, maybeRootDevice.Err) - continue - } - - deviceClients, err := NewServiceClientsFromRootDevice(ctx, maybeRootDevice.Root, maybeRootDevice.Location, searchTarget) - if err != nil { - errors = append(errors, err) - continue - } - clients = append(clients, deviceClients...) - } - - return -} - -// NewServiceClientsByURL creates client(s) for the given service URN, for a -// root device at the given URL. -func NewServiceClientsByURL(ctx context.Context, loc *url.URL, searchTarget string) ([]ServiceClient, error) { - rootDevice, err := DeviceByURL(ctx, loc) - if err != nil { - return nil, err - } - return NewServiceClientsFromRootDevice(ctx, rootDevice, loc, searchTarget) -} - -// NewServiceClientsFromDevice creates client(s) for the given service URN, in -// a given root device. The loc parameter is simply assigned to the -// Location attribute of the returned ServiceClient(s). -func NewServiceClientsFromRootDevice(ctx context.Context, rootDevice *RootDevice, loc *url.URL, searchTarget string) ([]ServiceClient, error) { - device := &rootDevice.Device - srvs := device.FindService(ctx, searchTarget) - if len(srvs) == 0 { - return nil, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)", - searchTarget, device.FriendlyName, device.UDN) - } - clients := make([]ServiceClient, 0, len(srvs)) - for _, srv := range srvs { - clients = append(clients, ServiceClient{ - SOAPClient: srv.NewSOAPClient(httpClient(ctx)), - RootDevice: rootDevice, - Location: loc, - Service: srv, - }) - } - return clients, nil -} - -// GetServiceClient returns the ServiceClient itself. This is provided so that the -// service client attributes can be accessed via an interface method on a -// wrapping type. -func (client *ServiceClient) GetServiceClient() *ServiceClient { - return client -} diff --git a/vendor/github.com/tailscale/goupnp/ssdp/ssdp.go b/vendor/github.com/tailscale/goupnp/ssdp/ssdp.go deleted file mode 100644 index cdb6f4a..0000000 --- a/vendor/github.com/tailscale/goupnp/ssdp/ssdp.go +++ /dev/null @@ -1,113 +0,0 @@ -package ssdp - -import ( - "context" - "log" - "net/http" - "net/url" - "strconv" - "time" -) - -const ( - ssdpDiscover = `"ssdp:discover"` - ntsAlive = `ssdp:alive` - ntsByebye = `ssdp:byebye` - ntsUpdate = `ssdp:update` - ssdpUDP4Addr = "239.255.255.250:1900" - ssdpSearchPort = 1900 - methodSearch = "M-SEARCH" - methodNotify = "NOTIFY" - - // SSDPAll is a value for searchTarget that searches for all devices and services. - SSDPAll = "ssdp:all" - // UPNPRootDevice is a value for searchTarget that searches for all root devices. - UPNPRootDevice = "upnp:rootdevice" -) - -// HTTPUClient is the interface required to perform HTTP-over-UDP requests. -type HTTPUClient interface { - Do(req *http.Request, numSends int) ([]*http.Response, error) -} - -func max(a, b int64) int64 { - if a > b { - return a - } - return b -} - -// SSDPRawSearch performs a fairly raw SSDP search request, and returns the -// unique response(s) that it receives. Each response has the requested -// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to -// wait for responses in seconds, and must be a minimum of 1 (the -// implementation waits an additional 100ms for responses to arrive), 2 is a -// reasonable value for this. numSends is the number of requests to send - 3 is -// a reasonable value for this. -func SSDPRawSearch( - ctx context.Context, - httpu HTTPUClient, - searchTarget string, - numSends int, -) ([]*http.Response, error) { - // Must specify at least 1 second according to the spec. - var wait int64 = 1 - // https://openconnectivity.org/upnp-specs/UPnP-arch-DeviceArchitecture-v2.0-20200417.pdf - if deadline, ok := ctx.Deadline(); ok { - wait = max(wait, int64(time.Until(deadline).Seconds())) - } - - header := http.Header{ - // Putting headers in here avoids them being title-cased. - // (The UPnP discovery protocol uses case-sensitive headers) - "HOST": []string{ssdpUDP4Addr}, - "MAN": []string{ssdpDiscover}, - "MX": []string{strconv.FormatInt(wait, 10)}, - "ST": []string{searchTarget}, - } - - req := &http.Request{ - Method: methodSearch, - // TODO: Support both IPv4 and IPv6. - Host: ssdpUDP4Addr, - URL: &url.URL{Opaque: "*"}, - Header: header, - } - ctx, cancel := context.WithTimeout(ctx, time.Duration(wait)*time.Second) - defer cancel() - req = req.WithContext(ctx) - allResponses, err := httpu.Do(req, numSends) - if err != nil { - return nil, err - } - - isExactSearch := searchTarget != SSDPAll && searchTarget != UPNPRootDevice - - seenUSNs := make(map[string]bool) - var responses []*http.Response - for _, response := range allResponses { - if response.StatusCode != 200 { - log.Printf("ssdp: got response status code %q in search response", response.Status) - continue - } - if st := response.Header.Get("ST"); isExactSearch && st != searchTarget { - continue - } - usn := response.Header.Get("USN") - if usn == "" { - // Empty/missing USN in search response - using location instead. - location, err := response.Location() - if err != nil { - // No usable location in search response - discard. - continue - } - usn = location.String() - } - if _, alreadySeen := seenUSNs[usn]; !alreadySeen { - seenUSNs[usn] = true - responses = append(responses, response) - } - } - - return responses, nil -} diff --git a/vendor/github.com/tailscale/netlink/.gitignore b/vendor/github.com/tailscale/netlink/.gitignore deleted file mode 100644 index 9f11b75..0000000 --- a/vendor/github.com/tailscale/netlink/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.idea/ diff --git a/vendor/github.com/tailscale/netlink/.travis.yml b/vendor/github.com/tailscale/netlink/.travis.yml deleted file mode 100644 index 9565b49..0000000 --- a/vendor/github.com/tailscale/netlink/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: go -go: - - "1.12.x" - - "1.13.x" - - "1.14.x" -before_script: - # make sure we keep path in tact when we sudo - - sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers - # modprobe ip_gre or else the first gre device can't be deleted - - sudo modprobe ip_gre - # modprobe nf_conntrack for the conntrack testing - - sudo modprobe nf_conntrack - - sudo modprobe nf_conntrack_netlink - - sudo modprobe nf_conntrack_ipv4 - - sudo modprobe nf_conntrack_ipv6 - - sudo modprobe sch_hfsc - - sudo modprobe sch_sfq -install: - - go get -v -t ./... -go_import_path: github.com/tailscale/netlink diff --git a/vendor/github.com/tailscale/netlink/CHANGELOG.md b/vendor/github.com/tailscale/netlink/CHANGELOG.md deleted file mode 100644 index b11e59f..0000000 --- a/vendor/github.com/tailscale/netlink/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -## 1.0.0 (2018-03-15) - -Initial release tagging \ No newline at end of file diff --git a/vendor/github.com/tailscale/netlink/LICENSE b/vendor/github.com/tailscale/netlink/LICENSE deleted file mode 100644 index 9f64db8..0000000 --- a/vendor/github.com/tailscale/netlink/LICENSE +++ /dev/null @@ -1,192 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014 Vishvananda Ishaya. - Copyright 2014 Docker, Inc. - - 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. diff --git a/vendor/github.com/tailscale/netlink/Makefile b/vendor/github.com/tailscale/netlink/Makefile deleted file mode 100644 index 1b210be..0000000 --- a/vendor/github.com/tailscale/netlink/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -DIRS := \ - . \ - nl - -DEPS = \ - github.com/vishvananda/netns \ - golang.org/x/sys/unix - -uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) -testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go)))) -goroot = $(addprefix ../../../,$(1)) -unroot = $(subst ../../../,,$(1)) -fmt = $(addprefix fmt-,$(1)) - -all: test - -$(call goroot,$(DEPS)): - go get $(call unroot,$@) - -.PHONY: $(call testdirs,$(DIRS)) -$(call testdirs,$(DIRS)): - go test -test.exec sudo -test.parallel 4 -timeout 60s -test.v github.com/tailscale/netlink/$@ - -$(call fmt,$(call testdirs,$(DIRS))): - ! gofmt -l $(subst fmt-,,$@)/*.go | grep -q . - -.PHONY: fmt -fmt: $(call fmt,$(call testdirs,$(DIRS))) - -test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS)) diff --git a/vendor/github.com/tailscale/netlink/README.md b/vendor/github.com/tailscale/netlink/README.md deleted file mode 100644 index 101084b..0000000 --- a/vendor/github.com/tailscale/netlink/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# netlink - netlink library for go # - -[![Build Status](https://app.travis-ci.com/vishvananda/netlink.svg?branch=master)](https://app.travis-ci.com/github/vishvananda/netlink) [![GoDoc](https://godoc.org/github.com/tailscale/netlink?status.svg)](https://godoc.org/github.com/tailscale/netlink) - -The netlink package provides a simple netlink library for go. Netlink -is the interface a user-space program in linux uses to communicate with -the kernel. It can be used to add and remove interfaces, set ip addresses -and routes, and configure ipsec. Netlink communication requires elevated -privileges, so in most cases this code needs to be run as root. Since -low-level netlink messages are inscrutable at best, the library attempts -to provide an api that is loosely modeled on the CLI provided by iproute2. -Actions like `ip link add` will be accomplished via a similarly named -function like AddLink(). This library began its life as a fork of the -netlink functionality in -[docker/libcontainer](https://github.com/docker/libcontainer) but was -heavily rewritten to improve testability, performance, and to add new -functionality like ipsec xfrm handling. - -## Local Build and Test ## - -You can use go get command: - - go get github.com/tailscale/netlink - -Testing dependencies: - - go get github.com/vishvananda/netns - -Testing (requires root): - - sudo -E go test github.com/tailscale/netlink - -## Examples ## - -Add a new bridge and add eth1 into it: - -```go -package main - -import ( - "fmt" - "github.com/tailscale/netlink" -) - -func main() { - la := netlink.NewLinkAttrs() - la.Name = "foo" - mybridge := &netlink.Bridge{LinkAttrs: la} - err := netlink.LinkAdd(mybridge) - if err != nil { - fmt.Printf("could not add %s: %v\n", la.Name, err) - } - eth1, _ := netlink.LinkByName("eth1") - netlink.LinkSetMaster(eth1, mybridge) -} - -``` -Note `NewLinkAttrs` constructor, it sets default values in structure. For now -it sets only `TxQLen` to `-1`, so kernel will set default by itself. If you're -using simple initialization(`LinkAttrs{Name: "foo"}`) `TxQLen` will be set to -`0` unless you specify it like `LinkAttrs{Name: "foo", TxQLen: 1000}`. - -Add a new ip address to loopback: - -```go -package main - -import ( - "github.com/tailscale/netlink" -) - -func main() { - lo, _ := netlink.LinkByName("lo") - addr, _ := netlink.ParseAddr("169.254.169.254/32") - netlink.AddrAdd(lo, addr) -} - -``` - -## Future Work ## - -Many pieces of netlink are not yet fully supported in the high-level -interface. Aspects of virtually all of the high-level objects don't exist. -Many of the underlying primitives are there, so its a matter of putting -the right fields into the high-level objects and making sure that they -are serialized and deserialized correctly in the Add and List methods. - -There are also a few pieces of low level netlink functionality that still -need to be implemented. Routing rules are not in place and some of the -more advanced link types. Hopefully there is decent structure and testing -in place to make these fairly straightforward to add. - diff --git a/vendor/github.com/tailscale/netlink/addr.go b/vendor/github.com/tailscale/netlink/addr.go deleted file mode 100644 index 653f540..0000000 --- a/vendor/github.com/tailscale/netlink/addr.go +++ /dev/null @@ -1,57 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "strings" -) - -// Addr represents an IP address from netlink. Netlink ip addresses -// include a mask, so it stores the address as a net.IPNet. -type Addr struct { - *net.IPNet - Label string - Flags int - Scope int - Peer *net.IPNet - Broadcast net.IP - PreferedLft int - ValidLft int - LinkIndex int -} - -// String returns $ip/$netmask $label -func (a Addr) String() string { - return strings.TrimSpace(fmt.Sprintf("%s %s", a.IPNet, a.Label)) -} - -// ParseAddr parses the string representation of an address in the -// form $ip/$netmask $label. The label portion is optional -func ParseAddr(s string) (*Addr, error) { - label := "" - parts := strings.Split(s, " ") - if len(parts) > 1 { - s = parts[0] - label = parts[1] - } - m, err := ParseIPNet(s) - if err != nil { - return nil, err - } - return &Addr{IPNet: m, Label: label}, nil -} - -// Equal returns true if both Addrs have the same net.IPNet value. -func (a Addr) Equal(x Addr) bool { - sizea, _ := a.Mask.Size() - sizeb, _ := x.Mask.Size() - // ignore label for comparison - return a.IP.Equal(x.IP) && sizea == sizeb -} - -func (a Addr) PeerEqual(x Addr) bool { - sizea, _ := a.Peer.Mask.Size() - sizeb, _ := x.Peer.Mask.Size() - // ignore label for comparison - return a.Peer.IP.Equal(x.Peer.IP) && sizea == sizeb -} diff --git a/vendor/github.com/tailscale/netlink/addr_linux.go b/vendor/github.com/tailscale/netlink/addr_linux.go deleted file mode 100644 index 118d054..0000000 --- a/vendor/github.com/tailscale/netlink/addr_linux.go +++ /dev/null @@ -1,414 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "strings" - "syscall" - - "github.com/tailscale/netlink/nl" - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -// AddrAdd will add an IP address to a link device. -// -// Equivalent to: `ip addr add $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func AddrAdd(link Link, addr *Addr) error { - return pkgHandle.AddrAdd(link, addr) -} - -// AddrAdd will add an IP address to a link device. -// -// Equivalent to: `ip addr add $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func (h *Handle) AddrAdd(link Link, addr *Addr) error { - req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) - return h.addrHandle(link, addr, req) -} - -// AddrReplace will replace (or, if not present, add) an IP address on a link device. -// -// Equivalent to: `ip addr replace $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func AddrReplace(link Link, addr *Addr) error { - return pkgHandle.AddrReplace(link, addr) -} - -// AddrReplace will replace (or, if not present, add) an IP address on a link device. -// -// Equivalent to: `ip addr replace $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func (h *Handle) AddrReplace(link Link, addr *Addr) error { - req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK) - return h.addrHandle(link, addr, req) -} - -// AddrDel will delete an IP address from a link device. -// -// Equivalent to: `ip addr del $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func AddrDel(link Link, addr *Addr) error { - return pkgHandle.AddrDel(link, addr) -} - -// AddrDel will delete an IP address from a link device. -// Equivalent to: `ip addr del $addr dev $link` -// -// If `addr` is an IPv4 address and the broadcast address is not given, it -// will be automatically computed based on the IP mask if /30 or larger. -func (h *Handle) AddrDel(link Link, addr *Addr) error { - req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK) - return h.addrHandle(link, addr, req) -} - -func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error { - base := link.Attrs() - if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) { - return fmt.Errorf("label must begin with interface name") - } - h.ensureIndex(base) - - family := nl.GetIPFamily(addr.IP) - - msg := nl.NewIfAddrmsg(family) - msg.Index = uint32(base.Index) - msg.Scope = uint8(addr.Scope) - mask := addr.Mask - if addr.Peer != nil { - mask = addr.Peer.Mask - } - prefixlen, masklen := mask.Size() - msg.Prefixlen = uint8(prefixlen) - req.AddData(msg) - - var localAddrData []byte - if family == FAMILY_V4 { - localAddrData = addr.IP.To4() - } else { - localAddrData = addr.IP.To16() - } - - localData := nl.NewRtAttr(unix.IFA_LOCAL, localAddrData) - req.AddData(localData) - var peerAddrData []byte - if addr.Peer != nil { - if family == FAMILY_V4 { - peerAddrData = addr.Peer.IP.To4() - } else { - peerAddrData = addr.Peer.IP.To16() - } - } else { - peerAddrData = localAddrData - } - - addressData := nl.NewRtAttr(unix.IFA_ADDRESS, peerAddrData) - req.AddData(addressData) - - if addr.Flags != 0 { - if addr.Flags <= 0xff { - msg.IfAddrmsg.Flags = uint8(addr.Flags) - } else { - b := make([]byte, 4) - native.PutUint32(b, uint32(addr.Flags)) - flagsData := nl.NewRtAttr(unix.IFA_FLAGS, b) - req.AddData(flagsData) - } - } - - if family == FAMILY_V4 { - // Automatically set the broadcast address if it is unset and the - // subnet is large enough to sensibly have one (/30 or larger). - // See: RFC 3021 - if addr.Broadcast == nil && prefixlen < 31 { - calcBroadcast := make(net.IP, masklen/8) - for i := range localAddrData { - calcBroadcast[i] = localAddrData[i] | ^mask[i] - } - addr.Broadcast = calcBroadcast - } - - if addr.Broadcast != nil { - req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast)) - } - - if addr.Label != "" { - labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label)) - req.AddData(labelData) - } - } - - // 0 is the default value for these attributes. However, 0 means "expired", while the least-surprising default - // value should be "forever". To compensate for that, only add the attributes if at least one of the values is - // non-zero, which means the caller has explicitly set them - if addr.ValidLft > 0 || addr.PreferedLft > 0 { - cachedata := nl.IfaCacheInfo{unix.IfaCacheinfo{ - Valid: uint32(addr.ValidLft), - Prefered: uint32(addr.PreferedLft), - }} - req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize())) - } - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// AddrList gets a list of IP addresses in the system. -// Equivalent to: `ip addr show`. -// The list can be filtered by link and ip family. -func AddrList(link Link, family int) ([]Addr, error) { - return pkgHandle.AddrList(link, family) -} - -// AddrList gets a list of IP addresses in the system. -// Equivalent to: `ip addr show`. -// The list can be filtered by link and ip family. -func (h *Handle) AddrList(link Link, family int) ([]Addr, error) { - req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP) - msg := nl.NewIfInfomsg(family) - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR) - if err != nil { - return nil, err - } - - indexFilter := 0 - if link != nil { - base := link.Attrs() - h.ensureIndex(base) - indexFilter = base.Index - } - - var res []Addr - for _, m := range msgs { - addr, msgFamily, err := parseAddr(m) - if err != nil { - return res, err - } - - if link != nil && addr.LinkIndex != indexFilter { - // Ignore messages from other interfaces - continue - } - - if family != FAMILY_ALL && msgFamily != family { - continue - } - - res = append(res, addr) - } - - return res, nil -} - -func parseAddr(m []byte) (addr Addr, family int, err error) { - msg := nl.DeserializeIfAddrmsg(m) - - family = -1 - addr.LinkIndex = -1 - - attrs, err1 := nl.ParseRouteAttr(m[msg.Len():]) - if err1 != nil { - err = err1 - return - } - - family = int(msg.Family) - addr.LinkIndex = int(msg.Index) - - var local, dst *net.IPNet - for _, attr := range attrs { - switch attr.Attr.Type { - case unix.IFA_ADDRESS: - dst = &net.IPNet{ - IP: attr.Value, - Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), - } - case unix.IFA_LOCAL: - // iproute2 manual: - // If a peer address is specified, the local address - // cannot have a prefix length. The network prefix is - // associated with the peer rather than with the local - // address. - n := 8 * len(attr.Value) - local = &net.IPNet{ - IP: attr.Value, - Mask: net.CIDRMask(n, n), - } - case unix.IFA_BROADCAST: - addr.Broadcast = attr.Value - case unix.IFA_LABEL: - addr.Label = string(attr.Value[:len(attr.Value)-1]) - case unix.IFA_FLAGS: - addr.Flags = int(native.Uint32(attr.Value[0:4])) - case unix.IFA_CACHEINFO: - ci := nl.DeserializeIfaCacheInfo(attr.Value) - addr.PreferedLft = int(ci.Prefered) - addr.ValidLft = int(ci.Valid) - } - } - - // libnl addr.c comment: - // IPv6 sends the local address as IFA_ADDRESS with no - // IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS - // with IFA_ADDRESS being the peer address if they differ - // - // But obviously, as there are IPv6 PtP addresses, too, - // IFA_LOCAL should also be handled for IPv6. - if local != nil { - if family == FAMILY_V4 && dst != nil && local.IP.Equal(dst.IP) { - addr.IPNet = dst - } else { - addr.IPNet = local - addr.Peer = dst - } - } else { - addr.IPNet = dst - } - - addr.Scope = int(msg.Scope) - - return -} - -type AddrUpdate struct { - LinkAddress net.IPNet - LinkIndex int - Flags int - Scope int - PreferedLft int - ValidLft int - NewAddr bool // true=added false=deleted -} - -// AddrSubscribe takes a chan down which notifications will be sent -// when addresses change. Close the 'done' chan to stop subscription. -func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error { - return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0) -} - -// AddrSubscribeAt works like AddrSubscribe plus it allows the caller -// to choose the network namespace in which to subscribe (ns). -func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error { - return addrSubscribeAt(ns, netns.None(), ch, done, nil, false, 0) -} - -// AddrSubscribeOptions contains a set of options to use with -// AddrSubscribeWithOptions. -type AddrSubscribeOptions struct { - Namespace *netns.NsHandle - ErrorCallback func(error) - ListExisting bool - ReceiveBufferSize int -} - -// AddrSubscribeWithOptions work like AddrSubscribe but enable to -// provide additional options to modify the behavior. Currently, the -// namespace can be provided as well as an error callback. -func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, options AddrSubscribeOptions) error { - if options.Namespace == nil { - none := netns.None() - options.Namespace = &none - } - return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting, options.ReceiveBufferSize) -} - -func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool, rcvbuf int) error { - s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR) - if err != nil { - return err - } - if done != nil { - go func() { - <-done - s.Close() - }() - } - if rcvbuf != 0 { - err = pkgHandle.SetSocketReceiveBufferSize(rcvbuf, false) - if err != nil { - return err - } - } - if listExisting { - req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR, - unix.NLM_F_DUMP) - infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(infmsg) - if err := s.Send(req); err != nil { - return err - } - } - go func() { - defer close(ch) - for { - msgs, from, err := s.Receive() - if err != nil { - if cberr != nil { - cberr(fmt.Errorf("Receive failed: %v", - err)) - } - return - } - if from.Pid != nl.PidKernel { - if cberr != nil { - cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)) - } - continue - } - for _, m := range msgs { - if m.Header.Type == unix.NLMSG_DONE { - continue - } - if m.Header.Type == unix.NLMSG_ERROR { - error := int32(native.Uint32(m.Data[0:4])) - if error == 0 { - continue - } - if cberr != nil { - cberr(fmt.Errorf("error message: %v", - syscall.Errno(-error))) - } - continue - } - msgType := m.Header.Type - if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR { - if cberr != nil { - cberr(fmt.Errorf("bad message type: %d", msgType)) - } - continue - } - - addr, _, err := parseAddr(m.Data) - if err != nil { - if cberr != nil { - cberr(fmt.Errorf("could not parse address: %v", err)) - } - continue - } - - ch <- AddrUpdate{LinkAddress: *addr.IPNet, - LinkIndex: addr.LinkIndex, - NewAddr: msgType == unix.RTM_NEWADDR, - Flags: addr.Flags, - Scope: addr.Scope, - PreferedLft: addr.PreferedLft, - ValidLft: addr.ValidLft} - } - } - }() - - return nil -} diff --git a/vendor/github.com/tailscale/netlink/bpf_linux.go b/vendor/github.com/tailscale/netlink/bpf_linux.go deleted file mode 100644 index 96befbf..0000000 --- a/vendor/github.com/tailscale/netlink/bpf_linux.go +++ /dev/null @@ -1,77 +0,0 @@ -package netlink - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -type BpfProgType uint32 - -const ( - BPF_PROG_TYPE_UNSPEC BpfProgType = iota - BPF_PROG_TYPE_SOCKET_FILTER - BPF_PROG_TYPE_KPROBE - BPF_PROG_TYPE_SCHED_CLS - BPF_PROG_TYPE_SCHED_ACT - BPF_PROG_TYPE_TRACEPOINT - BPF_PROG_TYPE_XDP - BPF_PROG_TYPE_PERF_EVENT - BPF_PROG_TYPE_CGROUP_SKB - BPF_PROG_TYPE_CGROUP_SOCK - BPF_PROG_TYPE_LWT_IN - BPF_PROG_TYPE_LWT_OUT - BPF_PROG_TYPE_LWT_XMIT - BPF_PROG_TYPE_SOCK_OPS - BPF_PROG_TYPE_SK_SKB - BPF_PROG_TYPE_CGROUP_DEVICE - BPF_PROG_TYPE_SK_MSG - BPF_PROG_TYPE_RAW_TRACEPOINT - BPF_PROG_TYPE_CGROUP_SOCK_ADDR - BPF_PROG_TYPE_LWT_SEG6LOCAL - BPF_PROG_TYPE_LIRC_MODE2 - BPF_PROG_TYPE_SK_REUSEPORT - BPF_PROG_TYPE_FLOW_DISSECTOR - BPF_PROG_TYPE_CGROUP_SYSCTL - BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE - BPF_PROG_TYPE_CGROUP_SOCKOPT - BPF_PROG_TYPE_TRACING - BPF_PROG_TYPE_STRUCT_OPS - BPF_PROG_TYPE_EXT - BPF_PROG_TYPE_LSM - BPF_PROG_TYPE_SK_LOOKUP -) - -type BPFAttr struct { - ProgType uint32 - InsnCnt uint32 - Insns uintptr - License uintptr - LogLevel uint32 - LogSize uint32 - LogBuf uintptr - KernVersion uint32 -} - -// loadSimpleBpf loads a trivial bpf program for testing purposes. -func loadSimpleBpf(progType BpfProgType, ret uint32) (int, error) { - insns := []uint64{ - 0x00000000000000b7 | (uint64(ret) << 32), - 0x0000000000000095, - } - license := []byte{'A', 'S', 'L', '2', '\x00'} - attr := BPFAttr{ - ProgType: uint32(progType), - InsnCnt: uint32(len(insns)), - Insns: uintptr(unsafe.Pointer(&insns[0])), - License: uintptr(unsafe.Pointer(&license[0])), - } - fd, _, errno := unix.Syscall(unix.SYS_BPF, - 5, /* bpf cmd */ - uintptr(unsafe.Pointer(&attr)), - unsafe.Sizeof(attr)) - if errno != 0 { - return 0, errno - } - return int(fd), nil -} diff --git a/vendor/github.com/tailscale/netlink/bridge_linux.go b/vendor/github.com/tailscale/netlink/bridge_linux.go deleted file mode 100644 index d03f856..0000000 --- a/vendor/github.com/tailscale/netlink/bridge_linux.go +++ /dev/null @@ -1,112 +0,0 @@ -package netlink - -import ( - "fmt" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// BridgeVlanList gets a map of device id to bridge vlan infos. -// Equivalent to: `bridge vlan show` -func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { - return pkgHandle.BridgeVlanList() -} - -// BridgeVlanList gets a map of device id to bridge vlan infos. -// Equivalent to: `bridge vlan show` -func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) - msg := nl.NewIfInfomsg(unix.AF_BRIDGE) - req.AddData(msg) - req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN)))) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) - if err != nil { - return nil, err - } - ret := make(map[int32][]*nl.BridgeVlanInfo) - for _, m := range msgs { - msg := nl.DeserializeIfInfomsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - for _, attr := range attrs { - switch attr.Attr.Type { - case unix.IFLA_AF_SPEC: - //nested attr - nestAttrs, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, fmt.Errorf("failed to parse nested attr %v", err) - } - for _, nestAttr := range nestAttrs { - switch nestAttr.Attr.Type { - case nl.IFLA_BRIDGE_VLAN_INFO: - vlanInfo := nl.DeserializeBridgeVlanInfo(nestAttr.Value) - ret[msg.Index] = append(ret[msg.Index], vlanInfo) - } - } - } - } - } - return ret, nil -} - -// BridgeVlanAdd adds a new vlan filter entry -// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` -func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { - return pkgHandle.BridgeVlanAdd(link, vid, pvid, untagged, self, master) -} - -// BridgeVlanAdd adds a new vlan filter entry -// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` -func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master) -} - -// BridgeVlanDel adds a new vlan filter entry -// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` -func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error { - return pkgHandle.BridgeVlanDel(link, vid, pvid, untagged, self, master) -} - -// BridgeVlanDel adds a new vlan filter entry -// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` -func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master) -} - -func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_BRIDGE) - msg.Index = int32(base.Index) - req.AddData(msg) - - br := nl.NewRtAttr(unix.IFLA_AF_SPEC, nil) - var flags uint16 - if self { - flags |= nl.BRIDGE_FLAGS_SELF - } - if master { - flags |= nl.BRIDGE_FLAGS_MASTER - } - if flags > 0 { - br.AddRtAttr(nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags)) - } - vlanInfo := &nl.BridgeVlanInfo{Vid: vid} - if pvid { - vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID - } - if untagged { - vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED - } - br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) - req.AddData(br) - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} diff --git a/vendor/github.com/tailscale/netlink/class.go b/vendor/github.com/tailscale/netlink/class.go deleted file mode 100644 index 10ceffe..0000000 --- a/vendor/github.com/tailscale/netlink/class.go +++ /dev/null @@ -1,239 +0,0 @@ -package netlink - -import ( - "fmt" -) - -// Class interfaces for all classes -type Class interface { - Attrs() *ClassAttrs - Type() string -} - -// Generic networking statistics for netlink users. -// This file contains "gnet_" prefixed structs and relevant functions. -// See Documentation/networking/getn_stats.txt in Linux source code for more details. - -// GnetStatsBasic Ref: struct gnet_stats_basic { ... } -type GnetStatsBasic struct { - Bytes uint64 // number of seen bytes - Packets uint32 // number of seen packets -} - -// GnetStatsRateEst Ref: struct gnet_stats_rate_est { ... } -type GnetStatsRateEst struct { - Bps uint32 // current byte rate - Pps uint32 // current packet rate -} - -// GnetStatsRateEst64 Ref: struct gnet_stats_rate_est64 { ... } -type GnetStatsRateEst64 struct { - Bps uint64 // current byte rate - Pps uint64 // current packet rate -} - -// GnetStatsQueue Ref: struct gnet_stats_queue { ... } -type GnetStatsQueue struct { - Qlen uint32 // queue length - Backlog uint32 // backlog size of queue - Drops uint32 // number of dropped packets - Requeues uint32 // number of requues - Overlimits uint32 // number of enqueues over the limit -} - -// ClassStatistics representation based on generic networking statistics for netlink. -// See Documentation/networking/gen_stats.txt in Linux source code for more details. -type ClassStatistics struct { - Basic *GnetStatsBasic - Queue *GnetStatsQueue - RateEst *GnetStatsRateEst -} - -// NewClassStatistics Construct a ClassStatistics struct which fields are all initialized by 0. -func NewClassStatistics() *ClassStatistics { - return &ClassStatistics{ - Basic: &GnetStatsBasic{}, - Queue: &GnetStatsQueue{}, - RateEst: &GnetStatsRateEst{}, - } -} - -// ClassAttrs represents a netlink class. A filter is associated with a link, -// has a handle and a parent. The root filter of a device should have a -// parent == HANDLE_ROOT. -type ClassAttrs struct { - LinkIndex int - Handle uint32 - Parent uint32 - Leaf uint32 - Statistics *ClassStatistics -} - -func (q ClassAttrs) String() string { - return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf) -} - -// HtbClassAttrs stores the attributes of HTB class -type HtbClassAttrs struct { - // TODO handle all attributes - Rate uint64 - Ceil uint64 - Buffer uint32 - Cbuffer uint32 - Quantum uint32 - Level uint32 - Prio uint32 -} - -func (q HtbClassAttrs) String() string { - return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) -} - -// HtbClass represents an Htb class -type HtbClass struct { - ClassAttrs - Rate uint64 - Ceil uint64 - Buffer uint32 - Cbuffer uint32 - Quantum uint32 - Level uint32 - Prio uint32 -} - -func (q HtbClass) String() string { - return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) -} - -// Attrs returns the class attributes -func (q *HtbClass) Attrs() *ClassAttrs { - return &q.ClassAttrs -} - -// Type return the class type -func (q *HtbClass) Type() string { - return "htb" -} - -// GenericClass classes represent types that are not currently understood -// by this netlink library. -type GenericClass struct { - ClassAttrs - ClassType string -} - -// Attrs return the class attributes -func (class *GenericClass) Attrs() *ClassAttrs { - return &class.ClassAttrs -} - -// Type return the class type -func (class *GenericClass) Type() string { - return class.ClassType -} - -// ServiceCurve is a nondecreasing function of some time unit, returning the amount of service -// (an allowed or allocated amount of bandwidth) at some specific point in time. The purpose of it -// should be subconsciously obvious: if a class was allowed to transfer not less than the amount -// specified by its service curve, then the service curve is not violated. -type ServiceCurve struct { - m1 uint32 - d uint32 - m2 uint32 -} - -// Attrs return the parameters of the service curve -func (c *ServiceCurve) Attrs() (uint32, uint32, uint32) { - return c.m1, c.d, c.m2 -} - -// Burst returns the burst rate (m1) of the curve -func (c *ServiceCurve) Burst() uint32 { - return c.m1 -} - -// Delay return the delay (d) of the curve -func (c *ServiceCurve) Delay() uint32 { - return c.d -} - -// Rate returns the rate (m2) of the curve -func (c *ServiceCurve) Rate() uint32 { - return c.m2 -} - -// HfscClass is a representation of the HFSC class -type HfscClass struct { - ClassAttrs - Rsc ServiceCurve - Fsc ServiceCurve - Usc ServiceCurve -} - -// SetUsc sets the USC curve. The bandwidth (m1 and m2) is specified in bits and the delay in -// seconds. -func (hfsc *HfscClass) SetUsc(m1 uint32, d uint32, m2 uint32) { - hfsc.Usc = ServiceCurve{m1: m1, d: d, m2: m2} -} - -// SetFsc sets the Fsc curve. The bandwidth (m1 and m2) is specified in bits and the delay in -// seconds. -func (hfsc *HfscClass) SetFsc(m1 uint32, d uint32, m2 uint32) { - hfsc.Fsc = ServiceCurve{m1: m1, d: d, m2: m2} -} - -// SetRsc sets the Rsc curve. The bandwidth (m1 and m2) is specified in bits and the delay in -// seconds. -func (hfsc *HfscClass) SetRsc(m1 uint32, d uint32, m2 uint32) { - hfsc.Rsc = ServiceCurve{m1: m1, d: d, m2: m2} -} - -// SetSC implements the SC from the `tc` CLI. This function behaves the same as if one would set the -// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and -// the delay in ms. -func (hfsc *HfscClass) SetSC(m1 uint32, d uint32, m2 uint32) { - hfsc.SetRsc(m1, d, m2) - hfsc.SetFsc(m1, d, m2) -} - -// SetUL implements the UL from the `tc` CLI. This function behaves the same as if one would set the -// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and -// the delay in ms. -func (hfsc *HfscClass) SetUL(m1 uint32, d uint32, m2 uint32) { - hfsc.SetUsc(m1, d, m2) -} - -// SetLS implements the LS from the `tc` CLI. This function behaves the same as if one would set the -// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and -// the delay in ms. -func (hfsc *HfscClass) SetLS(m1 uint32, d uint32, m2 uint32) { - hfsc.SetFsc(m1, d, m2) -} - -// NewHfscClass returns a new HFSC struct with the set parameters -func NewHfscClass(attrs ClassAttrs) *HfscClass { - return &HfscClass{ - ClassAttrs: attrs, - Rsc: ServiceCurve{}, - Fsc: ServiceCurve{}, - Usc: ServiceCurve{}, - } -} - -// String() returns a string that contains the information and attributes of the HFSC class -func (hfsc *HfscClass) String() string { - return fmt.Sprintf( - "{%s -- {RSC: {m1=%d d=%d m2=%d}} {FSC: {m1=%d d=%d m2=%d}} {USC: {m1=%d d=%d m2=%d}}}", - hfsc.Attrs(), hfsc.Rsc.m1*8, hfsc.Rsc.d, hfsc.Rsc.m2*8, hfsc.Fsc.m1*8, hfsc.Fsc.d, hfsc.Fsc.m2*8, hfsc.Usc.m1*8, hfsc.Usc.d, hfsc.Usc.m2*8, - ) -} - -// Attrs return the Hfsc parameters -func (hfsc *HfscClass) Attrs() *ClassAttrs { - return &hfsc.ClassAttrs -} - -// Type return the type of the class -func (hfsc *HfscClass) Type() string { - return "hfsc" -} diff --git a/vendor/github.com/tailscale/netlink/class_linux.go b/vendor/github.com/tailscale/netlink/class_linux.go deleted file mode 100644 index a576a74..0000000 --- a/vendor/github.com/tailscale/netlink/class_linux.go +++ /dev/null @@ -1,395 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// Internal tc_stats representation in Go struct. -// This is for internal uses only to deserialize the payload of rtattr. -// After the deserialization, this should be converted into the canonical stats -// struct, ClassStatistics, in case of statistics of a class. -// Ref: struct tc_stats { ... } -type tcStats struct { - Bytes uint64 // Number of enqueued bytes - Packets uint32 // Number of enqueued packets - Drops uint32 // Packets dropped because of lack of resources - Overlimits uint32 // Number of throttle events when this flow goes out of allocated bandwidth - Bps uint32 // Current flow byte rate - Pps uint32 // Current flow packet rate - Qlen uint32 - Backlog uint32 -} - -// NewHtbClass NOTE: function is in here because it uses other linux functions -func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass { - mtu := 1600 - rate := cattrs.Rate / 8 - ceil := cattrs.Ceil / 8 - buffer := cattrs.Buffer - cbuffer := cattrs.Cbuffer - - if ceil == 0 { - ceil = rate - } - - if buffer == 0 { - buffer = uint32(float64(rate)/Hz() + float64(mtu)) - } - buffer = Xmittime(rate, buffer) - - if cbuffer == 0 { - cbuffer = uint32(float64(ceil)/Hz() + float64(mtu)) - } - cbuffer = Xmittime(ceil, cbuffer) - - return &HtbClass{ - ClassAttrs: attrs, - Rate: rate, - Ceil: ceil, - Buffer: buffer, - Cbuffer: cbuffer, - Level: 0, - Prio: cattrs.Prio, - Quantum: cattrs.Quantum, - } -} - -// ClassDel will delete a class from the system. -// Equivalent to: `tc class del $class` -func ClassDel(class Class) error { - return pkgHandle.ClassDel(class) -} - -// ClassDel will delete a class from the system. -// Equivalent to: `tc class del $class` -func (h *Handle) ClassDel(class Class) error { - return h.classModify(unix.RTM_DELTCLASS, 0, class) -} - -// ClassChange will change a class in place -// Equivalent to: `tc class change $class` -// The parent and handle MUST NOT be changed. -func ClassChange(class Class) error { - return pkgHandle.ClassChange(class) -} - -// ClassChange will change a class in place -// Equivalent to: `tc class change $class` -// The parent and handle MUST NOT be changed. -func (h *Handle) ClassChange(class Class) error { - return h.classModify(unix.RTM_NEWTCLASS, 0, class) -} - -// ClassReplace will replace a class to the system. -// quivalent to: `tc class replace $class` -// The handle MAY be changed. -// If a class already exist with this parent/handle pair, the class is changed. -// If a class does not already exist with this parent/handle, a new class is created. -func ClassReplace(class Class) error { - return pkgHandle.ClassReplace(class) -} - -// ClassReplace will replace a class to the system. -// quivalent to: `tc class replace $class` -// The handle MAY be changed. -// If a class already exist with this parent/handle pair, the class is changed. -// If a class does not already exist with this parent/handle, a new class is created. -func (h *Handle) ClassReplace(class Class) error { - return h.classModify(unix.RTM_NEWTCLASS, unix.NLM_F_CREATE, class) -} - -// ClassAdd will add a class to the system. -// Equivalent to: `tc class add $class` -func ClassAdd(class Class) error { - return pkgHandle.ClassAdd(class) -} - -// ClassAdd will add a class to the system. -// Equivalent to: `tc class add $class` -func (h *Handle) ClassAdd(class Class) error { - return h.classModify( - unix.RTM_NEWTCLASS, - unix.NLM_F_CREATE|unix.NLM_F_EXCL, - class, - ) -} - -func (h *Handle) classModify(cmd, flags int, class Class) error { - req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) - base := class.Attrs() - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Ifindex: int32(base.LinkIndex), - Handle: base.Handle, - Parent: base.Parent, - } - req.AddData(msg) - - if cmd != unix.RTM_DELTCLASS { - if err := classPayload(req, class); err != nil { - return err - } - } - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func classPayload(req *nl.NetlinkRequest, class Class) error { - req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type()))) - - options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) - switch class.Type() { - case "htb": - htb := class.(*HtbClass) - opt := nl.TcHtbCopt{} - opt.Buffer = htb.Buffer - opt.Cbuffer = htb.Cbuffer - opt.Quantum = htb.Quantum - opt.Level = htb.Level - opt.Prio = htb.Prio - // TODO: Handle Debug properly. For now default to 0 - /* Calculate {R,C}Tab and set Rate and Ceil */ - cellLog := -1 - ccellLog := -1 - linklayer := nl.LINKLAYER_ETHERNET - mtu := 1600 - var rtab [256]uint32 - var ctab [256]uint32 - tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)} - if CalcRtable(&tcrate, rtab[:], cellLog, uint32(mtu), linklayer) < 0 { - return errors.New("HTB: failed to calculate rate table") - } - opt.Rate = tcrate - tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)} - if CalcRtable(&tcceil, ctab[:], ccellLog, uint32(mtu), linklayer) < 0 { - return errors.New("HTB: failed to calculate ceil rate table") - } - opt.Ceil = tcceil - options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize()) - options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab)) - options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab)) - if htb.Rate >= uint64(1<<32) { - options.AddRtAttr(nl.TCA_HTB_RATE64, nl.Uint64Attr(htb.Rate)) - } - if htb.Ceil >= uint64(1<<32) { - options.AddRtAttr(nl.TCA_HTB_CEIL64, nl.Uint64Attr(htb.Ceil)) - } - case "hfsc": - hfsc := class.(*HfscClass) - opt := nl.HfscCopt{} - rm1, rd, rm2 := hfsc.Rsc.Attrs() - opt.Rsc.Set(rm1/8, rd, rm2/8) - fm1, fd, fm2 := hfsc.Fsc.Attrs() - opt.Fsc.Set(fm1/8, fd, fm2/8) - um1, ud, um2 := hfsc.Usc.Attrs() - opt.Usc.Set(um1/8, ud, um2/8) - options.AddRtAttr(nl.TCA_HFSC_RSC, nl.SerializeHfscCurve(&opt.Rsc)) - options.AddRtAttr(nl.TCA_HFSC_FSC, nl.SerializeHfscCurve(&opt.Fsc)) - options.AddRtAttr(nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc)) - } - req.AddData(options) - return nil -} - -// ClassList gets a list of classes in the system. -// Equivalent to: `tc class show`. -// Generally returns nothing if link and parent are not specified. -func ClassList(link Link, parent uint32) ([]Class, error) { - return pkgHandle.ClassList(link, parent) -} - -// ClassList gets a list of classes in the system. -// Equivalent to: `tc class show`. -// Generally returns nothing if link and parent are not specified. -func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) { - req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP) - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Parent: parent, - } - if link != nil { - base := link.Attrs() - h.ensureIndex(base) - msg.Ifindex = int32(base.Index) - } - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS) - if err != nil { - return nil, err - } - - var res []Class - for _, m := range msgs { - msg := nl.DeserializeTcMsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - base := ClassAttrs{ - LinkIndex: int(msg.Ifindex), - Handle: msg.Handle, - Parent: msg.Parent, - Statistics: nil, - } - - var class Class - classType := "" - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.TCA_KIND: - classType = string(attr.Value[:len(attr.Value)-1]) - switch classType { - case "htb": - class = &HtbClass{} - case "hfsc": - class = &HfscClass{} - default: - class = &GenericClass{ClassType: classType} - } - case nl.TCA_OPTIONS: - switch classType { - case "htb": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - _, err = parseHtbClassData(class, data) - if err != nil { - return nil, err - } - case "hfsc": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - _, err = parseHfscClassData(class, data) - if err != nil { - return nil, err - } - } - // For backward compatibility. - case nl.TCA_STATS: - base.Statistics, err = parseTcStats(attr.Value) - if err != nil { - return nil, err - } - case nl.TCA_STATS2: - base.Statistics, err = parseTcStats2(attr.Value) - if err != nil { - return nil, err - } - } - } - *class.Attrs() = base - res = append(res, class) - } - - return res, nil -} - -func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) { - htb := class.(*HtbClass) - detailed := false - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_HTB_PARMS: - opt := nl.DeserializeTcHtbCopt(datum.Value) - htb.Rate = uint64(opt.Rate.Rate) - htb.Ceil = uint64(opt.Ceil.Rate) - htb.Buffer = opt.Buffer - htb.Cbuffer = opt.Cbuffer - htb.Quantum = opt.Quantum - htb.Level = opt.Level - htb.Prio = opt.Prio - case nl.TCA_HTB_RATE64: - htb.Rate = native.Uint64(datum.Value[0:8]) - case nl.TCA_HTB_CEIL64: - htb.Ceil = native.Uint64(datum.Value[0:8]) - } - } - return detailed, nil -} - -func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) { - hfsc := class.(*HfscClass) - detailed := false - for _, datum := range data { - m1, d, m2 := nl.DeserializeHfscCurve(datum.Value).Attrs() - switch datum.Attr.Type { - case nl.TCA_HFSC_RSC: - hfsc.Rsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8} - case nl.TCA_HFSC_FSC: - hfsc.Fsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8} - case nl.TCA_HFSC_USC: - hfsc.Usc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8} - } - } - return detailed, nil -} - -func parseTcStats(data []byte) (*ClassStatistics, error) { - buf := &bytes.Buffer{} - buf.Write(data) - tcStats := &tcStats{} - if err := binary.Read(buf, native, tcStats); err != nil { - return nil, err - } - - stats := NewClassStatistics() - stats.Basic.Bytes = tcStats.Bytes - stats.Basic.Packets = tcStats.Packets - stats.Queue.Qlen = tcStats.Qlen - stats.Queue.Backlog = tcStats.Backlog - stats.Queue.Drops = tcStats.Drops - stats.Queue.Overlimits = tcStats.Overlimits - stats.RateEst.Bps = tcStats.Bps - stats.RateEst.Pps = tcStats.Pps - - return stats, nil -} - -func parseGnetStats(data []byte, gnetStats interface{}) error { - buf := &bytes.Buffer{} - buf.Write(data) - return binary.Read(buf, native, gnetStats) -} - -func parseTcStats2(data []byte) (*ClassStatistics, error) { - rtAttrs, err := nl.ParseRouteAttr(data) - if err != nil { - return nil, err - } - stats := NewClassStatistics() - for _, datum := range rtAttrs { - switch datum.Attr.Type { - case nl.TCA_STATS_BASIC: - if err := parseGnetStats(datum.Value, stats.Basic); err != nil { - return nil, fmt.Errorf("Failed to parse ClassStatistics.Basic with: %v\n%s", - err, hex.Dump(datum.Value)) - } - case nl.TCA_STATS_QUEUE: - if err := parseGnetStats(datum.Value, stats.Queue); err != nil { - return nil, fmt.Errorf("Failed to parse ClassStatistics.Queue with: %v\n%s", - err, hex.Dump(datum.Value)) - } - case nl.TCA_STATS_RATE_EST: - if err := parseGnetStats(datum.Value, stats.RateEst); err != nil { - return nil, fmt.Errorf("Failed to parse ClassStatistics.RateEst with: %v\n%s", - err, hex.Dump(datum.Value)) - } - } - } - - return stats, nil -} diff --git a/vendor/github.com/tailscale/netlink/conntrack_linux.go b/vendor/github.com/tailscale/netlink/conntrack_linux.go deleted file mode 100644 index b5b211e..0000000 --- a/vendor/github.com/tailscale/netlink/conntrack_linux.go +++ /dev/null @@ -1,537 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "net" - "time" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// ConntrackTableType Conntrack table for the netlink operation -type ConntrackTableType uint8 - -const ( - // ConntrackTable Conntrack table - // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK 1 - ConntrackTable = 1 - // ConntrackExpectTable Conntrack expect table - // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2 - ConntrackExpectTable = 2 -) - -const ( - // backward compatibility with golang 1.6 which does not have io.SeekCurrent - seekCurrent = 1 -) - -// InetFamily Family type -type InetFamily uint8 - -// -L [table] [options] List conntrack or expectation table -// -G [table] parameters Get conntrack or expectation - -// -I [table] parameters Create a conntrack or expectation -// -U [table] parameters Update a conntrack -// -E [table] [options] Show events - -// -C [table] Show counter -// -S Show statistics - -// ConntrackTableList returns the flow list of a table of a specific family -// conntrack -L [table] [options] List conntrack or expectation table -func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { - return pkgHandle.ConntrackTableList(table, family) -} - -// ConntrackTableFlush flushes all the flows of a specified table -// conntrack -F [table] Flush table -// The flush operation applies to all the family types -func ConntrackTableFlush(table ConntrackTableType) error { - return pkgHandle.ConntrackTableFlush(table) -} - -// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter -// conntrack -D [table] parameters Delete conntrack or expectation -func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) { - return pkgHandle.ConntrackDeleteFilter(table, family, filter) -} - -// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed -// conntrack -L [table] [options] List conntrack or expectation table -func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { - res, err := h.dumpConntrackTable(table, family) - if err != nil { - return nil, err - } - - // Deserialize all the flows - var result []*ConntrackFlow - for _, dataRaw := range res { - result = append(result, parseRawData(dataRaw)) - } - - return result, nil -} - -// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed -// conntrack -F [table] Flush table -// The flush operation applies to all the family types -func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error { - req := h.newConntrackRequest(table, unix.AF_INET, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) - _, err := req.Execute(unix.NETLINK_NETFILTER, 0) - return err -} - -// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed -// conntrack -D [table] parameters Delete conntrack or expectation -func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) { - res, err := h.dumpConntrackTable(table, family) - if err != nil { - return 0, err - } - - var matched uint - for _, dataRaw := range res { - flow := parseRawData(dataRaw) - if match := filter.MatchConntrackFlow(flow); match { - req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) - // skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already - req2.AddRawData(dataRaw[4:]) - req2.Execute(unix.NETLINK_NETFILTER, 0) - matched++ - } - } - - return matched, nil -} - -func (h *Handle) newConntrackRequest(table ConntrackTableType, family InetFamily, operation, flags int) *nl.NetlinkRequest { - // Create the Netlink request object - req := h.newNetlinkRequest((int(table)<<8)|operation, flags) - // Add the netfilter header - msg := &nl.Nfgenmsg{ - NfgenFamily: uint8(family), - Version: nl.NFNETLINK_V0, - ResId: 0, - } - req.AddData(msg) - return req -} - -func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) { - req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, unix.NLM_F_DUMP) - return req.Execute(unix.NETLINK_NETFILTER, 0) -} - -// The full conntrack flow structure is very complicated and can be found in the file: -// http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h -// For the time being, the structure below allows to parse and extract the base information of a flow -type ipTuple struct { - Bytes uint64 - DstIP net.IP - DstPort uint16 - Packets uint64 - Protocol uint8 - SrcIP net.IP - SrcPort uint16 -} - -type ConntrackFlow struct { - FamilyType uint8 - Forward ipTuple - Reverse ipTuple - Mark uint32 - TimeStart uint64 - TimeStop uint64 - TimeOut uint32 -} - -func (s *ConntrackFlow) String() string { - // conntrack cmd output: - // udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 packets=5 bytes=532 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 packets=10 bytes=1078 mark=0 - // start=2019-07-26 01:26:21.557800506 +0000 UTC stop=1970-01-01 00:00:00 +0000 UTC timeout=30(sec) - start := time.Unix(0, int64(s.TimeStart)) - stop := time.Unix(0, int64(s.TimeStop)) - timeout := int32(s.TimeOut) - return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d packets=%d bytes=%d\tsrc=%s dst=%s sport=%d dport=%d packets=%d bytes=%d mark=0x%x start=%v stop=%v timeout=%d(sec)", - nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol, - s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes, - s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes, - s.Mark, start, stop, timeout) -} - -// This method parse the ip tuple structure -// The message structure is the following: -// -// -// -// -// -func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 { - for i := 0; i < 2; i++ { - _, t, _, v := parseNfAttrTLV(reader) - switch t { - case nl.CTA_IP_V4_SRC, nl.CTA_IP_V6_SRC: - tpl.SrcIP = v - case nl.CTA_IP_V4_DST, nl.CTA_IP_V6_DST: - tpl.DstIP = v - } - } - // Get total length of nested protocol-specific info. - _, _, protoInfoTotalLen := parseNfAttrTL(reader) - _, t, l, v := parseNfAttrTLV(reader) - // Track the number of bytes read. - protoInfoBytesRead := uint16(nl.SizeofNfattr) + l - if t == nl.CTA_PROTO_NUM { - tpl.Protocol = uint8(v[0]) - } - // We only parse TCP & UDP headers. Skip the others. - if tpl.Protocol != 6 && tpl.Protocol != 17 { - // skip the rest - bytesRemaining := protoInfoTotalLen - protoInfoBytesRead - reader.Seek(int64(bytesRemaining), seekCurrent) - return tpl.Protocol - } - // Skip 3 bytes of padding - reader.Seek(3, seekCurrent) - protoInfoBytesRead += 3 - for i := 0; i < 2; i++ { - _, t, _ := parseNfAttrTL(reader) - protoInfoBytesRead += uint16(nl.SizeofNfattr) - switch t { - case nl.CTA_PROTO_SRC_PORT: - parseBERaw16(reader, &tpl.SrcPort) - protoInfoBytesRead += 2 - case nl.CTA_PROTO_DST_PORT: - parseBERaw16(reader, &tpl.DstPort) - protoInfoBytesRead += 2 - } - // Skip 2 bytes of padding - reader.Seek(2, seekCurrent) - protoInfoBytesRead += 2 - } - // Skip any remaining/unknown parts of the message - bytesRemaining := protoInfoTotalLen - protoInfoBytesRead - reader.Seek(int64(bytesRemaining), seekCurrent) - - return tpl.Protocol -} - -func parseNfAttrTLV(r *bytes.Reader) (isNested bool, attrType, len uint16, value []byte) { - isNested, attrType, len = parseNfAttrTL(r) - - value = make([]byte, len) - binary.Read(r, binary.BigEndian, &value) - return isNested, attrType, len, value -} - -func parseNfAttrTL(r *bytes.Reader) (isNested bool, attrType, len uint16) { - binary.Read(r, nl.NativeEndian(), &len) - len -= nl.SizeofNfattr - - binary.Read(r, nl.NativeEndian(), &attrType) - isNested = (attrType & nl.NLA_F_NESTED) == nl.NLA_F_NESTED - attrType = attrType & (nl.NLA_F_NESTED - 1) - return isNested, attrType, len -} - -func skipNfAttrValue(r *bytes.Reader, len uint16) { - len = (len + nl.NLA_ALIGNTO - 1) & ^(nl.NLA_ALIGNTO - 1) - r.Seek(int64(len), seekCurrent) -} - -func parseBERaw16(r *bytes.Reader, v *uint16) { - binary.Read(r, binary.BigEndian, v) -} - -func parseBERaw32(r *bytes.Reader, v *uint32) { - binary.Read(r, binary.BigEndian, v) -} - -func parseBERaw64(r *bytes.Reader, v *uint64) { - binary.Read(r, binary.BigEndian, v) -} - -func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) { - for i := 0; i < 2; i++ { - switch _, t, _ := parseNfAttrTL(r); t { - case nl.CTA_COUNTERS_BYTES: - parseBERaw64(r, &bytes) - case nl.CTA_COUNTERS_PACKETS: - parseBERaw64(r, &packets) - default: - return - } - } - return -} - -// when the flow is alive, only the timestamp_start is returned in structure -func parseTimeStamp(r *bytes.Reader, readSize uint16) (tstart, tstop uint64) { - var numTimeStamps int - oneItem := nl.SizeofNfattr + 8 // 4 bytes attr header + 8 bytes timestamp - if readSize == uint16(oneItem) { - numTimeStamps = 1 - } else if readSize == 2*uint16(oneItem) { - numTimeStamps = 2 - } else { - return - } - for i := 0; i < numTimeStamps; i++ { - switch _, t, _ := parseNfAttrTL(r); t { - case nl.CTA_TIMESTAMP_START: - parseBERaw64(r, &tstart) - case nl.CTA_TIMESTAMP_STOP: - parseBERaw64(r, &tstop) - default: - return - } - } - return - -} - -func parseTimeOut(r *bytes.Reader) (ttimeout uint32) { - parseBERaw32(r, &ttimeout) - return -} - -func parseConnectionMark(r *bytes.Reader) (mark uint32) { - parseBERaw32(r, &mark) - return -} - -func parseRawData(data []byte) *ConntrackFlow { - s := &ConntrackFlow{} - // First there is the Nfgenmsg header - // consume only the family field - reader := bytes.NewReader(data) - binary.Read(reader, nl.NativeEndian(), &s.FamilyType) - - // skip rest of the Netfilter header - reader.Seek(3, seekCurrent) - // The message structure is the following: - // 4 bytes - // 4 bytes - // flow information of the forward flow - // 4 bytes - // 4 bytes - // flow information of the reverse flow - for reader.Len() > 0 { - if nested, t, l := parseNfAttrTL(reader); nested { - switch t { - case nl.CTA_TUPLE_ORIG: - if nested, t, l = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { - parseIpTuple(reader, &s.Forward) - } - case nl.CTA_TUPLE_REPLY: - if nested, t, l = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP { - parseIpTuple(reader, &s.Reverse) - } else { - // Header not recognized skip it - skipNfAttrValue(reader, l) - } - case nl.CTA_COUNTERS_ORIG: - s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader) - case nl.CTA_COUNTERS_REPLY: - s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader) - case nl.CTA_TIMESTAMP: - s.TimeStart, s.TimeStop = parseTimeStamp(reader, l) - case nl.CTA_PROTOINFO: - skipNfAttrValue(reader, l) - default: - skipNfAttrValue(reader, l) - } - } else { - switch t { - case nl.CTA_MARK: - s.Mark = parseConnectionMark(reader) - case nl.CTA_TIMEOUT: - s.TimeOut = parseTimeOut(reader) - case nl.CTA_STATUS, nl.CTA_USE, nl.CTA_ID: - skipNfAttrValue(reader, l) - default: - skipNfAttrValue(reader, l) - } - } - } - return s -} - -// Conntrack parameters and options: -// -n, --src-nat ip source NAT ip -// -g, --dst-nat ip destination NAT ip -// -j, --any-nat ip source or destination NAT ip -// -m, --mark mark Set mark -// -c, --secmark secmark Set selinux secmark -// -e, --event-mask eventmask Event mask, eg. NEW,DESTROY -// -z, --zero Zero counters while listing -// -o, --output type[,...] Output format, eg. xml -// -l, --label label[,...] conntrack labels - -// Common parameters and options: -// -s, --src, --orig-src ip Source address from original direction -// -d, --dst, --orig-dst ip Destination address from original direction -// -r, --reply-src ip Source address from reply direction -// -q, --reply-dst ip Destination address from reply direction -// -p, --protonum proto Layer 4 Protocol, eg. 'tcp' -// -f, --family proto Layer 3 Protocol, eg. 'ipv6' -// -t, --timeout timeout Set timeout -// -u, --status status Set status, eg. ASSURED -// -w, --zone value Set conntrack zone -// --orig-zone value Set zone for original direction -// --reply-zone value Set zone for reply direction -// -b, --buffer-size Netlink socket buffer size -// --mask-src ip Source mask address -// --mask-dst ip Destination mask address - -// Layer 4 Protocol common parameters and options: -// TCP, UDP, SCTP, UDPLite and DCCP -// --sport, --orig-port-src port Source port in original direction -// --dport, --orig-port-dst port Destination port in original direction - -// Filter types -type ConntrackFilterType uint8 - -const ( - ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction - ConntrackOrigDstIP // -orig-dst ip Destination address from original direction - ConntrackReplySrcIP // --reply-src ip Reply Source IP - ConntrackReplyDstIP // --reply-dst ip Reply Destination IP - ConntrackReplyAnyIP // Match source or destination reply IP - ConntrackOrigSrcPort // --orig-port-src port Source port in original direction - ConntrackOrigDstPort // --orig-port-dst port Destination port in original direction - ConntrackNatSrcIP = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP - ConntrackNatDstIP = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP - ConntrackNatAnyIP = ConntrackReplyAnyIP // deprecated use instead ConntrackReplyAnyIP -) - -type CustomConntrackFilter interface { - // MatchConntrackFlow applies the filter to the flow and returns true if the flow matches - // the filter or false otherwise - MatchConntrackFlow(flow *ConntrackFlow) bool -} - -type ConntrackFilter struct { - ipNetFilter map[ConntrackFilterType]*net.IPNet - portFilter map[ConntrackFilterType]uint16 - protoFilter uint8 -} - -// AddIPNet adds a IP subnet to the conntrack filter -func (f *ConntrackFilter) AddIPNet(tp ConntrackFilterType, ipNet *net.IPNet) error { - if ipNet == nil { - return fmt.Errorf("Filter attribute empty") - } - if f.ipNetFilter == nil { - f.ipNetFilter = make(map[ConntrackFilterType]*net.IPNet) - } - if _, ok := f.ipNetFilter[tp]; ok { - return errors.New("Filter attribute already present") - } - f.ipNetFilter[tp] = ipNet - return nil -} - -// AddIP adds an IP to the conntrack filter -func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error { - if ip == nil { - return fmt.Errorf("Filter attribute empty") - } - return f.AddIPNet(tp, NewIPNet(ip)) -} - -// AddPort adds a Port to the conntrack filter if the Layer 4 protocol allows it -func (f *ConntrackFilter) AddPort(tp ConntrackFilterType, port uint16) error { - switch f.protoFilter { - // TCP, UDP, DCCP, SCTP, UDPLite - case 6, 17, 33, 132, 136: - default: - return fmt.Errorf("Filter attribute not available without a valid Layer 4 protocol: %d", f.protoFilter) - } - - if f.portFilter == nil { - f.portFilter = make(map[ConntrackFilterType]uint16) - } - if _, ok := f.portFilter[tp]; ok { - return errors.New("Filter attribute already present") - } - f.portFilter[tp] = port - return nil -} - -// AddProtocol adds the Layer 4 protocol to the conntrack filter -func (f *ConntrackFilter) AddProtocol(proto uint8) error { - if f.protoFilter != 0 { - return errors.New("Filter attribute already present") - } - f.protoFilter = proto - return nil -} - -// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches the filter -// false otherwise -func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool { - if len(f.ipNetFilter) == 0 && len(f.portFilter) == 0 && f.protoFilter == 0 { - // empty filter always not match - return false - } - - // -p, --protonum proto Layer 4 Protocol, eg. 'tcp' - if f.protoFilter != 0 && flow.Forward.Protocol != f.protoFilter { - // different Layer 4 protocol always not match - return false - } - - match := true - - // IP conntrack filter - if len(f.ipNetFilter) > 0 { - // -orig-src ip Source address from original direction - if elem, found := f.ipNetFilter[ConntrackOrigSrcIP]; found { - match = match && elem.Contains(flow.Forward.SrcIP) - } - - // -orig-dst ip Destination address from original direction - if elem, found := f.ipNetFilter[ConntrackOrigDstIP]; match && found { - match = match && elem.Contains(flow.Forward.DstIP) - } - - // -src-nat ip Source NAT ip - if elem, found := f.ipNetFilter[ConntrackReplySrcIP]; match && found { - match = match && elem.Contains(flow.Reverse.SrcIP) - } - - // -dst-nat ip Destination NAT ip - if elem, found := f.ipNetFilter[ConntrackReplyDstIP]; match && found { - match = match && elem.Contains(flow.Reverse.DstIP) - } - - // Match source or destination reply IP - if elem, found := f.ipNetFilter[ConntrackReplyAnyIP]; match && found { - match = match && (elem.Contains(flow.Reverse.SrcIP) || elem.Contains(flow.Reverse.DstIP)) - } - } - - // Layer 4 Port filter - if len(f.portFilter) > 0 { - // -orig-port-src port Source port from original direction - if elem, found := f.portFilter[ConntrackOrigSrcPort]; match && found { - match = match && elem == flow.Forward.SrcPort - } - - // -orig-port-dst port Destination port from original direction - if elem, found := f.portFilter[ConntrackOrigDstPort]; match && found { - match = match && elem == flow.Forward.DstPort - } - } - - return match -} - -var _ CustomConntrackFilter = (*ConntrackFilter)(nil) diff --git a/vendor/github.com/tailscale/netlink/conntrack_unspecified.go b/vendor/github.com/tailscale/netlink/conntrack_unspecified.go deleted file mode 100644 index af7af79..0000000 --- a/vendor/github.com/tailscale/netlink/conntrack_unspecified.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build !linux - -package netlink - -// ConntrackTableType Conntrack table for the netlink operation -type ConntrackTableType uint8 - -// InetFamily Family type -type InetFamily uint8 - -// ConntrackFlow placeholder -type ConntrackFlow struct{} - -// ConntrackFilter placeholder -type ConntrackFilter struct{} - -// ConntrackTableList returns the flow list of a table of a specific family -// conntrack -L [table] [options] List conntrack or expectation table -func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { - return nil, ErrNotImplemented -} - -// ConntrackTableFlush flushes all the flows of a specified table -// conntrack -F [table] Flush table -// The flush operation applies to all the family types -func ConntrackTableFlush(table ConntrackTableType) error { - return ErrNotImplemented -} - -// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter -// conntrack -D [table] parameters Delete conntrack or expectation -func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) { - return 0, ErrNotImplemented -} - -// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed -// conntrack -L [table] [options] List conntrack or expectation table -func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) { - return nil, ErrNotImplemented -} - -// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed -// conntrack -F [table] Flush table -// The flush operation applies to all the family types -func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error { - return ErrNotImplemented -} - -// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed -// conntrack -D [table] parameters Delete conntrack or expectation -func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) { - return 0, ErrNotImplemented -} diff --git a/vendor/github.com/tailscale/netlink/devlink_linux.go b/vendor/github.com/tailscale/netlink/devlink_linux.go deleted file mode 100644 index d65c32d..0000000 --- a/vendor/github.com/tailscale/netlink/devlink_linux.go +++ /dev/null @@ -1,728 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "strings" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// DevlinkDevEswitchAttr represents device's eswitch attributes -type DevlinkDevEswitchAttr struct { - Mode string - InlineMode string - EncapMode string -} - -// DevlinkDevAttrs represents device attributes -type DevlinkDevAttrs struct { - Eswitch DevlinkDevEswitchAttr -} - -// DevlinkDevice represents device and its attributes -type DevlinkDevice struct { - BusName string - DeviceName string - Attrs DevlinkDevAttrs -} - -// DevlinkPortFn represents port function and its attributes -type DevlinkPortFn struct { - HwAddr net.HardwareAddr - State uint8 - OpState uint8 -} - -// DevlinkPortFnSetAttrs represents attributes to set -type DevlinkPortFnSetAttrs struct { - FnAttrs DevlinkPortFn - HwAddrValid bool - StateValid bool -} - -// DevlinkPort represents port and its attributes -type DevlinkPort struct { - BusName string - DeviceName string - PortIndex uint32 - PortType uint16 - NetdeviceName string - NetdevIfIndex uint32 - RdmaDeviceName string - PortFlavour uint16 - Fn *DevlinkPortFn -} - -type DevLinkPortAddAttrs struct { - Controller uint32 - SfNumber uint32 - PortIndex uint32 - PfNumber uint16 - SfNumberValid bool - PortIndexValid bool - ControllerValid bool -} - -// DevlinkDeviceInfo represents devlink info -type DevlinkDeviceInfo struct { - Driver string - SerialNumber string - BoardID string - FwApp string - FwAppBoundleID string - FwAppName string - FwBoundleID string - FwMgmt string - FwMgmtAPI string - FwMgmtBuild string - FwNetlist string - FwNetlistBuild string - FwPsidAPI string - FwUndi string -} - -func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) { - devices := make([]*DevlinkDevice, 0, len(msgs)) - for _, m := range msgs { - attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) - if err != nil { - return nil, err - } - dev := &DevlinkDevice{} - if err = dev.parseAttributes(attrs); err != nil { - return nil, err - } - devices = append(devices, dev) - } - return devices, nil -} - -func eswitchStringToMode(modeName string) (uint16, error) { - if modeName == "legacy" { - return nl.DEVLINK_ESWITCH_MODE_LEGACY, nil - } else if modeName == "switchdev" { - return nl.DEVLINK_ESWITCH_MODE_SWITCHDEV, nil - } else { - return 0xffff, fmt.Errorf("invalid switchdev mode") - } -} - -func parseEswitchMode(mode uint16) string { - var eswitchMode = map[uint16]string{ - nl.DEVLINK_ESWITCH_MODE_LEGACY: "legacy", - nl.DEVLINK_ESWITCH_MODE_SWITCHDEV: "switchdev", - } - if eswitchMode[mode] == "" { - return "unknown" - } else { - return eswitchMode[mode] - } -} - -func parseEswitchInlineMode(inlinemode uint8) string { - var eswitchInlineMode = map[uint8]string{ - nl.DEVLINK_ESWITCH_INLINE_MODE_NONE: "none", - nl.DEVLINK_ESWITCH_INLINE_MODE_LINK: "link", - nl.DEVLINK_ESWITCH_INLINE_MODE_NETWORK: "network", - nl.DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT: "transport", - } - if eswitchInlineMode[inlinemode] == "" { - return "unknown" - } else { - return eswitchInlineMode[inlinemode] - } -} - -func parseEswitchEncapMode(encapmode uint8) string { - var eswitchEncapMode = map[uint8]string{ - nl.DEVLINK_ESWITCH_ENCAP_MODE_NONE: "disable", - nl.DEVLINK_ESWITCH_ENCAP_MODE_BASIC: "enable", - } - if eswitchEncapMode[encapmode] == "" { - return "unknown" - } else { - return eswitchEncapMode[encapmode] - } -} - -func (d *DevlinkDevice) parseAttributes(attrs []syscall.NetlinkRouteAttr) error { - for _, a := range attrs { - switch a.Attr.Type { - case nl.DEVLINK_ATTR_BUS_NAME: - d.BusName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_DEV_NAME: - d.DeviceName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_ESWITCH_MODE: - d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value)) - case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE: - d.Attrs.Eswitch.InlineMode = parseEswitchInlineMode(uint8(a.Value[0])) - case nl.DEVLINK_ATTR_ESWITCH_ENCAP_MODE: - d.Attrs.Eswitch.EncapMode = parseEswitchEncapMode(uint8(a.Value[0])) - } - } - return nil -} - -func (dev *DevlinkDevice) parseEswitchAttrs(msgs [][]byte) { - m := msgs[0] - attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) - if err != nil { - return - } - dev.parseAttributes(attrs) -} - -func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) { - msg := &nl.Genlmsg{ - Command: nl.DEVLINK_CMD_ESWITCH_GET, - Version: nl.GENL_DEVLINK_VERSION, - } - req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK) - req.AddData(msg) - - b := make([]byte, len(dev.BusName)+1) - copy(b, dev.BusName) - data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b) - req.AddData(data) - - b = make([]byte, len(dev.DeviceName)+1) - copy(b, dev.DeviceName) - data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b) - req.AddData(data) - - msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return - } - dev.parseEswitchAttrs(msgs) -} - -// DevLinkGetDeviceList provides a pointer to devlink devices and nil error, -// otherwise returns an error code. -func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) { - f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME) - if err != nil { - return nil, err - } - msg := &nl.Genlmsg{ - Command: nl.DEVLINK_CMD_GET, - Version: nl.GENL_DEVLINK_VERSION, - } - req := h.newNetlinkRequest(int(f.ID), - unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP) - req.AddData(msg) - msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - devices, err := parseDevLinkDeviceList(msgs) - if err != nil { - return nil, err - } - for _, d := range devices { - h.getEswitchAttrs(f, d) - } - return devices, nil -} - -// DevLinkGetDeviceList provides a pointer to devlink devices and nil error, -// otherwise returns an error code. -func DevLinkGetDeviceList() ([]*DevlinkDevice, error) { - return pkgHandle.DevLinkGetDeviceList() -} - -func parseDevlinkDevice(msgs [][]byte) (*DevlinkDevice, error) { - m := msgs[0] - attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) - if err != nil { - return nil, err - } - dev := &DevlinkDevice{} - if err = dev.parseAttributes(attrs); err != nil { - return nil, err - } - return dev, nil -} - -func (h *Handle) createCmdReq(cmd uint8, bus string, device string) (*GenlFamily, *nl.NetlinkRequest, error) { - f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME) - if err != nil { - return nil, nil, err - } - - msg := &nl.Genlmsg{ - Command: cmd, - Version: nl.GENL_DEVLINK_VERSION, - } - req := h.newNetlinkRequest(int(f.ID), - unix.NLM_F_REQUEST|unix.NLM_F_ACK) - req.AddData(msg) - - b := make([]byte, len(bus)+1) - copy(b, bus) - data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b) - req.AddData(data) - - b = make([]byte, len(device)+1) - copy(b, device) - data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b) - req.AddData(data) - - return f, req, nil -} - -// DevlinkGetDeviceByName provides a pointer to devlink device and nil error, -// otherwise returns an error code. -func (h *Handle) DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) { - f, req, err := h.createCmdReq(nl.DEVLINK_CMD_GET, Bus, Device) - if err != nil { - return nil, err - } - - respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - dev, err := parseDevlinkDevice(respmsg) - if err == nil { - h.getEswitchAttrs(f, dev) - } - return dev, err -} - -// DevlinkGetDeviceByName provides a pointer to devlink device and nil error, -// otherwise returns an error code. -func DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) { - return pkgHandle.DevLinkGetDeviceByName(Bus, Device) -} - -// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or -// returns an error code. -// Equivalent to: `devlink dev eswitch set $dev mode switchdev` -// Equivalent to: `devlink dev eswitch set $dev mode legacy` -func (h *Handle) DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error { - mode, err := eswitchStringToMode(NewMode) - if err != nil { - return err - } - - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_ESWITCH_SET, Dev.BusName, Dev.DeviceName) - if err != nil { - return err - } - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_ESWITCH_MODE, nl.Uint16Attr(mode))) - - _, err = req.Execute(unix.NETLINK_GENERIC, 0) - return err -} - -// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or -// returns an error code. -// Equivalent to: `devlink dev eswitch set $dev mode switchdev` -// Equivalent to: `devlink dev eswitch set $dev mode legacy` -func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error { - return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode) -} - -func (port *DevlinkPort) parseAttributes(attrs []syscall.NetlinkRouteAttr) error { - for _, a := range attrs { - switch a.Attr.Type { - case nl.DEVLINK_ATTR_BUS_NAME: - port.BusName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_DEV_NAME: - port.DeviceName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_PORT_INDEX: - port.PortIndex = native.Uint32(a.Value) - case nl.DEVLINK_ATTR_PORT_TYPE: - port.PortType = native.Uint16(a.Value) - case nl.DEVLINK_ATTR_PORT_NETDEV_NAME: - port.NetdeviceName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_PORT_NETDEV_IFINDEX: - port.NetdevIfIndex = native.Uint32(a.Value) - case nl.DEVLINK_ATTR_PORT_IBDEV_NAME: - port.RdmaDeviceName = string(a.Value[:len(a.Value)-1]) - case nl.DEVLINK_ATTR_PORT_FLAVOUR: - port.PortFlavour = native.Uint16(a.Value) - case nl.DEVLINK_ATTR_PORT_FUNCTION: - port.Fn = &DevlinkPortFn{} - for nested := range nl.ParseAttributes(a.Value) { - switch nested.Type { - case nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR: - port.Fn.HwAddr = nested.Value[:] - case nl.DEVLINK_PORT_FN_ATTR_STATE: - port.Fn.State = uint8(nested.Value[0]) - case nl.DEVLINK_PORT_FN_ATTR_OPSTATE: - port.Fn.OpState = uint8(nested.Value[0]) - } - } - } - } - return nil -} - -func parseDevLinkAllPortList(msgs [][]byte) ([]*DevlinkPort, error) { - ports := make([]*DevlinkPort, 0, len(msgs)) - for _, m := range msgs { - attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) - if err != nil { - return nil, err - } - port := &DevlinkPort{} - if err = port.parseAttributes(attrs); err != nil { - return nil, err - } - ports = append(ports, port) - } - return ports, nil -} - -// DevLinkGetPortList provides a pointer to devlink ports and nil error, -// otherwise returns an error code. -func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) { - f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME) - if err != nil { - return nil, err - } - msg := &nl.Genlmsg{ - Command: nl.DEVLINK_CMD_PORT_GET, - Version: nl.GENL_DEVLINK_VERSION, - } - req := h.newNetlinkRequest(int(f.ID), - unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP) - req.AddData(msg) - msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - ports, err := parseDevLinkAllPortList(msgs) - if err != nil { - return nil, err - } - return ports, nil -} - -// DevLinkGetPortList provides a pointer to devlink ports and nil error, -// otherwise returns an error code. -func DevLinkGetAllPortList() ([]*DevlinkPort, error) { - return pkgHandle.DevLinkGetAllPortList() -} - -func parseDevlinkPortMsg(msgs [][]byte) (*DevlinkPort, error) { - m := msgs[0] - attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:]) - if err != nil { - return nil, err - } - port := &DevlinkPort{} - if err = port.parseAttributes(attrs); err != nil { - return nil, err - } - return port, nil -} - -// DevLinkGetPortByIndexprovides a pointer to devlink device and nil error, -// otherwise returns an error code. -func (h *Handle) DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) { - - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_GET, Bus, Device) - if err != nil { - return nil, err - } - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex))) - - respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - port, err := parseDevlinkPortMsg(respmsg) - return port, err -} - -// DevLinkGetPortByIndex provides a pointer to devlink portand nil error, -// otherwise returns an error code. -func DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) { - return pkgHandle.DevLinkGetPortByIndex(Bus, Device, PortIndex) -} - -// DevLinkPortAdd adds a devlink port and returns a port on success -// otherwise returns nil port and an error code. -func (h *Handle) DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) { - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_NEW, Bus, Device) - if err != nil { - return nil, err - } - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FLAVOUR, nl.Uint16Attr(Flavour))) - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_PF_NUMBER, nl.Uint16Attr(Attrs.PfNumber))) - if Flavour == nl.DEVLINK_PORT_FLAVOUR_PCI_SF && Attrs.SfNumberValid { - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_SF_NUMBER, nl.Uint32Attr(Attrs.SfNumber))) - } - if Attrs.PortIndexValid { - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(Attrs.PortIndex))) - } - if Attrs.ControllerValid { - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, nl.Uint32Attr(Attrs.Controller))) - } - respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - port, err := parseDevlinkPortMsg(respmsg) - return port, err -} - -// DevLinkPortAdd adds a devlink port and returns a port on success -// otherwise returns nil port and an error code. -func DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) { - return pkgHandle.DevLinkPortAdd(Bus, Device, Flavour, Attrs) -} - -// DevLinkPortDel deletes a devlink port and returns success or error code. -func (h *Handle) DevLinkPortDel(Bus string, Device string, PortIndex uint32) error { - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_DEL, Bus, Device) - if err != nil { - return err - } - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex))) - _, err = req.Execute(unix.NETLINK_GENERIC, 0) - return err -} - -// DevLinkPortDel deletes a devlink port and returns success or error code. -func DevLinkPortDel(Bus string, Device string, PortIndex uint32) error { - return pkgHandle.DevLinkPortDel(Bus, Device, PortIndex) -} - -// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask. -// It returns 0 on success or error code. -func (h *Handle) DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error { - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_SET, Bus, Device) - if err != nil { - return err - } - - req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex))) - - fnAttr := nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FUNCTION|unix.NLA_F_NESTED, nil) - - if FnAttrs.HwAddrValid { - fnAttr.AddRtAttr(nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, []byte(FnAttrs.FnAttrs.HwAddr)) - } - - if FnAttrs.StateValid { - fnAttr.AddRtAttr(nl.DEVLINK_PORT_FN_ATTR_STATE, nl.Uint8Attr(FnAttrs.FnAttrs.State)) - } - req.AddData(fnAttr) - - _, err = req.Execute(unix.NETLINK_GENERIC, 0) - return err -} - -// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask. -// It returns 0 on success or error code. -func DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error { - return pkgHandle.DevlinkPortFnSet(Bus, Device, PortIndex, FnAttrs) -} - -// devlinkInfoGetter is function that is responsible for getting devlink info message -// this is introduced for test purpose -type devlinkInfoGetter func(bus, device string) ([]byte, error) - -// DevlinkGetDeviceInfoByName returns devlink info for selected device, -// otherwise returns an error code. -// Equivalent to: `devlink dev info $dev` -func (h *Handle) DevlinkGetDeviceInfoByName(Bus string, Device string, getInfoMsg devlinkInfoGetter) (*DevlinkDeviceInfo, error) { - info, err := h.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, getInfoMsg) - if err != nil { - return nil, err - } - - return parseInfoData(info), nil -} - -// DevlinkGetDeviceInfoByName returns devlink info for selected device, -// otherwise returns an error code. -// Equivalent to: `devlink dev info $dev` -func DevlinkGetDeviceInfoByName(Bus string, Device string) (*DevlinkDeviceInfo, error) { - return pkgHandle.DevlinkGetDeviceInfoByName(Bus, Device, pkgHandle.getDevlinkInfoMsg) -} - -// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map, -// otherwise returns an error code. -// Equivalent to: `devlink dev info $dev` -func (h *Handle) DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string, getInfoMsg devlinkInfoGetter) (map[string]string, error) { - response, err := getInfoMsg(Bus, Device) - if err != nil { - return nil, err - } - - info, err := parseInfoMsg(response) - if err != nil { - return nil, err - } - - return info, nil -} - -// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map, -// otherwise returns an error code. -// Equivalent to: `devlink dev info $dev` -func DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string) (map[string]string, error) { - return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, pkgHandle.getDevlinkInfoMsg) -} - -// GetDevlinkInfo returns devlink info for target device, -// otherwise returns an error code. -func (d *DevlinkDevice) GetDevlinkInfo() (*DevlinkDeviceInfo, error) { - return pkgHandle.DevlinkGetDeviceInfoByName(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg) -} - -// GetDevlinkInfoAsMap returns devlink info for target device as a map, -// otherwise returns an error code. -func (d *DevlinkDevice) GetDevlinkInfoAsMap() (map[string]string, error) { - return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg) -} - -func (h *Handle) getDevlinkInfoMsg(bus, device string) ([]byte, error) { - _, req, err := h.createCmdReq(nl.DEVLINK_CMD_INFO_GET, bus, device) - if err != nil { - return nil, err - } - - response, err := req.Execute(unix.NETLINK_GENERIC, 0) - if err != nil { - return nil, err - } - - if len(response) < 1 { - return nil, fmt.Errorf("getDevlinkInfoMsg: message too short") - } - - return response[0], nil -} - -func parseInfoMsg(msg []byte) (map[string]string, error) { - if len(msg) < nl.SizeofGenlmsg { - return nil, fmt.Errorf("parseInfoMsg: message too short") - } - - info := make(map[string]string) - err := collectInfoData(msg[nl.SizeofGenlmsg:], info) - - if err != nil { - return nil, err - } - - return info, nil -} - -func collectInfoData(msg []byte, data map[string]string) error { - attrs, err := nl.ParseRouteAttr(msg) - if err != nil { - return err - } - - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.DEVLINK_ATTR_INFO_DRIVER_NAME: - data["driver"] = parseInfoValue(attr.Value) - case nl.DEVLINK_ATTR_INFO_SERIAL_NUMBER: - data["serialNumber"] = parseInfoValue(attr.Value) - case nl.DEVLINK_ATTR_INFO_VERSION_RUNNING, nl.DEVLINK_ATTR_INFO_VERSION_FIXED, - nl.DEVLINK_ATTR_INFO_VERSION_STORED: - key, value, err := getNestedInfoData(attr.Value) - if err != nil { - return err - } - data[key] = value - } - } - - if len(data) == 0 { - return fmt.Errorf("collectInfoData: could not read attributes") - } - - return nil -} - -func getNestedInfoData(msg []byte) (string, string, error) { - nestedAttrs, err := nl.ParseRouteAttr(msg) - - var key, value string - - if err != nil { - return "", "", err - } - - if len(nestedAttrs) != 2 { - return "", "", fmt.Errorf("getNestedInfoData: too few attributes in nested structure") - } - - for _, nestedAttr := range nestedAttrs { - switch nestedAttr.Attr.Type { - case nl.DEVLINK_ATTR_INFO_VERSION_NAME: - key = parseInfoValue(nestedAttr.Value) - case nl.DEVLINK_ATTR_INFO_VERSION_VALUE: - value = parseInfoValue(nestedAttr.Value) - } - } - - if key == "" { - return "", "", fmt.Errorf("getNestedInfoData: key not found") - } - - if value == "" { - return "", "", fmt.Errorf("getNestedInfoData: value not found") - } - - return key, value, nil -} - -func parseInfoData(data map[string]string) *DevlinkDeviceInfo { - info := new(DevlinkDeviceInfo) - for key, value := range data { - switch key { - case "driver": - info.Driver = value - case "serialNumber": - info.SerialNumber = value - case "board.id": - info.BoardID = value - case "fw.app": - info.FwApp = value - case "fw.app.bundle_id": - info.FwAppBoundleID = value - case "fw.app.name": - info.FwAppName = value - case "fw.bundle_id": - info.FwBoundleID = value - case "fw.mgmt": - info.FwMgmt = value - case "fw.mgmt.api": - info.FwMgmtAPI = value - case "fw.mgmt.build": - info.FwMgmtBuild = value - case "fw.netlist": - info.FwNetlist = value - case "fw.netlist.build": - info.FwNetlistBuild = value - case "fw.psid.api": - info.FwPsidAPI = value - case "fw.undi": - info.FwUndi = value - } - } - return info -} - -func parseInfoValue(value []byte) string { - v := strings.ReplaceAll(string(value), "\x00", "") - return strings.TrimSpace(v) -} diff --git a/vendor/github.com/tailscale/netlink/filter.go b/vendor/github.com/tailscale/netlink/filter.go deleted file mode 100644 index 2dc34b9..0000000 --- a/vendor/github.com/tailscale/netlink/filter.go +++ /dev/null @@ -1,325 +0,0 @@ -package netlink - -import ( - "fmt" - "net" -) - -type Filter interface { - Attrs() *FilterAttrs - Type() string -} - -// FilterAttrs represents a netlink filter. A filter is associated with a link, -// has a handle and a parent. The root filter of a device should have a -// parent == HANDLE_ROOT. -type FilterAttrs struct { - LinkIndex int - Handle uint32 - Parent uint32 - Priority uint16 // lower is higher priority - Protocol uint16 // unix.ETH_P_* -} - -func (q FilterAttrs) String() string { - return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol) -} - -type TcAct int32 - -const ( - TC_ACT_UNSPEC TcAct = -1 - TC_ACT_OK TcAct = 0 - TC_ACT_RECLASSIFY TcAct = 1 - TC_ACT_SHOT TcAct = 2 - TC_ACT_PIPE TcAct = 3 - TC_ACT_STOLEN TcAct = 4 - TC_ACT_QUEUED TcAct = 5 - TC_ACT_REPEAT TcAct = 6 - TC_ACT_REDIRECT TcAct = 7 - TC_ACT_JUMP TcAct = 0x10000000 -) - -func (a TcAct) String() string { - switch a { - case TC_ACT_UNSPEC: - return "unspec" - case TC_ACT_OK: - return "ok" - case TC_ACT_RECLASSIFY: - return "reclassify" - case TC_ACT_SHOT: - return "shot" - case TC_ACT_PIPE: - return "pipe" - case TC_ACT_STOLEN: - return "stolen" - case TC_ACT_QUEUED: - return "queued" - case TC_ACT_REPEAT: - return "repeat" - case TC_ACT_REDIRECT: - return "redirect" - case TC_ACT_JUMP: - return "jump" - } - return fmt.Sprintf("0x%x", int32(a)) -} - -type TcPolAct int32 - -const ( - TC_POLICE_UNSPEC TcPolAct = TcPolAct(TC_ACT_UNSPEC) - TC_POLICE_OK TcPolAct = TcPolAct(TC_ACT_OK) - TC_POLICE_RECLASSIFY TcPolAct = TcPolAct(TC_ACT_RECLASSIFY) - TC_POLICE_SHOT TcPolAct = TcPolAct(TC_ACT_SHOT) - TC_POLICE_PIPE TcPolAct = TcPolAct(TC_ACT_PIPE) -) - -func (a TcPolAct) String() string { - switch a { - case TC_POLICE_UNSPEC: - return "unspec" - case TC_POLICE_OK: - return "ok" - case TC_POLICE_RECLASSIFY: - return "reclassify" - case TC_POLICE_SHOT: - return "shot" - case TC_POLICE_PIPE: - return "pipe" - } - return fmt.Sprintf("0x%x", int32(a)) -} - -type ActionAttrs struct { - Index int - Capab int - Action TcAct - Refcnt int - Bindcnt int -} - -func (q ActionAttrs) String() string { - return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt) -} - -// Action represents an action in any supported filter. -type Action interface { - Attrs() *ActionAttrs - Type() string -} - -type GenericAction struct { - ActionAttrs -} - -func (action *GenericAction) Type() string { - return "generic" -} - -func (action *GenericAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -type BpfAction struct { - ActionAttrs - Fd int - Name string -} - -func (action *BpfAction) Type() string { - return "bpf" -} - -func (action *BpfAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -type ConnmarkAction struct { - ActionAttrs - Zone uint16 -} - -func (action *ConnmarkAction) Type() string { - return "connmark" -} - -func (action *ConnmarkAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -func NewConnmarkAction() *ConnmarkAction { - return &ConnmarkAction{ - ActionAttrs: ActionAttrs{ - Action: TC_ACT_PIPE, - }, - } -} - -type MirredAct uint8 - -func (a MirredAct) String() string { - switch a { - case TCA_EGRESS_REDIR: - return "egress redir" - case TCA_EGRESS_MIRROR: - return "egress mirror" - case TCA_INGRESS_REDIR: - return "ingress redir" - case TCA_INGRESS_MIRROR: - return "ingress mirror" - } - return "unknown" -} - -const ( - TCA_EGRESS_REDIR MirredAct = 1 /* packet redirect to EGRESS*/ - TCA_EGRESS_MIRROR MirredAct = 2 /* mirror packet to EGRESS */ - TCA_INGRESS_REDIR MirredAct = 3 /* packet redirect to INGRESS*/ - TCA_INGRESS_MIRROR MirredAct = 4 /* mirror packet to INGRESS */ -) - -type MirredAction struct { - ActionAttrs - MirredAction MirredAct - Ifindex int -} - -func (action *MirredAction) Type() string { - return "mirred" -} - -func (action *MirredAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -func NewMirredAction(redirIndex int) *MirredAction { - return &MirredAction{ - ActionAttrs: ActionAttrs{ - Action: TC_ACT_STOLEN, - }, - MirredAction: TCA_EGRESS_REDIR, - Ifindex: redirIndex, - } -} - -type TunnelKeyAct int8 - -const ( - TCA_TUNNEL_KEY_SET TunnelKeyAct = 1 // set tunnel key - TCA_TUNNEL_KEY_UNSET TunnelKeyAct = 2 // unset tunnel key -) - -type TunnelKeyAction struct { - ActionAttrs - Action TunnelKeyAct - SrcAddr net.IP - DstAddr net.IP - KeyID uint32 - DestPort uint16 -} - -func (action *TunnelKeyAction) Type() string { - return "tunnel_key" -} - -func (action *TunnelKeyAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -func NewTunnelKeyAction() *TunnelKeyAction { - return &TunnelKeyAction{ - ActionAttrs: ActionAttrs{ - Action: TC_ACT_PIPE, - }, - } -} - -type SkbEditAction struct { - ActionAttrs - QueueMapping *uint16 - PType *uint16 - Priority *uint32 - Mark *uint32 -} - -func (action *SkbEditAction) Type() string { - return "skbedit" -} - -func (action *SkbEditAction) Attrs() *ActionAttrs { - return &action.ActionAttrs -} - -func NewSkbEditAction() *SkbEditAction { - return &SkbEditAction{ - ActionAttrs: ActionAttrs{ - Action: TC_ACT_PIPE, - }, - } -} - -// MatchAll filters match all packets -type MatchAll struct { - FilterAttrs - ClassId uint32 - Actions []Action -} - -func (filter *MatchAll) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -func (filter *MatchAll) Type() string { - return "matchall" -} - -type FilterFwAttrs struct { - ClassId uint32 - InDev string - Mask uint32 - Index uint32 - Buffer uint32 - Mtu uint32 - Mpu uint16 - Rate uint32 - AvRate uint32 - PeakRate uint32 - Action TcPolAct - Overhead uint16 - LinkLayer int -} - -type BpfFilter struct { - FilterAttrs - ClassId uint32 - Fd int - Name string - DirectAction bool - Id int - Tag string -} - -func (filter *BpfFilter) Type() string { - return "bpf" -} - -func (filter *BpfFilter) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -// GenericFilter filters represent types that are not currently understood -// by this netlink library. -type GenericFilter struct { - FilterAttrs - FilterType string -} - -func (filter *GenericFilter) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -func (filter *GenericFilter) Type() string { - return filter.FilterType -} diff --git a/vendor/github.com/tailscale/netlink/filter_linux.go b/vendor/github.com/tailscale/netlink/filter_linux.go deleted file mode 100644 index bb3384e..0000000 --- a/vendor/github.com/tailscale/netlink/filter_linux.go +++ /dev/null @@ -1,950 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "net" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// Constants used in TcU32Sel.Flags. -const ( - TC_U32_TERMINAL = nl.TC_U32_TERMINAL - TC_U32_OFFSET = nl.TC_U32_OFFSET - TC_U32_VAROFFSET = nl.TC_U32_VAROFFSET - TC_U32_EAT = nl.TC_U32_EAT -) - -// Sel of the U32 filters that contains multiple TcU32Key. This is the type -// alias and the frontend representation of nl.TcU32Sel. It is serialized into -// canonical nl.TcU32Sel with the appropriate endianness. -type TcU32Sel = nl.TcU32Sel - -// TcU32Key contained of Sel in the U32 filters. This is the type alias and the -// frontend representation of nl.TcU32Key. It is serialized into chanonical -// nl.TcU32Sel with the appropriate endianness. -type TcU32Key = nl.TcU32Key - -// U32 filters on many packet related properties -type U32 struct { - FilterAttrs - ClassId uint32 - Divisor uint32 // Divisor MUST be power of 2. - Hash uint32 - Link uint32 - RedirIndex int - Sel *TcU32Sel - Actions []Action -} - -func (filter *U32) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -func (filter *U32) Type() string { - return "u32" -} - -// Fw filter filters on firewall marks -// NOTE: this is in filter_linux because it refers to nl.TcPolice which -// -// is defined in nl/tc_linux.go -type Fw struct { - FilterAttrs - ClassId uint32 - // TODO remove nl type from interface - Police nl.TcPolice - InDev string - // TODO Action - Mask uint32 - AvRate uint32 - Rtab [256]uint32 - Ptab [256]uint32 -} - -func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) { - var rtab [256]uint32 - var ptab [256]uint32 - rcellLog := -1 - pcellLog := -1 - avrate := fattrs.AvRate / 8 - police := nl.TcPolice{} - police.Rate.Rate = fattrs.Rate / 8 - police.PeakRate.Rate = fattrs.PeakRate / 8 - buffer := fattrs.Buffer - linklayer := nl.LINKLAYER_ETHERNET - - if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC { - linklayer = fattrs.LinkLayer - } - - police.Action = int32(fattrs.Action) - if police.Rate.Rate != 0 { - police.Rate.Mpu = fattrs.Mpu - police.Rate.Overhead = fattrs.Overhead - if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 { - return nil, errors.New("TBF: failed to calculate rate table") - } - police.Burst = Xmittime(uint64(police.Rate.Rate), uint32(buffer)) - } - police.Mtu = fattrs.Mtu - if police.PeakRate.Rate != 0 { - police.PeakRate.Mpu = fattrs.Mpu - police.PeakRate.Overhead = fattrs.Overhead - if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 { - return nil, errors.New("POLICE: failed to calculate peak rate table") - } - } - - return &Fw{ - FilterAttrs: attrs, - ClassId: fattrs.ClassId, - InDev: fattrs.InDev, - Mask: fattrs.Mask, - Police: police, - AvRate: avrate, - Rtab: rtab, - Ptab: ptab, - }, nil -} - -func (filter *Fw) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -func (filter *Fw) Type() string { - return "fw" -} - -type Flower struct { - FilterAttrs - DestIP net.IP - DestIPMask net.IPMask - SrcIP net.IP - SrcIPMask net.IPMask - EthType uint16 - EncDestIP net.IP - EncDestIPMask net.IPMask - EncSrcIP net.IP - EncSrcIPMask net.IPMask - EncDestPort uint16 - EncKeyId uint32 - - Actions []Action -} - -func (filter *Flower) Attrs() *FilterAttrs { - return &filter.FilterAttrs -} - -func (filter *Flower) Type() string { - return "flower" -} - -func (filter *Flower) encodeIP(parent *nl.RtAttr, ip net.IP, mask net.IPMask, v4Type, v6Type int, v4MaskType, v6MaskType int) { - ipType := v4Type - maskType := v4MaskType - - encodeMask := mask - if mask == nil { - encodeMask = net.CIDRMask(32, 32) - } - v4IP := ip.To4() - if v4IP == nil { - ipType = v6Type - maskType = v6MaskType - if mask == nil { - encodeMask = net.CIDRMask(128, 128) - } - } else { - ip = v4IP - } - - parent.AddRtAttr(ipType, ip) - parent.AddRtAttr(maskType, encodeMask) -} - -func (filter *Flower) encode(parent *nl.RtAttr) error { - if filter.EthType != 0 { - parent.AddRtAttr(nl.TCA_FLOWER_KEY_ETH_TYPE, htons(filter.EthType)) - } - if filter.SrcIP != nil { - filter.encodeIP(parent, filter.SrcIP, filter.SrcIPMask, - nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC, - nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK) - } - if filter.DestIP != nil { - filter.encodeIP(parent, filter.DestIP, filter.DestIPMask, - nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST, - nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK) - } - if filter.EncSrcIP != nil { - filter.encodeIP(parent, filter.EncSrcIP, filter.EncSrcIPMask, - nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC, - nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK) - } - if filter.EncDestIP != nil { - filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask, - nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST, - nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK) - } - if filter.EncDestPort != 0 { - parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT, htons(filter.EncDestPort)) - } - if filter.EncKeyId != 0 { - parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_KEY_ID, htonl(filter.EncKeyId)) - } - - actionsAttr := parent.AddRtAttr(nl.TCA_FLOWER_ACT, nil) - if err := EncodeActions(actionsAttr, filter.Actions); err != nil { - return err - } - return nil -} - -func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error { - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_FLOWER_KEY_ETH_TYPE: - filter.EthType = ntohs(datum.Value) - case nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC: - filter.SrcIP = datum.Value - case nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK: - filter.SrcIPMask = datum.Value - case nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST: - filter.DestIP = datum.Value - case nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK: - filter.DestIPMask = datum.Value - case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC: - filter.EncSrcIP = datum.Value - case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK: - filter.EncSrcIPMask = datum.Value - case nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST: - filter.EncDestIP = datum.Value - case nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK: - filter.EncDestIPMask = datum.Value - case nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT: - filter.EncDestPort = ntohs(datum.Value) - case nl.TCA_FLOWER_KEY_ENC_KEY_ID: - filter.EncKeyId = ntohl(datum.Value) - case nl.TCA_FLOWER_ACT: - tables, err := nl.ParseRouteAttr(datum.Value) - if err != nil { - return err - } - filter.Actions, err = parseActions(tables) - if err != nil { - return err - } - } - } - return nil -} - -// FilterDel will delete a filter from the system. -// Equivalent to: `tc filter del $filter` -func FilterDel(filter Filter) error { - return pkgHandle.FilterDel(filter) -} - -// FilterDel will delete a filter from the system. -// Equivalent to: `tc filter del $filter` -func (h *Handle) FilterDel(filter Filter) error { - req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK) - base := filter.Attrs() - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Ifindex: int32(base.LinkIndex), - Handle: base.Handle, - Parent: base.Parent, - Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)), - } - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// FilterAdd will add a filter to the system. -// Equivalent to: `tc filter add $filter` -func FilterAdd(filter Filter) error { - return pkgHandle.FilterAdd(filter) -} - -// FilterAdd will add a filter to the system. -// Equivalent to: `tc filter add $filter` -func (h *Handle) FilterAdd(filter Filter) error { - return h.filterModify(filter, unix.NLM_F_CREATE|unix.NLM_F_EXCL) -} - -// FilterReplace will replace a filter. -// Equivalent to: `tc filter replace $filter` -func FilterReplace(filter Filter) error { - return pkgHandle.FilterReplace(filter) -} - -// FilterReplace will replace a filter. -// Equivalent to: `tc filter replace $filter` -func (h *Handle) FilterReplace(filter Filter) error { - return h.filterModify(filter, unix.NLM_F_CREATE) -} - -func (h *Handle) filterModify(filter Filter, flags int) error { - req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK) - base := filter.Attrs() - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Ifindex: int32(base.LinkIndex), - Handle: base.Handle, - Parent: base.Parent, - Info: MakeHandle(base.Priority, nl.Swap16(base.Protocol)), - } - req.AddData(msg) - req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type()))) - - options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) - - switch filter := filter.(type) { - case *U32: - sel := filter.Sel - if sel == nil { - // match all - sel = &nl.TcU32Sel{ - Nkeys: 1, - Flags: nl.TC_U32_TERMINAL, - } - sel.Keys = append(sel.Keys, nl.TcU32Key{}) - } - - if native != networkOrder { - // Copy TcU32Sel. - cSel := *sel - keys := make([]nl.TcU32Key, cap(sel.Keys)) - copy(keys, sel.Keys) - cSel.Keys = keys - sel = &cSel - - // Handle the endianness of attributes - sel.Offmask = native.Uint16(htons(sel.Offmask)) - sel.Hmask = native.Uint32(htonl(sel.Hmask)) - for i, key := range sel.Keys { - sel.Keys[i].Mask = native.Uint32(htonl(key.Mask)) - sel.Keys[i].Val = native.Uint32(htonl(key.Val)) - } - } - sel.Nkeys = uint8(len(sel.Keys)) - options.AddRtAttr(nl.TCA_U32_SEL, sel.Serialize()) - if filter.ClassId != 0 { - options.AddRtAttr(nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId)) - } - if filter.Divisor != 0 { - if (filter.Divisor-1)&filter.Divisor != 0 { - return fmt.Errorf("illegal divisor %d. Must be a power of 2", filter.Divisor) - } - options.AddRtAttr(nl.TCA_U32_DIVISOR, nl.Uint32Attr(filter.Divisor)) - } - if filter.Hash != 0 { - options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash)) - } - if filter.Link != 0 { - options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link)) - } - actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil) - // backwards compatibility - if filter.RedirIndex != 0 { - filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...) - } - if err := EncodeActions(actionsAttr, filter.Actions); err != nil { - return err - } - case *Fw: - if filter.Mask != 0 { - b := make([]byte, 4) - native.PutUint32(b, filter.Mask) - options.AddRtAttr(nl.TCA_FW_MASK, b) - } - if filter.InDev != "" { - options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev)) - } - if (filter.Police != nl.TcPolice{}) { - - police := options.AddRtAttr(nl.TCA_FW_POLICE, nil) - police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize()) - if (filter.Police.Rate != nl.TcRateSpec{}) { - payload := SerializeRtab(filter.Rtab) - police.AddRtAttr(nl.TCA_POLICE_RATE, payload) - } - if (filter.Police.PeakRate != nl.TcRateSpec{}) { - payload := SerializeRtab(filter.Ptab) - police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload) - } - } - if filter.ClassId != 0 { - b := make([]byte, 4) - native.PutUint32(b, filter.ClassId) - options.AddRtAttr(nl.TCA_FW_CLASSID, b) - } - case *BpfFilter: - var bpfFlags uint32 - if filter.ClassId != 0 { - options.AddRtAttr(nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId)) - } - if filter.Fd >= 0 { - options.AddRtAttr(nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd)))) - } - if filter.Name != "" { - options.AddRtAttr(nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name)) - } - if filter.DirectAction { - bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT - } - options.AddRtAttr(nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags)) - case *MatchAll: - actionsAttr := options.AddRtAttr(nl.TCA_MATCHALL_ACT, nil) - if err := EncodeActions(actionsAttr, filter.Actions); err != nil { - return err - } - if filter.ClassId != 0 { - options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId)) - } - case *Flower: - if err := filter.encode(options); err != nil { - return err - } - } - - req.AddData(options) - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// FilterList gets a list of filters in the system. -// Equivalent to: `tc filter show`. -// Generally returns nothing if link and parent are not specified. -func FilterList(link Link, parent uint32) ([]Filter, error) { - return pkgHandle.FilterList(link, parent) -} - -// FilterList gets a list of filters in the system. -// Equivalent to: `tc filter show`. -// Generally returns nothing if link and parent are not specified. -func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) { - req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP) - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Parent: parent, - } - if link != nil { - base := link.Attrs() - h.ensureIndex(base) - msg.Ifindex = int32(base.Index) - } - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER) - if err != nil { - return nil, err - } - - var res []Filter - for _, m := range msgs { - msg := nl.DeserializeTcMsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - base := FilterAttrs{ - LinkIndex: int(msg.Ifindex), - Handle: msg.Handle, - Parent: msg.Parent, - } - base.Priority, base.Protocol = MajorMinor(msg.Info) - base.Protocol = nl.Swap16(base.Protocol) - - var filter Filter - filterType := "" - detailed := false - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.TCA_KIND: - filterType = string(attr.Value[:len(attr.Value)-1]) - switch filterType { - case "u32": - filter = &U32{} - case "fw": - filter = &Fw{} - case "bpf": - filter = &BpfFilter{} - case "matchall": - filter = &MatchAll{} - case "flower": - filter = &Flower{} - default: - filter = &GenericFilter{FilterType: filterType} - } - case nl.TCA_OPTIONS: - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - switch filterType { - case "u32": - detailed, err = parseU32Data(filter, data) - if err != nil { - return nil, err - } - case "fw": - detailed, err = parseFwData(filter, data) - if err != nil { - return nil, err - } - case "bpf": - detailed, err = parseBpfData(filter, data) - if err != nil { - return nil, err - } - case "matchall": - detailed, err = parseMatchAllData(filter, data) - if err != nil { - return nil, err - } - case "flower": - detailed, err = parseFlowerData(filter, data) - if err != nil { - return nil, err - } - default: - detailed = true - } - } - } - // only return the detailed version of the filter - if detailed { - *filter.Attrs() = base - res = append(res, filter) - } - } - - return res, nil -} - -func toTcGen(attrs *ActionAttrs, tcgen *nl.TcGen) { - tcgen.Index = uint32(attrs.Index) - tcgen.Capab = uint32(attrs.Capab) - tcgen.Action = int32(attrs.Action) - tcgen.Refcnt = int32(attrs.Refcnt) - tcgen.Bindcnt = int32(attrs.Bindcnt) -} - -func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) { - attrs.Index = int(tcgen.Index) - attrs.Capab = int(tcgen.Capab) - attrs.Action = TcAct(tcgen.Action) - attrs.Refcnt = int(tcgen.Refcnt) - attrs.Bindcnt = int(tcgen.Bindcnt) -} - -func EncodeActions(attr *nl.RtAttr, actions []Action) error { - tabIndex := int(nl.TCA_ACT_TAB) - - for _, action := range actions { - switch action := action.(type) { - default: - return fmt.Errorf("unknown action type %s", action.Type()) - case *MirredAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - mirred := nl.TcMirred{ - Eaction: int32(action.MirredAction), - Ifindex: uint32(action.Ifindex), - } - toTcGen(action.Attrs(), &mirred.TcGen) - aopts.AddRtAttr(nl.TCA_MIRRED_PARMS, mirred.Serialize()) - case *TunnelKeyAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("tunnel_key")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - tun := nl.TcTunnelKey{ - Action: int32(action.Action), - } - toTcGen(action.Attrs(), &tun.TcGen) - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_PARMS, tun.Serialize()) - if action.Action == TCA_TUNNEL_KEY_SET { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_KEY_ID, htonl(action.KeyID)) - if v4 := action.SrcAddr.To4(); v4 != nil { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC, v4[:]) - } else if v6 := action.SrcAddr.To16(); v6 != nil { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, v6[:]) - } else { - return fmt.Errorf("invalid src addr %s for tunnel_key action", action.SrcAddr) - } - if v4 := action.DstAddr.To4(); v4 != nil { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_DST, v4[:]) - } else if v6 := action.DstAddr.To16(); v6 != nil { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, v6[:]) - } else { - return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr) - } - if action.DestPort != 0 { - aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_DST_PORT, htons(action.DestPort)) - } - } - case *SkbEditAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("skbedit")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - skbedit := nl.TcSkbEdit{} - toTcGen(action.Attrs(), &skbedit.TcGen) - aopts.AddRtAttr(nl.TCA_SKBEDIT_PARMS, skbedit.Serialize()) - if action.QueueMapping != nil { - aopts.AddRtAttr(nl.TCA_SKBEDIT_QUEUE_MAPPING, nl.Uint16Attr(*action.QueueMapping)) - } - if action.Priority != nil { - aopts.AddRtAttr(nl.TCA_SKBEDIT_PRIORITY, nl.Uint32Attr(*action.Priority)) - } - if action.PType != nil { - aopts.AddRtAttr(nl.TCA_SKBEDIT_PTYPE, nl.Uint16Attr(*action.PType)) - } - if action.Mark != nil { - aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark)) - } - case *ConnmarkAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("connmark")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - connmark := nl.TcConnmark{ - Zone: action.Zone, - } - toTcGen(action.Attrs(), &connmark.TcGen) - aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize()) - case *BpfAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - gen := nl.TcGen{} - toTcGen(action.Attrs(), &gen) - aopts.AddRtAttr(nl.TCA_ACT_BPF_PARMS, gen.Serialize()) - aopts.AddRtAttr(nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd))) - aopts.AddRtAttr(nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name)) - case *GenericAction: - table := attr.AddRtAttr(tabIndex, nil) - tabIndex++ - table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("gact")) - aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil) - gen := nl.TcGen{} - toTcGen(action.Attrs(), &gen) - aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize()) - } - } - return nil -} - -func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) { - var actions []Action - for _, table := range tables { - var action Action - var actionType string - aattrs, err := nl.ParseRouteAttr(table.Value) - if err != nil { - return nil, err - } - nextattr: - for _, aattr := range aattrs { - switch aattr.Attr.Type { - case nl.TCA_KIND: - actionType = string(aattr.Value[:len(aattr.Value)-1]) - // only parse if the action is mirred or bpf - switch actionType { - case "mirred": - action = &MirredAction{} - case "bpf": - action = &BpfAction{} - case "connmark": - action = &ConnmarkAction{} - case "gact": - action = &GenericAction{} - case "tunnel_key": - action = &TunnelKeyAction{} - case "skbedit": - action = &SkbEditAction{} - default: - break nextattr - } - case nl.TCA_OPTIONS: - adata, err := nl.ParseRouteAttr(aattr.Value) - if err != nil { - return nil, err - } - for _, adatum := range adata { - switch actionType { - case "mirred": - switch adatum.Attr.Type { - case nl.TCA_MIRRED_PARMS: - mirred := *nl.DeserializeTcMirred(adatum.Value) - action.(*MirredAction).ActionAttrs = ActionAttrs{} - toAttrs(&mirred.TcGen, action.Attrs()) - action.(*MirredAction).Ifindex = int(mirred.Ifindex) - action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction) - } - case "tunnel_key": - switch adatum.Attr.Type { - case nl.TCA_TUNNEL_KEY_PARMS: - tun := *nl.DeserializeTunnelKey(adatum.Value) - action.(*TunnelKeyAction).ActionAttrs = ActionAttrs{} - toAttrs(&tun.TcGen, action.Attrs()) - action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action) - case nl.TCA_TUNNEL_KEY_ENC_KEY_ID: - action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4]) - case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC: - action.(*TunnelKeyAction).SrcAddr = adatum.Value[:] - case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, nl.TCA_TUNNEL_KEY_ENC_IPV4_DST: - action.(*TunnelKeyAction).DstAddr = adatum.Value[:] - case nl.TCA_TUNNEL_KEY_ENC_DST_PORT: - action.(*TunnelKeyAction).DestPort = ntohs(adatum.Value) - } - case "skbedit": - switch adatum.Attr.Type { - case nl.TCA_SKBEDIT_PARMS: - skbedit := *nl.DeserializeSkbEdit(adatum.Value) - action.(*SkbEditAction).ActionAttrs = ActionAttrs{} - toAttrs(&skbedit.TcGen, action.Attrs()) - case nl.TCA_SKBEDIT_MARK: - mark := native.Uint32(adatum.Value[0:4]) - action.(*SkbEditAction).Mark = &mark - case nl.TCA_SKBEDIT_PRIORITY: - priority := native.Uint32(adatum.Value[0:4]) - action.(*SkbEditAction).Priority = &priority - case nl.TCA_SKBEDIT_PTYPE: - ptype := native.Uint16(adatum.Value[0:2]) - action.(*SkbEditAction).PType = &ptype - case nl.TCA_SKBEDIT_QUEUE_MAPPING: - mapping := native.Uint16(adatum.Value[0:2]) - action.(*SkbEditAction).QueueMapping = &mapping - } - case "bpf": - switch adatum.Attr.Type { - case nl.TCA_ACT_BPF_PARMS: - gen := *nl.DeserializeTcGen(adatum.Value) - toAttrs(&gen, action.Attrs()) - case nl.TCA_ACT_BPF_FD: - action.(*BpfAction).Fd = int(native.Uint32(adatum.Value[0:4])) - case nl.TCA_ACT_BPF_NAME: - action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1]) - } - case "connmark": - switch adatum.Attr.Type { - case nl.TCA_CONNMARK_PARMS: - connmark := *nl.DeserializeTcConnmark(adatum.Value) - action.(*ConnmarkAction).ActionAttrs = ActionAttrs{} - toAttrs(&connmark.TcGen, action.Attrs()) - action.(*ConnmarkAction).Zone = connmark.Zone - } - case "gact": - switch adatum.Attr.Type { - case nl.TCA_GACT_PARMS: - gen := *nl.DeserializeTcGen(adatum.Value) - toAttrs(&gen, action.Attrs()) - } - } - } - } - } - actions = append(actions, action) - } - return actions, nil -} - -func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { - u32 := filter.(*U32) - detailed := false - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_U32_SEL: - detailed = true - sel := nl.DeserializeTcU32Sel(datum.Value) - u32.Sel = sel - if native != networkOrder { - // Handle the endianness of attributes - u32.Sel.Offmask = native.Uint16(htons(sel.Offmask)) - u32.Sel.Hmask = native.Uint32(htonl(sel.Hmask)) - for i, key := range u32.Sel.Keys { - u32.Sel.Keys[i].Mask = native.Uint32(htonl(key.Mask)) - u32.Sel.Keys[i].Val = native.Uint32(htonl(key.Val)) - } - } - case nl.TCA_U32_ACT: - tables, err := nl.ParseRouteAttr(datum.Value) - if err != nil { - return detailed, err - } - u32.Actions, err = parseActions(tables) - if err != nil { - return detailed, err - } - for _, action := range u32.Actions { - if action, ok := action.(*MirredAction); ok { - u32.RedirIndex = int(action.Ifindex) - } - } - case nl.TCA_U32_CLASSID: - u32.ClassId = native.Uint32(datum.Value) - case nl.TCA_U32_DIVISOR: - u32.Divisor = native.Uint32(datum.Value) - case nl.TCA_U32_HASH: - u32.Hash = native.Uint32(datum.Value) - case nl.TCA_U32_LINK: - u32.Link = native.Uint32(datum.Value) - } - } - return detailed, nil -} - -func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { - fw := filter.(*Fw) - detailed := true - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_FW_MASK: - fw.Mask = native.Uint32(datum.Value[0:4]) - case nl.TCA_FW_CLASSID: - fw.ClassId = native.Uint32(datum.Value[0:4]) - case nl.TCA_FW_INDEV: - fw.InDev = string(datum.Value[:len(datum.Value)-1]) - case nl.TCA_FW_POLICE: - adata, _ := nl.ParseRouteAttr(datum.Value) - for _, aattr := range adata { - switch aattr.Attr.Type { - case nl.TCA_POLICE_TBF: - fw.Police = *nl.DeserializeTcPolice(aattr.Value) - case nl.TCA_POLICE_RATE: - fw.Rtab = DeserializeRtab(aattr.Value) - case nl.TCA_POLICE_PEAKRATE: - fw.Ptab = DeserializeRtab(aattr.Value) - } - } - } - } - return detailed, nil -} - -func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { - bpf := filter.(*BpfFilter) - detailed := true - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_BPF_FD: - bpf.Fd = int(native.Uint32(datum.Value[0:4])) - case nl.TCA_BPF_NAME: - bpf.Name = string(datum.Value[:len(datum.Value)-1]) - case nl.TCA_BPF_CLASSID: - bpf.ClassId = native.Uint32(datum.Value[0:4]) - case nl.TCA_BPF_FLAGS: - flags := native.Uint32(datum.Value[0:4]) - if (flags & nl.TCA_BPF_FLAG_ACT_DIRECT) != 0 { - bpf.DirectAction = true - } - case nl.TCA_BPF_ID: - bpf.Id = int(native.Uint32(datum.Value[0:4])) - case nl.TCA_BPF_TAG: - bpf.Tag = hex.EncodeToString(datum.Value[:len(datum.Value)-1]) - } - } - return detailed, nil -} - -func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { - matchall := filter.(*MatchAll) - detailed := true - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_MATCHALL_CLASSID: - matchall.ClassId = native.Uint32(datum.Value[0:4]) - case nl.TCA_MATCHALL_ACT: - tables, err := nl.ParseRouteAttr(datum.Value) - if err != nil { - return detailed, err - } - matchall.Actions, err = parseActions(tables) - if err != nil { - return detailed, err - } - } - } - return detailed, nil -} - -func parseFlowerData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { - return true, filter.(*Flower).decode(data) -} - -func AlignToAtm(size uint) uint { - var linksize, cells int - cells = int(size / nl.ATM_CELL_PAYLOAD) - if (size % nl.ATM_CELL_PAYLOAD) > 0 { - cells++ - } - linksize = cells * nl.ATM_CELL_SIZE - return uint(linksize) -} - -func AdjustSize(sz uint, mpu uint, linklayer int) uint { - if sz < mpu { - sz = mpu - } - switch linklayer { - case nl.LINKLAYER_ATM: - return AlignToAtm(sz) - default: - return sz - } -} - -func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, linklayer int) int { - bps := rate.Rate - mpu := rate.Mpu - var sz uint - if mtu == 0 { - mtu = 2047 - } - if cellLog < 0 { - cellLog = 0 - for (mtu >> uint(cellLog)) > 255 { - cellLog++ - } - } - for i := 0; i < 256; i++ { - sz = AdjustSize(uint((i+1)<= nl.IPSET_ERR_PRIVATE { - err = nl.IPSetError(uintptr(errno)) - } - } - return -} - -func ipsetUnserialize(msgs [][]byte) (result IPSetResult) { - for _, msg := range msgs { - result.unserialize(msg) - } - return result -} - -func (result *IPSetResult) unserialize(msg []byte) { - result.Nfgenmsg = nl.DeserializeNfgenmsg(msg) - - for attr := range nl.ParseAttributes(msg[4:]) { - switch attr.Type { - case nl.IPSET_ATTR_PROTOCOL: - result.Protocol = attr.Value[0] - case nl.IPSET_ATTR_SETNAME: - result.SetName = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_COMMENT: - result.Comment = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_TYPENAME: - result.TypeName = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_REVISION: - result.Revision = attr.Value[0] - case nl.IPSET_ATTR_FAMILY: - result.Family = attr.Value[0] - case nl.IPSET_ATTR_FLAGS: - result.Flags = attr.Value[0] - case nl.IPSET_ATTR_DATA | nl.NLA_F_NESTED: - result.parseAttrData(attr.Value) - case nl.IPSET_ATTR_ADT | nl.NLA_F_NESTED: - result.parseAttrADT(attr.Value) - case nl.IPSET_ATTR_PROTOCOL_MIN: - result.ProtocolMinVersion = attr.Value[0] - case nl.IPSET_ATTR_MARKMASK: - result.MarkMask = attr.Uint32() - default: - log.Printf("unknown ipset attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK) - } - } -} - -func (result *IPSetResult) parseAttrData(data []byte) { - for attr := range nl.ParseAttributes(data) { - switch attr.Type { - case nl.IPSET_ATTR_HASHSIZE | nl.NLA_F_NET_BYTEORDER: - result.HashSize = attr.Uint32() - case nl.IPSET_ATTR_MAXELEM | nl.NLA_F_NET_BYTEORDER: - result.MaxElements = attr.Uint32() - case nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER: - val := attr.Uint32() - result.Timeout = &val - case nl.IPSET_ATTR_ELEMENTS | nl.NLA_F_NET_BYTEORDER: - result.NumEntries = attr.Uint32() - case nl.IPSET_ATTR_REFERENCES | nl.NLA_F_NET_BYTEORDER: - result.References = attr.Uint32() - case nl.IPSET_ATTR_MEMSIZE | nl.NLA_F_NET_BYTEORDER: - result.SizeInMemory = attr.Uint32() - case nl.IPSET_ATTR_CADT_FLAGS | nl.NLA_F_NET_BYTEORDER: - result.CadtFlags = attr.Uint32() - case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED: - for nested := range nl.ParseAttributes(attr.Value) { - switch nested.Type { - case nl.IPSET_ATTR_IP | nl.NLA_F_NET_BYTEORDER: - result.Entries = append(result.Entries, IPSetEntry{IP: nested.Value}) - case nl.IPSET_ATTR_IP: - result.IPFrom = nested.Value - default: - log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK) - } - } - case nl.IPSET_ATTR_IP_TO | nl.NLA_F_NESTED: - for nested := range nl.ParseAttributes(attr.Value) { - switch nested.Type { - case nl.IPSET_ATTR_IP: - result.IPTo = nested.Value - default: - log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK) - } - } - case nl.IPSET_ATTR_PORT_FROM | nl.NLA_F_NET_BYTEORDER: - result.PortFrom = networkOrder.Uint16(attr.Value) - case nl.IPSET_ATTR_PORT_TO | nl.NLA_F_NET_BYTEORDER: - result.PortTo = networkOrder.Uint16(attr.Value) - case nl.IPSET_ATTR_CADT_LINENO | nl.NLA_F_NET_BYTEORDER: - result.LineNo = attr.Uint32() - case nl.IPSET_ATTR_COMMENT: - result.Comment = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_MARKMASK: - result.MarkMask = attr.Uint32() - default: - log.Printf("unknown ipset data attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK) - } - } -} - -func (result *IPSetResult) parseAttrADT(data []byte) { - for attr := range nl.ParseAttributes(data) { - switch attr.Type { - case nl.IPSET_ATTR_DATA | nl.NLA_F_NESTED: - result.Entries = append(result.Entries, parseIPSetEntry(attr.Value)) - default: - log.Printf("unknown ADT attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK) - } - } -} - -func parseIPSetEntry(data []byte) (entry IPSetEntry) { - for attr := range nl.ParseAttributes(data) { - switch attr.Type { - case nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER: - val := attr.Uint32() - entry.Timeout = &val - case nl.IPSET_ATTR_BYTES | nl.NLA_F_NET_BYTEORDER: - val := attr.Uint64() - entry.Bytes = &val - case nl.IPSET_ATTR_PACKETS | nl.NLA_F_NET_BYTEORDER: - val := attr.Uint64() - entry.Packets = &val - case nl.IPSET_ATTR_ETHER: - entry.MAC = net.HardwareAddr(attr.Value) - case nl.IPSET_ATTR_IP: - entry.IP = net.IP(attr.Value) - case nl.IPSET_ATTR_COMMENT: - entry.Comment = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED: - for attr := range nl.ParseAttributes(attr.Value) { - switch attr.Type { - case nl.IPSET_ATTR_IP: - entry.IP = net.IP(attr.Value) - default: - log.Printf("unknown nested ADT attribute from kernel: %+v", attr) - } - } - case nl.IPSET_ATTR_IP2 | nl.NLA_F_NESTED: - for attr := range nl.ParseAttributes(attr.Value) { - switch attr.Type { - case nl.IPSET_ATTR_IP: - entry.IP2 = net.IP(attr.Value) - default: - log.Printf("unknown nested ADT attribute from kernel: %+v", attr) - } - } - case nl.IPSET_ATTR_CIDR: - entry.CIDR = attr.Value[0] - case nl.IPSET_ATTR_CIDR2: - entry.CIDR2 = attr.Value[0] - case nl.IPSET_ATTR_PORT | nl.NLA_F_NET_BYTEORDER: - val := networkOrder.Uint16(attr.Value) - entry.Port = &val - case nl.IPSET_ATTR_PROTO: - val := attr.Value[0] - entry.Protocol = &val - case nl.IPSET_ATTR_IFACE: - entry.IFace = nl.BytesToString(attr.Value) - case nl.IPSET_ATTR_MARK | nl.NLA_F_NET_BYTEORDER: - val := attr.Uint32() - entry.Mark = &val - default: - log.Printf("unknown ADT attribute from kernel: %+v", attr) - } - } - return -} diff --git a/vendor/github.com/tailscale/netlink/link.go b/vendor/github.com/tailscale/netlink/link.go deleted file mode 100644 index bdcb994..0000000 --- a/vendor/github.com/tailscale/netlink/link.go +++ /dev/null @@ -1,1315 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "os" - "strconv" -) - -// Link represents a link device from netlink. Shared link attributes -// like name may be retrieved using the Attrs() method. Unique data -// can be retrieved by casting the object to the proper type. -type Link interface { - Attrs() *LinkAttrs - Type() string -} - -type ( - NsPid int - NsFd int -) - -// LinkAttrs represents data shared by most link types -type LinkAttrs struct { - Index int - MTU int - TxQLen int // Transmit Queue Length - Name string - HardwareAddr net.HardwareAddr - Flags net.Flags - RawFlags uint32 - ParentIndex int // index of the parent link device - MasterIndex int // must be the index of a bridge - Namespace interface{} // nil | NsPid | NsFd - Alias string - Statistics *LinkStatistics - Promisc int - Allmulti int - Multi int - Xdp *LinkXdp - EncapType string - Protinfo *Protinfo - OperState LinkOperState - PhysSwitchID int - NetNsID int - NumTxQueues int - NumRxQueues int - GSOMaxSize uint32 - GSOMaxSegs uint32 - Vfs []VfInfo // virtual functions available on link - Group uint32 - Slave LinkSlave -} - -// LinkSlave represents a slave device. -type LinkSlave interface { - SlaveType() string -} - -// VfInfo represents configuration of virtual function -type VfInfo struct { - ID int - Mac net.HardwareAddr - Vlan int - Qos int - TxRate int // IFLA_VF_TX_RATE Max TxRate - Spoofchk bool - LinkState uint32 - MaxTxRate uint32 // IFLA_VF_RATE Max TxRate - MinTxRate uint32 // IFLA_VF_RATE Min TxRate - RxPackets uint64 - TxPackets uint64 - RxBytes uint64 - TxBytes uint64 - Multicast uint64 - Broadcast uint64 - RxDropped uint64 - TxDropped uint64 - - RssQuery uint32 - Trust uint32 -} - -// LinkOperState represents the values of the IFLA_OPERSTATE link -// attribute, which contains the RFC2863 state of the interface. -type LinkOperState uint8 - -const ( - OperUnknown = iota // Status can't be determined. - OperNotPresent // Some component is missing. - OperDown // Down. - OperLowerLayerDown // Down due to state of lower layer. - OperTesting // In some test mode. - OperDormant // Not up but pending an external event. - OperUp // Up, ready to send packets. -) - -func (s LinkOperState) String() string { - switch s { - case OperNotPresent: - return "not-present" - case OperDown: - return "down" - case OperLowerLayerDown: - return "lower-layer-down" - case OperTesting: - return "testing" - case OperDormant: - return "dormant" - case OperUp: - return "up" - default: - return "unknown" - } -} - -// NewLinkAttrs returns LinkAttrs structure filled with default values -func NewLinkAttrs() LinkAttrs { - return LinkAttrs{ - NetNsID: -1, - TxQLen: -1, - } -} - -type LinkStatistics LinkStatistics64 - -/* -Ref: struct rtnl_link_stats {...} -*/ -type LinkStatistics32 struct { - RxPackets uint32 - TxPackets uint32 - RxBytes uint32 - TxBytes uint32 - RxErrors uint32 - TxErrors uint32 - RxDropped uint32 - TxDropped uint32 - Multicast uint32 - Collisions uint32 - RxLengthErrors uint32 - RxOverErrors uint32 - RxCrcErrors uint32 - RxFrameErrors uint32 - RxFifoErrors uint32 - RxMissedErrors uint32 - TxAbortedErrors uint32 - TxCarrierErrors uint32 - TxFifoErrors uint32 - TxHeartbeatErrors uint32 - TxWindowErrors uint32 - RxCompressed uint32 - TxCompressed uint32 -} - -func (s32 LinkStatistics32) to64() *LinkStatistics64 { - return &LinkStatistics64{ - RxPackets: uint64(s32.RxPackets), - TxPackets: uint64(s32.TxPackets), - RxBytes: uint64(s32.RxBytes), - TxBytes: uint64(s32.TxBytes), - RxErrors: uint64(s32.RxErrors), - TxErrors: uint64(s32.TxErrors), - RxDropped: uint64(s32.RxDropped), - TxDropped: uint64(s32.TxDropped), - Multicast: uint64(s32.Multicast), - Collisions: uint64(s32.Collisions), - RxLengthErrors: uint64(s32.RxLengthErrors), - RxOverErrors: uint64(s32.RxOverErrors), - RxCrcErrors: uint64(s32.RxCrcErrors), - RxFrameErrors: uint64(s32.RxFrameErrors), - RxFifoErrors: uint64(s32.RxFifoErrors), - RxMissedErrors: uint64(s32.RxMissedErrors), - TxAbortedErrors: uint64(s32.TxAbortedErrors), - TxCarrierErrors: uint64(s32.TxCarrierErrors), - TxFifoErrors: uint64(s32.TxFifoErrors), - TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors), - TxWindowErrors: uint64(s32.TxWindowErrors), - RxCompressed: uint64(s32.RxCompressed), - TxCompressed: uint64(s32.TxCompressed), - } -} - -/* -Ref: struct rtnl_link_stats64 {...} -*/ -type LinkStatistics64 struct { - RxPackets uint64 - TxPackets uint64 - RxBytes uint64 - TxBytes uint64 - RxErrors uint64 - TxErrors uint64 - RxDropped uint64 - TxDropped uint64 - Multicast uint64 - Collisions uint64 - RxLengthErrors uint64 - RxOverErrors uint64 - RxCrcErrors uint64 - RxFrameErrors uint64 - RxFifoErrors uint64 - RxMissedErrors uint64 - TxAbortedErrors uint64 - TxCarrierErrors uint64 - TxFifoErrors uint64 - TxHeartbeatErrors uint64 - TxWindowErrors uint64 - RxCompressed uint64 - TxCompressed uint64 -} - -type LinkXdp struct { - Fd int - Attached bool - AttachMode uint32 - Flags uint32 - ProgId uint32 -} - -// Device links cannot be created via netlink. These links -// are links created by udev like 'lo' and 'etho0' -type Device struct { - LinkAttrs -} - -func (device *Device) Attrs() *LinkAttrs { - return &device.LinkAttrs -} - -func (device *Device) Type() string { - return "device" -} - -// Dummy links are dummy ethernet devices -type Dummy struct { - LinkAttrs -} - -func (dummy *Dummy) Attrs() *LinkAttrs { - return &dummy.LinkAttrs -} - -func (dummy *Dummy) Type() string { - return "dummy" -} - -// Ifb links are advanced dummy devices for packet filtering -type Ifb struct { - LinkAttrs -} - -func (ifb *Ifb) Attrs() *LinkAttrs { - return &ifb.LinkAttrs -} - -func (ifb *Ifb) Type() string { - return "ifb" -} - -// Bridge links are simple linux bridges -type Bridge struct { - LinkAttrs - MulticastSnooping *bool - AgeingTime *uint32 - HelloTime *uint32 - VlanFiltering *bool -} - -func (bridge *Bridge) Attrs() *LinkAttrs { - return &bridge.LinkAttrs -} - -func (bridge *Bridge) Type() string { - return "bridge" -} - -// Vlan links have ParentIndex set in their Attrs() -type Vlan struct { - LinkAttrs - VlanId int - VlanProtocol VlanProtocol -} - -func (vlan *Vlan) Attrs() *LinkAttrs { - return &vlan.LinkAttrs -} - -func (vlan *Vlan) Type() string { - return "vlan" -} - -type MacvlanMode uint16 - -const ( - MACVLAN_MODE_DEFAULT MacvlanMode = iota - MACVLAN_MODE_PRIVATE - MACVLAN_MODE_VEPA - MACVLAN_MODE_BRIDGE - MACVLAN_MODE_PASSTHRU - MACVLAN_MODE_SOURCE -) - -// Macvlan links have ParentIndex set in their Attrs() -type Macvlan struct { - LinkAttrs - Mode MacvlanMode - - // MACAddrs is only populated for Macvlan SOURCE links - MACAddrs []net.HardwareAddr -} - -func (macvlan *Macvlan) Attrs() *LinkAttrs { - return &macvlan.LinkAttrs -} - -func (macvlan *Macvlan) Type() string { - return "macvlan" -} - -// Macvtap - macvtap is a virtual interfaces based on macvlan -type Macvtap struct { - Macvlan -} - -func (macvtap Macvtap) Type() string { - return "macvtap" -} - -type TuntapMode uint16 -type TuntapFlag uint16 - -// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink -type Tuntap struct { - LinkAttrs - Mode TuntapMode - Flags TuntapFlag - NonPersist bool - Queues int - Fds []*os.File - Owner uint32 - Group uint32 -} - -func (tuntap *Tuntap) Attrs() *LinkAttrs { - return &tuntap.LinkAttrs -} - -func (tuntap *Tuntap) Type() string { - return "tuntap" -} - -// Veth devices must specify PeerName on create -type Veth struct { - LinkAttrs - PeerName string // veth on create only - PeerHardwareAddr net.HardwareAddr - PeerNamespace interface{} -} - -func (veth *Veth) Attrs() *LinkAttrs { - return &veth.LinkAttrs -} - -func (veth *Veth) Type() string { - return "veth" -} - -// Wireguard represent links of type "wireguard", see https://www.wireguard.com/ -type Wireguard struct { - LinkAttrs -} - -func (wg *Wireguard) Attrs() *LinkAttrs { - return &wg.LinkAttrs -} - -func (wg *Wireguard) Type() string { - return "wireguard" -} - -// GenericLink links represent types that are not currently understood -// by this netlink library. -type GenericLink struct { - LinkAttrs - LinkType string -} - -func (generic *GenericLink) Attrs() *LinkAttrs { - return &generic.LinkAttrs -} - -func (generic *GenericLink) Type() string { - return generic.LinkType -} - -type Vxlan struct { - LinkAttrs - VxlanId int - VtepDevIndex int - SrcAddr net.IP - Group net.IP - TTL int - TOS int - Learning bool - Proxy bool - RSC bool - L2miss bool - L3miss bool - UDPCSum bool - UDP6ZeroCSumTx bool - UDP6ZeroCSumRx bool - NoAge bool - GBP bool - FlowBased bool - Age int - Limit int - Port int - PortLow int - PortHigh int -} - -func (vxlan *Vxlan) Attrs() *LinkAttrs { - return &vxlan.LinkAttrs -} - -func (vxlan *Vxlan) Type() string { - return "vxlan" -} - -type IPVlanMode uint16 - -const ( - IPVLAN_MODE_L2 IPVlanMode = iota - IPVLAN_MODE_L3 - IPVLAN_MODE_L3S - IPVLAN_MODE_MAX -) - -type IPVlanFlag uint16 - -const ( - IPVLAN_FLAG_BRIDGE IPVlanFlag = iota - IPVLAN_FLAG_PRIVATE - IPVLAN_FLAG_VEPA -) - -type IPVlan struct { - LinkAttrs - Mode IPVlanMode - Flag IPVlanFlag -} - -func (ipvlan *IPVlan) Attrs() *LinkAttrs { - return &ipvlan.LinkAttrs -} - -func (ipvlan *IPVlan) Type() string { - return "ipvlan" -} - -// IPVtap - IPVtap is a virtual interfaces based on ipvlan -type IPVtap struct { - IPVlan -} - -func (ipvtap *IPVtap) Attrs() *LinkAttrs { - return &ipvtap.LinkAttrs -} - -func (ipvtap IPVtap) Type() string { - return "ipvtap" -} - -// VlanProtocol type -type VlanProtocol int - -func (p VlanProtocol) String() string { - s, ok := VlanProtocolToString[p] - if !ok { - return fmt.Sprintf("VlanProtocol(%d)", p) - } - return s -} - -// StringToVlanProtocol returns vlan protocol, or unknown is the s is invalid. -func StringToVlanProtocol(s string) VlanProtocol { - mode, ok := StringToVlanProtocolMap[s] - if !ok { - return VLAN_PROTOCOL_UNKNOWN - } - return mode -} - -// VlanProtocol possible values -const ( - VLAN_PROTOCOL_UNKNOWN VlanProtocol = 0 - VLAN_PROTOCOL_8021Q VlanProtocol = 0x8100 - VLAN_PROTOCOL_8021AD VlanProtocol = 0x88A8 -) - -var VlanProtocolToString = map[VlanProtocol]string{ - VLAN_PROTOCOL_8021Q: "802.1q", - VLAN_PROTOCOL_8021AD: "802.1ad", -} - -var StringToVlanProtocolMap = map[string]VlanProtocol{ - "802.1q": VLAN_PROTOCOL_8021Q, - "802.1ad": VLAN_PROTOCOL_8021AD, -} - -// BondMode type -type BondMode int - -func (b BondMode) String() string { - s, ok := bondModeToString[b] - if !ok { - return fmt.Sprintf("BondMode(%d)", b) - } - return s -} - -// StringToBondMode returns bond mode, or unknown is the s is invalid. -func StringToBondMode(s string) BondMode { - mode, ok := StringToBondModeMap[s] - if !ok { - return BOND_MODE_UNKNOWN - } - return mode -} - -// Possible BondMode -const ( - BOND_MODE_BALANCE_RR BondMode = iota - BOND_MODE_ACTIVE_BACKUP - BOND_MODE_BALANCE_XOR - BOND_MODE_BROADCAST - BOND_MODE_802_3AD - BOND_MODE_BALANCE_TLB - BOND_MODE_BALANCE_ALB - BOND_MODE_UNKNOWN -) - -var bondModeToString = map[BondMode]string{ - BOND_MODE_BALANCE_RR: "balance-rr", - BOND_MODE_ACTIVE_BACKUP: "active-backup", - BOND_MODE_BALANCE_XOR: "balance-xor", - BOND_MODE_BROADCAST: "broadcast", - BOND_MODE_802_3AD: "802.3ad", - BOND_MODE_BALANCE_TLB: "balance-tlb", - BOND_MODE_BALANCE_ALB: "balance-alb", -} -var StringToBondModeMap = map[string]BondMode{ - "balance-rr": BOND_MODE_BALANCE_RR, - "active-backup": BOND_MODE_ACTIVE_BACKUP, - "balance-xor": BOND_MODE_BALANCE_XOR, - "broadcast": BOND_MODE_BROADCAST, - "802.3ad": BOND_MODE_802_3AD, - "balance-tlb": BOND_MODE_BALANCE_TLB, - "balance-alb": BOND_MODE_BALANCE_ALB, -} - -// BondArpValidate type -type BondArpValidate int - -// Possible BondArpValidate value -const ( - BOND_ARP_VALIDATE_NONE BondArpValidate = iota - BOND_ARP_VALIDATE_ACTIVE - BOND_ARP_VALIDATE_BACKUP - BOND_ARP_VALIDATE_ALL -) - -var bondArpValidateToString = map[BondArpValidate]string{ - BOND_ARP_VALIDATE_NONE: "none", - BOND_ARP_VALIDATE_ACTIVE: "active", - BOND_ARP_VALIDATE_BACKUP: "backup", - BOND_ARP_VALIDATE_ALL: "none", -} -var StringToBondArpValidateMap = map[string]BondArpValidate{ - "none": BOND_ARP_VALIDATE_NONE, - "active": BOND_ARP_VALIDATE_ACTIVE, - "backup": BOND_ARP_VALIDATE_BACKUP, - "all": BOND_ARP_VALIDATE_ALL, -} - -func (b BondArpValidate) String() string { - s, ok := bondArpValidateToString[b] - if !ok { - return fmt.Sprintf("BondArpValidate(%d)", b) - } - return s -} - -// BondPrimaryReselect type -type BondPrimaryReselect int - -// Possible BondPrimaryReselect value -const ( - BOND_PRIMARY_RESELECT_ALWAYS BondPrimaryReselect = iota - BOND_PRIMARY_RESELECT_BETTER - BOND_PRIMARY_RESELECT_FAILURE -) - -var bondPrimaryReselectToString = map[BondPrimaryReselect]string{ - BOND_PRIMARY_RESELECT_ALWAYS: "always", - BOND_PRIMARY_RESELECT_BETTER: "better", - BOND_PRIMARY_RESELECT_FAILURE: "failure", -} -var StringToBondPrimaryReselectMap = map[string]BondPrimaryReselect{ - "always": BOND_PRIMARY_RESELECT_ALWAYS, - "better": BOND_PRIMARY_RESELECT_BETTER, - "failure": BOND_PRIMARY_RESELECT_FAILURE, -} - -func (b BondPrimaryReselect) String() string { - s, ok := bondPrimaryReselectToString[b] - if !ok { - return fmt.Sprintf("BondPrimaryReselect(%d)", b) - } - return s -} - -// BondArpAllTargets type -type BondArpAllTargets int - -// Possible BondArpAllTargets value -const ( - BOND_ARP_ALL_TARGETS_ANY BondArpAllTargets = iota - BOND_ARP_ALL_TARGETS_ALL -) - -var bondArpAllTargetsToString = map[BondArpAllTargets]string{ - BOND_ARP_ALL_TARGETS_ANY: "any", - BOND_ARP_ALL_TARGETS_ALL: "all", -} -var StringToBondArpAllTargetsMap = map[string]BondArpAllTargets{ - "any": BOND_ARP_ALL_TARGETS_ANY, - "all": BOND_ARP_ALL_TARGETS_ALL, -} - -func (b BondArpAllTargets) String() string { - s, ok := bondArpAllTargetsToString[b] - if !ok { - return fmt.Sprintf("BondArpAllTargets(%d)", b) - } - return s -} - -// BondFailOverMac type -type BondFailOverMac int - -// Possible BondFailOverMac value -const ( - BOND_FAIL_OVER_MAC_NONE BondFailOverMac = iota - BOND_FAIL_OVER_MAC_ACTIVE - BOND_FAIL_OVER_MAC_FOLLOW -) - -var bondFailOverMacToString = map[BondFailOverMac]string{ - BOND_FAIL_OVER_MAC_NONE: "none", - BOND_FAIL_OVER_MAC_ACTIVE: "active", - BOND_FAIL_OVER_MAC_FOLLOW: "follow", -} -var StringToBondFailOverMacMap = map[string]BondFailOverMac{ - "none": BOND_FAIL_OVER_MAC_NONE, - "active": BOND_FAIL_OVER_MAC_ACTIVE, - "follow": BOND_FAIL_OVER_MAC_FOLLOW, -} - -func (b BondFailOverMac) String() string { - s, ok := bondFailOverMacToString[b] - if !ok { - return fmt.Sprintf("BondFailOverMac(%d)", b) - } - return s -} - -// BondXmitHashPolicy type -type BondXmitHashPolicy int - -func (b BondXmitHashPolicy) String() string { - s, ok := bondXmitHashPolicyToString[b] - if !ok { - return fmt.Sprintf("XmitHashPolicy(%d)", b) - } - return s -} - -// StringToBondXmitHashPolicy returns bond lacp arte, or unknown is the s is invalid. -func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy { - lacp, ok := StringToBondXmitHashPolicyMap[s] - if !ok { - return BOND_XMIT_HASH_POLICY_UNKNOWN - } - return lacp -} - -// Possible BondXmitHashPolicy value -const ( - BOND_XMIT_HASH_POLICY_LAYER2 BondXmitHashPolicy = iota - BOND_XMIT_HASH_POLICY_LAYER3_4 - BOND_XMIT_HASH_POLICY_LAYER2_3 - BOND_XMIT_HASH_POLICY_ENCAP2_3 - BOND_XMIT_HASH_POLICY_ENCAP3_4 - BOND_XMIT_HASH_POLICY_UNKNOWN -) - -var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{ - BOND_XMIT_HASH_POLICY_LAYER2: "layer2", - BOND_XMIT_HASH_POLICY_LAYER3_4: "layer3+4", - BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3", - BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3", - BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4", -} -var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{ - "layer2": BOND_XMIT_HASH_POLICY_LAYER2, - "layer3+4": BOND_XMIT_HASH_POLICY_LAYER3_4, - "layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3, - "encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3, - "encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4, -} - -// BondLacpRate type -type BondLacpRate int - -func (b BondLacpRate) String() string { - s, ok := bondLacpRateToString[b] - if !ok { - return fmt.Sprintf("LacpRate(%d)", b) - } - return s -} - -// StringToBondLacpRate returns bond lacp arte, or unknown is the s is invalid. -func StringToBondLacpRate(s string) BondLacpRate { - lacp, ok := StringToBondLacpRateMap[s] - if !ok { - return BOND_LACP_RATE_UNKNOWN - } - return lacp -} - -// Possible BondLacpRate value -const ( - BOND_LACP_RATE_SLOW BondLacpRate = iota - BOND_LACP_RATE_FAST - BOND_LACP_RATE_UNKNOWN -) - -var bondLacpRateToString = map[BondLacpRate]string{ - BOND_LACP_RATE_SLOW: "slow", - BOND_LACP_RATE_FAST: "fast", -} -var StringToBondLacpRateMap = map[string]BondLacpRate{ - "slow": BOND_LACP_RATE_SLOW, - "fast": BOND_LACP_RATE_FAST, -} - -// BondAdSelect type -type BondAdSelect int - -// Possible BondAdSelect value -const ( - BOND_AD_SELECT_STABLE BondAdSelect = iota - BOND_AD_SELECT_BANDWIDTH - BOND_AD_SELECT_COUNT -) - -var bondAdSelectToString = map[BondAdSelect]string{ - BOND_AD_SELECT_STABLE: "stable", - BOND_AD_SELECT_BANDWIDTH: "bandwidth", - BOND_AD_SELECT_COUNT: "count", -} -var StringToBondAdSelectMap = map[string]BondAdSelect{ - "stable": BOND_AD_SELECT_STABLE, - "bandwidth": BOND_AD_SELECT_BANDWIDTH, - "count": BOND_AD_SELECT_COUNT, -} - -func (b BondAdSelect) String() string { - s, ok := bondAdSelectToString[b] - if !ok { - return fmt.Sprintf("BondAdSelect(%d)", b) - } - return s -} - -// BondAdInfo represents ad info for bond -type BondAdInfo struct { - AggregatorId int - NumPorts int - ActorKey int - PartnerKey int - PartnerMac net.HardwareAddr -} - -// Bond representation -type Bond struct { - LinkAttrs - Mode BondMode - ActiveSlave int - Miimon int - UpDelay int - DownDelay int - UseCarrier int - ArpInterval int - ArpIpTargets []net.IP - ArpValidate BondArpValidate - ArpAllTargets BondArpAllTargets - Primary int - PrimaryReselect BondPrimaryReselect - FailOverMac BondFailOverMac - XmitHashPolicy BondXmitHashPolicy - ResendIgmp int - NumPeerNotif int - AllSlavesActive int - MinLinks int - LpInterval int - PacketsPerSlave int - LacpRate BondLacpRate - AdSelect BondAdSelect - // looking at iproute tool AdInfo can only be retrived. It can't be set. - AdInfo *BondAdInfo - AdActorSysPrio int - AdUserPortKey int - AdActorSystem net.HardwareAddr - TlbDynamicLb int -} - -func NewLinkBond(atr LinkAttrs) *Bond { - return &Bond{ - LinkAttrs: atr, - Mode: -1, - ActiveSlave: -1, - Miimon: -1, - UpDelay: -1, - DownDelay: -1, - UseCarrier: -1, - ArpInterval: -1, - ArpIpTargets: nil, - ArpValidate: -1, - ArpAllTargets: -1, - Primary: -1, - PrimaryReselect: -1, - FailOverMac: -1, - XmitHashPolicy: -1, - ResendIgmp: -1, - NumPeerNotif: -1, - AllSlavesActive: -1, - MinLinks: -1, - LpInterval: -1, - PacketsPerSlave: -1, - LacpRate: -1, - AdSelect: -1, - AdActorSysPrio: -1, - AdUserPortKey: -1, - AdActorSystem: nil, - TlbDynamicLb: -1, - } -} - -// Flag mask for bond options. Bond.Flagmask must be set to on for option to work. -const ( - BOND_MODE_MASK uint64 = 1 << (1 + iota) - BOND_ACTIVE_SLAVE_MASK - BOND_MIIMON_MASK - BOND_UPDELAY_MASK - BOND_DOWNDELAY_MASK - BOND_USE_CARRIER_MASK - BOND_ARP_INTERVAL_MASK - BOND_ARP_VALIDATE_MASK - BOND_ARP_ALL_TARGETS_MASK - BOND_PRIMARY_MASK - BOND_PRIMARY_RESELECT_MASK - BOND_FAIL_OVER_MAC_MASK - BOND_XMIT_HASH_POLICY_MASK - BOND_RESEND_IGMP_MASK - BOND_NUM_PEER_NOTIF_MASK - BOND_ALL_SLAVES_ACTIVE_MASK - BOND_MIN_LINKS_MASK - BOND_LP_INTERVAL_MASK - BOND_PACKETS_PER_SLAVE_MASK - BOND_LACP_RATE_MASK - BOND_AD_SELECT_MASK -) - -// Attrs implementation. -func (bond *Bond) Attrs() *LinkAttrs { - return &bond.LinkAttrs -} - -// Type implementation fro Vxlan. -func (bond *Bond) Type() string { - return "bond" -} - -// BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave -// attribute, which contains the state of the bond slave. -type BondSlaveState uint8 - -const ( - //BondStateActive Link is active. - BondStateActive BondSlaveState = iota - //BondStateBackup Link is backup. - BondStateBackup -) - -func (s BondSlaveState) String() string { - switch s { - case BondStateActive: - return "ACTIVE" - case BondStateBackup: - return "BACKUP" - default: - return strconv.Itoa(int(s)) - } -} - -// BondSlaveMiiStatus represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave -// attribute, which contains the status of MII link monitoring -type BondSlaveMiiStatus uint8 - -const ( - //BondLinkUp link is up and running. - BondLinkUp BondSlaveMiiStatus = iota - //BondLinkFail link has just gone down. - BondLinkFail - //BondLinkDown link has been down for too long time. - BondLinkDown - //BondLinkBack link is going back. - BondLinkBack -) - -func (s BondSlaveMiiStatus) String() string { - switch s { - case BondLinkUp: - return "UP" - case BondLinkFail: - return "GOING_DOWN" - case BondLinkDown: - return "DOWN" - case BondLinkBack: - return "GOING_BACK" - default: - return strconv.Itoa(int(s)) - } -} - -type BondSlave struct { - State BondSlaveState - MiiStatus BondSlaveMiiStatus - LinkFailureCount uint32 - PermHardwareAddr net.HardwareAddr - QueueId uint16 - AggregatorId uint16 - AdActorOperPortState uint8 - AdPartnerOperPortState uint16 -} - -func (b *BondSlave) SlaveType() string { - return "bond" -} - -type VrfSlave struct { - Table uint32 -} - -func (v *VrfSlave) SlaveType() string { - return "vrf" -} - -// Geneve devices must specify RemoteIP and ID (VNI) on create -// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223 -type Geneve struct { - LinkAttrs - ID uint32 // vni - Remote net.IP - Ttl uint8 - Tos uint8 - Dport uint16 - UdpCsum uint8 - UdpZeroCsum6Tx uint8 - UdpZeroCsum6Rx uint8 - Link uint32 - FlowBased bool -} - -func (geneve *Geneve) Attrs() *LinkAttrs { - return &geneve.LinkAttrs -} - -func (geneve *Geneve) Type() string { - return "geneve" -} - -// Gretap devices must specify LocalIP and RemoteIP on create -type Gretap struct { - LinkAttrs - IKey uint32 - OKey uint32 - EncapSport uint16 - EncapDport uint16 - Local net.IP - Remote net.IP - IFlags uint16 - OFlags uint16 - PMtuDisc uint8 - Ttl uint8 - Tos uint8 - EncapType uint16 - EncapFlags uint16 - Link uint32 - FlowBased bool -} - -func (gretap *Gretap) Attrs() *LinkAttrs { - return &gretap.LinkAttrs -} - -func (gretap *Gretap) Type() string { - if gretap.Local.To4() == nil { - return "ip6gretap" - } - return "gretap" -} - -type Iptun struct { - LinkAttrs - Ttl uint8 - Tos uint8 - PMtuDisc uint8 - Link uint32 - Local net.IP - Remote net.IP - EncapSport uint16 - EncapDport uint16 - EncapType uint16 - EncapFlags uint16 - FlowBased bool -} - -func (iptun *Iptun) Attrs() *LinkAttrs { - return &iptun.LinkAttrs -} - -func (iptun *Iptun) Type() string { - return "ipip" -} - -type Ip6tnl struct { - LinkAttrs - Link uint32 - Local net.IP - Remote net.IP - Ttl uint8 - Tos uint8 - Flags uint32 - Proto uint8 - FlowInfo uint32 - EncapLimit uint8 - EncapType uint16 - EncapFlags uint16 - EncapSport uint16 - EncapDport uint16 -} - -func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs { - return &ip6tnl.LinkAttrs -} - -func (ip6tnl *Ip6tnl) Type() string { - return "ip6tnl" -} - -type Sittun struct { - LinkAttrs - Link uint32 - Ttl uint8 - Tos uint8 - PMtuDisc uint8 - Proto uint8 - Local net.IP - Remote net.IP - EncapLimit uint8 - EncapType uint16 - EncapFlags uint16 - EncapSport uint16 - EncapDport uint16 -} - -func (sittun *Sittun) Attrs() *LinkAttrs { - return &sittun.LinkAttrs -} - -func (sittun *Sittun) Type() string { - return "sit" -} - -type Vti struct { - LinkAttrs - IKey uint32 - OKey uint32 - Link uint32 - Local net.IP - Remote net.IP -} - -func (vti *Vti) Attrs() *LinkAttrs { - return &vti.LinkAttrs -} - -func (vti *Vti) Type() string { - if vti.Local.To4() == nil { - return "vti6" - } - return "vti" -} - -type Gretun struct { - LinkAttrs - Link uint32 - IFlags uint16 - OFlags uint16 - IKey uint32 - OKey uint32 - Local net.IP - Remote net.IP - Ttl uint8 - Tos uint8 - PMtuDisc uint8 - EncapType uint16 - EncapFlags uint16 - EncapSport uint16 - EncapDport uint16 -} - -func (gretun *Gretun) Attrs() *LinkAttrs { - return &gretun.LinkAttrs -} - -func (gretun *Gretun) Type() string { - if gretun.Local.To4() == nil { - return "ip6gre" - } - return "gre" -} - -type Vrf struct { - LinkAttrs - Table uint32 -} - -func (vrf *Vrf) Attrs() *LinkAttrs { - return &vrf.LinkAttrs -} - -func (vrf *Vrf) Type() string { - return "vrf" -} - -type GTP struct { - LinkAttrs - FD0 int - FD1 int - Role int - PDPHashsize int -} - -func (gtp *GTP) Attrs() *LinkAttrs { - return >p.LinkAttrs -} - -func (gtp *GTP) Type() string { - return "gtp" -} - -// Virtual XFRM Interfaces -// Named "xfrmi" to prevent confusion with XFRM objects -type Xfrmi struct { - LinkAttrs - Ifid uint32 -} - -func (xfrm *Xfrmi) Attrs() *LinkAttrs { - return &xfrm.LinkAttrs -} - -func (xfrm *Xfrmi) Type() string { - return "xfrm" -} - -// IPoIB interface - -type IPoIBMode uint16 - -func (m *IPoIBMode) String() string { - str, ok := iPoIBModeToString[*m] - if !ok { - return fmt.Sprintf("mode(%d)", *m) - } - return str -} - -const ( - IPOIB_MODE_DATAGRAM = iota - IPOIB_MODE_CONNECTED -) - -var iPoIBModeToString = map[IPoIBMode]string{ - IPOIB_MODE_DATAGRAM: "datagram", - IPOIB_MODE_CONNECTED: "connected", -} - -var StringToIPoIBMode = map[string]IPoIBMode{ - "datagram": IPOIB_MODE_DATAGRAM, - "connected": IPOIB_MODE_CONNECTED, -} - -const ( - CAN_STATE_ERROR_ACTIVE = iota - CAN_STATE_ERROR_WARNING - CAN_STATE_ERROR_PASSIVE - CAN_STATE_BUS_OFF - CAN_STATE_STOPPED - CAN_STATE_SLEEPING -) - -type Can struct { - LinkAttrs - - BitRate uint32 - SamplePoint uint32 - TimeQuanta uint32 - PropagationSegment uint32 - PhaseSegment1 uint32 - PhaseSegment2 uint32 - SyncJumpWidth uint32 - BitRatePreScaler uint32 - - Name string - TimeSegment1Min uint32 - TimeSegment1Max uint32 - TimeSegment2Min uint32 - TimeSegment2Max uint32 - SyncJumpWidthMax uint32 - BitRatePreScalerMin uint32 - BitRatePreScalerMax uint32 - BitRatePreScalerInc uint32 - - ClockFrequency uint32 - - State uint32 - - Mask uint32 - Flags uint32 - - TxError uint16 - RxError uint16 - - RestartMs uint32 -} - -func (can *Can) Attrs() *LinkAttrs { - return &can.LinkAttrs -} - -func (can *Can) Type() string { - return "can" -} - -type IPoIB struct { - LinkAttrs - Pkey uint16 - Mode IPoIBMode - Umcast uint16 -} - -func (ipoib *IPoIB) Attrs() *LinkAttrs { - return &ipoib.LinkAttrs -} - -func (ipoib *IPoIB) Type() string { - return "ipoib" -} - -type BareUDP struct { - LinkAttrs - Port uint16 - EtherType uint16 - SrcPortMin uint16 - MultiProto bool -} - -func (bareudp *BareUDP) Attrs() *LinkAttrs { - return &bareudp.LinkAttrs -} - -func (bareudp *BareUDP) Type() string { - return "bareudp" -} - -// iproute2 supported devices; -// vlan | veth | vcan | dummy | ifb | macvlan | macvtap | -// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | -// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon | -// bond_slave | ipvlan | xfrm | bareudp - -// LinkNotFoundError wraps the various not found errors when -// getting/reading links. This is intended for better error -// handling by dependent code so that "not found error" can -// be distinguished from other errors -type LinkNotFoundError struct { - error -} diff --git a/vendor/github.com/tailscale/netlink/link_linux.go b/vendor/github.com/tailscale/netlink/link_linux.go deleted file mode 100644 index 0e03bfa..0000000 --- a/vendor/github.com/tailscale/netlink/link_linux.go +++ /dev/null @@ -1,3457 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "fmt" - "io/ioutil" - "net" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - "github.com/tailscale/netlink/nl" - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -const ( - SizeofLinkStats32 = 0x5c - SizeofLinkStats64 = 0xb8 -) - -const ( - TUNTAP_MODE_TUN TuntapMode = unix.IFF_TUN - TUNTAP_MODE_TAP TuntapMode = unix.IFF_TAP - TUNTAP_DEFAULTS TuntapFlag = unix.IFF_TUN_EXCL | unix.IFF_ONE_QUEUE - TUNTAP_VNET_HDR TuntapFlag = unix.IFF_VNET_HDR - TUNTAP_TUN_EXCL TuntapFlag = unix.IFF_TUN_EXCL - TUNTAP_NO_PI TuntapFlag = unix.IFF_NO_PI - TUNTAP_ONE_QUEUE TuntapFlag = unix.IFF_ONE_QUEUE - TUNTAP_MULTI_QUEUE TuntapFlag = unix.IFF_MULTI_QUEUE - TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI -) - -var StringToTuntapModeMap = map[string]TuntapMode{ - "tun": TUNTAP_MODE_TUN, - "tap": TUNTAP_MODE_TAP, -} - -func (ttm TuntapMode) String() string { - switch ttm { - case TUNTAP_MODE_TUN: - return "tun" - case TUNTAP_MODE_TAP: - return "tap" - } - return "unknown" -} - -const ( - VF_LINK_STATE_AUTO uint32 = 0 - VF_LINK_STATE_ENABLE uint32 = 1 - VF_LINK_STATE_DISABLE uint32 = 2 -) - -var macvlanModes = [...]uint32{ - 0, - nl.MACVLAN_MODE_PRIVATE, - nl.MACVLAN_MODE_VEPA, - nl.MACVLAN_MODE_BRIDGE, - nl.MACVLAN_MODE_PASSTHRU, - nl.MACVLAN_MODE_SOURCE, -} - -func ensureIndex(link *LinkAttrs) { - if link != nil && link.Index == 0 { - newlink, _ := LinkByName(link.Name) - if newlink != nil { - link.Index = newlink.Attrs().Index - } - } -} - -func (h *Handle) ensureIndex(link *LinkAttrs) { - if link != nil && link.Index == 0 { - newlink, _ := h.LinkByName(link.Name) - if newlink != nil { - link.Index = newlink.Attrs().Index - } - } -} - -func (h *Handle) LinkSetARPOff(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change |= unix.IFF_NOARP - msg.Flags |= unix.IFF_NOARP - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func LinkSetARPOff(link Link) error { - return pkgHandle.LinkSetARPOff(link) -} - -func (h *Handle) LinkSetARPOn(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change |= unix.IFF_NOARP - msg.Flags &= ^uint32(unix.IFF_NOARP) - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func LinkSetARPOn(link Link) error { - return pkgHandle.LinkSetARPOn(link) -} - -func (h *Handle) SetPromiscOn(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_PROMISC - msg.Flags = unix.IFF_PROMISC - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetAllmulticastOn enables the reception of all hardware multicast packets for the link device. -// Equivalent to: `ip link set $link allmulticast on` -func LinkSetAllmulticastOn(link Link) error { - return pkgHandle.LinkSetAllmulticastOn(link) -} - -// LinkSetAllmulticastOn enables the reception of all hardware multicast packets for the link device. -// Equivalent to: `ip link set $link allmulticast on` -func (h *Handle) LinkSetAllmulticastOn(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_ALLMULTI - msg.Flags = unix.IFF_ALLMULTI - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetAllmulticastOff disables the reception of all hardware multicast packets for the link device. -// Equivalent to: `ip link set $link allmulticast off` -func LinkSetAllmulticastOff(link Link) error { - return pkgHandle.LinkSetAllmulticastOff(link) -} - -// LinkSetAllmulticastOff disables the reception of all hardware multicast packets for the link device. -// Equivalent to: `ip link set $link allmulticast off` -func (h *Handle) LinkSetAllmulticastOff(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_ALLMULTI - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetMulticastOn enables the reception of multicast packets for the link device. -// Equivalent to: `ip link set $link multicast on` -func LinkSetMulticastOn(link Link) error { - return pkgHandle.LinkSetMulticastOn(link) -} - -// LinkSetMulticastOn enables the reception of multicast packets for the link device. -// Equivalent to: `ip link set $link multicast on` -func (h *Handle) LinkSetMulticastOn(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_MULTICAST - msg.Flags = unix.IFF_MULTICAST - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetAllmulticastOff disables the reception of multicast packets for the link device. -// Equivalent to: `ip link set $link multicast off` -func LinkSetMulticastOff(link Link) error { - return pkgHandle.LinkSetMulticastOff(link) -} - -// LinkSetAllmulticastOff disables the reception of multicast packets for the link device. -// Equivalent to: `ip link set $link multicast off` -func (h *Handle) LinkSetMulticastOff(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_MULTICAST - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error { - return pkgHandle.MacvlanMACAddrAdd(link, addr) -} - -func (h *Handle) MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error { - return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_ADD) -} - -func MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error { - return pkgHandle.MacvlanMACAddrDel(link, addr) -} - -func (h *Handle) MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error { - return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_DEL) -} - -func MacvlanMACAddrFlush(link Link) error { - return pkgHandle.MacvlanMACAddrFlush(link) -} - -func (h *Handle) MacvlanMACAddrFlush(link Link) error { - return h.macvlanMACAddrChange(link, nil, nl.MACVLAN_MACADDR_FLUSH) -} - -func MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error { - return pkgHandle.MacvlanMACAddrSet(link, addrs) -} - -func (h *Handle) MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error { - return h.macvlanMACAddrChange(link, addrs, nl.MACVLAN_MACADDR_SET) -} - -func (h *Handle) macvlanMACAddrChange(link Link, addrs []net.HardwareAddr, mode uint32) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) - linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) - inner := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - // IFLA_MACVLAN_MACADDR_MODE = mode - b := make([]byte, 4) - native.PutUint32(b, mode) - inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR_MODE, b) - - // populate message with MAC addrs, if necessary - switch mode { - case nl.MACVLAN_MACADDR_ADD, nl.MACVLAN_MACADDR_DEL: - if len(addrs) == 1 { - inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR, []byte(addrs[0])) - } - case nl.MACVLAN_MACADDR_SET: - mad := inner.AddRtAttr(nl.IFLA_MACVLAN_MACADDR_DATA, nil) - for _, addr := range addrs { - mad.AddRtAttr(nl.IFLA_MACVLAN_MACADDR, []byte(addr)) - } - } - - req.AddData(linkInfo) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetMacvlanMode sets the mode of a macvlan or macvtap link device. -// Note that passthrough mode cannot be set to and from and will fail. -// Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode -func LinkSetMacvlanMode(link Link, mode MacvlanMode) error { - return pkgHandle.LinkSetMacvlanMode(link, mode) -} - -// LinkSetMacvlanMode sets the mode of the macvlan or macvtap link device. -// Note that passthrough mode cannot be set to and from and will fail. -// Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode -func (h *Handle) LinkSetMacvlanMode(link Link, mode MacvlanMode) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) - linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) - - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[mode])) - - req.AddData(linkInfo) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func BridgeSetMcastSnoop(link Link, on bool) error { - return pkgHandle.BridgeSetMcastSnoop(link, on) -} - -func (h *Handle) BridgeSetMcastSnoop(link Link, on bool) error { - bridge := link.(*Bridge) - bridge.MulticastSnooping = &on - return h.linkModify(bridge, unix.NLM_F_ACK) -} - -func BridgeSetVlanFiltering(link Link, on bool) error { - return pkgHandle.BridgeSetVlanFiltering(link, on) -} - -func (h *Handle) BridgeSetVlanFiltering(link Link, on bool) error { - bridge := link.(*Bridge) - bridge.VlanFiltering = &on - return h.linkModify(bridge, unix.NLM_F_ACK) -} - -func SetPromiscOn(link Link) error { - return pkgHandle.SetPromiscOn(link) -} - -func (h *Handle) SetPromiscOff(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_PROMISC - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func SetPromiscOff(link Link) error { - return pkgHandle.SetPromiscOff(link) -} - -// LinkSetUp enables the link device. -// Equivalent to: `ip link set $link up` -func LinkSetUp(link Link) error { - return pkgHandle.LinkSetUp(link) -} - -// LinkSetUp enables the link device. -// Equivalent to: `ip link set $link up` -func (h *Handle) LinkSetUp(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_UP - msg.Flags = unix.IFF_UP - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetDown disables link device. -// Equivalent to: `ip link set $link down` -func LinkSetDown(link Link) error { - return pkgHandle.LinkSetDown(link) -} - -// LinkSetDown disables link device. -// Equivalent to: `ip link set $link down` -func (h *Handle) LinkSetDown(link Link) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Change = unix.IFF_UP - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetMTU sets the mtu of the link device. -// Equivalent to: `ip link set $link mtu $mtu` -func LinkSetMTU(link Link, mtu int) error { - return pkgHandle.LinkSetMTU(link, mtu) -} - -// LinkSetMTU sets the mtu of the link device. -// Equivalent to: `ip link set $link mtu $mtu` -func (h *Handle) LinkSetMTU(link Link, mtu int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(mtu)) - - data := nl.NewRtAttr(unix.IFLA_MTU, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetName sets the name of the link device. -// Equivalent to: `ip link set $link name $name` -func LinkSetName(link Link, name string) error { - return pkgHandle.LinkSetName(link, name) -} - -// LinkSetName sets the name of the link device. -// Equivalent to: `ip link set $link name $name` -func (h *Handle) LinkSetName(link Link, name string) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_IFNAME, []byte(name)) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetAlias sets the alias of the link device. -// Equivalent to: `ip link set dev $link alias $name` -func LinkSetAlias(link Link, name string) error { - return pkgHandle.LinkSetAlias(link, name) -} - -// LinkSetAlias sets the alias of the link device. -// Equivalent to: `ip link set dev $link alias $name` -func (h *Handle) LinkSetAlias(link Link, name string) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(name)) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetHardwareAddr sets the hardware address of the link device. -// Equivalent to: `ip link set $link address $hwaddr` -func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { - return pkgHandle.LinkSetHardwareAddr(link, hwaddr) -} - -// LinkSetHardwareAddr sets the hardware address of the link device. -// Equivalent to: `ip link set $link address $hwaddr` -func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(hwaddr)) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfHardwareAddr sets the hardware address of a vf for the link. -// Equivalent to: `ip link set $link vf $vf mac $hwaddr` -func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { - return pkgHandle.LinkSetVfHardwareAddr(link, vf, hwaddr) -} - -// LinkSetVfHardwareAddr sets the hardware address of a vf for the link. -// Equivalent to: `ip link set $link vf $vf mac $hwaddr` -func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfMac{ - Vf: uint32(vf), - } - copy(vfmsg.Mac[:], []byte(hwaddr)) - info.AddRtAttr(nl.IFLA_VF_MAC, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfVlan sets the vlan of a vf for the link. -// Equivalent to: `ip link set $link vf $vf vlan $vlan` -func LinkSetVfVlan(link Link, vf, vlan int) error { - return pkgHandle.LinkSetVfVlan(link, vf, vlan) -} - -// LinkSetVfVlan sets the vlan of a vf for the link. -// Equivalent to: `ip link set $link vf $vf vlan $vlan` -func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfVlan{ - Vf: uint32(vf), - Vlan: uint32(vlan), - } - info.AddRtAttr(nl.IFLA_VF_VLAN, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link. -// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos` -func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error { - return pkgHandle.LinkSetVfVlanQos(link, vf, vlan, qos) -} - -// LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link. -// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos` -func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfVlan{ - Vf: uint32(vf), - Vlan: uint32(vlan), - Qos: uint32(qos), - } - info.AddRtAttr(nl.IFLA_VF_VLAN, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfTxRate sets the tx rate of a vf for the link. -// Equivalent to: `ip link set $link vf $vf rate $rate` -func LinkSetVfTxRate(link Link, vf, rate int) error { - return pkgHandle.LinkSetVfTxRate(link, vf, rate) -} - -// LinkSetVfTxRate sets the tx rate of a vf for the link. -// Equivalent to: `ip link set $link vf $vf rate $rate` -func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfTxRate{ - Vf: uint32(vf), - Rate: uint32(rate), - } - info.AddRtAttr(nl.IFLA_VF_TX_RATE, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfRate sets the min and max tx rate of a vf for the link. -// Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate` -func LinkSetVfRate(link Link, vf, minRate, maxRate int) error { - return pkgHandle.LinkSetVfRate(link, vf, minRate, maxRate) -} - -// LinkSetVfRate sets the min and max tx rate of a vf for the link. -// Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate` -func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfRate{ - Vf: uint32(vf), - MinTxRate: uint32(minRate), - MaxTxRate: uint32(maxRate), - } - info.AddRtAttr(nl.IFLA_VF_RATE, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfState enables/disables virtual link state on a vf. -// Equivalent to: `ip link set $link vf $vf state $state` -func LinkSetVfState(link Link, vf int, state uint32) error { - return pkgHandle.LinkSetVfState(link, vf, state) -} - -// LinkSetVfState enables/disables virtual link state on a vf. -// Equivalent to: `ip link set $link vf $vf state $state` -func (h *Handle) LinkSetVfState(link Link, vf int, state uint32) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfLinkState{ - Vf: uint32(vf), - LinkState: state, - } - info.AddRtAttr(nl.IFLA_VF_LINK_STATE, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link. -// Equivalent to: `ip link set $link vf $vf spoofchk $check` -func LinkSetVfSpoofchk(link Link, vf int, check bool) error { - return pkgHandle.LinkSetVfSpoofchk(link, vf, check) -} - -// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link. -// Equivalent to: `ip link set $link vf $vf spoofchk $check` -func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error { - var setting uint32 - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - if check { - setting = 1 - } - vfmsg := nl.VfSpoofchk{ - Vf: uint32(vf), - Setting: setting, - } - info.AddRtAttr(nl.IFLA_VF_SPOOFCHK, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfTrust enables/disables trust state on a vf for the link. -// Equivalent to: `ip link set $link vf $vf trust $state` -func LinkSetVfTrust(link Link, vf int, state bool) error { - return pkgHandle.LinkSetVfTrust(link, vf, state) -} - -// LinkSetVfTrust enables/disables trust state on a vf for the link. -// Equivalent to: `ip link set $link vf $vf trust $state` -func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error { - var setting uint32 - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - if state { - setting = 1 - } - vfmsg := nl.VfTrust{ - Vf: uint32(vf), - Setting: setting, - } - info.AddRtAttr(nl.IFLA_VF_TRUST, vfmsg.Serialize()) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetVfNodeGUID sets the node GUID of a vf for the link. -// Equivalent to: `ip link set dev $link vf $vf node_guid $nodeguid` -func LinkSetVfNodeGUID(link Link, vf int, nodeguid net.HardwareAddr) error { - return pkgHandle.LinkSetVfGUID(link, vf, nodeguid, nl.IFLA_VF_IB_NODE_GUID) -} - -// LinkSetVfPortGUID sets the port GUID of a vf for the link. -// Equivalent to: `ip link set dev $link vf $vf port_guid $portguid` -func LinkSetVfPortGUID(link Link, vf int, portguid net.HardwareAddr) error { - return pkgHandle.LinkSetVfGUID(link, vf, portguid, nl.IFLA_VF_IB_PORT_GUID) -} - -// LinkSetVfGUID sets the node or port GUID of a vf for the link. -func (h *Handle) LinkSetVfGUID(link Link, vf int, vfGuid net.HardwareAddr, guidType int) error { - var err error - var guid uint64 - - buf := bytes.NewBuffer(vfGuid) - err = binary.Read(buf, binary.BigEndian, &guid) - if err != nil { - return err - } - - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) - info := data.AddRtAttr(nl.IFLA_VF_INFO, nil) - vfmsg := nl.VfGUID{ - Vf: uint32(vf), - GUID: guid, - } - info.AddRtAttr(guidType, vfmsg.Serialize()) - req.AddData(data) - - _, err = req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetMaster sets the master of the link device. -// Equivalent to: `ip link set $link master $master` -func LinkSetMaster(link Link, master Link) error { - return pkgHandle.LinkSetMaster(link, master) -} - -// LinkSetMaster sets the master of the link device. -// Equivalent to: `ip link set $link master $master` -func (h *Handle) LinkSetMaster(link Link, master Link) error { - index := 0 - if master != nil { - masterBase := master.Attrs() - h.ensureIndex(masterBase) - index = masterBase.Index - } - if index <= 0 { - return fmt.Errorf("Device does not exist") - } - return h.LinkSetMasterByIndex(link, index) -} - -// LinkSetNoMaster removes the master of the link device. -// Equivalent to: `ip link set $link nomaster` -func LinkSetNoMaster(link Link) error { - return pkgHandle.LinkSetNoMaster(link) -} - -// LinkSetNoMaster removes the master of the link device. -// Equivalent to: `ip link set $link nomaster` -func (h *Handle) LinkSetNoMaster(link Link) error { - return h.LinkSetMasterByIndex(link, 0) -} - -// LinkSetMasterByIndex sets the master of the link device. -// Equivalent to: `ip link set $link master $master` -func LinkSetMasterByIndex(link Link, masterIndex int) error { - return pkgHandle.LinkSetMasterByIndex(link, masterIndex) -} - -// LinkSetMasterByIndex sets the master of the link device. -// Equivalent to: `ip link set $link master $master` -func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(masterIndex)) - - data := nl.NewRtAttr(unix.IFLA_MASTER, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetNsPid puts the device into a new network namespace. The -// pid must be a pid of a running process. -// Equivalent to: `ip link set $link netns $pid` -func LinkSetNsPid(link Link, nspid int) error { - return pkgHandle.LinkSetNsPid(link, nspid) -} - -// LinkSetNsPid puts the device into a new network namespace. The -// pid must be a pid of a running process. -// Equivalent to: `ip link set $link netns $pid` -func (h *Handle) LinkSetNsPid(link Link, nspid int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(nspid)) - - data := nl.NewRtAttr(unix.IFLA_NET_NS_PID, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetNsFd puts the device into a new network namespace. The -// fd must be an open file descriptor to a network namespace. -// Similar to: `ip link set $link netns $ns` -func LinkSetNsFd(link Link, fd int) error { - return pkgHandle.LinkSetNsFd(link, fd) -} - -// LinkSetNsFd puts the device into a new network namespace. The -// fd must be an open file descriptor to a network namespace. -// Similar to: `ip link set $link netns $ns` -func (h *Handle) LinkSetNsFd(link Link, fd int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(fd)) - - data := nl.NewRtAttr(unix.IFLA_NET_NS_FD, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf -// program loaded with bpf(type=BPF_PROG_TYPE_XDP) -func LinkSetXdpFd(link Link, fd int) error { - return LinkSetXdpFdWithFlags(link, fd, 0) -} - -// LinkSetXdpFdWithFlags adds a bpf function to the driver with the given -// options. The fd must be a bpf program loaded with bpf(type=BPF_PROG_TYPE_XDP) -func LinkSetXdpFdWithFlags(link Link, fd, flags int) error { - base := link.Attrs() - ensureIndex(base) - req := nl.NewNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func boolAttr(val bool) []byte { - var v uint8 - if val { - v = 1 - } - return nl.Uint8Attr(v) -} - -type vxlanPortRange struct { - Lo, Hi uint16 -} - -func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if vxlan.FlowBased { - vxlan.VxlanId = 0 - } - - data.AddRtAttr(nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId))) - - if vxlan.VtepDevIndex != 0 { - data.AddRtAttr(nl.IFLA_VXLAN_LINK, nl.Uint32Attr(uint32(vxlan.VtepDevIndex))) - } - if vxlan.SrcAddr != nil { - ip := vxlan.SrcAddr.To4() - if ip != nil { - data.AddRtAttr(nl.IFLA_VXLAN_LOCAL, []byte(ip)) - } else { - ip = vxlan.SrcAddr.To16() - if ip != nil { - data.AddRtAttr(nl.IFLA_VXLAN_LOCAL6, []byte(ip)) - } - } - } - if vxlan.Group != nil { - group := vxlan.Group.To4() - if group != nil { - data.AddRtAttr(nl.IFLA_VXLAN_GROUP, []byte(group)) - } else { - group = vxlan.Group.To16() - if group != nil { - data.AddRtAttr(nl.IFLA_VXLAN_GROUP6, []byte(group)) - } - } - } - - data.AddRtAttr(nl.IFLA_VXLAN_TTL, nl.Uint8Attr(uint8(vxlan.TTL))) - data.AddRtAttr(nl.IFLA_VXLAN_TOS, nl.Uint8Attr(uint8(vxlan.TOS))) - data.AddRtAttr(nl.IFLA_VXLAN_LEARNING, boolAttr(vxlan.Learning)) - data.AddRtAttr(nl.IFLA_VXLAN_PROXY, boolAttr(vxlan.Proxy)) - data.AddRtAttr(nl.IFLA_VXLAN_RSC, boolAttr(vxlan.RSC)) - data.AddRtAttr(nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss)) - data.AddRtAttr(nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss)) - data.AddRtAttr(nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX, boolAttr(vxlan.UDP6ZeroCSumTx)) - data.AddRtAttr(nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX, boolAttr(vxlan.UDP6ZeroCSumRx)) - - if vxlan.UDPCSum { - data.AddRtAttr(nl.IFLA_VXLAN_UDP_CSUM, boolAttr(vxlan.UDPCSum)) - } - if vxlan.GBP { - data.AddRtAttr(nl.IFLA_VXLAN_GBP, []byte{}) - } - if vxlan.FlowBased { - data.AddRtAttr(nl.IFLA_VXLAN_FLOWBASED, boolAttr(vxlan.FlowBased)) - } - if vxlan.NoAge { - data.AddRtAttr(nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0)) - } else if vxlan.Age > 0 { - data.AddRtAttr(nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(uint32(vxlan.Age))) - } - if vxlan.Limit > 0 { - data.AddRtAttr(nl.IFLA_VXLAN_LIMIT, nl.Uint32Attr(uint32(vxlan.Limit))) - } - if vxlan.Port > 0 { - data.AddRtAttr(nl.IFLA_VXLAN_PORT, htons(uint16(vxlan.Port))) - } - if vxlan.PortLow > 0 || vxlan.PortHigh > 0 { - pr := vxlanPortRange{uint16(vxlan.PortLow), uint16(vxlan.PortHigh)} - - buf := new(bytes.Buffer) - binary.Write(buf, binary.BigEndian, &pr) - - data.AddRtAttr(nl.IFLA_VXLAN_PORT_RANGE, buf.Bytes()) - } -} - -func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - if bond.Mode >= 0 { - data.AddRtAttr(nl.IFLA_BOND_MODE, nl.Uint8Attr(uint8(bond.Mode))) - } - if bond.ActiveSlave >= 0 { - data.AddRtAttr(nl.IFLA_BOND_ACTIVE_SLAVE, nl.Uint32Attr(uint32(bond.ActiveSlave))) - } - if bond.Miimon >= 0 { - data.AddRtAttr(nl.IFLA_BOND_MIIMON, nl.Uint32Attr(uint32(bond.Miimon))) - } - if bond.UpDelay >= 0 { - data.AddRtAttr(nl.IFLA_BOND_UPDELAY, nl.Uint32Attr(uint32(bond.UpDelay))) - } - if bond.DownDelay >= 0 { - data.AddRtAttr(nl.IFLA_BOND_DOWNDELAY, nl.Uint32Attr(uint32(bond.DownDelay))) - } - if bond.UseCarrier >= 0 { - data.AddRtAttr(nl.IFLA_BOND_USE_CARRIER, nl.Uint8Attr(uint8(bond.UseCarrier))) - } - if bond.ArpInterval >= 0 { - data.AddRtAttr(nl.IFLA_BOND_ARP_INTERVAL, nl.Uint32Attr(uint32(bond.ArpInterval))) - } - if bond.ArpIpTargets != nil { - msg := data.AddRtAttr(nl.IFLA_BOND_ARP_IP_TARGET, nil) - for i := range bond.ArpIpTargets { - ip := bond.ArpIpTargets[i].To4() - if ip != nil { - msg.AddRtAttr(i, []byte(ip)) - continue - } - ip = bond.ArpIpTargets[i].To16() - if ip != nil { - msg.AddRtAttr(i, []byte(ip)) - } - } - } - if bond.ArpValidate >= 0 { - data.AddRtAttr(nl.IFLA_BOND_ARP_VALIDATE, nl.Uint32Attr(uint32(bond.ArpValidate))) - } - if bond.ArpAllTargets >= 0 { - data.AddRtAttr(nl.IFLA_BOND_ARP_ALL_TARGETS, nl.Uint32Attr(uint32(bond.ArpAllTargets))) - } - if bond.Primary >= 0 { - data.AddRtAttr(nl.IFLA_BOND_PRIMARY, nl.Uint32Attr(uint32(bond.Primary))) - } - if bond.PrimaryReselect >= 0 { - data.AddRtAttr(nl.IFLA_BOND_PRIMARY_RESELECT, nl.Uint8Attr(uint8(bond.PrimaryReselect))) - } - if bond.FailOverMac >= 0 { - data.AddRtAttr(nl.IFLA_BOND_FAIL_OVER_MAC, nl.Uint8Attr(uint8(bond.FailOverMac))) - } - if bond.XmitHashPolicy >= 0 { - data.AddRtAttr(nl.IFLA_BOND_XMIT_HASH_POLICY, nl.Uint8Attr(uint8(bond.XmitHashPolicy))) - } - if bond.ResendIgmp >= 0 { - data.AddRtAttr(nl.IFLA_BOND_RESEND_IGMP, nl.Uint32Attr(uint32(bond.ResendIgmp))) - } - if bond.NumPeerNotif >= 0 { - data.AddRtAttr(nl.IFLA_BOND_NUM_PEER_NOTIF, nl.Uint8Attr(uint8(bond.NumPeerNotif))) - } - if bond.AllSlavesActive >= 0 { - data.AddRtAttr(nl.IFLA_BOND_ALL_SLAVES_ACTIVE, nl.Uint8Attr(uint8(bond.AllSlavesActive))) - } - if bond.MinLinks >= 0 { - data.AddRtAttr(nl.IFLA_BOND_MIN_LINKS, nl.Uint32Attr(uint32(bond.MinLinks))) - } - if bond.LpInterval >= 0 { - data.AddRtAttr(nl.IFLA_BOND_LP_INTERVAL, nl.Uint32Attr(uint32(bond.LpInterval))) - } - if bond.PacketsPerSlave >= 0 { - data.AddRtAttr(nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PacketsPerSlave))) - } - if bond.LacpRate >= 0 { - data.AddRtAttr(nl.IFLA_BOND_AD_LACP_RATE, nl.Uint8Attr(uint8(bond.LacpRate))) - } - if bond.AdSelect >= 0 { - data.AddRtAttr(nl.IFLA_BOND_AD_SELECT, nl.Uint8Attr(uint8(bond.AdSelect))) - } - if bond.AdActorSysPrio >= 0 { - data.AddRtAttr(nl.IFLA_BOND_AD_ACTOR_SYS_PRIO, nl.Uint16Attr(uint16(bond.AdActorSysPrio))) - } - if bond.AdUserPortKey >= 0 { - data.AddRtAttr(nl.IFLA_BOND_AD_USER_PORT_KEY, nl.Uint16Attr(uint16(bond.AdUserPortKey))) - } - if bond.AdActorSystem != nil { - data.AddRtAttr(nl.IFLA_BOND_AD_ACTOR_SYSTEM, []byte(bond.AdActorSystem)) - } - if bond.TlbDynamicLb >= 0 { - data.AddRtAttr(nl.IFLA_BOND_TLB_DYNAMIC_LB, nl.Uint8Attr(uint8(bond.TlbDynamicLb))) - } -} - -func cleanupFds(fds []*os.File) { - for _, f := range fds { - f.Close() - } -} - -// LinkAdd adds a new link device. The type and features of the device -// are taken from the parameters in the link object. -// Equivalent to: `ip link add $link` -func LinkAdd(link Link) error { - return pkgHandle.LinkAdd(link) -} - -// LinkAdd adds a new link device. The type and features of the device -// are taken from the parameters in the link object. -// Equivalent to: `ip link add $link` -func (h *Handle) LinkAdd(link Link) error { - return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) -} - -func (h *Handle) LinkModify(link Link) error { - return h.linkModify(link, unix.NLM_F_REQUEST|unix.NLM_F_ACK) -} - -func (h *Handle) linkModify(link Link, flags int) error { - // TODO: support extra data for macvlan - base := link.Attrs() - - // if tuntap, then the name can be empty, OS will provide a name - tuntap, isTuntap := link.(*Tuntap) - - if base.Name == "" && !isTuntap { - return fmt.Errorf("LinkAttrs.Name cannot be empty") - } - - if isTuntap { - if tuntap.Mode < unix.IFF_TUN || tuntap.Mode > unix.IFF_TAP { - return fmt.Errorf("Tuntap.Mode %v unknown", tuntap.Mode) - } - - queues := tuntap.Queues - - var fds []*os.File - var req ifReq - copy(req.Name[:15], base.Name) - - req.Flags = uint16(tuntap.Flags) - - if queues == 0 { //Legacy compatibility - queues = 1 - if tuntap.Flags == 0 { - req.Flags = uint16(TUNTAP_DEFAULTS) - } - } else { - // For best peformance set Flags to TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR - // when a) KVM has support for this ABI and - // b) the value of the flag is queryable using the TUNGETIFF ioctl - if tuntap.Flags == 0 { - req.Flags = uint16(TUNTAP_MULTI_QUEUE_DEFAULTS) - } - } - - req.Flags |= uint16(tuntap.Mode) - const TUN = "/dev/net/tun" - for i := 0; i < queues; i++ { - localReq := req - fd, err := unix.Open(TUN, os.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - cleanupFds(fds) - return err - } - - _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&localReq))) - if errno != 0 { - // close the new fd - unix.Close(fd) - // and the already opened ones - cleanupFds(fds) - return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed [%d], errno %v", i, errno) - } - - _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETOWNER, uintptr(tuntap.Owner)) - if errno != 0 { - cleanupFds(fds) - return fmt.Errorf("Tuntap IOCTL TUNSETOWNER failed [%d], errno %v", i, errno) - } - - _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETGROUP, uintptr(tuntap.Group)) - if errno != 0 { - cleanupFds(fds) - return fmt.Errorf("Tuntap IOCTL TUNSETGROUP failed [%d], errno %v", i, errno) - } - - // Set the tun device to non-blocking before use. The below comment - // taken from: - // - // https://github.com/mistsys/tuntap/commit/161418c25003bbee77d085a34af64d189df62bea - // - // Note there is a complication because in go, if a device node is - // opened, go sets it to use nonblocking I/O. However a /dev/net/tun - // doesn't work with epoll until after the TUNSETIFF ioctl has been - // done. So we open the unix fd directly, do the ioctl, then put the - // fd in nonblocking mode, an then finally wrap it in a os.File, - // which will see the nonblocking mode and add the fd to the - // pollable set, so later on when we Read() from it blocked the - // calling thread in the kernel. - // - // See - // https://github.com/golang/go/issues/30426 - // which got exposed in go 1.13 by the fix to - // https://github.com/golang/go/issues/30624 - err = unix.SetNonblock(fd, true) - if err != nil { - cleanupFds(fds) - return fmt.Errorf("Tuntap set to non-blocking failed [%d], err %v", i, err) - } - - // create the file from the file descriptor and store it - file := os.NewFile(uintptr(fd), TUN) - fds = append(fds, file) - - // 1) we only care for the name of the first tap in the multi queue set - // 2) if the original name was empty, the localReq has now the actual name - // - // In addition: - // This ensures that the link name is always identical to what the kernel returns. - // Not only in case of an empty name, but also when using name templates. - // e.g. when the provided name is "tap%d", the kernel replaces %d with the next available number. - if i == 0 { - link.Attrs().Name = strings.Trim(string(localReq.Name[:]), "\x00") - } - - } - - control := func(file *os.File, f func(fd uintptr)) error { - name := file.Name() - conn, err := file.SyscallConn() - if err != nil { - return fmt.Errorf("SyscallConn() failed on %s: %v", name, err) - } - if err := conn.Control(f); err != nil { - return fmt.Errorf("Failed to get file descriptor for %s: %v", name, err) - } - return nil - } - - // only persist interface if NonPersist is NOT set - if !tuntap.NonPersist { - var errno syscall.Errno - if err := control(fds[0], func(fd uintptr) { - _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 1) - }); err != nil { - return err - } - if errno != 0 { - cleanupFds(fds) - return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno) - } - } - - h.ensureIndex(base) - - // can't set master during create, so set it afterwards - if base.MasterIndex != 0 { - // TODO: verify MasterIndex is actually a bridge? - err := h.LinkSetMasterByIndex(link, base.MasterIndex) - if err != nil { - // un-persist (e.g. allow the interface to be removed) the tuntap - // should not hurt if not set prior, condition might be not needed - if !tuntap.NonPersist { - // ignore error - _ = control(fds[0], func(fd uintptr) { - _, _, _ = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 0) - }) - } - cleanupFds(fds) - return err - } - } - - if tuntap.Queues == 0 { - cleanupFds(fds) - } else { - tuntap.Fds = fds - } - - return nil - } - - req := h.newNetlinkRequest(unix.RTM_NEWLINK, flags) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - // TODO: make it shorter - if base.Flags&net.FlagUp != 0 { - msg.Change = unix.IFF_UP - msg.Flags = unix.IFF_UP - } - if base.Flags&net.FlagBroadcast != 0 { - msg.Change |= unix.IFF_BROADCAST - msg.Flags |= unix.IFF_BROADCAST - } - if base.Flags&net.FlagLoopback != 0 { - msg.Change |= unix.IFF_LOOPBACK - msg.Flags |= unix.IFF_LOOPBACK - } - if base.Flags&net.FlagPointToPoint != 0 { - msg.Change |= unix.IFF_POINTOPOINT - msg.Flags |= unix.IFF_POINTOPOINT - } - if base.Flags&net.FlagMulticast != 0 { - msg.Change |= unix.IFF_MULTICAST - msg.Flags |= unix.IFF_MULTICAST - } - if base.Index != 0 { - msg.Index = int32(base.Index) - } - - req.AddData(msg) - - if base.ParentIndex != 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(base.ParentIndex)) - data := nl.NewRtAttr(unix.IFLA_LINK, b) - req.AddData(data) - } else if link.Type() == "ipvlan" || link.Type() == "ipoib" { - return fmt.Errorf("Can't create %s link without ParentIndex", link.Type()) - } - - nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name)) - req.AddData(nameData) - - if base.Alias != "" { - alias := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(base.Alias)) - req.AddData(alias) - } - - if base.MTU > 0 { - mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) - req.AddData(mtu) - } - - if base.TxQLen >= 0 { - qlen := nl.NewRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) - req.AddData(qlen) - } - - if base.HardwareAddr != nil { - hwaddr := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(base.HardwareAddr)) - req.AddData(hwaddr) - } - - if base.NumTxQueues > 0 { - txqueues := nl.NewRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues))) - req.AddData(txqueues) - } - - if base.NumRxQueues > 0 { - rxqueues := nl.NewRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues))) - req.AddData(rxqueues) - } - - if base.GSOMaxSegs > 0 { - gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SEGS, nl.Uint32Attr(base.GSOMaxSegs)) - req.AddData(gsoAttr) - } - - if base.GSOMaxSize > 0 { - gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, nl.Uint32Attr(base.GSOMaxSize)) - req.AddData(gsoAttr) - } - - if base.Group > 0 { - groupAttr := nl.NewRtAttr(unix.IFLA_GROUP, nl.Uint32Attr(base.Group)) - req.AddData(groupAttr) - } - - if base.Namespace != nil { - var attr *nl.RtAttr - switch ns := base.Namespace.(type) { - case NsPid: - val := nl.Uint32Attr(uint32(ns)) - attr = nl.NewRtAttr(unix.IFLA_NET_NS_PID, val) - case NsFd: - val := nl.Uint32Attr(uint32(ns)) - attr = nl.NewRtAttr(unix.IFLA_NET_NS_FD, val) - } - - req.AddData(attr) - } - - if base.Xdp != nil { - addXdpAttrs(base.Xdp, req) - } - - linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) - linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) - - switch link := link.(type) { - case *Vlan: - b := make([]byte, 2) - native.PutUint16(b, uint16(link.VlanId)) - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_VLAN_ID, b) - - if link.VlanProtocol != VLAN_PROTOCOL_UNKNOWN { - data.AddRtAttr(nl.IFLA_VLAN_PROTOCOL, htons(uint16(link.VlanProtocol))) - } - case *Veth: - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - peer := data.AddRtAttr(nl.VETH_INFO_PEER, nil) - nl.NewIfInfomsgChild(peer, unix.AF_UNSPEC) - peer.AddRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName)) - if base.TxQLen >= 0 { - peer.AddRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) - } - if base.NumTxQueues > 0 { - peer.AddRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues))) - } - if base.NumRxQueues > 0 { - peer.AddRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues))) - } - if base.MTU > 0 { - peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) - } - if link.PeerHardwareAddr != nil { - peer.AddRtAttr(unix.IFLA_ADDRESS, []byte(link.PeerHardwareAddr)) - } - if link.PeerNamespace != nil { - switch ns := link.PeerNamespace.(type) { - case NsPid: - val := nl.Uint32Attr(uint32(ns)) - peer.AddRtAttr(unix.IFLA_NET_NS_PID, val) - case NsFd: - val := nl.Uint32Attr(uint32(ns)) - peer.AddRtAttr(unix.IFLA_NET_NS_FD, val) - } - } - case *Vxlan: - addVxlanAttrs(link, linkInfo) - case *Bond: - addBondAttrs(link, linkInfo) - case *IPVlan: - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode))) - data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag))) - case *IPVtap: - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode))) - data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag))) - case *Macvlan: - if link.Mode != MACVLAN_MODE_DEFAULT { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode])) - } - case *Macvtap: - if link.Mode != MACVLAN_MODE_DEFAULT { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode])) - } - case *Geneve: - addGeneveAttrs(link, linkInfo) - case *Gretap: - addGretapAttrs(link, linkInfo) - case *Iptun: - addIptunAttrs(link, linkInfo) - case *Ip6tnl: - addIp6tnlAttrs(link, linkInfo) - case *Sittun: - addSittunAttrs(link, linkInfo) - case *Gretun: - addGretunAttrs(link, linkInfo) - case *Vti: - addVtiAttrs(link, linkInfo) - case *Vrf: - addVrfAttrs(link, linkInfo) - case *Bridge: - addBridgeAttrs(link, linkInfo) - case *GTP: - addGTPAttrs(link, linkInfo) - case *Xfrmi: - addXfrmiAttrs(link, linkInfo) - case *IPoIB: - addIPoIBAttrs(link, linkInfo) - case *BareUDP: - addBareUDPAttrs(link, linkInfo) - } - - req.AddData(linkInfo) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - if err != nil { - return err - } - - h.ensureIndex(base) - - // can't set master during create, so set it afterwards - if base.MasterIndex != 0 { - // TODO: verify MasterIndex is actually a bridge? - return h.LinkSetMasterByIndex(link, base.MasterIndex) - } - return nil -} - -// LinkDel deletes link device. Either Index or Name must be set in -// the link object for it to be deleted. The other values are ignored. -// Equivalent to: `ip link del $link` -func LinkDel(link Link) error { - return pkgHandle.LinkDel(link) -} - -// LinkDel deletes link device. Either Index or Name must be set in -// the link object for it to be deleted. The other values are ignored. -// Equivalent to: `ip link del $link` -func (h *Handle) LinkDel(link Link) error { - base := link.Attrs() - - h.ensureIndex(base) - - req := h.newNetlinkRequest(unix.RTM_DELLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func (h *Handle) linkByNameDump(name string) (Link, error) { - links, err := h.LinkList() - if err != nil { - return nil, err - } - - for _, link := range links { - if link.Attrs().Name == name { - return link, nil - } - } - return nil, LinkNotFoundError{fmt.Errorf("Link %s not found", name)} -} - -func (h *Handle) linkByAliasDump(alias string) (Link, error) { - links, err := h.LinkList() - if err != nil { - return nil, err - } - - for _, link := range links { - if link.Attrs().Alias == alias { - return link, nil - } - } - return nil, LinkNotFoundError{fmt.Errorf("Link alias %s not found", alias)} -} - -// LinkByName finds a link by name and returns a pointer to the object. -func LinkByName(name string) (Link, error) { - return pkgHandle.LinkByName(name) -} - -// LinkByName finds a link by name and returns a pointer to the object. -func (h *Handle) LinkByName(name string) (Link, error) { - if h.lookupByDump { - return h.linkByNameDump(name) - } - - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(msg) - - attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF)) - req.AddData(attr) - - nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name)) - req.AddData(nameData) - - link, err := execGetLink(req) - if err == unix.EINVAL { - // older kernels don't support looking up via IFLA_IFNAME - // so fall back to dumping all links - h.lookupByDump = true - return h.linkByNameDump(name) - } - - return link, err -} - -// LinkByAlias finds a link by its alias and returns a pointer to the object. -// If there are multiple links with the alias it returns the first one -func LinkByAlias(alias string) (Link, error) { - return pkgHandle.LinkByAlias(alias) -} - -// LinkByAlias finds a link by its alias and returns a pointer to the object. -// If there are multiple links with the alias it returns the first one -func (h *Handle) LinkByAlias(alias string) (Link, error) { - if h.lookupByDump { - return h.linkByAliasDump(alias) - } - - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(msg) - - attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF)) - req.AddData(attr) - - nameData := nl.NewRtAttr(unix.IFLA_IFALIAS, nl.ZeroTerminated(alias)) - req.AddData(nameData) - - link, err := execGetLink(req) - if err == unix.EINVAL { - // older kernels don't support looking up via IFLA_IFALIAS - // so fall back to dumping all links - h.lookupByDump = true - return h.linkByAliasDump(alias) - } - - return link, err -} - -// LinkByIndex finds a link by index and returns a pointer to the object. -func LinkByIndex(index int) (Link, error) { - return pkgHandle.LinkByIndex(index) -} - -// LinkByIndex finds a link by index and returns a pointer to the object. -func (h *Handle) LinkByIndex(index int) (Link, error) { - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(index) - req.AddData(msg) - attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF)) - req.AddData(attr) - - return execGetLink(req) -} - -func execGetLink(req *nl.NetlinkRequest) (Link, error) { - msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) - if err != nil { - if errno, ok := err.(syscall.Errno); ok { - if errno == unix.ENODEV { - return nil, LinkNotFoundError{fmt.Errorf("Link not found")} - } - } - return nil, err - } - - switch { - case len(msgs) == 0: - return nil, LinkNotFoundError{fmt.Errorf("Link not found")} - - case len(msgs) == 1: - return LinkDeserialize(nil, msgs[0]) - - default: - return nil, fmt.Errorf("More than one link found") - } -} - -// LinkDeserialize deserializes a raw message received from netlink into -// a link object. -func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) { - msg := nl.DeserializeIfInfomsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - base := NewLinkAttrs() - base.Index = int(msg.Index) - base.RawFlags = msg.Flags - base.Flags = linkFlags(msg.Flags) - base.EncapType = msg.EncapType() - base.NetNsID = -1 - if msg.Flags&unix.IFF_PROMISC != 0 { - base.Promisc = 1 - } - if msg.Flags&unix.IFF_ALLMULTI != 0 { - base.Allmulti = 1 - } - if msg.Flags&unix.IFF_MULTICAST != 0 { - base.Multi = 1 - } - - var ( - link Link - stats32 *LinkStatistics32 - stats64 *LinkStatistics64 - linkType string - linkSlave LinkSlave - slaveType string - ) - for _, attr := range attrs { - switch attr.Attr.Type { - case unix.IFLA_LINKINFO: - infos, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - for _, info := range infos { - switch info.Attr.Type { - case nl.IFLA_INFO_KIND: - linkType = string(info.Value[:len(info.Value)-1]) - switch linkType { - case "dummy": - link = &Dummy{} - case "ifb": - link = &Ifb{} - case "bridge": - link = &Bridge{} - case "vlan": - link = &Vlan{} - case "veth": - link = &Veth{} - case "wireguard": - link = &Wireguard{} - case "vxlan": - link = &Vxlan{} - case "bond": - link = &Bond{} - case "ipvlan": - link = &IPVlan{} - case "ipvtap": - link = &IPVtap{} - case "macvlan": - link = &Macvlan{} - case "macvtap": - link = &Macvtap{} - case "geneve": - link = &Geneve{} - case "gretap": - link = &Gretap{} - case "ip6gretap": - link = &Gretap{} - case "ipip": - link = &Iptun{} - case "ip6tnl": - link = &Ip6tnl{} - case "sit": - link = &Sittun{} - case "gre": - link = &Gretun{} - case "ip6gre": - link = &Gretun{} - case "vti", "vti6": - link = &Vti{} - case "vrf": - link = &Vrf{} - case "gtp": - link = >P{} - case "xfrm": - link = &Xfrmi{} - case "tun": - link = &Tuntap{} - case "ipoib": - link = &IPoIB{} - case "can": - link = &Can{} - case "bareudp": - link = &BareUDP{} - default: - link = &GenericLink{LinkType: linkType} - } - case nl.IFLA_INFO_DATA: - data, err := nl.ParseRouteAttr(info.Value) - if err != nil { - return nil, err - } - switch linkType { - case "vlan": - parseVlanData(link, data) - case "vxlan": - parseVxlanData(link, data) - case "bond": - parseBondData(link, data) - case "ipvlan": - parseIPVlanData(link, data) - case "ipvtap": - parseIPVtapData(link, data) - case "macvlan": - parseMacvlanData(link, data) - case "macvtap": - parseMacvtapData(link, data) - case "geneve": - parseGeneveData(link, data) - case "gretap": - parseGretapData(link, data) - case "ip6gretap": - parseGretapData(link, data) - case "ipip": - parseIptunData(link, data) - case "ip6tnl": - parseIp6tnlData(link, data) - case "sit": - parseSittunData(link, data) - case "gre": - parseGretunData(link, data) - case "ip6gre": - parseGretunData(link, data) - case "vti", "vti6": - parseVtiData(link, data) - case "vrf": - parseVrfData(link, data) - case "bridge": - parseBridgeData(link, data) - case "gtp": - parseGTPData(link, data) - case "xfrm": - parseXfrmiData(link, data) - case "tun": - parseTuntapData(link, data) - case "ipoib": - parseIPoIBData(link, data) - case "can": - parseCanData(link, data) - case "bareudp": - parseBareUDPData(link, data) - } - - case nl.IFLA_INFO_SLAVE_KIND: - slaveType = string(info.Value[:len(info.Value)-1]) - switch slaveType { - case "bond": - linkSlave = &BondSlave{} - case "vrf": - linkSlave = &VrfSlave{} - } - - case nl.IFLA_INFO_SLAVE_DATA: - switch slaveType { - case "bond": - data, err := nl.ParseRouteAttr(info.Value) - if err != nil { - return nil, err - } - parseBondSlaveData(linkSlave, data) - case "vrf": - data, err := nl.ParseRouteAttr(info.Value) - if err != nil { - return nil, err - } - parseVrfSlaveData(linkSlave, data) - } - } - } - case unix.IFLA_ADDRESS: - var nonzero bool - for _, b := range attr.Value { - if b != 0 { - nonzero = true - } - } - if nonzero { - base.HardwareAddr = attr.Value[:] - } - case unix.IFLA_IFNAME: - base.Name = string(attr.Value[:len(attr.Value)-1]) - case unix.IFLA_MTU: - base.MTU = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_LINK: - base.ParentIndex = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_MASTER: - base.MasterIndex = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_TXQLEN: - base.TxQLen = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_IFALIAS: - base.Alias = string(attr.Value[:len(attr.Value)-1]) - case unix.IFLA_STATS: - stats32 = new(LinkStatistics32) - if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats32); err != nil { - return nil, err - } - case unix.IFLA_STATS64: - stats64 = new(LinkStatistics64) - if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats64); err != nil { - return nil, err - } - case unix.IFLA_XDP: - xdp, err := parseLinkXdp(attr.Value[:]) - if err != nil { - return nil, err - } - base.Xdp = xdp - case unix.IFLA_PROTINFO | unix.NLA_F_NESTED: - if hdr != nil && hdr.Type == unix.RTM_NEWLINK && - msg.Family == unix.AF_BRIDGE { - attrs, err := nl.ParseRouteAttr(attr.Value[:]) - if err != nil { - return nil, err - } - protinfo := parseProtinfo(attrs) - base.Protinfo = &protinfo - } - case unix.IFLA_OPERSTATE: - base.OperState = LinkOperState(uint8(attr.Value[0])) - case unix.IFLA_PHYS_SWITCH_ID: - base.PhysSwitchID = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_LINK_NETNSID: - base.NetNsID = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_GSO_MAX_SIZE: - base.GSOMaxSize = native.Uint32(attr.Value[0:4]) - case unix.IFLA_GSO_MAX_SEGS: - base.GSOMaxSegs = native.Uint32(attr.Value[0:4]) - case unix.IFLA_VFINFO_LIST: - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - vfs, err := parseVfInfoList(data) - if err != nil { - return nil, err - } - base.Vfs = vfs - case unix.IFLA_NUM_TX_QUEUES: - base.NumTxQueues = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_NUM_RX_QUEUES: - base.NumRxQueues = int(native.Uint32(attr.Value[0:4])) - case unix.IFLA_GROUP: - base.Group = native.Uint32(attr.Value[0:4]) - } - } - - if stats64 != nil { - base.Statistics = (*LinkStatistics)(stats64) - } else if stats32 != nil { - base.Statistics = (*LinkStatistics)(stats32.to64()) - } - - // Links that don't have IFLA_INFO_KIND are hardware devices - if link == nil { - link = &Device{} - } - *link.Attrs() = base - link.Attrs().Slave = linkSlave - - // If the tuntap attributes are not updated by netlink due to - // an older driver, use sysfs - if link != nil && linkType == "tun" { - tuntap := link.(*Tuntap) - - if tuntap.Mode == 0 { - ifname := tuntap.Attrs().Name - if flags, err := readSysPropAsInt64(ifname, "tun_flags"); err == nil { - - if flags&unix.IFF_TUN != 0 { - tuntap.Mode = unix.IFF_TUN - } else if flags&unix.IFF_TAP != 0 { - tuntap.Mode = unix.IFF_TAP - } - - tuntap.NonPersist = false - if flags&unix.IFF_PERSIST == 0 { - tuntap.NonPersist = true - } - } - - // The sysfs interface for owner/group returns -1 for root user, instead of returning 0. - // So explicitly check for negative value, before assigning the owner uid/gid. - if owner, err := readSysPropAsInt64(ifname, "owner"); err == nil && owner > 0 { - tuntap.Owner = uint32(owner) - } - - if group, err := readSysPropAsInt64(ifname, "group"); err == nil && group > 0 { - tuntap.Group = uint32(group) - } - } - } - - return link, nil -} - -func readSysPropAsInt64(ifname, prop string) (int64, error) { - fname := fmt.Sprintf("/sys/class/net/%s/%s", ifname, prop) - contents, err := ioutil.ReadFile(fname) - if err != nil { - return 0, err - } - - num, err := strconv.ParseInt(strings.TrimSpace(string(contents)), 0, 64) - if err == nil { - return num, nil - } - - return 0, err -} - -// LinkList gets a list of link devices. -// Equivalent to: `ip link show` -func LinkList() ([]Link, error) { - return pkgHandle.LinkList() -} - -// LinkList gets a list of link devices. -// Equivalent to: `ip link show` -func (h *Handle) LinkList() ([]Link, error) { - // NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need - // to get the message ourselves to parse link type. - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(msg) - attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF)) - req.AddData(attr) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) - if err != nil { - return nil, err - } - - var res []Link - for _, m := range msgs { - link, err := LinkDeserialize(nil, m) - if err != nil { - return nil, err - } - res = append(res, link) - } - - return res, nil -} - -// LinkUpdate is used to pass information back from LinkSubscribe() -type LinkUpdate struct { - nl.IfInfomsg - Header unix.NlMsghdr - Link -} - -// LinkSubscribe takes a chan down which notifications will be sent -// when links change. Close the 'done' chan to stop subscription. -func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error { - return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) -} - -// LinkSubscribeAt works like LinkSubscribe plus it allows the caller -// to choose the network namespace in which to subscribe (ns). -func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error { - return linkSubscribeAt(ns, netns.None(), ch, done, nil, false) -} - -// LinkSubscribeOptions contains a set of options to use with -// LinkSubscribeWithOptions. -type LinkSubscribeOptions struct { - Namespace *netns.NsHandle - ErrorCallback func(error) - ListExisting bool -} - -// LinkSubscribeWithOptions work like LinkSubscribe but enable to -// provide additional options to modify the behavior. Currently, the -// namespace can be provided as well as an error callback. -func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, options LinkSubscribeOptions) error { - if options.Namespace == nil { - none := netns.None() - options.Namespace = &none - } - return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) -} - -func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { - s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_LINK) - if err != nil { - return err - } - if done != nil { - go func() { - <-done - s.Close() - }() - } - if listExisting { - req := pkgHandle.newNetlinkRequest(unix.RTM_GETLINK, - unix.NLM_F_DUMP) - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(msg) - if err := s.Send(req); err != nil { - return err - } - } - go func() { - defer close(ch) - for { - msgs, from, err := s.Receive() - if err != nil { - if cberr != nil { - cberr(fmt.Errorf("Receive failed: %v", - err)) - } - return - } - if from.Pid != nl.PidKernel { - if cberr != nil { - cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)) - } - continue - } - for _, m := range msgs { - if m.Header.Type == unix.NLMSG_DONE { - continue - } - if m.Header.Type == unix.NLMSG_ERROR { - error := int32(native.Uint32(m.Data[0:4])) - if error == 0 { - continue - } - if cberr != nil { - cberr(fmt.Errorf("error message: %v", - syscall.Errno(-error))) - } - continue - } - ifmsg := nl.DeserializeIfInfomsg(m.Data) - header := unix.NlMsghdr(m.Header) - link, err := LinkDeserialize(&header, m.Data) - if err != nil { - if cberr != nil { - cberr(err) - } - continue - } - ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: header, Link: link} - } - } - }() - - return nil -} - -func LinkSetHairpin(link Link, mode bool) error { - return pkgHandle.LinkSetHairpin(link, mode) -} - -func (h *Handle) LinkSetHairpin(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE) -} - -func LinkSetGuard(link Link, mode bool) error { - return pkgHandle.LinkSetGuard(link, mode) -} - -func (h *Handle) LinkSetGuard(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD) -} - -func LinkSetFastLeave(link Link, mode bool) error { - return pkgHandle.LinkSetFastLeave(link, mode) -} - -func (h *Handle) LinkSetFastLeave(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_FAST_LEAVE) -} - -func LinkSetLearning(link Link, mode bool) error { - return pkgHandle.LinkSetLearning(link, mode) -} - -func (h *Handle) LinkSetLearning(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING) -} - -func LinkSetRootBlock(link Link, mode bool) error { - return pkgHandle.LinkSetRootBlock(link, mode) -} - -func (h *Handle) LinkSetRootBlock(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROTECT) -} - -func LinkSetFlood(link Link, mode bool) error { - return pkgHandle.LinkSetFlood(link, mode) -} - -func (h *Handle) LinkSetFlood(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD) -} - -func LinkSetBrProxyArp(link Link, mode bool) error { - return pkgHandle.LinkSetBrProxyArp(link, mode) -} - -func (h *Handle) LinkSetBrProxyArp(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP) -} - -func LinkSetBrProxyArpWiFi(link Link, mode bool) error { - return pkgHandle.LinkSetBrProxyArpWiFi(link, mode) -} - -func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error { - return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI) -} - -func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_BRIDGE) - msg.Index = int32(base.Index) - req.AddData(msg) - - br := nl.NewRtAttr(unix.IFLA_PROTINFO|unix.NLA_F_NESTED, nil) - br.AddRtAttr(attr, boolToByte(mode)) - req.AddData(br) - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - if err != nil { - return err - } - return nil -} - -// LinkSetTxQLen sets the transaction queue length for the link. -// Equivalent to: `ip link set $link txqlen $qlen` -func LinkSetTxQLen(link Link, qlen int) error { - return pkgHandle.LinkSetTxQLen(link, qlen) -} - -// LinkSetTxQLen sets the transaction queue length for the link. -// Equivalent to: `ip link set $link txqlen $qlen` -func (h *Handle) LinkSetTxQLen(link Link, qlen int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(qlen)) - - data := nl.NewRtAttr(unix.IFLA_TXQLEN, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetGroup sets the link group id which can be used to perform mass actions -// with iproute2 as well use it as a reference in nft filters. -// Equivalent to: `ip link set $link group $id` -func LinkSetGroup(link Link, group int) error { - return pkgHandle.LinkSetGroup(link, group) -} - -// LinkSetGroup sets the link group id which can be used to perform mass actions -// with iproute2 as well use it as a reference in nft filters. -// Equivalent to: `ip link set $link group $id` -func (h *Handle) LinkSetGroup(link Link, group int) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - b := make([]byte, 4) - native.PutUint32(b, uint32(group)) - - data := nl.NewRtAttr(unix.IFLA_GROUP, b) - req.AddData(data) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) { - vlan := link.(*Vlan) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_VLAN_ID: - vlan.VlanId = int(native.Uint16(datum.Value[0:2])) - case nl.IFLA_VLAN_PROTOCOL: - vlan.VlanProtocol = VlanProtocol(int(ntohs(datum.Value[0:2]))) - } - } -} - -func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) { - vxlan := link.(*Vxlan) - for _, datum := range data { - // NOTE(vish): Apparently some messages can be sent with no value. - // We special case GBP here to not change existing - // functionality. It appears that GBP sends a datum.Value - // of null. - if len(datum.Value) == 0 && datum.Attr.Type != nl.IFLA_VXLAN_GBP { - continue - } - switch datum.Attr.Type { - case nl.IFLA_VXLAN_ID: - vxlan.VxlanId = int(native.Uint32(datum.Value[0:4])) - case nl.IFLA_VXLAN_LINK: - vxlan.VtepDevIndex = int(native.Uint32(datum.Value[0:4])) - case nl.IFLA_VXLAN_LOCAL: - vxlan.SrcAddr = net.IP(datum.Value[0:4]) - case nl.IFLA_VXLAN_LOCAL6: - vxlan.SrcAddr = net.IP(datum.Value[0:16]) - case nl.IFLA_VXLAN_GROUP: - vxlan.Group = net.IP(datum.Value[0:4]) - case nl.IFLA_VXLAN_GROUP6: - vxlan.Group = net.IP(datum.Value[0:16]) - case nl.IFLA_VXLAN_TTL: - vxlan.TTL = int(datum.Value[0]) - case nl.IFLA_VXLAN_TOS: - vxlan.TOS = int(datum.Value[0]) - case nl.IFLA_VXLAN_LEARNING: - vxlan.Learning = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_PROXY: - vxlan.Proxy = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_RSC: - vxlan.RSC = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_L2MISS: - vxlan.L2miss = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_L3MISS: - vxlan.L3miss = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_UDP_CSUM: - vxlan.UDPCSum = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX: - vxlan.UDP6ZeroCSumTx = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX: - vxlan.UDP6ZeroCSumRx = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_GBP: - vxlan.GBP = true - case nl.IFLA_VXLAN_FLOWBASED: - vxlan.FlowBased = int8(datum.Value[0]) != 0 - case nl.IFLA_VXLAN_AGEING: - vxlan.Age = int(native.Uint32(datum.Value[0:4])) - vxlan.NoAge = vxlan.Age == 0 - case nl.IFLA_VXLAN_LIMIT: - vxlan.Limit = int(native.Uint32(datum.Value[0:4])) - case nl.IFLA_VXLAN_PORT: - vxlan.Port = int(ntohs(datum.Value[0:2])) - case nl.IFLA_VXLAN_PORT_RANGE: - buf := bytes.NewBuffer(datum.Value[0:4]) - var pr vxlanPortRange - if binary.Read(buf, binary.BigEndian, &pr) != nil { - vxlan.PortLow = int(pr.Lo) - vxlan.PortHigh = int(pr.Hi) - } - } - } -} - -func parseBondData(link Link, data []syscall.NetlinkRouteAttr) { - bond := link.(*Bond) - for i := range data { - switch data[i].Attr.Type { - case nl.IFLA_BOND_MODE: - bond.Mode = BondMode(data[i].Value[0]) - case nl.IFLA_BOND_ACTIVE_SLAVE: - bond.ActiveSlave = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_MIIMON: - bond.Miimon = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_UPDELAY: - bond.UpDelay = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_DOWNDELAY: - bond.DownDelay = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_USE_CARRIER: - bond.UseCarrier = int(data[i].Value[0]) - case nl.IFLA_BOND_ARP_INTERVAL: - bond.ArpInterval = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_ARP_IP_TARGET: - bond.ArpIpTargets = parseBondArpIpTargets(data[i].Value) - case nl.IFLA_BOND_ARP_VALIDATE: - bond.ArpValidate = BondArpValidate(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_ARP_ALL_TARGETS: - bond.ArpAllTargets = BondArpAllTargets(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_PRIMARY: - bond.Primary = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_PRIMARY_RESELECT: - bond.PrimaryReselect = BondPrimaryReselect(data[i].Value[0]) - case nl.IFLA_BOND_FAIL_OVER_MAC: - bond.FailOverMac = BondFailOverMac(data[i].Value[0]) - case nl.IFLA_BOND_XMIT_HASH_POLICY: - bond.XmitHashPolicy = BondXmitHashPolicy(data[i].Value[0]) - case nl.IFLA_BOND_RESEND_IGMP: - bond.ResendIgmp = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_NUM_PEER_NOTIF: - bond.NumPeerNotif = int(data[i].Value[0]) - case nl.IFLA_BOND_ALL_SLAVES_ACTIVE: - bond.AllSlavesActive = int(data[i].Value[0]) - case nl.IFLA_BOND_MIN_LINKS: - bond.MinLinks = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_LP_INTERVAL: - bond.LpInterval = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_PACKETS_PER_SLAVE: - bond.PacketsPerSlave = int(native.Uint32(data[i].Value[0:4])) - case nl.IFLA_BOND_AD_LACP_RATE: - bond.LacpRate = BondLacpRate(data[i].Value[0]) - case nl.IFLA_BOND_AD_SELECT: - bond.AdSelect = BondAdSelect(data[i].Value[0]) - case nl.IFLA_BOND_AD_INFO: - // TODO: implement - case nl.IFLA_BOND_AD_ACTOR_SYS_PRIO: - bond.AdActorSysPrio = int(native.Uint16(data[i].Value[0:2])) - case nl.IFLA_BOND_AD_USER_PORT_KEY: - bond.AdUserPortKey = int(native.Uint16(data[i].Value[0:2])) - case nl.IFLA_BOND_AD_ACTOR_SYSTEM: - bond.AdActorSystem = net.HardwareAddr(data[i].Value[0:6]) - case nl.IFLA_BOND_TLB_DYNAMIC_LB: - bond.TlbDynamicLb = int(data[i].Value[0]) - } - } -} - -func parseBondArpIpTargets(value []byte) []net.IP { - data, err := nl.ParseRouteAttr(value) - if err != nil { - return nil - } - - targets := []net.IP{} - for i := range data { - target := net.IP(data[i].Value) - if ip := target.To4(); ip != nil { - targets = append(targets, ip) - continue - } - if ip := target.To16(); ip != nil { - targets = append(targets, ip) - } - } - - return targets -} - -func addBondSlaveAttrs(bondSlave *BondSlave, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil) - - data.AddRtAttr(nl.IFLA_BOND_SLAVE_STATE, nl.Uint8Attr(uint8(bondSlave.State))) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_MII_STATUS, nl.Uint8Attr(uint8(bondSlave.MiiStatus))) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, nl.Uint32Attr(bondSlave.LinkFailureCount)) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(bondSlave.QueueId)) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, nl.Uint16Attr(bondSlave.AggregatorId)) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, nl.Uint8Attr(bondSlave.AdActorOperPortState)) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, nl.Uint16Attr(bondSlave.AdPartnerOperPortState)) - - if mac := bondSlave.PermHardwareAddr; mac != nil { - data.AddRtAttr(nl.IFLA_BOND_SLAVE_PERM_HWADDR, []byte(mac)) - } -} - -func parseBondSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) { - bondSlave := slave.(*BondSlave) - for i := range data { - switch data[i].Attr.Type { - case nl.IFLA_BOND_SLAVE_STATE: - bondSlave.State = BondSlaveState(data[i].Value[0]) - case nl.IFLA_BOND_SLAVE_MII_STATUS: - bondSlave.MiiStatus = BondSlaveMiiStatus(data[i].Value[0]) - case nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT: - bondSlave.LinkFailureCount = native.Uint32(data[i].Value[0:4]) - case nl.IFLA_BOND_SLAVE_PERM_HWADDR: - bondSlave.PermHardwareAddr = net.HardwareAddr(data[i].Value[0:6]) - case nl.IFLA_BOND_SLAVE_QUEUE_ID: - bondSlave.QueueId = native.Uint16(data[i].Value[0:2]) - case nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID: - bondSlave.AggregatorId = native.Uint16(data[i].Value[0:2]) - case nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE: - bondSlave.AdActorOperPortState = uint8(data[i].Value[0]) - case nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE: - bondSlave.AdPartnerOperPortState = native.Uint16(data[i].Value[0:2]) - } - } -} - -func parseVrfSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) { - vrfSlave := slave.(*VrfSlave) - for i := range data { - switch data[i].Attr.Type { - case nl.IFLA_BOND_SLAVE_STATE: - vrfSlave.Table = native.Uint32(data[i].Value[0:4]) - } - } -} - -func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) { - ipv := link.(*IPVlan) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_IPVLAN_MODE: - ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4])) - case nl.IFLA_IPVLAN_FLAG: - ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4])) - } - } -} - -func parseIPVtapData(link Link, data []syscall.NetlinkRouteAttr) { - ipv := link.(*IPVtap) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_IPVLAN_MODE: - ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4])) - case nl.IFLA_IPVLAN_FLAG: - ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4])) - } - } -} - -func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) { - macv := link.(*Macvtap) - parseMacvlanData(&macv.Macvlan, data) -} - -func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) { - macv := link.(*Macvlan) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_MACVLAN_MODE: - switch native.Uint32(datum.Value[0:4]) { - case nl.MACVLAN_MODE_PRIVATE: - macv.Mode = MACVLAN_MODE_PRIVATE - case nl.MACVLAN_MODE_VEPA: - macv.Mode = MACVLAN_MODE_VEPA - case nl.MACVLAN_MODE_BRIDGE: - macv.Mode = MACVLAN_MODE_BRIDGE - case nl.MACVLAN_MODE_PASSTHRU: - macv.Mode = MACVLAN_MODE_PASSTHRU - case nl.MACVLAN_MODE_SOURCE: - macv.Mode = MACVLAN_MODE_SOURCE - } - case nl.IFLA_MACVLAN_MACADDR_COUNT: - macv.MACAddrs = make([]net.HardwareAddr, 0, int(native.Uint32(datum.Value[0:4]))) - case nl.IFLA_MACVLAN_MACADDR_DATA: - macs, err := nl.ParseRouteAttr(datum.Value[:]) - if err != nil { - panic(fmt.Sprintf("failed to ParseRouteAttr for IFLA_MACVLAN_MACADDR_DATA: %v", err)) - } - for _, macDatum := range macs { - macv.MACAddrs = append(macv.MACAddrs, net.HardwareAddr(macDatum.Value[0:6])) - } - } - } -} - -// copied from pkg/net_linux.go -func linkFlags(rawFlags uint32) net.Flags { - var f net.Flags - if rawFlags&unix.IFF_UP != 0 { - f |= net.FlagUp - } - if rawFlags&unix.IFF_BROADCAST != 0 { - f |= net.FlagBroadcast - } - if rawFlags&unix.IFF_LOOPBACK != 0 { - f |= net.FlagLoopback - } - if rawFlags&unix.IFF_POINTOPOINT != 0 { - f |= net.FlagPointToPoint - } - if rawFlags&unix.IFF_MULTICAST != 0 { - f |= net.FlagMulticast - } - return f -} - -func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if geneve.FlowBased { - // In flow based mode, no other attributes need to be configured - linkInfo.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, boolAttr(geneve.FlowBased)) - return - } - - if ip := geneve.Remote; ip != nil { - if ip4 := ip.To4(); ip4 != nil { - data.AddRtAttr(nl.IFLA_GENEVE_REMOTE, ip.To4()) - } else { - data.AddRtAttr(nl.IFLA_GENEVE_REMOTE6, []byte(ip)) - } - } - - if geneve.ID != 0 { - data.AddRtAttr(nl.IFLA_GENEVE_ID, nl.Uint32Attr(geneve.ID)) - } - - if geneve.Dport != 0 { - data.AddRtAttr(nl.IFLA_GENEVE_PORT, htons(geneve.Dport)) - } - - if geneve.Ttl != 0 { - data.AddRtAttr(nl.IFLA_GENEVE_TTL, nl.Uint8Attr(geneve.Ttl)) - } - - if geneve.Tos != 0 { - data.AddRtAttr(nl.IFLA_GENEVE_TOS, nl.Uint8Attr(geneve.Tos)) - } -} - -func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) { - geneve := link.(*Geneve) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_GENEVE_ID: - geneve.ID = native.Uint32(datum.Value[0:4]) - case nl.IFLA_GENEVE_REMOTE, nl.IFLA_GENEVE_REMOTE6: - geneve.Remote = datum.Value - case nl.IFLA_GENEVE_PORT: - geneve.Dport = ntohs(datum.Value[0:2]) - case nl.IFLA_GENEVE_TTL: - geneve.Ttl = uint8(datum.Value[0]) - case nl.IFLA_GENEVE_TOS: - geneve.Tos = uint8(datum.Value[0]) - } - } -} - -func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if gretap.FlowBased { - // In flow based mode, no other attributes need to be configured - data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, boolAttr(gretap.FlowBased)) - return - } - - if ip := gretap.Local; ip != nil { - if ip.To4() != nil { - ip = ip.To4() - } - data.AddRtAttr(nl.IFLA_GRE_LOCAL, []byte(ip)) - } - - if ip := gretap.Remote; ip != nil { - if ip.To4() != nil { - ip = ip.To4() - } - data.AddRtAttr(nl.IFLA_GRE_REMOTE, []byte(ip)) - } - - if gretap.IKey != 0 { - data.AddRtAttr(nl.IFLA_GRE_IKEY, htonl(gretap.IKey)) - gretap.IFlags |= uint16(nl.GRE_KEY) - } - - if gretap.OKey != 0 { - data.AddRtAttr(nl.IFLA_GRE_OKEY, htonl(gretap.OKey)) - gretap.OFlags |= uint16(nl.GRE_KEY) - } - - data.AddRtAttr(nl.IFLA_GRE_IFLAGS, htons(gretap.IFlags)) - data.AddRtAttr(nl.IFLA_GRE_OFLAGS, htons(gretap.OFlags)) - - if gretap.Link != 0 { - data.AddRtAttr(nl.IFLA_GRE_LINK, nl.Uint32Attr(gretap.Link)) - } - - data.AddRtAttr(nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gretap.PMtuDisc)) - data.AddRtAttr(nl.IFLA_GRE_TTL, nl.Uint8Attr(gretap.Ttl)) - data.AddRtAttr(nl.IFLA_GRE_TOS, nl.Uint8Attr(gretap.Tos)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gretap.EncapType)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gretap.EncapFlags)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_SPORT, htons(gretap.EncapSport)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_DPORT, htons(gretap.EncapDport)) -} - -func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) { - gre := link.(*Gretap) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_GRE_OKEY: - gre.IKey = ntohl(datum.Value[0:4]) - case nl.IFLA_GRE_IKEY: - gre.OKey = ntohl(datum.Value[0:4]) - case nl.IFLA_GRE_LOCAL: - gre.Local = net.IP(datum.Value) - case nl.IFLA_GRE_REMOTE: - gre.Remote = net.IP(datum.Value) - case nl.IFLA_GRE_ENCAP_SPORT: - gre.EncapSport = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_ENCAP_DPORT: - gre.EncapDport = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_IFLAGS: - gre.IFlags = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_OFLAGS: - gre.OFlags = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_TTL: - gre.Ttl = uint8(datum.Value[0]) - case nl.IFLA_GRE_TOS: - gre.Tos = uint8(datum.Value[0]) - case nl.IFLA_GRE_PMTUDISC: - gre.PMtuDisc = uint8(datum.Value[0]) - case nl.IFLA_GRE_ENCAP_TYPE: - gre.EncapType = native.Uint16(datum.Value[0:2]) - case nl.IFLA_GRE_ENCAP_FLAGS: - gre.EncapFlags = native.Uint16(datum.Value[0:2]) - case nl.IFLA_GRE_COLLECT_METADATA: - gre.FlowBased = true - } - } -} - -func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if ip := gre.Local; ip != nil { - if ip.To4() != nil { - ip = ip.To4() - } - data.AddRtAttr(nl.IFLA_GRE_LOCAL, []byte(ip)) - } - - if ip := gre.Remote; ip != nil { - if ip.To4() != nil { - ip = ip.To4() - } - data.AddRtAttr(nl.IFLA_GRE_REMOTE, []byte(ip)) - } - - if gre.IKey != 0 { - data.AddRtAttr(nl.IFLA_GRE_IKEY, htonl(gre.IKey)) - gre.IFlags |= uint16(nl.GRE_KEY) - } - - if gre.OKey != 0 { - data.AddRtAttr(nl.IFLA_GRE_OKEY, htonl(gre.OKey)) - gre.OFlags |= uint16(nl.GRE_KEY) - } - - data.AddRtAttr(nl.IFLA_GRE_IFLAGS, htons(gre.IFlags)) - data.AddRtAttr(nl.IFLA_GRE_OFLAGS, htons(gre.OFlags)) - - if gre.Link != 0 { - data.AddRtAttr(nl.IFLA_GRE_LINK, nl.Uint32Attr(gre.Link)) - } - - data.AddRtAttr(nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gre.PMtuDisc)) - data.AddRtAttr(nl.IFLA_GRE_TTL, nl.Uint8Attr(gre.Ttl)) - data.AddRtAttr(nl.IFLA_GRE_TOS, nl.Uint8Attr(gre.Tos)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gre.EncapType)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gre.EncapFlags)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_SPORT, htons(gre.EncapSport)) - data.AddRtAttr(nl.IFLA_GRE_ENCAP_DPORT, htons(gre.EncapDport)) -} - -func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) { - gre := link.(*Gretun) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_GRE_IKEY: - gre.IKey = ntohl(datum.Value[0:4]) - case nl.IFLA_GRE_OKEY: - gre.OKey = ntohl(datum.Value[0:4]) - case nl.IFLA_GRE_LOCAL: - gre.Local = net.IP(datum.Value) - case nl.IFLA_GRE_REMOTE: - gre.Remote = net.IP(datum.Value) - case nl.IFLA_GRE_IFLAGS: - gre.IFlags = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_OFLAGS: - gre.OFlags = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_TTL: - gre.Ttl = uint8(datum.Value[0]) - case nl.IFLA_GRE_TOS: - gre.Tos = uint8(datum.Value[0]) - case nl.IFLA_GRE_PMTUDISC: - gre.PMtuDisc = uint8(datum.Value[0]) - case nl.IFLA_GRE_ENCAP_TYPE: - gre.EncapType = native.Uint16(datum.Value[0:2]) - case nl.IFLA_GRE_ENCAP_FLAGS: - gre.EncapFlags = native.Uint16(datum.Value[0:2]) - case nl.IFLA_GRE_ENCAP_SPORT: - gre.EncapSport = ntohs(datum.Value[0:2]) - case nl.IFLA_GRE_ENCAP_DPORT: - gre.EncapDport = ntohs(datum.Value[0:2]) - } - } -} - -func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) { - attrs := nl.NewRtAttr(unix.IFLA_XDP|unix.NLA_F_NESTED, nil) - b := make([]byte, 4) - native.PutUint32(b, uint32(xdp.Fd)) - attrs.AddRtAttr(nl.IFLA_XDP_FD, b) - if xdp.Flags != 0 { - b := make([]byte, 4) - native.PutUint32(b, xdp.Flags) - attrs.AddRtAttr(nl.IFLA_XDP_FLAGS, b) - } - req.AddData(attrs) -} - -func parseLinkXdp(data []byte) (*LinkXdp, error) { - attrs, err := nl.ParseRouteAttr(data) - if err != nil { - return nil, err - } - xdp := &LinkXdp{} - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.IFLA_XDP_FD: - xdp.Fd = int(native.Uint32(attr.Value[0:4])) - case nl.IFLA_XDP_ATTACHED: - xdp.AttachMode = uint32(attr.Value[0]) - xdp.Attached = xdp.AttachMode != 0 - case nl.IFLA_XDP_FLAGS: - xdp.Flags = native.Uint32(attr.Value[0:4]) - case nl.IFLA_XDP_PROG_ID: - xdp.ProgId = native.Uint32(attr.Value[0:4]) - } - } - return xdp, nil -} - -func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) { - if iptun.FlowBased { - // In flow based mode, no other attributes need to be configured - linkInfo.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, boolAttr(iptun.FlowBased)) - return - } - - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - ip := iptun.Local.To4() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip)) - } - - ip = iptun.Remote.To4() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip)) - } - - if iptun.Link != 0 { - data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(iptun.Link)) - } - data.AddRtAttr(nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc)) - data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl)) - data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(iptun.EncapType)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(iptun.EncapFlags)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(iptun.EncapSport)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(iptun.EncapDport)) -} - -func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) { - iptun := link.(*Iptun) - for _, datum := range data { - // NOTE: same with vxlan, ip tunnel may also has null datum.Value - if len(datum.Value) == 0 { - continue - } - switch datum.Attr.Type { - case nl.IFLA_IPTUN_LOCAL: - iptun.Local = net.IP(datum.Value[0:4]) - case nl.IFLA_IPTUN_REMOTE: - iptun.Remote = net.IP(datum.Value[0:4]) - case nl.IFLA_IPTUN_TTL: - iptun.Ttl = uint8(datum.Value[0]) - case nl.IFLA_IPTUN_TOS: - iptun.Tos = uint8(datum.Value[0]) - case nl.IFLA_IPTUN_PMTUDISC: - iptun.PMtuDisc = uint8(datum.Value[0]) - case nl.IFLA_IPTUN_ENCAP_SPORT: - iptun.EncapSport = ntohs(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_DPORT: - iptun.EncapDport = ntohs(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_TYPE: - iptun.EncapType = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_FLAGS: - iptun.EncapFlags = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_COLLECT_METADATA: - iptun.FlowBased = true - } - } -} - -func addIp6tnlAttrs(ip6tnl *Ip6tnl, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if ip6tnl.Link != 0 { - data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(ip6tnl.Link)) - } - - ip := ip6tnl.Local.To16() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip)) - } - - ip = ip6tnl.Remote.To16() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip)) - } - - data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(ip6tnl.Ttl)) - data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(ip6tnl.Tos)) - data.AddRtAttr(nl.IFLA_IPTUN_FLAGS, nl.Uint32Attr(ip6tnl.Flags)) - data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(ip6tnl.Proto)) - data.AddRtAttr(nl.IFLA_IPTUN_FLOWINFO, nl.Uint32Attr(ip6tnl.FlowInfo)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_LIMIT, nl.Uint8Attr(ip6tnl.EncapLimit)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(ip6tnl.EncapType)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(ip6tnl.EncapFlags)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(ip6tnl.EncapSport)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(ip6tnl.EncapDport)) -} - -func parseIp6tnlData(link Link, data []syscall.NetlinkRouteAttr) { - ip6tnl := link.(*Ip6tnl) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_IPTUN_LOCAL: - ip6tnl.Local = net.IP(datum.Value[:16]) - case nl.IFLA_IPTUN_REMOTE: - ip6tnl.Remote = net.IP(datum.Value[:16]) - case nl.IFLA_IPTUN_TTL: - ip6tnl.Ttl = datum.Value[0] - case nl.IFLA_IPTUN_TOS: - ip6tnl.Tos = datum.Value[0] - case nl.IFLA_IPTUN_FLAGS: - ip6tnl.Flags = native.Uint32(datum.Value[:4]) - case nl.IFLA_IPTUN_PROTO: - ip6tnl.Proto = datum.Value[0] - case nl.IFLA_IPTUN_FLOWINFO: - ip6tnl.FlowInfo = native.Uint32(datum.Value[:4]) - case nl.IFLA_IPTUN_ENCAP_LIMIT: - ip6tnl.EncapLimit = datum.Value[0] - case nl.IFLA_IPTUN_ENCAP_TYPE: - ip6tnl.EncapType = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_FLAGS: - ip6tnl.EncapFlags = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_SPORT: - ip6tnl.EncapSport = ntohs(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_DPORT: - ip6tnl.EncapDport = ntohs(datum.Value[0:2]) - } - } -} - -func addSittunAttrs(sittun *Sittun, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - if sittun.Link != 0 { - data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(sittun.Link)) - } - - ip := sittun.Local.To4() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip)) - } - - ip = sittun.Remote.To4() - if ip != nil { - data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip)) - } - - if sittun.Ttl > 0 { - // Would otherwise fail on 3.10 kernel - data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(sittun.Ttl)) - } - - data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(sittun.Proto)) - data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(sittun.Tos)) - data.AddRtAttr(nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(sittun.PMtuDisc)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_LIMIT, nl.Uint8Attr(sittun.EncapLimit)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(sittun.EncapType)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(sittun.EncapFlags)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_SPORT, htons(sittun.EncapSport)) - data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_DPORT, htons(sittun.EncapDport)) -} - -func parseSittunData(link Link, data []syscall.NetlinkRouteAttr) { - sittun := link.(*Sittun) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_IPTUN_LOCAL: - sittun.Local = net.IP(datum.Value[0:4]) - case nl.IFLA_IPTUN_REMOTE: - sittun.Remote = net.IP(datum.Value[0:4]) - case nl.IFLA_IPTUN_TTL: - sittun.Ttl = datum.Value[0] - case nl.IFLA_IPTUN_TOS: - sittun.Tos = datum.Value[0] - case nl.IFLA_IPTUN_PMTUDISC: - sittun.PMtuDisc = datum.Value[0] - case nl.IFLA_IPTUN_PROTO: - sittun.Proto = datum.Value[0] - case nl.IFLA_IPTUN_ENCAP_TYPE: - sittun.EncapType = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_FLAGS: - sittun.EncapFlags = native.Uint16(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_SPORT: - sittun.EncapSport = ntohs(datum.Value[0:2]) - case nl.IFLA_IPTUN_ENCAP_DPORT: - sittun.EncapDport = ntohs(datum.Value[0:2]) - } - } -} - -func addVtiAttrs(vti *Vti, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - family := FAMILY_V4 - if vti.Local.To4() == nil { - family = FAMILY_V6 - } - - var ip net.IP - - if family == FAMILY_V4 { - ip = vti.Local.To4() - } else { - ip = vti.Local - } - if ip != nil { - data.AddRtAttr(nl.IFLA_VTI_LOCAL, []byte(ip)) - } - - if family == FAMILY_V4 { - ip = vti.Remote.To4() - } else { - ip = vti.Remote - } - if ip != nil { - data.AddRtAttr(nl.IFLA_VTI_REMOTE, []byte(ip)) - } - - if vti.Link != 0 { - data.AddRtAttr(nl.IFLA_VTI_LINK, nl.Uint32Attr(vti.Link)) - } - - data.AddRtAttr(nl.IFLA_VTI_IKEY, htonl(vti.IKey)) - data.AddRtAttr(nl.IFLA_VTI_OKEY, htonl(vti.OKey)) -} - -func parseVtiData(link Link, data []syscall.NetlinkRouteAttr) { - vti := link.(*Vti) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_VTI_LOCAL: - vti.Local = net.IP(datum.Value) - case nl.IFLA_VTI_REMOTE: - vti.Remote = net.IP(datum.Value) - case nl.IFLA_VTI_IKEY: - vti.IKey = ntohl(datum.Value[0:4]) - case nl.IFLA_VTI_OKEY: - vti.OKey = ntohl(datum.Value[0:4]) - } - } -} - -func addVrfAttrs(vrf *Vrf, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - b := make([]byte, 4) - native.PutUint32(b, uint32(vrf.Table)) - data.AddRtAttr(nl.IFLA_VRF_TABLE, b) -} - -func parseVrfData(link Link, data []syscall.NetlinkRouteAttr) { - vrf := link.(*Vrf) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_VRF_TABLE: - vrf.Table = native.Uint32(datum.Value[0:4]) - } - } -} - -func addBridgeAttrs(bridge *Bridge, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - if bridge.MulticastSnooping != nil { - data.AddRtAttr(nl.IFLA_BR_MCAST_SNOOPING, boolToByte(*bridge.MulticastSnooping)) - } - if bridge.AgeingTime != nil { - data.AddRtAttr(nl.IFLA_BR_AGEING_TIME, nl.Uint32Attr(*bridge.AgeingTime)) - } - if bridge.HelloTime != nil { - data.AddRtAttr(nl.IFLA_BR_HELLO_TIME, nl.Uint32Attr(*bridge.HelloTime)) - } - if bridge.VlanFiltering != nil { - data.AddRtAttr(nl.IFLA_BR_VLAN_FILTERING, boolToByte(*bridge.VlanFiltering)) - } -} - -func parseBridgeData(bridge Link, data []syscall.NetlinkRouteAttr) { - br := bridge.(*Bridge) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_BR_AGEING_TIME: - ageingTime := native.Uint32(datum.Value[0:4]) - br.AgeingTime = &ageingTime - case nl.IFLA_BR_HELLO_TIME: - helloTime := native.Uint32(datum.Value[0:4]) - br.HelloTime = &helloTime - case nl.IFLA_BR_MCAST_SNOOPING: - mcastSnooping := datum.Value[0] == 1 - br.MulticastSnooping = &mcastSnooping - case nl.IFLA_BR_VLAN_FILTERING: - vlanFiltering := datum.Value[0] == 1 - br.VlanFiltering = &vlanFiltering - } - } -} - -func addGTPAttrs(gtp *GTP, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_GTP_FD0, nl.Uint32Attr(uint32(gtp.FD0))) - data.AddRtAttr(nl.IFLA_GTP_FD1, nl.Uint32Attr(uint32(gtp.FD1))) - data.AddRtAttr(nl.IFLA_GTP_PDP_HASHSIZE, nl.Uint32Attr(131072)) - if gtp.Role != nl.GTP_ROLE_GGSN { - data.AddRtAttr(nl.IFLA_GTP_ROLE, nl.Uint32Attr(uint32(gtp.Role))) - } -} - -func parseGTPData(link Link, data []syscall.NetlinkRouteAttr) { - gtp := link.(*GTP) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_GTP_FD0: - gtp.FD0 = int(native.Uint32(datum.Value)) - case nl.IFLA_GTP_FD1: - gtp.FD1 = int(native.Uint32(datum.Value)) - case nl.IFLA_GTP_PDP_HASHSIZE: - gtp.PDPHashsize = int(native.Uint32(datum.Value)) - case nl.IFLA_GTP_ROLE: - gtp.Role = int(native.Uint32(datum.Value)) - } - } -} - -func parseVfInfoList(data []syscall.NetlinkRouteAttr) ([]VfInfo, error) { - var vfs []VfInfo - - for i, element := range data { - if element.Attr.Type != nl.IFLA_VF_INFO { - return nil, fmt.Errorf("Incorrect element type in vf info list: %d", element.Attr.Type) - } - vfAttrs, err := nl.ParseRouteAttr(element.Value) - if err != nil { - return nil, err - } - vfs = append(vfs, parseVfInfo(vfAttrs, i)) - } - return vfs, nil -} - -func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) VfInfo { - vf := VfInfo{ID: id} - for _, element := range data { - switch element.Attr.Type { - case nl.IFLA_VF_MAC: - mac := nl.DeserializeVfMac(element.Value[:]) - vf.Mac = mac.Mac[:6] - case nl.IFLA_VF_VLAN: - vl := nl.DeserializeVfVlan(element.Value[:]) - vf.Vlan = int(vl.Vlan) - vf.Qos = int(vl.Qos) - case nl.IFLA_VF_TX_RATE: - txr := nl.DeserializeVfTxRate(element.Value[:]) - vf.TxRate = int(txr.Rate) - case nl.IFLA_VF_SPOOFCHK: - sp := nl.DeserializeVfSpoofchk(element.Value[:]) - vf.Spoofchk = sp.Setting != 0 - case nl.IFLA_VF_LINK_STATE: - ls := nl.DeserializeVfLinkState(element.Value[:]) - vf.LinkState = ls.LinkState - case nl.IFLA_VF_RATE: - vfr := nl.DeserializeVfRate(element.Value[:]) - vf.MaxTxRate = vfr.MaxTxRate - vf.MinTxRate = vfr.MinTxRate - case nl.IFLA_VF_STATS: - vfstats := nl.DeserializeVfStats(element.Value[:]) - vf.RxPackets = vfstats.RxPackets - vf.TxPackets = vfstats.TxPackets - vf.RxBytes = vfstats.RxBytes - vf.TxBytes = vfstats.TxBytes - vf.Multicast = vfstats.Multicast - vf.Broadcast = vfstats.Broadcast - vf.RxDropped = vfstats.RxDropped - vf.TxDropped = vfstats.TxDropped - - case nl.IFLA_VF_RSS_QUERY_EN: - result := nl.DeserializeVfRssQueryEn(element.Value) - vf.RssQuery = result.Setting - - case nl.IFLA_VF_TRUST: - result := nl.DeserializeVfTrust(element.Value) - vf.Trust = result.Setting - } - } - return vf -} - -func addXfrmiAttrs(xfrmi *Xfrmi, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_XFRM_LINK, nl.Uint32Attr(uint32(xfrmi.ParentIndex))) - data.AddRtAttr(nl.IFLA_XFRM_IF_ID, nl.Uint32Attr(xfrmi.Ifid)) - -} - -func parseXfrmiData(link Link, data []syscall.NetlinkRouteAttr) { - xfrmi := link.(*Xfrmi) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_XFRM_LINK: - xfrmi.ParentIndex = int(native.Uint32(datum.Value)) - case nl.IFLA_XFRM_IF_ID: - xfrmi.Ifid = native.Uint32(datum.Value) - } - } -} - -// LinkSetBondSlave add slave to bond link via ioctl interface. -func LinkSetBondSlave(link Link, master *Bond) error { - fd, err := getSocketUDP() - if err != nil { - return err - } - defer syscall.Close(fd) - - ifreq := newIocltSlaveReq(link.Attrs().Name, master.Attrs().Name) - - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), unix.SIOCBONDENSLAVE, uintptr(unsafe.Pointer(ifreq))) - if errno != 0 { - return fmt.Errorf("Failed to enslave %q to %q, errno=%v", link.Attrs().Name, master.Attrs().Name, errno) - } - return nil -} - -// LinkSetBondSlaveQueueId modify bond slave queue-id. -func (h *Handle) LinkSetBondSlaveQueueId(link Link, queueId uint16) error { - base := link.Attrs() - h.ensureIndex(base) - req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) - - msg := nl.NewIfInfomsg(unix.AF_UNSPEC) - msg.Index = int32(base.Index) - req.AddData(msg) - - linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) - data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil) - data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(queueId)) - - req.AddData(linkInfo) - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// LinkSetBondSlaveQueueId modify bond slave queue-id. -func LinkSetBondSlaveQueueId(link Link, queueId uint16) error { - return pkgHandle.LinkSetBondSlaveQueueId(link, queueId) -} - -func vethStatsSerialize(stats ethtoolStats) ([]byte, error) { - statsSize := int(unsafe.Sizeof(stats)) + int(stats.nStats)*int(unsafe.Sizeof(uint64(0))) - b := make([]byte, 0, statsSize) - buf := bytes.NewBuffer(b) - err := binary.Write(buf, nl.NativeEndian(), stats) - return buf.Bytes()[:statsSize], err -} - -type vethEthtoolStats struct { - Cmd uint32 - NStats uint32 - Peer uint64 - // Newer kernels have XDP stats in here, but we only care - // to extract the peer ifindex here. -} - -func vethStatsDeserialize(b []byte) (vethEthtoolStats, error) { - var stats = vethEthtoolStats{} - err := binary.Read(bytes.NewReader(b), nl.NativeEndian(), &stats) - return stats, err -} - -// VethPeerIndex get veth peer index. -func VethPeerIndex(link *Veth) (int, error) { - fd, err := getSocketUDP() - if err != nil { - return -1, err - } - defer syscall.Close(fd) - - ifreq, sSet := newIocltStringSetReq(link.Name) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) - if errno != 0 { - return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno) - } - - stats := ethtoolStats{ - cmd: ETHTOOL_GSTATS, - nStats: sSet.data[0], - } - - buffer, err := vethStatsSerialize(stats) - if err != nil { - return -1, err - } - - ifreq.Data = uintptr(unsafe.Pointer(&buffer[0])) - _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) - if errno != 0 { - return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno) - } - - vstats, err := vethStatsDeserialize(buffer) - if err != nil { - return -1, err - } - - return int(vstats.Peer), nil -} - -func parseTuntapData(link Link, data []syscall.NetlinkRouteAttr) { - tuntap := link.(*Tuntap) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_TUN_OWNER: - tuntap.Owner = native.Uint32(datum.Value) - case nl.IFLA_TUN_GROUP: - tuntap.Group = native.Uint32(datum.Value) - case nl.IFLA_TUN_TYPE: - tuntap.Mode = TuntapMode(uint8(datum.Value[0])) - case nl.IFLA_TUN_PERSIST: - tuntap.NonPersist = false - if uint8(datum.Value[0]) == 0 { - tuntap.NonPersist = true - } - } - } -} - -func parseIPoIBData(link Link, data []syscall.NetlinkRouteAttr) { - ipoib := link.(*IPoIB) - for _, datum := range data { - switch datum.Attr.Type { - case nl.IFLA_IPOIB_PKEY: - ipoib.Pkey = uint16(native.Uint16(datum.Value)) - case nl.IFLA_IPOIB_MODE: - ipoib.Mode = IPoIBMode(native.Uint16(datum.Value)) - case nl.IFLA_IPOIB_UMCAST: - ipoib.Umcast = uint16(native.Uint16(datum.Value)) - } - } -} - -func parseCanData(link Link, data []syscall.NetlinkRouteAttr) { - can := link.(*Can) - for _, datum := range data { - - switch datum.Attr.Type { - case nl.IFLA_CAN_BITTIMING: - can.BitRate = native.Uint32(datum.Value) - can.SamplePoint = native.Uint32(datum.Value[4:]) - can.TimeQuanta = native.Uint32(datum.Value[8:]) - can.PropagationSegment = native.Uint32(datum.Value[12:]) - can.PhaseSegment1 = native.Uint32(datum.Value[16:]) - can.PhaseSegment2 = native.Uint32(datum.Value[20:]) - can.SyncJumpWidth = native.Uint32(datum.Value[24:]) - can.BitRatePreScaler = native.Uint32(datum.Value[28:]) - case nl.IFLA_CAN_BITTIMING_CONST: - can.Name = string(datum.Value[:16]) - can.TimeSegment1Min = native.Uint32(datum.Value[16:]) - can.TimeSegment1Max = native.Uint32(datum.Value[20:]) - can.TimeSegment2Min = native.Uint32(datum.Value[24:]) - can.TimeSegment2Max = native.Uint32(datum.Value[28:]) - can.SyncJumpWidthMax = native.Uint32(datum.Value[32:]) - can.BitRatePreScalerMin = native.Uint32(datum.Value[36:]) - can.BitRatePreScalerMax = native.Uint32(datum.Value[40:]) - can.BitRatePreScalerInc = native.Uint32(datum.Value[44:]) - case nl.IFLA_CAN_CLOCK: - can.ClockFrequency = native.Uint32(datum.Value) - case nl.IFLA_CAN_STATE: - can.State = native.Uint32(datum.Value) - case nl.IFLA_CAN_CTRLMODE: - can.Mask = native.Uint32(datum.Value) - can.Flags = native.Uint32(datum.Value[4:]) - case nl.IFLA_CAN_BERR_COUNTER: - can.TxError = native.Uint16(datum.Value) - can.RxError = native.Uint16(datum.Value[2:]) - case nl.IFLA_CAN_RESTART_MS: - can.RestartMs = native.Uint32(datum.Value) - case nl.IFLA_CAN_DATA_BITTIMING_CONST: - case nl.IFLA_CAN_RESTART: - case nl.IFLA_CAN_DATA_BITTIMING: - case nl.IFLA_CAN_TERMINATION: - case nl.IFLA_CAN_TERMINATION_CONST: - case nl.IFLA_CAN_BITRATE_CONST: - case nl.IFLA_CAN_DATA_BITRATE_CONST: - case nl.IFLA_CAN_BITRATE_MAX: - } - } -} - -func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - data.AddRtAttr(nl.IFLA_IPOIB_PKEY, nl.Uint16Attr(uint16(ipoib.Pkey))) - data.AddRtAttr(nl.IFLA_IPOIB_MODE, nl.Uint16Attr(uint16(ipoib.Mode))) - data.AddRtAttr(nl.IFLA_IPOIB_UMCAST, nl.Uint16Attr(uint16(ipoib.Umcast))) -} - -func addBareUDPAttrs(bareudp *BareUDP, linkInfo *nl.RtAttr) { - data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) - - data.AddRtAttr(nl.IFLA_BAREUDP_PORT, nl.Uint16Attr(nl.Swap16(bareudp.Port))) - data.AddRtAttr(nl.IFLA_BAREUDP_ETHERTYPE, nl.Uint16Attr(nl.Swap16(bareudp.EtherType))) - if bareudp.SrcPortMin != 0 { - data.AddRtAttr(nl.IFLA_BAREUDP_SRCPORT_MIN, nl.Uint16Attr(bareudp.SrcPortMin)) - } - if bareudp.MultiProto { - data.AddRtAttr(nl.IFLA_BAREUDP_MULTIPROTO_MODE, []byte{}) - } -} - -func parseBareUDPData(link Link, data []syscall.NetlinkRouteAttr) { - bareudp := link.(*BareUDP) - for _, attr := range data { - switch attr.Attr.Type { - case nl.IFLA_BAREUDP_PORT: - bareudp.Port = binary.BigEndian.Uint16(attr.Value) - case nl.IFLA_BAREUDP_ETHERTYPE: - bareudp.EtherType = binary.BigEndian.Uint16(attr.Value) - case nl.IFLA_BAREUDP_SRCPORT_MIN: - bareudp.SrcPortMin = native.Uint16(attr.Value) - case nl.IFLA_BAREUDP_MULTIPROTO_MODE: - bareudp.MultiProto = true - } - } -} diff --git a/vendor/github.com/tailscale/netlink/link_tuntap_linux.go b/vendor/github.com/tailscale/netlink/link_tuntap_linux.go deleted file mode 100644 index 310bd33..0000000 --- a/vendor/github.com/tailscale/netlink/link_tuntap_linux.go +++ /dev/null @@ -1,14 +0,0 @@ -package netlink - -// ideally golang.org/x/sys/unix would define IfReq but it only has -// IFNAMSIZ, hence this minimalistic implementation -const ( - SizeOfIfReq = 40 - IFNAMSIZ = 16 -) - -type ifReq struct { - Name [IFNAMSIZ]byte - Flags uint16 - pad [SizeOfIfReq - IFNAMSIZ - 2]byte -} diff --git a/vendor/github.com/tailscale/netlink/neigh.go b/vendor/github.com/tailscale/netlink/neigh.go deleted file mode 100644 index 32d722e..0000000 --- a/vendor/github.com/tailscale/netlink/neigh.go +++ /dev/null @@ -1,33 +0,0 @@ -package netlink - -import ( - "fmt" - "net" -) - -// Neigh represents a link layer neighbor from netlink. -type Neigh struct { - LinkIndex int - Family int - State int - Type int - Flags int - FlagsExt int - IP net.IP - HardwareAddr net.HardwareAddr - LLIPAddr net.IP //Used in the case of NHRP - Vlan int - VNI int - MasterIndex int -} - -// String returns $ip/$hwaddr $label -func (neigh *Neigh) String() string { - return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr) -} - -// NeighUpdate is sent when a neighbor changes - type is RTM_NEWNEIGH or RTM_DELNEIGH. -type NeighUpdate struct { - Type uint16 - Neigh -} diff --git a/vendor/github.com/tailscale/netlink/neigh_linux.go b/vendor/github.com/tailscale/netlink/neigh_linux.go deleted file mode 100644 index 23b4b7e..0000000 --- a/vendor/github.com/tailscale/netlink/neigh_linux.go +++ /dev/null @@ -1,452 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "syscall" - "unsafe" - - "github.com/tailscale/netlink/nl" - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -const ( - NDA_UNSPEC = iota - NDA_DST - NDA_LLADDR - NDA_CACHEINFO - NDA_PROBES - NDA_VLAN - NDA_PORT - NDA_VNI - NDA_IFINDEX - NDA_MASTER - NDA_LINK_NETNSID - NDA_SRC_VNI - NDA_PROTOCOL - NDA_NH_ID - NDA_FDB_EXT_ATTRS - NDA_FLAGS_EXT - NDA_MAX = NDA_FLAGS_EXT -) - -// Neighbor Cache Entry States. -const ( - NUD_NONE = 0x00 - NUD_INCOMPLETE = 0x01 - NUD_REACHABLE = 0x02 - NUD_STALE = 0x04 - NUD_DELAY = 0x08 - NUD_PROBE = 0x10 - NUD_FAILED = 0x20 - NUD_NOARP = 0x40 - NUD_PERMANENT = 0x80 -) - -// Neighbor Flags -const ( - NTF_USE = 0x01 - NTF_SELF = 0x02 - NTF_MASTER = 0x04 - NTF_PROXY = 0x08 - NTF_EXT_LEARNED = 0x10 - NTF_OFFLOADED = 0x20 - NTF_STICKY = 0x40 - NTF_ROUTER = 0x80 -) - -// Extended Neighbor Flags -const ( - NTF_EXT_MANAGED = 0x00000001 -) - -// Ndmsg is for adding, removing or receiving information about a neighbor table entry -type Ndmsg struct { - Family uint8 - Index uint32 - State uint16 - Flags uint8 - Type uint8 -} - -func deserializeNdmsg(b []byte) *Ndmsg { - var dummy Ndmsg - return (*Ndmsg)(unsafe.Pointer(&b[0:unsafe.Sizeof(dummy)][0])) -} - -func (msg *Ndmsg) Serialize() []byte { - return (*(*[unsafe.Sizeof(*msg)]byte)(unsafe.Pointer(msg)))[:] -} - -func (msg *Ndmsg) Len() int { - return int(unsafe.Sizeof(*msg)) -} - -// NeighAdd will add an IP to MAC mapping to the ARP table -// Equivalent to: `ip neigh add ....` -func NeighAdd(neigh *Neigh) error { - return pkgHandle.NeighAdd(neigh) -} - -// NeighAdd will add an IP to MAC mapping to the ARP table -// Equivalent to: `ip neigh add ....` -func (h *Handle) NeighAdd(neigh *Neigh) error { - return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_EXCL) -} - -// NeighSet will add or replace an IP to MAC mapping to the ARP table -// Equivalent to: `ip neigh replace....` -func NeighSet(neigh *Neigh) error { - return pkgHandle.NeighSet(neigh) -} - -// NeighSet will add or replace an IP to MAC mapping to the ARP table -// Equivalent to: `ip neigh replace....` -func (h *Handle) NeighSet(neigh *Neigh) error { - return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_REPLACE) -} - -// NeighAppend will append an entry to FDB -// Equivalent to: `bridge fdb append...` -func NeighAppend(neigh *Neigh) error { - return pkgHandle.NeighAppend(neigh) -} - -// NeighAppend will append an entry to FDB -// Equivalent to: `bridge fdb append...` -func (h *Handle) NeighAppend(neigh *Neigh) error { - return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_APPEND) -} - -// NeighAppend will append an entry to FDB -// Equivalent to: `bridge fdb append...` -func neighAdd(neigh *Neigh, mode int) error { - return pkgHandle.neighAdd(neigh, mode) -} - -// NeighAppend will append an entry to FDB -// Equivalent to: `bridge fdb append...` -func (h *Handle) neighAdd(neigh *Neigh, mode int) error { - req := h.newNetlinkRequest(unix.RTM_NEWNEIGH, mode|unix.NLM_F_ACK) - return neighHandle(neigh, req) -} - -// NeighDel will delete an IP address from a link device. -// Equivalent to: `ip addr del $addr dev $link` -func NeighDel(neigh *Neigh) error { - return pkgHandle.NeighDel(neigh) -} - -// NeighDel will delete an IP address from a link device. -// Equivalent to: `ip addr del $addr dev $link` -func (h *Handle) NeighDel(neigh *Neigh) error { - req := h.newNetlinkRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK) - return neighHandle(neigh, req) -} - -func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error { - var family int - - if neigh.Family > 0 { - family = neigh.Family - } else { - family = nl.GetIPFamily(neigh.IP) - } - - msg := Ndmsg{ - Family: uint8(family), - Index: uint32(neigh.LinkIndex), - State: uint16(neigh.State), - Type: uint8(neigh.Type), - Flags: uint8(neigh.Flags), - } - req.AddData(&msg) - - ipData := neigh.IP.To4() - if ipData == nil { - ipData = neigh.IP.To16() - } - - dstData := nl.NewRtAttr(NDA_DST, ipData) - req.AddData(dstData) - - if neigh.LLIPAddr != nil { - llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4()) - req.AddData(llIPData) - } else if neigh.HardwareAddr != nil { - hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr)) - req.AddData(hwData) - } - - if neigh.FlagsExt != 0 { - flagsExtData := nl.NewRtAttr(NDA_FLAGS_EXT, nl.Uint32Attr(uint32(neigh.FlagsExt))) - req.AddData(flagsExtData) - } - - if neigh.Vlan != 0 { - vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan))) - req.AddData(vlanData) - } - - if neigh.VNI != 0 { - vniData := nl.NewRtAttr(NDA_VNI, nl.Uint32Attr(uint32(neigh.VNI))) - req.AddData(vniData) - } - - if neigh.MasterIndex != 0 { - masterData := nl.NewRtAttr(NDA_MASTER, nl.Uint32Attr(uint32(neigh.MasterIndex))) - req.AddData(masterData) - } - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// NeighList returns a list of IP-MAC mappings in the system (ARP table). -// Equivalent to: `ip neighbor show`. -// The list can be filtered by link and ip family. -func NeighList(linkIndex, family int) ([]Neigh, error) { - return pkgHandle.NeighList(linkIndex, family) -} - -// NeighProxyList returns a list of neighbor proxies in the system. -// Equivalent to: `ip neighbor show proxy`. -// The list can be filtered by link and ip family. -func NeighProxyList(linkIndex, family int) ([]Neigh, error) { - return pkgHandle.NeighProxyList(linkIndex, family) -} - -// NeighList returns a list of IP-MAC mappings in the system (ARP table). -// Equivalent to: `ip neighbor show`. -// The list can be filtered by link and ip family. -func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) { - return h.NeighListExecute(Ndmsg{ - Family: uint8(family), - Index: uint32(linkIndex), - }) -} - -// NeighProxyList returns a list of neighbor proxies in the system. -// Equivalent to: `ip neighbor show proxy`. -// The list can be filtered by link, ip family. -func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) { - return h.NeighListExecute(Ndmsg{ - Family: uint8(family), - Index: uint32(linkIndex), - Flags: NTF_PROXY, - }) -} - -// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state. -func NeighListExecute(msg Ndmsg) ([]Neigh, error) { - return pkgHandle.NeighListExecute(msg) -} - -// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state. -func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) { - req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP) - req.AddData(&msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH) - if err != nil { - return nil, err - } - - var res []Neigh - for _, m := range msgs { - ndm := deserializeNdmsg(m) - if msg.Index != 0 && ndm.Index != msg.Index { - // Ignore messages from other interfaces - continue - } - if msg.Family != 0 && ndm.Family != msg.Family { - continue - } - if msg.State != 0 && ndm.State != msg.State { - continue - } - if msg.Type != 0 && ndm.Type != msg.Type { - continue - } - if msg.Flags != 0 && ndm.Flags != msg.Flags { - continue - } - - neigh, err := NeighDeserialize(m) - if err != nil { - continue - } - - res = append(res, *neigh) - } - - return res, nil -} - -func NeighDeserialize(m []byte) (*Neigh, error) { - msg := deserializeNdmsg(m) - - neigh := Neigh{ - LinkIndex: int(msg.Index), - Family: int(msg.Family), - State: int(msg.State), - Type: int(msg.Type), - Flags: int(msg.Flags), - } - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - for _, attr := range attrs { - switch attr.Attr.Type { - case NDA_DST: - neigh.IP = net.IP(attr.Value) - case NDA_LLADDR: - // BUG: Is this a bug in the netlink library? - // #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) - // #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) - attrLen := attr.Attr.Len - unix.SizeofRtAttr - if attrLen == 4 { - neigh.LLIPAddr = net.IP(attr.Value) - } else if attrLen == 16 { - // Can be IPv6 or FireWire HWAddr - link, err := LinkByIndex(neigh.LinkIndex) - if err == nil && link.Attrs().EncapType == "tunnel6" { - neigh.IP = net.IP(attr.Value) - } else { - neigh.HardwareAddr = net.HardwareAddr(attr.Value) - } - } else { - neigh.HardwareAddr = net.HardwareAddr(attr.Value) - } - case NDA_FLAGS_EXT: - neigh.FlagsExt = int(native.Uint32(attr.Value[0:4])) - case NDA_VLAN: - neigh.Vlan = int(native.Uint16(attr.Value[0:2])) - case NDA_VNI: - neigh.VNI = int(native.Uint32(attr.Value[0:4])) - case NDA_MASTER: - neigh.MasterIndex = int(native.Uint32(attr.Value[0:4])) - } - } - - return &neigh, nil -} - -// NeighSubscribe takes a chan down which notifications will be sent -// when neighbors are added or deleted. Close the 'done' chan to stop subscription. -func NeighSubscribe(ch chan<- NeighUpdate, done <-chan struct{}) error { - return neighSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) -} - -// NeighSubscribeAt works like NeighSubscribe plus it allows the caller -// to choose the network namespace in which to subscribe (ns). -func NeighSubscribeAt(ns netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}) error { - return neighSubscribeAt(ns, netns.None(), ch, done, nil, false) -} - -// NeighSubscribeOptions contains a set of options to use with -// NeighSubscribeWithOptions. -type NeighSubscribeOptions struct { - Namespace *netns.NsHandle - ErrorCallback func(error) - ListExisting bool -} - -// NeighSubscribeWithOptions work like NeighSubscribe but enable to -// provide additional options to modify the behavior. Currently, the -// namespace can be provided as well as an error callback. -func NeighSubscribeWithOptions(ch chan<- NeighUpdate, done <-chan struct{}, options NeighSubscribeOptions) error { - if options.Namespace == nil { - none := netns.None() - options.Namespace = &none - } - return neighSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) -} - -func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { - s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH) - makeRequest := func(family int) error { - req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH, - unix.NLM_F_DUMP) - infmsg := nl.NewIfInfomsg(family) - req.AddData(infmsg) - if err := s.Send(req); err != nil { - return err - } - return nil - } - if err != nil { - return err - } - if done != nil { - go func() { - <-done - s.Close() - }() - } - if listExisting { - if err := makeRequest(unix.AF_UNSPEC); err != nil { - return err - } - // We have to wait for NLMSG_DONE before making AF_BRIDGE request - } - go func() { - defer close(ch) - for { - msgs, from, err := s.Receive() - if err != nil { - if cberr != nil { - cberr(err) - } - return - } - if from.Pid != nl.PidKernel { - if cberr != nil { - cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)) - } - continue - } - for _, m := range msgs { - if m.Header.Type == unix.NLMSG_DONE { - if listExisting { - // This will be called after handling AF_UNSPEC - // list request, we have to wait for NLMSG_DONE - // before making another request - if err := makeRequest(unix.AF_BRIDGE); err != nil { - if cberr != nil { - cberr(err) - } - return - } - listExisting = false - } - continue - } - if m.Header.Type == unix.NLMSG_ERROR { - error := int32(native.Uint32(m.Data[0:4])) - if error == 0 { - continue - } - if cberr != nil { - cberr(syscall.Errno(-error)) - } - return - } - neigh, err := NeighDeserialize(m.Data) - if err != nil { - if cberr != nil { - cberr(err) - } - return - } - ch <- NeighUpdate{Type: m.Header.Type, Neigh: *neigh} - } - } - }() - - return nil -} diff --git a/vendor/github.com/tailscale/netlink/netlink.go b/vendor/github.com/tailscale/netlink/netlink.go deleted file mode 100644 index 9cb685d..0000000 --- a/vendor/github.com/tailscale/netlink/netlink.go +++ /dev/null @@ -1,40 +0,0 @@ -// Package netlink provides a simple library for netlink. Netlink is -// the interface a user-space program in linux uses to communicate with -// the kernel. It can be used to add and remove interfaces, set up ip -// addresses and routes, and confiugre ipsec. Netlink communication -// requires elevated privileges, so in most cases this code needs to -// be run as root. The low level primitives for netlink are contained -// in the nl subpackage. This package attempts to provide a high-level -// interface that is loosly modeled on the iproute2 cli. -package netlink - -import ( - "errors" - "net" -) - -var ( - // ErrNotImplemented is returned when a requested feature is not implemented. - ErrNotImplemented = errors.New("not implemented") -) - -// ParseIPNet parses a string in ip/net format and returns a net.IPNet. -// This is valuable because addresses in netlink are often IPNets and -// ParseCIDR returns an IPNet with the IP part set to the base IP of the -// range. -func ParseIPNet(s string) (*net.IPNet, error) { - ip, ipNet, err := net.ParseCIDR(s) - if err != nil { - return nil, err - } - ipNet.IP = ip - return ipNet, nil -} - -// NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128. -func NewIPNet(ip net.IP) *net.IPNet { - if ip.To4() != nil { - return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)} - } - return &net.IPNet{IP: ip, Mask: net.CIDRMask(128, 128)} -} diff --git a/vendor/github.com/tailscale/netlink/netlink_linux.go b/vendor/github.com/tailscale/netlink/netlink_linux.go deleted file mode 100644 index 69d712c..0000000 --- a/vendor/github.com/tailscale/netlink/netlink_linux.go +++ /dev/null @@ -1,11 +0,0 @@ -package netlink - -import "github.com/tailscale/netlink/nl" - -// Family type definitions -const ( - FAMILY_ALL = nl.FAMILY_ALL - FAMILY_V4 = nl.FAMILY_V4 - FAMILY_V6 = nl.FAMILY_V6 - FAMILY_MPLS = nl.FAMILY_MPLS -) diff --git a/vendor/github.com/tailscale/netlink/netlink_unspecified.go b/vendor/github.com/tailscale/netlink/netlink_unspecified.go deleted file mode 100644 index 98d2c0d..0000000 --- a/vendor/github.com/tailscale/netlink/netlink_unspecified.go +++ /dev/null @@ -1,257 +0,0 @@ -// +build !linux - -package netlink - -import "net" - -func LinkSetUp(link Link) error { - return ErrNotImplemented -} - -func LinkSetDown(link Link) error { - return ErrNotImplemented -} - -func LinkSetMTU(link Link, mtu int) error { - return ErrNotImplemented -} - -func LinkSetMaster(link Link, master Link) error { - return ErrNotImplemented -} - -func LinkSetNsPid(link Link, nspid int) error { - return ErrNotImplemented -} - -func LinkSetNsFd(link Link, fd int) error { - return ErrNotImplemented -} - -func LinkSetName(link Link, name string) error { - return ErrNotImplemented -} - -func LinkSetAlias(link Link, name string) error { - return ErrNotImplemented -} - -func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error { - return ErrNotImplemented -} - -func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error { - return ErrNotImplemented -} - -func LinkSetVfVlan(link Link, vf, vlan int) error { - return ErrNotImplemented -} - -func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error { - return ErrNotImplemented -} - -func LinkSetVfTxRate(link Link, vf, rate int) error { - return ErrNotImplemented -} - -func LinkSetVfRate(link Link, vf, minRate, maxRate int) error { - return ErrNotImplemented -} - -func LinkSetNoMaster(link Link) error { - return ErrNotImplemented -} - -func LinkSetMasterByIndex(link Link, masterIndex int) error { - return ErrNotImplemented -} - -func LinkSetXdpFd(link Link, fd int) error { - return ErrNotImplemented -} - -func LinkSetXdpFdWithFlags(link Link, fd, flags int) error { - return ErrNotImplemented -} - -func LinkSetARPOff(link Link) error { - return ErrNotImplemented -} - -func LinkSetARPOn(link Link) error { - return ErrNotImplemented -} - -func LinkByName(name string) (Link, error) { - return nil, ErrNotImplemented -} - -func LinkByAlias(alias string) (Link, error) { - return nil, ErrNotImplemented -} - -func LinkByIndex(index int) (Link, error) { - return nil, ErrNotImplemented -} - -func LinkSetHairpin(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetGuard(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetFastLeave(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetLearning(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetRootBlock(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetFlood(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkSetTxQLen(link Link, qlen int) error { - return ErrNotImplemented -} - -func LinkAdd(link Link) error { - return ErrNotImplemented -} - -func LinkDel(link Link) error { - return ErrNotImplemented -} - -func SetHairpin(link Link, mode bool) error { - return ErrNotImplemented -} - -func SetGuard(link Link, mode bool) error { - return ErrNotImplemented -} - -func SetFastLeave(link Link, mode bool) error { - return ErrNotImplemented -} - -func SetLearning(link Link, mode bool) error { - return ErrNotImplemented -} - -func SetRootBlock(link Link, mode bool) error { - return ErrNotImplemented -} - -func SetFlood(link Link, mode bool) error { - return ErrNotImplemented -} - -func LinkList() ([]Link, error) { - return nil, ErrNotImplemented -} - -func AddrAdd(link Link, addr *Addr) error { - return ErrNotImplemented -} - -func AddrReplace(link Link, addr *Addr) error { - return ErrNotImplemented -} - -func AddrDel(link Link, addr *Addr) error { - return ErrNotImplemented -} - -func AddrList(link Link, family int) ([]Addr, error) { - return nil, ErrNotImplemented -} - -func RouteAdd(route *Route) error { - return ErrNotImplemented -} - -func RouteAppend(route *Route) error { - return ErrNotImplemented -} - -func RouteDel(route *Route) error { - return ErrNotImplemented -} - -func RouteGet(destination net.IP) ([]Route, error) { - return nil, ErrNotImplemented -} - -func RouteList(link Link, family int) ([]Route, error) { - return nil, ErrNotImplemented -} - -func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { - return nil, ErrNotImplemented -} - -func RouteReplace(route *Route) error { - return ErrNotImplemented -} - -func XfrmPolicyAdd(policy *XfrmPolicy) error { - return ErrNotImplemented -} - -func XfrmPolicyDel(policy *XfrmPolicy) error { - return ErrNotImplemented -} - -func XfrmPolicyList(family int) ([]XfrmPolicy, error) { - return nil, ErrNotImplemented -} - -func XfrmStateAdd(policy *XfrmState) error { - return ErrNotImplemented -} - -func XfrmStateDel(policy *XfrmState) error { - return ErrNotImplemented -} - -func XfrmStateList(family int) ([]XfrmState, error) { - return nil, ErrNotImplemented -} - -func NeighAdd(neigh *Neigh) error { - return ErrNotImplemented -} - -func NeighSet(neigh *Neigh) error { - return ErrNotImplemented -} - -func NeighAppend(neigh *Neigh) error { - return ErrNotImplemented -} - -func NeighDel(neigh *Neigh) error { - return ErrNotImplemented -} - -func NeighList(linkIndex, family int) ([]Neigh, error) { - return nil, ErrNotImplemented -} - -func NeighDeserialize(m []byte) (*Neigh, error) { - return nil, ErrNotImplemented -} - -func SocketGet(local, remote net.Addr) (*Socket, error) { - return nil, ErrNotImplemented -} diff --git a/vendor/github.com/tailscale/netlink/netns_linux.go b/vendor/github.com/tailscale/netlink/netns_linux.go deleted file mode 100644 index c2573ca..0000000 --- a/vendor/github.com/tailscale/netlink/netns_linux.go +++ /dev/null @@ -1,141 +0,0 @@ -package netlink - -// Network namespace ID functions -// -// The kernel has a weird concept called the network namespace ID. -// This is different from the file reference in proc (and any bind-mounted -// namespaces, etc.) -// -// Instead, namespaces can be assigned a numeric ID at any time. Once set, -// the ID is fixed. The ID can either be set manually by the user, or -// automatically, triggered by certain kernel actions. The most common kernel -// action that triggers namespace ID creation is moving one end of a veth pair -// in to that namespace. - -import ( - "fmt" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// These can be replaced by the values from sys/unix when it is next released. -const ( - _ = iota - NETNSA_NSID - NETNSA_PID - NETNSA_FD -) - -// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id). -// Returns -1 if the namespace does not have an ID set. -func (h *Handle) GetNetNsIdByPid(pid int) (int, error) { - return h.getNetNsId(NETNSA_PID, uint32(pid)) -} - -// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id). -// Returns -1 if the namespace does not have an ID set. -func GetNetNsIdByPid(pid int) (int, error) { - return pkgHandle.GetNetNsIdByPid(pid) -} - -// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id). -// The ID can only be set for namespaces without an ID already set. -func (h *Handle) SetNetNsIdByPid(pid, nsid int) error { - return h.setNetNsId(NETNSA_PID, uint32(pid), uint32(nsid)) -} - -// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id). -// The ID can only be set for namespaces without an ID already set. -func SetNetNsIdByPid(pid, nsid int) error { - return pkgHandle.SetNetNsIdByPid(pid, nsid) -} - -// GetNetNsIdByFd looks up the network namespace ID for a given fd. -// fd must be an open file descriptor to a namespace file. -// Returns -1 if the namespace does not have an ID set. -func (h *Handle) GetNetNsIdByFd(fd int) (int, error) { - return h.getNetNsId(NETNSA_FD, uint32(fd)) -} - -// GetNetNsIdByFd looks up the network namespace ID for a given fd. -// fd must be an open file descriptor to a namespace file. -// Returns -1 if the namespace does not have an ID set. -func GetNetNsIdByFd(fd int) (int, error) { - return pkgHandle.GetNetNsIdByFd(fd) -} - -// SetNetNSIdByFd sets the ID of the network namespace for a given fd. -// fd must be an open file descriptor to a namespace file. -// The ID can only be set for namespaces without an ID already set. -func (h *Handle) SetNetNsIdByFd(fd, nsid int) error { - return h.setNetNsId(NETNSA_FD, uint32(fd), uint32(nsid)) -} - -// SetNetNSIdByFd sets the ID of the network namespace for a given fd. -// fd must be an open file descriptor to a namespace file. -// The ID can only be set for namespaces without an ID already set. -func SetNetNsIdByFd(fd, nsid int) error { - return pkgHandle.SetNetNsIdByFd(fd, nsid) -} - -// getNetNsId requests the netnsid for a given type-val pair -// type should be either NETNSA_PID or NETNSA_FD -func (h *Handle) getNetNsId(attrType int, val uint32) (int, error) { - req := h.newNetlinkRequest(unix.RTM_GETNSID, unix.NLM_F_REQUEST) - - rtgen := nl.NewRtGenMsg() - req.AddData(rtgen) - - b := make([]byte, 4) - native.PutUint32(b, val) - attr := nl.NewRtAttr(attrType, b) - req.AddData(attr) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID) - - if err != nil { - return 0, err - } - - for _, m := range msgs { - msg := nl.DeserializeRtGenMsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return 0, err - } - - for _, attr := range attrs { - switch attr.Attr.Type { - case NETNSA_NSID: - return int(int32(native.Uint32(attr.Value))), nil - } - } - } - - return 0, fmt.Errorf("unexpected empty result") -} - -// setNetNsId sets the netnsid for a given type-val pair -// type should be either NETNSA_PID or NETNSA_FD -// The ID can only be set for namespaces without an ID already set -func (h *Handle) setNetNsId(attrType int, val uint32, newnsid uint32) error { - req := h.newNetlinkRequest(unix.RTM_NEWNSID, unix.NLM_F_REQUEST|unix.NLM_F_ACK) - - rtgen := nl.NewRtGenMsg() - req.AddData(rtgen) - - b := make([]byte, 4) - native.PutUint32(b, val) - attr := nl.NewRtAttr(attrType, b) - req.AddData(attr) - - b1 := make([]byte, 4) - native.PutUint32(b1, newnsid) - attr1 := nl.NewRtAttr(NETNSA_NSID, b1) - req.AddData(attr1) - - _, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID) - return err -} diff --git a/vendor/github.com/tailscale/netlink/netns_unspecified.go b/vendor/github.com/tailscale/netlink/netns_unspecified.go deleted file mode 100644 index 5c5899e..0000000 --- a/vendor/github.com/tailscale/netlink/netns_unspecified.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build !linux - -package netlink - -func GetNetNsIdByPid(pid int) (int, error) { - return 0, ErrNotImplemented -} - -func SetNetNsIdByPid(pid, nsid int) error { - return ErrNotImplemented -} - -func GetNetNsIdByFd(fd int) (int, error) { - return 0, ErrNotImplemented -} - -func SetNetNsIdByFd(fd, nsid int) error { - return ErrNotImplemented -} diff --git a/vendor/github.com/tailscale/netlink/nl/addr_linux.go b/vendor/github.com/tailscale/netlink/nl/addr_linux.go deleted file mode 100644 index 6bea4ed..0000000 --- a/vendor/github.com/tailscale/netlink/nl/addr_linux.go +++ /dev/null @@ -1,71 +0,0 @@ -package nl - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -type IfAddrmsg struct { - unix.IfAddrmsg -} - -func NewIfAddrmsg(family int) *IfAddrmsg { - return &IfAddrmsg{ - IfAddrmsg: unix.IfAddrmsg{ - Family: uint8(family), - }, - } -} - -// struct ifaddrmsg { -// __u8 ifa_family; -// __u8 ifa_prefixlen; /* The prefix length */ -// __u8 ifa_flags; /* Flags */ -// __u8 ifa_scope; /* Address scope */ -// __u32 ifa_index; /* Link index */ -// }; - -// type IfAddrmsg struct { -// Family uint8 -// Prefixlen uint8 -// Flags uint8 -// Scope uint8 -// Index uint32 -// } -// SizeofIfAddrmsg = 0x8 - -func DeserializeIfAddrmsg(b []byte) *IfAddrmsg { - return (*IfAddrmsg)(unsafe.Pointer(&b[0:unix.SizeofIfAddrmsg][0])) -} - -func (msg *IfAddrmsg) Serialize() []byte { - return (*(*[unix.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:] -} - -func (msg *IfAddrmsg) Len() int { - return unix.SizeofIfAddrmsg -} - -// struct ifa_cacheinfo { -// __u32 ifa_prefered; -// __u32 ifa_valid; -// __u32 cstamp; /* created timestamp, hundredths of seconds */ -// __u32 tstamp; /* updated timestamp, hundredths of seconds */ -// }; - -type IfaCacheInfo struct { - unix.IfaCacheinfo -} - -func (msg *IfaCacheInfo) Len() int { - return unix.SizeofIfaCacheinfo -} - -func DeserializeIfaCacheInfo(b []byte) *IfaCacheInfo { - return (*IfaCacheInfo)(unsafe.Pointer(&b[0:unix.SizeofIfaCacheinfo][0])) -} - -func (msg *IfaCacheInfo) Serialize() []byte { - return (*(*[unix.SizeofIfaCacheinfo]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/bridge_linux.go b/vendor/github.com/tailscale/netlink/nl/bridge_linux.go deleted file mode 100644 index 34e78ba..0000000 --- a/vendor/github.com/tailscale/netlink/nl/bridge_linux.go +++ /dev/null @@ -1,74 +0,0 @@ -package nl - -import ( - "fmt" - "unsafe" -) - -const ( - SizeofBridgeVlanInfo = 0x04 -) - -/* Bridge Flags */ -const ( - BRIDGE_FLAGS_MASTER = iota + 1 /* Bridge command to/from master */ - BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */ -) - -/* Bridge management nested attributes - * [IFLA_AF_SPEC] = { - * [IFLA_BRIDGE_FLAGS] - * [IFLA_BRIDGE_MODE] - * [IFLA_BRIDGE_VLAN_INFO] - * } - */ -const ( - IFLA_BRIDGE_FLAGS = iota - IFLA_BRIDGE_MODE - IFLA_BRIDGE_VLAN_INFO -) - -const ( - BRIDGE_VLAN_INFO_MASTER = 1 << iota - BRIDGE_VLAN_INFO_PVID - BRIDGE_VLAN_INFO_UNTAGGED - BRIDGE_VLAN_INFO_RANGE_BEGIN - BRIDGE_VLAN_INFO_RANGE_END -) - -// struct bridge_vlan_info { -// __u16 flags; -// __u16 vid; -// }; - -type BridgeVlanInfo struct { - Flags uint16 - Vid uint16 -} - -func (b *BridgeVlanInfo) Serialize() []byte { - return (*(*[SizeofBridgeVlanInfo]byte)(unsafe.Pointer(b)))[:] -} - -func DeserializeBridgeVlanInfo(b []byte) *BridgeVlanInfo { - return (*BridgeVlanInfo)(unsafe.Pointer(&b[0:SizeofBridgeVlanInfo][0])) -} - -func (b *BridgeVlanInfo) PortVID() bool { - return b.Flags&BRIDGE_VLAN_INFO_PVID > 0 -} - -func (b *BridgeVlanInfo) EngressUntag() bool { - return b.Flags&BRIDGE_VLAN_INFO_UNTAGGED > 0 -} - -func (b *BridgeVlanInfo) String() string { - return fmt.Sprintf("%+v", *b) -} - -/* New extended info filters for IFLA_EXT_MASK */ -const ( - RTEXT_FILTER_VF = 1 << iota - RTEXT_FILTER_BRVLAN - RTEXT_FILTER_BRVLAN_COMPRESSED -) diff --git a/vendor/github.com/tailscale/netlink/nl/conntrack_linux.go b/vendor/github.com/tailscale/netlink/nl/conntrack_linux.go deleted file mode 100644 index 1836018..0000000 --- a/vendor/github.com/tailscale/netlink/nl/conntrack_linux.go +++ /dev/null @@ -1,219 +0,0 @@ -package nl - -import "unsafe" - -// Track the message sizes for the correct serialization/deserialization -const ( - SizeofNfgenmsg = 4 - SizeofNfattr = 4 - SizeofNfConntrack = 376 - SizeofNfctTupleHead = 52 -) - -var L4ProtoMap = map[uint8]string{ - 6: "tcp", - 17: "udp", -} - -// All the following constants are coming from: -// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink_conntrack.h - -// enum cntl_msg_types { -// IPCTNL_MSG_CT_NEW, -// IPCTNL_MSG_CT_GET, -// IPCTNL_MSG_CT_DELETE, -// IPCTNL_MSG_CT_GET_CTRZERO, -// IPCTNL_MSG_CT_GET_STATS_CPU, -// IPCTNL_MSG_CT_GET_STATS, -// IPCTNL_MSG_CT_GET_DYING, -// IPCTNL_MSG_CT_GET_UNCONFIRMED, -// -// IPCTNL_MSG_MAX -// }; -const ( - IPCTNL_MSG_CT_GET = 1 - IPCTNL_MSG_CT_DELETE = 2 -) - -// #define NFNETLINK_V0 0 -const ( - NFNETLINK_V0 = 0 -) - -const ( - NLA_F_NESTED uint16 = (1 << 15) // #define NLA_F_NESTED (1 << 15) - NLA_F_NET_BYTEORDER uint16 = (1 << 14) // #define NLA_F_NESTED (1 << 14) - NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER) - NLA_ALIGNTO uint16 = 4 // #define NLA_ALIGNTO 4 -) - -// enum ctattr_type { -// CTA_UNSPEC, -// CTA_TUPLE_ORIG, -// CTA_TUPLE_REPLY, -// CTA_STATUS, -// CTA_PROTOINFO, -// CTA_HELP, -// CTA_NAT_SRC, -// #define CTA_NAT CTA_NAT_SRC /* backwards compatibility */ -// CTA_TIMEOUT, -// CTA_MARK, -// CTA_COUNTERS_ORIG, -// CTA_COUNTERS_REPLY, -// CTA_USE, -// CTA_ID, -// CTA_NAT_DST, -// CTA_TUPLE_MASTER, -// CTA_SEQ_ADJ_ORIG, -// CTA_NAT_SEQ_ADJ_ORIG = CTA_SEQ_ADJ_ORIG, -// CTA_SEQ_ADJ_REPLY, -// CTA_NAT_SEQ_ADJ_REPLY = CTA_SEQ_ADJ_REPLY, -// CTA_SECMARK, /* obsolete */ -// CTA_ZONE, -// CTA_SECCTX, -// CTA_TIMESTAMP, -// CTA_MARK_MASK, -// CTA_LABELS, -// CTA_LABELS_MASK, -// __CTA_MAX -// }; -const ( - CTA_TUPLE_ORIG = 1 - CTA_TUPLE_REPLY = 2 - CTA_STATUS = 3 - CTA_PROTOINFO = 4 - CTA_TIMEOUT = 7 - CTA_MARK = 8 - CTA_COUNTERS_ORIG = 9 - CTA_COUNTERS_REPLY = 10 - CTA_USE = 11 - CTA_ID = 12 - CTA_TIMESTAMP = 20 -) - -// enum ctattr_tuple { -// CTA_TUPLE_UNSPEC, -// CTA_TUPLE_IP, -// CTA_TUPLE_PROTO, -// CTA_TUPLE_ZONE, -// __CTA_TUPLE_MAX -// }; -// #define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1) -const ( - CTA_TUPLE_IP = 1 - CTA_TUPLE_PROTO = 2 -) - -// enum ctattr_ip { -// CTA_IP_UNSPEC, -// CTA_IP_V4_SRC, -// CTA_IP_V4_DST, -// CTA_IP_V6_SRC, -// CTA_IP_V6_DST, -// __CTA_IP_MAX -// }; -// #define CTA_IP_MAX (__CTA_IP_MAX - 1) -const ( - CTA_IP_V4_SRC = 1 - CTA_IP_V4_DST = 2 - CTA_IP_V6_SRC = 3 - CTA_IP_V6_DST = 4 -) - -// enum ctattr_l4proto { -// CTA_PROTO_UNSPEC, -// CTA_PROTO_NUM, -// CTA_PROTO_SRC_PORT, -// CTA_PROTO_DST_PORT, -// CTA_PROTO_ICMP_ID, -// CTA_PROTO_ICMP_TYPE, -// CTA_PROTO_ICMP_CODE, -// CTA_PROTO_ICMPV6_ID, -// CTA_PROTO_ICMPV6_TYPE, -// CTA_PROTO_ICMPV6_CODE, -// __CTA_PROTO_MAX -// }; -// #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1) -const ( - CTA_PROTO_NUM = 1 - CTA_PROTO_SRC_PORT = 2 - CTA_PROTO_DST_PORT = 3 -) - -// enum ctattr_protoinfo { -// CTA_PROTOINFO_UNSPEC, -// CTA_PROTOINFO_TCP, -// CTA_PROTOINFO_DCCP, -// CTA_PROTOINFO_SCTP, -// __CTA_PROTOINFO_MAX -// }; -// #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1) -const ( - CTA_PROTOINFO_TCP = 1 -) - -// enum ctattr_protoinfo_tcp { -// CTA_PROTOINFO_TCP_UNSPEC, -// CTA_PROTOINFO_TCP_STATE, -// CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, -// CTA_PROTOINFO_TCP_WSCALE_REPLY, -// CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, -// CTA_PROTOINFO_TCP_FLAGS_REPLY, -// __CTA_PROTOINFO_TCP_MAX -// }; -// #define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1) -const ( - CTA_PROTOINFO_TCP_STATE = 1 - CTA_PROTOINFO_TCP_WSCALE_ORIGINAL = 2 - CTA_PROTOINFO_TCP_WSCALE_REPLY = 3 - CTA_PROTOINFO_TCP_FLAGS_ORIGINAL = 4 - CTA_PROTOINFO_TCP_FLAGS_REPLY = 5 -) - -// enum ctattr_counters { -// CTA_COUNTERS_UNSPEC, -// CTA_COUNTERS_PACKETS, /* 64bit counters */ -// CTA_COUNTERS_BYTES, /* 64bit counters */ -// CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */ -// CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */ -// CTA_COUNTERS_PAD, -// __CTA_COUNTERS_M -// }; -// #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) -const ( - CTA_COUNTERS_PACKETS = 1 - CTA_COUNTERS_BYTES = 2 -) - -// enum CTA TIMESTAMP TLVs -// CTA_TIMESTAMP_START /* 64bit value */ -// CTA_TIMESTAMP_STOP /* 64bit value */ -const ( - CTA_TIMESTAMP_START = 1 - CTA_TIMESTAMP_STOP = 2 -) - -// /* General form of address family dependent message. -// */ -// struct nfgenmsg { -// __u8 nfgen_family; /* AF_xxx */ -// __u8 version; /* nfnetlink version */ -// __be16 res_id; /* resource id */ -// }; -type Nfgenmsg struct { - NfgenFamily uint8 - Version uint8 - ResId uint16 // big endian -} - -func (msg *Nfgenmsg) Len() int { - return SizeofNfgenmsg -} - -func DeserializeNfgenmsg(b []byte) *Nfgenmsg { - return (*Nfgenmsg)(unsafe.Pointer(&b[0:SizeofNfgenmsg][0])) -} - -func (msg *Nfgenmsg) Serialize() []byte { - return (*(*[SizeofNfgenmsg]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/devlink_linux.go b/vendor/github.com/tailscale/netlink/nl/devlink_linux.go deleted file mode 100644 index 2995da4..0000000 --- a/vendor/github.com/tailscale/netlink/nl/devlink_linux.go +++ /dev/null @@ -1,96 +0,0 @@ -package nl - -// All the following constants are coming from: -// https://github.com/torvalds/linux/blob/master/include/uapi/linux/devlink.h - -const ( - GENL_DEVLINK_VERSION = 1 - GENL_DEVLINK_NAME = "devlink" -) - -const ( - DEVLINK_CMD_GET = 1 - DEVLINK_CMD_PORT_GET = 5 - DEVLINK_CMD_PORT_SET = 6 - DEVLINK_CMD_PORT_NEW = 7 - DEVLINK_CMD_PORT_DEL = 8 - DEVLINK_CMD_ESWITCH_GET = 29 - DEVLINK_CMD_ESWITCH_SET = 30 - DEVLINK_CMD_INFO_GET = 51 -) - -const ( - DEVLINK_ATTR_BUS_NAME = 1 - DEVLINK_ATTR_DEV_NAME = 2 - DEVLINK_ATTR_PORT_INDEX = 3 - DEVLINK_ATTR_PORT_TYPE = 4 - DEVLINK_ATTR_PORT_NETDEV_IFINDEX = 6 - DEVLINK_ATTR_PORT_NETDEV_NAME = 7 - DEVLINK_ATTR_PORT_IBDEV_NAME = 8 - DEVLINK_ATTR_ESWITCH_MODE = 25 - DEVLINK_ATTR_ESWITCH_INLINE_MODE = 26 - DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 62 - DEVLINK_ATTR_PORT_FLAVOUR = 77 - DEVLINK_ATTR_INFO_DRIVER_NAME = 98 - DEVLINK_ATTR_INFO_SERIAL_NUMBER = 99 - DEVLINK_ATTR_INFO_VERSION_FIXED = 100 - DEVLINK_ATTR_INFO_VERSION_RUNNING = 101 - DEVLINK_ATTR_INFO_VERSION_STORED = 102 - DEVLINK_ATTR_INFO_VERSION_NAME = 103 - DEVLINK_ATTR_INFO_VERSION_VALUE = 104 - DEVLINK_ATTR_PORT_PCI_PF_NUMBER = 127 - DEVLINK_ATTR_PORT_FUNCTION = 145 - DEVLINK_ATTR_PORT_CONTROLLER_NUMBER = 150 - DEVLINK_ATTR_PORT_PCI_SF_NUMBER = 164 -) - -const ( - DEVLINK_ESWITCH_MODE_LEGACY = 0 - DEVLINK_ESWITCH_MODE_SWITCHDEV = 1 -) - -const ( - DEVLINK_ESWITCH_INLINE_MODE_NONE = 0 - DEVLINK_ESWITCH_INLINE_MODE_LINK = 1 - DEVLINK_ESWITCH_INLINE_MODE_NETWORK = 2 - DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT = 3 -) - -const ( - DEVLINK_ESWITCH_ENCAP_MODE_NONE = 0 - DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1 -) - -const ( - DEVLINK_PORT_FLAVOUR_PHYSICAL = 0 - DEVLINK_PORT_FLAVOUR_CPU = 1 - DEVLINK_PORT_FLAVOUR_DSA = 2 - DEVLINK_PORT_FLAVOUR_PCI_PF = 3 - DEVLINK_PORT_FLAVOUR_PCI_VF = 4 - DEVLINK_PORT_FLAVOUR_VIRTUAL = 5 - DEVLINK_PORT_FLAVOUR_UNUSED = 6 - DEVLINK_PORT_FLAVOUR_PCI_SF = 7 -) - -const ( - DEVLINK_PORT_TYPE_NOTSET = 0 - DEVLINK_PORT_TYPE_AUTO = 1 - DEVLINK_PORT_TYPE_ETH = 2 - DEVLINK_PORT_TYPE_IB = 3 -) - -const ( - DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR = 1 - DEVLINK_PORT_FN_ATTR_STATE = 2 - DEVLINK_PORT_FN_ATTR_OPSTATE = 3 -) - -const ( - DEVLINK_PORT_FN_STATE_INACTIVE = 0 - DEVLINK_PORT_FN_STATE_ACTIVE = 1 -) - -const ( - DEVLINK_PORT_FN_OPSTATE_DETACHED = 0 - DEVLINK_PORT_FN_OPSTATE_ATTACHED = 1 -) diff --git a/vendor/github.com/tailscale/netlink/nl/genetlink_linux.go b/vendor/github.com/tailscale/netlink/nl/genetlink_linux.go deleted file mode 100644 index 81b46f2..0000000 --- a/vendor/github.com/tailscale/netlink/nl/genetlink_linux.go +++ /dev/null @@ -1,89 +0,0 @@ -package nl - -import ( - "unsafe" -) - -const SizeofGenlmsg = 4 - -const ( - GENL_ID_CTRL = 0x10 - GENL_CTRL_VERSION = 2 - GENL_CTRL_NAME = "nlctrl" -) - -const ( - GENL_CTRL_CMD_GETFAMILY = 3 -) - -const ( - GENL_CTRL_ATTR_UNSPEC = iota - GENL_CTRL_ATTR_FAMILY_ID - GENL_CTRL_ATTR_FAMILY_NAME - GENL_CTRL_ATTR_VERSION - GENL_CTRL_ATTR_HDRSIZE - GENL_CTRL_ATTR_MAXATTR - GENL_CTRL_ATTR_OPS - GENL_CTRL_ATTR_MCAST_GROUPS -) - -const ( - GENL_CTRL_ATTR_OP_UNSPEC = iota - GENL_CTRL_ATTR_OP_ID - GENL_CTRL_ATTR_OP_FLAGS -) - -const ( - GENL_ADMIN_PERM = 1 << iota - GENL_CMD_CAP_DO - GENL_CMD_CAP_DUMP - GENL_CMD_CAP_HASPOL -) - -const ( - GENL_CTRL_ATTR_MCAST_GRP_UNSPEC = iota - GENL_CTRL_ATTR_MCAST_GRP_NAME - GENL_CTRL_ATTR_MCAST_GRP_ID -) - -const ( - GENL_GTP_VERSION = 0 - GENL_GTP_NAME = "gtp" -) - -const ( - GENL_GTP_CMD_NEWPDP = iota - GENL_GTP_CMD_DELPDP - GENL_GTP_CMD_GETPDP -) - -const ( - GENL_GTP_ATTR_UNSPEC = iota - GENL_GTP_ATTR_LINK - GENL_GTP_ATTR_VERSION - GENL_GTP_ATTR_TID - GENL_GTP_ATTR_PEER_ADDRESS - GENL_GTP_ATTR_MS_ADDRESS - GENL_GTP_ATTR_FLOW - GENL_GTP_ATTR_NET_NS_FD - GENL_GTP_ATTR_I_TEI - GENL_GTP_ATTR_O_TEI - GENL_GTP_ATTR_PAD -) - -type Genlmsg struct { - Command uint8 - Version uint8 -} - -func (msg *Genlmsg) Len() int { - return SizeofGenlmsg -} - -func DeserializeGenlmsg(b []byte) *Genlmsg { - return (*Genlmsg)(unsafe.Pointer(&b[0:SizeofGenlmsg][0])) -} - -func (msg *Genlmsg) Serialize() []byte { - return (*(*[SizeofGenlmsg]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/ipset_linux.go b/vendor/github.com/tailscale/netlink/nl/ipset_linux.go deleted file mode 100644 index a60b4b0..0000000 --- a/vendor/github.com/tailscale/netlink/nl/ipset_linux.go +++ /dev/null @@ -1,222 +0,0 @@ -package nl - -import ( - "strconv" - - "golang.org/x/sys/unix" -) - -const ( - /* The protocol version */ - IPSET_PROTOCOL = 6 - - /* The max length of strings including NUL: set and type identifiers */ - IPSET_MAXNAMELEN = 32 - - /* The maximum permissible comment length we will accept over netlink */ - IPSET_MAX_COMMENT_SIZE = 255 -) - -const ( - _ = iota - IPSET_CMD_PROTOCOL /* 1: Return protocol version */ - IPSET_CMD_CREATE /* 2: Create a new (empty) set */ - IPSET_CMD_DESTROY /* 3: Destroy a (empty) set */ - IPSET_CMD_FLUSH /* 4: Remove all elements from a set */ - IPSET_CMD_RENAME /* 5: Rename a set */ - IPSET_CMD_SWAP /* 6: Swap two sets */ - IPSET_CMD_LIST /* 7: List sets */ - IPSET_CMD_SAVE /* 8: Save sets */ - IPSET_CMD_ADD /* 9: Add an element to a set */ - IPSET_CMD_DEL /* 10: Delete an element from a set */ - IPSET_CMD_TEST /* 11: Test an element in a set */ - IPSET_CMD_HEADER /* 12: Get set header data only */ - IPSET_CMD_TYPE /* 13: Get set type */ -) - -/* Attributes at command level */ -const ( - _ = iota - IPSET_ATTR_PROTOCOL /* 1: Protocol version */ - IPSET_ATTR_SETNAME /* 2: Name of the set */ - IPSET_ATTR_TYPENAME /* 3: Typename */ - IPSET_ATTR_REVISION /* 4: Settype revision */ - IPSET_ATTR_FAMILY /* 5: Settype family */ - IPSET_ATTR_FLAGS /* 6: Flags at command level */ - IPSET_ATTR_DATA /* 7: Nested attributes */ - IPSET_ATTR_ADT /* 8: Multiple data containers */ - IPSET_ATTR_LINENO /* 9: Restore lineno */ - IPSET_ATTR_PROTOCOL_MIN /* 10: Minimal supported version number */ - - IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME /* Setname at rename/swap */ - IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN /* type rev min */ -) - -/* CADT specific attributes */ -const ( - IPSET_ATTR_IP = 1 - IPSET_ATTR_IP_FROM = 1 - IPSET_ATTR_IP_TO = 2 - IPSET_ATTR_CIDR = 3 - IPSET_ATTR_PORT = 4 - IPSET_ATTR_PORT_FROM = 4 - IPSET_ATTR_PORT_TO = 5 - IPSET_ATTR_TIMEOUT = 6 - IPSET_ATTR_PROTO = 7 - IPSET_ATTR_CADT_FLAGS = 8 - IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO /* 9 */ - IPSET_ATTR_MARK = 10 - IPSET_ATTR_MARKMASK = 11 - - /* Reserve empty slots */ - IPSET_ATTR_CADT_MAX = 16 - - /* Create-only specific attributes */ - IPSET_ATTR_GC = 3 + iota - IPSET_ATTR_HASHSIZE - IPSET_ATTR_MAXELEM - IPSET_ATTR_NETMASK - IPSET_ATTR_PROBES - IPSET_ATTR_RESIZE - IPSET_ATTR_SIZE - - /* Kernel-only */ - IPSET_ATTR_ELEMENTS - IPSET_ATTR_REFERENCES - IPSET_ATTR_MEMSIZE - - SET_ATTR_CREATE_MAX -) - -/* ADT specific attributes */ -const ( - IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + iota + 1 - IPSET_ATTR_NAME - IPSET_ATTR_NAMEREF - IPSET_ATTR_IP2 - IPSET_ATTR_CIDR2 - IPSET_ATTR_IP2_TO - IPSET_ATTR_IFACE - IPSET_ATTR_BYTES - IPSET_ATTR_PACKETS - IPSET_ATTR_COMMENT - IPSET_ATTR_SKBMARK - IPSET_ATTR_SKBPRIO - IPSET_ATTR_SKBQUEUE -) - -/* Flags at CADT attribute level, upper half of cmdattrs */ -const ( - IPSET_FLAG_BIT_BEFORE = 0 - IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE) - IPSET_FLAG_BIT_PHYSDEV = 1 - IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV) - IPSET_FLAG_BIT_NOMATCH = 2 - IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH) - IPSET_FLAG_BIT_WITH_COUNTERS = 3 - IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS) - IPSET_FLAG_BIT_WITH_COMMENT = 4 - IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT) - IPSET_FLAG_BIT_WITH_FORCEADD = 5 - IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD) - IPSET_FLAG_BIT_WITH_SKBINFO = 6 - IPSET_FLAG_WITH_SKBINFO = (1 << IPSET_FLAG_BIT_WITH_SKBINFO) - IPSET_FLAG_CADT_MAX = 15 -) - -const ( - IPSET_ERR_PRIVATE = 4096 + iota - IPSET_ERR_PROTOCOL - IPSET_ERR_FIND_TYPE - IPSET_ERR_MAX_SETS - IPSET_ERR_BUSY - IPSET_ERR_EXIST_SETNAME2 - IPSET_ERR_TYPE_MISMATCH - IPSET_ERR_EXIST - IPSET_ERR_INVALID_CIDR - IPSET_ERR_INVALID_NETMASK - IPSET_ERR_INVALID_FAMILY - IPSET_ERR_TIMEOUT - IPSET_ERR_REFERENCED - IPSET_ERR_IPADDR_IPV4 - IPSET_ERR_IPADDR_IPV6 - IPSET_ERR_COUNTER - IPSET_ERR_COMMENT - IPSET_ERR_INVALID_MARKMASK - IPSET_ERR_SKBINFO - - /* Type specific error codes */ - IPSET_ERR_TYPE_SPECIFIC = 4352 -) - -type IPSetError uintptr - -func (e IPSetError) Error() string { - switch int(e) { - case IPSET_ERR_PRIVATE: - return "private" - case IPSET_ERR_PROTOCOL: - return "invalid protocol" - case IPSET_ERR_FIND_TYPE: - return "invalid type" - case IPSET_ERR_MAX_SETS: - return "max sets reached" - case IPSET_ERR_BUSY: - return "busy" - case IPSET_ERR_EXIST_SETNAME2: - return "exist_setname2" - case IPSET_ERR_TYPE_MISMATCH: - return "type mismatch" - case IPSET_ERR_EXIST: - return "exist" - case IPSET_ERR_INVALID_CIDR: - return "invalid cidr" - case IPSET_ERR_INVALID_NETMASK: - return "invalid netmask" - case IPSET_ERR_INVALID_FAMILY: - return "invalid family" - case IPSET_ERR_TIMEOUT: - return "timeout" - case IPSET_ERR_REFERENCED: - return "referenced" - case IPSET_ERR_IPADDR_IPV4: - return "invalid ipv4 address" - case IPSET_ERR_IPADDR_IPV6: - return "invalid ipv6 address" - case IPSET_ERR_COUNTER: - return "invalid counter" - case IPSET_ERR_COMMENT: - return "invalid comment" - case IPSET_ERR_INVALID_MARKMASK: - return "invalid markmask" - case IPSET_ERR_SKBINFO: - return "skbinfo" - default: - return "errno " + strconv.Itoa(int(e)) - } -} - -func GetIpsetFlags(cmd int) int { - switch cmd { - case IPSET_CMD_CREATE: - return unix.NLM_F_REQUEST | unix.NLM_F_ACK | unix.NLM_F_CREATE - case IPSET_CMD_DESTROY, - IPSET_CMD_FLUSH, - IPSET_CMD_RENAME, - IPSET_CMD_SWAP, - IPSET_CMD_TEST: - return unix.NLM_F_REQUEST | unix.NLM_F_ACK - case IPSET_CMD_LIST, - IPSET_CMD_SAVE: - return unix.NLM_F_REQUEST | unix.NLM_F_ACK | unix.NLM_F_ROOT | unix.NLM_F_MATCH | unix.NLM_F_DUMP - case IPSET_CMD_ADD, - IPSET_CMD_DEL: - return unix.NLM_F_REQUEST | unix.NLM_F_ACK - case IPSET_CMD_HEADER, - IPSET_CMD_TYPE, - IPSET_CMD_PROTOCOL: - return unix.NLM_F_REQUEST - default: - return 0 - } -} diff --git a/vendor/github.com/tailscale/netlink/nl/link_linux.go b/vendor/github.com/tailscale/netlink/nl/link_linux.go deleted file mode 100644 index e10edbc..0000000 --- a/vendor/github.com/tailscale/netlink/nl/link_linux.go +++ /dev/null @@ -1,720 +0,0 @@ -package nl - -import ( - "bytes" - "encoding/binary" - "unsafe" -) - -const ( - DEFAULT_CHANGE = 0xFFFFFFFF -) - -const ( - IFLA_INFO_UNSPEC = iota - IFLA_INFO_KIND - IFLA_INFO_DATA - IFLA_INFO_XSTATS - IFLA_INFO_SLAVE_KIND - IFLA_INFO_SLAVE_DATA - IFLA_INFO_MAX = IFLA_INFO_SLAVE_DATA -) - -const ( - IFLA_VLAN_UNSPEC = iota - IFLA_VLAN_ID - IFLA_VLAN_FLAGS - IFLA_VLAN_EGRESS_QOS - IFLA_VLAN_INGRESS_QOS - IFLA_VLAN_PROTOCOL - IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL -) - -const ( - VETH_INFO_UNSPEC = iota - VETH_INFO_PEER - VETH_INFO_MAX = VETH_INFO_PEER -) - -const ( - IFLA_VXLAN_UNSPEC = iota - IFLA_VXLAN_ID - IFLA_VXLAN_GROUP - IFLA_VXLAN_LINK - IFLA_VXLAN_LOCAL - IFLA_VXLAN_TTL - IFLA_VXLAN_TOS - IFLA_VXLAN_LEARNING - IFLA_VXLAN_AGEING - IFLA_VXLAN_LIMIT - IFLA_VXLAN_PORT_RANGE - IFLA_VXLAN_PROXY - IFLA_VXLAN_RSC - IFLA_VXLAN_L2MISS - IFLA_VXLAN_L3MISS - IFLA_VXLAN_PORT - IFLA_VXLAN_GROUP6 - IFLA_VXLAN_LOCAL6 - IFLA_VXLAN_UDP_CSUM - IFLA_VXLAN_UDP_ZERO_CSUM6_TX - IFLA_VXLAN_UDP_ZERO_CSUM6_RX - IFLA_VXLAN_REMCSUM_TX - IFLA_VXLAN_REMCSUM_RX - IFLA_VXLAN_GBP - IFLA_VXLAN_REMCSUM_NOPARTIAL - IFLA_VXLAN_FLOWBASED - IFLA_VXLAN_MAX = IFLA_VXLAN_FLOWBASED -) - -const ( - BRIDGE_MODE_UNSPEC = iota - BRIDGE_MODE_HAIRPIN -) - -const ( - IFLA_BRPORT_UNSPEC = iota - IFLA_BRPORT_STATE - IFLA_BRPORT_PRIORITY - IFLA_BRPORT_COST - IFLA_BRPORT_MODE - IFLA_BRPORT_GUARD - IFLA_BRPORT_PROTECT - IFLA_BRPORT_FAST_LEAVE - IFLA_BRPORT_LEARNING - IFLA_BRPORT_UNICAST_FLOOD - IFLA_BRPORT_PROXYARP - IFLA_BRPORT_LEARNING_SYNC - IFLA_BRPORT_PROXYARP_WIFI - IFLA_BRPORT_MAX = IFLA_BRPORT_PROXYARP_WIFI -) - -const ( - IFLA_IPVLAN_UNSPEC = iota - IFLA_IPVLAN_MODE - IFLA_IPVLAN_FLAG - IFLA_IPVLAN_MAX = IFLA_IPVLAN_FLAG -) - -const ( - IFLA_MACVLAN_UNSPEC = iota - IFLA_MACVLAN_MODE - IFLA_MACVLAN_FLAGS - IFLA_MACVLAN_MACADDR_MODE - IFLA_MACVLAN_MACADDR - IFLA_MACVLAN_MACADDR_DATA - IFLA_MACVLAN_MACADDR_COUNT - IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS -) - -const ( - MACVLAN_MODE_PRIVATE = 1 - MACVLAN_MODE_VEPA = 2 - MACVLAN_MODE_BRIDGE = 4 - MACVLAN_MODE_PASSTHRU = 8 - MACVLAN_MODE_SOURCE = 16 -) - -const ( - MACVLAN_MACADDR_ADD = iota - MACVLAN_MACADDR_DEL - MACVLAN_MACADDR_FLUSH - MACVLAN_MACADDR_SET -) - -const ( - IFLA_BOND_UNSPEC = iota - IFLA_BOND_MODE - IFLA_BOND_ACTIVE_SLAVE - IFLA_BOND_MIIMON - IFLA_BOND_UPDELAY - IFLA_BOND_DOWNDELAY - IFLA_BOND_USE_CARRIER - IFLA_BOND_ARP_INTERVAL - IFLA_BOND_ARP_IP_TARGET - IFLA_BOND_ARP_VALIDATE - IFLA_BOND_ARP_ALL_TARGETS - IFLA_BOND_PRIMARY - IFLA_BOND_PRIMARY_RESELECT - IFLA_BOND_FAIL_OVER_MAC - IFLA_BOND_XMIT_HASH_POLICY - IFLA_BOND_RESEND_IGMP - IFLA_BOND_NUM_PEER_NOTIF - IFLA_BOND_ALL_SLAVES_ACTIVE - IFLA_BOND_MIN_LINKS - IFLA_BOND_LP_INTERVAL - IFLA_BOND_PACKETS_PER_SLAVE - IFLA_BOND_AD_LACP_RATE - IFLA_BOND_AD_SELECT - IFLA_BOND_AD_INFO - IFLA_BOND_AD_ACTOR_SYS_PRIO - IFLA_BOND_AD_USER_PORT_KEY - IFLA_BOND_AD_ACTOR_SYSTEM - IFLA_BOND_TLB_DYNAMIC_LB -) - -const ( - IFLA_BOND_AD_INFO_UNSPEC = iota - IFLA_BOND_AD_INFO_AGGREGATOR - IFLA_BOND_AD_INFO_NUM_PORTS - IFLA_BOND_AD_INFO_ACTOR_KEY - IFLA_BOND_AD_INFO_PARTNER_KEY - IFLA_BOND_AD_INFO_PARTNER_MAC -) - -const ( - IFLA_BOND_SLAVE_UNSPEC = iota - IFLA_BOND_SLAVE_STATE - IFLA_BOND_SLAVE_MII_STATUS - IFLA_BOND_SLAVE_LINK_FAILURE_COUNT - IFLA_BOND_SLAVE_PERM_HWADDR - IFLA_BOND_SLAVE_QUEUE_ID - IFLA_BOND_SLAVE_AD_AGGREGATOR_ID - IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE - IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE -) - -const ( - IFLA_GENEVE_UNSPEC = iota - IFLA_GENEVE_ID // vni - IFLA_GENEVE_REMOTE - IFLA_GENEVE_TTL - IFLA_GENEVE_TOS - IFLA_GENEVE_PORT // destination port - IFLA_GENEVE_COLLECT_METADATA - IFLA_GENEVE_REMOTE6 - IFLA_GENEVE_UDP_CSUM - IFLA_GENEVE_UDP_ZERO_CSUM6_TX - IFLA_GENEVE_UDP_ZERO_CSUM6_RX - IFLA_GENEVE_LABEL - IFLA_GENEVE_MAX = IFLA_GENEVE_LABEL -) - -const ( - IFLA_GRE_UNSPEC = iota - IFLA_GRE_LINK - IFLA_GRE_IFLAGS - IFLA_GRE_OFLAGS - IFLA_GRE_IKEY - IFLA_GRE_OKEY - IFLA_GRE_LOCAL - IFLA_GRE_REMOTE - IFLA_GRE_TTL - IFLA_GRE_TOS - IFLA_GRE_PMTUDISC - IFLA_GRE_ENCAP_LIMIT - IFLA_GRE_FLOWINFO - IFLA_GRE_FLAGS - IFLA_GRE_ENCAP_TYPE - IFLA_GRE_ENCAP_FLAGS - IFLA_GRE_ENCAP_SPORT - IFLA_GRE_ENCAP_DPORT - IFLA_GRE_COLLECT_METADATA - IFLA_GRE_MAX = IFLA_GRE_COLLECT_METADATA -) - -const ( - GRE_CSUM = 0x8000 - GRE_ROUTING = 0x4000 - GRE_KEY = 0x2000 - GRE_SEQ = 0x1000 - GRE_STRICT = 0x0800 - GRE_REC = 0x0700 - GRE_FLAGS = 0x00F8 - GRE_VERSION = 0x0007 -) - -const ( - IFLA_VF_INFO_UNSPEC = iota - IFLA_VF_INFO - IFLA_VF_INFO_MAX = IFLA_VF_INFO -) - -const ( - IFLA_VF_UNSPEC = iota - IFLA_VF_MAC /* Hardware queue specific attributes */ - IFLA_VF_VLAN - IFLA_VF_TX_RATE /* Max TX Bandwidth Allocation */ - IFLA_VF_SPOOFCHK /* Spoof Checking on/off switch */ - IFLA_VF_LINK_STATE /* link state enable/disable/auto switch */ - IFLA_VF_RATE /* Min and Max TX Bandwidth Allocation */ - IFLA_VF_RSS_QUERY_EN /* RSS Redirection Table and Hash Key query - * on/off switch - */ - IFLA_VF_STATS /* network device statistics */ - IFLA_VF_TRUST /* Trust state of VF */ - IFLA_VF_IB_NODE_GUID /* VF Infiniband node GUID */ - IFLA_VF_IB_PORT_GUID /* VF Infiniband port GUID */ - IFLA_VF_MAX = IFLA_VF_IB_PORT_GUID -) - -const ( - IFLA_VF_LINK_STATE_AUTO = iota /* link state of the uplink */ - IFLA_VF_LINK_STATE_ENABLE /* link always up */ - IFLA_VF_LINK_STATE_DISABLE /* link always down */ - IFLA_VF_LINK_STATE_MAX = IFLA_VF_LINK_STATE_DISABLE -) - -const ( - IFLA_VF_STATS_RX_PACKETS = iota - IFLA_VF_STATS_TX_PACKETS - IFLA_VF_STATS_RX_BYTES - IFLA_VF_STATS_TX_BYTES - IFLA_VF_STATS_BROADCAST - IFLA_VF_STATS_MULTICAST - IFLA_VF_STATS_RX_DROPPED - IFLA_VF_STATS_TX_DROPPED - IFLA_VF_STATS_MAX = IFLA_VF_STATS_TX_DROPPED -) - -const ( - SizeofVfMac = 0x24 - SizeofVfVlan = 0x0c - SizeofVfTxRate = 0x08 - SizeofVfRate = 0x0c - SizeofVfSpoofchk = 0x08 - SizeofVfLinkState = 0x08 - SizeofVfRssQueryEn = 0x08 - SizeofVfTrust = 0x08 - SizeofVfGUID = 0x10 -) - -// struct ifla_vf_mac { -// __u32 vf; -// __u8 mac[32]; /* MAX_ADDR_LEN */ -// }; - -type VfMac struct { - Vf uint32 - Mac [32]byte -} - -func (msg *VfMac) Len() int { - return SizeofVfMac -} - -func DeserializeVfMac(b []byte) *VfMac { - return (*VfMac)(unsafe.Pointer(&b[0:SizeofVfMac][0])) -} - -func (msg *VfMac) Serialize() []byte { - return (*(*[SizeofVfMac]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_vlan { -// __u32 vf; -// __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ -// __u32 qos; -// }; - -type VfVlan struct { - Vf uint32 - Vlan uint32 - Qos uint32 -} - -func (msg *VfVlan) Len() int { - return SizeofVfVlan -} - -func DeserializeVfVlan(b []byte) *VfVlan { - return (*VfVlan)(unsafe.Pointer(&b[0:SizeofVfVlan][0])) -} - -func (msg *VfVlan) Serialize() []byte { - return (*(*[SizeofVfVlan]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_tx_rate { -// __u32 vf; -// __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ -// }; - -type VfTxRate struct { - Vf uint32 - Rate uint32 -} - -func (msg *VfTxRate) Len() int { - return SizeofVfTxRate -} - -func DeserializeVfTxRate(b []byte) *VfTxRate { - return (*VfTxRate)(unsafe.Pointer(&b[0:SizeofVfTxRate][0])) -} - -func (msg *VfTxRate) Serialize() []byte { - return (*(*[SizeofVfTxRate]byte)(unsafe.Pointer(msg)))[:] -} - -//struct ifla_vf_stats { -// __u64 rx_packets; -// __u64 tx_packets; -// __u64 rx_bytes; -// __u64 tx_bytes; -// __u64 broadcast; -// __u64 multicast; -//}; - -type VfStats struct { - RxPackets uint64 - TxPackets uint64 - RxBytes uint64 - TxBytes uint64 - Multicast uint64 - Broadcast uint64 - RxDropped uint64 - TxDropped uint64 -} - -func DeserializeVfStats(b []byte) VfStats { - var vfstat VfStats - stats, err := ParseRouteAttr(b) - if err != nil { - return vfstat - } - var valueVar uint64 - for _, stat := range stats { - if err := binary.Read(bytes.NewBuffer(stat.Value), NativeEndian(), &valueVar); err != nil { - break - } - switch stat.Attr.Type { - case IFLA_VF_STATS_RX_PACKETS: - vfstat.RxPackets = valueVar - case IFLA_VF_STATS_TX_PACKETS: - vfstat.TxPackets = valueVar - case IFLA_VF_STATS_RX_BYTES: - vfstat.RxBytes = valueVar - case IFLA_VF_STATS_TX_BYTES: - vfstat.TxBytes = valueVar - case IFLA_VF_STATS_MULTICAST: - vfstat.Multicast = valueVar - case IFLA_VF_STATS_BROADCAST: - vfstat.Broadcast = valueVar - case IFLA_VF_STATS_RX_DROPPED: - vfstat.RxDropped = valueVar - case IFLA_VF_STATS_TX_DROPPED: - vfstat.TxDropped = valueVar - } - } - return vfstat -} - -// struct ifla_vf_rate { -// __u32 vf; -// __u32 min_tx_rate; /* Min Bandwidth in Mbps */ -// __u32 max_tx_rate; /* Max Bandwidth in Mbps */ -// }; - -type VfRate struct { - Vf uint32 - MinTxRate uint32 - MaxTxRate uint32 -} - -func (msg *VfRate) Len() int { - return SizeofVfRate -} - -func DeserializeVfRate(b []byte) *VfRate { - return (*VfRate)(unsafe.Pointer(&b[0:SizeofVfRate][0])) -} - -func (msg *VfRate) Serialize() []byte { - return (*(*[SizeofVfRate]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_spoofchk { -// __u32 vf; -// __u32 setting; -// }; - -type VfSpoofchk struct { - Vf uint32 - Setting uint32 -} - -func (msg *VfSpoofchk) Len() int { - return SizeofVfSpoofchk -} - -func DeserializeVfSpoofchk(b []byte) *VfSpoofchk { - return (*VfSpoofchk)(unsafe.Pointer(&b[0:SizeofVfSpoofchk][0])) -} - -func (msg *VfSpoofchk) Serialize() []byte { - return (*(*[SizeofVfSpoofchk]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_link_state { -// __u32 vf; -// __u32 link_state; -// }; - -type VfLinkState struct { - Vf uint32 - LinkState uint32 -} - -func (msg *VfLinkState) Len() int { - return SizeofVfLinkState -} - -func DeserializeVfLinkState(b []byte) *VfLinkState { - return (*VfLinkState)(unsafe.Pointer(&b[0:SizeofVfLinkState][0])) -} - -func (msg *VfLinkState) Serialize() []byte { - return (*(*[SizeofVfLinkState]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_rss_query_en { -// __u32 vf; -// __u32 setting; -// }; - -type VfRssQueryEn struct { - Vf uint32 - Setting uint32 -} - -func (msg *VfRssQueryEn) Len() int { - return SizeofVfRssQueryEn -} - -func DeserializeVfRssQueryEn(b []byte) *VfRssQueryEn { - return (*VfRssQueryEn)(unsafe.Pointer(&b[0:SizeofVfRssQueryEn][0])) -} - -func (msg *VfRssQueryEn) Serialize() []byte { - return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_trust { -// __u32 vf; -// __u32 setting; -// }; - -type VfTrust struct { - Vf uint32 - Setting uint32 -} - -func (msg *VfTrust) Len() int { - return SizeofVfTrust -} - -func DeserializeVfTrust(b []byte) *VfTrust { - return (*VfTrust)(unsafe.Pointer(&b[0:SizeofVfTrust][0])) -} - -func (msg *VfTrust) Serialize() []byte { - return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:] -} - -// struct ifla_vf_guid { -// __u32 vf; -// __u32 rsvd; -// __u64 guid; -// }; - -type VfGUID struct { - Vf uint32 - Rsvd uint32 - GUID uint64 -} - -func (msg *VfGUID) Len() int { - return SizeofVfGUID -} - -func DeserializeVfGUID(b []byte) *VfGUID { - return (*VfGUID)(unsafe.Pointer(&b[0:SizeofVfGUID][0])) -} - -func (msg *VfGUID) Serialize() []byte { - return (*(*[SizeofVfGUID]byte)(unsafe.Pointer(msg)))[:] -} - -const ( - XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota - XDP_FLAGS_SKB_MODE - XDP_FLAGS_DRV_MODE - XDP_FLAGS_MASK = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE -) - -const ( - IFLA_XDP_UNSPEC = iota - IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */ - IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */ - IFLA_XDP_FLAGS /* xdp prog related flags */ - IFLA_XDP_PROG_ID /* xdp prog id */ - IFLA_XDP_MAX = IFLA_XDP_PROG_ID -) - -// XDP program attach mode (used as dump value for IFLA_XDP_ATTACHED) -const ( - XDP_ATTACHED_NONE = iota - XDP_ATTACHED_DRV - XDP_ATTACHED_SKB - XDP_ATTACHED_HW -) - -const ( - IFLA_IPTUN_UNSPEC = iota - IFLA_IPTUN_LINK - IFLA_IPTUN_LOCAL - IFLA_IPTUN_REMOTE - IFLA_IPTUN_TTL - IFLA_IPTUN_TOS - IFLA_IPTUN_ENCAP_LIMIT - IFLA_IPTUN_FLOWINFO - IFLA_IPTUN_FLAGS - IFLA_IPTUN_PROTO - IFLA_IPTUN_PMTUDISC - IFLA_IPTUN_6RD_PREFIX - IFLA_IPTUN_6RD_RELAY_PREFIX - IFLA_IPTUN_6RD_PREFIXLEN - IFLA_IPTUN_6RD_RELAY_PREFIXLEN - IFLA_IPTUN_ENCAP_TYPE - IFLA_IPTUN_ENCAP_FLAGS - IFLA_IPTUN_ENCAP_SPORT - IFLA_IPTUN_ENCAP_DPORT - IFLA_IPTUN_COLLECT_METADATA - IFLA_IPTUN_MAX = IFLA_IPTUN_COLLECT_METADATA -) - -const ( - IFLA_VTI_UNSPEC = iota - IFLA_VTI_LINK - IFLA_VTI_IKEY - IFLA_VTI_OKEY - IFLA_VTI_LOCAL - IFLA_VTI_REMOTE - IFLA_VTI_MAX = IFLA_VTI_REMOTE -) - -const ( - IFLA_VRF_UNSPEC = iota - IFLA_VRF_TABLE -) - -const ( - IFLA_BR_UNSPEC = iota - IFLA_BR_FORWARD_DELAY - IFLA_BR_HELLO_TIME - IFLA_BR_MAX_AGE - IFLA_BR_AGEING_TIME - IFLA_BR_STP_STATE - IFLA_BR_PRIORITY - IFLA_BR_VLAN_FILTERING - IFLA_BR_VLAN_PROTOCOL - IFLA_BR_GROUP_FWD_MASK - IFLA_BR_ROOT_ID - IFLA_BR_BRIDGE_ID - IFLA_BR_ROOT_PORT - IFLA_BR_ROOT_PATH_COST - IFLA_BR_TOPOLOGY_CHANGE - IFLA_BR_TOPOLOGY_CHANGE_DETECTED - IFLA_BR_HELLO_TIMER - IFLA_BR_TCN_TIMER - IFLA_BR_TOPOLOGY_CHANGE_TIMER - IFLA_BR_GC_TIMER - IFLA_BR_GROUP_ADDR - IFLA_BR_FDB_FLUSH - IFLA_BR_MCAST_ROUTER - IFLA_BR_MCAST_SNOOPING - IFLA_BR_MCAST_QUERY_USE_IFADDR - IFLA_BR_MCAST_QUERIER - IFLA_BR_MCAST_HASH_ELASTICITY - IFLA_BR_MCAST_HASH_MAX - IFLA_BR_MCAST_LAST_MEMBER_CNT - IFLA_BR_MCAST_STARTUP_QUERY_CNT - IFLA_BR_MCAST_LAST_MEMBER_INTVL - IFLA_BR_MCAST_MEMBERSHIP_INTVL - IFLA_BR_MCAST_QUERIER_INTVL - IFLA_BR_MCAST_QUERY_INTVL - IFLA_BR_MCAST_QUERY_RESPONSE_INTVL - IFLA_BR_MCAST_STARTUP_QUERY_INTVL - IFLA_BR_NF_CALL_IPTABLES - IFLA_BR_NF_CALL_IP6TABLES - IFLA_BR_NF_CALL_ARPTABLES - IFLA_BR_VLAN_DEFAULT_PVID - IFLA_BR_PAD - IFLA_BR_VLAN_STATS_ENABLED - IFLA_BR_MCAST_STATS_ENABLED - IFLA_BR_MCAST_IGMP_VERSION - IFLA_BR_MCAST_MLD_VERSION - IFLA_BR_MAX = IFLA_BR_MCAST_MLD_VERSION -) - -const ( - IFLA_GTP_UNSPEC = iota - IFLA_GTP_FD0 - IFLA_GTP_FD1 - IFLA_GTP_PDP_HASHSIZE - IFLA_GTP_ROLE -) - -const ( - GTP_ROLE_GGSN = iota - GTP_ROLE_SGSN -) - -const ( - IFLA_XFRM_UNSPEC = iota - IFLA_XFRM_LINK - IFLA_XFRM_IF_ID - - IFLA_XFRM_MAX = iota - 1 -) - -const ( - IFLA_TUN_UNSPEC = iota - IFLA_TUN_OWNER - IFLA_TUN_GROUP - IFLA_TUN_TYPE - IFLA_TUN_PI - IFLA_TUN_VNET_HDR - IFLA_TUN_PERSIST - IFLA_TUN_MULTI_QUEUE - IFLA_TUN_NUM_QUEUES - IFLA_TUN_NUM_DISABLED_QUEUES - IFLA_TUN_MAX = IFLA_TUN_NUM_DISABLED_QUEUES -) - -const ( - IFLA_IPOIB_UNSPEC = iota - IFLA_IPOIB_PKEY - IFLA_IPOIB_MODE - IFLA_IPOIB_UMCAST - IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST -) - -const ( - IFLA_CAN_UNSPEC = iota - IFLA_CAN_BITTIMING - IFLA_CAN_BITTIMING_CONST - IFLA_CAN_CLOCK - IFLA_CAN_STATE - IFLA_CAN_CTRLMODE - IFLA_CAN_RESTART_MS - IFLA_CAN_RESTART - IFLA_CAN_BERR_COUNTER - IFLA_CAN_DATA_BITTIMING - IFLA_CAN_DATA_BITTIMING_CONST - IFLA_CAN_TERMINATION - IFLA_CAN_TERMINATION_CONST - IFLA_CAN_BITRATE_CONST - IFLA_CAN_DATA_BITRATE_CONST - IFLA_CAN_BITRATE_MAX - IFLA_CAN_MAX = IFLA_CAN_BITRATE_MAX -) - -const ( - IFLA_BAREUDP_UNSPEC = iota - IFLA_BAREUDP_PORT - IFLA_BAREUDP_ETHERTYPE - IFLA_BAREUDP_SRCPORT_MIN - IFLA_BAREUDP_MULTIPROTO_MODE - IFLA_BAREUDP_MAX = IFLA_BAREUDP_MULTIPROTO_MODE -) diff --git a/vendor/github.com/tailscale/netlink/nl/lwt_linux.go b/vendor/github.com/tailscale/netlink/nl/lwt_linux.go deleted file mode 100644 index bafd593..0000000 --- a/vendor/github.com/tailscale/netlink/nl/lwt_linux.go +++ /dev/null @@ -1,29 +0,0 @@ -package nl - -const ( - LWT_BPF_PROG_UNSPEC = iota - LWT_BPF_PROG_FD - LWT_BPF_PROG_NAME - __LWT_BPF_PROG_MAX -) - -const ( - LWT_BPF_PROG_MAX = __LWT_BPF_PROG_MAX - 1 -) - -const ( - LWT_BPF_UNSPEC = iota - LWT_BPF_IN - LWT_BPF_OUT - LWT_BPF_XMIT - LWT_BPF_XMIT_HEADROOM - __LWT_BPF_MAX -) - -const ( - LWT_BPF_MAX = __LWT_BPF_MAX - 1 -) - -const ( - LWT_BPF_MAX_HEADROOM = 256 -) diff --git a/vendor/github.com/tailscale/netlink/nl/mpls_linux.go b/vendor/github.com/tailscale/netlink/nl/mpls_linux.go deleted file mode 100644 index 3915b7e..0000000 --- a/vendor/github.com/tailscale/netlink/nl/mpls_linux.go +++ /dev/null @@ -1,36 +0,0 @@ -package nl - -import "encoding/binary" - -const ( - MPLS_LS_LABEL_SHIFT = 12 - MPLS_LS_S_SHIFT = 8 -) - -func EncodeMPLSStack(labels ...int) []byte { - b := make([]byte, 4*len(labels)) - for idx, label := range labels { - l := label << MPLS_LS_LABEL_SHIFT - if idx == len(labels)-1 { - l |= 1 << MPLS_LS_S_SHIFT - } - binary.BigEndian.PutUint32(b[idx*4:], uint32(l)) - } - return b -} - -func DecodeMPLSStack(buf []byte) []int { - if len(buf)%4 != 0 { - return nil - } - stack := make([]int, 0, len(buf)/4) - for len(buf) > 0 { - l := binary.BigEndian.Uint32(buf[:4]) - buf = buf[4:] - stack = append(stack, int(l)>>MPLS_LS_LABEL_SHIFT) - if (l>>MPLS_LS_S_SHIFT)&1 > 0 { - break - } - } - return stack -} diff --git a/vendor/github.com/tailscale/netlink/nl/nl_linux.go b/vendor/github.com/tailscale/netlink/nl/nl_linux.go deleted file mode 100644 index dcd4b94..0000000 --- a/vendor/github.com/tailscale/netlink/nl/nl_linux.go +++ /dev/null @@ -1,791 +0,0 @@ -// Package nl has low level primitives for making Netlink calls. -package nl - -import ( - "bytes" - "encoding/binary" - "fmt" - "net" - "runtime" - "sync" - "sync/atomic" - "syscall" - "unsafe" - - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -const ( - // Family type definitions - FAMILY_ALL = unix.AF_UNSPEC - FAMILY_V4 = unix.AF_INET - FAMILY_V6 = unix.AF_INET6 - FAMILY_MPLS = unix.AF_MPLS - // Arbitrary set value (greater than default 4k) to allow receiving - // from kernel more verbose messages e.g. for statistics, - // tc rules or filters, or other more memory requiring data. - RECEIVE_BUFFER_SIZE = 65536 - // Kernel netlink pid - PidKernel uint32 = 0 -) - -// SupportedNlFamilies contains the list of netlink families this netlink package supports -var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETLINK_NETFILTER} - -var nextSeqNr uint32 - -// Default netlink socket timeout, 60s -var SocketTimeoutTv = unix.Timeval{Sec: 60, Usec: 0} - -// GetIPFamily returns the family type of a net.IP. -func GetIPFamily(ip net.IP) int { - if len(ip) <= net.IPv4len { - return FAMILY_V4 - } - if ip.To4() != nil { - return FAMILY_V4 - } - return FAMILY_V6 -} - -var nativeEndian binary.ByteOrder - -// NativeEndian gets native endianness for the system -func NativeEndian() binary.ByteOrder { - if nativeEndian == nil { - var x uint32 = 0x01020304 - if *(*byte)(unsafe.Pointer(&x)) == 0x01 { - nativeEndian = binary.BigEndian - } else { - nativeEndian = binary.LittleEndian - } - } - return nativeEndian -} - -// Byte swap a 16 bit value if we aren't big endian -func Swap16(i uint16) uint16 { - if NativeEndian() == binary.BigEndian { - return i - } - return (i&0xff00)>>8 | (i&0xff)<<8 -} - -// Byte swap a 32 bit value if aren't big endian -func Swap32(i uint32) uint32 { - if NativeEndian() == binary.BigEndian { - return i - } - return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24 -} - -type NetlinkRequestData interface { - Len() int - Serialize() []byte -} - -// IfInfomsg is related to links, but it is used for list requests as well -type IfInfomsg struct { - unix.IfInfomsg -} - -// Create an IfInfomsg with family specified -func NewIfInfomsg(family int) *IfInfomsg { - return &IfInfomsg{ - IfInfomsg: unix.IfInfomsg{ - Family: uint8(family), - }, - } -} - -func DeserializeIfInfomsg(b []byte) *IfInfomsg { - return (*IfInfomsg)(unsafe.Pointer(&b[0:unix.SizeofIfInfomsg][0])) -} - -func (msg *IfInfomsg) Serialize() []byte { - return (*(*[unix.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:] -} - -func (msg *IfInfomsg) Len() int { - return unix.SizeofIfInfomsg -} - -func (msg *IfInfomsg) EncapType() string { - switch msg.Type { - case 0: - return "generic" - case unix.ARPHRD_ETHER: - return "ether" - case unix.ARPHRD_EETHER: - return "eether" - case unix.ARPHRD_AX25: - return "ax25" - case unix.ARPHRD_PRONET: - return "pronet" - case unix.ARPHRD_CHAOS: - return "chaos" - case unix.ARPHRD_IEEE802: - return "ieee802" - case unix.ARPHRD_ARCNET: - return "arcnet" - case unix.ARPHRD_APPLETLK: - return "atalk" - case unix.ARPHRD_DLCI: - return "dlci" - case unix.ARPHRD_ATM: - return "atm" - case unix.ARPHRD_METRICOM: - return "metricom" - case unix.ARPHRD_IEEE1394: - return "ieee1394" - case unix.ARPHRD_INFINIBAND: - return "infiniband" - case unix.ARPHRD_SLIP: - return "slip" - case unix.ARPHRD_CSLIP: - return "cslip" - case unix.ARPHRD_SLIP6: - return "slip6" - case unix.ARPHRD_CSLIP6: - return "cslip6" - case unix.ARPHRD_RSRVD: - return "rsrvd" - case unix.ARPHRD_ADAPT: - return "adapt" - case unix.ARPHRD_ROSE: - return "rose" - case unix.ARPHRD_X25: - return "x25" - case unix.ARPHRD_HWX25: - return "hwx25" - case unix.ARPHRD_PPP: - return "ppp" - case unix.ARPHRD_HDLC: - return "hdlc" - case unix.ARPHRD_LAPB: - return "lapb" - case unix.ARPHRD_DDCMP: - return "ddcmp" - case unix.ARPHRD_RAWHDLC: - return "rawhdlc" - case unix.ARPHRD_TUNNEL: - return "ipip" - case unix.ARPHRD_TUNNEL6: - return "tunnel6" - case unix.ARPHRD_FRAD: - return "frad" - case unix.ARPHRD_SKIP: - return "skip" - case unix.ARPHRD_LOOPBACK: - return "loopback" - case unix.ARPHRD_LOCALTLK: - return "ltalk" - case unix.ARPHRD_FDDI: - return "fddi" - case unix.ARPHRD_BIF: - return "bif" - case unix.ARPHRD_SIT: - return "sit" - case unix.ARPHRD_IPDDP: - return "ip/ddp" - case unix.ARPHRD_IPGRE: - return "gre" - case unix.ARPHRD_PIMREG: - return "pimreg" - case unix.ARPHRD_HIPPI: - return "hippi" - case unix.ARPHRD_ASH: - return "ash" - case unix.ARPHRD_ECONET: - return "econet" - case unix.ARPHRD_IRDA: - return "irda" - case unix.ARPHRD_FCPP: - return "fcpp" - case unix.ARPHRD_FCAL: - return "fcal" - case unix.ARPHRD_FCPL: - return "fcpl" - case unix.ARPHRD_FCFABRIC: - return "fcfb0" - case unix.ARPHRD_FCFABRIC + 1: - return "fcfb1" - case unix.ARPHRD_FCFABRIC + 2: - return "fcfb2" - case unix.ARPHRD_FCFABRIC + 3: - return "fcfb3" - case unix.ARPHRD_FCFABRIC + 4: - return "fcfb4" - case unix.ARPHRD_FCFABRIC + 5: - return "fcfb5" - case unix.ARPHRD_FCFABRIC + 6: - return "fcfb6" - case unix.ARPHRD_FCFABRIC + 7: - return "fcfb7" - case unix.ARPHRD_FCFABRIC + 8: - return "fcfb8" - case unix.ARPHRD_FCFABRIC + 9: - return "fcfb9" - case unix.ARPHRD_FCFABRIC + 10: - return "fcfb10" - case unix.ARPHRD_FCFABRIC + 11: - return "fcfb11" - case unix.ARPHRD_FCFABRIC + 12: - return "fcfb12" - case unix.ARPHRD_IEEE802_TR: - return "tr" - case unix.ARPHRD_IEEE80211: - return "ieee802.11" - case unix.ARPHRD_IEEE80211_PRISM: - return "ieee802.11/prism" - case unix.ARPHRD_IEEE80211_RADIOTAP: - return "ieee802.11/radiotap" - case unix.ARPHRD_IEEE802154: - return "ieee802.15.4" - - case 65534: - return "none" - case 65535: - return "void" - } - return fmt.Sprintf("unknown%d", msg.Type) -} - -func rtaAlignOf(attrlen int) int { - return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1) -} - -func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg { - msg := NewIfInfomsg(family) - parent.children = append(parent.children, msg) - return msg -} - -type Uint32Attribute struct { - Type uint16 - Value uint32 -} - -func (a *Uint32Attribute) Serialize() []byte { - native := NativeEndian() - buf := make([]byte, rtaAlignOf(8)) - native.PutUint16(buf[0:2], 8) - native.PutUint16(buf[2:4], a.Type) - - if a.Type&NLA_F_NET_BYTEORDER != 0 { - binary.BigEndian.PutUint32(buf[4:], a.Value) - } else { - native.PutUint32(buf[4:], a.Value) - } - return buf -} - -func (a *Uint32Attribute) Len() int { - return 8 -} - -// Extend RtAttr to handle data and children -type RtAttr struct { - unix.RtAttr - Data []byte - children []NetlinkRequestData -} - -// Create a new Extended RtAttr object -func NewRtAttr(attrType int, data []byte) *RtAttr { - return &RtAttr{ - RtAttr: unix.RtAttr{ - Type: uint16(attrType), - }, - children: []NetlinkRequestData{}, - Data: data, - } -} - -// NewRtAttrChild adds an RtAttr as a child to the parent and returns the new attribute -// -// Deprecated: Use AddRtAttr() on the parent object -func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr { - return parent.AddRtAttr(attrType, data) -} - -// AddRtAttr adds an RtAttr as a child and returns the new attribute -func (a *RtAttr) AddRtAttr(attrType int, data []byte) *RtAttr { - attr := NewRtAttr(attrType, data) - a.children = append(a.children, attr) - return attr -} - -// AddChild adds an existing NetlinkRequestData as a child. -func (a *RtAttr) AddChild(attr NetlinkRequestData) { - a.children = append(a.children, attr) -} - -func (a *RtAttr) Len() int { - if len(a.children) == 0 { - return (unix.SizeofRtAttr + len(a.Data)) - } - - l := 0 - for _, child := range a.children { - l += rtaAlignOf(child.Len()) - } - l += unix.SizeofRtAttr - return rtaAlignOf(l + len(a.Data)) -} - -// Serialize the RtAttr into a byte array -// This can't just unsafe.cast because it must iterate through children. -func (a *RtAttr) Serialize() []byte { - native := NativeEndian() - - length := a.Len() - buf := make([]byte, rtaAlignOf(length)) - - next := 4 - if a.Data != nil { - copy(buf[next:], a.Data) - next += rtaAlignOf(len(a.Data)) - } - if len(a.children) > 0 { - for _, child := range a.children { - childBuf := child.Serialize() - copy(buf[next:], childBuf) - next += rtaAlignOf(len(childBuf)) - } - } - - if l := uint16(length); l != 0 { - native.PutUint16(buf[0:2], l) - } - native.PutUint16(buf[2:4], a.Type) - return buf -} - -type NetlinkRequest struct { - unix.NlMsghdr - Data []NetlinkRequestData - RawData []byte - Sockets map[int]*SocketHandle -} - -// Serialize the Netlink Request into a byte array -func (req *NetlinkRequest) Serialize() []byte { - length := unix.SizeofNlMsghdr - dataBytes := make([][]byte, len(req.Data)) - for i, data := range req.Data { - dataBytes[i] = data.Serialize() - length = length + len(dataBytes[i]) - } - length += len(req.RawData) - - req.Len = uint32(length) - b := make([]byte, length) - hdr := (*(*[unix.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:] - next := unix.SizeofNlMsghdr - copy(b[0:next], hdr) - for _, data := range dataBytes { - for _, dataByte := range data { - b[next] = dataByte - next = next + 1 - } - } - // Add the raw data if any - if len(req.RawData) > 0 { - copy(b[next:length], req.RawData) - } - return b -} - -func (req *NetlinkRequest) AddData(data NetlinkRequestData) { - req.Data = append(req.Data, data) -} - -// AddRawData adds raw bytes to the end of the NetlinkRequest object during serialization -func (req *NetlinkRequest) AddRawData(data []byte) { - req.RawData = append(req.RawData, data...) -} - -// Execute the request against a the given sockType. -// Returns a list of netlink messages in serialized format, optionally filtered -// by resType. -func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) { - var ( - s *NetlinkSocket - err error - ) - - if req.Sockets != nil { - if sh, ok := req.Sockets[sockType]; ok { - s = sh.Socket - req.Seq = atomic.AddUint32(&sh.Seq, 1) - } - } - sharedSocket := s != nil - - if s == nil { - s, err = getNetlinkSocket(sockType) - if err != nil { - return nil, err - } - - if err := s.SetSendTimeout(&SocketTimeoutTv); err != nil { - return nil, err - } - if err := s.SetReceiveTimeout(&SocketTimeoutTv); err != nil { - return nil, err - } - - defer s.Close() - } else { - s.Lock() - defer s.Unlock() - } - - if err := s.Send(req); err != nil { - return nil, err - } - - pid, err := s.GetPid() - if err != nil { - return nil, err - } - - var res [][]byte - -done: - for { - msgs, from, err := s.Receive() - if err != nil { - return nil, err - } - if from.Pid != PidKernel { - return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel) - } - for _, m := range msgs { - if m.Header.Seq != req.Seq { - if sharedSocket { - continue - } - return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq) - } - if m.Header.Pid != pid { - continue - } - if m.Header.Type == unix.NLMSG_DONE || m.Header.Type == unix.NLMSG_ERROR { - native := NativeEndian() - error := int32(native.Uint32(m.Data[0:4])) - if error == 0 { - break done - } - return nil, syscall.Errno(-error) - } - if resType != 0 && m.Header.Type != resType { - continue - } - res = append(res, m.Data) - if m.Header.Flags&unix.NLM_F_MULTI == 0 { - break done - } - } - } - return res, nil -} - -// Create a new netlink request from proto and flags -// Note the Len value will be inaccurate once data is added until -// the message is serialized -func NewNetlinkRequest(proto, flags int) *NetlinkRequest { - return &NetlinkRequest{ - NlMsghdr: unix.NlMsghdr{ - Len: uint32(unix.SizeofNlMsghdr), - Type: uint16(proto), - Flags: unix.NLM_F_REQUEST | uint16(flags), - Seq: atomic.AddUint32(&nextSeqNr, 1), - }, - } -} - -type NetlinkSocket struct { - fd int32 - lsa unix.SockaddrNetlink - sync.Mutex -} - -func getNetlinkSocket(protocol int) (*NetlinkSocket, error) { - fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, protocol) - if err != nil { - return nil, err - } - s := &NetlinkSocket{ - fd: int32(fd), - } - s.lsa.Family = unix.AF_NETLINK - if err := unix.Bind(fd, &s.lsa); err != nil { - unix.Close(fd) - return nil, err - } - - return s, nil -} - -// GetNetlinkSocketAt opens a netlink socket in the network namespace newNs -// and positions the thread back into the network namespace specified by curNs, -// when done. If curNs is close, the function derives the current namespace and -// moves back into it when done. If newNs is close, the socket will be opened -// in the current network namespace. -func GetNetlinkSocketAt(newNs, curNs netns.NsHandle, protocol int) (*NetlinkSocket, error) { - c, err := executeInNetns(newNs, curNs) - if err != nil { - return nil, err - } - defer c() - return getNetlinkSocket(protocol) -} - -// executeInNetns sets execution of the code following this call to the -// network namespace newNs, then moves the thread back to curNs if open, -// otherwise to the current netns at the time the function was invoked -// In case of success, the caller is expected to execute the returned function -// at the end of the code that needs to be executed in the network namespace. -// Example: -// func jobAt(...) error { -// d, err := executeInNetns(...) -// if err != nil { return err} -// defer d() -// < code which needs to be executed in specific netns> -// } -// TODO: his function probably belongs to netns pkg. -func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) { - var ( - err error - moveBack func(netns.NsHandle) error - closeNs func() error - unlockThd func() - ) - restore := func() { - // order matters - if moveBack != nil { - moveBack(curNs) - } - if closeNs != nil { - closeNs() - } - if unlockThd != nil { - unlockThd() - } - } - if newNs.IsOpen() { - runtime.LockOSThread() - unlockThd = runtime.UnlockOSThread - if !curNs.IsOpen() { - if curNs, err = netns.Get(); err != nil { - restore() - return nil, fmt.Errorf("could not get current namespace while creating netlink socket: %v", err) - } - closeNs = curNs.Close - } - if err := netns.Set(newNs); err != nil { - restore() - return nil, fmt.Errorf("failed to set into network namespace %d while creating netlink socket: %v", newNs, err) - } - moveBack = netns.Set - } - return restore, nil -} - -// Create a netlink socket with a given protocol (e.g. NETLINK_ROUTE) -// and subscribe it to multicast groups passed in variable argument list. -// Returns the netlink socket on which Receive() method can be called -// to retrieve the messages from the kernel. -func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) { - fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, protocol) - if err != nil { - return nil, err - } - s := &NetlinkSocket{ - fd: int32(fd), - } - s.lsa.Family = unix.AF_NETLINK - - for _, g := range groups { - s.lsa.Groups |= (1 << (g - 1)) - } - - if err := unix.Bind(fd, &s.lsa); err != nil { - unix.Close(fd) - return nil, err - } - - return s, nil -} - -// SubscribeAt works like Subscribe plus let's the caller choose the network -// namespace in which the socket would be opened (newNs). Then control goes back -// to curNs if open, otherwise to the netns at the time this function was called. -func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*NetlinkSocket, error) { - c, err := executeInNetns(newNs, curNs) - if err != nil { - return nil, err - } - defer c() - return Subscribe(protocol, groups...) -} - -func (s *NetlinkSocket) Close() { - fd := int(atomic.SwapInt32(&s.fd, -1)) - unix.Close(fd) -} - -func (s *NetlinkSocket) GetFd() int { - return int(atomic.LoadInt32(&s.fd)) -} - -func (s *NetlinkSocket) Send(request *NetlinkRequest) error { - fd := int(atomic.LoadInt32(&s.fd)) - if fd < 0 { - return fmt.Errorf("Send called on a closed socket") - } - if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil { - return err - } - return nil -} - -func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) { - fd := int(atomic.LoadInt32(&s.fd)) - if fd < 0 { - return nil, nil, fmt.Errorf("Receive called on a closed socket") - } - var fromAddr *unix.SockaddrNetlink - var rb [RECEIVE_BUFFER_SIZE]byte - nr, from, err := unix.Recvfrom(fd, rb[:], 0) - if err != nil { - return nil, nil, err - } - fromAddr, ok := from.(*unix.SockaddrNetlink) - if !ok { - return nil, nil, fmt.Errorf("Error converting to netlink sockaddr") - } - if nr < unix.NLMSG_HDRLEN { - return nil, nil, fmt.Errorf("Got short response from netlink") - } - rb2 := make([]byte, nr) - copy(rb2, rb[:nr]) - nl, err := syscall.ParseNetlinkMessage(rb2) - if err != nil { - return nil, nil, err - } - return nl, fromAddr, nil -} - -// SetSendTimeout allows to set a send timeout on the socket -func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error { - // Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine - // remains stuck on a send on a closed fd - return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout) -} - -// SetReceiveTimeout allows to set a receive timeout on the socket -func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error { - // Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine - // remains stuck on a recvmsg on a closed fd - return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout) -} - -func (s *NetlinkSocket) GetPid() (uint32, error) { - fd := int(atomic.LoadInt32(&s.fd)) - lsa, err := unix.Getsockname(fd) - if err != nil { - return 0, err - } - switch v := lsa.(type) { - case *unix.SockaddrNetlink: - return v.Pid, nil - } - return 0, fmt.Errorf("Wrong socket type") -} - -func ZeroTerminated(s string) []byte { - bytes := make([]byte, len(s)+1) - for i := 0; i < len(s); i++ { - bytes[i] = s[i] - } - bytes[len(s)] = 0 - return bytes -} - -func NonZeroTerminated(s string) []byte { - bytes := make([]byte, len(s)) - for i := 0; i < len(s); i++ { - bytes[i] = s[i] - } - return bytes -} - -func BytesToString(b []byte) string { - n := bytes.Index(b, []byte{0}) - return string(b[:n]) -} - -func Uint8Attr(v uint8) []byte { - return []byte{byte(v)} -} - -func Uint16Attr(v uint16) []byte { - native := NativeEndian() - bytes := make([]byte, 2) - native.PutUint16(bytes, v) - return bytes -} - -func Uint32Attr(v uint32) []byte { - native := NativeEndian() - bytes := make([]byte, 4) - native.PutUint32(bytes, v) - return bytes -} - -func Uint64Attr(v uint64) []byte { - native := NativeEndian() - bytes := make([]byte, 8) - native.PutUint64(bytes, v) - return bytes -} - -func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) { - var attrs []syscall.NetlinkRouteAttr - for len(b) >= unix.SizeofRtAttr { - a, vbuf, alen, err := netlinkRouteAttrAndValue(b) - if err != nil { - return nil, err - } - ra := syscall.NetlinkRouteAttr{Attr: syscall.RtAttr(*a), Value: vbuf[:int(a.Len)-unix.SizeofRtAttr]} - attrs = append(attrs, ra) - b = b[alen:] - } - return attrs, nil -} - -func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) { - a := (*unix.RtAttr)(unsafe.Pointer(&b[0])) - if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) { - return nil, nil, 0, unix.EINVAL - } - return a, b[unix.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil -} - -// SocketHandle contains the netlink socket and the associated -// sequence counter for a specific netlink family -type SocketHandle struct { - Seq uint32 - Socket *NetlinkSocket -} - -// Close closes the netlink socket -func (sh *SocketHandle) Close() { - if sh.Socket != nil { - sh.Socket.Close() - } -} diff --git a/vendor/github.com/tailscale/netlink/nl/nl_unspecified.go b/vendor/github.com/tailscale/netlink/nl/nl_unspecified.go deleted file mode 100644 index dfc0be6..0000000 --- a/vendor/github.com/tailscale/netlink/nl/nl_unspecified.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux - -package nl - -import "encoding/binary" - -var SupportedNlFamilies = []int{} - -func NativeEndian() binary.ByteOrder { - return nil -} diff --git a/vendor/github.com/tailscale/netlink/nl/parse_attr_linux.go b/vendor/github.com/tailscale/netlink/nl/parse_attr_linux.go deleted file mode 100644 index 7f49125..0000000 --- a/vendor/github.com/tailscale/netlink/nl/parse_attr_linux.go +++ /dev/null @@ -1,79 +0,0 @@ -package nl - -import ( - "encoding/binary" - "fmt" - "log" -) - -type Attribute struct { - Type uint16 - Value []byte -} - -func ParseAttributes(data []byte) <-chan Attribute { - native := NativeEndian() - result := make(chan Attribute) - - go func() { - i := 0 - for i+4 < len(data) { - length := int(native.Uint16(data[i : i+2])) - attrType := native.Uint16(data[i+2 : i+4]) - - if length < 4 { - log.Printf("attribute 0x%02x has invalid length of %d bytes", attrType, length) - break - } - - if len(data) < i+length { - log.Printf("attribute 0x%02x of length %d is truncated, only %d bytes remaining", attrType, length, len(data)-i) - break - } - - result <- Attribute{ - Type: attrType, - Value: data[i+4 : i+length], - } - i += rtaAlignOf(length) - } - close(result) - }() - - return result -} - -func PrintAttributes(data []byte) { - printAttributes(data, 0) -} - -func printAttributes(data []byte, level int) { - for attr := range ParseAttributes(data) { - for i := 0; i < level; i++ { - print("> ") - } - nested := attr.Type&NLA_F_NESTED != 0 - fmt.Printf("type=%d nested=%v len=%v %v\n", attr.Type&NLA_TYPE_MASK, nested, len(attr.Value), attr.Value) - if nested { - printAttributes(attr.Value, level+1) - } - } -} - -// Uint32 returns the uint32 value respecting the NET_BYTEORDER flag -func (attr *Attribute) Uint32() uint32 { - if attr.Type&NLA_F_NET_BYTEORDER != 0 { - return binary.BigEndian.Uint32(attr.Value) - } else { - return NativeEndian().Uint32(attr.Value) - } -} - -// Uint64 returns the uint64 value respecting the NET_BYTEORDER flag -func (attr *Attribute) Uint64() uint64 { - if attr.Type&NLA_F_NET_BYTEORDER != 0 { - return binary.BigEndian.Uint64(attr.Value) - } else { - return NativeEndian().Uint64(attr.Value) - } -} diff --git a/vendor/github.com/tailscale/netlink/nl/rdma_link_linux.go b/vendor/github.com/tailscale/netlink/nl/rdma_link_linux.go deleted file mode 100644 index ce43ee1..0000000 --- a/vendor/github.com/tailscale/netlink/nl/rdma_link_linux.go +++ /dev/null @@ -1,39 +0,0 @@ -package nl - -const ( - RDMA_NL_GET_CLIENT_SHIFT = 10 -) - -const ( - RDMA_NL_NLDEV = 5 -) - -const ( - RDMA_NLDEV_CMD_GET = 1 - RDMA_NLDEV_CMD_SET = 2 - RDMA_NLDEV_CMD_NEWLINK = 3 - RDMA_NLDEV_CMD_DELLINK = 4 - RDMA_NLDEV_CMD_SYS_GET = 6 - RDMA_NLDEV_CMD_SYS_SET = 7 -) - -const ( - RDMA_NLDEV_ATTR_DEV_INDEX = 1 - RDMA_NLDEV_ATTR_DEV_NAME = 2 - RDMA_NLDEV_ATTR_PORT_INDEX = 3 - RDMA_NLDEV_ATTR_CAP_FLAGS = 4 - RDMA_NLDEV_ATTR_FW_VERSION = 5 - RDMA_NLDEV_ATTR_NODE_GUID = 6 - RDMA_NLDEV_ATTR_SYS_IMAGE_GUID = 7 - RDMA_NLDEV_ATTR_SUBNET_PREFIX = 8 - RDMA_NLDEV_ATTR_LID = 9 - RDMA_NLDEV_ATTR_SM_LID = 10 - RDMA_NLDEV_ATTR_LMC = 11 - RDMA_NLDEV_ATTR_PORT_STATE = 12 - RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13 - RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14 - RDMA_NLDEV_ATTR_NDEV_NAME = 51 - RDMA_NLDEV_ATTR_LINK_TYPE = 65 - RDMA_NLDEV_SYS_ATTR_NETNS_MODE = 66 - RDMA_NLDEV_NET_NS_FD = 68 -) diff --git a/vendor/github.com/tailscale/netlink/nl/route_linux.go b/vendor/github.com/tailscale/netlink/nl/route_linux.go deleted file mode 100644 index 03c1900..0000000 --- a/vendor/github.com/tailscale/netlink/nl/route_linux.go +++ /dev/null @@ -1,107 +0,0 @@ -package nl - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -type RtMsg struct { - unix.RtMsg -} - -func NewRtMsg() *RtMsg { - return &RtMsg{ - RtMsg: unix.RtMsg{ - Table: unix.RT_TABLE_MAIN, - Scope: unix.RT_SCOPE_UNIVERSE, - Protocol: unix.RTPROT_BOOT, - Type: unix.RTN_UNICAST, - }, - } -} - -func NewRtDelMsg() *RtMsg { - return &RtMsg{ - RtMsg: unix.RtMsg{ - Table: unix.RT_TABLE_MAIN, - Scope: unix.RT_SCOPE_NOWHERE, - }, - } -} - -func (msg *RtMsg) Len() int { - return unix.SizeofRtMsg -} - -func DeserializeRtMsg(b []byte) *RtMsg { - return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0])) -} - -func (msg *RtMsg) Serialize() []byte { - return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] -} - -type RtNexthop struct { - unix.RtNexthop - Children []NetlinkRequestData -} - -func DeserializeRtNexthop(b []byte) *RtNexthop { - return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0])) -} - -func (msg *RtNexthop) Len() int { - if len(msg.Children) == 0 { - return unix.SizeofRtNexthop - } - - l := 0 - for _, child := range msg.Children { - l += rtaAlignOf(child.Len()) - } - l += unix.SizeofRtNexthop - return rtaAlignOf(l) -} - -func (msg *RtNexthop) Serialize() []byte { - length := msg.Len() - msg.RtNexthop.Len = uint16(length) - buf := make([]byte, length) - copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]) - next := rtaAlignOf(unix.SizeofRtNexthop) - if len(msg.Children) > 0 { - for _, child := range msg.Children { - childBuf := child.Serialize() - copy(buf[next:], childBuf) - next += rtaAlignOf(len(childBuf)) - } - } - return buf -} - -type RtGenMsg struct { - unix.RtGenmsg -} - -func NewRtGenMsg() *RtGenMsg { - return &RtGenMsg{ - RtGenmsg: unix.RtGenmsg{ - Family: unix.AF_UNSPEC, - }, - } -} - -func (msg *RtGenMsg) Len() int { - return rtaAlignOf(unix.SizeofRtGenmsg) -} - -func DeserializeRtGenMsg(b []byte) *RtGenMsg { - return &RtGenMsg{RtGenmsg: unix.RtGenmsg{Family: b[0]}} -} - -func (msg *RtGenMsg) Serialize() []byte { - out := make([]byte, msg.Len()) - out[0] = msg.Family - return out -} diff --git a/vendor/github.com/tailscale/netlink/nl/seg6_linux.go b/vendor/github.com/tailscale/netlink/nl/seg6_linux.go deleted file mode 100644 index fe88285..0000000 --- a/vendor/github.com/tailscale/netlink/nl/seg6_linux.go +++ /dev/null @@ -1,154 +0,0 @@ -package nl - -import ( - "errors" - "fmt" - "net" -) - -type IPv6SrHdr struct { - nextHdr uint8 - hdrLen uint8 - routingType uint8 - segmentsLeft uint8 - firstSegment uint8 - flags uint8 - reserved uint16 - - Segments []net.IP -} - -func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool { - if len(s1.Segments) != len(s2.Segments) { - return false - } - for i := range s1.Segments { - if !s1.Segments[i].Equal(s2.Segments[i]) { - return false - } - } - return s1.nextHdr == s2.nextHdr && - s1.hdrLen == s2.hdrLen && - s1.routingType == s2.routingType && - s1.segmentsLeft == s2.segmentsLeft && - s1.firstSegment == s2.firstSegment && - s1.flags == s2.flags - // reserved doesn't need to be identical. -} - -// seg6 encap mode -const ( - SEG6_IPTUN_MODE_INLINE = iota - SEG6_IPTUN_MODE_ENCAP -) - -// number of nested RTATTR -// from include/uapi/linux/seg6_iptunnel.h -const ( - SEG6_IPTUNNEL_UNSPEC = iota - SEG6_IPTUNNEL_SRH - __SEG6_IPTUNNEL_MAX -) -const ( - SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1 -) - -func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) { - nsegs := len(segments) // nsegs: number of segments - if nsegs == 0 { - return nil, errors.New("EncodeSEG6Encap: No Segment in srh") - } - b := make([]byte, 12, 12+len(segments)*16) - native := NativeEndian() - native.PutUint32(b, uint32(mode)) - b[4] = 0 // srh.nextHdr (0 when calling netlink) - b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit) - b[6] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA) - b[7] = uint8(nsegs - 1) // srh.segmentsLeft - b[8] = uint8(nsegs - 1) // srh.firstSegment - b[9] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac) - // srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07 - native.PutUint16(b[10:], 0) // srh.reserved - for _, netIP := range segments { - b = append(b, netIP...) // srh.Segments - } - return b, nil -} - -func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) { - native := NativeEndian() - mode := int(native.Uint32(buf)) - srh := IPv6SrHdr{ - nextHdr: buf[4], - hdrLen: buf[5], - routingType: buf[6], - segmentsLeft: buf[7], - firstSegment: buf[8], - flags: buf[9], - reserved: native.Uint16(buf[10:12]), - } - buf = buf[12:] - if len(buf)%16 != 0 { - err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)", len(buf)) - return mode, nil, err - } - for len(buf) > 0 { - srh.Segments = append(srh.Segments, net.IP(buf[:16])) - buf = buf[16:] - } - return mode, srh.Segments, nil -} - -func DecodeSEG6Srh(buf []byte) ([]net.IP, error) { - native := NativeEndian() - srh := IPv6SrHdr{ - nextHdr: buf[0], - hdrLen: buf[1], - routingType: buf[2], - segmentsLeft: buf[3], - firstSegment: buf[4], - flags: buf[5], - reserved: native.Uint16(buf[6:8]), - } - buf = buf[8:] - if len(buf)%16 != 0 { - err := fmt.Errorf("DecodeSEG6Srh: error parsing Segment List (buf len: %d)", len(buf)) - return nil, err - } - for len(buf) > 0 { - srh.Segments = append(srh.Segments, net.IP(buf[:16])) - buf = buf[16:] - } - return srh.Segments, nil -} -func EncodeSEG6Srh(segments []net.IP) ([]byte, error) { - nsegs := len(segments) // nsegs: number of segments - if nsegs == 0 { - return nil, errors.New("EncodeSEG6Srh: No Segments") - } - b := make([]byte, 8, 8+len(segments)*16) - native := NativeEndian() - b[0] = 0 // srh.nextHdr (0 when calling netlink) - b[1] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit) - b[2] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA) - b[3] = uint8(nsegs - 1) // srh.segmentsLeft - b[4] = uint8(nsegs - 1) // srh.firstSegment - b[5] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac) - // srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07 - native.PutUint16(b[6:], 0) // srh.reserved - for _, netIP := range segments { - b = append(b, netIP...) // srh.Segments - } - return b, nil -} - -// Helper functions -func SEG6EncapModeString(mode int) string { - switch mode { - case SEG6_IPTUN_MODE_INLINE: - return "inline" - case SEG6_IPTUN_MODE_ENCAP: - return "encap" - } - return "unknown" -} diff --git a/vendor/github.com/tailscale/netlink/nl/seg6local_linux.go b/vendor/github.com/tailscale/netlink/nl/seg6local_linux.go deleted file mode 100644 index 1500177..0000000 --- a/vendor/github.com/tailscale/netlink/nl/seg6local_linux.go +++ /dev/null @@ -1,76 +0,0 @@ -package nl - -import () - -// seg6local parameters -const ( - SEG6_LOCAL_UNSPEC = iota - SEG6_LOCAL_ACTION - SEG6_LOCAL_SRH - SEG6_LOCAL_TABLE - SEG6_LOCAL_NH4 - SEG6_LOCAL_NH6 - SEG6_LOCAL_IIF - SEG6_LOCAL_OIF - __SEG6_LOCAL_MAX -) -const ( - SEG6_LOCAL_MAX = __SEG6_LOCAL_MAX -) - -// seg6local actions -const ( - SEG6_LOCAL_ACTION_END = iota + 1 // 1 - SEG6_LOCAL_ACTION_END_X // 2 - SEG6_LOCAL_ACTION_END_T // 3 - SEG6_LOCAL_ACTION_END_DX2 // 4 - SEG6_LOCAL_ACTION_END_DX6 // 5 - SEG6_LOCAL_ACTION_END_DX4 // 6 - SEG6_LOCAL_ACTION_END_DT6 // 7 - SEG6_LOCAL_ACTION_END_DT4 // 8 - SEG6_LOCAL_ACTION_END_B6 // 9 - SEG6_LOCAL_ACTION_END_B6_ENCAPS // 10 - SEG6_LOCAL_ACTION_END_BM // 11 - SEG6_LOCAL_ACTION_END_S // 12 - SEG6_LOCAL_ACTION_END_AS // 13 - SEG6_LOCAL_ACTION_END_AM // 14 - __SEG6_LOCAL_ACTION_MAX -) -const ( - SEG6_LOCAL_ACTION_MAX = __SEG6_LOCAL_ACTION_MAX - 1 -) - -// Helper functions -func SEG6LocalActionString(action int) string { - switch action { - case SEG6_LOCAL_ACTION_END: - return "End" - case SEG6_LOCAL_ACTION_END_X: - return "End.X" - case SEG6_LOCAL_ACTION_END_T: - return "End.T" - case SEG6_LOCAL_ACTION_END_DX2: - return "End.DX2" - case SEG6_LOCAL_ACTION_END_DX6: - return "End.DX6" - case SEG6_LOCAL_ACTION_END_DX4: - return "End.DX4" - case SEG6_LOCAL_ACTION_END_DT6: - return "End.DT6" - case SEG6_LOCAL_ACTION_END_DT4: - return "End.DT4" - case SEG6_LOCAL_ACTION_END_B6: - return "End.B6" - case SEG6_LOCAL_ACTION_END_B6_ENCAPS: - return "End.B6.Encaps" - case SEG6_LOCAL_ACTION_END_BM: - return "End.BM" - case SEG6_LOCAL_ACTION_END_S: - return "End.S" - case SEG6_LOCAL_ACTION_END_AS: - return "End.AS" - case SEG6_LOCAL_ACTION_END_AM: - return "End.AM" - } - return "unknown" -} diff --git a/vendor/github.com/tailscale/netlink/nl/syscall.go b/vendor/github.com/tailscale/netlink/nl/syscall.go deleted file mode 100644 index bdf6ba6..0000000 --- a/vendor/github.com/tailscale/netlink/nl/syscall.go +++ /dev/null @@ -1,76 +0,0 @@ -package nl - -// syscall package lack of rule attributes type. -// Thus there are defined below -const ( - FRA_UNSPEC = iota - FRA_DST /* destination address */ - FRA_SRC /* source address */ - FRA_IIFNAME /* interface name */ - FRA_GOTO /* target to jump to (FR_ACT_GOTO) */ - FRA_UNUSED2 - FRA_PRIORITY /* priority/preference */ - FRA_UNUSED3 - FRA_UNUSED4 - FRA_UNUSED5 - FRA_FWMARK /* mark */ - FRA_FLOW /* flow/class id */ - FRA_TUN_ID - FRA_SUPPRESS_IFGROUP - FRA_SUPPRESS_PREFIXLEN - FRA_TABLE /* Extended table id */ - FRA_FWMASK /* mask for netfilter mark */ - FRA_OIFNAME - FRA_PAD - FRA_L3MDEV /* iif or oif is l3mdev goto its table */ - FRA_UID_RANGE /* UID range */ - FRA_PROTOCOL /* Originator of the rule */ - FRA_IP_PROTO /* ip proto */ - FRA_SPORT_RANGE /* sport */ - FRA_DPORT_RANGE /* dport */ -) - -// ip rule netlink request types -const ( - FR_ACT_UNSPEC = iota - FR_ACT_TO_TBL /* Pass to fixed table */ - FR_ACT_GOTO /* Jump to another rule */ - FR_ACT_NOP /* No operation */ - FR_ACT_RES3 - FR_ACT_RES4 - FR_ACT_BLACKHOLE /* Drop without notification */ - FR_ACT_UNREACHABLE /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT /* Drop with EACCES */ -) - -// socket diags related -const ( - SOCK_DIAG_BY_FAMILY = 20 /* linux.sock_diag.h */ - TCPDIAG_NOCOOKIE = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/ -) - -// RTA_ENCAP subtype -const ( - MPLS_IPTUNNEL_UNSPEC = iota - MPLS_IPTUNNEL_DST -) - -// light weight tunnel encap types -const ( - LWTUNNEL_ENCAP_NONE = iota - LWTUNNEL_ENCAP_MPLS - LWTUNNEL_ENCAP_IP - LWTUNNEL_ENCAP_ILA - LWTUNNEL_ENCAP_IP6 - LWTUNNEL_ENCAP_SEG6 - LWTUNNEL_ENCAP_BPF - LWTUNNEL_ENCAP_SEG6_LOCAL -) - -// routing header types -const ( - IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed - IPV6_SRCRT_TYPE_0 = 0 // Deprecated; will be removed - IPV6_SRCRT_TYPE_2 = 2 // IPv6 type 2 Routing Header - IPV6_SRCRT_TYPE_4 = 4 // Segment Routing with IPv6 -) diff --git a/vendor/github.com/tailscale/netlink/nl/tc_linux.go b/vendor/github.com/tailscale/netlink/nl/tc_linux.go deleted file mode 100644 index 002beda..0000000 --- a/vendor/github.com/tailscale/netlink/nl/tc_linux.go +++ /dev/null @@ -1,1088 +0,0 @@ -package nl - -import ( - "encoding/binary" - "unsafe" -) - -// LinkLayer -const ( - LINKLAYER_UNSPEC = iota - LINKLAYER_ETHERNET - LINKLAYER_ATM -) - -// ATM -const ( - ATM_CELL_PAYLOAD = 48 - ATM_CELL_SIZE = 53 -) - -const TC_LINKLAYER_MASK = 0x0F - -// Police -const ( - TCA_POLICE_UNSPEC = iota - TCA_POLICE_TBF - TCA_POLICE_RATE - TCA_POLICE_PEAKRATE - TCA_POLICE_AVRATE - TCA_POLICE_RESULT - TCA_POLICE_MAX = TCA_POLICE_RESULT -) - -// Message types -const ( - TCA_UNSPEC = iota - TCA_KIND - TCA_OPTIONS - TCA_STATS - TCA_XSTATS - TCA_RATE - TCA_FCNT - TCA_STATS2 - TCA_STAB - TCA_MAX = TCA_STAB -) - -const ( - TCA_ACT_TAB = 1 - TCAA_MAX = 1 -) - -const ( - TCA_ACT_UNSPEC = iota - TCA_ACT_KIND - TCA_ACT_OPTIONS - TCA_ACT_INDEX - TCA_ACT_STATS - TCA_ACT_MAX -) - -const ( - TCA_PRIO_UNSPEC = iota - TCA_PRIO_MQ - TCA_PRIO_MAX = TCA_PRIO_MQ -) - -const ( - TCA_STATS_UNSPEC = iota - TCA_STATS_BASIC - TCA_STATS_RATE_EST - TCA_STATS_QUEUE - TCA_STATS_APP - TCA_STATS_MAX = TCA_STATS_APP -) - -const ( - SizeofTcMsg = 0x14 - SizeofTcActionMsg = 0x04 - SizeofTcPrioMap = 0x14 - SizeofTcRateSpec = 0x0c - SizeofTcNetemQopt = 0x18 - SizeofTcNetemCorr = 0x0c - SizeofTcNetemReorder = 0x08 - SizeofTcNetemCorrupt = 0x08 - SizeofTcTbfQopt = 2*SizeofTcRateSpec + 0x0c - SizeofTcHtbCopt = 2*SizeofTcRateSpec + 0x14 - SizeofTcHtbGlob = 0x14 - SizeofTcU32Key = 0x10 - SizeofTcU32Sel = 0x10 // without keys - SizeofTcGen = 0x14 - SizeofTcConnmark = SizeofTcGen + 0x04 - SizeofTcMirred = SizeofTcGen + 0x08 - SizeofTcTunnelKey = SizeofTcGen + 0x04 - SizeofTcSkbEdit = SizeofTcGen - SizeofTcPolice = 2*SizeofTcRateSpec + 0x20 - SizeofTcSfqQopt = 0x0b - SizeofTcSfqRedStats = 0x18 - SizeofTcSfqQoptV1 = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c -) - -// struct tcmsg { -// unsigned char tcm_family; -// unsigned char tcm__pad1; -// unsigned short tcm__pad2; -// int tcm_ifindex; -// __u32 tcm_handle; -// __u32 tcm_parent; -// __u32 tcm_info; -// }; - -type TcMsg struct { - Family uint8 - Pad [3]byte - Ifindex int32 - Handle uint32 - Parent uint32 - Info uint32 -} - -func (msg *TcMsg) Len() int { - return SizeofTcMsg -} - -func DeserializeTcMsg(b []byte) *TcMsg { - return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0])) -} - -func (x *TcMsg) Serialize() []byte { - return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:] -} - -// struct tcamsg { -// unsigned char tca_family; -// unsigned char tca__pad1; -// unsigned short tca__pad2; -// }; - -type TcActionMsg struct { - Family uint8 - Pad [3]byte -} - -func (msg *TcActionMsg) Len() int { - return SizeofTcActionMsg -} - -func DeserializeTcActionMsg(b []byte) *TcActionMsg { - return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0])) -} - -func (x *TcActionMsg) Serialize() []byte { - return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TC_PRIO_MAX = 15 -) - -// struct tc_prio_qopt { -// int bands; /* Number of bands */ -// __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ -// }; - -type TcPrioMap struct { - Bands int32 - Priomap [TC_PRIO_MAX + 1]uint8 -} - -func (msg *TcPrioMap) Len() int { - return SizeofTcPrioMap -} - -func DeserializeTcPrioMap(b []byte) *TcPrioMap { - return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0])) -} - -func (x *TcPrioMap) Serialize() []byte { - return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_TBF_UNSPEC = iota - TCA_TBF_PARMS - TCA_TBF_RTAB - TCA_TBF_PTAB - TCA_TBF_RATE64 - TCA_TBF_PRATE64 - TCA_TBF_BURST - TCA_TBF_PBURST - TCA_TBF_MAX = TCA_TBF_PBURST -) - -// struct tc_ratespec { -// unsigned char cell_log; -// __u8 linklayer; /* lower 4 bits */ -// unsigned short overhead; -// short cell_align; -// unsigned short mpu; -// __u32 rate; -// }; - -type TcRateSpec struct { - CellLog uint8 - Linklayer uint8 - Overhead uint16 - CellAlign int16 - Mpu uint16 - Rate uint32 -} - -func (msg *TcRateSpec) Len() int { - return SizeofTcRateSpec -} - -func DeserializeTcRateSpec(b []byte) *TcRateSpec { - return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0])) -} - -func (x *TcRateSpec) Serialize() []byte { - return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:] -} - -/** -* NETEM - */ - -const ( - TCA_NETEM_UNSPEC = iota - TCA_NETEM_CORR - TCA_NETEM_DELAY_DIST - TCA_NETEM_REORDER - TCA_NETEM_CORRUPT - TCA_NETEM_LOSS - TCA_NETEM_RATE - TCA_NETEM_ECN - TCA_NETEM_RATE64 - TCA_NETEM_MAX = TCA_NETEM_RATE64 -) - -// struct tc_netem_qopt { -// __u32 latency; /* added delay (us) */ -// __u32 limit; /* fifo limit (packets) */ -// __u32 loss; /* random packet loss (0=none ~0=100%) */ -// __u32 gap; /* re-ordering gap (0 for none) */ -// __u32 duplicate; /* random packet dup (0=none ~0=100%) */ -// __u32 jitter; /* random jitter in latency (us) */ -// }; - -type TcNetemQopt struct { - Latency uint32 - Limit uint32 - Loss uint32 - Gap uint32 - Duplicate uint32 - Jitter uint32 -} - -func (msg *TcNetemQopt) Len() int { - return SizeofTcNetemQopt -} - -func DeserializeTcNetemQopt(b []byte) *TcNetemQopt { - return (*TcNetemQopt)(unsafe.Pointer(&b[0:SizeofTcNetemQopt][0])) -} - -func (x *TcNetemQopt) Serialize() []byte { - return (*(*[SizeofTcNetemQopt]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_netem_corr { -// __u32 delay_corr; /* delay correlation */ -// __u32 loss_corr; /* packet loss correlation */ -// __u32 dup_corr; /* duplicate correlation */ -// }; - -type TcNetemCorr struct { - DelayCorr uint32 - LossCorr uint32 - DupCorr uint32 -} - -func (msg *TcNetemCorr) Len() int { - return SizeofTcNetemCorr -} - -func DeserializeTcNetemCorr(b []byte) *TcNetemCorr { - return (*TcNetemCorr)(unsafe.Pointer(&b[0:SizeofTcNetemCorr][0])) -} - -func (x *TcNetemCorr) Serialize() []byte { - return (*(*[SizeofTcNetemCorr]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_netem_reorder { -// __u32 probability; -// __u32 correlation; -// }; - -type TcNetemReorder struct { - Probability uint32 - Correlation uint32 -} - -func (msg *TcNetemReorder) Len() int { - return SizeofTcNetemReorder -} - -func DeserializeTcNetemReorder(b []byte) *TcNetemReorder { - return (*TcNetemReorder)(unsafe.Pointer(&b[0:SizeofTcNetemReorder][0])) -} - -func (x *TcNetemReorder) Serialize() []byte { - return (*(*[SizeofTcNetemReorder]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_netem_corrupt { -// __u32 probability; -// __u32 correlation; -// }; - -type TcNetemCorrupt struct { - Probability uint32 - Correlation uint32 -} - -func (msg *TcNetemCorrupt) Len() int { - return SizeofTcNetemCorrupt -} - -func DeserializeTcNetemCorrupt(b []byte) *TcNetemCorrupt { - return (*TcNetemCorrupt)(unsafe.Pointer(&b[0:SizeofTcNetemCorrupt][0])) -} - -func (x *TcNetemCorrupt) Serialize() []byte { - return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_tbf_qopt { -// struct tc_ratespec rate; -// struct tc_ratespec peakrate; -// __u32 limit; -// __u32 buffer; -// __u32 mtu; -// }; - -type TcTbfQopt struct { - Rate TcRateSpec - Peakrate TcRateSpec - Limit uint32 - Buffer uint32 - Mtu uint32 -} - -func (msg *TcTbfQopt) Len() int { - return SizeofTcTbfQopt -} - -func DeserializeTcTbfQopt(b []byte) *TcTbfQopt { - return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0])) -} - -func (x *TcTbfQopt) Serialize() []byte { - return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_HTB_UNSPEC = iota - TCA_HTB_PARMS - TCA_HTB_INIT - TCA_HTB_CTAB - TCA_HTB_RTAB - TCA_HTB_DIRECT_QLEN - TCA_HTB_RATE64 - TCA_HTB_CEIL64 - TCA_HTB_MAX = TCA_HTB_CEIL64 -) - -//struct tc_htb_opt { -// struct tc_ratespec rate; -// struct tc_ratespec ceil; -// __u32 buffer; -// __u32 cbuffer; -// __u32 quantum; -// __u32 level; /* out only */ -// __u32 prio; -//}; - -type TcHtbCopt struct { - Rate TcRateSpec - Ceil TcRateSpec - Buffer uint32 - Cbuffer uint32 - Quantum uint32 - Level uint32 - Prio uint32 -} - -func (msg *TcHtbCopt) Len() int { - return SizeofTcHtbCopt -} - -func DeserializeTcHtbCopt(b []byte) *TcHtbCopt { - return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0])) -} - -func (x *TcHtbCopt) Serialize() []byte { - return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:] -} - -type TcHtbGlob struct { - Version uint32 - Rate2Quantum uint32 - Defcls uint32 - Debug uint32 - DirectPkts uint32 -} - -func (msg *TcHtbGlob) Len() int { - return SizeofTcHtbGlob -} - -func DeserializeTcHtbGlob(b []byte) *TcHtbGlob { - return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0])) -} - -func (x *TcHtbGlob) Serialize() []byte { - return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:] -} - -// HFSC - -type Curve struct { - m1 uint32 - d uint32 - m2 uint32 -} - -type HfscCopt struct { - Rsc Curve - Fsc Curve - Usc Curve -} - -func (c *Curve) Attrs() (uint32, uint32, uint32) { - return c.m1, c.d, c.m2 -} - -func (c *Curve) Set(m1 uint32, d uint32, m2 uint32) { - c.m1 = m1 - c.d = d - c.m2 = m2 -} - -func DeserializeHfscCurve(b []byte) *Curve { - return &Curve{ - m1: binary.LittleEndian.Uint32(b[0:4]), - d: binary.LittleEndian.Uint32(b[4:8]), - m2: binary.LittleEndian.Uint32(b[8:12]), - } -} - -func SerializeHfscCurve(c *Curve) (b []byte) { - t := make([]byte, binary.MaxVarintLen32) - binary.LittleEndian.PutUint32(t, c.m1) - b = append(b, t[:4]...) - binary.LittleEndian.PutUint32(t, c.d) - b = append(b, t[:4]...) - binary.LittleEndian.PutUint32(t, c.m2) - b = append(b, t[:4]...) - return b -} - -type TcHfscOpt struct { - Defcls uint16 -} - -func (x *TcHfscOpt) Serialize() []byte { - return (*(*[2]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_U32_UNSPEC = iota - TCA_U32_CLASSID - TCA_U32_HASH - TCA_U32_LINK - TCA_U32_DIVISOR - TCA_U32_SEL - TCA_U32_POLICE - TCA_U32_ACT - TCA_U32_INDEV - TCA_U32_PCNT - TCA_U32_MARK - TCA_U32_MAX = TCA_U32_MARK -) - -// struct tc_u32_key { -// __be32 mask; -// __be32 val; -// int off; -// int offmask; -// }; - -type TcU32Key struct { - Mask uint32 // big endian - Val uint32 // big endian - Off int32 - OffMask int32 -} - -func (msg *TcU32Key) Len() int { - return SizeofTcU32Key -} - -func DeserializeTcU32Key(b []byte) *TcU32Key { - return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0])) -} - -func (x *TcU32Key) Serialize() []byte { - return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_u32_sel { -// unsigned char flags; -// unsigned char offshift; -// unsigned char nkeys; -// -// __be16 offmask; -// __u16 off; -// short offoff; -// -// short hoff; -// __be32 hmask; -// struct tc_u32_key keys[0]; -// }; - -const ( - TC_U32_TERMINAL = 1 << iota - TC_U32_OFFSET = 1 << iota - TC_U32_VAROFFSET = 1 << iota - TC_U32_EAT = 1 << iota -) - -type TcU32Sel struct { - Flags uint8 - Offshift uint8 - Nkeys uint8 - Pad uint8 - Offmask uint16 // big endian - Off uint16 - Offoff int16 - Hoff int16 - Hmask uint32 // big endian - Keys []TcU32Key -} - -func (msg *TcU32Sel) Len() int { - return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key -} - -func DeserializeTcU32Sel(b []byte) *TcU32Sel { - x := &TcU32Sel{} - copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b) - next := SizeofTcU32Sel - var i uint8 - for i = 0; i < x.Nkeys; i++ { - x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:])) - next += SizeofTcU32Key - } - return x -} - -func (x *TcU32Sel) Serialize() []byte { - // This can't just unsafe.cast because it must iterate through keys. - buf := make([]byte, x.Len()) - copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:]) - next := SizeofTcU32Sel - for _, key := range x.Keys { - keyBuf := key.Serialize() - copy(buf[next:], keyBuf) - next += SizeofTcU32Key - } - return buf -} - -type TcGen struct { - Index uint32 - Capab uint32 - Action int32 - Refcnt int32 - Bindcnt int32 -} - -func (msg *TcGen) Len() int { - return SizeofTcGen -} - -func DeserializeTcGen(b []byte) *TcGen { - return (*TcGen)(unsafe.Pointer(&b[0:SizeofTcGen][0])) -} - -func (x *TcGen) Serialize() []byte { - return (*(*[SizeofTcGen]byte)(unsafe.Pointer(x)))[:] -} - -// #define tc_gen \ -// __u32 index; \ -// __u32 capab; \ -// int action; \ -// int refcnt; \ -// int bindcnt - -const ( - TCA_ACT_GACT = 5 -) - -const ( - TCA_GACT_UNSPEC = iota - TCA_GACT_TM - TCA_GACT_PARMS - TCA_GACT_PROB - TCA_GACT_MAX = TCA_GACT_PROB -) - -type TcGact TcGen - -const ( - TCA_ACT_BPF = 13 -) - -const ( - TCA_ACT_BPF_UNSPEC = iota - TCA_ACT_BPF_TM - TCA_ACT_BPF_PARMS - TCA_ACT_BPF_OPS_LEN - TCA_ACT_BPF_OPS - TCA_ACT_BPF_FD - TCA_ACT_BPF_NAME - TCA_ACT_BPF_MAX = TCA_ACT_BPF_NAME -) - -const ( - TCA_BPF_FLAG_ACT_DIRECT uint32 = 1 << iota -) - -const ( - TCA_BPF_UNSPEC = iota - TCA_BPF_ACT - TCA_BPF_POLICE - TCA_BPF_CLASSID - TCA_BPF_OPS_LEN - TCA_BPF_OPS - TCA_BPF_FD - TCA_BPF_NAME - TCA_BPF_FLAGS - TCA_BPF_FLAGS_GEN - TCA_BPF_TAG - TCA_BPF_ID - TCA_BPF_MAX = TCA_BPF_ID -) - -type TcBpf TcGen - -const ( - TCA_ACT_CONNMARK = 14 -) - -const ( - TCA_CONNMARK_UNSPEC = iota - TCA_CONNMARK_PARMS - TCA_CONNMARK_TM - TCA_CONNMARK_MAX = TCA_CONNMARK_TM -) - -// struct tc_connmark { -// tc_gen; -// __u16 zone; -// }; - -type TcConnmark struct { - TcGen - Zone uint16 -} - -func (msg *TcConnmark) Len() int { - return SizeofTcConnmark -} - -func DeserializeTcConnmark(b []byte) *TcConnmark { - return (*TcConnmark)(unsafe.Pointer(&b[0:SizeofTcConnmark][0])) -} - -func (x *TcConnmark) Serialize() []byte { - return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_ACT_MIRRED = 8 -) - -const ( - TCA_MIRRED_UNSPEC = iota - TCA_MIRRED_TM - TCA_MIRRED_PARMS - TCA_MIRRED_MAX = TCA_MIRRED_PARMS -) - -// struct tc_mirred { -// tc_gen; -// int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ -// __u32 ifindex; /* ifindex of egress port */ -// }; - -type TcMirred struct { - TcGen - Eaction int32 - Ifindex uint32 -} - -func (msg *TcMirred) Len() int { - return SizeofTcMirred -} - -func DeserializeTcMirred(b []byte) *TcMirred { - return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0])) -} - -func (x *TcMirred) Serialize() []byte { - return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_TUNNEL_KEY_UNSPEC = iota - TCA_TUNNEL_KEY_TM - TCA_TUNNEL_KEY_PARMS - TCA_TUNNEL_KEY_ENC_IPV4_SRC - TCA_TUNNEL_KEY_ENC_IPV4_DST - TCA_TUNNEL_KEY_ENC_IPV6_SRC - TCA_TUNNEL_KEY_ENC_IPV6_DST - TCA_TUNNEL_KEY_ENC_KEY_ID - TCA_TUNNEL_KEY_PAD - TCA_TUNNEL_KEY_ENC_DST_PORT - TCA_TUNNEL_KEY_NO_CSUM - TCA_TUNNEL_KEY_ENC_OPTS - TCA_TUNNEL_KEY_ENC_TOS - TCA_TUNNEL_KEY_ENC_TTL - TCA_TUNNEL_KEY_MAX -) - -type TcTunnelKey struct { - TcGen - Action int32 -} - -func (x *TcTunnelKey) Len() int { - return SizeofTcTunnelKey -} - -func DeserializeTunnelKey(b []byte) *TcTunnelKey { - return (*TcTunnelKey)(unsafe.Pointer(&b[0:SizeofTcTunnelKey][0])) -} - -func (x *TcTunnelKey) Serialize() []byte { - return (*(*[SizeofTcTunnelKey]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_SKBEDIT_UNSPEC = iota - TCA_SKBEDIT_TM - TCA_SKBEDIT_PARMS - TCA_SKBEDIT_PRIORITY - TCA_SKBEDIT_QUEUE_MAPPING - TCA_SKBEDIT_MARK - TCA_SKBEDIT_PAD - TCA_SKBEDIT_PTYPE - TCA_SKBEDIT_MAX = TCA_SKBEDIT_MARK -) - -type TcSkbEdit struct { - TcGen -} - -func (x *TcSkbEdit) Len() int { - return SizeofTcSkbEdit -} - -func DeserializeSkbEdit(b []byte) *TcSkbEdit { - return (*TcSkbEdit)(unsafe.Pointer(&b[0:SizeofTcSkbEdit][0])) -} - -func (x *TcSkbEdit) Serialize() []byte { - return (*(*[SizeofTcSkbEdit]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_police { -// __u32 index; -// int action; -// __u32 limit; -// __u32 burst; -// __u32 mtu; -// struct tc_ratespec rate; -// struct tc_ratespec peakrate; -// int refcnt; -// int bindcnt; -// __u32 capab; -// }; - -type TcPolice struct { - Index uint32 - Action int32 - Limit uint32 - Burst uint32 - Mtu uint32 - Rate TcRateSpec - PeakRate TcRateSpec - Refcnt int32 - Bindcnt int32 - Capab uint32 -} - -func (msg *TcPolice) Len() int { - return SizeofTcPolice -} - -func DeserializeTcPolice(b []byte) *TcPolice { - return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0])) -} - -func (x *TcPolice) Serialize() []byte { - return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:] -} - -const ( - TCA_FW_UNSPEC = iota - TCA_FW_CLASSID - TCA_FW_POLICE - TCA_FW_INDEV - TCA_FW_ACT - TCA_FW_MASK - TCA_FW_MAX = TCA_FW_MASK -) - -const ( - TCA_MATCHALL_UNSPEC = iota - TCA_MATCHALL_CLASSID - TCA_MATCHALL_ACT - TCA_MATCHALL_FLAGS -) - -const ( - TCA_FQ_UNSPEC = iota - TCA_FQ_PLIMIT // limit of total number of packets in queue - TCA_FQ_FLOW_PLIMIT // limit of packets per flow - TCA_FQ_QUANTUM // RR quantum - TCA_FQ_INITIAL_QUANTUM // RR quantum for new flow - TCA_FQ_RATE_ENABLE // enable/disable rate limiting - TCA_FQ_FLOW_DEFAULT_RATE // obsolete do not use - TCA_FQ_FLOW_MAX_RATE // per flow max rate - TCA_FQ_BUCKETS_LOG // log2(number of buckets) - TCA_FQ_FLOW_REFILL_DELAY // flow credit refill delay in usec - TCA_FQ_ORPHAN_MASK // mask applied to orphaned skb hashes - TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate -) - -const ( - TCA_FQ_CODEL_UNSPEC = iota - TCA_FQ_CODEL_TARGET - TCA_FQ_CODEL_LIMIT - TCA_FQ_CODEL_INTERVAL - TCA_FQ_CODEL_ECN - TCA_FQ_CODEL_FLOWS - TCA_FQ_CODEL_QUANTUM - TCA_FQ_CODEL_CE_THRESHOLD - TCA_FQ_CODEL_DROP_BATCH_SIZE - TCA_FQ_CODEL_MEMORY_LIMIT -) - -const ( - TCA_HFSC_UNSPEC = iota - TCA_HFSC_RSC - TCA_HFSC_FSC - TCA_HFSC_USC -) - -const ( - TCA_FLOWER_UNSPEC = iota - TCA_FLOWER_CLASSID - TCA_FLOWER_INDEV - TCA_FLOWER_ACT - TCA_FLOWER_KEY_ETH_DST /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_DST_MASK /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_SRC /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_SRC_MASK /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_TYPE /* be16 */ - TCA_FLOWER_KEY_IP_PROTO /* u8 */ - TCA_FLOWER_KEY_IPV4_SRC /* be32 */ - TCA_FLOWER_KEY_IPV4_SRC_MASK /* be32 */ - TCA_FLOWER_KEY_IPV4_DST /* be32 */ - TCA_FLOWER_KEY_IPV4_DST_MASK /* be32 */ - TCA_FLOWER_KEY_IPV6_SRC /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_SRC_MASK /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_DST /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_DST_MASK /* struct in6_addr */ - TCA_FLOWER_KEY_TCP_SRC /* be16 */ - TCA_FLOWER_KEY_TCP_DST /* be16 */ - TCA_FLOWER_KEY_UDP_SRC /* be16 */ - TCA_FLOWER_KEY_UDP_DST /* be16 */ - - TCA_FLOWER_FLAGS - TCA_FLOWER_KEY_VLAN_ID /* be16 */ - TCA_FLOWER_KEY_VLAN_PRIO /* u8 */ - TCA_FLOWER_KEY_VLAN_ETH_TYPE /* be16 */ - - TCA_FLOWER_KEY_ENC_KEY_ID /* be32 */ - TCA_FLOWER_KEY_ENC_IPV4_SRC /* be32 */ - TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK /* be32 */ - TCA_FLOWER_KEY_ENC_IPV4_DST /* be32 */ - TCA_FLOWER_KEY_ENC_IPV4_DST_MASK /* be32 */ - TCA_FLOWER_KEY_ENC_IPV6_SRC /* struct in6_addr */ - TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK /* struct in6_addr */ - TCA_FLOWER_KEY_ENC_IPV6_DST /* struct in6_addr */ - TCA_FLOWER_KEY_ENC_IPV6_DST_MASK /* struct in6_addr */ - - TCA_FLOWER_KEY_TCP_SRC_MASK /* be16 */ - TCA_FLOWER_KEY_TCP_DST_MASK /* be16 */ - TCA_FLOWER_KEY_UDP_SRC_MASK /* be16 */ - TCA_FLOWER_KEY_UDP_DST_MASK /* be16 */ - TCA_FLOWER_KEY_SCTP_SRC_MASK /* be16 */ - TCA_FLOWER_KEY_SCTP_DST_MASK /* be16 */ - - TCA_FLOWER_KEY_SCTP_SRC /* be16 */ - TCA_FLOWER_KEY_SCTP_DST /* be16 */ - - TCA_FLOWER_KEY_ENC_UDP_SRC_PORT /* be16 */ - TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK /* be16 */ - TCA_FLOWER_KEY_ENC_UDP_DST_PORT /* be16 */ - TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK /* be16 */ - - TCA_FLOWER_KEY_FLAGS /* be32 */ - TCA_FLOWER_KEY_FLAGS_MASK /* be32 */ - - TCA_FLOWER_KEY_ICMPV4_CODE /* u8 */ - TCA_FLOWER_KEY_ICMPV4_CODE_MASK /* u8 */ - TCA_FLOWER_KEY_ICMPV4_TYPE /* u8 */ - TCA_FLOWER_KEY_ICMPV4_TYPE_MASK /* u8 */ - TCA_FLOWER_KEY_ICMPV6_CODE /* u8 */ - TCA_FLOWER_KEY_ICMPV6_CODE_MASK /* u8 */ - TCA_FLOWER_KEY_ICMPV6_TYPE /* u8 */ - TCA_FLOWER_KEY_ICMPV6_TYPE_MASK /* u8 */ - - TCA_FLOWER_KEY_ARP_SIP /* be32 */ - TCA_FLOWER_KEY_ARP_SIP_MASK /* be32 */ - TCA_FLOWER_KEY_ARP_TIP /* be32 */ - TCA_FLOWER_KEY_ARP_TIP_MASK /* be32 */ - TCA_FLOWER_KEY_ARP_OP /* u8 */ - TCA_FLOWER_KEY_ARP_OP_MASK /* u8 */ - TCA_FLOWER_KEY_ARP_SHA /* ETH_ALEN */ - TCA_FLOWER_KEY_ARP_SHA_MASK /* ETH_ALEN */ - TCA_FLOWER_KEY_ARP_THA /* ETH_ALEN */ - TCA_FLOWER_KEY_ARP_THA_MASK /* ETH_ALEN */ - - TCA_FLOWER_KEY_MPLS_TTL /* u8 - 8 bits */ - TCA_FLOWER_KEY_MPLS_BOS /* u8 - 1 bit */ - TCA_FLOWER_KEY_MPLS_TC /* u8 - 3 bits */ - TCA_FLOWER_KEY_MPLS_LABEL /* be32 - 20 bits */ - - TCA_FLOWER_KEY_TCP_FLAGS /* be16 */ - TCA_FLOWER_KEY_TCP_FLAGS_MASK /* be16 */ - - TCA_FLOWER_KEY_IP_TOS /* u8 */ - TCA_FLOWER_KEY_IP_TOS_MASK /* u8 */ - TCA_FLOWER_KEY_IP_TTL /* u8 */ - TCA_FLOWER_KEY_IP_TTL_MASK /* u8 */ - - TCA_FLOWER_KEY_CVLAN_ID /* be16 */ - TCA_FLOWER_KEY_CVLAN_PRIO /* u8 */ - TCA_FLOWER_KEY_CVLAN_ETH_TYPE /* be16 */ - - TCA_FLOWER_KEY_ENC_IP_TOS /* u8 */ - TCA_FLOWER_KEY_ENC_IP_TOS_MASK /* u8 */ - TCA_FLOWER_KEY_ENC_IP_TTL /* u8 */ - TCA_FLOWER_KEY_ENC_IP_TTL_MASK /* u8 */ - - TCA_FLOWER_KEY_ENC_OPTS - TCA_FLOWER_KEY_ENC_OPTS_MASK - - __TCA_FLOWER_MAX -) - -// struct tc_sfq_qopt { -// unsigned quantum; /* Bytes per round allocated to flow */ -// int perturb_period; /* Period of hash perturbation */ -// __u32 limit; /* Maximal packets in queue */ -// unsigned divisor; /* Hash divisor */ -// unsigned flows; /* Maximal number of flows */ -// }; - -type TcSfqQopt struct { - Quantum uint8 - Perturb int32 - Limit uint32 - Divisor uint8 - Flows uint8 -} - -func (x *TcSfqQopt) Len() int { - return SizeofTcSfqQopt -} - -func DeserializeTcSfqQopt(b []byte) *TcSfqQopt { - return (*TcSfqQopt)(unsafe.Pointer(&b[0:SizeofTcSfqQopt][0])) -} - -func (x *TcSfqQopt) Serialize() []byte { - return (*(*[SizeofTcSfqQopt]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_sfqred_stats { -// __u32 prob_drop; /* Early drops, below max threshold */ -// __u32 forced_drop; /* Early drops, after max threshold */ -// __u32 prob_mark; /* Marked packets, below max threshold */ -// __u32 forced_mark; /* Marked packets, after max threshold */ -// __u32 prob_mark_head; /* Marked packets, below max threshold */ -// __u32 forced_mark_head;/* Marked packets, after max threshold */ -// }; -type TcSfqRedStats struct { - ProbDrop uint32 - ForcedDrop uint32 - ProbMark uint32 - ForcedMark uint32 - ProbMarkHead uint32 - ForcedMarkHead uint32 -} - -func (x *TcSfqRedStats) Len() int { - return SizeofTcSfqRedStats -} - -func DeserializeTcSfqRedStats(b []byte) *TcSfqRedStats { - return (*TcSfqRedStats)(unsafe.Pointer(&b[0:SizeofTcSfqRedStats][0])) -} - -func (x *TcSfqRedStats) Serialize() []byte { - return (*(*[SizeofTcSfqRedStats]byte)(unsafe.Pointer(x)))[:] -} - -// struct tc_sfq_qopt_v1 { -// struct tc_sfq_qopt v0; -// unsigned int depth; /* max number of packets per flow */ -// unsigned int headdrop; -// /* SFQRED parameters */ -// __u32 limit; /* HARD maximal flow queue length (bytes) */ -// __u32 qth_min; /* Min average length threshold (bytes) */ -// __u32 qth_max; /* Max average length threshold (bytes) */ -// unsigned char Wlog; /* log(W) */ -// unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */ -// unsigned char Scell_log; /* cell size for idle damping */ -// unsigned char flags; -// __u32 max_P; /* probability, high resolution */ -// /* SFQRED stats */ -// struct tc_sfqred_stats stats; -// }; -type TcSfqQoptV1 struct { - TcSfqQopt - Depth uint32 - HeadDrop uint32 - Limit uint32 - QthMin uint32 - QthMax uint32 - Wlog byte - Plog byte - ScellLog byte - Flags byte - MaxP uint32 - TcSfqRedStats -} - -func (x *TcSfqQoptV1) Len() int { - return SizeofTcSfqQoptV1 -} - -func DeserializeTcSfqQoptV1(b []byte) *TcSfqQoptV1 { - return (*TcSfqQoptV1)(unsafe.Pointer(&b[0:SizeofTcSfqQoptV1][0])) -} - -func (x *TcSfqQoptV1) Serialize() []byte { - return (*(*[SizeofTcSfqQoptV1]byte)(unsafe.Pointer(x)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/xfrm_linux.go b/vendor/github.com/tailscale/netlink/nl/xfrm_linux.go deleted file mode 100644 index dce9073..0000000 --- a/vendor/github.com/tailscale/netlink/nl/xfrm_linux.go +++ /dev/null @@ -1,306 +0,0 @@ -package nl - -import ( - "bytes" - "net" - "unsafe" -) - -// Infinity for packet and byte counts -const ( - XFRM_INF = ^uint64(0) -) - -type XfrmMsgType uint8 - -type XfrmMsg interface { - Type() XfrmMsgType -} - -// Message Types -const ( - XFRM_MSG_BASE XfrmMsgType = 0x10 - XFRM_MSG_NEWSA = 0x10 - XFRM_MSG_DELSA = 0x11 - XFRM_MSG_GETSA = 0x12 - XFRM_MSG_NEWPOLICY = 0x13 - XFRM_MSG_DELPOLICY = 0x14 - XFRM_MSG_GETPOLICY = 0x15 - XFRM_MSG_ALLOCSPI = 0x16 - XFRM_MSG_ACQUIRE = 0x17 - XFRM_MSG_EXPIRE = 0x18 - XFRM_MSG_UPDPOLICY = 0x19 - XFRM_MSG_UPDSA = 0x1a - XFRM_MSG_POLEXPIRE = 0x1b - XFRM_MSG_FLUSHSA = 0x1c - XFRM_MSG_FLUSHPOLICY = 0x1d - XFRM_MSG_NEWAE = 0x1e - XFRM_MSG_GETAE = 0x1f - XFRM_MSG_REPORT = 0x20 - XFRM_MSG_MIGRATE = 0x21 - XFRM_MSG_NEWSADINFO = 0x22 - XFRM_MSG_GETSADINFO = 0x23 - XFRM_MSG_NEWSPDINFO = 0x24 - XFRM_MSG_GETSPDINFO = 0x25 - XFRM_MSG_MAPPING = 0x26 - XFRM_MSG_MAX = 0x26 - XFRM_NR_MSGTYPES = 0x17 -) - -// Attribute types -const ( - /* Netlink message attributes. */ - XFRMA_UNSPEC = iota - XFRMA_ALG_AUTH /* struct xfrm_algo */ - XFRMA_ALG_CRYPT /* struct xfrm_algo */ - XFRMA_ALG_COMP /* struct xfrm_algo */ - XFRMA_ENCAP /* struct xfrm_algo + struct xfrm_encap_tmpl */ - XFRMA_TMPL /* 1 or more struct xfrm_user_tmpl */ - XFRMA_SA /* struct xfrm_usersa_info */ - XFRMA_POLICY /* struct xfrm_userpolicy_info */ - XFRMA_SEC_CTX /* struct xfrm_sec_ctx */ - XFRMA_LTIME_VAL - XFRMA_REPLAY_VAL - XFRMA_REPLAY_THRESH - XFRMA_ETIMER_THRESH - XFRMA_SRCADDR /* xfrm_address_t */ - XFRMA_COADDR /* xfrm_address_t */ - XFRMA_LASTUSED /* unsigned long */ - XFRMA_POLICY_TYPE /* struct xfrm_userpolicy_type */ - XFRMA_MIGRATE - XFRMA_ALG_AEAD /* struct xfrm_algo_aead */ - XFRMA_KMADDRESS /* struct xfrm_user_kmaddress */ - XFRMA_ALG_AUTH_TRUNC /* struct xfrm_algo_auth */ - XFRMA_MARK /* struct xfrm_mark */ - XFRMA_TFCPAD /* __u32 */ - XFRMA_REPLAY_ESN_VAL /* struct xfrm_replay_esn */ - XFRMA_SA_EXTRA_FLAGS /* __u32 */ - XFRMA_PROTO /* __u8 */ - XFRMA_ADDRESS_FILTER /* struct xfrm_address_filter */ - XFRMA_PAD - XFRMA_OFFLOAD_DEV /* struct xfrm_state_offload */ - XFRMA_SET_MARK /* __u32 */ - XFRMA_SET_MARK_MASK /* __u32 */ - XFRMA_IF_ID /* __u32 */ - - XFRMA_MAX = iota - 1 -) - -const XFRMA_OUTPUT_MARK = XFRMA_SET_MARK - -const ( - SizeofXfrmAddress = 0x10 - SizeofXfrmSelector = 0x38 - SizeofXfrmLifetimeCfg = 0x40 - SizeofXfrmLifetimeCur = 0x20 - SizeofXfrmId = 0x18 - SizeofXfrmMark = 0x08 -) - -// Netlink groups -const ( - XFRMNLGRP_NONE = 0x0 - XFRMNLGRP_ACQUIRE = 0x1 - XFRMNLGRP_EXPIRE = 0x2 - XFRMNLGRP_SA = 0x3 - XFRMNLGRP_POLICY = 0x4 - XFRMNLGRP_AEVENTS = 0x5 - XFRMNLGRP_REPORT = 0x6 - XFRMNLGRP_MIGRATE = 0x7 - XFRMNLGRP_MAPPING = 0x8 - __XFRMNLGRP_MAX = 0x9 -) - -// typedef union { -// __be32 a4; -// __be32 a6[4]; -// } xfrm_address_t; - -type XfrmAddress [SizeofXfrmAddress]byte - -func (x *XfrmAddress) ToIP() net.IP { - var empty = [12]byte{} - ip := make(net.IP, net.IPv6len) - if bytes.Equal(x[4:16], empty[:]) { - ip[10] = 0xff - ip[11] = 0xff - copy(ip[12:16], x[0:4]) - } else { - copy(ip[:], x[:]) - } - return ip -} - -func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet { - ip := x.ToIP() - if GetIPFamily(ip) == FAMILY_V4 { - return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)} - } - return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 128)} -} - -func (x *XfrmAddress) FromIP(ip net.IP) { - var empty = [16]byte{} - if len(ip) < net.IPv4len { - copy(x[4:16], empty[:]) - } else if GetIPFamily(ip) == FAMILY_V4 { - copy(x[0:4], ip.To4()[0:4]) - copy(x[4:16], empty[:12]) - } else { - copy(x[0:16], ip.To16()[0:16]) - } -} - -func DeserializeXfrmAddress(b []byte) *XfrmAddress { - return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0])) -} - -func (x *XfrmAddress) Serialize() []byte { - return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(x)))[:] -} - -// struct xfrm_selector { -// xfrm_address_t daddr; -// xfrm_address_t saddr; -// __be16 dport; -// __be16 dport_mask; -// __be16 sport; -// __be16 sport_mask; -// __u16 family; -// __u8 prefixlen_d; -// __u8 prefixlen_s; -// __u8 proto; -// int ifindex; -// __kernel_uid32_t user; -// }; - -type XfrmSelector struct { - Daddr XfrmAddress - Saddr XfrmAddress - Dport uint16 // big endian - DportMask uint16 // big endian - Sport uint16 // big endian - SportMask uint16 // big endian - Family uint16 - PrefixlenD uint8 - PrefixlenS uint8 - Proto uint8 - Pad [3]byte - Ifindex int32 - User uint32 -} - -func (msg *XfrmSelector) Len() int { - return SizeofXfrmSelector -} - -func DeserializeXfrmSelector(b []byte) *XfrmSelector { - return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0])) -} - -func (msg *XfrmSelector) Serialize() []byte { - return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_lifetime_cfg { -// __u64 soft_byte_limit; -// __u64 hard_byte_limit; -// __u64 soft_packet_limit; -// __u64 hard_packet_limit; -// __u64 soft_add_expires_seconds; -// __u64 hard_add_expires_seconds; -// __u64 soft_use_expires_seconds; -// __u64 hard_use_expires_seconds; -// }; -// - -type XfrmLifetimeCfg struct { - SoftByteLimit uint64 - HardByteLimit uint64 - SoftPacketLimit uint64 - HardPacketLimit uint64 - SoftAddExpiresSeconds uint64 - HardAddExpiresSeconds uint64 - SoftUseExpiresSeconds uint64 - HardUseExpiresSeconds uint64 -} - -func (msg *XfrmLifetimeCfg) Len() int { - return SizeofXfrmLifetimeCfg -} - -func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg { - return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0])) -} - -func (msg *XfrmLifetimeCfg) Serialize() []byte { - return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_lifetime_cur { -// __u64 bytes; -// __u64 packets; -// __u64 add_time; -// __u64 use_time; -// }; - -type XfrmLifetimeCur struct { - Bytes uint64 - Packets uint64 - AddTime uint64 - UseTime uint64 -} - -func (msg *XfrmLifetimeCur) Len() int { - return SizeofXfrmLifetimeCur -} - -func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur { - return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0])) -} - -func (msg *XfrmLifetimeCur) Serialize() []byte { - return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_id { -// xfrm_address_t daddr; -// __be32 spi; -// __u8 proto; -// }; - -type XfrmId struct { - Daddr XfrmAddress - Spi uint32 // big endian - Proto uint8 - Pad [3]byte -} - -func (msg *XfrmId) Len() int { - return SizeofXfrmId -} - -func DeserializeXfrmId(b []byte) *XfrmId { - return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0])) -} - -func (msg *XfrmId) Serialize() []byte { - return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:] -} - -type XfrmMark struct { - Value uint32 - Mask uint32 -} - -func (msg *XfrmMark) Len() int { - return SizeofXfrmMark -} - -func DeserializeXfrmMark(b []byte) *XfrmMark { - return (*XfrmMark)(unsafe.Pointer(&b[0:SizeofXfrmMark][0])) -} - -func (msg *XfrmMark) Serialize() []byte { - return (*(*[SizeofXfrmMark]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/xfrm_monitor_linux.go b/vendor/github.com/tailscale/netlink/nl/xfrm_monitor_linux.go deleted file mode 100644 index 715df4c..0000000 --- a/vendor/github.com/tailscale/netlink/nl/xfrm_monitor_linux.go +++ /dev/null @@ -1,32 +0,0 @@ -package nl - -import ( - "unsafe" -) - -const ( - SizeofXfrmUserExpire = 0xe8 -) - -// struct xfrm_user_expire { -// struct xfrm_usersa_info state; -// __u8 hard; -// }; - -type XfrmUserExpire struct { - XfrmUsersaInfo XfrmUsersaInfo - Hard uint8 - Pad [7]byte -} - -func (msg *XfrmUserExpire) Len() int { - return SizeofXfrmUserExpire -} - -func DeserializeXfrmUserExpire(b []byte) *XfrmUserExpire { - return (*XfrmUserExpire)(unsafe.Pointer(&b[0:SizeofXfrmUserExpire][0])) -} - -func (msg *XfrmUserExpire) Serialize() []byte { - return (*(*[SizeofXfrmUserExpire]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/xfrm_policy_linux.go b/vendor/github.com/tailscale/netlink/nl/xfrm_policy_linux.go deleted file mode 100644 index 66f7e03..0000000 --- a/vendor/github.com/tailscale/netlink/nl/xfrm_policy_linux.go +++ /dev/null @@ -1,119 +0,0 @@ -package nl - -import ( - "unsafe" -) - -const ( - SizeofXfrmUserpolicyId = 0x40 - SizeofXfrmUserpolicyInfo = 0xa8 - SizeofXfrmUserTmpl = 0x40 -) - -// struct xfrm_userpolicy_id { -// struct xfrm_selector sel; -// __u32 index; -// __u8 dir; -// }; -// - -type XfrmUserpolicyId struct { - Sel XfrmSelector - Index uint32 - Dir uint8 - Pad [3]byte -} - -func (msg *XfrmUserpolicyId) Len() int { - return SizeofXfrmUserpolicyId -} - -func DeserializeXfrmUserpolicyId(b []byte) *XfrmUserpolicyId { - return (*XfrmUserpolicyId)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyId][0])) -} - -func (msg *XfrmUserpolicyId) Serialize() []byte { - return (*(*[SizeofXfrmUserpolicyId]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_userpolicy_info { -// struct xfrm_selector sel; -// struct xfrm_lifetime_cfg lft; -// struct xfrm_lifetime_cur curlft; -// __u32 priority; -// __u32 index; -// __u8 dir; -// __u8 action; -// #define XFRM_POLICY_ALLOW 0 -// #define XFRM_POLICY_BLOCK 1 -// __u8 flags; -// #define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */ -// /* Automatically expand selector to include matching ICMP payloads. */ -// #define XFRM_POLICY_ICMP 2 -// __u8 share; -// }; - -type XfrmUserpolicyInfo struct { - Sel XfrmSelector - Lft XfrmLifetimeCfg - Curlft XfrmLifetimeCur - Priority uint32 - Index uint32 - Dir uint8 - Action uint8 - Flags uint8 - Share uint8 - Pad [4]byte -} - -func (msg *XfrmUserpolicyInfo) Len() int { - return SizeofXfrmUserpolicyInfo -} - -func DeserializeXfrmUserpolicyInfo(b []byte) *XfrmUserpolicyInfo { - return (*XfrmUserpolicyInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyInfo][0])) -} - -func (msg *XfrmUserpolicyInfo) Serialize() []byte { - return (*(*[SizeofXfrmUserpolicyInfo]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_user_tmpl { -// struct xfrm_id id; -// __u16 family; -// xfrm_address_t saddr; -// __u32 reqid; -// __u8 mode; -// __u8 share; -// __u8 optional; -// __u32 aalgos; -// __u32 ealgos; -// __u32 calgos; -// } - -type XfrmUserTmpl struct { - XfrmId XfrmId - Family uint16 - Pad1 [2]byte - Saddr XfrmAddress - Reqid uint32 - Mode uint8 - Share uint8 - Optional uint8 - Pad2 byte - Aalgos uint32 - Ealgos uint32 - Calgos uint32 -} - -func (msg *XfrmUserTmpl) Len() int { - return SizeofXfrmUserTmpl -} - -func DeserializeXfrmUserTmpl(b []byte) *XfrmUserTmpl { - return (*XfrmUserTmpl)(unsafe.Pointer(&b[0:SizeofXfrmUserTmpl][0])) -} - -func (msg *XfrmUserTmpl) Serialize() []byte { - return (*(*[SizeofXfrmUserTmpl]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/nl/xfrm_state_linux.go b/vendor/github.com/tailscale/netlink/nl/xfrm_state_linux.go deleted file mode 100644 index 43a947f..0000000 --- a/vendor/github.com/tailscale/netlink/nl/xfrm_state_linux.go +++ /dev/null @@ -1,334 +0,0 @@ -package nl - -import ( - "unsafe" -) - -const ( - SizeofXfrmUsersaId = 0x18 - SizeofXfrmStats = 0x0c - SizeofXfrmUsersaInfo = 0xe0 - SizeofXfrmUserSpiInfo = 0xe8 - SizeofXfrmAlgo = 0x44 - SizeofXfrmAlgoAuth = 0x48 - SizeofXfrmAlgoAEAD = 0x48 - SizeofXfrmEncapTmpl = 0x18 - SizeofXfrmUsersaFlush = 0x1 - SizeofXfrmReplayStateEsn = 0x18 -) - -const ( - XFRM_STATE_NOECN = 1 - XFRM_STATE_DECAP_DSCP = 2 - XFRM_STATE_NOPMTUDISC = 4 - XFRM_STATE_WILDRECV = 8 - XFRM_STATE_ICMP = 16 - XFRM_STATE_AF_UNSPEC = 32 - XFRM_STATE_ALIGN4 = 64 - XFRM_STATE_ESN = 128 -) - -// struct xfrm_usersa_id { -// xfrm_address_t daddr; -// __be32 spi; -// __u16 family; -// __u8 proto; -// }; - -type XfrmUsersaId struct { - Daddr XfrmAddress - Spi uint32 // big endian - Family uint16 - Proto uint8 - Pad byte -} - -func (msg *XfrmUsersaId) Len() int { - return SizeofXfrmUsersaId -} - -func DeserializeXfrmUsersaId(b []byte) *XfrmUsersaId { - return (*XfrmUsersaId)(unsafe.Pointer(&b[0:SizeofXfrmUsersaId][0])) -} - -func (msg *XfrmUsersaId) Serialize() []byte { - return (*(*[SizeofXfrmUsersaId]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_stats { -// __u32 replay_window; -// __u32 replay; -// __u32 integrity_failed; -// }; - -type XfrmStats struct { - ReplayWindow uint32 - Replay uint32 - IntegrityFailed uint32 -} - -func (msg *XfrmStats) Len() int { - return SizeofXfrmStats -} - -func DeserializeXfrmStats(b []byte) *XfrmStats { - return (*XfrmStats)(unsafe.Pointer(&b[0:SizeofXfrmStats][0])) -} - -func (msg *XfrmStats) Serialize() []byte { - return (*(*[SizeofXfrmStats]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_usersa_info { -// struct xfrm_selector sel; -// struct xfrm_id id; -// xfrm_address_t saddr; -// struct xfrm_lifetime_cfg lft; -// struct xfrm_lifetime_cur curlft; -// struct xfrm_stats stats; -// __u32 seq; -// __u32 reqid; -// __u16 family; -// __u8 mode; /* XFRM_MODE_xxx */ -// __u8 replay_window; -// __u8 flags; -// #define XFRM_STATE_NOECN 1 -// #define XFRM_STATE_DECAP_DSCP 2 -// #define XFRM_STATE_NOPMTUDISC 4 -// #define XFRM_STATE_WILDRECV 8 -// #define XFRM_STATE_ICMP 16 -// #define XFRM_STATE_AF_UNSPEC 32 -// #define XFRM_STATE_ALIGN4 64 -// #define XFRM_STATE_ESN 128 -// }; -// -// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1 -// - -type XfrmUsersaInfo struct { - Sel XfrmSelector - Id XfrmId - Saddr XfrmAddress - Lft XfrmLifetimeCfg - Curlft XfrmLifetimeCur - Stats XfrmStats - Seq uint32 - Reqid uint32 - Family uint16 - Mode uint8 - ReplayWindow uint8 - Flags uint8 - Pad [7]byte -} - -func (msg *XfrmUsersaInfo) Len() int { - return SizeofXfrmUsersaInfo -} - -func DeserializeXfrmUsersaInfo(b []byte) *XfrmUsersaInfo { - return (*XfrmUsersaInfo)(unsafe.Pointer(&b[0:SizeofXfrmUsersaInfo][0])) -} - -func (msg *XfrmUsersaInfo) Serialize() []byte { - return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_userspi_info { -// struct xfrm_usersa_info info; -// __u32 min; -// __u32 max; -// }; - -type XfrmUserSpiInfo struct { - XfrmUsersaInfo XfrmUsersaInfo - Min uint32 - Max uint32 -} - -func (msg *XfrmUserSpiInfo) Len() int { - return SizeofXfrmUserSpiInfo -} - -func DeserializeXfrmUserSpiInfo(b []byte) *XfrmUserSpiInfo { - return (*XfrmUserSpiInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserSpiInfo][0])) -} - -func (msg *XfrmUserSpiInfo) Serialize() []byte { - return (*(*[SizeofXfrmUserSpiInfo]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_algo { -// char alg_name[64]; -// unsigned int alg_key_len; /* in bits */ -// char alg_key[0]; -// }; - -type XfrmAlgo struct { - AlgName [64]byte - AlgKeyLen uint32 - AlgKey []byte -} - -func (msg *XfrmAlgo) Len() int { - return SizeofXfrmAlgo + int(msg.AlgKeyLen/8) -} - -func DeserializeXfrmAlgo(b []byte) *XfrmAlgo { - ret := XfrmAlgo{} - copy(ret.AlgName[:], b[0:64]) - ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) - ret.AlgKey = b[68:ret.Len()] - return &ret -} - -func (msg *XfrmAlgo) Serialize() []byte { - b := make([]byte, msg.Len()) - copy(b[0:64], msg.AlgName[:]) - copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) - copy(b[68:msg.Len()], msg.AlgKey[:]) - return b -} - -// struct xfrm_algo_auth { -// char alg_name[64]; -// unsigned int alg_key_len; /* in bits */ -// unsigned int alg_trunc_len; /* in bits */ -// char alg_key[0]; -// }; - -type XfrmAlgoAuth struct { - AlgName [64]byte - AlgKeyLen uint32 - AlgTruncLen uint32 - AlgKey []byte -} - -func (msg *XfrmAlgoAuth) Len() int { - return SizeofXfrmAlgoAuth + int(msg.AlgKeyLen/8) -} - -func DeserializeXfrmAlgoAuth(b []byte) *XfrmAlgoAuth { - ret := XfrmAlgoAuth{} - copy(ret.AlgName[:], b[0:64]) - ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) - ret.AlgTruncLen = *(*uint32)(unsafe.Pointer(&b[68])) - ret.AlgKey = b[72:ret.Len()] - return &ret -} - -func (msg *XfrmAlgoAuth) Serialize() []byte { - b := make([]byte, msg.Len()) - copy(b[0:64], msg.AlgName[:]) - copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) - copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgTruncLen)))[:]) - copy(b[72:msg.Len()], msg.AlgKey[:]) - return b -} - -// struct xfrm_algo_aead { -// char alg_name[64]; -// unsigned int alg_key_len; /* in bits */ -// unsigned int alg_icv_len; /* in bits */ -// char alg_key[0]; -// } - -type XfrmAlgoAEAD struct { - AlgName [64]byte - AlgKeyLen uint32 - AlgICVLen uint32 - AlgKey []byte -} - -func (msg *XfrmAlgoAEAD) Len() int { - return SizeofXfrmAlgoAEAD + int(msg.AlgKeyLen/8) -} - -func DeserializeXfrmAlgoAEAD(b []byte) *XfrmAlgoAEAD { - ret := XfrmAlgoAEAD{} - copy(ret.AlgName[:], b[0:64]) - ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) - ret.AlgICVLen = *(*uint32)(unsafe.Pointer(&b[68])) - ret.AlgKey = b[72:ret.Len()] - return &ret -} - -func (msg *XfrmAlgoAEAD) Serialize() []byte { - b := make([]byte, msg.Len()) - copy(b[0:64], msg.AlgName[:]) - copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) - copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgICVLen)))[:]) - copy(b[72:msg.Len()], msg.AlgKey[:]) - return b -} - -// struct xfrm_encap_tmpl { -// __u16 encap_type; -// __be16 encap_sport; -// __be16 encap_dport; -// xfrm_address_t encap_oa; -// }; - -type XfrmEncapTmpl struct { - EncapType uint16 - EncapSport uint16 // big endian - EncapDport uint16 // big endian - Pad [2]byte - EncapOa XfrmAddress -} - -func (msg *XfrmEncapTmpl) Len() int { - return SizeofXfrmEncapTmpl -} - -func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl { - return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0])) -} - -func (msg *XfrmEncapTmpl) Serialize() []byte { - return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_usersa_flush { -// __u8 proto; -// }; - -type XfrmUsersaFlush struct { - Proto uint8 -} - -func (msg *XfrmUsersaFlush) Len() int { - return SizeofXfrmUsersaFlush -} - -func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush { - return (*XfrmUsersaFlush)(unsafe.Pointer(&b[0:SizeofXfrmUsersaFlush][0])) -} - -func (msg *XfrmUsersaFlush) Serialize() []byte { - return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:] -} - -// struct xfrm_replay_state_esn { -// unsigned int bmp_len; -// __u32 oseq; -// __u32 seq; -// __u32 oseq_hi; -// __u32 seq_hi; -// __u32 replay_window; -// __u32 bmp[0]; -// }; - -type XfrmReplayStateEsn struct { - BmpLen uint32 - OSeq uint32 - Seq uint32 - OSeqHi uint32 - SeqHi uint32 - ReplayWindow uint32 - Bmp []uint32 -} - -func (msg *XfrmReplayStateEsn) Serialize() []byte { - // We deliberately do not pass Bmp, as it gets set by the kernel. - return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:] -} diff --git a/vendor/github.com/tailscale/netlink/order.go b/vendor/github.com/tailscale/netlink/order.go deleted file mode 100644 index c3248ea..0000000 --- a/vendor/github.com/tailscale/netlink/order.go +++ /dev/null @@ -1,32 +0,0 @@ -package netlink - -import ( - "encoding/binary" - - "github.com/tailscale/netlink/nl" -) - -var ( - native = nl.NativeEndian() - networkOrder = binary.BigEndian -) - -func htonl(val uint32) []byte { - bytes := make([]byte, 4) - binary.BigEndian.PutUint32(bytes, val) - return bytes -} - -func htons(val uint16) []byte { - bytes := make([]byte, 2) - binary.BigEndian.PutUint16(bytes, val) - return bytes -} - -func ntohl(buf []byte) uint32 { - return binary.BigEndian.Uint32(buf) -} - -func ntohs(buf []byte) uint16 { - return binary.BigEndian.Uint16(buf) -} diff --git a/vendor/github.com/tailscale/netlink/protinfo.go b/vendor/github.com/tailscale/netlink/protinfo.go deleted file mode 100644 index 60b23b3..0000000 --- a/vendor/github.com/tailscale/netlink/protinfo.go +++ /dev/null @@ -1,62 +0,0 @@ -package netlink - -import ( - "strings" -) - -// Protinfo represents bridge flags from netlink. -type Protinfo struct { - Hairpin bool - Guard bool - FastLeave bool - RootBlock bool - Learning bool - Flood bool - ProxyArp bool - ProxyArpWiFi bool -} - -// String returns a list of enabled flags -func (prot *Protinfo) String() string { - if prot == nil { - return "" - } - - var boolStrings []string - if prot.Hairpin { - boolStrings = append(boolStrings, "Hairpin") - } - if prot.Guard { - boolStrings = append(boolStrings, "Guard") - } - if prot.FastLeave { - boolStrings = append(boolStrings, "FastLeave") - } - if prot.RootBlock { - boolStrings = append(boolStrings, "RootBlock") - } - if prot.Learning { - boolStrings = append(boolStrings, "Learning") - } - if prot.Flood { - boolStrings = append(boolStrings, "Flood") - } - if prot.ProxyArp { - boolStrings = append(boolStrings, "ProxyArp") - } - if prot.ProxyArpWiFi { - boolStrings = append(boolStrings, "ProxyArpWiFi") - } - return strings.Join(boolStrings, " ") -} - -func boolToByte(x bool) []byte { - if x { - return []byte{1} - } - return []byte{0} -} - -func byteToBool(x byte) bool { - return uint8(x) != 0 -} diff --git a/vendor/github.com/tailscale/netlink/protinfo_linux.go b/vendor/github.com/tailscale/netlink/protinfo_linux.go deleted file mode 100644 index d5fe605..0000000 --- a/vendor/github.com/tailscale/netlink/protinfo_linux.go +++ /dev/null @@ -1,74 +0,0 @@ -package netlink - -import ( - "fmt" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -func LinkGetProtinfo(link Link) (Protinfo, error) { - return pkgHandle.LinkGetProtinfo(link) -} - -func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) { - base := link.Attrs() - h.ensureIndex(base) - var pi Protinfo - req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) - msg := nl.NewIfInfomsg(unix.AF_BRIDGE) - req.AddData(msg) - msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) - if err != nil { - return pi, err - } - - for _, m := range msgs { - ans := nl.DeserializeIfInfomsg(m) - if int(ans.Index) != base.Index { - continue - } - attrs, err := nl.ParseRouteAttr(m[ans.Len():]) - if err != nil { - return pi, err - } - for _, attr := range attrs { - if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED { - continue - } - infos, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return pi, err - } - pi = parseProtinfo(infos) - - return pi, nil - } - } - return pi, fmt.Errorf("Device with index %d not found", base.Index) -} - -func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) { - for _, info := range infos { - switch info.Attr.Type { - case nl.IFLA_BRPORT_MODE: - pi.Hairpin = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_GUARD: - pi.Guard = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_FAST_LEAVE: - pi.FastLeave = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_PROTECT: - pi.RootBlock = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_LEARNING: - pi.Learning = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_UNICAST_FLOOD: - pi.Flood = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_PROXYARP: - pi.ProxyArp = byteToBool(info.Value[0]) - case nl.IFLA_BRPORT_PROXYARP_WIFI: - pi.ProxyArpWiFi = byteToBool(info.Value[0]) - } - } - return -} diff --git a/vendor/github.com/tailscale/netlink/qdisc.go b/vendor/github.com/tailscale/netlink/qdisc.go deleted file mode 100644 index f594c9c..0000000 --- a/vendor/github.com/tailscale/netlink/qdisc.go +++ /dev/null @@ -1,366 +0,0 @@ -package netlink - -import ( - "fmt" - "math" -) - -const ( - HANDLE_NONE = 0 - HANDLE_INGRESS = 0xFFFFFFF1 - HANDLE_CLSACT = HANDLE_INGRESS - HANDLE_ROOT = 0xFFFFFFFF - PRIORITY_MAP_LEN = 16 -) -const ( - HANDLE_MIN_INGRESS = 0xFFFFFFF2 - HANDLE_MIN_EGRESS = 0xFFFFFFF3 -) - -type Qdisc interface { - Attrs() *QdiscAttrs - Type() string -} - -// QdiscAttrs represents a netlink qdisc. A qdisc is associated with a link, -// has a handle, a parent and a refcnt. The root qdisc of a device should -// have parent == HANDLE_ROOT. -type QdiscAttrs struct { - LinkIndex int - Handle uint32 - Parent uint32 - Refcnt uint32 // read only -} - -func (q QdiscAttrs) String() string { - return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt) -} - -func MakeHandle(major, minor uint16) uint32 { - return (uint32(major) << 16) | uint32(minor) -} - -func MajorMinor(handle uint32) (uint16, uint16) { - return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF) -} - -func HandleStr(handle uint32) string { - switch handle { - case HANDLE_NONE: - return "none" - case HANDLE_INGRESS: - return "ingress" - case HANDLE_ROOT: - return "root" - default: - major, minor := MajorMinor(handle) - return fmt.Sprintf("%x:%x", major, minor) - } -} - -func Percentage2u32(percentage float32) uint32 { - // FIXME this is most likely not the best way to convert from % to uint32 - if percentage == 100 { - return math.MaxUint32 - } - return uint32(math.MaxUint32 * (percentage / 100)) -} - -// PfifoFast is the default qdisc created by the kernel if one has not -// been defined for the interface -type PfifoFast struct { - QdiscAttrs - Bands uint8 - PriorityMap [PRIORITY_MAP_LEN]uint8 -} - -func (qdisc *PfifoFast) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *PfifoFast) Type() string { - return "pfifo_fast" -} - -// Prio is a basic qdisc that works just like PfifoFast -type Prio struct { - QdiscAttrs - Bands uint8 - PriorityMap [PRIORITY_MAP_LEN]uint8 -} - -func NewPrio(attrs QdiscAttrs) *Prio { - return &Prio{ - QdiscAttrs: attrs, - Bands: 3, - PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - } -} - -func (qdisc *Prio) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Prio) Type() string { - return "prio" -} - -// Htb is a classful qdisc that rate limits based on tokens -type Htb struct { - QdiscAttrs - Version uint32 - Rate2Quantum uint32 - Defcls uint32 - Debug uint32 - DirectPkts uint32 -} - -func NewHtb(attrs QdiscAttrs) *Htb { - return &Htb{ - QdiscAttrs: attrs, - Version: 3, - Defcls: 0, - Rate2Quantum: 10, - Debug: 0, - DirectPkts: 0, - } -} - -func (qdisc *Htb) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Htb) Type() string { - return "htb" -} - -// Netem is a classless qdisc that rate limits based on tokens - -type NetemQdiscAttrs struct { - Latency uint32 // in us - DelayCorr float32 // in % - Limit uint32 - Loss float32 // in % - LossCorr float32 // in % - Gap uint32 - Duplicate float32 // in % - DuplicateCorr float32 // in % - Jitter uint32 // in us - ReorderProb float32 // in % - ReorderCorr float32 // in % - CorruptProb float32 // in % - CorruptCorr float32 // in % -} - -func (q NetemQdiscAttrs) String() string { - return fmt.Sprintf( - "{Latency: %d, Limit: %d, Loss: %f, Gap: %d, Duplicate: %f, Jitter: %d}", - q.Latency, q.Limit, q.Loss, q.Gap, q.Duplicate, q.Jitter, - ) -} - -type Netem struct { - QdiscAttrs - Latency uint32 - DelayCorr uint32 - Limit uint32 - Loss uint32 - LossCorr uint32 - Gap uint32 - Duplicate uint32 - DuplicateCorr uint32 - Jitter uint32 - ReorderProb uint32 - ReorderCorr uint32 - CorruptProb uint32 - CorruptCorr uint32 -} - -func (netem *Netem) String() string { - return fmt.Sprintf( - "{Latency: %v, Limit: %v, Loss: %v, Gap: %v, Duplicate: %v, Jitter: %v}", - netem.Latency, netem.Limit, netem.Loss, netem.Gap, netem.Duplicate, netem.Jitter, - ) -} - -func (qdisc *Netem) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Netem) Type() string { - return "netem" -} - -// Tbf is a classless qdisc that rate limits based on tokens -type Tbf struct { - QdiscAttrs - Rate uint64 - Limit uint32 - Buffer uint32 - Peakrate uint64 - Minburst uint32 - // TODO: handle other settings -} - -func (qdisc *Tbf) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Tbf) Type() string { - return "tbf" -} - -// Ingress is a qdisc for adding ingress filters -type Ingress struct { - QdiscAttrs -} - -func (qdisc *Ingress) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Ingress) Type() string { - return "ingress" -} - -// GenericQdisc qdiscs represent types that are not currently understood -// by this netlink library. -type GenericQdisc struct { - QdiscAttrs - QdiscType string -} - -func (qdisc *GenericQdisc) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *GenericQdisc) Type() string { - return qdisc.QdiscType -} - -type Hfsc struct { - QdiscAttrs - Defcls uint16 -} - -func NewHfsc(attrs QdiscAttrs) *Hfsc { - return &Hfsc{ - QdiscAttrs: attrs, - Defcls: 1, - } -} - -func (hfsc *Hfsc) Attrs() *QdiscAttrs { - return &hfsc.QdiscAttrs -} - -func (hfsc *Hfsc) Type() string { - return "hfsc" -} - -func (hfsc *Hfsc) String() string { - return fmt.Sprintf( - "{%v -- default: %d}", - hfsc.Attrs(), hfsc.Defcls, - ) -} - -// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic. -type Fq struct { - QdiscAttrs - PacketLimit uint32 - FlowPacketLimit uint32 - // In bytes - Quantum uint32 - InitialQuantum uint32 - // called RateEnable under the hood - Pacing uint32 - FlowDefaultRate uint32 - FlowMaxRate uint32 - // called BucketsLog under the hood - Buckets uint32 - FlowRefillDelay uint32 - LowRateThreshold uint32 -} - -func (fq *Fq) String() string { - return fmt.Sprintf( - "{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v, LowRateThreshold: %v}", - fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold, - ) -} - -func NewFq(attrs QdiscAttrs) *Fq { - return &Fq{ - QdiscAttrs: attrs, - Pacing: 1, - } -} - -func (qdisc *Fq) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Fq) Type() string { - return "fq" -} - -// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme. -type FqCodel struct { - QdiscAttrs - Target uint32 - Limit uint32 - Interval uint32 - ECN uint32 - Flows uint32 - Quantum uint32 - CEThreshold uint32 - DropBatchSize uint32 - MemoryLimit uint32 -} - -func (fqcodel *FqCodel) String() string { - return fmt.Sprintf( - "{%v -- Target: %v, Limit: %v, Interval: %v, ECM: %v, Flows: %v, Quantum: %v}", - fqcodel.Attrs(), fqcodel.Target, fqcodel.Limit, fqcodel.Interval, fqcodel.ECN, fqcodel.Flows, fqcodel.Quantum, - ) -} - -func NewFqCodel(attrs QdiscAttrs) *FqCodel { - return &FqCodel{ - QdiscAttrs: attrs, - ECN: 1, - } -} - -func (qdisc *FqCodel) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *FqCodel) Type() string { - return "fq_codel" -} - -type Sfq struct { - QdiscAttrs - // TODO: Only the simplified options for SFQ are handled here. Support for the extended one can be added later. - Quantum uint8 - Perturb uint8 - Limit uint32 - Divisor uint8 -} - -func (sfq *Sfq) String() string { - return fmt.Sprintf( - "{%v -- Quantum: %v, Perturb: %v, Limit: %v, Divisor: %v}", - sfq.Attrs(), sfq.Quantum, sfq.Perturb, sfq.Limit, sfq.Divisor, - ) -} - -func (qdisc *Sfq) Attrs() *QdiscAttrs { - return &qdisc.QdiscAttrs -} - -func (qdisc *Sfq) Type() string { - return "sfq" -} diff --git a/vendor/github.com/tailscale/netlink/qdisc_linux.go b/vendor/github.com/tailscale/netlink/qdisc_linux.go deleted file mode 100644 index 7898b56..0000000 --- a/vendor/github.com/tailscale/netlink/qdisc_linux.go +++ /dev/null @@ -1,708 +0,0 @@ -package netlink - -import ( - "fmt" - "io/ioutil" - "strconv" - "strings" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// NOTE function is here because it uses other linux functions -func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem { - var limit uint32 = 1000 - var lossCorr, delayCorr, duplicateCorr uint32 - var reorderProb, reorderCorr uint32 - var corruptProb, corruptCorr uint32 - - latency := nattrs.Latency - loss := Percentage2u32(nattrs.Loss) - gap := nattrs.Gap - duplicate := Percentage2u32(nattrs.Duplicate) - jitter := nattrs.Jitter - - // Correlation - if latency > 0 && jitter > 0 { - delayCorr = Percentage2u32(nattrs.DelayCorr) - } - if loss > 0 { - lossCorr = Percentage2u32(nattrs.LossCorr) - } - if duplicate > 0 { - duplicateCorr = Percentage2u32(nattrs.DuplicateCorr) - } - // FIXME should validate values(like loss/duplicate are percentages...) - latency = time2Tick(latency) - - if nattrs.Limit != 0 { - limit = nattrs.Limit - } - // Jitter is only value if latency is > 0 - if latency > 0 { - jitter = time2Tick(jitter) - } - - reorderProb = Percentage2u32(nattrs.ReorderProb) - reorderCorr = Percentage2u32(nattrs.ReorderCorr) - - if reorderProb > 0 { - // ERROR if lantency == 0 - if gap == 0 { - gap = 1 - } - } - - corruptProb = Percentage2u32(nattrs.CorruptProb) - corruptCorr = Percentage2u32(nattrs.CorruptCorr) - - return &Netem{ - QdiscAttrs: attrs, - Latency: latency, - DelayCorr: delayCorr, - Limit: limit, - Loss: loss, - LossCorr: lossCorr, - Gap: gap, - Duplicate: duplicate, - DuplicateCorr: duplicateCorr, - Jitter: jitter, - ReorderProb: reorderProb, - ReorderCorr: reorderCorr, - CorruptProb: corruptProb, - CorruptCorr: corruptCorr, - } -} - -// QdiscDel will delete a qdisc from the system. -// Equivalent to: `tc qdisc del $qdisc` -func QdiscDel(qdisc Qdisc) error { - return pkgHandle.QdiscDel(qdisc) -} - -// QdiscDel will delete a qdisc from the system. -// Equivalent to: `tc qdisc del $qdisc` -func (h *Handle) QdiscDel(qdisc Qdisc) error { - return h.qdiscModify(unix.RTM_DELQDISC, 0, qdisc) -} - -// QdiscChange will change a qdisc in place -// Equivalent to: `tc qdisc change $qdisc` -// The parent and handle MUST NOT be changed. -func QdiscChange(qdisc Qdisc) error { - return pkgHandle.QdiscChange(qdisc) -} - -// QdiscChange will change a qdisc in place -// Equivalent to: `tc qdisc change $qdisc` -// The parent and handle MUST NOT be changed. -func (h *Handle) QdiscChange(qdisc Qdisc) error { - return h.qdiscModify(unix.RTM_NEWQDISC, 0, qdisc) -} - -// QdiscReplace will replace a qdisc to the system. -// Equivalent to: `tc qdisc replace $qdisc` -// The handle MUST change. -func QdiscReplace(qdisc Qdisc) error { - return pkgHandle.QdiscReplace(qdisc) -} - -// QdiscReplace will replace a qdisc to the system. -// Equivalent to: `tc qdisc replace $qdisc` -// The handle MUST change. -func (h *Handle) QdiscReplace(qdisc Qdisc) error { - return h.qdiscModify( - unix.RTM_NEWQDISC, - unix.NLM_F_CREATE|unix.NLM_F_REPLACE, - qdisc) -} - -// QdiscAdd will add a qdisc to the system. -// Equivalent to: `tc qdisc add $qdisc` -func QdiscAdd(qdisc Qdisc) error { - return pkgHandle.QdiscAdd(qdisc) -} - -// QdiscAdd will add a qdisc to the system. -// Equivalent to: `tc qdisc add $qdisc` -func (h *Handle) QdiscAdd(qdisc Qdisc) error { - return h.qdiscModify( - unix.RTM_NEWQDISC, - unix.NLM_F_CREATE|unix.NLM_F_EXCL, - qdisc) -} - -func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error { - req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) - base := qdisc.Attrs() - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Ifindex: int32(base.LinkIndex), - Handle: base.Handle, - Parent: base.Parent, - } - req.AddData(msg) - - // When deleting don't bother building the rest of the netlink payload - if cmd != unix.RTM_DELQDISC { - if err := qdiscPayload(req, qdisc); err != nil { - return err - } - } - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error { - - req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type()))) - - options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) - - switch qdisc := qdisc.(type) { - case *Prio: - tcmap := nl.TcPrioMap{ - Bands: int32(qdisc.Bands), - Priomap: qdisc.PriorityMap, - } - options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize()) - case *Tbf: - opt := nl.TcTbfQopt{} - opt.Rate.Rate = uint32(qdisc.Rate) - opt.Peakrate.Rate = uint32(qdisc.Peakrate) - opt.Limit = qdisc.Limit - opt.Buffer = qdisc.Buffer - options.AddRtAttr(nl.TCA_TBF_PARMS, opt.Serialize()) - if qdisc.Rate >= uint64(1<<32) { - options.AddRtAttr(nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate)) - } - if qdisc.Peakrate >= uint64(1<<32) { - options.AddRtAttr(nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate)) - } - if qdisc.Peakrate > 0 { - options.AddRtAttr(nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst)) - } - case *Htb: - opt := nl.TcHtbGlob{} - opt.Version = qdisc.Version - opt.Rate2Quantum = qdisc.Rate2Quantum - opt.Defcls = qdisc.Defcls - // TODO: Handle Debug properly. For now default to 0 - opt.Debug = qdisc.Debug - opt.DirectPkts = qdisc.DirectPkts - options.AddRtAttr(nl.TCA_HTB_INIT, opt.Serialize()) - // options.AddRtAttr(nl.TCA_HTB_DIRECT_QLEN, opt.Serialize()) - case *Hfsc: - opt := nl.TcHfscOpt{} - opt.Defcls = qdisc.Defcls - options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize()) - case *Netem: - opt := nl.TcNetemQopt{} - opt.Latency = qdisc.Latency - opt.Limit = qdisc.Limit - opt.Loss = qdisc.Loss - opt.Gap = qdisc.Gap - opt.Duplicate = qdisc.Duplicate - opt.Jitter = qdisc.Jitter - options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize()) - // Correlation - corr := nl.TcNetemCorr{} - corr.DelayCorr = qdisc.DelayCorr - corr.LossCorr = qdisc.LossCorr - corr.DupCorr = qdisc.DuplicateCorr - - if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 { - options.AddRtAttr(nl.TCA_NETEM_CORR, corr.Serialize()) - } - // Corruption - corruption := nl.TcNetemCorrupt{} - corruption.Probability = qdisc.CorruptProb - corruption.Correlation = qdisc.CorruptCorr - if corruption.Probability > 0 { - options.AddRtAttr(nl.TCA_NETEM_CORRUPT, corruption.Serialize()) - } - // Reorder - reorder := nl.TcNetemReorder{} - reorder.Probability = qdisc.ReorderProb - reorder.Correlation = qdisc.ReorderCorr - if reorder.Probability > 0 { - options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize()) - } - case *Ingress: - // ingress filters must use the proper handle - if qdisc.Attrs().Parent != HANDLE_INGRESS { - return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS") - } - case *FqCodel: - options.AddRtAttr(nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN)))) - if qdisc.Limit > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit)))) - } - if qdisc.Interval > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval)))) - } - if qdisc.Flows > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows)))) - } - if qdisc.Quantum > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) - } - if qdisc.CEThreshold > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_CE_THRESHOLD, nl.Uint32Attr(qdisc.CEThreshold)) - } - if qdisc.DropBatchSize > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_DROP_BATCH_SIZE, nl.Uint32Attr(qdisc.DropBatchSize)) - } - if qdisc.MemoryLimit > 0 { - options.AddRtAttr(nl.TCA_FQ_CODEL_MEMORY_LIMIT, nl.Uint32Attr(qdisc.MemoryLimit)) - } - case *Fq: - options.AddRtAttr(nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing)))) - - if qdisc.Buckets > 0 { - options.AddRtAttr(nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets)))) - } - if qdisc.LowRateThreshold > 0 { - options.AddRtAttr(nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold)))) - } - if qdisc.Quantum > 0 { - options.AddRtAttr(nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) - } - if qdisc.InitialQuantum > 0 { - options.AddRtAttr(nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum)))) - } - if qdisc.FlowRefillDelay > 0 { - options.AddRtAttr(nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay)))) - } - if qdisc.FlowPacketLimit > 0 { - options.AddRtAttr(nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit)))) - } - if qdisc.FlowMaxRate > 0 { - options.AddRtAttr(nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate)))) - } - if qdisc.FlowDefaultRate > 0 { - options.AddRtAttr(nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate)))) - } - case *Sfq: - opt := nl.TcSfqQoptV1{} - opt.TcSfqQopt.Quantum = qdisc.Quantum - opt.TcSfqQopt.Perturb = int32(qdisc.Perturb) - opt.TcSfqQopt.Limit = qdisc.Limit - opt.TcSfqQopt.Divisor = qdisc.Divisor - - options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize()) - default: - options = nil - } - - if options != nil { - req.AddData(options) - } - return nil -} - -// QdiscList gets a list of qdiscs in the system. -// Equivalent to: `tc qdisc show`. -// The list can be filtered by link. -func QdiscList(link Link) ([]Qdisc, error) { - return pkgHandle.QdiscList(link) -} - -// QdiscList gets a list of qdiscs in the system. -// Equivalent to: `tc qdisc show`. -// The list can be filtered by link. -func (h *Handle) QdiscList(link Link) ([]Qdisc, error) { - req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP) - index := int32(0) - if link != nil { - base := link.Attrs() - h.ensureIndex(base) - index = int32(base.Index) - } - msg := &nl.TcMsg{ - Family: nl.FAMILY_ALL, - Ifindex: index, - } - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC) - if err != nil { - return nil, err - } - - var res []Qdisc - for _, m := range msgs { - msg := nl.DeserializeTcMsg(m) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - // skip qdiscs from other interfaces - if link != nil && msg.Ifindex != index { - continue - } - - base := QdiscAttrs{ - LinkIndex: int(msg.Ifindex), - Handle: msg.Handle, - Parent: msg.Parent, - Refcnt: msg.Info, - } - var qdisc Qdisc - qdiscType := "" - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.TCA_KIND: - qdiscType = string(attr.Value[:len(attr.Value)-1]) - switch qdiscType { - case "pfifo_fast": - qdisc = &PfifoFast{} - case "prio": - qdisc = &Prio{} - case "tbf": - qdisc = &Tbf{} - case "ingress": - qdisc = &Ingress{} - case "htb": - qdisc = &Htb{} - case "fq": - qdisc = &Fq{} - case "hfsc": - qdisc = &Hfsc{} - case "fq_codel": - qdisc = &FqCodel{} - case "netem": - qdisc = &Netem{} - case "sfq": - qdisc = &Sfq{} - default: - qdisc = &GenericQdisc{QdiscType: qdiscType} - } - case nl.TCA_OPTIONS: - switch qdiscType { - case "pfifo_fast": - // pfifo returns TcPrioMap directly without wrapping it in rtattr - if err := parsePfifoFastData(qdisc, attr.Value); err != nil { - return nil, err - } - case "prio": - // prio returns TcPrioMap directly without wrapping it in rtattr - if err := parsePrioData(qdisc, attr.Value); err != nil { - return nil, err - } - case "tbf": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - if err := parseTbfData(qdisc, data); err != nil { - return nil, err - } - case "hfsc": - if err := parseHfscData(qdisc, attr.Value); err != nil { - return nil, err - } - case "htb": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - if err := parseHtbData(qdisc, data); err != nil { - return nil, err - } - case "fq": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - if err := parseFqData(qdisc, data); err != nil { - return nil, err - } - case "fq_codel": - data, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return nil, err - } - if err := parseFqCodelData(qdisc, data); err != nil { - return nil, err - } - case "netem": - if err := parseNetemData(qdisc, attr.Value); err != nil { - return nil, err - } - case "sfq": - if err := parseSfqData(qdisc, attr.Value); err != nil { - return nil, err - } - - // no options for ingress - } - } - } - *qdisc.Attrs() = base - res = append(res, qdisc) - } - - return res, nil -} - -func parsePfifoFastData(qdisc Qdisc, value []byte) error { - pfifo := qdisc.(*PfifoFast) - tcmap := nl.DeserializeTcPrioMap(value) - pfifo.PriorityMap = tcmap.Priomap - pfifo.Bands = uint8(tcmap.Bands) - return nil -} - -func parsePrioData(qdisc Qdisc, value []byte) error { - prio := qdisc.(*Prio) - tcmap := nl.DeserializeTcPrioMap(value) - prio.PriorityMap = tcmap.Priomap - prio.Bands = uint8(tcmap.Bands) - return nil -} - -func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { - htb := qdisc.(*Htb) - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_HTB_INIT: - opt := nl.DeserializeTcHtbGlob(datum.Value) - htb.Version = opt.Version - htb.Rate2Quantum = opt.Rate2Quantum - htb.Defcls = opt.Defcls - htb.Debug = opt.Debug - htb.DirectPkts = opt.DirectPkts - case nl.TCA_HTB_DIRECT_QLEN: - // TODO - //htb.DirectQlen = native.uint32(datum.Value) - } - } - return nil -} - -func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { - fqCodel := qdisc.(*FqCodel) - for _, datum := range data { - - switch datum.Attr.Type { - case nl.TCA_FQ_CODEL_TARGET: - fqCodel.Target = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_LIMIT: - fqCodel.Limit = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_INTERVAL: - fqCodel.Interval = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_ECN: - fqCodel.ECN = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_FLOWS: - fqCodel.Flows = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_QUANTUM: - fqCodel.Quantum = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_CE_THRESHOLD: - fqCodel.CEThreshold = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_DROP_BATCH_SIZE: - fqCodel.DropBatchSize = native.Uint32(datum.Value) - case nl.TCA_FQ_CODEL_MEMORY_LIMIT: - fqCodel.MemoryLimit = native.Uint32(datum.Value) - } - } - return nil -} - -func parseHfscData(qdisc Qdisc, data []byte) error { - Hfsc := qdisc.(*Hfsc) - Hfsc.Defcls = native.Uint16(data) - return nil -} - -func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { - fq := qdisc.(*Fq) - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_FQ_BUCKETS_LOG: - fq.Buckets = native.Uint32(datum.Value) - case nl.TCA_FQ_LOW_RATE_THRESHOLD: - fq.LowRateThreshold = native.Uint32(datum.Value) - case nl.TCA_FQ_QUANTUM: - fq.Quantum = native.Uint32(datum.Value) - case nl.TCA_FQ_RATE_ENABLE: - fq.Pacing = native.Uint32(datum.Value) - case nl.TCA_FQ_INITIAL_QUANTUM: - fq.InitialQuantum = native.Uint32(datum.Value) - case nl.TCA_FQ_ORPHAN_MASK: - // TODO - case nl.TCA_FQ_FLOW_REFILL_DELAY: - fq.FlowRefillDelay = native.Uint32(datum.Value) - case nl.TCA_FQ_FLOW_PLIMIT: - fq.FlowPacketLimit = native.Uint32(datum.Value) - case nl.TCA_FQ_PLIMIT: - fq.PacketLimit = native.Uint32(datum.Value) - case nl.TCA_FQ_FLOW_MAX_RATE: - fq.FlowMaxRate = native.Uint32(datum.Value) - case nl.TCA_FQ_FLOW_DEFAULT_RATE: - fq.FlowDefaultRate = native.Uint32(datum.Value) - } - } - return nil -} - -func parseNetemData(qdisc Qdisc, value []byte) error { - netem := qdisc.(*Netem) - opt := nl.DeserializeTcNetemQopt(value) - netem.Latency = opt.Latency - netem.Limit = opt.Limit - netem.Loss = opt.Loss - netem.Gap = opt.Gap - netem.Duplicate = opt.Duplicate - netem.Jitter = opt.Jitter - data, err := nl.ParseRouteAttr(value[nl.SizeofTcNetemQopt:]) - if err != nil { - return err - } - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_NETEM_CORR: - opt := nl.DeserializeTcNetemCorr(datum.Value) - netem.DelayCorr = opt.DelayCorr - netem.LossCorr = opt.LossCorr - netem.DuplicateCorr = opt.DupCorr - case nl.TCA_NETEM_CORRUPT: - opt := nl.DeserializeTcNetemCorrupt(datum.Value) - netem.CorruptProb = opt.Probability - netem.CorruptCorr = opt.Correlation - case nl.TCA_NETEM_REORDER: - opt := nl.DeserializeTcNetemReorder(datum.Value) - netem.ReorderProb = opt.Probability - netem.ReorderCorr = opt.Correlation - } - } - return nil -} - -func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { - tbf := qdisc.(*Tbf) - for _, datum := range data { - switch datum.Attr.Type { - case nl.TCA_TBF_PARMS: - opt := nl.DeserializeTcTbfQopt(datum.Value) - tbf.Rate = uint64(opt.Rate.Rate) - tbf.Peakrate = uint64(opt.Peakrate.Rate) - tbf.Limit = opt.Limit - tbf.Buffer = opt.Buffer - case nl.TCA_TBF_RATE64: - tbf.Rate = native.Uint64(datum.Value[0:8]) - case nl.TCA_TBF_PRATE64: - tbf.Peakrate = native.Uint64(datum.Value[0:8]) - case nl.TCA_TBF_PBURST: - tbf.Minburst = native.Uint32(datum.Value[0:4]) - } - } - return nil -} - -func parseSfqData(qdisc Qdisc, value []byte) error { - sfq := qdisc.(*Sfq) - opt := nl.DeserializeTcSfqQoptV1(value) - sfq.Quantum = opt.TcSfqQopt.Quantum - sfq.Perturb = uint8(opt.TcSfqQopt.Perturb) - sfq.Limit = opt.TcSfqQopt.Limit - sfq.Divisor = opt.TcSfqQopt.Divisor - - return nil -} - -const ( - TIME_UNITS_PER_SEC = 1000000 -) - -var ( - tickInUsec float64 - clockFactor float64 - hz float64 -) - -func initClock() { - data, err := ioutil.ReadFile("/proc/net/psched") - if err != nil { - return - } - parts := strings.Split(strings.TrimSpace(string(data)), " ") - if len(parts) < 4 { - return - } - var vals [4]uint64 - for i := range vals { - val, err := strconv.ParseUint(parts[i], 16, 32) - if err != nil { - return - } - vals[i] = val - } - // compatibility - if vals[2] == 1000000000 { - vals[0] = vals[1] - } - clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC - tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor - if vals[2] == 1000000 { - // ref https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/lib/utils.c#n963 - hz = float64(vals[3]) - } else { - hz = 100 - } -} - -func TickInUsec() float64 { - if tickInUsec == 0.0 { - initClock() - } - return tickInUsec -} - -func ClockFactor() float64 { - if clockFactor == 0.0 { - initClock() - } - return clockFactor -} - -func Hz() float64 { - if hz == 0.0 { - initClock() - } - return hz -} - -func time2Tick(time uint32) uint32 { - return uint32(float64(time) * TickInUsec()) -} - -func tick2Time(tick uint32) uint32 { - return uint32(float64(tick) / TickInUsec()) -} - -func time2Ktime(time uint32) uint32 { - return uint32(float64(time) * ClockFactor()) -} - -func ktime2Time(ktime uint32) uint32 { - return uint32(float64(ktime) / ClockFactor()) -} - -func burst(rate uint64, buffer uint32) uint32 { - return uint32(float64(rate) * float64(tick2Time(buffer)) / TIME_UNITS_PER_SEC) -} - -func latency(rate uint64, limit, buffer uint32) float64 { - return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer)) -} - -func Xmittime(rate uint64, size uint32) uint32 { - // https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/tc/tc_core.c#n62 - return time2Tick(uint32(TIME_UNITS_PER_SEC * (float64(size) / float64(rate)))) -} diff --git a/vendor/github.com/tailscale/netlink/rdma_link_linux.go b/vendor/github.com/tailscale/netlink/rdma_link_linux.go deleted file mode 100644 index 6a09332..0000000 --- a/vendor/github.com/tailscale/netlink/rdma_link_linux.go +++ /dev/null @@ -1,332 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "fmt" - "net" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -// LinkAttrs represents data shared by most link types -type RdmaLinkAttrs struct { - Index uint32 - Name string - FirmwareVersion string - NodeGuid string - SysImageGuid string -} - -// Link represents a rdma device from netlink. -type RdmaLink struct { - Attrs RdmaLinkAttrs -} - -func getProtoField(clientType int, op int) int { - return ((clientType << nl.RDMA_NL_GET_CLIENT_SHIFT) | op) -} - -func uint64ToGuidString(guid uint64) string { - //Convert to byte array - sysGuidBytes := new(bytes.Buffer) - binary.Write(sysGuidBytes, binary.LittleEndian, guid) - - //Convert to HardwareAddr - sysGuidNet := net.HardwareAddr(sysGuidBytes.Bytes()) - - //Get the String - return sysGuidNet.String() -} - -func executeOneGetRdmaLink(data []byte) (*RdmaLink, error) { - - link := RdmaLink{} - - reader := bytes.NewReader(data) - for reader.Len() >= 4 { - _, attrType, len, value := parseNfAttrTLV(reader) - - switch attrType { - case nl.RDMA_NLDEV_ATTR_DEV_INDEX: - var Index uint32 - r := bytes.NewReader(value) - binary.Read(r, nl.NativeEndian(), &Index) - link.Attrs.Index = Index - case nl.RDMA_NLDEV_ATTR_DEV_NAME: - link.Attrs.Name = string(value[0 : len-1]) - case nl.RDMA_NLDEV_ATTR_FW_VERSION: - link.Attrs.FirmwareVersion = string(value[0 : len-1]) - case nl.RDMA_NLDEV_ATTR_NODE_GUID: - var guid uint64 - r := bytes.NewReader(value) - binary.Read(r, nl.NativeEndian(), &guid) - link.Attrs.NodeGuid = uint64ToGuidString(guid) - case nl.RDMA_NLDEV_ATTR_SYS_IMAGE_GUID: - var sysGuid uint64 - r := bytes.NewReader(value) - binary.Read(r, nl.NativeEndian(), &sysGuid) - link.Attrs.SysImageGuid = uint64ToGuidString(sysGuid) - } - if (len % 4) != 0 { - // Skip pad bytes - reader.Seek(int64(4-(len%4)), seekCurrent) - } - } - return &link, nil -} - -func execRdmaSetLink(req *nl.NetlinkRequest) error { - - _, err := req.Execute(unix.NETLINK_RDMA, 0) - return err -} - -// RdmaLinkList gets a list of RDMA link devices. -// Equivalent to: `rdma dev show` -func RdmaLinkList() ([]*RdmaLink, error) { - return pkgHandle.RdmaLinkList() -} - -// RdmaLinkList gets a list of RDMA link devices. -// Equivalent to: `rdma dev show` -func (h *Handle) RdmaLinkList() ([]*RdmaLink, error) { - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_GET) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_DUMP) - - msgs, err := req.Execute(unix.NETLINK_RDMA, 0) - if err != nil { - return nil, err - } - - var res []*RdmaLink - for _, m := range msgs { - link, err := executeOneGetRdmaLink(m) - if err != nil { - return nil, err - } - res = append(res, link) - } - - return res, nil -} - -// RdmaLinkByName finds a link by name and returns a pointer to the object if -// found and nil error, otherwise returns error code. -func RdmaLinkByName(name string) (*RdmaLink, error) { - return pkgHandle.RdmaLinkByName(name) -} - -// RdmaLinkByName finds a link by name and returns a pointer to the object if -// found and nil error, otherwise returns error code. -func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) { - links, err := h.RdmaLinkList() - if err != nil { - return nil, err - } - for _, link := range links { - if link.Attrs.Name == name { - return link, nil - } - } - return nil, fmt.Errorf("Rdma device %v not found", name) -} - -// RdmaLinkSetName sets the name of the rdma link device. Return nil on success -// or error otherwise. -// Equivalent to: `rdma dev set $old_devname name $name` -func RdmaLinkSetName(link *RdmaLink, name string) error { - return pkgHandle.RdmaLinkSetName(link, name) -} - -// RdmaLinkSetName sets the name of the rdma link device. Return nil on success -// or error otherwise. -// Equivalent to: `rdma dev set $old_devname name $name` -func (h *Handle) RdmaLinkSetName(link *RdmaLink, name string) error { - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - b := make([]byte, 4) - native.PutUint32(b, uint32(link.Attrs.Index)) - data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b) - req.AddData(data) - - b = make([]byte, len(name)+1) - copy(b, name) - data = nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, b) - req.AddData(data) - - return execRdmaSetLink(req) -} - -func netnsModeToString(mode uint8) string { - switch mode { - case 0: - return "exclusive" - case 1: - return "shared" - default: - return "unknown" - } -} - -func executeOneGetRdmaNetnsMode(data []byte) (string, error) { - reader := bytes.NewReader(data) - for reader.Len() >= 4 { - _, attrType, len, value := parseNfAttrTLV(reader) - - switch attrType { - case nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE: - var mode uint8 - r := bytes.NewReader(value) - binary.Read(r, nl.NativeEndian(), &mode) - return netnsModeToString(mode), nil - } - if (len % 4) != 0 { - // Skip pad bytes - reader.Seek(int64(4-(len%4)), seekCurrent) - } - } - return "", fmt.Errorf("Invalid netns mode") -} - -// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem -// Returns mode string and error status as nil on success or returns error -// otherwise. -// Equivalent to: `rdma system show netns' -func RdmaSystemGetNetnsMode() (string, error) { - return pkgHandle.RdmaSystemGetNetnsMode() -} - -// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem -// Returns mode string and error status as nil on success or returns error -// otherwise. -// Equivalent to: `rdma system show netns' -func (h *Handle) RdmaSystemGetNetnsMode() (string, error) { - - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_GET) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - msgs, err := req.Execute(unix.NETLINK_RDMA, 0) - if err != nil { - return "", err - } - if len(msgs) == 0 { - return "", fmt.Errorf("No valid response from kernel") - } - return executeOneGetRdmaNetnsMode(msgs[0]) -} - -func netnsModeStringToUint8(mode string) (uint8, error) { - switch mode { - case "exclusive": - return 0, nil - case "shared": - return 1, nil - default: - return 0, fmt.Errorf("Invalid mode; %q", mode) - } -} - -// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem -// Returns nil on success or appropriate error code. -// Equivalent to: `rdma system set netns { shared | exclusive }' -func RdmaSystemSetNetnsMode(NewMode string) error { - return pkgHandle.RdmaSystemSetNetnsMode(NewMode) -} - -// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem -// Returns nil on success or appropriate error code. -// Equivalent to: `rdma system set netns { shared | exclusive }' -func (h *Handle) RdmaSystemSetNetnsMode(NewMode string) error { - value, err := netnsModeStringToUint8(NewMode) - if err != nil { - return err - } - - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_SET) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - data := nl.NewRtAttr(nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE, []byte{value}) - req.AddData(data) - - _, err = req.Execute(unix.NETLINK_RDMA, 0) - return err -} - -// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The -// fd must be an open file descriptor to a network namespace. -// Similar to: `rdma dev set $dev netns $ns` -func RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error { - return pkgHandle.RdmaLinkSetNsFd(link, fd) -} - -// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The -// fd must be an open file descriptor to a network namespace. -// Similar to: `rdma dev set $dev netns $ns` -func (h *Handle) RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error { - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, - nl.Uint32Attr(link.Attrs.Index)) - req.AddData(data) - - data = nl.NewRtAttr(nl.RDMA_NLDEV_NET_NS_FD, nl.Uint32Attr(fd)) - req.AddData(data) - - return execRdmaSetLink(req) -} - -// RdmaLinkDel deletes an rdma link -// -// Similar to: rdma link delete NAME -// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html -func RdmaLinkDel(name string) error { - return pkgHandle.RdmaLinkDel(name) -} - -// RdmaLinkDel deletes an rdma link. -func (h *Handle) RdmaLinkDel(name string) error { - link, err := h.RdmaLinkByName(name) - if err != nil { - return err - } - - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_DELLINK) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - b := make([]byte, 4) - native.PutUint32(b, link.Attrs.Index) - req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b)) - - _, err = req.Execute(unix.NETLINK_RDMA, 0) - return err -} - -// RdmaLinkAdd adds an rdma link for the specified type to the network device. -// Similar to: rdma link add NAME type TYPE netdev NETDEV -// -// NAME - specifies the new name of the rdma link to add -// TYPE - specifies which rdma type to use. Link types: -// rxe - Soft RoCE driver -// siw - Soft iWARP driver -// NETDEV - specifies the network device to which the link is bound -// -// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html -func RdmaLinkAdd(linkName, linkType, netdev string) error { - return pkgHandle.RdmaLinkAdd(linkName, linkType, netdev) -} - -// RdmaLinkAdd adds an rdma link for the specified type to the network device. -func (h *Handle) RdmaLinkAdd(linkName string, linkType string, netdev string) error { - proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_NEWLINK) - req := h.newNetlinkRequest(proto, unix.NLM_F_ACK) - - req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, nl.ZeroTerminated(linkName))) - req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_LINK_TYPE, nl.ZeroTerminated(linkType))) - req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_NDEV_NAME, nl.ZeroTerminated(netdev))) - _, err := req.Execute(unix.NETLINK_RDMA, 0) - return err -} diff --git a/vendor/github.com/tailscale/netlink/route.go b/vendor/github.com/tailscale/netlink/route.go deleted file mode 100644 index ffad5d3..0000000 --- a/vendor/github.com/tailscale/netlink/route.go +++ /dev/null @@ -1,209 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "strings" -) - -// Scope is an enum representing a route scope. -type Scope uint8 - -type NextHopFlag int - -type Destination interface { - Family() int - Decode([]byte) error - Encode() ([]byte, error) - String() string - Equal(Destination) bool -} - -type Encap interface { - Type() int - Decode([]byte) error - Encode() ([]byte, error) - String() string - Equal(Encap) bool -} - -//Protocol describe what was the originator of the route -type RouteProtocol int - -// Route represents a netlink route. -type Route struct { - LinkIndex int - ILinkIndex int - Scope Scope - Dst *net.IPNet - Src net.IP - Gw net.IP - MultiPath []*NexthopInfo - Protocol RouteProtocol - Priority int - Family int - Table int - Type int - Tos int - Flags int - MPLSDst *int - NewDst Destination - Encap Encap - Via Destination - Realm int - MTU int - Window int - Rtt int - RttVar int - Ssthresh int - Cwnd int - AdvMSS int - Reordering int - Hoplimit int - InitCwnd int - Features int - RtoMin int - InitRwnd int - QuickACK int - Congctl string - FastOpenNoCookie int -} - -func (r Route) String() string { - elems := []string{} - if len(r.MultiPath) == 0 { - elems = append(elems, fmt.Sprintf("Ifindex: %d", r.LinkIndex)) - } - if r.MPLSDst != nil { - elems = append(elems, fmt.Sprintf("Dst: %d", r.MPLSDst)) - } else { - elems = append(elems, fmt.Sprintf("Dst: %s", r.Dst)) - } - if r.NewDst != nil { - elems = append(elems, fmt.Sprintf("NewDst: %s", r.NewDst)) - } - if r.Encap != nil { - elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap)) - } - if r.Via != nil { - elems = append(elems, fmt.Sprintf("Via: %s", r.Via)) - } - elems = append(elems, fmt.Sprintf("Src: %s", r.Src)) - if len(r.MultiPath) > 0 { - elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath)) - } else { - elems = append(elems, fmt.Sprintf("Gw: %s", r.Gw)) - } - elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags())) - elems = append(elems, fmt.Sprintf("Table: %d", r.Table)) - elems = append(elems, fmt.Sprintf("Realm: %d", r.Realm)) - return fmt.Sprintf("{%s}", strings.Join(elems, " ")) -} - -func (r Route) Equal(x Route) bool { - return r.LinkIndex == x.LinkIndex && - r.ILinkIndex == x.ILinkIndex && - r.Scope == x.Scope && - ipNetEqual(r.Dst, x.Dst) && - r.Src.Equal(x.Src) && - r.Gw.Equal(x.Gw) && - nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) && - r.Protocol == x.Protocol && - r.Priority == x.Priority && - r.Realm == x.Realm && - r.Table == x.Table && - r.Type == x.Type && - r.Tos == x.Tos && - r.Hoplimit == x.Hoplimit && - r.Flags == x.Flags && - (r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) && - (r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) && - (r.Via == x.Via || (r.Via != nil && r.Via.Equal(x.Via))) && - (r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap))) -} - -func (r *Route) SetFlag(flag NextHopFlag) { - r.Flags |= int(flag) -} - -func (r *Route) ClearFlag(flag NextHopFlag) { - r.Flags &^= int(flag) -} - -type flagString struct { - f NextHopFlag - s string -} - -// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE -type RouteUpdate struct { - Type uint16 - Route -} - -type NexthopInfo struct { - LinkIndex int - Hops int - Gw net.IP - Flags int - NewDst Destination - Encap Encap - Via Destination -} - -func (n *NexthopInfo) String() string { - elems := []string{} - elems = append(elems, fmt.Sprintf("Ifindex: %d", n.LinkIndex)) - if n.NewDst != nil { - elems = append(elems, fmt.Sprintf("NewDst: %s", n.NewDst)) - } - if n.Encap != nil { - elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap)) - } - if n.Via != nil { - elems = append(elems, fmt.Sprintf("Via: %s", n.Via)) - } - elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1)) - elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw)) - elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags())) - return fmt.Sprintf("{%s}", strings.Join(elems, " ")) -} - -func (n NexthopInfo) Equal(x NexthopInfo) bool { - return n.LinkIndex == x.LinkIndex && - n.Hops == x.Hops && - n.Gw.Equal(x.Gw) && - n.Flags == x.Flags && - (n.NewDst == x.NewDst || (n.NewDst != nil && n.NewDst.Equal(x.NewDst))) && - (n.Encap == x.Encap || (n.Encap != nil && n.Encap.Equal(x.Encap))) -} - -type nexthopInfoSlice []*NexthopInfo - -func (n nexthopInfoSlice) Equal(x []*NexthopInfo) bool { - if len(n) != len(x) { - return false - } - for i := range n { - if n[i] == nil || x[i] == nil { - return false - } - if !n[i].Equal(*x[i]) { - return false - } - } - return true -} - -// ipNetEqual returns true iff both IPNet are equal -func ipNetEqual(ipn1 *net.IPNet, ipn2 *net.IPNet) bool { - if ipn1 == ipn2 { - return true - } - if ipn1 == nil || ipn2 == nil { - return false - } - m1, _ := ipn1.Mask.Size() - m2, _ := ipn2.Mask.Size() - return m1 == m2 && ipn1.IP.Equal(ipn2.IP) -} diff --git a/vendor/github.com/tailscale/netlink/route_linux.go b/vendor/github.com/tailscale/netlink/route_linux.go deleted file mode 100644 index 0bccafe..0000000 --- a/vendor/github.com/tailscale/netlink/route_linux.go +++ /dev/null @@ -1,1571 +0,0 @@ -package netlink - -import ( - "bytes" - "encoding/binary" - "fmt" - "net" - "strconv" - "strings" - "syscall" - - "github.com/tailscale/netlink/nl" - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -// RtAttr is shared so it is in netlink_linux.go - -const ( - SCOPE_UNIVERSE Scope = unix.RT_SCOPE_UNIVERSE - SCOPE_SITE Scope = unix.RT_SCOPE_SITE - SCOPE_LINK Scope = unix.RT_SCOPE_LINK - SCOPE_HOST Scope = unix.RT_SCOPE_HOST - SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE -) - -func (s Scope) String() string { - switch s { - case SCOPE_UNIVERSE: - return "universe" - case SCOPE_SITE: - return "site" - case SCOPE_LINK: - return "link" - case SCOPE_HOST: - return "host" - case SCOPE_NOWHERE: - return "nowhere" - default: - return "unknown" - } -} - -const ( - RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota) - RT_FILTER_SCOPE - RT_FILTER_TYPE - RT_FILTER_TOS - RT_FILTER_IIF - RT_FILTER_OIF - RT_FILTER_DST - RT_FILTER_SRC - RT_FILTER_GW - RT_FILTER_TABLE - RT_FILTER_HOPLIMIT - RT_FILTER_PRIORITY - RT_FILTER_MARK - RT_FILTER_MASK - RT_FILTER_REALM -) - -const ( - FLAG_ONLINK NextHopFlag = unix.RTNH_F_ONLINK - FLAG_PERVASIVE NextHopFlag = unix.RTNH_F_PERVASIVE -) - -var testFlags = []flagString{ - {f: FLAG_ONLINK, s: "onlink"}, - {f: FLAG_PERVASIVE, s: "pervasive"}, -} - -func listFlags(flag int) []string { - var flags []string - for _, tf := range testFlags { - if flag&int(tf.f) != 0 { - flags = append(flags, tf.s) - } - } - return flags -} - -func (r *Route) ListFlags() []string { - return listFlags(r.Flags) -} - -func (n *NexthopInfo) ListFlags() []string { - return listFlags(n.Flags) -} - -type MPLSDestination struct { - Labels []int -} - -func (d *MPLSDestination) Family() int { - return nl.FAMILY_MPLS -} - -func (d *MPLSDestination) Decode(buf []byte) error { - d.Labels = nl.DecodeMPLSStack(buf) - return nil -} - -func (d *MPLSDestination) Encode() ([]byte, error) { - return nl.EncodeMPLSStack(d.Labels...), nil -} - -func (d *MPLSDestination) String() string { - s := make([]string, 0, len(d.Labels)) - for _, l := range d.Labels { - s = append(s, fmt.Sprintf("%d", l)) - } - return strings.Join(s, "/") -} - -func (d *MPLSDestination) Equal(x Destination) bool { - o, ok := x.(*MPLSDestination) - if !ok { - return false - } - if d == nil && o == nil { - return true - } - if d == nil || o == nil { - return false - } - if d.Labels == nil && o.Labels == nil { - return true - } - if d.Labels == nil || o.Labels == nil { - return false - } - if len(d.Labels) != len(o.Labels) { - return false - } - for i := range d.Labels { - if d.Labels[i] != o.Labels[i] { - return false - } - } - return true -} - -type MPLSEncap struct { - Labels []int -} - -func (e *MPLSEncap) Type() int { - return nl.LWTUNNEL_ENCAP_MPLS -} - -func (e *MPLSEncap) Decode(buf []byte) error { - if len(buf) < 4 { - return fmt.Errorf("lack of bytes") - } - l := native.Uint16(buf) - if len(buf) < int(l) { - return fmt.Errorf("lack of bytes") - } - buf = buf[:l] - typ := native.Uint16(buf[2:]) - if typ != nl.MPLS_IPTUNNEL_DST { - return fmt.Errorf("unknown MPLS Encap Type: %d", typ) - } - e.Labels = nl.DecodeMPLSStack(buf[4:]) - return nil -} - -func (e *MPLSEncap) Encode() ([]byte, error) { - s := nl.EncodeMPLSStack(e.Labels...) - hdr := make([]byte, 4) - native.PutUint16(hdr, uint16(len(s)+4)) - native.PutUint16(hdr[2:], nl.MPLS_IPTUNNEL_DST) - return append(hdr, s...), nil -} - -func (e *MPLSEncap) String() string { - s := make([]string, 0, len(e.Labels)) - for _, l := range e.Labels { - s = append(s, fmt.Sprintf("%d", l)) - } - return strings.Join(s, "/") -} - -func (e *MPLSEncap) Equal(x Encap) bool { - o, ok := x.(*MPLSEncap) - if !ok { - return false - } - if e == nil && o == nil { - return true - } - if e == nil || o == nil { - return false - } - if e.Labels == nil && o.Labels == nil { - return true - } - if e.Labels == nil || o.Labels == nil { - return false - } - if len(e.Labels) != len(o.Labels) { - return false - } - for i := range e.Labels { - if e.Labels[i] != o.Labels[i] { - return false - } - } - return true -} - -// SEG6 definitions -type SEG6Encap struct { - Mode int - Segments []net.IP -} - -func (e *SEG6Encap) Type() int { - return nl.LWTUNNEL_ENCAP_SEG6 -} -func (e *SEG6Encap) Decode(buf []byte) error { - if len(buf) < 4 { - return fmt.Errorf("lack of bytes") - } - // Get Length(l) & Type(typ) : 2 + 2 bytes - l := native.Uint16(buf) - if len(buf) < int(l) { - return fmt.Errorf("lack of bytes") - } - buf = buf[:l] // make sure buf size upper limit is Length - typ := native.Uint16(buf[2:]) - // LWTUNNEL_ENCAP_SEG6 has only one attr type SEG6_IPTUNNEL_SRH - if typ != nl.SEG6_IPTUNNEL_SRH { - return fmt.Errorf("unknown SEG6 Type: %d", typ) - } - - var err error - e.Mode, e.Segments, err = nl.DecodeSEG6Encap(buf[4:]) - - return err -} -func (e *SEG6Encap) Encode() ([]byte, error) { - s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments) - hdr := make([]byte, 4) - native.PutUint16(hdr, uint16(len(s)+4)) - native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH) - return append(hdr, s...), err -} -func (e *SEG6Encap) String() string { - segs := make([]string, 0, len(e.Segments)) - // append segment backwards (from n to 0) since seg#0 is the last segment. - for i := len(e.Segments); i > 0; i-- { - segs = append(segs, e.Segments[i-1].String()) - } - str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode), - len(e.Segments), strings.Join(segs, " ")) - return str -} -func (e *SEG6Encap) Equal(x Encap) bool { - o, ok := x.(*SEG6Encap) - if !ok { - return false - } - if e == o { - return true - } - if e == nil || o == nil { - return false - } - if e.Mode != o.Mode { - return false - } - if len(e.Segments) != len(o.Segments) { - return false - } - for i := range e.Segments { - if !e.Segments[i].Equal(o.Segments[i]) { - return false - } - } - return true -} - -// SEG6LocalEncap definitions -type SEG6LocalEncap struct { - Flags [nl.SEG6_LOCAL_MAX]bool - Action int - Segments []net.IP // from SRH in seg6_local_lwt - Table int // table id for End.T and End.DT6 - InAddr net.IP - In6Addr net.IP - Iif int - Oif int -} - -func (e *SEG6LocalEncap) Type() int { - return nl.LWTUNNEL_ENCAP_SEG6_LOCAL -} -func (e *SEG6LocalEncap) Decode(buf []byte) error { - attrs, err := nl.ParseRouteAttr(buf) - if err != nil { - return err - } - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.SEG6_LOCAL_ACTION: - e.Action = int(native.Uint32(attr.Value[0:4])) - e.Flags[nl.SEG6_LOCAL_ACTION] = true - case nl.SEG6_LOCAL_SRH: - e.Segments, err = nl.DecodeSEG6Srh(attr.Value[:]) - e.Flags[nl.SEG6_LOCAL_SRH] = true - case nl.SEG6_LOCAL_TABLE: - e.Table = int(native.Uint32(attr.Value[0:4])) - e.Flags[nl.SEG6_LOCAL_TABLE] = true - case nl.SEG6_LOCAL_NH4: - e.InAddr = net.IP(attr.Value[0:4]) - e.Flags[nl.SEG6_LOCAL_NH4] = true - case nl.SEG6_LOCAL_NH6: - e.In6Addr = net.IP(attr.Value[0:16]) - e.Flags[nl.SEG6_LOCAL_NH6] = true - case nl.SEG6_LOCAL_IIF: - e.Iif = int(native.Uint32(attr.Value[0:4])) - e.Flags[nl.SEG6_LOCAL_IIF] = true - case nl.SEG6_LOCAL_OIF: - e.Oif = int(native.Uint32(attr.Value[0:4])) - e.Flags[nl.SEG6_LOCAL_OIF] = true - } - } - return err -} -func (e *SEG6LocalEncap) Encode() ([]byte, error) { - var err error - res := make([]byte, 8) - native.PutUint16(res, 8) // length - native.PutUint16(res[2:], nl.SEG6_LOCAL_ACTION) - native.PutUint32(res[4:], uint32(e.Action)) - if e.Flags[nl.SEG6_LOCAL_SRH] { - srh, err := nl.EncodeSEG6Srh(e.Segments) - if err != nil { - return nil, err - } - attr := make([]byte, 4) - native.PutUint16(attr, uint16(len(srh)+4)) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_SRH) - attr = append(attr, srh...) - res = append(res, attr...) - } - if e.Flags[nl.SEG6_LOCAL_TABLE] { - attr := make([]byte, 8) - native.PutUint16(attr, 8) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_TABLE) - native.PutUint32(attr[4:], uint32(e.Table)) - res = append(res, attr...) - } - if e.Flags[nl.SEG6_LOCAL_NH4] { - attr := make([]byte, 4) - native.PutUint16(attr, 8) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH4) - ipv4 := e.InAddr.To4() - if ipv4 == nil { - err = fmt.Errorf("SEG6_LOCAL_NH4 has invalid IPv4 address") - return nil, err - } - attr = append(attr, ipv4...) - res = append(res, attr...) - } - if e.Flags[nl.SEG6_LOCAL_NH6] { - attr := make([]byte, 4) - native.PutUint16(attr, 20) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH6) - attr = append(attr, e.In6Addr...) - res = append(res, attr...) - } - if e.Flags[nl.SEG6_LOCAL_IIF] { - attr := make([]byte, 8) - native.PutUint16(attr, 8) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_IIF) - native.PutUint32(attr[4:], uint32(e.Iif)) - res = append(res, attr...) - } - if e.Flags[nl.SEG6_LOCAL_OIF] { - attr := make([]byte, 8) - native.PutUint16(attr, 8) - native.PutUint16(attr[2:], nl.SEG6_LOCAL_OIF) - native.PutUint32(attr[4:], uint32(e.Oif)) - res = append(res, attr...) - } - return res, err -} -func (e *SEG6LocalEncap) String() string { - strs := make([]string, 0, nl.SEG6_LOCAL_MAX) - strs = append(strs, fmt.Sprintf("action %s", nl.SEG6LocalActionString(e.Action))) - - if e.Flags[nl.SEG6_LOCAL_TABLE] { - strs = append(strs, fmt.Sprintf("table %d", e.Table)) - } - if e.Flags[nl.SEG6_LOCAL_NH4] { - strs = append(strs, fmt.Sprintf("nh4 %s", e.InAddr)) - } - if e.Flags[nl.SEG6_LOCAL_NH6] { - strs = append(strs, fmt.Sprintf("nh6 %s", e.In6Addr)) - } - if e.Flags[nl.SEG6_LOCAL_IIF] { - link, err := LinkByIndex(e.Iif) - if err != nil { - strs = append(strs, fmt.Sprintf("iif %d", e.Iif)) - } else { - strs = append(strs, fmt.Sprintf("iif %s", link.Attrs().Name)) - } - } - if e.Flags[nl.SEG6_LOCAL_OIF] { - link, err := LinkByIndex(e.Oif) - if err != nil { - strs = append(strs, fmt.Sprintf("oif %d", e.Oif)) - } else { - strs = append(strs, fmt.Sprintf("oif %s", link.Attrs().Name)) - } - } - if e.Flags[nl.SEG6_LOCAL_SRH] { - segs := make([]string, 0, len(e.Segments)) - //append segment backwards (from n to 0) since seg#0 is the last segment. - for i := len(e.Segments); i > 0; i-- { - segs = append(segs, e.Segments[i-1].String()) - } - strs = append(strs, fmt.Sprintf("segs %d [ %s ]", len(e.Segments), strings.Join(segs, " "))) - } - return strings.Join(strs, " ") -} -func (e *SEG6LocalEncap) Equal(x Encap) bool { - o, ok := x.(*SEG6LocalEncap) - if !ok { - return false - } - if e == o { - return true - } - if e == nil || o == nil { - return false - } - // compare all arrays first - for i := range e.Flags { - if e.Flags[i] != o.Flags[i] { - return false - } - } - if len(e.Segments) != len(o.Segments) { - return false - } - for i := range e.Segments { - if !e.Segments[i].Equal(o.Segments[i]) { - return false - } - } - // compare values - if !e.InAddr.Equal(o.InAddr) || !e.In6Addr.Equal(o.In6Addr) { - return false - } - if e.Action != o.Action || e.Table != o.Table || e.Iif != o.Iif || e.Oif != o.Oif { - return false - } - return true -} - -// Encap BPF definitions -type bpfObj struct { - progFd int - progName string -} -type BpfEncap struct { - progs [nl.LWT_BPF_MAX]bpfObj - headroom int -} - -// SetProg adds a bpf function to the route via netlink RTA_ENCAP. The fd must be a bpf -// program loaded with bpf(type=BPF_PROG_TYPE_LWT_*) matching the direction the program should -// be applied to (LWT_BPF_IN, LWT_BPF_OUT, LWT_BPF_XMIT). -func (e *BpfEncap) SetProg(mode, progFd int, progName string) error { - if progFd <= 0 { - return fmt.Errorf("lwt bpf SetProg: invalid fd") - } - if mode <= nl.LWT_BPF_UNSPEC || mode >= nl.LWT_BPF_XMIT_HEADROOM { - return fmt.Errorf("lwt bpf SetProg:invalid mode") - } - e.progs[mode].progFd = progFd - e.progs[mode].progName = fmt.Sprintf("%s[fd:%d]", progName, progFd) - return nil -} - -// SetXmitHeadroom sets the xmit headroom (LWT_BPF_MAX_HEADROOM) via netlink RTA_ENCAP. -// maximum headroom is LWT_BPF_MAX_HEADROOM -func (e *BpfEncap) SetXmitHeadroom(headroom int) error { - if headroom > nl.LWT_BPF_MAX_HEADROOM || headroom < 0 { - return fmt.Errorf("invalid headroom size. range is 0 - %d", nl.LWT_BPF_MAX_HEADROOM) - } - e.headroom = headroom - return nil -} - -func (e *BpfEncap) Type() int { - return nl.LWTUNNEL_ENCAP_BPF -} -func (e *BpfEncap) Decode(buf []byte) error { - if len(buf) < 4 { - return fmt.Errorf("lwt bpf decode: lack of bytes") - } - native := nl.NativeEndian() - attrs, err := nl.ParseRouteAttr(buf) - if err != nil { - return fmt.Errorf("lwt bpf decode: failed parsing attribute. err: %v", err) - } - for _, attr := range attrs { - if int(attr.Attr.Type) < 1 { - // nl.LWT_BPF_UNSPEC - continue - } - if int(attr.Attr.Type) > nl.LWT_BPF_MAX { - return fmt.Errorf("lwt bpf decode: received unknown attribute type: %d", attr.Attr.Type) - } - switch int(attr.Attr.Type) { - case nl.LWT_BPF_MAX_HEADROOM: - e.headroom = int(native.Uint32(attr.Value)) - default: - bpfO := bpfObj{} - parsedAttrs, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return fmt.Errorf("lwt bpf decode: failed parsing route attribute") - } - for _, parsedAttr := range parsedAttrs { - switch int(parsedAttr.Attr.Type) { - case nl.LWT_BPF_PROG_FD: - bpfO.progFd = int(native.Uint32(parsedAttr.Value)) - case nl.LWT_BPF_PROG_NAME: - bpfO.progName = string(parsedAttr.Value) - default: - return fmt.Errorf("lwt bpf decode: received unknown attribute: type: %d, len: %d", parsedAttr.Attr.Type, parsedAttr.Attr.Len) - } - } - e.progs[attr.Attr.Type] = bpfO - } - } - return nil -} - -func (e *BpfEncap) Encode() ([]byte, error) { - buf := make([]byte, 0) - native = nl.NativeEndian() - for index, attr := range e.progs { - nlMsg := nl.NewRtAttr(index, []byte{}) - if attr.progFd != 0 { - nlMsg.AddRtAttr(nl.LWT_BPF_PROG_FD, nl.Uint32Attr(uint32(attr.progFd))) - } - if attr.progName != "" { - nlMsg.AddRtAttr(nl.LWT_BPF_PROG_NAME, nl.ZeroTerminated(attr.progName)) - } - if nlMsg.Len() > 4 { - buf = append(buf, nlMsg.Serialize()...) - } - } - if len(buf) <= 4 { - return nil, fmt.Errorf("lwt bpf encode: bpf obj definitions returned empty buffer") - } - if e.headroom > 0 { - hRoom := nl.NewRtAttr(nl.LWT_BPF_XMIT_HEADROOM, nl.Uint32Attr(uint32(e.headroom))) - buf = append(buf, hRoom.Serialize()...) - } - return buf, nil -} - -func (e *BpfEncap) String() string { - progs := make([]string, 0) - for index, obj := range e.progs { - empty := bpfObj{} - switch index { - case nl.LWT_BPF_IN: - if obj != empty { - progs = append(progs, fmt.Sprintf("in: %s", obj.progName)) - } - case nl.LWT_BPF_OUT: - if obj != empty { - progs = append(progs, fmt.Sprintf("out: %s", obj.progName)) - } - case nl.LWT_BPF_XMIT: - if obj != empty { - progs = append(progs, fmt.Sprintf("xmit: %s", obj.progName)) - } - } - } - if e.headroom > 0 { - progs = append(progs, fmt.Sprintf("xmit headroom: %d", e.headroom)) - } - return strings.Join(progs, " ") -} - -func (e *BpfEncap) Equal(x Encap) bool { - o, ok := x.(*BpfEncap) - if !ok { - return false - } - if e.headroom != o.headroom { - return false - } - for i := range o.progs { - if o.progs[i] != e.progs[i] { - return false - } - } - return true -} - -type Via struct { - AddrFamily int - Addr net.IP -} - -func (v *Via) Equal(x Destination) bool { - o, ok := x.(*Via) - if !ok { - return false - } - if v.AddrFamily == x.Family() && v.Addr.Equal(o.Addr) { - return true - } - return false -} - -func (v *Via) String() string { - return fmt.Sprintf("Family: %d, Address: %s", v.AddrFamily, v.Addr.String()) -} - -func (v *Via) Family() int { - return v.AddrFamily -} - -func (v *Via) Encode() ([]byte, error) { - buf := &bytes.Buffer{} - err := binary.Write(buf, native, uint16(v.AddrFamily)) - if err != nil { - return nil, err - } - err = binary.Write(buf, native, v.Addr) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func (v *Via) Decode(b []byte) error { - if len(b) < 6 { - return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b)) - } - v.AddrFamily = int(native.Uint16(b[0:2])) - if v.AddrFamily == nl.FAMILY_V4 { - v.Addr = net.IP(b[2:6]) - return nil - } else if v.AddrFamily == nl.FAMILY_V6 { - if len(b) < 18 { - return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b)) - } - v.Addr = net.IP(b[2:]) - return nil - } - return fmt.Errorf("decoding failed: address family %d unknown", v.AddrFamily) -} - -// RouteAdd will add a route to the system. -// Equivalent to: `ip route add $route` -func RouteAdd(route *Route) error { - return pkgHandle.RouteAdd(route) -} - -// RouteAdd will add a route to the system. -// Equivalent to: `ip route add $route` -func (h *Handle) RouteAdd(route *Route) error { - flags := unix.NLM_F_CREATE | unix.NLM_F_EXCL | unix.NLM_F_ACK - req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) - return h.routeHandle(route, req, nl.NewRtMsg()) -} - -// RouteAppend will append a route to the system. -// Equivalent to: `ip route append $route` -func RouteAppend(route *Route) error { - return pkgHandle.RouteAppend(route) -} - -// RouteAppend will append a route to the system. -// Equivalent to: `ip route append $route` -func (h *Handle) RouteAppend(route *Route) error { - flags := unix.NLM_F_CREATE | unix.NLM_F_APPEND | unix.NLM_F_ACK - req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) - return h.routeHandle(route, req, nl.NewRtMsg()) -} - -// RouteAddEcmp will add a route to the system. -func RouteAddEcmp(route *Route) error { - return pkgHandle.RouteAddEcmp(route) -} - -// RouteAddEcmp will add a route to the system. -func (h *Handle) RouteAddEcmp(route *Route) error { - flags := unix.NLM_F_CREATE | unix.NLM_F_ACK - req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) - return h.routeHandle(route, req, nl.NewRtMsg()) -} - -// RouteReplace will add a route to the system. -// Equivalent to: `ip route replace $route` -func RouteReplace(route *Route) error { - return pkgHandle.RouteReplace(route) -} - -// RouteReplace will add a route to the system. -// Equivalent to: `ip route replace $route` -func (h *Handle) RouteReplace(route *Route) error { - flags := unix.NLM_F_CREATE | unix.NLM_F_REPLACE | unix.NLM_F_ACK - req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) - return h.routeHandle(route, req, nl.NewRtMsg()) -} - -// RouteDel will delete a route from the system. -// Equivalent to: `ip route del $route` -func RouteDel(route *Route) error { - return pkgHandle.RouteDel(route) -} - -// RouteDel will delete a route from the system. -// Equivalent to: `ip route del $route` -func (h *Handle) RouteDel(route *Route) error { - req := h.newNetlinkRequest(unix.RTM_DELROUTE, unix.NLM_F_ACK) - return h.routeHandle(route, req, nl.NewRtDelMsg()) -} - -func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error { - if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil && route.MPLSDst == nil { - return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil") - } - - family := -1 - var rtAttrs []*nl.RtAttr - - if route.Dst != nil && route.Dst.IP != nil { - dstLen, _ := route.Dst.Mask.Size() - msg.Dst_len = uint8(dstLen) - dstFamily := nl.GetIPFamily(route.Dst.IP) - family = dstFamily - var dstData []byte - if dstFamily == FAMILY_V4 { - dstData = route.Dst.IP.To4() - } else { - dstData = route.Dst.IP.To16() - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) - } else if route.MPLSDst != nil { - family = nl.FAMILY_MPLS - msg.Dst_len = uint8(20) - msg.Type = unix.RTN_UNICAST - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst))) - } - - if route.NewDst != nil { - if family != -1 && family != route.NewDst.Family() { - return fmt.Errorf("new destination and destination are not the same address family") - } - buf, err := route.NewDst.Encode() - if err != nil { - return err - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_NEWDST, buf)) - } - - if route.Encap != nil { - buf := make([]byte, 2) - native.PutUint16(buf, uint16(route.Encap.Type())) - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf)) - buf, err := route.Encap.Encode() - if err != nil { - return err - } - switch route.Encap.Type() { - case nl.LWTUNNEL_ENCAP_BPF: - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP|unix.NLA_F_NESTED, buf)) - default: - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP, buf)) - } - - } - - if route.Src != nil { - srcFamily := nl.GetIPFamily(route.Src) - if family != -1 && family != srcFamily { - return fmt.Errorf("source and destination ip are not the same IP family") - } - family = srcFamily - var srcData []byte - if srcFamily == FAMILY_V4 { - srcData = route.Src.To4() - } else { - srcData = route.Src.To16() - } - // The commonly used src ip for routes is actually PREFSRC - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PREFSRC, srcData)) - } - - if route.Gw != nil { - gwFamily := nl.GetIPFamily(route.Gw) - if family != -1 && family != gwFamily { - return fmt.Errorf("gateway, source, and destination ip are not the same IP family") - } - family = gwFamily - var gwData []byte - if gwFamily == FAMILY_V4 { - gwData = route.Gw.To4() - } else { - gwData = route.Gw.To16() - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData)) - } - - if route.Via != nil { - buf, err := route.Via.Encode() - if err != nil { - return fmt.Errorf("failed to encode RTA_VIA: %v", err) - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_VIA, buf)) - } - - if len(route.MultiPath) > 0 { - buf := []byte{} - for _, nh := range route.MultiPath { - rtnh := &nl.RtNexthop{ - RtNexthop: unix.RtNexthop{ - Hops: uint8(nh.Hops), - Ifindex: int32(nh.LinkIndex), - Flags: uint8(nh.Flags), - }, - } - children := []nl.NetlinkRequestData{} - if nh.Gw != nil { - gwFamily := nl.GetIPFamily(nh.Gw) - if family != -1 && family != gwFamily { - return fmt.Errorf("gateway, source, and destination ip are not the same IP family") - } - if gwFamily == FAMILY_V4 { - children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To4()))) - } else { - children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To16()))) - } - } - if nh.NewDst != nil { - if family != -1 && family != nh.NewDst.Family() { - return fmt.Errorf("new destination and destination are not the same address family") - } - buf, err := nh.NewDst.Encode() - if err != nil { - return err - } - children = append(children, nl.NewRtAttr(unix.RTA_NEWDST, buf)) - } - if nh.Encap != nil { - buf := make([]byte, 2) - native.PutUint16(buf, uint16(nh.Encap.Type())) - children = append(children, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf)) - buf, err := nh.Encap.Encode() - if err != nil { - return err - } - children = append(children, nl.NewRtAttr(unix.RTA_ENCAP, buf)) - } - if nh.Via != nil { - buf, err := nh.Via.Encode() - if err != nil { - return err - } - children = append(children, nl.NewRtAttr(unix.RTA_VIA, buf)) - } - rtnh.Children = children - buf = append(buf, rtnh.Serialize()...) - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_MULTIPATH, buf)) - } - - if route.Table > 0 { - if route.Table >= 256 { - msg.Table = unix.RT_TABLE_UNSPEC - b := make([]byte, 4) - native.PutUint32(b, uint32(route.Table)) - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_TABLE, b)) - } else { - msg.Table = uint8(route.Table) - } - } - - if route.Priority > 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(route.Priority)) - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b)) - } - if route.Realm > 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(route.Realm)) - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_FLOW, b)) - } - if route.Tos > 0 { - msg.Tos = uint8(route.Tos) - } - if route.Protocol > 0 { - msg.Protocol = uint8(route.Protocol) - } - if route.Type > 0 { - msg.Type = uint8(route.Type) - } - - var metrics []*nl.RtAttr - if route.MTU > 0 { - b := nl.Uint32Attr(uint32(route.MTU)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b)) - } - if route.Window > 0 { - b := nl.Uint32Attr(uint32(route.Window)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_WINDOW, b)) - } - if route.Rtt > 0 { - b := nl.Uint32Attr(uint32(route.Rtt)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTT, b)) - } - if route.RttVar > 0 { - b := nl.Uint32Attr(uint32(route.RttVar)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTTVAR, b)) - } - if route.Ssthresh > 0 { - b := nl.Uint32Attr(uint32(route.Ssthresh)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_SSTHRESH, b)) - } - if route.Cwnd > 0 { - b := nl.Uint32Attr(uint32(route.Cwnd)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_CWND, b)) - } - if route.AdvMSS > 0 { - b := nl.Uint32Attr(uint32(route.AdvMSS)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b)) - } - if route.Reordering > 0 { - b := nl.Uint32Attr(uint32(route.Reordering)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_REORDERING, b)) - } - if route.Hoplimit > 0 { - b := nl.Uint32Attr(uint32(route.Hoplimit)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_HOPLIMIT, b)) - } - if route.InitCwnd > 0 { - b := nl.Uint32Attr(uint32(route.InitCwnd)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_INITCWND, b)) - } - if route.Features > 0 { - b := nl.Uint32Attr(uint32(route.Features)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_FEATURES, b)) - } - if route.RtoMin > 0 { - b := nl.Uint32Attr(uint32(route.RtoMin)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTO_MIN, b)) - } - if route.InitRwnd > 0 { - b := nl.Uint32Attr(uint32(route.InitRwnd)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_INITRWND, b)) - } - if route.QuickACK > 0 { - b := nl.Uint32Attr(uint32(route.QuickACK)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_QUICKACK, b)) - } - if route.Congctl != "" { - b := nl.ZeroTerminated(route.Congctl) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_CC_ALGO, b)) - } - if route.FastOpenNoCookie > 0 { - b := nl.Uint32Attr(uint32(route.FastOpenNoCookie)) - metrics = append(metrics, nl.NewRtAttr(unix.RTAX_FASTOPEN_NO_COOKIE, b)) - } - - if metrics != nil { - attr := nl.NewRtAttr(unix.RTA_METRICS, nil) - for _, metric := range metrics { - attr.AddChild(metric) - } - rtAttrs = append(rtAttrs, attr) - } - - msg.Flags = uint32(route.Flags) - msg.Scope = uint8(route.Scope) - msg.Family = uint8(family) - req.AddData(msg) - for _, attr := range rtAttrs { - req.AddData(attr) - } - - b := make([]byte, 4) - native.PutUint32(b, uint32(route.LinkIndex)) - - req.AddData(nl.NewRtAttr(unix.RTA_OIF, b)) - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// RouteList gets a list of routes in the system. -// Equivalent to: `ip route show`. -// The list can be filtered by link and ip family. -func RouteList(link Link, family int) ([]Route, error) { - return pkgHandle.RouteList(link, family) -} - -// RouteList gets a list of routes in the system. -// Equivalent to: `ip route show`. -// The list can be filtered by link and ip family. -func (h *Handle) RouteList(link Link, family int) ([]Route, error) { - var routeFilter *Route - if link != nil { - routeFilter = &Route{ - LinkIndex: link.Attrs().Index, - } - } - return h.RouteListFiltered(family, routeFilter, RT_FILTER_OIF) -} - -// RouteListFiltered gets a list of routes in the system filtered with specified rules. -// All rules must be defined in RouteFilter struct -func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { - return pkgHandle.RouteListFiltered(family, filter, filterMask) -} - -// RouteListFiltered gets a list of routes in the system filtered with specified rules. -// All rules must be defined in RouteFilter struct -func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { - req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP) - infmsg := nl.NewIfInfomsg(family) - req.AddData(infmsg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) - if err != nil { - return nil, err - } - - var res []Route - for _, m := range msgs { - msg := nl.DeserializeRtMsg(m) - if msg.Flags&unix.RTM_F_CLONED != 0 { - // Ignore cloned routes - continue - } - if msg.Table != unix.RT_TABLE_MAIN { - if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 { - // Ignore non-main tables - continue - } - } - route, err := deserializeRoute(m) - if err != nil { - return nil, err - } - if filter != nil { - switch { - case filterMask&RT_FILTER_TABLE != 0 && filter.Table != unix.RT_TABLE_UNSPEC && route.Table != filter.Table: - continue - case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol: - continue - case filterMask&RT_FILTER_SCOPE != 0 && route.Scope != filter.Scope: - continue - case filterMask&RT_FILTER_TYPE != 0 && route.Type != filter.Type: - continue - case filterMask&RT_FILTER_TOS != 0 && route.Tos != filter.Tos: - continue - case filterMask&RT_FILTER_REALM != 0 && route.Realm != filter.Realm: - continue - case filterMask&RT_FILTER_OIF != 0 && route.LinkIndex != filter.LinkIndex: - continue - case filterMask&RT_FILTER_IIF != 0 && route.ILinkIndex != filter.ILinkIndex: - continue - case filterMask&RT_FILTER_GW != 0 && !route.Gw.Equal(filter.Gw): - continue - case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src): - continue - case filterMask&RT_FILTER_DST != 0: - if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) { - if !ipNetEqual(route.Dst, filter.Dst) { - continue - } - } - case filterMask&RT_FILTER_HOPLIMIT != 0 && route.Hoplimit != filter.Hoplimit: - continue - } - } - res = append(res, route) - } - return res, nil -} - -// deserializeRoute decodes a binary netlink message into a Route struct -func deserializeRoute(m []byte) (Route, error) { - msg := nl.DeserializeRtMsg(m) - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return Route{}, err - } - route := Route{ - Scope: Scope(msg.Scope), - Protocol: RouteProtocol(int(msg.Protocol)), - Table: int(msg.Table), - Type: int(msg.Type), - Tos: int(msg.Tos), - Flags: int(msg.Flags), - Family: int(msg.Family), - } - - var encap, encapType syscall.NetlinkRouteAttr - for _, attr := range attrs { - switch attr.Attr.Type { - case unix.RTA_GATEWAY: - route.Gw = net.IP(attr.Value) - case unix.RTA_PREFSRC: - route.Src = net.IP(attr.Value) - case unix.RTA_DST: - if msg.Family == nl.FAMILY_MPLS { - stack := nl.DecodeMPLSStack(attr.Value) - if len(stack) == 0 || len(stack) > 1 { - return route, fmt.Errorf("invalid MPLS RTA_DST") - } - route.MPLSDst = &stack[0] - } else { - route.Dst = &net.IPNet{ - IP: attr.Value, - Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), - } - } - case unix.RTA_OIF: - route.LinkIndex = int(native.Uint32(attr.Value[0:4])) - case unix.RTA_IIF: - route.ILinkIndex = int(native.Uint32(attr.Value[0:4])) - case unix.RTA_PRIORITY: - route.Priority = int(native.Uint32(attr.Value[0:4])) - case unix.RTA_FLOW: - route.Realm = int(native.Uint32(attr.Value[0:4])) - case unix.RTA_TABLE: - route.Table = int(native.Uint32(attr.Value[0:4])) - case unix.RTA_MULTIPATH: - parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) { - if len(value) < unix.SizeofRtNexthop { - return nil, nil, fmt.Errorf("lack of bytes") - } - nh := nl.DeserializeRtNexthop(value) - if len(value) < int(nh.RtNexthop.Len) { - return nil, nil, fmt.Errorf("lack of bytes") - } - info := &NexthopInfo{ - LinkIndex: int(nh.RtNexthop.Ifindex), - Hops: int(nh.RtNexthop.Hops), - Flags: int(nh.RtNexthop.Flags), - } - attrs, err := nl.ParseRouteAttr(value[unix.SizeofRtNexthop:int(nh.RtNexthop.Len)]) - if err != nil { - return nil, nil, err - } - var encap, encapType syscall.NetlinkRouteAttr - for _, attr := range attrs { - switch attr.Attr.Type { - case unix.RTA_GATEWAY: - info.Gw = net.IP(attr.Value) - case unix.RTA_NEWDST: - var d Destination - switch msg.Family { - case nl.FAMILY_MPLS: - d = &MPLSDestination{} - } - if err := d.Decode(attr.Value); err != nil { - return nil, nil, err - } - info.NewDst = d - case unix.RTA_ENCAP_TYPE: - encapType = attr - case unix.RTA_ENCAP: - encap = attr - case unix.RTA_VIA: - d := &Via{} - if err := d.Decode(attr.Value); err != nil { - return nil, nil, err - } - info.Via = d - } - } - - if len(encap.Value) != 0 && len(encapType.Value) != 0 { - typ := int(native.Uint16(encapType.Value[0:2])) - var e Encap - switch typ { - case nl.LWTUNNEL_ENCAP_MPLS: - e = &MPLSEncap{} - if err := e.Decode(encap.Value); err != nil { - return nil, nil, err - } - } - info.Encap = e - } - - return info, value[int(nh.RtNexthop.Len):], nil - } - rest := attr.Value - for len(rest) > 0 { - info, buf, err := parseRtNexthop(rest) - if err != nil { - return route, err - } - route.MultiPath = append(route.MultiPath, info) - rest = buf - } - case unix.RTA_NEWDST: - var d Destination - switch msg.Family { - case nl.FAMILY_MPLS: - d = &MPLSDestination{} - } - if err := d.Decode(attr.Value); err != nil { - return route, err - } - route.NewDst = d - case unix.RTA_VIA: - v := &Via{} - if err := v.Decode(attr.Value); err != nil { - return route, err - } - route.Via = v - case unix.RTA_ENCAP_TYPE: - encapType = attr - case unix.RTA_ENCAP: - encap = attr - case unix.RTA_METRICS: - metrics, err := nl.ParseRouteAttr(attr.Value) - if err != nil { - return route, err - } - for _, metric := range metrics { - switch metric.Attr.Type { - case unix.RTAX_MTU: - route.MTU = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_WINDOW: - route.Window = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_RTT: - route.Rtt = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_RTTVAR: - route.RttVar = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_SSTHRESH: - route.Ssthresh = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_CWND: - route.Cwnd = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_ADVMSS: - route.AdvMSS = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_REORDERING: - route.Reordering = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_HOPLIMIT: - route.Hoplimit = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_INITCWND: - route.InitCwnd = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_FEATURES: - route.Features = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_RTO_MIN: - route.RtoMin = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_INITRWND: - route.InitRwnd = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_QUICKACK: - route.QuickACK = int(native.Uint32(metric.Value[0:4])) - case unix.RTAX_CC_ALGO: - route.Congctl = nl.BytesToString(metric.Value) - case unix.RTAX_FASTOPEN_NO_COOKIE: - route.FastOpenNoCookie = int(native.Uint32(metric.Value[0:4])) - } - } - } - } - - if len(encap.Value) != 0 && len(encapType.Value) != 0 { - typ := int(native.Uint16(encapType.Value[0:2])) - var e Encap - switch typ { - case nl.LWTUNNEL_ENCAP_MPLS: - e = &MPLSEncap{} - if err := e.Decode(encap.Value); err != nil { - return route, err - } - case nl.LWTUNNEL_ENCAP_SEG6: - e = &SEG6Encap{} - if err := e.Decode(encap.Value); err != nil { - return route, err - } - case nl.LWTUNNEL_ENCAP_SEG6_LOCAL: - e = &SEG6LocalEncap{} - if err := e.Decode(encap.Value); err != nil { - return route, err - } - case nl.LWTUNNEL_ENCAP_BPF: - e = &BpfEncap{} - if err := e.Decode(encap.Value); err != nil { - return route, err - } - } - route.Encap = e - } - - return route, nil -} - -// RouteGetOptions contains a set of options to use with -// RouteGetWithOptions -type RouteGetOptions struct { - Iif string - Oif string - VrfName string - SrcAddr net.IP -} - -// RouteGetWithOptions gets a route to a specific destination from the host system. -// Equivalent to: 'ip route get <> vrf '. -func RouteGetWithOptions(destination net.IP, options *RouteGetOptions) ([]Route, error) { - return pkgHandle.RouteGetWithOptions(destination, options) -} - -// RouteGet gets a route to a specific destination from the host system. -// Equivalent to: 'ip route get'. -func RouteGet(destination net.IP) ([]Route, error) { - return pkgHandle.RouteGet(destination) -} - -// RouteGetWithOptions gets a route to a specific destination from the host system. -// Equivalent to: 'ip route get <> vrf '. -func (h *Handle) RouteGetWithOptions(destination net.IP, options *RouteGetOptions) ([]Route, error) { - req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST) - family := nl.GetIPFamily(destination) - var destinationData []byte - var bitlen uint8 - if family == FAMILY_V4 { - destinationData = destination.To4() - bitlen = 32 - } else { - destinationData = destination.To16() - bitlen = 128 - } - msg := &nl.RtMsg{} - msg.Family = uint8(family) - msg.Dst_len = bitlen - if options != nil && options.SrcAddr != nil { - msg.Src_len = bitlen - } - msg.Flags = unix.RTM_F_LOOKUP_TABLE - req.AddData(msg) - - rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData) - req.AddData(rtaDst) - - if options != nil { - if options.VrfName != "" { - link, err := LinkByName(options.VrfName) - if err != nil { - return nil, err - } - b := make([]byte, 4) - native.PutUint32(b, uint32(link.Attrs().Index)) - - req.AddData(nl.NewRtAttr(unix.RTA_OIF, b)) - } - - if len(options.Iif) > 0 { - link, err := LinkByName(options.Iif) - if err != nil { - return nil, err - } - - b := make([]byte, 4) - native.PutUint32(b, uint32(link.Attrs().Index)) - - req.AddData(nl.NewRtAttr(unix.RTA_IIF, b)) - } - - if len(options.Oif) > 0 { - link, err := LinkByName(options.Oif) - if err != nil { - return nil, err - } - - b := make([]byte, 4) - native.PutUint32(b, uint32(link.Attrs().Index)) - - req.AddData(nl.NewRtAttr(unix.RTA_OIF, b)) - } - - if options.SrcAddr != nil { - var srcAddr []byte - if family == FAMILY_V4 { - srcAddr = options.SrcAddr.To4() - } else { - srcAddr = options.SrcAddr.To16() - } - - req.AddData(nl.NewRtAttr(unix.RTA_SRC, srcAddr)) - } - } - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) - if err != nil { - return nil, err - } - - var res []Route - for _, m := range msgs { - route, err := deserializeRoute(m) - if err != nil { - return nil, err - } - res = append(res, route) - } - return res, nil -} - -// RouteGet gets a route to a specific destination from the host system. -// Equivalent to: 'ip route get'. -func (h *Handle) RouteGet(destination net.IP) ([]Route, error) { - return h.RouteGetWithOptions(destination, nil) -} - -// RouteSubscribe takes a chan down which notifications will be sent -// when routes are added or deleted. Close the 'done' chan to stop subscription. -func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error { - return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) -} - -// RouteSubscribeAt works like RouteSubscribe plus it allows the caller -// to choose the network namespace in which to subscribe (ns). -func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error { - return routeSubscribeAt(ns, netns.None(), ch, done, nil, false) -} - -// RouteSubscribeOptions contains a set of options to use with -// RouteSubscribeWithOptions. -type RouteSubscribeOptions struct { - Namespace *netns.NsHandle - ErrorCallback func(error) - ListExisting bool -} - -// RouteSubscribeWithOptions work like RouteSubscribe but enable to -// provide additional options to modify the behavior. Currently, the -// namespace can be provided as well as an error callback. -func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, options RouteSubscribeOptions) error { - if options.Namespace == nil { - none := netns.None() - options.Namespace = &none - } - return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) -} - -func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error { - s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_ROUTE, unix.RTNLGRP_IPV6_ROUTE) - if err != nil { - return err - } - if done != nil { - go func() { - <-done - s.Close() - }() - } - if listExisting { - req := pkgHandle.newNetlinkRequest(unix.RTM_GETROUTE, - unix.NLM_F_DUMP) - infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) - req.AddData(infmsg) - if err := s.Send(req); err != nil { - return err - } - } - go func() { - defer close(ch) - for { - msgs, from, err := s.Receive() - if err != nil { - if cberr != nil { - cberr(fmt.Errorf("Receive failed: %v", - err)) - } - return - } - if from.Pid != nl.PidKernel { - if cberr != nil { - cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)) - } - continue - } - for _, m := range msgs { - if m.Header.Type == unix.NLMSG_DONE { - continue - } - if m.Header.Type == unix.NLMSG_ERROR { - error := int32(native.Uint32(m.Data[0:4])) - if error == 0 { - continue - } - if cberr != nil { - cberr(fmt.Errorf("error message: %v", - syscall.Errno(-error))) - } - continue - } - route, err := deserializeRoute(m.Data) - if err != nil { - if cberr != nil { - cberr(err) - } - continue - } - ch <- RouteUpdate{Type: m.Header.Type, Route: route} - } - } - }() - - return nil -} - -func (p RouteProtocol) String() string { - switch int(p) { - case unix.RTPROT_BABEL: - return "babel" - case unix.RTPROT_BGP: - return "bgp" - case unix.RTPROT_BIRD: - return "bird" - case unix.RTPROT_BOOT: - return "boot" - case unix.RTPROT_DHCP: - return "dhcp" - case unix.RTPROT_DNROUTED: - return "dnrouted" - case unix.RTPROT_EIGRP: - return "eigrp" - case unix.RTPROT_GATED: - return "gated" - case unix.RTPROT_ISIS: - return "isis" - //case unix.RTPROT_KEEPALIVED: - // return "keepalived" - case unix.RTPROT_KERNEL: - return "kernel" - case unix.RTPROT_MROUTED: - return "mrouted" - case unix.RTPROT_MRT: - return "mrt" - case unix.RTPROT_NTK: - return "ntk" - case unix.RTPROT_OSPF: - return "ospf" - case unix.RTPROT_RA: - return "ra" - case unix.RTPROT_REDIRECT: - return "redirect" - case unix.RTPROT_RIP: - return "rip" - case unix.RTPROT_STATIC: - return "static" - case unix.RTPROT_UNSPEC: - return "unspec" - case unix.RTPROT_XORP: - return "xorp" - case unix.RTPROT_ZEBRA: - return "zebra" - default: - return strconv.Itoa(int(p)) - } -} diff --git a/vendor/github.com/tailscale/netlink/route_unspecified.go b/vendor/github.com/tailscale/netlink/route_unspecified.go deleted file mode 100644 index db73726..0000000 --- a/vendor/github.com/tailscale/netlink/route_unspecified.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !linux - -package netlink - -import "strconv" - -func (r *Route) ListFlags() []string { - return []string{} -} - -func (n *NexthopInfo) ListFlags() []string { - return []string{} -} - -func (s Scope) String() string { - return "unknown" -} - -func (p RouteProtocol) String() string { - return strconv.Itoa(int(p)) -} diff --git a/vendor/github.com/tailscale/netlink/rule.go b/vendor/github.com/tailscale/netlink/rule.go deleted file mode 100644 index c4e949e..0000000 --- a/vendor/github.com/tailscale/netlink/rule.go +++ /dev/null @@ -1,103 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - - "golang.org/x/sys/unix" -) - -// Rule represents a netlink rule. -type Rule struct { - Priority int - Family int - Table int - Mark int - Mask int - Tos uint - TunID uint - Goto int - Src *net.IPNet - Dst *net.IPNet - Flow int - IifName string - OifName string - SuppressIfgroup int - SuppressPrefixlen int - Invert bool - Dport *RulePortRange - Sport *RulePortRange - - // Type is the unix.RTN_* rule type, such as RTN_UNICAST - // or RTN_UNREACHABLE. - // When adding a new rule, zero means automatic. - Type uint8 -} - -func (r Rule) String() string { - from := "all" - if r.Src != nil && r.Src.String() != "" { - from = r.Src.String() - } - - to := "all" - if r.Dst != nil && r.Dst.String() != "" { - to = r.Dst.String() - } - - var typ string - switch r.Type { - case unix.RTN_UNSPEC: // zero - typ = "" - case unix.RTN_UNICAST: - typ = "" - case unix.RTN_LOCAL: - typ = " local" - case unix.RTN_BROADCAST: - typ = " broadcast" - case unix.RTN_ANYCAST: - typ = " anycast" - case unix.RTN_MULTICAST: - typ = " multicast" - case unix.RTN_BLACKHOLE: - typ = " blackhole" - case unix.RTN_UNREACHABLE: - typ = " unreachable" - case unix.RTN_PROHIBIT: - typ = " prohibit" - case unix.RTN_THROW: - typ = " throw" - case unix.RTN_NAT: - typ = " nat" - case unix.RTN_XRESOLVE: - typ = " xresolve" - default: - typ = fmt.Sprintf(" type(0x%x)", r.Type) - } - return fmt.Sprintf("ip rule %d: from %s to %s table %d%s", - r.Priority, from, to, r.Table, typ) -} - -// NewRule return empty rules. -func NewRule() *Rule { - return &Rule{ - SuppressIfgroup: -1, - SuppressPrefixlen: -1, - Priority: -1, - Mark: -1, - Mask: -1, - Goto: -1, - Flow: -1, - } -} - -// NewRulePortRange creates rule sport/dport range. -func NewRulePortRange(start, end uint16) *RulePortRange { - return &RulePortRange{Start: start, End: end} -} - -// RulePortRange represents rule sport/dport range. -type RulePortRange struct { - Start uint16 - End uint16 -} diff --git a/vendor/github.com/tailscale/netlink/rule_linux.go b/vendor/github.com/tailscale/netlink/rule_linux.go deleted file mode 100644 index aefffae..0000000 --- a/vendor/github.com/tailscale/netlink/rule_linux.go +++ /dev/null @@ -1,294 +0,0 @@ -package netlink - -import ( - "bytes" - "fmt" - "net" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -const FibRuleInvert = 0x2 - -// RuleAdd adds a rule to the system. -// Equivalent to: ip rule add -func RuleAdd(rule *Rule) error { - return pkgHandle.RuleAdd(rule) -} - -// RuleAdd adds a rule to the system. -// Equivalent to: ip rule add -func (h *Handle) RuleAdd(rule *Rule) error { - req := h.newNetlinkRequest(unix.RTM_NEWRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) - return ruleHandle(rule, req) -} - -// RuleDel deletes a rule from the system. -// Equivalent to: ip rule del -func RuleDel(rule *Rule) error { - return pkgHandle.RuleDel(rule) -} - -// RuleDel deletes a rule from the system. -// Equivalent to: ip rule del -func (h *Handle) RuleDel(rule *Rule) error { - req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK) - return ruleHandle(rule, req) -} - -func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { - msg := nl.NewRtMsg() - msg.Family = unix.AF_INET - msg.Protocol = unix.RTPROT_BOOT - msg.Scope = unix.RT_SCOPE_UNIVERSE - msg.Table = unix.RT_TABLE_UNSPEC - msg.Type = rule.Type // usually 0, same as unix.RTN_UNSPEC - if msg.Type == 0 && req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 { - msg.Type = unix.RTN_UNICAST - } - if rule.Invert { - msg.Flags |= FibRuleInvert - } - if rule.Family != 0 { - msg.Family = uint8(rule.Family) - } - if rule.Table >= 0 && rule.Table < 256 { - msg.Table = uint8(rule.Table) - } - if rule.Tos != 0 { - msg.Tos = uint8(rule.Tos) - } - - var dstFamily uint8 - var rtAttrs []*nl.RtAttr - if rule.Dst != nil && rule.Dst.IP != nil { - dstLen, _ := rule.Dst.Mask.Size() - msg.Dst_len = uint8(dstLen) - msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP)) - dstFamily = msg.Family - var dstData []byte - if msg.Family == unix.AF_INET { - dstData = rule.Dst.IP.To4() - } else { - dstData = rule.Dst.IP.To16() - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) - } - - if rule.Src != nil && rule.Src.IP != nil { - msg.Family = uint8(nl.GetIPFamily(rule.Src.IP)) - if dstFamily != 0 && dstFamily != msg.Family { - return fmt.Errorf("source and destination ip are not the same IP family") - } - srcLen, _ := rule.Src.Mask.Size() - msg.Src_len = uint8(srcLen) - var srcData []byte - if msg.Family == unix.AF_INET { - srcData = rule.Src.IP.To4() - } else { - srcData = rule.Src.IP.To16() - } - rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData)) - } - - req.AddData(msg) - for i := range rtAttrs { - req.AddData(rtAttrs[i]) - } - - if rule.Priority >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Priority)) - req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b)) - } - if rule.Mark >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Mark)) - req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b)) - } - if rule.Mask >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Mask)) - req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b)) - } - if rule.Flow >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Flow)) - req.AddData(nl.NewRtAttr(nl.FRA_FLOW, b)) - } - if rule.TunID > 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.TunID)) - req.AddData(nl.NewRtAttr(nl.FRA_TUN_ID, b)) - } - if rule.Table >= 256 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Table)) - req.AddData(nl.NewRtAttr(nl.FRA_TABLE, b)) - } - if msg.Table > 0 { - if rule.SuppressPrefixlen >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.SuppressPrefixlen)) - req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_PREFIXLEN, b)) - } - if rule.SuppressIfgroup >= 0 { - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.SuppressIfgroup)) - req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_IFGROUP, b)) - } - } - if rule.IifName != "" { - req.AddData(nl.NewRtAttr(nl.FRA_IIFNAME, []byte(rule.IifName+"\x00"))) - } - if rule.OifName != "" { - req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName+"\x00"))) - } - if rule.Goto >= 0 { - msg.Type = nl.FR_ACT_GOTO - b := make([]byte, 4) - native.PutUint32(b, uint32(rule.Goto)) - req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b)) - } - - if rule.Dport != nil { - b := rule.Dport.toRtAttrData() - req.AddData(nl.NewRtAttr(nl.FRA_DPORT_RANGE, b)) - } - - if rule.Sport != nil { - b := rule.Sport.toRtAttrData() - req.AddData(nl.NewRtAttr(nl.FRA_SPORT_RANGE, b)) - } - - _, err := req.Execute(unix.NETLINK_ROUTE, 0) - return err -} - -// RuleList lists rules in the system. -// Equivalent to: ip rule list -func RuleList(family int) ([]Rule, error) { - return pkgHandle.RuleList(family) -} - -// RuleList lists rules in the system. -// Equivalent to: ip rule list -func (h *Handle) RuleList(family int) ([]Rule, error) { - return h.RuleListFiltered(family, nil, 0) -} - -// RuleListFiltered gets a list of rules in the system filtered by the -// specified rule template `filter`. -// Equivalent to: ip rule list -func RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) { - return pkgHandle.RuleListFiltered(family, filter, filterMask) -} - -// RuleListFiltered lists rules in the system. -// Equivalent to: ip rule list -func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) { - req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST) - msg := nl.NewIfInfomsg(family) - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE) - if err != nil { - return nil, err - } - - var res = make([]Rule, 0) - for i := range msgs { - msg := nl.DeserializeRtMsg(msgs[i]) - attrs, err := nl.ParseRouteAttr(msgs[i][msg.Len():]) - if err != nil { - return nil, err - } - - rule := NewRule() - - rule.Invert = msg.Flags&FibRuleInvert > 0 - rule.Tos = uint(msg.Tos) - rule.Type = msg.Type - - for j := range attrs { - switch attrs[j].Attr.Type { - case unix.RTA_TABLE: - rule.Table = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_SRC: - rule.Src = &net.IPNet{ - IP: attrs[j].Value, - Mask: net.CIDRMask(int(msg.Src_len), 8*len(attrs[j].Value)), - } - case nl.FRA_DST: - rule.Dst = &net.IPNet{ - IP: attrs[j].Value, - Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attrs[j].Value)), - } - case nl.FRA_FWMARK: - rule.Mark = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_FWMASK: - rule.Mask = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_TUN_ID: - rule.TunID = uint(native.Uint64(attrs[j].Value[0:8])) - case nl.FRA_IIFNAME: - rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) - case nl.FRA_OIFNAME: - rule.OifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) - case nl.FRA_SUPPRESS_PREFIXLEN: - i := native.Uint32(attrs[j].Value[0:4]) - if i != 0xffffffff { - rule.SuppressPrefixlen = int(i) - } - case nl.FRA_SUPPRESS_IFGROUP: - i := native.Uint32(attrs[j].Value[0:4]) - if i != 0xffffffff { - rule.SuppressIfgroup = int(i) - } - case nl.FRA_FLOW: - rule.Flow = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_GOTO: - rule.Goto = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_PRIORITY: - rule.Priority = int(native.Uint32(attrs[j].Value[0:4])) - case nl.FRA_DPORT_RANGE: - rule.Dport = NewRulePortRange(native.Uint16(attrs[j].Value[0:2]), native.Uint16(attrs[j].Value[2:4])) - case nl.FRA_SPORT_RANGE: - rule.Sport = NewRulePortRange(native.Uint16(attrs[j].Value[0:2]), native.Uint16(attrs[j].Value[2:4])) - } - } - - if filter != nil { - switch { - case filterMask&RT_FILTER_SRC != 0 && - (rule.Src == nil || rule.Src.String() != filter.Src.String()): - continue - case filterMask&RT_FILTER_DST != 0 && - (rule.Dst == nil || rule.Dst.String() != filter.Dst.String()): - continue - case filterMask&RT_FILTER_TABLE != 0 && - filter.Table != unix.RT_TABLE_UNSPEC && rule.Table != filter.Table: - continue - case filterMask&RT_FILTER_TOS != 0 && rule.Tos != filter.Tos: - continue - case filterMask&RT_FILTER_PRIORITY != 0 && rule.Priority != filter.Priority: - continue - case filterMask&RT_FILTER_MARK != 0 && rule.Mark != filter.Mark: - continue - case filterMask&RT_FILTER_MASK != 0 && rule.Mask != filter.Mask: - continue - } - } - - res = append(res, *rule) - } - - return res, nil -} - -func (pr *RulePortRange) toRtAttrData() []byte { - b := [][]byte{make([]byte, 2), make([]byte, 2)} - native.PutUint16(b[0], pr.Start) - native.PutUint16(b[1], pr.End) - return bytes.Join(b, []byte{}) -} diff --git a/vendor/github.com/tailscale/netlink/socket.go b/vendor/github.com/tailscale/netlink/socket.go deleted file mode 100644 index 41aa726..0000000 --- a/vendor/github.com/tailscale/netlink/socket.go +++ /dev/null @@ -1,27 +0,0 @@ -package netlink - -import "net" - -// SocketID identifies a single socket. -type SocketID struct { - SourcePort uint16 - DestinationPort uint16 - Source net.IP - Destination net.IP - Interface uint32 - Cookie [2]uint32 -} - -// Socket represents a netlink socket. -type Socket struct { - Family uint8 - State uint8 - Timer uint8 - Retrans uint8 - ID SocketID - Expires uint32 - RQueue uint32 - WQueue uint32 - UID uint32 - INode uint32 -} diff --git a/vendor/github.com/tailscale/netlink/socket_linux.go b/vendor/github.com/tailscale/netlink/socket_linux.go deleted file mode 100644 index 58cb3aa..0000000 --- a/vendor/github.com/tailscale/netlink/socket_linux.go +++ /dev/null @@ -1,291 +0,0 @@ -package netlink - -import ( - "errors" - "fmt" - "net" - "syscall" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -const ( - sizeofSocketID = 0x30 - sizeofSocketRequest = sizeofSocketID + 0x8 - sizeofSocket = sizeofSocketID + 0x18 -) - -type socketRequest struct { - Family uint8 - Protocol uint8 - Ext uint8 - pad uint8 - States uint32 - ID SocketID -} - -type writeBuffer struct { - Bytes []byte - pos int -} - -func (b *writeBuffer) Write(c byte) { - b.Bytes[b.pos] = c - b.pos++ -} - -func (b *writeBuffer) Next(n int) []byte { - s := b.Bytes[b.pos : b.pos+n] - b.pos += n - return s -} - -func (r *socketRequest) Serialize() []byte { - b := writeBuffer{Bytes: make([]byte, sizeofSocketRequest)} - b.Write(r.Family) - b.Write(r.Protocol) - b.Write(r.Ext) - b.Write(r.pad) - native.PutUint32(b.Next(4), r.States) - networkOrder.PutUint16(b.Next(2), r.ID.SourcePort) - networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort) - if r.Family == unix.AF_INET6 { - copy(b.Next(16), r.ID.Source) - copy(b.Next(16), r.ID.Destination) - } else { - copy(b.Next(4), r.ID.Source.To4()) - b.Next(12) - copy(b.Next(4), r.ID.Destination.To4()) - b.Next(12) - } - native.PutUint32(b.Next(4), r.ID.Interface) - native.PutUint32(b.Next(4), r.ID.Cookie[0]) - native.PutUint32(b.Next(4), r.ID.Cookie[1]) - return b.Bytes -} - -func (r *socketRequest) Len() int { return sizeofSocketRequest } - -type readBuffer struct { - Bytes []byte - pos int -} - -func (b *readBuffer) Read() byte { - c := b.Bytes[b.pos] - b.pos++ - return c -} - -func (b *readBuffer) Next(n int) []byte { - s := b.Bytes[b.pos : b.pos+n] - b.pos += n - return s -} - -func (s *Socket) deserialize(b []byte) error { - if len(b) < sizeofSocket { - return fmt.Errorf("socket data short read (%d); want %d", len(b), sizeofSocket) - } - rb := readBuffer{Bytes: b} - s.Family = rb.Read() - s.State = rb.Read() - s.Timer = rb.Read() - s.Retrans = rb.Read() - s.ID.SourcePort = networkOrder.Uint16(rb.Next(2)) - s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2)) - if s.Family == unix.AF_INET6 { - s.ID.Source = net.IP(rb.Next(16)) - s.ID.Destination = net.IP(rb.Next(16)) - } else { - s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read()) - rb.Next(12) - s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read()) - rb.Next(12) - } - s.ID.Interface = native.Uint32(rb.Next(4)) - s.ID.Cookie[0] = native.Uint32(rb.Next(4)) - s.ID.Cookie[1] = native.Uint32(rb.Next(4)) - s.Expires = native.Uint32(rb.Next(4)) - s.RQueue = native.Uint32(rb.Next(4)) - s.WQueue = native.Uint32(rb.Next(4)) - s.UID = native.Uint32(rb.Next(4)) - s.INode = native.Uint32(rb.Next(4)) - return nil -} - -// SocketGet returns the Socket identified by its local and remote addresses. -func SocketGet(local, remote net.Addr) (*Socket, error) { - localTCP, ok := local.(*net.TCPAddr) - if !ok { - return nil, ErrNotImplemented - } - remoteTCP, ok := remote.(*net.TCPAddr) - if !ok { - return nil, ErrNotImplemented - } - localIP := localTCP.IP.To4() - if localIP == nil { - return nil, ErrNotImplemented - } - remoteIP := remoteTCP.IP.To4() - if remoteIP == nil { - return nil, ErrNotImplemented - } - - s, err := nl.Subscribe(unix.NETLINK_INET_DIAG) - if err != nil { - return nil, err - } - defer s.Close() - req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0) - req.AddData(&socketRequest{ - Family: unix.AF_INET, - Protocol: unix.IPPROTO_TCP, - ID: SocketID{ - SourcePort: uint16(localTCP.Port), - DestinationPort: uint16(remoteTCP.Port), - Source: localIP, - Destination: remoteIP, - Cookie: [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE}, - }, - }) - s.Send(req) - msgs, from, err := s.Receive() - if err != nil { - return nil, err - } - if from.Pid != nl.PidKernel { - return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel) - } - if len(msgs) == 0 { - return nil, errors.New("no message nor error from netlink") - } - if len(msgs) > 2 { - return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs)) - } - sock := &Socket{} - if err := sock.deserialize(msgs[0].Data); err != nil { - return nil, err - } - return sock, nil -} - -// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info. -func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) { - var result []*InetDiagTCPInfoResp - err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error { - sockInfo := &Socket{} - if err := sockInfo.deserialize(m.Data); err != nil { - return err - } - attrs, err := nl.ParseRouteAttr(m.Data[sizeofSocket:]) - if err != nil { - return err - } - - res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo) - if err != nil { - return err - } - - result = append(result, res) - return nil - }) - if err != nil { - return nil, err - } - return result, nil -} - -// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket. -func SocketDiagTCP(family uint8) ([]*Socket, error) { - var result []*Socket - err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error { - sockInfo := &Socket{} - if err := sockInfo.deserialize(m.Data); err != nil { - return err - } - result = append(result, sockInfo) - return nil - }) - if err != nil { - return nil, err - } - return result, nil -} - -// socketDiagTCPExecutor requests INET_DIAG_INFO for TCP protocol for specified family type. -func socketDiagTCPExecutor(family uint8, receiver func(syscall.NetlinkMessage) error) error { - s, err := nl.Subscribe(unix.NETLINK_INET_DIAG) - if err != nil { - return err - } - defer s.Close() - - req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP) - req.AddData(&socketRequest{ - Family: family, - Protocol: unix.IPPROTO_TCP, - Ext: (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)), - States: uint32(0xfff), // All TCP states - }) - s.Send(req) - -loop: - for { - msgs, from, err := s.Receive() - if err != nil { - return err - } - if from.Pid != nl.PidKernel { - return fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel) - } - if len(msgs) == 0 { - return errors.New("no message nor error from netlink") - } - - for _, m := range msgs { - switch m.Header.Type { - case unix.NLMSG_DONE: - break loop - case unix.NLMSG_ERROR: - error := int32(native.Uint32(m.Data[0:4])) - return syscall.Errno(-error) - } - if err := receiver(m); err != nil { - return err - } - } - } - return nil -} - -func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) { - var tcpInfo *TCPInfo - var tcpBBRInfo *TCPBBRInfo - for _, a := range attrs { - if a.Attr.Type == INET_DIAG_INFO { - tcpInfo = &TCPInfo{} - if err := tcpInfo.deserialize(a.Value); err != nil { - return nil, err - } - continue - } - - if a.Attr.Type == INET_DIAG_BBRINFO { - tcpBBRInfo = &TCPBBRInfo{} - if err := tcpBBRInfo.deserialize(a.Value); err != nil { - return nil, err - } - continue - } - } - - return &InetDiagTCPInfoResp{ - InetDiagMsg: sockInfo, - TCPInfo: tcpInfo, - TCPBBRInfo: tcpBBRInfo, - }, nil -} diff --git a/vendor/github.com/tailscale/netlink/tcp.go b/vendor/github.com/tailscale/netlink/tcp.go deleted file mode 100644 index 23ca014..0000000 --- a/vendor/github.com/tailscale/netlink/tcp.go +++ /dev/null @@ -1,84 +0,0 @@ -package netlink - -// TCP States -const ( - TCP_ESTABLISHED = iota + 0x01 - TCP_SYN_SENT - TCP_SYN_RECV - TCP_FIN_WAIT1 - TCP_FIN_WAIT2 - TCP_TIME_WAIT - TCP_CLOSE - TCP_CLOSE_WAIT - TCP_LAST_ACK - TCP_LISTEN - TCP_CLOSING - TCP_NEW_SYN_REC - TCP_MAX_STATES -) - -type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Snd_wscale uint8 // no uint4 - Rcv_wscale uint8 - Delivery_rate_app_limited uint8 - Fastopen_client_fail uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 - Pacing_rate uint64 - Max_pacing_rate uint64 - Bytes_acked uint64 /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ - Bytes_received uint64 /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ - Segs_out uint32 /* RFC4898 tcpEStatsPerfSegsOut */ - Segs_in uint32 /* RFC4898 tcpEStatsPerfSegsIn */ - Notsent_bytes uint32 - Min_rtt uint32 - Data_segs_in uint32 /* RFC4898 tcpEStatsDataSegsIn */ - Data_segs_out uint32 /* RFC4898 tcpEStatsDataSegsOut */ - Delivery_rate uint64 - Busy_time uint64 /* Time (usec) busy sending data */ - Rwnd_limited uint64 /* Time (usec) limited by receive window */ - Sndbuf_limited uint64 /* Time (usec) limited by send buffer */ - Delivered uint32 - Delivered_ce uint32 - Bytes_sent uint64 /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ - Bytes_retrans uint64 /* RFC4898 tcpEStatsPerfOctetsRetrans */ - Dsack_dups uint32 /* RFC4898 tcpEStatsStackDSACKDups */ - Reord_seen uint32 /* reordering events seen */ - Rcv_ooopack uint32 /* Out-of-order packets received */ - Snd_wnd uint32 /* peer's advertised receive window after * scaling (bytes) */ -} - -type TCPBBRInfo struct { - BBRBW uint64 - BBRMinRTT uint32 - BBRPacingGain uint32 - BBRCwndGain uint32 -} diff --git a/vendor/github.com/tailscale/netlink/tcp_linux.go b/vendor/github.com/tailscale/netlink/tcp_linux.go deleted file mode 100644 index 2938587..0000000 --- a/vendor/github.com/tailscale/netlink/tcp_linux.go +++ /dev/null @@ -1,353 +0,0 @@ -package netlink - -import ( - "bytes" - "errors" - "io" -) - -const ( - tcpBBRInfoLen = 20 -) - -func checkDeserErr(err error) error { - if err == io.EOF { - return nil - } - return err -} - -func (t *TCPInfo) deserialize(b []byte) error { - var err error - rb := bytes.NewBuffer(b) - - t.State, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - - t.Ca_state, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - - t.Retransmits, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - - t.Probes, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - - t.Backoff, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - t.Options, err = rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - - scales, err := rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - t.Snd_wscale = scales >> 4 // first 4 bits - t.Rcv_wscale = scales & 0xf // last 4 bits - - rateLimAndFastOpen, err := rb.ReadByte() - if err != nil { - return checkDeserErr(err) - } - t.Delivery_rate_app_limited = rateLimAndFastOpen >> 7 // get first bit - t.Fastopen_client_fail = rateLimAndFastOpen >> 5 & 3 // get next two bits - - next := rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rto = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Ato = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Snd_mss = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rcv_mss = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Unacked = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Sacked = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Lost = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Retrans = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Fackets = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Last_data_sent = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Last_ack_sent = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Last_data_recv = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Last_ack_recv = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Pmtu = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rcv_ssthresh = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rtt = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rttvar = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Snd_ssthresh = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Snd_cwnd = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Advmss = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Reordering = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rcv_rtt = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rcv_space = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Total_retrans = native.Uint32(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Pacing_rate = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Max_pacing_rate = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Bytes_acked = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Bytes_received = native.Uint64(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Segs_out = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Segs_in = native.Uint32(next) - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Notsent_bytes = native.Uint32(next) - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Min_rtt = native.Uint32(next) - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Data_segs_in = native.Uint32(next) - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Data_segs_out = native.Uint32(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Delivery_rate = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Busy_time = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Rwnd_limited = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Sndbuf_limited = native.Uint64(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Delivered = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Delivered_ce = native.Uint32(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Bytes_sent = native.Uint64(next) - - next = rb.Next(8) - if len(next) == 0 { - return nil - } - t.Bytes_retrans = native.Uint64(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Dsack_dups = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Reord_seen = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Rcv_ooopack = native.Uint32(next) - - next = rb.Next(4) - if len(next) == 0 { - return nil - } - t.Snd_wnd = native.Uint32(next) - return nil -} - -func (t *TCPBBRInfo) deserialize(b []byte) error { - if len(b) != tcpBBRInfoLen { - return errors.New("Invalid length") - } - - rb := bytes.NewBuffer(b) - t.BBRBW = native.Uint64(rb.Next(8)) - t.BBRMinRTT = native.Uint32(rb.Next(4)) - t.BBRPacingGain = native.Uint32(rb.Next(4)) - t.BBRCwndGain = native.Uint32(rb.Next(4)) - - return nil -} diff --git a/vendor/github.com/tailscale/netlink/xfrm.go b/vendor/github.com/tailscale/netlink/xfrm.go deleted file mode 100644 index 02b4184..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm.go +++ /dev/null @@ -1,75 +0,0 @@ -package netlink - -import ( - "fmt" - - "golang.org/x/sys/unix" -) - -// Proto is an enum representing an ipsec protocol. -type Proto uint8 - -const ( - XFRM_PROTO_ROUTE2 Proto = unix.IPPROTO_ROUTING - XFRM_PROTO_ESP Proto = unix.IPPROTO_ESP - XFRM_PROTO_AH Proto = unix.IPPROTO_AH - XFRM_PROTO_HAO Proto = unix.IPPROTO_DSTOPTS - XFRM_PROTO_COMP Proto = 0x6c // NOTE not defined on darwin - XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW -) - -func (p Proto) String() string { - switch p { - case XFRM_PROTO_ROUTE2: - return "route2" - case XFRM_PROTO_ESP: - return "esp" - case XFRM_PROTO_AH: - return "ah" - case XFRM_PROTO_HAO: - return "hao" - case XFRM_PROTO_COMP: - return "comp" - case XFRM_PROTO_IPSEC_ANY: - return "ipsec-any" - } - return fmt.Sprintf("%d", p) -} - -// Mode is an enum representing an ipsec transport. -type Mode uint8 - -const ( - XFRM_MODE_TRANSPORT Mode = iota - XFRM_MODE_TUNNEL - XFRM_MODE_ROUTEOPTIMIZATION - XFRM_MODE_IN_TRIGGER - XFRM_MODE_BEET - XFRM_MODE_MAX -) - -func (m Mode) String() string { - switch m { - case XFRM_MODE_TRANSPORT: - return "transport" - case XFRM_MODE_TUNNEL: - return "tunnel" - case XFRM_MODE_ROUTEOPTIMIZATION: - return "ro" - case XFRM_MODE_IN_TRIGGER: - return "in_trigger" - case XFRM_MODE_BEET: - return "beet" - } - return fmt.Sprintf("%d", m) -} - -// XfrmMark represents the mark associated to the state or policy -type XfrmMark struct { - Value uint32 - Mask uint32 -} - -func (m *XfrmMark) String() string { - return fmt.Sprintf("(0x%x,0x%x)", m.Value, m.Mask) -} diff --git a/vendor/github.com/tailscale/netlink/xfrm_monitor_linux.go b/vendor/github.com/tailscale/netlink/xfrm_monitor_linux.go deleted file mode 100644 index 8fa5dc8..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm_monitor_linux.go +++ /dev/null @@ -1,101 +0,0 @@ -package netlink - -import ( - "fmt" - - "github.com/tailscale/netlink/nl" - "github.com/vishvananda/netns" - "golang.org/x/sys/unix" -) - -type XfrmMsg interface { - Type() nl.XfrmMsgType -} - -type XfrmMsgExpire struct { - XfrmState *XfrmState - Hard bool -} - -func (ue *XfrmMsgExpire) Type() nl.XfrmMsgType { - return nl.XFRM_MSG_EXPIRE -} - -func parseXfrmMsgExpire(b []byte) *XfrmMsgExpire { - var e XfrmMsgExpire - - msg := nl.DeserializeXfrmUserExpire(b) - e.XfrmState = xfrmStateFromXfrmUsersaInfo(&msg.XfrmUsersaInfo) - e.Hard = msg.Hard == 1 - - return &e -} - -func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error, - types ...nl.XfrmMsgType) error { - - groups, err := xfrmMcastGroups(types) - if err != nil { - return nil - } - s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_XFRM, groups...) - if err != nil { - return err - } - - if done != nil { - go func() { - <-done - s.Close() - }() - - } - - go func() { - defer close(ch) - for { - msgs, from, err := s.Receive() - if err != nil { - errorChan <- err - return - } - if from.Pid != nl.PidKernel { - errorChan <- fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel) - return - } - for _, m := range msgs { - switch m.Header.Type { - case nl.XFRM_MSG_EXPIRE: - ch <- parseXfrmMsgExpire(m.Data) - default: - errorChan <- fmt.Errorf("unsupported msg type: %x", m.Header.Type) - } - } - } - }() - - return nil -} - -func xfrmMcastGroups(types []nl.XfrmMsgType) ([]uint, error) { - groups := make([]uint, 0) - - if len(types) == 0 { - return nil, fmt.Errorf("no xfrm msg type specified") - } - - for _, t := range types { - var group uint - - switch t { - case nl.XFRM_MSG_EXPIRE: - group = nl.XFRMNLGRP_EXPIRE - default: - return nil, fmt.Errorf("unsupported group: %x", t) - } - - groups = append(groups, group) - } - - return groups, nil -} diff --git a/vendor/github.com/tailscale/netlink/xfrm_policy.go b/vendor/github.com/tailscale/netlink/xfrm_policy.go deleted file mode 100644 index b7532b0..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm_policy.go +++ /dev/null @@ -1,97 +0,0 @@ -package netlink - -import ( - "fmt" - "net" -) - -// Dir is an enum representing an ipsec template direction. -type Dir uint8 - -const ( - XFRM_DIR_IN Dir = iota - XFRM_DIR_OUT - XFRM_DIR_FWD - XFRM_SOCKET_IN - XFRM_SOCKET_OUT - XFRM_SOCKET_FWD -) - -func (d Dir) String() string { - switch d { - case XFRM_DIR_IN: - return "dir in" - case XFRM_DIR_OUT: - return "dir out" - case XFRM_DIR_FWD: - return "dir fwd" - case XFRM_SOCKET_IN: - return "socket in" - case XFRM_SOCKET_OUT: - return "socket out" - case XFRM_SOCKET_FWD: - return "socket fwd" - } - return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN) -} - -// PolicyAction is an enum representing an ipsec policy action. -type PolicyAction uint8 - -const ( - XFRM_POLICY_ALLOW PolicyAction = 0 - XFRM_POLICY_BLOCK PolicyAction = 1 -) - -func (a PolicyAction) String() string { - switch a { - case XFRM_POLICY_ALLOW: - return "allow" - case XFRM_POLICY_BLOCK: - return "block" - default: - return fmt.Sprintf("action %d", a) - } -} - -// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec -// policy. These rules are matched with XfrmState to determine encryption -// and authentication algorithms. -type XfrmPolicyTmpl struct { - Dst net.IP - Src net.IP - Proto Proto - Mode Mode - Spi int - Reqid int - Optional int -} - -func (t XfrmPolicyTmpl) String() string { - return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Spi: 0x%x, Reqid: 0x%x}", - t.Dst, t.Src, t.Proto, t.Mode, t.Spi, t.Reqid) -} - -// XfrmPolicy represents an ipsec policy. It represents the overlay network -// and has a list of XfrmPolicyTmpls representing the base addresses of -// the policy. -type XfrmPolicy struct { - Dst *net.IPNet - Src *net.IPNet - Proto Proto - DstPort int - SrcPort int - Dir Dir - Priority int - Index int - Action PolicyAction - Ifindex int - Ifid int - Mark *XfrmMark - Tmpls []XfrmPolicyTmpl -} - -func (p XfrmPolicy) String() string { - return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Action: %s, Ifindex: %d, Ifid: %d, Mark: %s, Tmpls: %s}", - p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Action, p.Ifindex, p.Ifid, p.Mark, p.Tmpls) -} diff --git a/vendor/github.com/tailscale/netlink/xfrm_policy_linux.go b/vendor/github.com/tailscale/netlink/xfrm_policy_linux.go deleted file mode 100644 index 48fc1b9..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm_policy_linux.go +++ /dev/null @@ -1,265 +0,0 @@ -package netlink - -import ( - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) { - sel.Family = uint16(nl.FAMILY_V4) - if policy.Dst != nil { - sel.Family = uint16(nl.GetIPFamily(policy.Dst.IP)) - sel.Daddr.FromIP(policy.Dst.IP) - prefixlenD, _ := policy.Dst.Mask.Size() - sel.PrefixlenD = uint8(prefixlenD) - } - if policy.Src != nil { - sel.Saddr.FromIP(policy.Src.IP) - prefixlenS, _ := policy.Src.Mask.Size() - sel.PrefixlenS = uint8(prefixlenS) - } - sel.Proto = uint8(policy.Proto) - sel.Dport = nl.Swap16(uint16(policy.DstPort)) - sel.Sport = nl.Swap16(uint16(policy.SrcPort)) - if sel.Dport != 0 { - sel.DportMask = ^uint16(0) - } - if sel.Sport != 0 { - sel.SportMask = ^uint16(0) - } - sel.Ifindex = int32(policy.Ifindex) -} - -// XfrmPolicyAdd will add an xfrm policy to the system. -// Equivalent to: `ip xfrm policy add $policy` -func XfrmPolicyAdd(policy *XfrmPolicy) error { - return pkgHandle.XfrmPolicyAdd(policy) -} - -// XfrmPolicyAdd will add an xfrm policy to the system. -// Equivalent to: `ip xfrm policy add $policy` -func (h *Handle) XfrmPolicyAdd(policy *XfrmPolicy) error { - return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_NEWPOLICY) -} - -// XfrmPolicyUpdate will update an xfrm policy to the system. -// Equivalent to: `ip xfrm policy update $policy` -func XfrmPolicyUpdate(policy *XfrmPolicy) error { - return pkgHandle.XfrmPolicyUpdate(policy) -} - -// XfrmPolicyUpdate will update an xfrm policy to the system. -// Equivalent to: `ip xfrm policy update $policy` -func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error { - return h.xfrmPolicyAddOrUpdate(policy, nl.XFRM_MSG_UPDPOLICY) -} - -func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error { - req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) - - msg := &nl.XfrmUserpolicyInfo{} - selFromPolicy(&msg.Sel, policy) - msg.Priority = uint32(policy.Priority) - msg.Index = uint32(policy.Index) - msg.Dir = uint8(policy.Dir) - msg.Action = uint8(policy.Action) - msg.Lft.SoftByteLimit = nl.XFRM_INF - msg.Lft.HardByteLimit = nl.XFRM_INF - msg.Lft.SoftPacketLimit = nl.XFRM_INF - msg.Lft.HardPacketLimit = nl.XFRM_INF - req.AddData(msg) - - tmplData := make([]byte, nl.SizeofXfrmUserTmpl*len(policy.Tmpls)) - for i, tmpl := range policy.Tmpls { - start := i * nl.SizeofXfrmUserTmpl - userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl]) - userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst) - userTmpl.Saddr.FromIP(tmpl.Src) - userTmpl.XfrmId.Proto = uint8(tmpl.Proto) - userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi)) - userTmpl.Mode = uint8(tmpl.Mode) - userTmpl.Reqid = uint32(tmpl.Reqid) - userTmpl.Optional = uint8(tmpl.Optional) - userTmpl.Aalgos = ^uint32(0) - userTmpl.Ealgos = ^uint32(0) - userTmpl.Calgos = ^uint32(0) - } - if len(tmplData) > 0 { - tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData) - req.AddData(tmpls) - } - if policy.Mark != nil { - out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark)) - req.AddData(out) - } - - ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid))) - req.AddData(ifId) - - _, err := req.Execute(unix.NETLINK_XFRM, 0) - return err -} - -// XfrmPolicyDel will delete an xfrm policy from the system. Note that -// the Tmpls are ignored when matching the policy to delete. -// Equivalent to: `ip xfrm policy del $policy` -func XfrmPolicyDel(policy *XfrmPolicy) error { - return pkgHandle.XfrmPolicyDel(policy) -} - -// XfrmPolicyDel will delete an xfrm policy from the system. Note that -// the Tmpls are ignored when matching the policy to delete. -// Equivalent to: `ip xfrm policy del $policy` -func (h *Handle) XfrmPolicyDel(policy *XfrmPolicy) error { - _, err := h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_DELPOLICY) - return err -} - -// XfrmPolicyList gets a list of xfrm policies in the system. -// Equivalent to: `ip xfrm policy show`. -// The list can be filtered by ip family. -func XfrmPolicyList(family int) ([]XfrmPolicy, error) { - return pkgHandle.XfrmPolicyList(family) -} - -// XfrmPolicyList gets a list of xfrm policies in the system. -// Equivalent to: `ip xfrm policy show`. -// The list can be filtered by ip family. -func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) { - req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP) - - msg := nl.NewIfInfomsg(family) - req.AddData(msg) - - msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY) - if err != nil { - return nil, err - } - - var res []XfrmPolicy - for _, m := range msgs { - if policy, err := parseXfrmPolicy(m, family); err == nil { - res = append(res, *policy) - } else if err == familyError { - continue - } else { - return nil, err - } - } - return res, nil -} - -// XfrmPolicyGet gets a the policy described by the index or selector, if found. -// Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`. -func XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) { - return pkgHandle.XfrmPolicyGet(policy) -} - -// XfrmPolicyGet gets a the policy described by the index or selector, if found. -// Equivalent to: `ip xfrm policy get { SELECTOR | index INDEX } dir DIR [ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]`. -func (h *Handle) XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) { - return h.xfrmPolicyGetOrDelete(policy, nl.XFRM_MSG_GETPOLICY) -} - -// XfrmPolicyFlush will flush the policies on the system. -// Equivalent to: `ip xfrm policy flush` -func XfrmPolicyFlush() error { - return pkgHandle.XfrmPolicyFlush() -} - -// XfrmPolicyFlush will flush the policies on the system. -// Equivalent to: `ip xfrm policy flush` -func (h *Handle) XfrmPolicyFlush() error { - req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK) - _, err := req.Execute(unix.NETLINK_XFRM, 0) - return err -} - -func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) { - req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) - - msg := &nl.XfrmUserpolicyId{} - selFromPolicy(&msg.Sel, policy) - msg.Index = uint32(policy.Index) - msg.Dir = uint8(policy.Dir) - req.AddData(msg) - - if policy.Mark != nil { - out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(policy.Mark)) - req.AddData(out) - } - - ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid))) - req.AddData(ifId) - - resType := nl.XFRM_MSG_NEWPOLICY - if nlProto == nl.XFRM_MSG_DELPOLICY { - resType = 0 - } - - msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) - if err != nil { - return nil, err - } - - if nlProto == nl.XFRM_MSG_DELPOLICY { - return nil, err - } - - return parseXfrmPolicy(msgs[0], FAMILY_ALL) -} - -func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) { - msg := nl.DeserializeXfrmUserpolicyInfo(m) - - // This is mainly for the policy dump - if family != FAMILY_ALL && family != int(msg.Sel.Family) { - return nil, familyError - } - - var policy XfrmPolicy - - policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD) - policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS) - policy.Proto = Proto(msg.Sel.Proto) - policy.DstPort = int(nl.Swap16(msg.Sel.Dport)) - policy.SrcPort = int(nl.Swap16(msg.Sel.Sport)) - policy.Ifindex = int(msg.Sel.Ifindex) - policy.Priority = int(msg.Priority) - policy.Index = int(msg.Index) - policy.Dir = Dir(msg.Dir) - policy.Action = PolicyAction(msg.Action) - - attrs, err := nl.ParseRouteAttr(m[msg.Len():]) - if err != nil { - return nil, err - } - - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.XFRMA_TMPL: - max := len(attr.Value) - for i := 0; i < max; i += nl.SizeofXfrmUserTmpl { - var resTmpl XfrmPolicyTmpl - tmpl := nl.DeserializeXfrmUserTmpl(attr.Value[i : i+nl.SizeofXfrmUserTmpl]) - resTmpl.Dst = tmpl.XfrmId.Daddr.ToIP() - resTmpl.Src = tmpl.Saddr.ToIP() - resTmpl.Proto = Proto(tmpl.XfrmId.Proto) - resTmpl.Mode = Mode(tmpl.Mode) - resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi)) - resTmpl.Reqid = int(tmpl.Reqid) - resTmpl.Optional = int(tmpl.Optional) - policy.Tmpls = append(policy.Tmpls, resTmpl) - } - case nl.XFRMA_MARK: - mark := nl.DeserializeXfrmMark(attr.Value[:]) - policy.Mark = new(XfrmMark) - policy.Mark.Value = mark.Value - policy.Mark.Mask = mark.Mask - case nl.XFRMA_IF_ID: - policy.Ifid = int(native.Uint32(attr.Value)) - } - } - - return &policy, nil -} diff --git a/vendor/github.com/tailscale/netlink/xfrm_state.go b/vendor/github.com/tailscale/netlink/xfrm_state.go deleted file mode 100644 index 19df82c..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm_state.go +++ /dev/null @@ -1,131 +0,0 @@ -package netlink - -import ( - "fmt" - "net" - "time" -) - -// XfrmStateAlgo represents the algorithm to use for the ipsec encryption. -type XfrmStateAlgo struct { - Name string - Key []byte - TruncateLen int // Auth only - ICVLen int // AEAD only -} - -func (a XfrmStateAlgo) String() string { - base := fmt.Sprintf("{Name: %s, Key: 0x%x", a.Name, a.Key) - if a.TruncateLen != 0 { - base = fmt.Sprintf("%s, Truncate length: %d", base, a.TruncateLen) - } - if a.ICVLen != 0 { - base = fmt.Sprintf("%s, ICV length: %d", base, a.ICVLen) - } - return fmt.Sprintf("%s}", base) -} - -// EncapType is an enum representing the optional packet encapsulation. -type EncapType uint8 - -const ( - XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1 - XFRM_ENCAP_ESPINUDP -) - -func (e EncapType) String() string { - switch e { - case XFRM_ENCAP_ESPINUDP_NONIKE: - return "espinudp-non-ike" - case XFRM_ENCAP_ESPINUDP: - return "espinudp" - } - return "unknown" -} - -// XfrmStateEncap represents the encapsulation to use for the ipsec encryption. -type XfrmStateEncap struct { - Type EncapType - SrcPort int - DstPort int - OriginalAddress net.IP -} - -func (e XfrmStateEncap) String() string { - return fmt.Sprintf("{Type: %s, Srcport: %d, DstPort: %d, OriginalAddress: %v}", - e.Type, e.SrcPort, e.DstPort, e.OriginalAddress) -} - -// XfrmStateLimits represents the configured limits for the state. -type XfrmStateLimits struct { - ByteSoft uint64 - ByteHard uint64 - PacketSoft uint64 - PacketHard uint64 - TimeSoft uint64 - TimeHard uint64 - TimeUseSoft uint64 - TimeUseHard uint64 -} - -// XfrmStateStats represents the current number of bytes/packets -// processed by this State, the State's installation and first use -// time and the replay window counters. -type XfrmStateStats struct { - ReplayWindow uint32 - Replay uint32 - Failed uint32 - Bytes uint64 - Packets uint64 - AddTime uint64 - UseTime uint64 -} - -// XfrmState represents the state of an ipsec policy. It optionally -// contains an XfrmStateAlgo for encryption and one for authentication. -type XfrmState struct { - Dst net.IP - Src net.IP - Proto Proto - Mode Mode - Spi int - Reqid int - ReplayWindow int - Limits XfrmStateLimits - Statistics XfrmStateStats - Mark *XfrmMark - OutputMark *XfrmMark - Ifid int - Auth *XfrmStateAlgo - Crypt *XfrmStateAlgo - Aead *XfrmStateAlgo - Encap *XfrmStateEncap - ESN bool -} - -func (sa XfrmState) String() string { - return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %v, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t", - sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.OutputMark, sa.Ifid, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN) -} -func (sa XfrmState) Print(stats bool) string { - if !stats { - return sa.String() - } - at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate) - ut := "-" - if sa.Statistics.UseTime > 0 { - ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate) - } - return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+ - "AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d", - sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard), - sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut, - sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed) -} - -func printLimit(lmt uint64) string { - if lmt == ^uint64(0) { - return "(INF)" - } - return fmt.Sprintf("%d", lmt) -} diff --git a/vendor/github.com/tailscale/netlink/xfrm_state_linux.go b/vendor/github.com/tailscale/netlink/xfrm_state_linux.go deleted file mode 100644 index f82e090..0000000 --- a/vendor/github.com/tailscale/netlink/xfrm_state_linux.go +++ /dev/null @@ -1,477 +0,0 @@ -package netlink - -import ( - "fmt" - "unsafe" - - "github.com/tailscale/netlink/nl" - "golang.org/x/sys/unix" -) - -func writeStateAlgo(a *XfrmStateAlgo) []byte { - algo := nl.XfrmAlgo{ - AlgKeyLen: uint32(len(a.Key) * 8), - AlgKey: a.Key, - } - end := len(a.Name) - if end > 64 { - end = 64 - } - copy(algo.AlgName[:end], a.Name) - return algo.Serialize() -} - -func writeStateAlgoAuth(a *XfrmStateAlgo) []byte { - algo := nl.XfrmAlgoAuth{ - AlgKeyLen: uint32(len(a.Key) * 8), - AlgTruncLen: uint32(a.TruncateLen), - AlgKey: a.Key, - } - end := len(a.Name) - if end > 64 { - end = 64 - } - copy(algo.AlgName[:end], a.Name) - return algo.Serialize() -} - -func writeStateAlgoAead(a *XfrmStateAlgo) []byte { - algo := nl.XfrmAlgoAEAD{ - AlgKeyLen: uint32(len(a.Key) * 8), - AlgICVLen: uint32(a.ICVLen), - AlgKey: a.Key, - } - end := len(a.Name) - if end > 64 { - end = 64 - } - copy(algo.AlgName[:end], a.Name) - return algo.Serialize() -} - -func writeMark(m *XfrmMark) []byte { - mark := &nl.XfrmMark{ - Value: m.Value, - Mask: m.Mask, - } - if mark.Mask == 0 { - mark.Mask = ^uint32(0) - } - return mark.Serialize() -} - -func writeReplayEsn(replayWindow int) []byte { - replayEsn := &nl.XfrmReplayStateEsn{ - OSeq: 0, - Seq: 0, - OSeqHi: 0, - SeqHi: 0, - ReplayWindow: uint32(replayWindow), - } - - // Linux stores the bitmap to identify the already received sequence packets in blocks of uint32 elements. - // Therefore bitmap length is the minimum number of uint32 elements needed. The following is a ceiling operation. - bytesPerElem := int(unsafe.Sizeof(replayEsn.BmpLen)) // Any uint32 variable is good for this - replayEsn.BmpLen = uint32((replayWindow + (bytesPerElem * 8) - 1) / (bytesPerElem * 8)) - - return replayEsn.Serialize() -} - -// XfrmStateAdd will add an xfrm state to the system. -// Equivalent to: `ip xfrm state add $state` -func XfrmStateAdd(state *XfrmState) error { - return pkgHandle.XfrmStateAdd(state) -} - -// XfrmStateAdd will add an xfrm state to the system. -// Equivalent to: `ip xfrm state add $state` -func (h *Handle) XfrmStateAdd(state *XfrmState) error { - return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA) -} - -// XfrmStateAllocSpi will allocate an xfrm state in the system. -// Equivalent to: `ip xfrm state allocspi` -func XfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) { - return pkgHandle.xfrmStateAllocSpi(state) -} - -// XfrmStateUpdate will update an xfrm state to the system. -// Equivalent to: `ip xfrm state update $state` -func XfrmStateUpdate(state *XfrmState) error { - return pkgHandle.XfrmStateUpdate(state) -} - -// XfrmStateUpdate will update an xfrm state to the system. -// Equivalent to: `ip xfrm state update $state` -func (h *Handle) XfrmStateUpdate(state *XfrmState) error { - return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_UPDSA) -} - -func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error { - - // A state with spi 0 can't be deleted so don't allow it to be set - if state.Spi == 0 { - return fmt.Errorf("Spi must be set when adding xfrm state") - } - req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) - - msg := xfrmUsersaInfoFromXfrmState(state) - - if state.ESN { - if state.ReplayWindow == 0 { - return fmt.Errorf("ESN flag set without ReplayWindow") - } - msg.Flags |= nl.XFRM_STATE_ESN - msg.ReplayWindow = 0 - } - - limitsToLft(state.Limits, &msg.Lft) - req.AddData(msg) - - if state.Auth != nil { - out := nl.NewRtAttr(nl.XFRMA_ALG_AUTH_TRUNC, writeStateAlgoAuth(state.Auth)) - req.AddData(out) - } - if state.Crypt != nil { - out := nl.NewRtAttr(nl.XFRMA_ALG_CRYPT, writeStateAlgo(state.Crypt)) - req.AddData(out) - } - if state.Aead != nil { - out := nl.NewRtAttr(nl.XFRMA_ALG_AEAD, writeStateAlgoAead(state.Aead)) - req.AddData(out) - } - if state.Encap != nil { - encapData := make([]byte, nl.SizeofXfrmEncapTmpl) - encap := nl.DeserializeXfrmEncapTmpl(encapData) - encap.EncapType = uint16(state.Encap.Type) - encap.EncapSport = nl.Swap16(uint16(state.Encap.SrcPort)) - encap.EncapDport = nl.Swap16(uint16(state.Encap.DstPort)) - encap.EncapOa.FromIP(state.Encap.OriginalAddress) - out := nl.NewRtAttr(nl.XFRMA_ENCAP, encapData) - req.AddData(out) - } - if state.Mark != nil { - out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) - req.AddData(out) - } - if state.ESN { - out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow)) - req.AddData(out) - } - if state.OutputMark != nil { - out := nl.NewRtAttr(nl.XFRMA_SET_MARK, nl.Uint32Attr(state.OutputMark.Value)) - req.AddData(out) - if state.OutputMark.Mask != 0 { - out = nl.NewRtAttr(nl.XFRMA_SET_MARK_MASK, nl.Uint32Attr(state.OutputMark.Mask)) - req.AddData(out) - } - } - - ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid))) - req.AddData(ifId) - - _, err := req.Execute(unix.NETLINK_XFRM, 0) - return err -} - -func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) { - req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI, - unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) - - msg := &nl.XfrmUserSpiInfo{} - msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state)) - // 1-255 is reserved by IANA for future use - msg.Min = 0x100 - msg.Max = 0xffffffff - req.AddData(msg) - - if state.Mark != nil { - out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) - req.AddData(out) - } - - msgs, err := req.Execute(unix.NETLINK_XFRM, 0) - if err != nil { - return nil, err - } - - return parseXfrmState(msgs[0], FAMILY_ALL) -} - -// XfrmStateDel will delete an xfrm state from the system. Note that -// the Algos are ignored when matching the state to delete. -// Equivalent to: `ip xfrm state del $state` -func XfrmStateDel(state *XfrmState) error { - return pkgHandle.XfrmStateDel(state) -} - -// XfrmStateDel will delete an xfrm state from the system. Note that -// the Algos are ignored when matching the state to delete. -// Equivalent to: `ip xfrm state del $state` -func (h *Handle) XfrmStateDel(state *XfrmState) error { - _, err := h.xfrmStateGetOrDelete(state, nl.XFRM_MSG_DELSA) - return err -} - -// XfrmStateList gets a list of xfrm states in the system. -// Equivalent to: `ip [-4|-6] xfrm state show`. -// The list can be filtered by ip family. -func XfrmStateList(family int) ([]XfrmState, error) { - return pkgHandle.XfrmStateList(family) -} - -// XfrmStateList gets a list of xfrm states in the system. -// Equivalent to: `ip xfrm state show`. -// The list can be filtered by ip family. -func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) { - req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP) - - msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA) - if err != nil { - return nil, err - } - - var res []XfrmState - for _, m := range msgs { - if state, err := parseXfrmState(m, family); err == nil { - res = append(res, *state) - } else if err == familyError { - continue - } else { - return nil, err - } - } - return res, nil -} - -// XfrmStateGet gets the xfrm state described by the ID, if found. -// Equivalent to: `ip xfrm state get ID [ mark MARK [ mask MASK ] ]`. -// Only the fields which constitue the SA ID must be filled in: -// ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ] -// mark is optional -func XfrmStateGet(state *XfrmState) (*XfrmState, error) { - return pkgHandle.XfrmStateGet(state) -} - -// XfrmStateGet gets the xfrm state described by the ID, if found. -// Equivalent to: `ip xfrm state get ID [ mark MARK [ mask MASK ] ]`. -// Only the fields which constitue the SA ID must be filled in: -// ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM-PROTO ] [ spi SPI ] -// mark is optional -func (h *Handle) XfrmStateGet(state *XfrmState) (*XfrmState, error) { - return h.xfrmStateGetOrDelete(state, nl.XFRM_MSG_GETSA) -} - -func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) { - req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) - - msg := &nl.XfrmUsersaId{} - msg.Family = uint16(nl.GetIPFamily(state.Dst)) - msg.Daddr.FromIP(state.Dst) - msg.Proto = uint8(state.Proto) - msg.Spi = nl.Swap32(uint32(state.Spi)) - req.AddData(msg) - - if state.Mark != nil { - out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark)) - req.AddData(out) - } - if state.Src != nil { - out := nl.NewRtAttr(nl.XFRMA_SRCADDR, state.Src.To16()) - req.AddData(out) - } - - ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid))) - req.AddData(ifId) - - resType := nl.XFRM_MSG_NEWSA - if nlProto == nl.XFRM_MSG_DELSA { - resType = 0 - } - - msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) - if err != nil { - return nil, err - } - - if nlProto == nl.XFRM_MSG_DELSA { - return nil, nil - } - - s, err := parseXfrmState(msgs[0], FAMILY_ALL) - if err != nil { - return nil, err - } - - return s, nil -} - -var familyError = fmt.Errorf("family error") - -func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState { - var state XfrmState - - state.Dst = msg.Id.Daddr.ToIP() - state.Src = msg.Saddr.ToIP() - state.Proto = Proto(msg.Id.Proto) - state.Mode = Mode(msg.Mode) - state.Spi = int(nl.Swap32(msg.Id.Spi)) - state.Reqid = int(msg.Reqid) - state.ReplayWindow = int(msg.ReplayWindow) - lftToLimits(&msg.Lft, &state.Limits) - curToStats(&msg.Curlft, &msg.Stats, &state.Statistics) - - return &state -} - -func parseXfrmState(m []byte, family int) (*XfrmState, error) { - msg := nl.DeserializeXfrmUsersaInfo(m) - - // This is mainly for the state dump - if family != FAMILY_ALL && family != int(msg.Family) { - return nil, familyError - } - - state := xfrmStateFromXfrmUsersaInfo(msg) - - attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:]) - if err != nil { - return nil, err - } - - for _, attr := range attrs { - switch attr.Attr.Type { - case nl.XFRMA_ALG_AUTH, nl.XFRMA_ALG_CRYPT: - var resAlgo *XfrmStateAlgo - if attr.Attr.Type == nl.XFRMA_ALG_AUTH { - if state.Auth == nil { - state.Auth = new(XfrmStateAlgo) - } - resAlgo = state.Auth - } else { - state.Crypt = new(XfrmStateAlgo) - resAlgo = state.Crypt - } - algo := nl.DeserializeXfrmAlgo(attr.Value[:]) - (*resAlgo).Name = nl.BytesToString(algo.AlgName[:]) - (*resAlgo).Key = algo.AlgKey - case nl.XFRMA_ALG_AUTH_TRUNC: - if state.Auth == nil { - state.Auth = new(XfrmStateAlgo) - } - algo := nl.DeserializeXfrmAlgoAuth(attr.Value[:]) - state.Auth.Name = nl.BytesToString(algo.AlgName[:]) - state.Auth.Key = algo.AlgKey - state.Auth.TruncateLen = int(algo.AlgTruncLen) - case nl.XFRMA_ALG_AEAD: - state.Aead = new(XfrmStateAlgo) - algo := nl.DeserializeXfrmAlgoAEAD(attr.Value[:]) - state.Aead.Name = nl.BytesToString(algo.AlgName[:]) - state.Aead.Key = algo.AlgKey - state.Aead.ICVLen = int(algo.AlgICVLen) - case nl.XFRMA_ENCAP: - encap := nl.DeserializeXfrmEncapTmpl(attr.Value[:]) - state.Encap = new(XfrmStateEncap) - state.Encap.Type = EncapType(encap.EncapType) - state.Encap.SrcPort = int(nl.Swap16(encap.EncapSport)) - state.Encap.DstPort = int(nl.Swap16(encap.EncapDport)) - state.Encap.OriginalAddress = encap.EncapOa.ToIP() - case nl.XFRMA_MARK: - mark := nl.DeserializeXfrmMark(attr.Value[:]) - state.Mark = new(XfrmMark) - state.Mark.Value = mark.Value - state.Mark.Mask = mark.Mask - case nl.XFRMA_SET_MARK: - if state.OutputMark == nil { - state.OutputMark = new(XfrmMark) - } - state.OutputMark.Value = native.Uint32(attr.Value) - case nl.XFRMA_SET_MARK_MASK: - if state.OutputMark == nil { - state.OutputMark = new(XfrmMark) - } - state.OutputMark.Mask = native.Uint32(attr.Value) - if state.OutputMark.Mask == 0xffffffff { - state.OutputMark.Mask = 0 - } - case nl.XFRMA_IF_ID: - state.Ifid = int(native.Uint32(attr.Value)) - } - } - - return state, nil -} - -// XfrmStateFlush will flush the xfrm state on the system. -// proto = 0 means any transformation protocols -// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]` -func XfrmStateFlush(proto Proto) error { - return pkgHandle.XfrmStateFlush(proto) -} - -// XfrmStateFlush will flush the xfrm state on the system. -// proto = 0 means any transformation protocols -// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]` -func (h *Handle) XfrmStateFlush(proto Proto) error { - req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, unix.NLM_F_ACK) - - req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)}) - - _, err := req.Execute(unix.NETLINK_XFRM, 0) - return err -} - -func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) { - if lmts.ByteSoft != 0 { - lft.SoftByteLimit = lmts.ByteSoft - } else { - lft.SoftByteLimit = nl.XFRM_INF - } - if lmts.ByteHard != 0 { - lft.HardByteLimit = lmts.ByteHard - } else { - lft.HardByteLimit = nl.XFRM_INF - } - if lmts.PacketSoft != 0 { - lft.SoftPacketLimit = lmts.PacketSoft - } else { - lft.SoftPacketLimit = nl.XFRM_INF - } - if lmts.PacketHard != 0 { - lft.HardPacketLimit = lmts.PacketHard - } else { - lft.HardPacketLimit = nl.XFRM_INF - } - lft.SoftAddExpiresSeconds = lmts.TimeSoft - lft.HardAddExpiresSeconds = lmts.TimeHard - lft.SoftUseExpiresSeconds = lmts.TimeUseSoft - lft.HardUseExpiresSeconds = lmts.TimeUseHard -} - -func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) { - *lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft)) -} - -func curToStats(cur *nl.XfrmLifetimeCur, wstats *nl.XfrmStats, stats *XfrmStateStats) { - stats.Bytes = cur.Bytes - stats.Packets = cur.Packets - stats.AddTime = cur.AddTime - stats.UseTime = cur.UseTime - stats.ReplayWindow = wstats.ReplayWindow - stats.Replay = wstats.Replay - stats.Failed = wstats.IntegrityFailed -} - -func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo { - msg := &nl.XfrmUsersaInfo{} - msg.Family = uint16(nl.GetIPFamily(state.Dst)) - msg.Id.Daddr.FromIP(state.Dst) - msg.Saddr.FromIP(state.Src) - msg.Id.Proto = uint8(state.Proto) - msg.Mode = uint8(state.Mode) - msg.Id.Spi = nl.Swap32(uint32(state.Spi)) - msg.Reqid = uint32(state.Reqid) - msg.ReplayWindow = uint8(state.ReplayWindow) - - return msg -} diff --git a/vendor/github.com/tailscale/wireguard-go/conn/bind_std.go b/vendor/github.com/tailscale/wireguard-go/conn/bind_std.go index 428e528..fc05634 100644 --- a/vendor/github.com/tailscale/wireguard-go/conn/bind_std.go +++ b/vendor/github.com/tailscale/wireguard-go/conn/bind_std.go @@ -341,7 +341,7 @@ func (e ErrUDPGSODisabled) Unwrap() error { return e.RetryErr } -func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint) error { +func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint, offset int) error { s.mu.Lock() blackhole := s.blackhole4 conn := s.ipv4 @@ -384,7 +384,7 @@ func (s *StdNetBind) Send(bufs [][]byte, endpoint Endpoint) error { ) retry: if offload { - n := coalesceMessages(ua, endpoint.(*StdNetEndpoint), bufs, *msgs, setGSOSize) + n := coalesceMessages(ua, endpoint.(*StdNetEndpoint), bufs, offset, *msgs, setGSOSize) err = s.send(conn, br, (*msgs)[:n]) if err != nil && offload && errShouldDisableUDPGSO(err) { offload = false @@ -401,7 +401,7 @@ retry: } else { for i := range bufs { (*msgs)[i].Addr = ua - (*msgs)[i].Buffers[0] = bufs[i] + (*msgs)[i].Buffers[0] = bufs[i][offset:] setSrcControl(&(*msgs)[i].OOB, endpoint.(*StdNetEndpoint)) } err = s.send(conn, br, (*msgs)[:len(bufs)]) @@ -450,7 +450,7 @@ const ( type setGSOFunc func(control *[]byte, gsoSize uint16) -func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, msgs []ipv6.Message, setGSO setGSOFunc) int { +func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, offset int, msgs []ipv6.Message, setGSO setGSOFunc) int { var ( base = -1 // index of msg we are currently coalescing into gsoSize int // segmentation size of msgs[base] @@ -462,6 +462,7 @@ func coalesceMessages(addr *net.UDPAddr, ep *StdNetEndpoint, bufs [][]byte, msgs maxPayloadLen = maxIPv6PayloadLen } for i, buf := range bufs { + buf = buf[offset:] if i > 0 { msgLen := len(buf) baseLenBefore := len(msgs[base].Buffers[0]) diff --git a/vendor/github.com/tailscale/wireguard-go/conn/bind_windows.go b/vendor/github.com/tailscale/wireguard-go/conn/bind_windows.go index 9638b30..737b475 100644 --- a/vendor/github.com/tailscale/wireguard-go/conn/bind_windows.go +++ b/vendor/github.com/tailscale/wireguard-go/conn/bind_windows.go @@ -486,7 +486,7 @@ func (bind *afWinRingBind) Send(buf []byte, nend *WinRingEndpoint, isOpen *atomi return winrio.SendEx(bind.rq, dataBuffer, 1, nil, addressBuffer, nil, nil, 0, 0) } -func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint) error { +func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint, offset int) error { nend, ok := endpoint.(*WinRingEndpoint) if !ok { return ErrWrongEndpointType @@ -494,6 +494,7 @@ func (bind *WinRingBind) Send(bufs [][]byte, endpoint Endpoint) error { bind.mu.RLock() defer bind.mu.RUnlock() for _, buf := range bufs { + buf = buf[offset:] switch nend.family { case windows.AF_INET: if bind.v4.blackhole { diff --git a/vendor/github.com/tailscale/wireguard-go/conn/conn.go b/vendor/github.com/tailscale/wireguard-go/conn/conn.go index 8df5aaa..f178161 100644 --- a/vendor/github.com/tailscale/wireguard-go/conn/conn.go +++ b/vendor/github.com/tailscale/wireguard-go/conn/conn.go @@ -45,9 +45,11 @@ type Bind interface { // This mark is passed to the kernel as the socket option SO_MARK. SetMark(mark uint32) error - // Send writes one or more packets in bufs to address ep. The length of - // bufs must not exceed BatchSize(). - Send(bufs [][]byte, ep Endpoint) error + // Send writes one or more packets in bufs to address ep. A nonzero offset + // can be used to instruct the Bind on where packet data begins in each + // element of the bufs slice. Space preceding offset is free to use for + // additional encapsulation. The length of bufs must not exceed BatchSize(). + Send(bufs [][]byte, ep Endpoint, offset int) error // ParseEndpoint creates a new endpoint from a string. ParseEndpoint(s string) (Endpoint, error) @@ -84,18 +86,38 @@ type Endpoint interface { SrcIP() netip.Addr } +// InitiationAwareEndpoint is an optional [Endpoint] specialization for +// integrations that want to know when a WireGuard handshake initiation +// message has been received, enabling just-in-time peer configuration before +// attempted decryption. +// +// It's most useful when used in combination with [PeerAwareEndpoint], enabling +// JIT peer configuration and post-decryption peer verification from a single +// implementer. +type InitiationAwareEndpoint interface { + // InitiationMessagePublicKey is called when a handshake initiation message + // has been received, and the sender's public key has been identified, but + // BEFORE an attempt has been made to verify it. + InitiationMessagePublicKey(peerPublicKey [32]byte) +} + // PeerAwareEndpoint is an optional Endpoint specialization for -// integrations that want to know about the outcome of cryptorouting +// integrations that want to know about the outcome of Cryptokey Routing // identification. // // If they receive a packet from a source they had not pre-identified, // to learn the identification WireGuard can derive from the session // or handshake. // -// If GetPeerEndpoint returns nil, WireGuard will be unable to respond -// to the peer until a new endpoint is written by a later packet. +// A [PeerAwareEndpoint] may be installed as the [conn.Endpoint] following +// successful decryption unless endpoint roaming has been disabled for +// the peer. type PeerAwareEndpoint interface { - GetPeerEndpoint(peerPublicKey [32]byte) Endpoint + // FromPeer is called at least once per successfully Cryptokey Routing ID'd + // [ReceiveFunc] packets batch for a given node key. wireguard-go will + // always call it for the latest/tail packet in the batch, only ever + // suppressing calls for older packets. + FromPeer(peerPublicKey [32]byte) } var ( diff --git a/vendor/github.com/tailscale/wireguard-go/device/constants.go b/vendor/github.com/tailscale/wireguard-go/device/constants.go index 59854a1..92c3bde 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/constants.go +++ b/vendor/github.com/tailscale/wireguard-go/device/constants.go @@ -27,9 +27,9 @@ const ( ) const ( - MinMessageSize = MessageKeepaliveSize // minimum size of transport message (keepalive) - MaxMessageSize = MaxSegmentSize // maximum size of transport message - MaxContentSize = MaxSegmentSize - MessageTransportSize // maximum size of transport message content + MinMessageSize = MessageKeepaliveSize // minimum size of transport message (keepalive) + MaxMessageSize = MaxSegmentSize // maximum size of transport message + MaxContentSize = MaxSegmentSize - MessageTransportSize - MessageEncapsulatingTransportSize // maximum size of transport message content ) /* Implementation constants */ diff --git a/vendor/github.com/tailscale/wireguard-go/device/device.go b/vendor/github.com/tailscale/wireguard-go/device/device.go index 86dff0d..5b23485 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/device.go +++ b/vendor/github.com/tailscale/wireguard-go/device/device.go @@ -368,10 +368,10 @@ func (device *Device) RemoveAllPeers() { } func (device *Device) Close() { - device.ipcMutex.Lock() - defer device.ipcMutex.Unlock() device.state.Lock() defer device.state.Unlock() + device.ipcMutex.Lock() + defer device.ipcMutex.Unlock() if device.isClosed() { return } diff --git a/vendor/github.com/tailscale/wireguard-go/device/noise-protocol.go b/vendor/github.com/tailscale/wireguard-go/device/noise-protocol.go index 2d8f984..ad5838e 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/noise-protocol.go +++ b/vendor/github.com/tailscale/wireguard-go/device/noise-protocol.go @@ -6,6 +6,7 @@ package device import ( + "encoding/binary" "errors" "fmt" "sync" @@ -15,6 +16,7 @@ import ( "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/poly1305" + "github.com/tailscale/wireguard-go/conn" "github.com/tailscale/wireguard-go/tai64n" ) @@ -60,13 +62,14 @@ const ( ) const ( - MessageInitiationSize = 148 // size of handshake initiation message - MessageResponseSize = 92 // size of response message - MessageCookieReplySize = 64 // size of cookie reply message - MessageTransportHeaderSize = 16 // size of data preceding content in transport message - MessageTransportSize = MessageTransportHeaderSize + poly1305.TagSize // size of empty transport - MessageKeepaliveSize = MessageTransportSize // size of keepalive - MessageHandshakeSize = MessageInitiationSize // size of largest handshake related message + MessageInitiationSize = 148 // size of handshake initiation message + MessageResponseSize = 92 // size of response message + MessageCookieReplySize = 64 // size of cookie reply message + MessageTransportHeaderSize = 16 // size of data preceding content in transport message + MessageEncapsulatingTransportSize = 8 // size of optional, free (for use by conn.Bind.Send()) space preceding the transport header + MessageTransportSize = MessageTransportHeaderSize + poly1305.TagSize // size of empty transport + MessageKeepaliveSize = MessageTransportSize // size of keepalive + MessageHandshakeSize = MessageInitiationSize // size of largest handshake related message ) const ( @@ -115,6 +118,98 @@ type MessageCookieReply struct { Cookie [blake2s.Size128 + poly1305.TagSize]byte } +var errMessageLengthMismatch = errors.New("message length mismatch") + +func (msg *MessageInitiation) unmarshal(b []byte) error { + if len(b) != MessageInitiationSize { + return errMessageLengthMismatch + } + + msg.Type = binary.LittleEndian.Uint32(b) + msg.Sender = binary.LittleEndian.Uint32(b[4:]) + copy(msg.Ephemeral[:], b[8:]) + copy(msg.Static[:], b[8+len(msg.Ephemeral):]) + copy(msg.Timestamp[:], b[8+len(msg.Ephemeral)+len(msg.Static):]) + copy(msg.MAC1[:], b[8+len(msg.Ephemeral)+len(msg.Static)+len(msg.Timestamp):]) + copy(msg.MAC2[:], b[8+len(msg.Ephemeral)+len(msg.Static)+len(msg.Timestamp)+len(msg.MAC1):]) + + return nil +} + +func (msg *MessageInitiation) marshal(b []byte) error { + if len(b) != MessageInitiationSize { + return errMessageLengthMismatch + } + + binary.LittleEndian.PutUint32(b, msg.Type) + binary.LittleEndian.PutUint32(b[4:], msg.Sender) + copy(b[8:], msg.Ephemeral[:]) + copy(b[8+len(msg.Ephemeral):], msg.Static[:]) + copy(b[8+len(msg.Ephemeral)+len(msg.Static):], msg.Timestamp[:]) + copy(b[8+len(msg.Ephemeral)+len(msg.Static)+len(msg.Timestamp):], msg.MAC1[:]) + copy(b[8+len(msg.Ephemeral)+len(msg.Static)+len(msg.Timestamp)+len(msg.MAC1):], msg.MAC2[:]) + + return nil +} + +func (msg *MessageResponse) unmarshal(b []byte) error { + if len(b) != MessageResponseSize { + return errMessageLengthMismatch + } + + msg.Type = binary.LittleEndian.Uint32(b) + msg.Sender = binary.LittleEndian.Uint32(b[4:]) + msg.Receiver = binary.LittleEndian.Uint32(b[8:]) + copy(msg.Ephemeral[:], b[12:]) + copy(msg.Empty[:], b[12+len(msg.Ephemeral):]) + copy(msg.MAC1[:], b[12+len(msg.Ephemeral)+len(msg.Empty):]) + copy(msg.MAC2[:], b[12+len(msg.Ephemeral)+len(msg.Empty)+len(msg.MAC1):]) + + return nil +} + +func (msg *MessageResponse) marshal(b []byte) error { + if len(b) != MessageResponseSize { + return errMessageLengthMismatch + } + + binary.LittleEndian.PutUint32(b, msg.Type) + binary.LittleEndian.PutUint32(b[4:], msg.Sender) + binary.LittleEndian.PutUint32(b[8:], msg.Receiver) + copy(b[12:], msg.Ephemeral[:]) + copy(b[12+len(msg.Ephemeral):], msg.Empty[:]) + copy(b[12+len(msg.Ephemeral)+len(msg.Empty):], msg.MAC1[:]) + copy(b[12+len(msg.Ephemeral)+len(msg.Empty)+len(msg.MAC1):], msg.MAC2[:]) + + return nil +} + +func (msg *MessageCookieReply) unmarshal(b []byte) error { + if len(b) != MessageCookieReplySize { + return errMessageLengthMismatch + } + + msg.Type = binary.LittleEndian.Uint32(b) + msg.Receiver = binary.LittleEndian.Uint32(b[4:]) + copy(msg.Nonce[:], b[8:]) + copy(msg.Cookie[:], b[8+len(msg.Nonce):]) + + return nil +} + +func (msg *MessageCookieReply) marshal(b []byte) error { + if len(b) != MessageCookieReplySize { + return errMessageLengthMismatch + } + + binary.LittleEndian.PutUint32(b, msg.Type) + binary.LittleEndian.PutUint32(b[4:], msg.Receiver) + copy(b[8:], msg.Nonce[:]) + copy(b[8+len(msg.Nonce):], msg.Cookie[:]) + + return nil +} + type Handshake struct { state handshakeState mutex sync.RWMutex @@ -244,7 +339,7 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e return &msg, nil } -func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer { +func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation, endpoint conn.Endpoint) *Peer { var ( hash [blake2s.Size]byte chainKey [blake2s.Size]byte @@ -278,6 +373,11 @@ func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer { // lookup peer + initEP, ok := endpoint.(conn.InitiationAwareEndpoint) + if ok { + initEP.InitiationMessagePublicKey(peerPK) + } + peer := device.LookupPeer(peerPK) if peer == nil || !peer.isRunning.Load() { return nil diff --git a/vendor/github.com/tailscale/wireguard-go/device/peer.go b/vendor/github.com/tailscale/wireguard-go/device/peer.go index 876e5da..064feb2 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/peer.go +++ b/vendor/github.com/tailscale/wireguard-go/device/peer.go @@ -113,6 +113,9 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) { return peer, nil } +// SendBuffers sends buffers to peer. WireGuard packet data in each element of +// buffers must be preceded by MessageEncapsulatingTransportSize number of +// bytes. func (peer *Peer) SendBuffers(buffers [][]byte) error { peer.device.net.RLock() defer peer.device.net.RUnlock() @@ -133,7 +136,7 @@ func (peer *Peer) SendBuffers(buffers [][]byte) error { } peer.endpoint.Unlock() - err := peer.device.net.bind.Send(buffers, endpoint) + err := peer.device.net.bind.Send(buffers, endpoint, MessageEncapsulatingTransportSize) if err == nil { var totalLen uint64 for _, b := range buffers { @@ -283,9 +286,6 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) { return } peer.endpoint.clearSrcOnTx = false - if ep, ok := endpoint.(conn.PeerAwareEndpoint); ok { - endpoint = ep.GetPeerEndpoint(peer.handshake.remoteStatic) - } peer.endpoint.val = endpoint } diff --git a/vendor/github.com/tailscale/wireguard-go/device/receive.go b/vendor/github.com/tailscale/wireguard-go/device/receive.go index af2db44..02c8f21 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/receive.go +++ b/vendor/github.com/tailscale/wireguard-go/device/receive.go @@ -6,7 +6,6 @@ package device import ( - "bytes" "encoding/binary" "errors" "net" @@ -287,8 +286,7 @@ func (device *Device) RoutineHandshake(id int) { // unmarshal packet var reply MessageCookieReply - reader := bytes.NewReader(elem.packet) - err := binary.Read(reader, binary.LittleEndian, &reply) + err := reply.unmarshal(elem.packet) if err != nil { device.log.Verbosef("Failed to decode cookie reply") goto skip @@ -353,8 +351,7 @@ func (device *Device) RoutineHandshake(id int) { // unmarshal var msg MessageInitiation - reader := bytes.NewReader(elem.packet) - err := binary.Read(reader, binary.LittleEndian, &msg) + err := msg.unmarshal(elem.packet) if err != nil { device.log.Errorf("Failed to decode initiation message") goto skip @@ -362,7 +359,7 @@ func (device *Device) RoutineHandshake(id int) { // consume initiation - peer := device.ConsumeMessageInitiation(&msg) + peer := device.ConsumeMessageInitiation(&msg, elem.endpoint) if peer == nil { device.log.Verbosef("Received invalid initiation message from %s", elem.endpoint.DstToString()) goto skip @@ -386,8 +383,7 @@ func (device *Device) RoutineHandshake(id int) { // unmarshal var msg MessageResponse - reader := bytes.NewReader(elem.packet) - err := binary.Read(reader, binary.LittleEndian, &msg) + err := msg.unmarshal(elem.packet) if err != nil { device.log.Errorf("Failed to decode response message") goto skip @@ -447,6 +443,7 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) { elemsContainer.Lock() validTailPacket := -1 dataPacketReceived := false + rxBytesLen := uint64(0) for i, elem := range elemsContainer.elems { if elem.packet == nil { // decryption failed @@ -463,7 +460,10 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) { peer.timersHandshakeComplete() peer.SendStagedPackets() } - peer.rxBytes.Add(uint64(len(elem.packet) + MinMessageSize)) + if ep, ok := elem.endpoint.(conn.PeerAwareEndpoint); ok { + ep.FromPeer(peer.handshake.remoteStatic) + } + rxBytesLen += uint64(len(elem.packet) + MinMessageSize) if len(elem.packet) == 0 { device.log.Verbosef("%v - Receiving keepalive packet", peer) @@ -512,6 +512,8 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) { bufs = append(bufs, elem.buffer[:MessageTransportOffsetContent+len(elem.packet)]) } + + peer.rxBytes.Add(rxBytesLen) if validTailPacket >= 0 { peer.SetEndpointFromPacket(elemsContainer.elems[validTailPacket].endpoint) peer.keepKeyFreshReceiving() diff --git a/vendor/github.com/tailscale/wireguard-go/device/send.go b/vendor/github.com/tailscale/wireguard-go/device/send.go index 8ed2e5f..c8bb079 100644 --- a/vendor/github.com/tailscale/wireguard-go/device/send.go +++ b/vendor/github.com/tailscale/wireguard-go/device/send.go @@ -6,7 +6,6 @@ package device import ( - "bytes" "encoding/binary" "errors" "net" @@ -46,11 +45,15 @@ import ( */ type QueueOutboundElement struct { - buffer *[MaxMessageSize]byte // slice holding the packet data - packet []byte // slice of "buffer" (always!) - nonce uint64 // nonce for encryption - keypair *Keypair // keypair for encryption - peer *Peer // related peer + buffer *[MaxMessageSize]byte // slice holding the packet data + // packet is always a slice of "buffer". The starting offset in buffer + // is either: + // a) MessageEncapsulatingTransportSize+MessageTransportHeaderSize (plaintext) + // b) 0 (post-encryption) + packet []byte + nonce uint64 // nonce for encryption + keypair *Keypair // keypair for encryption + peer *Peer // related peer } type QueueOutboundElementsContainer struct { @@ -124,16 +127,15 @@ func (peer *Peer) SendHandshakeInitiation(isRetry bool) error { return err } - var buf [MessageInitiationSize]byte - writer := bytes.NewBuffer(buf[:0]) - binary.Write(writer, binary.LittleEndian, msg) - packet := writer.Bytes() + buf := make([]byte, MessageEncapsulatingTransportSize+MessageInitiationSize) + packet := buf[MessageEncapsulatingTransportSize:] + _ = msg.marshal(packet) peer.cookieGenerator.AddMacs(packet) peer.timersAnyAuthenticatedPacketTraversal() peer.timersAnyAuthenticatedPacketSent() - err = peer.SendBuffers([][]byte{packet}) + err = peer.SendBuffers([][]byte{buf}) if err != nil { peer.device.log.Errorf("%v - Failed to send handshake initiation: %v", peer, err) } @@ -155,10 +157,9 @@ func (peer *Peer) SendHandshakeResponse() error { return err } - var buf [MessageResponseSize]byte - writer := bytes.NewBuffer(buf[:0]) - binary.Write(writer, binary.LittleEndian, response) - packet := writer.Bytes() + buf := make([]byte, MessageEncapsulatingTransportSize+MessageResponseSize) + packet := buf[MessageEncapsulatingTransportSize:] + _ = response.marshal(packet) peer.cookieGenerator.AddMacs(packet) err = peer.BeginSymmetricSession() @@ -172,7 +173,7 @@ func (peer *Peer) SendHandshakeResponse() error { peer.timersAnyAuthenticatedPacketSent() // TODO: allocation could be avoided - err = peer.SendBuffers([][]byte{packet}) + err = peer.SendBuffers([][]byte{buf}) if err != nil { peer.device.log.Errorf("%v - Failed to send handshake response: %v", peer, err) } @@ -189,11 +190,12 @@ func (device *Device) SendHandshakeCookie(initiatingElem *QueueHandshakeElement) return err } - var buf [MessageCookieReplySize]byte - writer := bytes.NewBuffer(buf[:0]) - binary.Write(writer, binary.LittleEndian, reply) + buf := make([]byte, MessageEncapsulatingTransportSize+MessageCookieReplySize) + packet := buf[MessageEncapsulatingTransportSize:] + _ = reply.marshal(packet) // TODO: allocation could be avoided - device.net.bind.Send([][]byte{writer.Bytes()}, initiatingElem.endpoint) + device.net.bind.Send([][]byte{buf}, initiatingElem.endpoint, MessageEncapsulatingTransportSize) + return nil } @@ -225,7 +227,7 @@ func (device *Device) RoutineReadFromTUN() { elemsByPeer = make(map[*Peer]*QueueOutboundElementsContainer, batchSize) count = 0 sizes = make([]int, batchSize) - offset = MessageTransportHeaderSize + offset = MessageEncapsulatingTransportSize + MessageTransportHeaderSize ) for i := range elems { @@ -451,7 +453,7 @@ func (device *Device) RoutineEncryption(id int) { for elemsContainer := range device.queue.encryption.c { for _, elem := range elemsContainer.elems { // populate header fields - header := elem.buffer[:MessageTransportHeaderSize] + header := elem.buffer[MessageEncapsulatingTransportSize : MessageEncapsulatingTransportSize+MessageTransportHeaderSize] fieldType := header[0:4] fieldReceiver := header[4:8] @@ -474,6 +476,9 @@ func (device *Device) RoutineEncryption(id int) { elem.packet, nil, ) + + // re-slice packet to include encapsulating transport space + elem.packet = elem.buffer[:MessageEncapsulatingTransportSize+len(elem.packet)] } elemsContainer.Unlock() } @@ -512,7 +517,7 @@ func (peer *Peer) RoutineSequentialSender(maxBatchSize int) { dataSent := false elemsContainer.Lock() for _, elem := range elemsContainer.elems { - if len(elem.packet) != MessageKeepaliveSize { + if len(elem.packet[MessageEncapsulatingTransportSize:]) != MessageKeepaliveSize { dataSent = true } bufs = append(bufs, elem.packet) diff --git a/vendor/github.com/tailscale/wireguard-go/tun/tun_plan9.go b/vendor/github.com/tailscale/wireguard-go/tun/tun_plan9.go new file mode 100644 index 0000000..7b66ead --- /dev/null +++ b/vendor/github.com/tailscale/wireguard-go/tun/tun_plan9.go @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. + */ + +package tun + +import ( + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" +) + +type NativeTun struct { + name string // "/net/ipifc/2" + ctlFile *os.File + dataFile *os.File + events chan Event + errors chan error + closeOnce sync.Once +} + +func CreateTUN(_ string, mtu int) (Device, error) { + ctl, err := os.OpenFile("/net/ipifc/clone", os.O_RDWR, 0) + if err != nil { + return nil, err + } + nbuf := make([]byte, 5) + n, err := ctl.Read(nbuf) + if err != nil { + ctl.Close() + return nil, fmt.Errorf("error reading from clone file: %w", err) + } + ifn, err := strconv.Atoi(strings.TrimSpace(string(nbuf[:n]))) + if err != nil { + ctl.Close() + return nil, fmt.Errorf("error converting clone result %q to int: %w", nbuf[:n], err) + } + + if _, err := fmt.Fprintf(ctl, "bind pkt\n"); err != nil { + ctl.Close() + return nil, fmt.Errorf("error binding to pkt: %w", err) + } + if mtu > 0 { + if _, err := fmt.Fprintf(ctl, "mtu %d\n", mtu); err != nil { + ctl.Close() + return nil, fmt.Errorf("error setting MTU: %w", err) + } + } + + dataFile, err := os.OpenFile(fmt.Sprintf("/net/ipifc/%d/data", ifn), os.O_RDWR, 0) + if err != nil { + ctl.Close() + return nil, err + } + + tun := &NativeTun{ + ctlFile: ctl, + dataFile: dataFile, + name: fmt.Sprintf("/net/ipifc/%d", ifn), + events: make(chan Event, 10), + errors: make(chan error, 5), + } + tun.events <- EventUp + + return tun, nil +} + +func (tun *NativeTun) Name() (string, error) { + return tun.name, nil +} + +func (tun *NativeTun) File() *os.File { + return tun.ctlFile +} + +func (tun *NativeTun) Events() <-chan Event { + return tun.events +} + +func (tun *NativeTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) { + select { + case err := <-tun.errors: + return 0, err + default: + n, err := tun.dataFile.Read(bufs[0][offset:]) + if n == 1 && bufs[0][offset] == 0 { + // EOF + err = io.EOF + n = 0 + } + sizes[0] = n + return 1, err + } +} + +func (tun *NativeTun) Write(bufs [][]byte, offset int) (int, error) { + for i, buf := range bufs { + if _, err := tun.dataFile.Write(buf[offset:]); err != nil { + return i, err + } + } + return len(bufs), nil +} + +func (tun *NativeTun) Close() error { + var err1, err2 error + tun.closeOnce.Do(func() { + _, err1 := fmt.Fprintf(tun.ctlFile, "unbind\n") + if err := tun.ctlFile.Close(); err != nil && err1 == nil { + err1 = err + } + err2 = tun.dataFile.Close() + }) + if err1 != nil { + return err1 + } + return err2 +} + +func (tun *NativeTun) MTU() (int, error) { + var buf [100]byte + f, err := os.Open(tun.name + "/status") + if err != nil { + return 0, err + } + defer f.Close() + n, err := f.Read(buf[:]) + _, res, ok := strings.Cut(string(buf[:n]), " maxtu ") + if ok { + if mtus, _, ok := strings.Cut(res, " "); ok { + mtu, err := strconv.Atoi(mtus) + if err != nil { + return 0, fmt.Errorf("error converting mtu %q to int: %w", mtus, err) + } + return mtu, nil + } + } + return 0, fmt.Errorf("no 'maxtu' field found in %s/status", tun.name) +} + +func (tun *NativeTun) BatchSize() int { + return 1 +} diff --git a/vendor/github.com/u-root/uio/LICENSE b/vendor/github.com/u-root/uio/LICENSE deleted file mode 100644 index 652ff7e..0000000 --- a/vendor/github.com/u-root/uio/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index e189199..0000000 --- a/vendor/github.com/u-root/uio/rand/random.go +++ /dev/null @@ -1,62 +0,0 @@ -// 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 deleted file mode 100644 index 42931cc..0000000 --- a/vendor/github.com/u-root/uio/rand/random_linux.go +++ /dev/null @@ -1,77 +0,0 @@ -// 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 deleted file mode 100644 index 47b2e74..0000000 --- a/vendor/github.com/u-root/uio/rand/random_std.go +++ /dev/null @@ -1,32 +0,0 @@ -// 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 deleted file mode 100644 index 57d2e2f..0000000 --- a/vendor/github.com/u-root/uio/rand/random_unix.go +++ /dev/null @@ -1,10 +0,0 @@ -// 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 deleted file mode 100644 index cd6e263..0000000 --- a/vendor/github.com/u-root/uio/rand/random_urandom.go +++ /dev/null @@ -1,60 +0,0 @@ -// 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 deleted file mode 100644 index 6800644..0000000 --- a/vendor/github.com/u-root/uio/uio/alignreader.go +++ /dev/null @@ -1,41 +0,0 @@ -// 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 deleted file mode 100644 index 95a52f6..0000000 --- a/vendor/github.com/u-root/uio/uio/alignwriter.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 deleted file mode 100644 index 6d0eeef..0000000 --- a/vendor/github.com/u-root/uio/uio/archivereader.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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 deleted file mode 100644 index a0a603b..0000000 --- a/vendor/github.com/u-root/uio/uio/buffer.go +++ /dev/null @@ -1,380 +0,0 @@ -// 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 deleted file mode 100644 index a39ff98..0000000 --- a/vendor/github.com/u-root/uio/uio/cached.go +++ /dev/null @@ -1,98 +0,0 @@ -// 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 deleted file mode 100644 index 4cb06ac..0000000 --- a/vendor/github.com/u-root/uio/uio/lazy.go +++ /dev/null @@ -1,165 +0,0 @@ -// 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 deleted file mode 100644 index 1c89f74..0000000 --- a/vendor/github.com/u-root/uio/uio/null.go +++ /dev/null @@ -1,76 +0,0 @@ -// 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 deleted file mode 100644 index 3aa2a3e..0000000 --- a/vendor/github.com/u-root/uio/uio/progress.go +++ /dev/null @@ -1,42 +0,0 @@ -// 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 deleted file mode 100644 index 0ca839a..0000000 --- a/vendor/github.com/u-root/uio/uio/reader.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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 deleted file mode 100644 index bdd507c..0000000 --- a/vendor/github.com/u-root/uio/uio/uio.go +++ /dev/null @@ -1,9 +0,0 @@ -// 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/github.com/vishvananda/netns/.golangci.yml b/vendor/github.com/vishvananda/netns/.golangci.yml deleted file mode 100644 index 600bef7..0000000 --- a/vendor/github.com/vishvananda/netns/.golangci.yml +++ /dev/null @@ -1,2 +0,0 @@ -run: - timeout: 5m diff --git a/vendor/github.com/vishvananda/netns/LICENSE b/vendor/github.com/vishvananda/netns/LICENSE deleted file mode 100644 index 9f64db8..0000000 --- a/vendor/github.com/vishvananda/netns/LICENSE +++ /dev/null @@ -1,192 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014 Vishvananda Ishaya. - Copyright 2014 Docker, Inc. - - 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. diff --git a/vendor/github.com/vishvananda/netns/README.md b/vendor/github.com/vishvananda/netns/README.md deleted file mode 100644 index bdfedbe..0000000 --- a/vendor/github.com/vishvananda/netns/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# netns - network namespaces in go # - -The netns package provides an ultra-simple interface for handling -network namespaces in go. Changing namespaces requires elevated -privileges, so in most cases this code needs to be run as root. - -## Local Build and Test ## - -You can use go get command: - - go get github.com/vishvananda/netns - -Testing (requires root): - - sudo -E go test github.com/vishvananda/netns - -## Example ## - -```go -package main - -import ( - "fmt" - "net" - "runtime" - - "github.com/vishvananda/netns" -) - -func main() { - // Lock the OS Thread so we don't accidentally switch namespaces - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - // Save the current network namespace - origns, _ := netns.Get() - defer origns.Close() - - // Create a new network namespace - newns, _ := netns.New() - defer newns.Close() - - // Do something with the network namespace - ifaces, _ := net.Interfaces() - fmt.Printf("Interfaces: %v\n", ifaces) - - // Switch back to the original namespace - netns.Set(origns) -} - -``` diff --git a/vendor/github.com/vishvananda/netns/doc.go b/vendor/github.com/vishvananda/netns/doc.go deleted file mode 100644 index cd4093a..0000000 --- a/vendor/github.com/vishvananda/netns/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package netns allows ultra-simple network namespace handling. NsHandles -// can be retrieved and set. Note that the current namespace is thread -// local so actions that set and reset namespaces should use LockOSThread -// to make sure the namespace doesn't change due to a goroutine switch. -// It is best to close NsHandles when you are done with them. This can be -// accomplished via a `defer ns.Close()` on the handle. Changing namespaces -// requires elevated privileges, so in most cases this code needs to be run -// as root. -package netns diff --git a/vendor/github.com/vishvananda/netns/netns_linux.go b/vendor/github.com/vishvananda/netns/netns_linux.go deleted file mode 100644 index 2ed7c7e..0000000 --- a/vendor/github.com/vishvananda/netns/netns_linux.go +++ /dev/null @@ -1,283 +0,0 @@ -package netns - -import ( - "fmt" - "os" - "path" - "path/filepath" - "strconv" - "strings" - - "golang.org/x/sys/unix" -) - -// Deprecated: use golang.org/x/sys/unix pkg instead. -const ( - CLONE_NEWUTS = unix.CLONE_NEWUTS /* New utsname group? */ - CLONE_NEWIPC = unix.CLONE_NEWIPC /* New ipcs */ - CLONE_NEWUSER = unix.CLONE_NEWUSER /* New user namespace */ - CLONE_NEWPID = unix.CLONE_NEWPID /* New pid namespace */ - CLONE_NEWNET = unix.CLONE_NEWNET /* New network namespace */ - CLONE_IO = unix.CLONE_IO /* Get io context */ -) - -const bindMountPath = "/run/netns" /* Bind mount path for named netns */ - -// Setns sets namespace using golang.org/x/sys/unix.Setns. -// -// Deprecated: Use golang.org/x/sys/unix.Setns instead. -func Setns(ns NsHandle, nstype int) (err error) { - return unix.Setns(int(ns), nstype) -} - -// Set sets the current network namespace to the namespace represented -// by NsHandle. -func Set(ns NsHandle) (err error) { - return unix.Setns(int(ns), unix.CLONE_NEWNET) -} - -// New creates a new network namespace, sets it as current and returns -// a handle to it. -func New() (ns NsHandle, err error) { - if err := unix.Unshare(unix.CLONE_NEWNET); err != nil { - return -1, err - } - return Get() -} - -// NewNamed creates a new named network namespace, sets it as current, -// and returns a handle to it -func NewNamed(name string) (NsHandle, error) { - if _, err := os.Stat(bindMountPath); os.IsNotExist(err) { - err = os.MkdirAll(bindMountPath, 0755) - if err != nil { - return None(), err - } - } - - newNs, err := New() - if err != nil { - return None(), err - } - - namedPath := path.Join(bindMountPath, name) - - f, err := os.OpenFile(namedPath, os.O_CREATE|os.O_EXCL, 0444) - if err != nil { - newNs.Close() - return None(), err - } - f.Close() - - nsPath := fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid()) - err = unix.Mount(nsPath, namedPath, "bind", unix.MS_BIND, "") - if err != nil { - newNs.Close() - return None(), err - } - - return newNs, nil -} - -// DeleteNamed deletes a named network namespace -func DeleteNamed(name string) error { - namedPath := path.Join(bindMountPath, name) - - err := unix.Unmount(namedPath, unix.MNT_DETACH) - if err != nil { - return err - } - - return os.Remove(namedPath) -} - -// Get gets a handle to the current threads network namespace. -func Get() (NsHandle, error) { - return GetFromThread(os.Getpid(), unix.Gettid()) -} - -// GetFromPath gets a handle to a network namespace -// identified by the path -func GetFromPath(path string) (NsHandle, error) { - fd, err := unix.Open(path, unix.O_RDONLY|unix.O_CLOEXEC, 0) - if err != nil { - return -1, err - } - return NsHandle(fd), nil -} - -// GetFromName gets a handle to a named network namespace such as one -// created by `ip netns add`. -func GetFromName(name string) (NsHandle, error) { - return GetFromPath(filepath.Join(bindMountPath, name)) -} - -// GetFromPid gets a handle to the network namespace of a given pid. -func GetFromPid(pid int) (NsHandle, error) { - return GetFromPath(fmt.Sprintf("/proc/%d/ns/net", pid)) -} - -// GetFromThread gets a handle to the network namespace of a given pid and tid. -func GetFromThread(pid, tid int) (NsHandle, error) { - return GetFromPath(fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid)) -} - -// GetFromDocker gets a handle to the network namespace of a docker container. -// Id is prefixed matched against the running docker containers, so a short -// identifier can be used as long as it isn't ambiguous. -func GetFromDocker(id string) (NsHandle, error) { - pid, err := getPidForContainer(id) - if err != nil { - return -1, err - } - return GetFromPid(pid) -} - -// borrowed from docker/utils/utils.go -func findCgroupMountpoint(cgroupType string) (int, string, error) { - output, err := os.ReadFile("/proc/mounts") - if err != nil { - return -1, "", err - } - - // /proc/mounts has 6 fields per line, one mount per line, e.g. - // cgroup /sys/fs/cgroup/devices cgroup rw,relatime,devices 0 0 - for _, line := range strings.Split(string(output), "\n") { - parts := strings.Split(line, " ") - if len(parts) == 6 { - switch parts[2] { - case "cgroup2": - return 2, parts[1], nil - case "cgroup": - for _, opt := range strings.Split(parts[3], ",") { - if opt == cgroupType { - return 1, parts[1], nil - } - } - } - } - } - - return -1, "", fmt.Errorf("cgroup mountpoint not found for %s", cgroupType) -} - -// Returns the relative path to the cgroup docker is running in. -// borrowed from docker/utils/utils.go -// modified to get the docker pid instead of using /proc/self -func getDockerCgroup(cgroupVer int, cgroupType string) (string, error) { - dockerpid, err := os.ReadFile("/var/run/docker.pid") - if err != nil { - return "", err - } - result := strings.Split(string(dockerpid), "\n") - if len(result) == 0 || len(result[0]) == 0 { - return "", fmt.Errorf("docker pid not found in /var/run/docker.pid") - } - pid, err := strconv.Atoi(result[0]) - if err != nil { - return "", err - } - output, err := os.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) - if err != nil { - return "", err - } - for _, line := range strings.Split(string(output), "\n") { - parts := strings.Split(line, ":") - // any type used by docker should work - if (cgroupVer == 1 && parts[1] == cgroupType) || - (cgroupVer == 2 && parts[1] == "") { - return parts[2], nil - } - } - return "", fmt.Errorf("cgroup '%s' not found in /proc/%d/cgroup", cgroupType, pid) -} - -// Returns the first pid in a container. -// borrowed from docker/utils/utils.go -// modified to only return the first pid -// modified to glob with id -// modified to search for newer docker containers -// modified to look for cgroups v2 -func getPidForContainer(id string) (int, error) { - pid := 0 - - // memory is chosen randomly, any cgroup used by docker works - cgroupType := "memory" - - cgroupVer, cgroupRoot, err := findCgroupMountpoint(cgroupType) - if err != nil { - return pid, err - } - - cgroupDocker, err := getDockerCgroup(cgroupVer, cgroupType) - if err != nil { - return pid, err - } - - id += "*" - - var pidFile string - if cgroupVer == 1 { - pidFile = "tasks" - } else if cgroupVer == 2 { - pidFile = "cgroup.procs" - } else { - return -1, fmt.Errorf("Invalid cgroup version '%d'", cgroupVer) - } - - attempts := []string{ - filepath.Join(cgroupRoot, cgroupDocker, id, pidFile), - // With more recent lxc versions use, cgroup will be in lxc/ - filepath.Join(cgroupRoot, cgroupDocker, "lxc", id, pidFile), - // With more recent docker, cgroup will be in docker/ - filepath.Join(cgroupRoot, cgroupDocker, "docker", id, pidFile), - // Even more recent docker versions under systemd use docker-.scope/ - filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", pidFile), - // Even more recent docker versions under cgroup/systemd/docker// - filepath.Join(cgroupRoot, "..", "systemd", "docker", id, pidFile), - // Kubernetes with docker and CNI is even more different. Works for BestEffort and Burstable QoS - filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, pidFile), - // Same as above but for Guaranteed QoS - filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "pod*", id, pidFile), - // Another flavor of containers location in recent kubernetes 1.11+. Works for BestEffort and Burstable QoS - filepath.Join(cgroupRoot, cgroupDocker, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", pidFile), - // Same as above but for Guaranteed QoS - filepath.Join(cgroupRoot, cgroupDocker, "kubepods.slice", "*", "docker-"+id+".scope", pidFile), - // When runs inside of a container with recent kubernetes 1.11+. Works for BestEffort and Burstable QoS - filepath.Join(cgroupRoot, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", pidFile), - // Same as above but for Guaranteed QoS - filepath.Join(cgroupRoot, "kubepods.slice", "*", "docker-"+id+".scope", pidFile), - } - - var filename string - for _, attempt := range attempts { - filenames, _ := filepath.Glob(attempt) - if len(filenames) > 1 { - return pid, fmt.Errorf("Ambiguous id supplied: %v", filenames) - } else if len(filenames) == 1 { - filename = filenames[0] - break - } - } - - if filename == "" { - return pid, fmt.Errorf("Unable to find container: %v", id[:len(id)-1]) - } - - output, err := os.ReadFile(filename) - if err != nil { - return pid, err - } - - result := strings.Split(string(output), "\n") - if len(result) == 0 || len(result[0]) == 0 { - return pid, fmt.Errorf("No pid found for container") - } - - pid, err = strconv.Atoi(result[0]) - if err != nil { - return pid, fmt.Errorf("Invalid pid '%s': %s", result[0], err) - } - - return pid, nil -} diff --git a/vendor/github.com/vishvananda/netns/netns_others.go b/vendor/github.com/vishvananda/netns/netns_others.go deleted file mode 100644 index 0489837..0000000 --- a/vendor/github.com/vishvananda/netns/netns_others.go +++ /dev/null @@ -1,60 +0,0 @@ -//go:build !linux -// +build !linux - -package netns - -import ( - "errors" -) - -var ( - ErrNotImplemented = errors.New("not implemented") -) - -// Setns sets namespace using golang.org/x/sys/unix.Setns on Linux. It -// is not implemented on other platforms. -// -// Deprecated: Use golang.org/x/sys/unix.Setns instead. -func Setns(ns NsHandle, nstype int) (err error) { - return ErrNotImplemented -} - -func Set(ns NsHandle) (err error) { - return ErrNotImplemented -} - -func New() (ns NsHandle, err error) { - return -1, ErrNotImplemented -} - -func NewNamed(name string) (NsHandle, error) { - return -1, ErrNotImplemented -} - -func DeleteNamed(name string) error { - return ErrNotImplemented -} - -func Get() (NsHandle, error) { - return -1, ErrNotImplemented -} - -func GetFromPath(path string) (NsHandle, error) { - return -1, ErrNotImplemented -} - -func GetFromName(name string) (NsHandle, error) { - return -1, ErrNotImplemented -} - -func GetFromPid(pid int) (NsHandle, error) { - return -1, ErrNotImplemented -} - -func GetFromThread(pid, tid int) (NsHandle, error) { - return -1, ErrNotImplemented -} - -func GetFromDocker(id string) (NsHandle, error) { - return -1, ErrNotImplemented -} diff --git a/vendor/github.com/vishvananda/netns/nshandle_linux.go b/vendor/github.com/vishvananda/netns/nshandle_linux.go deleted file mode 100644 index 1baffb6..0000000 --- a/vendor/github.com/vishvananda/netns/nshandle_linux.go +++ /dev/null @@ -1,73 +0,0 @@ -package netns - -import ( - "fmt" - - "golang.org/x/sys/unix" -) - -// NsHandle is a handle to a network namespace. It can be cast directly -// to an int and used as a file descriptor. -type NsHandle int - -// Equal determines if two network handles refer to the same network -// namespace. This is done by comparing the device and inode that the -// file descriptors point to. -func (ns NsHandle) Equal(other NsHandle) bool { - if ns == other { - return true - } - var s1, s2 unix.Stat_t - if err := unix.Fstat(int(ns), &s1); err != nil { - return false - } - if err := unix.Fstat(int(other), &s2); err != nil { - return false - } - return (s1.Dev == s2.Dev) && (s1.Ino == s2.Ino) -} - -// String shows the file descriptor number and its dev and inode. -func (ns NsHandle) String() string { - if ns == -1 { - return "NS(none)" - } - var s unix.Stat_t - if err := unix.Fstat(int(ns), &s); err != nil { - return fmt.Sprintf("NS(%d: unknown)", ns) - } - return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino) -} - -// UniqueId returns a string which uniquely identifies the namespace -// associated with the network handle. -func (ns NsHandle) UniqueId() string { - if ns == -1 { - return "NS(none)" - } - var s unix.Stat_t - if err := unix.Fstat(int(ns), &s); err != nil { - return "NS(unknown)" - } - return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino) -} - -// IsOpen returns true if Close() has not been called. -func (ns NsHandle) IsOpen() bool { - return ns != -1 -} - -// Close closes the NsHandle and resets its file descriptor to -1. -// It is not safe to use an NsHandle after Close() is called. -func (ns *NsHandle) Close() error { - if err := unix.Close(int(*ns)); err != nil { - return err - } - *ns = -1 - return nil -} - -// None gets an empty (closed) NsHandle. -func None() NsHandle { - return NsHandle(-1) -} diff --git a/vendor/github.com/vishvananda/netns/nshandle_others.go b/vendor/github.com/vishvananda/netns/nshandle_others.go deleted file mode 100644 index af727bc..0000000 --- a/vendor/github.com/vishvananda/netns/nshandle_others.go +++ /dev/null @@ -1,45 +0,0 @@ -//go:build !linux -// +build !linux - -package netns - -// NsHandle is a handle to a network namespace. It can only be used on Linux, -// but provides stub methods on other platforms. -type NsHandle int - -// Equal determines if two network handles refer to the same network -// namespace. It is only implemented on Linux. -func (ns NsHandle) Equal(_ NsHandle) bool { - return false -} - -// String shows the file descriptor number and its dev and inode. -// It is only implemented on Linux, and returns "NS(none)" on other -// platforms. -func (ns NsHandle) String() string { - return "NS(none)" -} - -// UniqueId returns a string which uniquely identifies the namespace -// associated with the network handle. It is only implemented on Linux, -// and returns "NS(none)" on other platforms. -func (ns NsHandle) UniqueId() string { - return "NS(none)" -} - -// IsOpen returns true if Close() has not been called. It is only implemented -// on Linux and always returns false on other platforms. -func (ns NsHandle) IsOpen() bool { - return false -} - -// Close closes the NsHandle and resets its file descriptor to -1. -// It is only implemented on Linux. -func (ns *NsHandle) Close() error { - return nil -} - -// None gets an empty (closed) NsHandle. -func None() NsHandle { - return NsHandle(-1) -} diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go index 29f0a2d..2b65ec9 100644 --- a/vendor/golang.org/x/crypto/argon2/argon2.go +++ b/vendor/golang.org/x/crypto/argon2/argon2.go @@ -6,7 +6,7 @@ // Argon2 was selected as the winner of the Password Hashing Competition and can // be used to derive cryptographic keys from passwords. // -// For a detailed specification of Argon2 see [1]. +// For a detailed specification of Argon2 see [argon2-specs.pdf]. // // If you aren't sure which function you need, use Argon2id (IDKey) and // the parameter recommendations for your scenario. @@ -17,7 +17,7 @@ // It uses data-independent memory access, which is preferred for password // hashing and password-based key derivation. Argon2i requires more passes over // memory than Argon2id to protect from trade-off attacks. The recommended -// parameters (taken from [2]) for non-interactive operations are time=3 and to +// parameters (taken from [RFC 9106 Section 7.3]) for non-interactive operations are time=3 and to // use the maximum available memory. // // # Argon2id @@ -27,11 +27,11 @@ // half of the first iteration over the memory and data-dependent memory access // for the rest. Argon2id is side-channel resistant and provides better brute- // force cost savings due to time-memory tradeoffs than Argon2i. The recommended -// parameters for non-interactive operations (taken from [2]) are time=1 and to +// parameters for non-interactive operations (taken from [RFC 9106 Section 7.3]) are time=1 and to // use the maximum available memory. // -// [1] https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf -// [2] https://tools.ietf.org/html/draft-irtf-cfrg-argon2-03#section-9.3 +// [argon2-specs.pdf]: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf +// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 package argon2 import ( @@ -59,7 +59,7 @@ const ( // // key := argon2.Key([]byte("some password"), salt, 3, 32*1024, 4, 32) // -// The draft RFC recommends[2] time=3, and memory=32*1024 is a sensible number. +// [RFC 9106 Section 7.3] recommends time=3, and memory=32*1024 as a sensible number. // If using that amount of memory (32 MB) is not possible in some contexts then // the time parameter can be increased to compensate. // @@ -69,6 +69,8 @@ const ( // adjusted to the number of available CPUs. The cost parameters should be // increased as memory latency and CPU parallelism increases. Remember to get a // good random salt. +// +// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen) } @@ -83,7 +85,7 @@ func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint3 // // key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32) // -// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number. +// [RFC 9106 Section 7.3] recommends time=1, and memory=64*1024 as a sensible number. // If using that amount of memory (64 MB) is not possible in some contexts then // the time parameter can be increased to compensate. // @@ -93,6 +95,8 @@ func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint3 // adjusted to the numbers of available CPUs. The cost parameters should be // increased as memory latency and CPU parallelism increases. Remember to get a // good random salt. +// +// [RFC 9106 Section 7.3]: https://www.rfc-editor.org/rfc/rfc9106.html#section-7.3 func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen) } diff --git a/vendor/golang.org/x/crypto/blake2b/blake2x.go b/vendor/golang.org/x/crypto/blake2b/blake2x.go index 52c414d..7692bb3 100644 --- a/vendor/golang.org/x/crypto/blake2b/blake2x.go +++ b/vendor/golang.org/x/crypto/blake2b/blake2x.go @@ -12,6 +12,8 @@ import ( // XOF defines the interface to hash functions that // support arbitrary-length output. +// +// New callers should prefer the standard library [hash.XOF]. type XOF interface { // Write absorbs more data into the hash's state. It panics if called // after Read. @@ -47,6 +49,8 @@ const maxOutputLength = (1 << 32) * 64 // // A non-nil key turns the hash into a MAC. The key must between // zero and 32 bytes long. +// +// The result can be safely interface-upgraded to [hash.XOF]. func NewXOF(size uint32, key []byte) (XOF, error) { if len(key) > Size { return nil, errKeySize @@ -93,6 +97,10 @@ func (x *xof) Clone() XOF { return &clone } +func (x *xof) BlockSize() int { + return x.d.BlockSize() +} + func (x *xof) Reset() { x.cfg[0] = byte(Size) binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length diff --git a/vendor/golang.org/x/crypto/blake2b/go125.go b/vendor/golang.org/x/crypto/blake2b/go125.go new file mode 100644 index 0000000..67e990b --- /dev/null +++ b/vendor/golang.org/x/crypto/blake2b/go125.go @@ -0,0 +1,11 @@ +// Copyright 2025 The Go 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.25 + +package blake2b + +import "hash" + +var _ hash.XOF = (*xof)(nil) diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s index 7dd2638..769af38 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s @@ -29,7 +29,7 @@ loop: MOVD $NUM_ROUNDS, R21 VLD1 (R11), [V30.S4, V31.S4] - // load contants + // load constants // VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4] WORD $0x4D60E940 diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go index 50695a1..b850e77 100644 --- a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go @@ -56,7 +56,10 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) [] ret, out := sliceForAppend(dst, len(plaintext)+16) if alias.InexactOverlap(out, plaintext) { - panic("chacha20poly1305: invalid buffer overlap") + panic("chacha20poly1305: invalid buffer overlap of output and input") + } + if alias.AnyOverlap(out, additionalData) { + panic("chacha20poly1305: invalid buffer overlap of output and additional data") } chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData) return ret @@ -73,7 +76,10 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ( ciphertext = ciphertext[:len(ciphertext)-16] ret, out := sliceForAppend(dst, len(ciphertext)) if alias.InexactOverlap(out, ciphertext) { - panic("chacha20poly1305: invalid buffer overlap") + panic("chacha20poly1305: invalid buffer overlap of output and input") + } + if alias.AnyOverlap(out, additionalData) { + panic("chacha20poly1305: invalid buffer overlap of output and additional data") } if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) { for i := range out { diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go index 6313898..2ecc840 100644 --- a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go +++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go @@ -31,7 +31,10 @@ func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []b ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) ciphertext, tag := out[:len(plaintext)], out[len(plaintext):] if alias.InexactOverlap(out, plaintext) { - panic("chacha20poly1305: invalid buffer overlap") + panic("chacha20poly1305: invalid buffer overlap of output and input") + } + if alias.AnyOverlap(out, additionalData) { + panic("chacha20poly1305: invalid buffer overlap of output and additional data") } var polyKey [32]byte @@ -67,7 +70,10 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData [] ret, out := sliceForAppend(dst, len(ciphertext)) if alias.InexactOverlap(out, ciphertext) { - panic("chacha20poly1305: invalid buffer overlap") + panic("chacha20poly1305: invalid buffer overlap of output and input") + } + if alias.AnyOverlap(out, additionalData) { + panic("chacha20poly1305: invalid buffer overlap of output and additional data") } if !p.Verify(tag) { for i := range out { diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go index 21ca3b2..048faef 100644 --- a/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -3,11 +3,14 @@ // license that can be found in the LICENSE file. // Package curve25519 provides an implementation of the X25519 function, which -// performs scalar multiplication on the elliptic curve known as Curve25519. -// See RFC 7748. +// performs scalar multiplication on the elliptic curve known as Curve25519 +// according to [RFC 7748]. // -// This package is a wrapper for the X25519 implementation -// in the crypto/ecdh package. +// The curve25519 package is a wrapper for the X25519 implementation in the +// crypto/ecdh package. It is [frozen] and is not accepting new features. +// +// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 +// [frozen]: https://go.dev/wiki/Frozen package curve25519 import "crypto/ecdh" @@ -36,7 +39,7 @@ func ScalarBaseMult(dst, scalar *[32]byte) { curve := ecdh.X25519() priv, err := curve.NewPrivateKey(scalar[:]) if err != nil { - panic("curve25519: internal error: scalarBaseMult was not 32 bytes") + panic("curve25519: " + err.Error()) } copy(dst[:], priv.PublicKey().Bytes()) } diff --git a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go index bd896bd..8d99551 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go +++ b/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (!amd64 && !ppc64le && !ppc64 && !s390x) || !gc || purego +//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !s390x) || !gc || purego package poly1305 diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go similarity index 94% rename from vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go rename to vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go index 164cd47..315b84a 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build gc && !purego +//go:build gc && !purego && (amd64 || loong64 || ppc64 || ppc64le) package poly1305 diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s new file mode 100644 index 0000000..bc8361d --- /dev/null +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s @@ -0,0 +1,123 @@ +// Copyright 2025 The Go 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 gc && !purego + +// func update(state *macState, msg []byte) +TEXT ·update(SB), $0-32 + MOVV state+0(FP), R4 + MOVV msg_base+8(FP), R5 + MOVV msg_len+16(FP), R6 + + MOVV $0x10, R7 + + MOVV (R4), R8 // h0 + MOVV 8(R4), R9 // h1 + MOVV 16(R4), R10 // h2 + MOVV 24(R4), R11 // r0 + MOVV 32(R4), R12 // r1 + + BLT R6, R7, bytes_between_0_and_15 + +loop: + MOVV (R5), R14 // msg[0:8] + MOVV 8(R5), R16 // msg[8:16] + ADDV R14, R8, R8 // h0 (x1 + y1 = z1', if z1' < x1 then z1' overflow) + ADDV R16, R9, R27 + SGTU R14, R8, R24 // h0.carry + SGTU R9, R27, R28 + ADDV R27, R24, R9 // h1 + SGTU R27, R9, R24 + OR R24, R28, R24 // h1.carry + ADDV $0x01, R24, R24 + ADDV R10, R24, R10 // h2 + + ADDV $16, R5, R5 // msg = msg[16:] + +multiply: + MULV R8, R11, R14 // h0r0.lo + MULHVU R8, R11, R15 // h0r0.hi + MULV R9, R11, R13 // h1r0.lo + MULHVU R9, R11, R16 // h1r0.hi + ADDV R13, R15, R15 + SGTU R13, R15, R24 + ADDV R24, R16, R16 + MULV R10, R11, R25 + ADDV R16, R25, R25 + MULV R8, R12, R13 // h0r1.lo + MULHVU R8, R12, R16 // h0r1.hi + ADDV R13, R15, R15 + SGTU R13, R15, R24 + ADDV R24, R16, R16 + MOVV R16, R8 + MULV R10, R12, R26 // h2r1 + MULV R9, R12, R13 // h1r1.lo + MULHVU R9, R12, R16 // h1r1.hi + ADDV R13, R25, R25 + ADDV R16, R26, R27 + SGTU R13, R25, R24 + ADDV R27, R24, R26 + ADDV R8, R25, R25 + SGTU R8, R25, R24 + ADDV R24, R26, R26 + AND $3, R25, R10 + AND $-4, R25, R17 + ADDV R17, R14, R8 + ADDV R26, R15, R27 + SGTU R17, R8, R24 + SGTU R26, R27, R28 + ADDV R27, R24, R9 + SGTU R27, R9, R24 + OR R24, R28, R24 + ADDV R24, R10, R10 + SLLV $62, R26, R27 + SRLV $2, R25, R28 + SRLV $2, R26, R26 + OR R27, R28, R25 + ADDV R25, R8, R8 + ADDV R26, R9, R27 + SGTU R25, R8, R24 + SGTU R26, R27, R28 + ADDV R27, R24, R9 + SGTU R27, R9, R24 + OR R24, R28, R24 + ADDV R24, R10, R10 + + SUBV $16, R6, R6 + BGE R6, R7, loop + +bytes_between_0_and_15: + BEQ R6, R0, done + MOVV $1, R14 + XOR R15, R15 + ADDV R6, R5, R5 + +flush_buffer: + MOVBU -1(R5), R25 + SRLV $56, R14, R24 + SLLV $8, R15, R28 + SLLV $8, R14, R14 + OR R24, R28, R15 + XOR R25, R14, R14 + SUBV $1, R6, R6 + SUBV $1, R5, R5 + BNE R6, R0, flush_buffer + + ADDV R14, R8, R8 + SGTU R14, R8, R24 + ADDV R15, R9, R27 + SGTU R15, R27, R28 + ADDV R27, R24, R9 + SGTU R27, R9, R24 + OR R24, R28, R24 + ADDV R10, R24, R10 + + MOVV $16, R6 + JMP multiply + +done: + MOVV R8, (R4) + MOVV R9, 8(R4) + MOVV R10, 16(R4) + RET diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.go deleted file mode 100644 index 1a1679a..0000000 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.go +++ /dev/null @@ -1,47 +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 gc && !purego && (ppc64 || ppc64le) - -package poly1305 - -//go:noescape -func update(state *macState, msg []byte) - -// mac is a wrapper for macGeneric that redirects calls that would have gone to -// updateGeneric to update. -// -// Its Write and Sum methods are otherwise identical to the macGeneric ones, but -// using function pointers would carry a major performance cost. -type mac struct{ macGeneric } - -func (h *mac) Write(p []byte) (int, error) { - nn := len(p) - if h.offset > 0 { - n := copy(h.buffer[h.offset:], p) - if h.offset+n < TagSize { - h.offset += n - return nn, nil - } - p = p[n:] - h.offset = 0 - update(&h.macState, h.buffer[:]) - } - if n := len(p) - (len(p) % TagSize); n > 0 { - update(&h.macState, p[:n]) - p = p[n:] - } - if len(p) > 0 { - h.offset += copy(h.buffer[h.offset:], p) - } - return nn, nil -} - -func (h *mac) Sum(out *[16]byte) { - state := h.macState - if h.offset > 0 { - update(&state, h.buffer[:h.offset]) - } - finalize(out, &state.h, &state.s) -} diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go index 3685b34..75df774 100644 --- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go +++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go @@ -3,6 +3,10 @@ // license that can be found in the LICENSE file. // Package salsa provides low-level access to functions in the Salsa family. +// +// Deprecated: this package exposes unsafe low-level operations. New applications +// should consider using the AEAD construction in golang.org/x/crypto/chacha20poly1305 +// instead. Existing users should migrate to golang.org/x/crypto/salsa20. package salsa import "math/bits" diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index 27d0e14..139fa31 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -20,14 +20,19 @@ import ( // returned by MultiAlgorithmSigner and don't appear in the Signature.Format // field. const ( - CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" - CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" - CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" - CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" - CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" - CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" + CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + CertAlgoDSAv01 = InsecureCertAlgoDSAv01 + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureCertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" + CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" + CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" + CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" + CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" // CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a // Certificate.Type (or PublicKey.Type), but only in @@ -228,7 +233,11 @@ func parseCert(in []byte, privAlgo string) (*Certificate, error) { if err != nil { return nil, err } - + // The Type() function is intended to return only certificate key types, but + // we use certKeyAlgoNames anyway for safety, to match [Certificate.Type]. + if _, ok := certKeyAlgoNames[k.Type()]; ok { + return nil, fmt.Errorf("ssh: the signature key type %q is invalid for certificates", k.Type()) + } c.SignatureKey = k c.Signature, rest, ok = parseSignatureBody(g.Signature) if !ok || len(rest) > 0 { @@ -296,16 +305,13 @@ type CertChecker struct { SupportedCriticalOptions []string // IsUserAuthority should return true if the key is recognized as an - // authority for the given user certificate. This allows for - // certificates to be signed by other certificates. This must be set - // if this CertChecker will be checking user certificates. + // authority for user certificate. This must be set if this CertChecker + // will be checking user certificates. IsUserAuthority func(auth PublicKey) bool // IsHostAuthority should report whether the key is recognized as - // an authority for this host. This allows for certificates to be - // signed by other keys, and for those other keys to only be valid - // signers for particular hostnames. This must be set if this - // CertChecker will be checking host certificates. + // an authority for this host. This must be set if this CertChecker + // will be checking host certificates. IsHostAuthority func(auth PublicKey, address string) bool // Clock is used for verifying time stamps. If nil, time.Now @@ -442,12 +448,19 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { // SignCert signs the certificate with an authority, setting the Nonce, // SignatureKey, and Signature fields. If the authority implements the // MultiAlgorithmSigner interface the first algorithm in the list is used. This -// is useful if you want to sign with a specific algorithm. +// is useful if you want to sign with a specific algorithm. As specified in +// [SSH-CERTS], Section 2.1.1, authority can't be a [Certificate]. func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { c.Nonce = make([]byte, 32) if _, err := io.ReadFull(rand, c.Nonce); err != nil { return err } + // The Type() function is intended to return only certificate key types, but + // we use certKeyAlgoNames anyway for safety, to match [Certificate.Type]. + if _, ok := certKeyAlgoNames[authority.PublicKey().Type()]; ok { + return fmt.Errorf("ssh: certificates cannot be used as authority (public key type %q)", + authority.PublicKey().Type()) + } c.SignatureKey = authority.PublicKey() if v, ok := authority.(MultiAlgorithmSigner); ok { @@ -485,16 +498,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { // // This map must be kept in sync with the one in agent/client.go. var certKeyAlgoNames = map[string]string{ - CertAlgoRSAv01: KeyAlgoRSA, - CertAlgoRSASHA256v01: KeyAlgoRSASHA256, - CertAlgoRSASHA512v01: KeyAlgoRSASHA512, - CertAlgoDSAv01: KeyAlgoDSA, - CertAlgoECDSA256v01: KeyAlgoECDSA256, - CertAlgoECDSA384v01: KeyAlgoECDSA384, - CertAlgoECDSA521v01: KeyAlgoECDSA521, - CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, - CertAlgoED25519v01: KeyAlgoED25519, - CertAlgoSKED25519v01: KeyAlgoSKED25519, + CertAlgoRSAv01: KeyAlgoRSA, + CertAlgoRSASHA256v01: KeyAlgoRSASHA256, + CertAlgoRSASHA512v01: KeyAlgoRSASHA512, + InsecureCertAlgoDSAv01: InsecureKeyAlgoDSA, + CertAlgoECDSA256v01: KeyAlgoECDSA256, + CertAlgoECDSA384v01: KeyAlgoECDSA384, + CertAlgoECDSA521v01: KeyAlgoECDSA521, + CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, + CertAlgoED25519v01: KeyAlgoED25519, + CertAlgoSKED25519v01: KeyAlgoSKED25519, } // underlyingAlgo returns the signature algorithm associated with algo (which is diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go index 741e984..7554ed5 100644 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/vendor/golang.org/x/crypto/ssh/cipher.go @@ -8,6 +8,7 @@ import ( "crypto/aes" "crypto/cipher" "crypto/des" + "crypto/fips140" "crypto/rc4" "crypto/subtle" "encoding/binary" @@ -15,6 +16,7 @@ import ( "fmt" "hash" "io" + "slices" "golang.org/x/crypto/chacha20" "golang.org/x/crypto/internal/poly1305" @@ -58,11 +60,11 @@ func newRC4(key, iv []byte) (cipher.Stream, error) { type cipherMode struct { keySize int ivSize int - create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) + create func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) } -func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { + return func(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { stream, err := createFunc(key, iv) if err != nil { return nil, err @@ -93,41 +95,41 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, } // cipherModes documents properties of supported ciphers. Ciphers not included -// are not supported and will not be negotiated, even if explicitly requested in -// ClientConfig.Crypto.Ciphers. -var cipherModes = map[string]*cipherMode{ - // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms - // are defined in the order specified in the RFC. - "aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, +// are not supported and will not be negotiated, even if explicitly configured. +// When FIPS mode is enabled, only FIPS-approved algorithms are included. +var cipherModes = map[string]*cipherMode{} - // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers. - // They are defined in the order specified in the RFC. - "arcfour128": {16, 0, streamCipherMode(1536, newRC4)}, - "arcfour256": {32, 0, streamCipherMode(1536, newRC4)}, +func init() { + cipherModes[CipherAES128CTR] = &cipherMode{16, aes.BlockSize, streamCipherMode(0, newAESCTR)} + cipherModes[CipherAES192CTR] = &cipherMode{24, aes.BlockSize, streamCipherMode(0, newAESCTR)} + cipherModes[CipherAES256CTR] = &cipherMode{32, aes.BlockSize, streamCipherMode(0, newAESCTR)} + // Use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, + // we'll wire it up to NewGCMForSSH in Go 1.26. + // + // For now it means we'll work with fips140=on but not fips140=only. + cipherModes[CipherAES128GCM] = &cipherMode{16, 12, newGCMCipher} + cipherModes[CipherAES256GCM] = &cipherMode{32, 12, newGCMCipher} - // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. - // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and - // RC4) has problems with weak keys, and should be used with caution." - // RFC 4345 introduces improved versions of Arcfour. - "arcfour": {16, 0, streamCipherMode(0, newRC4)}, - - // AEAD ciphers - gcm128CipherID: {16, 12, newGCMCipher}, - gcm256CipherID: {32, 12, newGCMCipher}, - chacha20Poly1305ID: {64, 0, newChaCha20Cipher}, + if fips140.Enabled() { + defaultCiphers = slices.DeleteFunc(defaultCiphers, func(algo string) bool { + _, ok := cipherModes[algo] + return !ok + }) + return + } + cipherModes[CipherChaCha20Poly1305] = &cipherMode{64, 0, newChaCha20Cipher} + // Insecure ciphers not included in the default configuration. + cipherModes[InsecureCipherRC4128] = &cipherMode{16, 0, streamCipherMode(1536, newRC4)} + cipherModes[InsecureCipherRC4256] = &cipherMode{32, 0, streamCipherMode(1536, newRC4)} + cipherModes[InsecureCipherRC4] = &cipherMode{16, 0, streamCipherMode(0, newRC4)} // CBC mode is insecure and so is not included in the default config. // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely // needed, it's possible to specify a custom Config to enable it. // You should expect that an active attacker can recover plaintext if // you do. - aes128cbcID: {16, aes.BlockSize, newAESCBCCipher}, - - // 3des-cbc is insecure and is not included in the default - // config. - tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher}, + cipherModes[InsecureCipherAES128CBC] = &cipherMode{16, aes.BlockSize, newAESCBCCipher} + cipherModes[InsecureCipherTripleDESCBC] = &cipherMode{24, des.BlockSize, newTripleDESCBCCipher} } // prefixLen is the length of the packet prefix that contains the packet length @@ -307,7 +309,7 @@ type gcmCipher struct { buf []byte } -func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -429,7 +431,7 @@ type cbcCipher struct { oracleCamouflage uint32 } -func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { cbc := &cbcCipher{ mac: macModes[algs.MAC].new(macKey), decrypter: cipher.NewCBCDecrypter(c, iv), @@ -443,7 +445,7 @@ func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorith return cbc, nil } -func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newAESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -457,7 +459,7 @@ func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCi return cbc, nil } -func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newTripleDESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := des.NewTripleDESCipher(key) if err != nil { return nil, err @@ -635,8 +637,6 @@ func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader return nil } -const chacha20Poly1305ID = "chacha20-poly1305@openssh.com" - // chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com // AEAD, which is described here: // @@ -650,7 +650,7 @@ type chacha20Poly1305Cipher struct { buf []byte } -func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { if len(key) != 64 { panic(len(key)) } diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go index fd8c497..3307978 100644 --- a/vendor/golang.org/x/crypto/ssh/client.go +++ b/vendor/golang.org/x/crypto/ssh/client.go @@ -110,6 +110,7 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e } c.sessionID = c.transport.getSessionID() + c.algorithms = c.transport.getAlgorithms() return c.clientAuthenticate(config) } diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index b86dde1..3127e49 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "slices" "strings" ) @@ -83,7 +84,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { // success return nil } else if ok == authFailure { - if m := auth.method(); !contains(tried, m) { + if m := auth.method(); !slices.Contains(tried, m) { tried = append(tried, m) } } @@ -97,7 +98,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { findNext: for _, a := range config.Auth { candidateMethod := a.method() - if contains(tried, candidateMethod) { + if slices.Contains(tried, candidateMethod) { continue } for _, meth := range methods { @@ -117,15 +118,6 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried) } -func contains(list []string, e string) bool { - for _, s := range list { - if s == e { - return true - } - } - return false -} - // An AuthMethod represents an instance of an RFC 4252 authentication method. type AuthMethod interface { // auth authenticates user over transport t. @@ -255,7 +247,7 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA // Fallback to use if there is no "server-sig-algs" extension or a // common algorithm cannot be found. We use the public key format if the // MultiAlgorithmSigner supports it, otherwise we return an error. - if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) { + if !slices.Contains(as.Algorithms(), underlyingAlgo(keyFormat)) { return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v", underlyingAlgo(keyFormat), keyFormat, as.Algorithms()) } @@ -284,12 +276,12 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA // Filter algorithms based on those supported by MultiAlgorithmSigner. var keyAlgos []string for _, algo := range algorithmsForKeyFormat(keyFormat) { - if contains(as.Algorithms(), underlyingAlgo(algo)) { + if slices.Contains(as.Algorithms(), underlyingAlgo(algo)) { keyAlgos = append(keyAlgos, algo) } } - algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos) + algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos, true) if err != nil { // If there is no overlap, return the fallback algorithm to support // servers that fail to list all supported algorithms. @@ -334,7 +326,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand // the key try to use the obtained algorithm as if "server-sig-algs" had // not been implemented if supported from the algorithm signer. if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 { - if contains(as.Algorithms(), KeyAlgoRSA) { + if slices.Contains(as.Algorithms(), KeyAlgoRSA) { // We retry using the compat algorithm after all signers have // been tried normally. signers = append(signers, &multiAlgorithmSigner{ @@ -385,7 +377,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand // contain the "publickey" method, do not attempt to authenticate with any // other keys. According to RFC 4252 Section 7, the latter can occur when // additional authentication methods are required. - if success == authSuccess || !contains(methods, cb.method()) { + if success == authSuccess || !slices.Contains(methods, cb.method()) { return success, methods, err } } @@ -434,7 +426,7 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) { // servers send the key type instead. OpenSSH allows any algorithm // that matches the public key, so we do the same. // https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709 - if !contains(algorithmsForKeyFormat(key.Type()), msg.Algo) { + if !slices.Contains(algorithmsForKeyFormat(key.Type()), msg.Algo) { return false, nil } if !bytes.Equal(msg.PubKey, pubKey) { diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go index 7e9c2cb..2e44e9c 100644 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ b/vendor/golang.org/x/crypto/ssh/common.go @@ -6,10 +6,12 @@ package ssh import ( "crypto" + "crypto/fips140" "crypto/rand" "fmt" "io" "math" + "slices" "sync" _ "crypto/sha1" @@ -24,88 +26,298 @@ const ( serviceSSH = "ssh-connection" ) -// supportedCiphers lists ciphers we support but might not recommend. -var supportedCiphers = []string{ - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "arcfour256", "arcfour128", "arcfour", - aes128cbcID, - tripledescbcID, +// The ciphers currently or previously implemented by this library, to use in +// [Config.Ciphers]. For a list, see the [Algorithms.Ciphers] returned by +// [SupportedAlgorithms] or [InsecureAlgorithms]. +const ( + CipherAES128GCM = "aes128-gcm@openssh.com" + CipherAES256GCM = "aes256-gcm@openssh.com" + CipherChaCha20Poly1305 = "chacha20-poly1305@openssh.com" + CipherAES128CTR = "aes128-ctr" + CipherAES192CTR = "aes192-ctr" + CipherAES256CTR = "aes256-ctr" + InsecureCipherAES128CBC = "aes128-cbc" + InsecureCipherTripleDESCBC = "3des-cbc" + InsecureCipherRC4 = "arcfour" + InsecureCipherRC4128 = "arcfour128" + InsecureCipherRC4256 = "arcfour256" +) + +// The key exchanges currently or previously implemented by this library, to use +// in [Config.KeyExchanges]. For a list, see the +// [Algorithms.KeyExchanges] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + InsecureKeyExchangeDH1SHA1 = "diffie-hellman-group1-sha1" + InsecureKeyExchangeDH14SHA1 = "diffie-hellman-group14-sha1" + KeyExchangeDH14SHA256 = "diffie-hellman-group14-sha256" + KeyExchangeDH16SHA512 = "diffie-hellman-group16-sha512" + KeyExchangeECDHP256 = "ecdh-sha2-nistp256" + KeyExchangeECDHP384 = "ecdh-sha2-nistp384" + KeyExchangeECDHP521 = "ecdh-sha2-nistp521" + KeyExchangeCurve25519 = "curve25519-sha256" + InsecureKeyExchangeDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" + KeyExchangeDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // KeyExchangeMLKEM768X25519 is supported from Go 1.24. + KeyExchangeMLKEM768X25519 = "mlkem768x25519-sha256" + + // An alias for KeyExchangeCurve25519SHA256. This kex ID will be added if + // KeyExchangeCurve25519SHA256 is requested for backward compatibility with + // OpenSSH versions up to 7.2. + keyExchangeCurve25519LibSSH = "curve25519-sha256@libssh.org" +) + +// The message authentication code (MAC) currently or previously implemented by +// this library, to use in [Config.MACs]. For a list, see the +// [Algorithms.MACs] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + HMACSHA256ETM = "hmac-sha2-256-etm@openssh.com" + HMACSHA512ETM = "hmac-sha2-512-etm@openssh.com" + HMACSHA256 = "hmac-sha2-256" + HMACSHA512 = "hmac-sha2-512" + HMACSHA1 = "hmac-sha1" + InsecureHMACSHA196 = "hmac-sha1-96" +) + +var ( + // supportedKexAlgos specifies key-exchange algorithms implemented by this + // package in preference order, excluding those with security issues. + supportedKexAlgos = []string{ + KeyExchangeMLKEM768X25519, + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + KeyExchangeDH16SHA512, + KeyExchangeDHGEXSHA256, + } + // defaultKexAlgos specifies the default preference for key-exchange + // algorithms in preference order. + defaultKexAlgos = []string{ + KeyExchangeMLKEM768X25519, + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + InsecureKeyExchangeDH14SHA1, + } + // insecureKexAlgos specifies key-exchange algorithms implemented by this + // package and which have security issues. + insecureKexAlgos = []string{ + InsecureKeyExchangeDH14SHA1, + InsecureKeyExchangeDH1SHA1, + InsecureKeyExchangeDHGEXSHA1, + } + // supportedCiphers specifies cipher algorithms implemented by this package + // in preference order, excluding those with security issues. + supportedCiphers = []string{ + CipherAES128GCM, + CipherAES256GCM, + CipherChaCha20Poly1305, + CipherAES128CTR, + CipherAES192CTR, + CipherAES256CTR, + } + // defaultCiphers specifies the default preference for ciphers algorithms + // in preference order. + defaultCiphers = supportedCiphers + // insecureCiphers specifies cipher algorithms implemented by this + // package and which have security issues. + insecureCiphers = []string{ + InsecureCipherAES128CBC, + InsecureCipherTripleDESCBC, + InsecureCipherRC4256, + InsecureCipherRC4128, + InsecureCipherRC4, + } + // supportedMACs specifies MAC algorithms implemented by this package in + // preference order, excluding those with security issues. + supportedMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + } + // defaultMACs specifies the default preference for MAC algorithms in + // preference order. + defaultMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + InsecureHMACSHA196, + } + // insecureMACs specifies MAC algorithms implemented by this + // package and which have security issues. + insecureMACs = []string{ + InsecureHMACSHA196, + } + // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. + // methods of authenticating servers) implemented by this package in + // preference order, excluding those with security issues. + supportedHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoED25519, + } + // defaultHostKeyAlgos specifies the default preference for host-key + // algorithms in preference order. + defaultHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + KeyAlgoED25519, + } + // insecureHostKeyAlgos specifies host-key algorithms implemented by this + // package and which have security issues. + insecureHostKeyAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + } + // supportedPubKeyAuthAlgos specifies the supported client public key + // authentication algorithms. Note that this doesn't include certificate + // types since those use the underlying algorithm. Order is irrelevant. + supportedPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + } + + // defaultPubKeyAuthAlgos specifies the preferred client public key + // authentication algorithms. This list is sent to the client if it supports + // the server-sig-algs extension. Order is irrelevant. + defaultPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } + // insecurePubKeyAuthAlgos specifies client public key authentication + // algorithms implemented by this package and which have security issues. + insecurePubKeyAuthAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } +) + +// NegotiatedAlgorithms defines algorithms negotiated between client and server. +type NegotiatedAlgorithms struct { + KeyExchange string + HostKey string + Read DirectionAlgorithms + Write DirectionAlgorithms } -// preferredCiphers specifies the default preference for ciphers. -var preferredCiphers = []string{ - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "aes128-ctr", "aes192-ctr", "aes256-ctr", +// Algorithms defines a set of algorithms that can be configured in the client +// or server config for negotiation during a handshake. +type Algorithms struct { + KeyExchanges []string + Ciphers []string + MACs []string + HostKeys []string + PublicKeyAuths []string } -// supportedKexAlgos specifies the supported key-exchange algorithms in -// preference order. -var supportedKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - // P384 and P521 are not constant-time yet, but since we don't - // reuse ephemeral keys, using them for ECDH should be OK. - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1, - kexAlgoDH1SHA1, +func init() { + if fips140.Enabled() { + defaultHostKeyAlgos = slices.DeleteFunc(defaultHostKeyAlgos, func(algo string) bool { + _, err := hashFunc(underlyingAlgo(algo)) + return err != nil + }) + defaultPubKeyAuthAlgos = slices.DeleteFunc(defaultPubKeyAuthAlgos, func(algo string) bool { + _, err := hashFunc(underlyingAlgo(algo)) + return err != nil + }) + } } -// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden -// for the server half. -var serverForbiddenKexAlgos = map[string]struct{}{ - kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests - kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests +func hashFunc(format string) (crypto.Hash, error) { + switch format { + case KeyAlgoRSASHA256, KeyAlgoECDSA256, KeyAlgoSKED25519, KeyAlgoSKECDSA256: + return crypto.SHA256, nil + case KeyAlgoECDSA384: + return crypto.SHA384, nil + case KeyAlgoRSASHA512, KeyAlgoECDSA521: + return crypto.SHA512, nil + case KeyAlgoED25519: + // KeyAlgoED25519 doesn't pre-hash. + return 0, nil + case KeyAlgoRSA, InsecureKeyAlgoDSA: + if fips140.Enabled() { + return 0, fmt.Errorf("ssh: hash algorithm for format %q not allowed in FIPS 140 mode", format) + } + return crypto.SHA1, nil + default: + return 0, fmt.Errorf("ssh: hash algorithm for format %q not mapped", format) + } } -// preferredKexAlgos specifies the default preference for key-exchange -// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm -// is disabled by default because it is a bit slower than the others. -var preferredKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH14SHA1, +// SupportedAlgorithms returns algorithms currently implemented by this package, +// excluding those with security issues, which are returned by +// InsecureAlgorithms. The algorithms listed here are in preference order. +func SupportedAlgorithms() Algorithms { + return Algorithms{ + Ciphers: slices.Clone(supportedCiphers), + MACs: slices.Clone(supportedMACs), + KeyExchanges: slices.Clone(supportedKexAlgos), + HostKeys: slices.Clone(supportedHostKeyAlgos), + PublicKeyAuths: slices.Clone(supportedPubKeyAuthAlgos), + } } -// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods -// of authenticating servers) in preference order. -var supportedHostKeyAlgos = []string{ - CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, - CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01, - - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, - KeyAlgoRSA, KeyAlgoDSA, - - KeyAlgoED25519, -} - -// supportedMACs specifies a default set of MAC algorithms in preference order. -// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed -// because they have reached the end of their useful life. -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96", +// InsecureAlgorithms returns algorithms currently implemented by this package +// and which have security issues. +func InsecureAlgorithms() Algorithms { + return Algorithms{ + KeyExchanges: slices.Clone(insecureKexAlgos), + Ciphers: slices.Clone(insecureCiphers), + MACs: slices.Clone(insecureMACs), + HostKeys: slices.Clone(insecureHostKeyAlgos), + PublicKeyAuths: slices.Clone(insecurePubKeyAuthAlgos), + } } var supportedCompressions = []string{compressionNone} -// hashFuncs keeps the mapping of supported signature algorithms to their -// respective hashes needed for signing and verification. -var hashFuncs = map[string]crypto.Hash{ - KeyAlgoRSA: crypto.SHA1, - KeyAlgoRSASHA256: crypto.SHA256, - KeyAlgoRSASHA512: crypto.SHA512, - KeyAlgoDSA: crypto.SHA1, - KeyAlgoECDSA256: crypto.SHA256, - KeyAlgoECDSA384: crypto.SHA384, - KeyAlgoECDSA521: crypto.SHA512, - // KeyAlgoED25519 doesn't pre-hash. - KeyAlgoSKECDSA256: crypto.SHA256, - KeyAlgoSKED25519: crypto.SHA256, -} - // algorithmsForKeyFormat returns the supported signature algorithms for a given // public key format (PublicKey.Type), in order of preference. See RFC 8332, // Section 2. See also the note in sendKexInit on backwards compatibility. @@ -120,11 +332,40 @@ func algorithmsForKeyFormat(keyFormat string) []string { } } +// keyFormatForAlgorithm returns the key format corresponding to the given +// signature algorithm. It returns an empty string if the signature algorithm is +// invalid or unsupported. +func keyFormatForAlgorithm(sigAlgo string) string { + switch sigAlgo { + case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512: + return KeyAlgoRSA + case CertAlgoRSAv01, CertAlgoRSASHA256v01, CertAlgoRSASHA512v01: + return CertAlgoRSAv01 + case KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + InsecureKeyAlgoDSA, + InsecureCertAlgoDSAv01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoSKECDSA256v01, + CertAlgoED25519v01, + CertAlgoSKED25519v01: + return sigAlgo + default: + return "" + } +} + // isRSA returns whether algo is a supported RSA algorithm, including certificate // algorithms. func isRSA(algo string) bool { algos := algorithmsForKeyFormat(KeyAlgoRSA) - return contains(algos, underlyingAlgo(algo)) + return slices.Contains(algos, underlyingAlgo(algo)) } func isRSACert(algo string) bool { @@ -135,18 +376,6 @@ func isRSACert(algo string) bool { return isRSA(algo) } -// supportedPubKeyAuthAlgos specifies the supported client public key -// authentication algorithms. Note that this doesn't include certificate types -// since those use the underlying algorithm. This list is sent to the client if -// it supports the server-sig-algs extension. Order is irrelevant. -var supportedPubKeyAuthAlgos = []string{ - KeyAlgoED25519, - KeyAlgoSKED25519, KeyAlgoSKECDSA256, - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA, - KeyAlgoDSA, -} - // unexpectedMessageError results when the SSH message that we received didn't // match what we wanted. func unexpectedMessageError(expected, got uint8) error { @@ -158,7 +387,7 @@ func parseError(tag uint8) error { return fmt.Errorf("ssh: parse error in message type %d", tag) } -func findCommon(what string, client []string, server []string) (common string, err error) { +func findCommon(what string, client []string, server []string, isClient bool) (string, error) { for _, c := range client { for _, s := range server { if c == s { @@ -166,23 +395,49 @@ func findCommon(what string, client []string, server []string) (common string, e } } } - return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server) + err := &AlgorithmNegotiationError{ + What: what, + } + if isClient { + err.SupportedAlgorithms = client + err.RequestedAlgorithms = server + } else { + err.SupportedAlgorithms = server + err.RequestedAlgorithms = client + } + return "", err } -// directionAlgorithms records algorithm choices in one direction (either read or write) -type directionAlgorithms struct { +// AlgorithmNegotiationError defines the error returned if the client and the +// server cannot agree on an algorithm for key exchange, host key, cipher, MAC. +type AlgorithmNegotiationError struct { + What string + // RequestedAlgorithms lists the algorithms supported by the peer. + RequestedAlgorithms []string + // SupportedAlgorithms lists the algorithms supported on our side. + SupportedAlgorithms []string +} + +func (a *AlgorithmNegotiationError) Error() string { + return fmt.Sprintf("ssh: no common algorithm for %s; we offered: %v, peer offered: %v", + a.What, a.SupportedAlgorithms, a.RequestedAlgorithms) +} + +// DirectionAlgorithms defines the algorithms negotiated in one direction +// (either read or write). +type DirectionAlgorithms struct { Cipher string MAC string - Compression string + compression string } // rekeyBytes returns a rekeying intervals in bytes. -func (a *directionAlgorithms) rekeyBytes() int64 { +func (a *DirectionAlgorithms) rekeyBytes() int64 { // According to RFC 4344 block ciphers should rekey after // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is // 128. switch a.Cipher { - case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID: + case CipherAES128CTR, CipherAES192CTR, CipherAES256CTR, CipherAES128GCM, CipherAES256GCM, InsecureCipherAES128CBC: return 16 * (1 << 32) } @@ -192,66 +447,59 @@ func (a *directionAlgorithms) rekeyBytes() int64 { } var aeadCiphers = map[string]bool{ - gcm128CipherID: true, - gcm256CipherID: true, - chacha20Poly1305ID: true, + CipherAES128GCM: true, + CipherAES256GCM: true, + CipherChaCha20Poly1305: true, } -type algorithms struct { - kex string - hostKey string - w directionAlgorithms - r directionAlgorithms -} +func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *NegotiatedAlgorithms, err error) { + result := &NegotiatedAlgorithms{} -func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) { - result := &algorithms{} - - result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) + result.KeyExchange, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos, isClient) if err != nil { return } - result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) + result.HostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos, isClient) if err != nil { return } - stoc, ctos := &result.w, &result.r + stoc, ctos := &result.Write, &result.Read if isClient { ctos, stoc = stoc, ctos } - ctos.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer) + ctos.Cipher, err = findCommon("client to server cipher", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer, isClient) if err != nil { return } - stoc.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient) + stoc.Cipher, err = findCommon("server to client cipher", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient, isClient) if err != nil { return } if !aeadCiphers[ctos.Cipher] { - ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer) + ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer, isClient) if err != nil { return } } if !aeadCiphers[stoc.Cipher] { - stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient) + stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient, isClient) if err != nil { return } } - ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) + ctos.compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer, isClient) if err != nil { return } - stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) + stoc.compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient, isClient) if err != nil { return } @@ -297,7 +545,7 @@ func (c *Config) SetDefaults() { c.Rand = rand.Reader } if c.Ciphers == nil { - c.Ciphers = preferredCiphers + c.Ciphers = defaultCiphers } var ciphers []string for _, c := range c.Ciphers { @@ -309,19 +557,22 @@ func (c *Config) SetDefaults() { c.Ciphers = ciphers if c.KeyExchanges == nil { - c.KeyExchanges = preferredKexAlgos + c.KeyExchanges = defaultKexAlgos } var kexs []string for _, k := range c.KeyExchanges { if kexAlgoMap[k] != nil { // Ignore the KEX if we have no kexAlgoMap definition. kexs = append(kexs, k) + if k == KeyExchangeCurve25519 && !slices.Contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) { + kexs = append(kexs, keyExchangeCurve25519LibSSH) + } } } c.KeyExchanges = kexs if c.MACs == nil { - c.MACs = supportedMACs + c.MACs = defaultMACs } var macs []string for _, m := range c.MACs { diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index 8f345ee..613a71a 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -74,6 +74,13 @@ type Conn interface { // Disconnect } +// AlgorithmsConnMetadata is a ConnMetadata that can return the algorithms +// negotiated between client and server. +type AlgorithmsConnMetadata interface { + ConnMetadata + Algorithms() NegotiatedAlgorithms +} + // DiscardRequests consumes and rejects all requests from the // passed-in channel. func DiscardRequests(in <-chan *Request) { @@ -106,6 +113,7 @@ type sshConn struct { sessionID []byte clientVersion []byte serverVersion []byte + algorithms NegotiatedAlgorithms } func dup(src []byte) []byte { @@ -141,3 +149,7 @@ func (c *sshConn) ClientVersion() []byte { func (c *sshConn) ServerVersion() []byte { return dup(c.serverVersion) } + +func (c *sshConn) Algorithms() NegotiatedAlgorithms { + return c.algorithms +} diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go index f5d352f..5b4de9e 100644 --- a/vendor/golang.org/x/crypto/ssh/doc.go +++ b/vendor/golang.org/x/crypto/ssh/doc.go @@ -16,8 +16,19 @@ References: [PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 + [SSH-CERTS]: https://datatracker.ietf.org/doc/html/draft-miller-ssh-cert-01 + [FIPS 140-3 mode]: https://go.dev/doc/security/fips140 This package does not fall under the stability promise of the Go language itself, so its API may be changed when pressing needs arise. + +# FIPS 140-3 mode + +When the program is in [FIPS 140-3 mode], this package behaves as if only SP +800-140C and SP 800-140D approved cipher suites, signature algorithms, +certificate public key types and sizes, and key exchange and derivation +algorithms were implemented. Others are silently ignored and not negotiated, or +rejected. This set may depend on the algorithms supported by the FIPS 140-3 Go +Cryptographic Module selected with GOFIPS140, and may change across Go versions. */ package ssh diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index c9202b0..4be3cbb 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -5,12 +5,12 @@ package ssh import ( - "crypto/rand" "errors" "fmt" "io" "log" "net" + "slices" "strings" "sync" ) @@ -39,7 +39,7 @@ type keyingTransport interface { // prepareKeyChange sets up a key change. The key change for a // direction will be effected if a msgNewKeys message is sent // or received. - prepareKeyChange(*algorithms, *kexResult) error + prepareKeyChange(*NegotiatedAlgorithms, *kexResult) error // setStrictMode sets the strict KEX mode, notably triggering // sequence number resets on sending or receiving msgNewKeys. @@ -116,7 +116,7 @@ type handshakeTransport struct { bannerCallback BannerCallback // Algorithms agreed in the last key exchange. - algorithms *algorithms + algorithms *NegotiatedAlgorithms // Counters exclusively owned by readLoop. readPacketsLeft uint32 @@ -165,7 +165,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt if config.HostKeyAlgorithms != nil { t.hostKeyAlgorithms = config.HostKeyAlgorithms } else { - t.hostKeyAlgorithms = supportedHostKeyAlgos + t.hostKeyAlgorithms = defaultHostKeyAlgos } go t.readLoop() go t.kexLoop() @@ -185,6 +185,10 @@ func (t *handshakeTransport) getSessionID() []byte { return t.sessionID } +func (t *handshakeTransport) getAlgorithms() NegotiatedAlgorithms { + return *t.algorithms +} + // waitSession waits for the session to be established. This should be // the first thing to call after instantiating handshakeTransport. func (t *handshakeTransport) waitSession() error { @@ -291,7 +295,7 @@ func (t *handshakeTransport) resetWriteThresholds() { if t.config.RekeyThreshold > 0 { t.writeBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.writeBytesLeft = t.algorithms.w.rekeyBytes() + t.writeBytesLeft = t.algorithms.Write.rekeyBytes() } else { t.writeBytesLeft = 1 << 30 } @@ -408,7 +412,7 @@ func (t *handshakeTransport) resetReadThresholds() { if t.config.RekeyThreshold > 0 { t.readBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.readBytesLeft = t.algorithms.r.rekeyBytes() + t.readBytesLeft = t.algorithms.Read.rekeyBytes() } else { t.readBytesLeft = 1 << 30 } @@ -501,7 +505,7 @@ func (t *handshakeTransport) sendKexInit() error { CompressionClientServer: supportedCompressions, CompressionServerClient: supportedCompressions, } - io.ReadFull(rand.Reader, msg.Cookie[:]) + io.ReadFull(t.config.Rand, msg.Cookie[:]) // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm, // and possibly to add the ext-info extension algorithm. Since the slice may be the @@ -524,7 +528,7 @@ func (t *handshakeTransport) sendKexInit() error { switch s := k.(type) { case MultiAlgorithmSigner: for _, algo := range algorithmsForKeyFormat(keyFormat) { - if contains(s.Algorithms(), underlyingAlgo(algo)) { + if slices.Contains(s.Algorithms(), underlyingAlgo(algo)) { msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo) } } @@ -676,7 +680,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { return err } - if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) { + if t.sessionID == nil && ((isClient && slices.Contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && slices.Contains(clientInit.KexAlgos, kexStrictClient))) { t.strictMode = true if err := t.conn.setStrictMode(); err != nil { return err @@ -701,9 +705,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { } } - kex, ok := kexAlgoMap[t.algorithms.kex] + kex, ok := kexAlgoMap[t.algorithms.KeyExchange] if !ok { - return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex) + return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.KeyExchange) } var result *kexResult @@ -733,7 +737,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO // message with the server-sig-algs extension if the client supports it. See // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9. - if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") { + if !isClient && firstKeyExchange && slices.Contains(clientInit.KexAlgos, "ext-info-c") { supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",") extInfo := &extInfoMsg{ NumExtensions: 2, @@ -787,7 +791,7 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { for _, k := range hostKeys { if s, ok := k.(MultiAlgorithmSigner); ok { - if !contains(s.Algorithms(), underlyingAlgo(algo)) { + if !slices.Contains(s.Algorithms(), underlyingAlgo(algo)) { continue } } @@ -810,12 +814,12 @@ func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { } func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) { - hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey) + hostKey := pickHostKey(t.hostKeys, t.algorithms.HostKey) if hostKey == nil { return nil, errors.New("ssh: internal error: negotiated unsupported signature type") } - r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey) + r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.HostKey) return r, err } @@ -830,7 +834,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) ( return nil, err } - if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil { + if err := verifyHostKeySignature(hostKey, t.algorithms.HostKey, result); err != nil { return nil, err } diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index 8a05f79..5f7fdd8 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -8,33 +8,31 @@ import ( "crypto" "crypto/ecdsa" "crypto/elliptic" + "crypto/fips140" "crypto/rand" - "crypto/subtle" "encoding/binary" "errors" "fmt" "io" "math/big" + "slices" "golang.org/x/crypto/curve25519" ) const ( - kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1" - kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1" - kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256" - kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512" - kexAlgoECDH256 = "ecdh-sha2-nistp256" - kexAlgoECDH384 = "ecdh-sha2-nistp384" - kexAlgoECDH521 = "ecdh-sha2-nistp521" - kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org" - kexAlgoCurve25519SHA256 = "curve25519-sha256" - - // For the following kex only the client half contains a production - // ready implementation. The server half only consists of a minimal - // implementation to satisfy the automated tests. - kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" - kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // This is the group called diffie-hellman-group1-sha1 in RFC 4253 and + // Oakley Group 2 in RFC 2409. + oakleyGroup2 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group14-sha1 in RFC 4253 and + // Oakley Group 14 in RFC 3526. + oakleyGroup14 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group15-sha512 in RFC 8268 and + // Oakley Group 15 in RFC 3526. + oakleyGroup15 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group16-sha512 in RFC 8268 and + // Oakley Group 16 in RFC 3526. + oakleyGroup16 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" ) // kexResult captures the outcome of a key exchange. @@ -399,56 +397,64 @@ func ecHash(curve elliptic.Curve) crypto.Hash { return crypto.SHA512 } +// kexAlgoMap defines the supported KEXs. KEXs not included are not supported +// and will not be negotiated, even if explicitly configured. When FIPS mode is +// enabled, only FIPS-approved algorithms are included. var kexAlgoMap = map[string]kexAlgorithm{} func init() { - // This is the group called diffie-hellman-group1-sha1 in - // RFC 4253 and Oakley Group 2 in RFC 2409. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) - kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ + // mlkem768x25519-sha256 we'll work with fips140=on but not fips140=only + // until Go 1.26. + kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{} + kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()} + kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()} + kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()} + + if fips140.Enabled() { + defaultKexAlgos = slices.DeleteFunc(defaultKexAlgos, func(algo string) bool { + _, ok := kexAlgoMap[algo] + return !ok + }) + return + } + + p, _ := new(big.Int).SetString(oakleyGroup2, 16) + kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA1, } - // This are the groups called diffie-hellman-group14-sha1 and - // diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268, - // and Oakley Group 14 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup14, 16) group14 := &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), } - kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ + kexAlgoMap[InsecureKeyExchangeDH14SHA1] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA1, } - kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{ + kexAlgoMap[KeyExchangeDH14SHA256] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA256, } - // This is the group called diffie-hellman-group16-sha512 in RFC - // 8268 and Oakley Group 16 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup16, 16) - kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{ + kexAlgoMap[KeyExchangeDH16SHA512] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA512, } - kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} - kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} - kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} - kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{} - kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{} - kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} - kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} + kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{} + kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{} + kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} + kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} } // curve25519sha256 implements the curve25519-sha256 (formerly known as @@ -464,15 +470,17 @@ func (kp *curve25519KeyPair) generate(rand io.Reader) error { if _, err := io.ReadFull(rand, kp.priv[:]); err != nil { return err } - curve25519.ScalarBaseMult(&kp.pub, &kp.priv) + p, err := curve25519.X25519(kp.priv[:], curve25519.Basepoint) + if err != nil { + return fmt.Errorf("curve25519: %w", err) + } + if len(p) != 32 { + return fmt.Errorf("curve25519: internal error: X25519 returned %d bytes, expected 32", len(p)) + } + copy(kp.pub[:], p) return nil } -// curve25519Zeros is just an array of 32 zero bytes so that we have something -// convenient to compare against in order to reject curve25519 points with the -// wrong order. -var curve25519Zeros [32]byte - func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { var kp curve25519KeyPair if err := kp.generate(rand); err != nil { @@ -495,11 +503,9 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh return nil, errors.New("ssh: peer's curve25519 public value has wrong length") } - var servPub, secret [32]byte - copy(servPub[:], reply.EphemeralPubKey) - curve25519.ScalarMult(&secret, &kp.priv, &servPub) - if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong order") + secret, err := curve25519.X25519(kp.priv[:], reply.EphemeralPubKey) + if err != nil { + return nil, fmt.Errorf("ssh: peer's curve25519 public value is not valid: %w", err) } h := crypto.SHA256.New() @@ -541,11 +547,9 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh return nil, err } - var clientPub, secret [32]byte - copy(clientPub[:], kexInit.ClientPubKey) - curve25519.ScalarMult(&secret, &kp.priv, &clientPub) - if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 { - return nil, errors.New("ssh: peer's curve25519 public value has wrong order") + secret, err := curve25519.X25519(kp.priv[:], kexInit.ClientPubKey) + if err != nil { + return nil, fmt.Errorf("ssh: peer's curve25519 public value is not valid: %w", err) } hostKeyBytes := priv.PublicKey().Marshal() @@ -601,9 +605,9 @@ const ( func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { // Send GexRequest kexDHGexRequest := kexDHGexRequestMsg{ - MinBits: dhGroupExchangeMinimumBits, - PreferedBits: dhGroupExchangePreferredBits, - MaxBits: dhGroupExchangeMaximumBits, + MinBits: dhGroupExchangeMinimumBits, + PreferredBits: dhGroupExchangePreferredBits, + MaxBits: dhGroupExchangeMaximumBits, } if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil { return nil, err @@ -690,9 +694,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak } // Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256. -// -// This is a minimal implementation to satisfy the automated tests. -func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { +func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { // Receive GexRequest packet, err := c.readPacket() if err != nil { @@ -702,13 +704,32 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake if err = Unmarshal(packet, &kexDHGexRequest); err != nil { return } + // We check that the request received is valid and that the MaxBits + // requested are at least equal to our supported minimum. This is the same + // check done in OpenSSH: + // https://github.com/openssh/openssh-portable/blob/80a2f64b/kexgexs.c#L94 + // + // Furthermore, we also check that the required MinBits are less than or + // equal to 4096 because we can use up to Oakley Group 16. + if kexDHGexRequest.MaxBits < kexDHGexRequest.MinBits || kexDHGexRequest.PreferredBits < kexDHGexRequest.MinBits || + kexDHGexRequest.MaxBits < kexDHGexRequest.PreferredBits || kexDHGexRequest.MaxBits < dhGroupExchangeMinimumBits || + kexDHGexRequest.MinBits > 4096 { + return nil, fmt.Errorf("ssh: DH GEX request out of range, min: %d, max: %d, preferred: %d", kexDHGexRequest.MinBits, + kexDHGexRequest.MaxBits, kexDHGexRequest.PreferredBits) + } + + var p *big.Int + // We hardcode sending Oakley Group 14 (2048 bits), Oakley Group 15 (3072 + // bits) or Oakley Group 16 (4096 bits), based on the requested max size. + if kexDHGexRequest.MaxBits < 3072 { + p, _ = new(big.Int).SetString(oakleyGroup14, 16) + } else if kexDHGexRequest.MaxBits < 4096 { + p, _ = new(big.Int).SetString(oakleyGroup15, 16) + } else { + p, _ = new(big.Int).SetString(oakleyGroup16, 16) + } - // Send GexGroup - // This is the group called diffie-hellman-group14-sha1 in RFC - // 4253 and Oakley Group 14 in RFC 3526. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) g := big.NewInt(2) - msg := &kexDHGexGroupMsg{ P: p, G: g, @@ -746,9 +767,9 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake h := gex.hashFunc.New() magics.write(h) writeString(h, hostKeyBytes) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits)) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MinBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.PreferredBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MaxBits) writeInt(h, p) writeInt(h, g) writeInt(h, kexDHGexInit.X) diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 98e6706..47a0753 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -27,6 +27,7 @@ import ( "fmt" "io" "math/big" + "slices" "strings" "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf" @@ -36,14 +37,19 @@ import ( // ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner // arguments. const ( - KeyAlgoRSA = "ssh-rsa" - KeyAlgoDSA = "ssh-dss" - KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" - KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" - KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" - KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" - KeyAlgoED25519 = "ssh-ed25519" - KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" + KeyAlgoRSA = "ssh-rsa" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + KeyAlgoDSA = InsecureKeyAlgoDSA + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureKeyAlgoDSA = "ssh-dss" + KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" + KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" + KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" + KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" + KeyAlgoED25519 = "ssh-ed25519" + KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not // public key formats, so they can't appear as a PublicKey.Type. The @@ -67,7 +73,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err switch algo { case KeyAlgoRSA: return parseRSA(in) - case KeyAlgoDSA: + case InsecureKeyAlgoDSA: return parseDSA(in) case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: return parseECDSA(in) @@ -77,13 +83,18 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err return parseED25519(in) case KeyAlgoSKED25519: return parseSKEd25519(in) - case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: + case CertAlgoRSAv01, InsecureCertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: cert, err := parseCert(in, certKeyAlgoNames[algo]) if err != nil { return nil, nil, err } return cert, nil, nil } + if keyFormat := keyFormatForAlgorithm(algo); keyFormat != "" { + return nil, nil, fmt.Errorf("ssh: signature algorithm %q isn't a key format; key is malformed and should be re-encoded with type %q", + algo, keyFormat) + } + return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo) } @@ -186,9 +197,10 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey return "", nil, nil, "", nil, io.EOF } -// ParseAuthorizedKey parses a public key from an authorized_keys -// file used in OpenSSH according to the sshd(8) manual page. +// ParseAuthorizedKey parses a public key from an authorized_keys file used in +// OpenSSH according to the sshd(8) manual page. Invalid lines are ignored. func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { + var lastErr error for len(in) > 0 { end := bytes.IndexByte(in, '\n') if end != -1 { @@ -217,6 +229,8 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { return out, comment, options, rest, nil + } else { + lastErr = err } // No key type recognised. Maybe there's an options field at @@ -259,16 +273,22 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str if out, comment, err = parseAuthorizedKey(in[i:]); err == nil { options = candidateOptions return out, comment, options, rest, nil + } else { + lastErr = err } in = rest continue } + if lastErr != nil { + return nil, "", nil, nil, fmt.Errorf("ssh: no key found; last parsing error for ignored line: %w", lastErr) + } + return nil, "", nil, nil, errors.New("ssh: no key found") } -// ParsePublicKey parses an SSH public key formatted for use in +// ParsePublicKey parses an SSH public key or certificate formatted for use in // the SSH wire protocol according to RFC 4253, section 6.6. func ParsePublicKey(in []byte) (out PublicKey, err error) { algo, in, ok := parseString(in) @@ -390,11 +410,11 @@ func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (Multi } for _, algo := range algorithms { - if !contains(supportedAlgos, algo) { + if !slices.Contains(supportedAlgos, algo) { return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q", algo, signer.PublicKey().Type()) } - if !contains(signerAlgos, algo) { + if !slices.Contains(signerAlgos, algo) { return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo) } } @@ -481,10 +501,13 @@ func (r *rsaPublicKey) Marshal() []byte { func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error { supportedAlgos := algorithmsForKeyFormat(r.Type()) - if !contains(supportedAlgos, sig.Format) { + if !slices.Contains(supportedAlgos, sig.Format) { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type()) } - hash := hashFuncs[sig.Format] + hash, err := hashFunc(sig.Format) + if err != nil { + return err + } h := hash.New() h.Write(data) digest := h.Sum(nil) @@ -601,7 +624,11 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - h := hashFuncs[sig.Format].New() + hash, err := hashFunc(sig.Format) + if err != nil { + return err + } + h := hash.New() h.Write(data) digest := h.Sum(nil) @@ -646,7 +673,11 @@ func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm) } - h := hashFuncs[k.PublicKey().Type()].New() + hash, err := hashFunc(k.PublicKey().Type()) + if err != nil { + return nil, err + } + h := hash.New() h.Write(data) digest := h.Sum(nil) r, s, err := dsa.Sign(rand, k.PrivateKey, digest) @@ -796,8 +827,11 @@ func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - - h := hashFuncs[sig.Format].New() + hash, err := hashFunc(sig.Format) + if err != nil { + return err + } + h := hash.New() h.Write(data) digest := h.Sum(nil) @@ -900,8 +934,11 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } - - h := hashFuncs[sig.Format].New() + hash, err := hashFunc(sig.Format) + if err != nil { + return err + } + h := hash.New() h.Write([]byte(k.application)) appDigest := h.Sum(nil) @@ -1004,7 +1041,11 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error { return fmt.Errorf("invalid size %d for Ed25519 public key", l) } - h := hashFuncs[sig.Format].New() + hash, err := hashFunc(sig.Format) + if err != nil { + return err + } + h := hash.New() h.Write([]byte(k.application)) appDigest := h.Sum(nil) @@ -1107,11 +1148,14 @@ func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm algorithm = s.pubKey.Type() } - if !contains(s.Algorithms(), algorithm) { + if !slices.Contains(s.Algorithms(), algorithm) { return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type()) } - hashFunc := hashFuncs[algorithm] + hashFunc, err := hashFunc(algorithm) + if err != nil { + return nil, err + } var digest []byte if hashFunc != 0 { h := hashFunc.New() @@ -1446,6 +1490,7 @@ type openSSHEncryptedPrivateKey struct { NumKeys uint32 PubKey []byte PrivKeyBlock []byte + Rest []byte `ssh:"rest"` } type openSSHPrivateKey struct { diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go index 06a1b27..87d626f 100644 --- a/vendor/golang.org/x/crypto/ssh/mac.go +++ b/vendor/golang.org/x/crypto/ssh/mac.go @@ -7,11 +7,13 @@ package ssh // Message authentication support import ( + "crypto/fips140" "crypto/hmac" "crypto/sha1" "crypto/sha256" "crypto/sha512" "hash" + "slices" ) type macMode struct { @@ -46,23 +48,37 @@ func (t truncatingMAC) Size() int { func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } -var macModes = map[string]*macMode{ - "hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash { +// macModes defines the supported MACs. MACs not included are not supported +// and will not be negotiated, even if explicitly configured. When FIPS mode is +// enabled, only FIPS-approved algorithms are included. +var macModes = map[string]*macMode{} + +func init() { + macModes[HMACSHA512ETM] = &macMode{64, true, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) - }}, - "hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash { + }} + macModes[HMACSHA256ETM] = &macMode{32, true, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) - }}, - "hmac-sha2-512": {64, false, func(key []byte) hash.Hash { + }} + macModes[HMACSHA512] = &macMode{64, false, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) - }}, - "hmac-sha2-256": {32, false, func(key []byte) hash.Hash { + }} + macModes[HMACSHA256] = &macMode{32, false, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) - }}, - "hmac-sha1": {20, false, func(key []byte) hash.Hash { + }} + + if fips140.Enabled() { + defaultMACs = slices.DeleteFunc(defaultMACs, func(algo string) bool { + _, ok := macModes[algo] + return !ok + }) + return + } + + macModes[HMACSHA1] = &macMode{20, false, func(key []byte) hash.Hash { return hmac.New(sha1.New, key) - }}, - "hmac-sha1-96": {20, false, func(key []byte) hash.Hash { + }} + macModes[InsecureHMACSHA196] = &macMode{20, false, func(key []byte) hash.Hash { return truncatingMAC{12, hmac.New(sha1.New, key)} - }}, + }} } diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index b55f860..ab22c3d 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -122,9 +122,9 @@ type kexDHGexReplyMsg struct { const msgKexDHGexRequest = 34 type kexDHGexRequestMsg struct { - MinBits uint32 `sshtype:"34"` - PreferedBits uint32 - MaxBits uint32 + MinBits uint32 `sshtype:"34"` + PreferredBits uint32 + MaxBits uint32 } // See RFC 4253, section 10. @@ -792,7 +792,7 @@ func marshalString(to []byte, s []byte) []byte { return to[len(s):] } -var bigIntType = reflect.TypeOf((*big.Int)(nil)) +var bigIntType = reflect.TypeFor[*big.Int]() // Decode a packet into its corresponding message. func decode(packet []byte) (interface{}, error) { @@ -818,6 +818,8 @@ func decode(packet []byte) (interface{}, error) { return new(userAuthSuccessMsg), nil case msgUserAuthFailure: msg = new(userAuthFailureMsg) + case msgUserAuthBanner: + msg = new(userAuthBannerMsg) case msgUserAuthPubKeyOk: msg = new(userAuthPubKeyOkMsg) case msgGlobalRequest: diff --git a/vendor/golang.org/x/crypto/ssh/mlkem.go b/vendor/golang.org/x/crypto/ssh/mlkem.go new file mode 100644 index 0000000..ddc0ed1 --- /dev/null +++ b/vendor/golang.org/x/crypto/ssh/mlkem.go @@ -0,0 +1,168 @@ +// Copyright 2024 The Go 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 ssh + +import ( + "crypto" + "crypto/mlkem" + "crypto/sha256" + "errors" + "fmt" + "io" + + "golang.org/x/crypto/curve25519" +) + +// mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with +// curve25519-sha256 key exchange method, as described by +// draft-kampanakis-curdle-ssh-pq-ke-05 section 2.3.3. +type mlkem768WithCurve25519sha256 struct{} + +func (kex *mlkem768WithCurve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) { + var c25519kp curve25519KeyPair + if err := c25519kp.generate(rand); err != nil { + return nil, err + } + + seed := make([]byte, mlkem.SeedSize) + if _, err := io.ReadFull(rand, seed); err != nil { + return nil, err + } + + mlkemDk, err := mlkem.NewDecapsulationKey768(seed) + if err != nil { + return nil, err + } + + hybridKey := append(mlkemDk.EncapsulationKey().Bytes(), c25519kp.pub[:]...) + if err := c.writePacket(Marshal(&kexECDHInitMsg{hybridKey})); err != nil { + return nil, err + } + + packet, err := c.readPacket() + if err != nil { + return nil, err + } + + var reply kexECDHReplyMsg + if err = Unmarshal(packet, &reply); err != nil { + return nil, err + } + + if len(reply.EphemeralPubKey) != mlkem.CiphertextSize768+32 { + return nil, errors.New("ssh: peer's mlkem768x25519 public value has wrong length") + } + + // Perform KEM decapsulate operation to obtain shared key from ML-KEM. + mlkem768Secret, err := mlkemDk.Decapsulate(reply.EphemeralPubKey[:mlkem.CiphertextSize768]) + if err != nil { + return nil, err + } + + // Complete Curve25519 ECDH to obtain its shared key. + c25519Secret, err := curve25519.X25519(c25519kp.priv[:], reply.EphemeralPubKey[mlkem.CiphertextSize768:]) + if err != nil { + return nil, fmt.Errorf("ssh: peer's mlkem768x25519 public value is not valid: %w", err) + } + // Compute actual shared key. + h := sha256.New() + h.Write(mlkem768Secret) + h.Write(c25519Secret) + secret := h.Sum(nil) + + h.Reset() + magics.write(h) + writeString(h, reply.HostKey) + writeString(h, hybridKey) + writeString(h, reply.EphemeralPubKey) + + K := make([]byte, stringLength(len(secret))) + marshalString(K, secret) + h.Write(K) + + return &kexResult{ + H: h.Sum(nil), + K: K, + HostKey: reply.HostKey, + Signature: reply.Signature, + Hash: crypto.SHA256, + }, nil +} + +func (kex *mlkem768WithCurve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (*kexResult, error) { + packet, err := c.readPacket() + if err != nil { + return nil, err + } + + var kexInit kexECDHInitMsg + if err = Unmarshal(packet, &kexInit); err != nil { + return nil, err + } + + if len(kexInit.ClientPubKey) != mlkem.EncapsulationKeySize768+32 { + return nil, errors.New("ssh: peer's ML-KEM768/curve25519 public value has wrong length") + } + + encapsulationKey, err := mlkem.NewEncapsulationKey768(kexInit.ClientPubKey[:mlkem.EncapsulationKeySize768]) + if err != nil { + return nil, fmt.Errorf("ssh: peer's ML-KEM768 encapsulation key is not valid: %w", err) + } + // Perform KEM encapsulate operation to obtain ciphertext and shared key. + mlkem768Secret, mlkem768Ciphertext := encapsulationKey.Encapsulate() + + // Perform server side of Curve25519 ECDH to obtain server public value and + // shared key. + var c25519kp curve25519KeyPair + if err := c25519kp.generate(rand); err != nil { + return nil, err + } + c25519Secret, err := curve25519.X25519(c25519kp.priv[:], kexInit.ClientPubKey[mlkem.EncapsulationKeySize768:]) + if err != nil { + return nil, fmt.Errorf("ssh: peer's ML-KEM768/curve25519 public value is not valid: %w", err) + } + hybridKey := append(mlkem768Ciphertext, c25519kp.pub[:]...) + + // Compute actual shared key. + h := sha256.New() + h.Write(mlkem768Secret) + h.Write(c25519Secret) + secret := h.Sum(nil) + + hostKeyBytes := priv.PublicKey().Marshal() + + h.Reset() + magics.write(h) + writeString(h, hostKeyBytes) + writeString(h, kexInit.ClientPubKey) + writeString(h, hybridKey) + + K := make([]byte, stringLength(len(secret))) + marshalString(K, secret) + h.Write(K) + + H := h.Sum(nil) + + sig, err := signAndMarshal(priv, rand, H, algo) + if err != nil { + return nil, err + } + + reply := kexECDHReplyMsg{ + EphemeralPubKey: hybridKey, + HostKey: hostKeyBytes, + Signature: sig, + } + if err := c.writePacket(Marshal(&reply)); err != nil { + return nil, err + } + return &kexResult{ + H: H, + K: K, + HostKey: hostKeyBytes, + Signature: sig, + Hash: crypto.SHA256, + }, nil +} diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 1839ddc..064dcba 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "net" + "slices" "strings" ) @@ -43,6 +44,9 @@ type Permissions struct { // pass data from the authentication callbacks to the server // application layer. Extensions map[string]string + + // ExtraData allows to store user defined data. + ExtraData map[any]any } type GSSAPIWithMICConfig struct { @@ -126,6 +130,21 @@ type ServerConfig struct { // Permissions.Extensions entry. PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) + // VerifiedPublicKeyCallback, if non-nil, is called after a client + // successfully confirms having control over a key that was previously + // approved by PublicKeyCallback. The permissions object passed to the + // callback is the one returned by PublicKeyCallback for the given public + // key and its ownership is transferred to the callback. The returned + // Permissions object can be the same object, optionally modified, or a + // completely new object. If VerifiedPublicKeyCallback is non-nil, + // PublicKeyCallback is not allowed to return a PartialSuccessError, which + // can instead be returned by VerifiedPublicKeyCallback. + // + // VerifiedPublicKeyCallback does not affect which authentication methods + // are included in the list of methods that can be attempted by the client. + VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions, + signatureAlgorithm string) (*Permissions, error) + // KeyboardInteractiveCallback, if non-nil, is called when // keyboard-interactive authentication is selected (RFC // 4256). The client object's Challenge function should be @@ -243,22 +262,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha fullConf.MaxAuthTries = 6 } if len(fullConf.PublicKeyAuthAlgorithms) == 0 { - fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos + fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos } else { for _, algo := range fullConf.PublicKeyAuthAlgorithms { - if !contains(supportedPubKeyAuthAlgos, algo) { + if !slices.Contains(SupportedAlgorithms().PublicKeyAuths, algo) && !slices.Contains(InsecureAlgorithms().PublicKeyAuths, algo) { c.Close() return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) } } } - // Check if the config contains any unsupported key exchanges - for _, kex := range fullConf.KeyExchanges { - if _, ok := serverForbiddenKexAlgos[kex]; ok { - c.Close() - return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex) - } - } s := &connection{ sshConn: sshConn{conn: c}, @@ -315,6 +327,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) // We just did the key change, so the session ID is established. s.sessionID = s.transport.getSessionID() + s.algorithms = s.transport.getAlgorithms() var packet []byte if packet, err = s.transport.readPacket(); err != nil { @@ -637,7 +650,7 @@ userAuthLoop: return nil, parseError(msgUserAuthRequest) } algo := string(algoBytes) - if !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) { + if !slices.Contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) { authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo) break } @@ -658,6 +671,9 @@ userAuthLoop: candidate.pubKeyData = pubKeyData candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey) _, isPartialSuccessError := candidate.result.(*PartialSuccessError) + if isPartialSuccessError && config.VerifiedPublicKeyCallback != nil { + return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined") + } if (candidate.result == nil || isPartialSuccessError) && candidate.perms != nil && @@ -701,7 +717,7 @@ userAuthLoop: // ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public // key type. The algorithm and public key type must be // consistent: both must be certificate algorithms, or neither. - if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) { + if !slices.Contains(algorithmsForKeyFormat(pubKey.Type()), algo) { authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q", pubKey.Type(), algo) break @@ -711,7 +727,7 @@ userAuthLoop: // algorithm name that corresponds to algo with // sig.Format. This is usually the same, but // for certs, the names differ. - if !contains(config.PublicKeyAuthAlgorithms, sig.Format) { + if !slices.Contains(config.PublicKeyAuthAlgorithms, sig.Format) { authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format) break } @@ -728,6 +744,12 @@ userAuthLoop: authErr = candidate.result perms = candidate.perms + if authErr == nil && config.VerifiedPublicKeyCallback != nil { + // Only call VerifiedPublicKeyCallback after the key has been accepted + // and successfully verified. If authErr is non-nil, the key is not + // considered verified and the callback must not run. + perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo) + } } case "gssapi-with-mic": if authConfig.GSSAPIWithMICConfig == nil { diff --git a/vendor/golang.org/x/crypto/ssh/ssh_gss.go b/vendor/golang.org/x/crypto/ssh/ssh_gss.go index 24bd7c8..a6249a1 100644 --- a/vendor/golang.org/x/crypto/ssh/ssh_gss.go +++ b/vendor/golang.org/x/crypto/ssh/ssh_gss.go @@ -106,6 +106,13 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) { if !ok { return nil, errors.New("parse uint32 failed") } + // Each ASN.1 encoded OID must have a minimum + // of 2 bytes; 64 maximum mechanisms is an + // arbitrary, but reasonable ceiling. + const maxMechs = 64 + if n > maxMechs || int(n)*2 > len(rest) { + return nil, errors.New("invalid mechanism count") + } s := &userAuthRequestGSSAPI{ N: n, OIDS: make([]asn1.ObjectIdentifier, n), @@ -122,7 +129,6 @@ func parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) { if rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil { return nil, err } - } return s, nil } diff --git a/vendor/golang.org/x/crypto/ssh/streamlocal.go b/vendor/golang.org/x/crypto/ssh/streamlocal.go index b171b33..152470f 100644 --- a/vendor/golang.org/x/crypto/ssh/streamlocal.go +++ b/vendor/golang.org/x/crypto/ssh/streamlocal.go @@ -44,7 +44,7 @@ func (c *Client) ListenUnix(socketPath string) (net.Listener, error) { if !ok { return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer") } - ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"}) + ch := c.forwards.add("unix", socketPath) return &unixListener{socketPath, c, ch}, nil } @@ -96,7 +96,7 @@ func (l *unixListener) Accept() (net.Conn, error) { // Close closes the listener. func (l *unixListener) Close() error { // this also closes the listener. - l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"}) + l.conn.forwards.remove("unix", l.socketPath) m := streamLocalChannelForwardMsg{ l.socketPath, } diff --git a/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go index ef5059a..78c41fe 100644 --- a/vendor/golang.org/x/crypto/ssh/tcpip.go +++ b/vendor/golang.org/x/crypto/ssh/tcpip.go @@ -11,6 +11,7 @@ import ( "io" "math/rand" "net" + "net/netip" "strconv" "strings" "sync" @@ -22,14 +23,21 @@ import ( // the returned net.Listener. The listener must be serviced, or the // SSH connection may hang. // N must be "tcp", "tcp4", "tcp6", or "unix". +// +// If the address is a hostname, it is sent to the remote peer as-is, without +// being resolved locally, and the Listener Addr method will return a zero IP. func (c *Client) Listen(n, addr string) (net.Listener, error) { switch n { case "tcp", "tcp4", "tcp6": - laddr, err := net.ResolveTCPAddr(n, addr) + host, portStr, err := net.SplitHostPort(addr) if err != nil { return nil, err } - return c.ListenTCP(laddr) + port, err := strconv.ParseInt(portStr, 10, 32) + if err != nil { + return nil, err + } + return c.listenTCPInternal(host, int(port)) case "unix": return c.ListenUnix(addr) default: @@ -102,15 +110,24 @@ func (c *Client) handleForwards() { // ListenTCP requests the remote peer open a listening socket // on laddr. Incoming connections will be available by calling // Accept on the returned net.Listener. +// +// ListenTCP accepts an IP address, to provide a hostname use [Client.Listen] +// with "tcp", "tcp4", or "tcp6" network instead. func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { c.handleForwardsOnce.Do(c.handleForwards) if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) { return c.autoPortListenWorkaround(laddr) } + return c.listenTCPInternal(laddr.IP.String(), laddr.Port) +} + +func (c *Client) listenTCPInternal(host string, port int) (net.Listener, error) { + c.handleForwardsOnce.Do(c.handleForwards) + m := channelForwardMsg{ - laddr.IP.String(), - uint32(laddr.Port), + host, + uint32(port), } // send message ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m)) @@ -123,20 +140,33 @@ func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) { // If the original port was 0, then the remote side will // supply a real port number in the response. - if laddr.Port == 0 { + if port == 0 { var p struct { Port uint32 } if err := Unmarshal(resp, &p); err != nil { return nil, err } - laddr.Port = int(p.Port) + port = int(p.Port) } + // Construct a local address placeholder for the remote listener. If the + // original host is an IP address, preserve it so that Listener.Addr() + // reports the same IP. If the host is a hostname or cannot be parsed as an + // IP, fall back to IPv4zero. The port field is always set, even if the + // original port was 0, because in that case the remote server will assign + // one, allowing callers to determine which port was selected. + ip := net.IPv4zero + if parsed, err := netip.ParseAddr(host); err == nil { + ip = net.IP(parsed.AsSlice()) + } + laddr := &net.TCPAddr{ + IP: ip, + Port: port, + } + addr := net.JoinHostPort(host, strconv.FormatInt(int64(port), 10)) + ch := c.forwards.add("tcp", addr) - // Register this forward, using the port number we obtained. - ch := c.forwards.add(laddr) - - return &tcpListener{laddr, c, ch}, nil + return &tcpListener{laddr, addr, c, ch}, nil } // forwardList stores a mapping between remote @@ -149,8 +179,9 @@ type forwardList struct { // forwardEntry represents an established mapping of a laddr on a // remote ssh server to a channel connected to a tcpListener. type forwardEntry struct { - laddr net.Addr - c chan forward + addr string // host:port or socket path + network string // tcp or unix + c chan forward } // forward represents an incoming forwarded tcpip connection. The @@ -161,12 +192,13 @@ type forward struct { raddr net.Addr // the raddr of the incoming connection } -func (l *forwardList) add(addr net.Addr) chan forward { +func (l *forwardList) add(n, addr string) chan forward { l.Lock() defer l.Unlock() f := forwardEntry{ - laddr: addr, - c: make(chan forward, 1), + addr: addr, + network: n, + c: make(chan forward, 1), } l.entries = append(l.entries, f) return f.c @@ -185,19 +217,20 @@ func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) { if port == 0 || port > 65535 { return nil, fmt.Errorf("ssh: port number out of range: %d", port) } - ip := net.ParseIP(string(addr)) - if ip == nil { + ip, err := netip.ParseAddr(addr) + if err != nil { return nil, fmt.Errorf("ssh: cannot parse IP address %q", addr) } - return &net.TCPAddr{IP: ip, Port: int(port)}, nil + return &net.TCPAddr{IP: net.IP(ip.AsSlice()), Port: int(port)}, nil } func (l *forwardList) handleChannels(in <-chan NewChannel) { for ch := range in { var ( - laddr net.Addr - raddr net.Addr - err error + addr string + network string + raddr net.Addr + err error ) switch channelType := ch.ChannelType(); channelType { case "forwarded-tcpip": @@ -207,40 +240,34 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) { continue } - // RFC 4254 section 7.2 specifies that incoming - // addresses should list the address, in string - // format. It is implied that this should be an IP - // address, as it would be impossible to connect to it - // otherwise. - laddr, err = parseTCPAddr(payload.Addr, payload.Port) - if err != nil { - ch.Reject(ConnectionFailed, err.Error()) - continue - } + // RFC 4254 section 7.2 specifies that incoming addresses should + // list the address that was connected, in string format. It is the + // same address used in the tcpip-forward request. The originator + // address is an IP address instead. + addr = net.JoinHostPort(payload.Addr, strconv.FormatUint(uint64(payload.Port), 10)) + raddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort) if err != nil { ch.Reject(ConnectionFailed, err.Error()) continue } - + network = "tcp" case "forwarded-streamlocal@openssh.com": var payload forwardedStreamLocalPayload if err = Unmarshal(ch.ExtraData(), &payload); err != nil { ch.Reject(ConnectionFailed, "could not parse forwarded-streamlocal@openssh.com payload: "+err.Error()) continue } - laddr = &net.UnixAddr{ - Name: payload.SocketPath, - Net: "unix", - } + addr = payload.SocketPath raddr = &net.UnixAddr{ Name: "@", Net: "unix", } + network = "unix" default: panic(fmt.Errorf("ssh: unknown channel type %s", channelType)) } - if ok := l.forward(laddr, raddr, ch); !ok { + if ok := l.forward(network, addr, raddr, ch); !ok { // Section 7.2, implementations MUST reject spurious incoming // connections. ch.Reject(Prohibited, "no forward for address") @@ -252,11 +279,11 @@ func (l *forwardList) handleChannels(in <-chan NewChannel) { // remove removes the forward entry, and the channel feeding its // listener. -func (l *forwardList) remove(addr net.Addr) { +func (l *forwardList) remove(n, addr string) { l.Lock() defer l.Unlock() for i, f := range l.entries { - if addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() { + if n == f.network && addr == f.addr { l.entries = append(l.entries[:i], l.entries[i+1:]...) close(f.c) return @@ -274,11 +301,11 @@ func (l *forwardList) closeAll() { l.entries = nil } -func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool { +func (l *forwardList) forward(n, addr string, raddr net.Addr, ch NewChannel) bool { l.Lock() defer l.Unlock() for _, f := range l.entries { - if laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() { + if n == f.network && addr == f.addr { f.c <- forward{newCh: ch, raddr: raddr} return true } @@ -288,6 +315,7 @@ func (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool { type tcpListener struct { laddr *net.TCPAddr + addr string conn *Client in <-chan forward @@ -314,13 +342,21 @@ func (l *tcpListener) Accept() (net.Conn, error) { // Close closes the listener. func (l *tcpListener) Close() error { + host, port, err := net.SplitHostPort(l.addr) + if err != nil { + return err + } + rport, err := strconv.ParseUint(port, 10, 32) + if err != nil { + return err + } m := channelForwardMsg{ - l.laddr.IP.String(), - uint32(l.laddr.Port), + host, + uint32(rport), } // this also closes the listener. - l.conn.forwards.remove(l.laddr) + l.conn.forwards.remove("tcp", l.addr) ok, _, err := l.conn.SendRequest("cancel-tcpip-forward", true, Marshal(&m)) if err == nil && !ok { err = errors.New("ssh: cancel-tcpip-forward failed") @@ -459,7 +495,7 @@ func (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel return nil, err } go DiscardRequests(in) - return ch, err + return ch, nil } type tcpChan struct { diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go index 0424d2d..fa3dd6a 100644 --- a/vendor/golang.org/x/crypto/ssh/transport.go +++ b/vendor/golang.org/x/crypto/ssh/transport.go @@ -8,6 +8,7 @@ import ( "bufio" "bytes" "errors" + "fmt" "io" "log" ) @@ -16,13 +17,6 @@ import ( // wire. No message decoding is done, to minimize the impact on timing. const debugTransport = false -const ( - gcm128CipherID = "aes128-gcm@openssh.com" - gcm256CipherID = "aes256-gcm@openssh.com" - aes128cbcID = "aes128-cbc" - tripledescbcID = "3des-cbc" -) - // packetConn represents a transport that implements packet based // operations. type packetConn interface { @@ -92,14 +86,14 @@ func (t *transport) setInitialKEXDone() { // prepareKeyChange sets up key material for a keychange. The key changes in // both directions are triggered by reading and writing a msgNewKey packet // respectively. -func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error { - ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult) +func (t *transport) prepareKeyChange(algs *NegotiatedAlgorithms, kexResult *kexResult) error { + ciph, err := newPacketCipher(t.reader.dir, algs.Read, kexResult) if err != nil { return err } t.reader.pendingKeyChange <- ciph - ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult) + ciph, err = newPacketCipher(t.writer.dir, algs.Write, kexResult) if err != nil { return err } @@ -259,8 +253,11 @@ var ( // setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as // described in RFC 4253, section 6.4. direction should either be serverKeys // (to setup server->client keys) or clientKeys (for client->server keys). -func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) { +func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) { cipherMode := cipherModes[algs.Cipher] + if cipherMode == nil { + return nil, fmt.Errorf("ssh: unsupported cipher %v", algs.Cipher) + } iv := make([]byte, cipherMode.ivSize) key := make([]byte, cipherMode.keySize) diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go index a9392af..9d260ba 100644 --- a/vendor/golang.org/x/exp/constraints/constraints.go +++ b/vendor/golang.org/x/exp/constraints/constraints.go @@ -6,6 +6,8 @@ // with type parameters. package constraints +import "cmp" + // Signed is a constraint that permits any signed integer type. // If future releases of Go add new predeclared signed integer types, // this constraint will be modified to include them. @@ -47,6 +49,6 @@ type Complex interface { // this constraint will be modified to include them. // // This type is redundant since Go 1.21 introduced [cmp.Ordered]. -type Ordered interface { - Integer | Float | ~string -} +// +//go:fix inline +type Ordered = cmp.Ordered diff --git a/vendor/golang.org/x/exp/maps/maps.go b/vendor/golang.org/x/exp/maps/maps.go index c25939b..4a9747e 100644 --- a/vendor/golang.org/x/exp/maps/maps.go +++ b/vendor/golang.org/x/exp/maps/maps.go @@ -7,17 +7,13 @@ package maps import "maps" -// TODO(adonovan): when https://go.dev/issue/32816 is accepted, all of -// these functions except Keys and Values should be annotated -// (provisionally with "//go:fix inline") so that tools can safely and -// automatically replace calls to exp/maps with calls to std maps by -// inlining them. - // Keys returns the keys of the map m. // The keys will be in an indeterminate order. +// +// The simplest true equivalent using the standard library is: +// +// slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m)) func Keys[M ~map[K]V, K comparable, V any](m M) []K { - // The simplest true equivalent using std is: - // return slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m)). r := make([]K, 0, len(m)) for k := range m { @@ -28,9 +24,11 @@ func Keys[M ~map[K]V, K comparable, V any](m M) []K { // Values returns the values of the map m. // The values will be in an indeterminate order. +// +// The simplest true equivalent using the standard library is: +// +// slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m)) func Values[M ~map[K]V, K comparable, V any](m M) []V { - // The simplest true equivalent using std is: - // return slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m)). r := make([]V, 0, len(m)) for _, v := range m { @@ -41,23 +39,31 @@ func Values[M ~map[K]V, K comparable, V any](m M) []V { // Equal reports whether two maps contain the same key/value pairs. // Values are compared using ==. +// +//go:fix inline func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool { return maps.Equal(m1, m2) } // EqualFunc is like Equal, but compares values using eq. // Keys are still compared with ==. +// +//go:fix inline func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool { return maps.EqualFunc(m1, m2, eq) } // Clear removes all entries from m, leaving it empty. +// +//go:fix inline func Clear[M ~map[K]V, K comparable, V any](m M) { clear(m) } // Clone returns a copy of m. This is a shallow clone: // the new keys and values are set using ordinary assignment. +// +//go:fix inline func Clone[M ~map[K]V, K comparable, V any](m M) M { return maps.Clone(m) } @@ -66,11 +72,15 @@ func Clone[M ~map[K]V, K comparable, V any](m M) M { // When a key in src is already present in dst, // the value in dst will be overwritten by the value associated // with the key in src. +// +//go:fix inline func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) { maps.Copy(dst, src) } // DeleteFunc deletes any key/value pairs from m for which del returns true. +// +//go:fix inline func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) { maps.DeleteFunc(m, del) } diff --git a/vendor/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS deleted file mode 100644 index 7330990..0000000 --- a/vendor/golang.org/x/mod/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -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/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go deleted file mode 100644 index 9a2dfd3..0000000 --- a/vendor/golang.org/x/mod/semver/semver.go +++ /dev/null @@ -1,401 +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. - -// Package semver implements comparison of semantic version strings. -// In this package, semantic version strings must begin with a leading "v", -// as in "v1.0.0". -// -// The general form of a semantic version string accepted by this package is -// -// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] -// -// where square brackets indicate optional parts of the syntax; -// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; -// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers -// using only alphanumeric characters and hyphens; and -// all-numeric PRERELEASE identifiers must not have leading zeros. -// -// This package follows Semantic Versioning 2.0.0 (see semver.org) -// with two exceptions. First, it requires the "v" prefix. Second, it recognizes -// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) -// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. -package semver - -import "sort" - -// parsed returns the parsed form of a semantic version string. -type parsed struct { - major string - minor string - patch string - short string - prerelease string - build string -} - -// IsValid reports whether v is a valid semantic version string. -func IsValid(v string) bool { - _, ok := parse(v) - return ok -} - -// Canonical returns the canonical formatting of the semantic version v. -// It fills in any missing .MINOR or .PATCH and discards build metadata. -// Two semantic versions compare equal only if their canonical formattings -// are identical strings. -// The canonical invalid semantic version is the empty string. -func Canonical(v string) string { - p, ok := parse(v) - if !ok { - return "" - } - if p.build != "" { - return v[:len(v)-len(p.build)] - } - if p.short != "" { - return v + p.short - } - return v -} - -// Major returns the major version prefix of the semantic version v. -// For example, Major("v2.1.0") == "v2". -// If v is an invalid semantic version string, Major returns the empty string. -func Major(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return v[:1+len(pv.major)] -} - -// MajorMinor returns the major.minor version prefix of the semantic version v. -// For example, MajorMinor("v2.1.0") == "v2.1". -// If v is an invalid semantic version string, MajorMinor returns the empty string. -func MajorMinor(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - i := 1 + len(pv.major) - if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { - return v[:j] - } - return v[:i] + "." + pv.minor -} - -// Prerelease returns the prerelease suffix of the semantic version v. -// For example, Prerelease("v2.1.0-pre+meta") == "-pre". -// If v is an invalid semantic version string, Prerelease returns the empty string. -func Prerelease(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.prerelease -} - -// Build returns the build suffix of the semantic version v. -// For example, Build("v2.1.0+meta") == "+meta". -// If v is an invalid semantic version string, Build returns the empty string. -func Build(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.build -} - -// Compare returns an integer comparing two versions according to -// semantic version precedence. -// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. -// -// An invalid semantic version string is considered less than a valid one. -// All invalid semantic version strings compare equal to each other. -func Compare(v, w string) int { - pv, ok1 := parse(v) - pw, ok2 := parse(w) - if !ok1 && !ok2 { - return 0 - } - if !ok1 { - return -1 - } - if !ok2 { - return +1 - } - if c := compareInt(pv.major, pw.major); c != 0 { - return c - } - if c := compareInt(pv.minor, pw.minor); c != 0 { - return c - } - if c := compareInt(pv.patch, pw.patch); c != 0 { - return c - } - return comparePrerelease(pv.prerelease, pw.prerelease) -} - -// Max canonicalizes its arguments and then returns the version string -// that compares greater. -// -// Deprecated: use [Compare] instead. In most cases, returning a canonicalized -// version is not expected or desired. -func Max(v, w string) string { - v = Canonical(v) - w = Canonical(w) - if Compare(v, w) > 0 { - return v - } - return w -} - -// ByVersion implements [sort.Interface] for sorting semantic version strings. -type ByVersion []string - -func (vs ByVersion) Len() int { return len(vs) } -func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } -func (vs ByVersion) Less(i, j int) bool { - cmp := Compare(vs[i], vs[j]) - if cmp != 0 { - return cmp < 0 - } - return vs[i] < vs[j] -} - -// Sort sorts a list of semantic version strings using [ByVersion]. -func Sort(list []string) { - sort.Sort(ByVersion(list)) -} - -func parse(v string) (p parsed, ok bool) { - if v == "" || v[0] != 'v' { - return - } - p.major, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.minor = "0" - p.patch = "0" - p.short = ".0.0" - return - } - if v[0] != '.' { - ok = false - return - } - p.minor, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.patch = "0" - p.short = ".0" - return - } - if v[0] != '.' { - ok = false - return - } - p.patch, v, ok = parseInt(v[1:]) - if !ok { - return - } - if len(v) > 0 && v[0] == '-' { - p.prerelease, v, ok = parsePrerelease(v) - if !ok { - return - } - } - if len(v) > 0 && v[0] == '+' { - p.build, v, ok = parseBuild(v) - if !ok { - return - } - } - if v != "" { - ok = false - return - } - ok = true - return -} - -func parseInt(v string) (t, rest string, ok bool) { - if v == "" { - return - } - if v[0] < '0' || '9' < v[0] { - return - } - i := 1 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - if v[0] == '0' && i != 1 { - return - } - return v[:i], v[i:], true -} - -func parsePrerelease(v string) (t, rest string, ok bool) { - // "A pre-release version MAY be denoted by appending a hyphen and - // a series of dot separated identifiers immediately following the patch version. - // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. - // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." - if v == "" || v[0] != '-' { - return - } - i := 1 - start := 1 - for i < len(v) && v[i] != '+' { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i || isBadNum(v[start:i]) { - return - } - start = i + 1 - } - i++ - } - if start == i || isBadNum(v[start:i]) { - return - } - return v[:i], v[i:], true -} - -func parseBuild(v string) (t, rest string, ok bool) { - if v == "" || v[0] != '+' { - return - } - i := 1 - start := 1 - for i < len(v) { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i { - return - } - start = i + 1 - } - i++ - } - if start == i { - return - } - return v[:i], v[i:], true -} - -func isIdentChar(c byte) bool { - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' -} - -func isBadNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) && i > 1 && v[0] == '0' -} - -func isNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) -} - -func compareInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} - -func comparePrerelease(x, y string) int { - // "When major, minor, and patch are equal, a pre-release version has - // lower precedence than a normal version. - // Example: 1.0.0-alpha < 1.0.0. - // Precedence for two pre-release versions with the same major, minor, - // and patch version MUST be determined by comparing each dot separated - // identifier from left to right until a difference is found as follows: - // identifiers consisting of only digits are compared numerically and - // identifiers with letters or hyphens are compared lexically in ASCII - // sort order. Numeric identifiers always have lower precedence than - // non-numeric identifiers. A larger set of pre-release fields has a - // higher precedence than a smaller set, if all of the preceding - // identifiers are equal. - // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < - // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." - if x == y { - return 0 - } - if x == "" { - return +1 - } - if y == "" { - return -1 - } - for x != "" && y != "" { - x = x[1:] // skip - or . - y = y[1:] // skip - or . - var dx, dy string - dx, x = nextIdent(x) - dy, y = nextIdent(y) - if dx != dy { - ix := isNum(dx) - iy := isNum(dy) - if ix != iy { - if ix { - return -1 - } else { - return +1 - } - } - if ix { - if len(dx) < len(dy) { - return -1 - } - if len(dx) > len(dy) { - return +1 - } - } - if dx < dy { - return -1 - } else { - return +1 - } - } - } - if x == "" { - return -1 - } else { - return +1 - } -} - -func nextIdent(x string) (dx, rest string) { - i := 0 - for i < len(x) && x[i] != '.' { - i++ - } - return x[:i], x[i:] -} diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message.go b/vendor/golang.org/x/net/dns/dnsmessage/message.go index a656efc..7a978b4 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/message.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/message.go @@ -17,8 +17,21 @@ import ( ) // Message formats +// +// To add a new Resource Record type: +// 1. Create Resource Record types +// 1.1. Add a Type constant named "Type" +// 1.2. Add the corresponding entry to the typeNames map +// 1.3. Add a [ResourceBody] implementation named "Resource" +// 2. Implement packing +// 2.1. Implement Builder.Resource() +// 3. Implement unpacking +// 3.1. Add the unpacking code to unpackResourceBody() +// 3.2. Implement Parser.Resource() -// A Type is a type of DNS request and response. +// A Type is the type of a DNS Resource Record, as defined in the [IANA registry]. +// +// [IANA registry]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 type Type uint16 const ( @@ -33,6 +46,8 @@ const ( TypeAAAA Type = 28 TypeSRV Type = 33 TypeOPT Type = 41 + TypeSVCB Type = 64 + TypeHTTPS Type = 65 // Question.Type TypeWKS Type = 11 @@ -53,6 +68,8 @@ var typeNames = map[Type]string{ TypeAAAA: "TypeAAAA", TypeSRV: "TypeSRV", TypeOPT: "TypeOPT", + TypeSVCB: "TypeSVCB", + TypeHTTPS: "TypeHTTPS", TypeWKS: "TypeWKS", TypeHINFO: "TypeHINFO", TypeMINFO: "TypeMINFO", @@ -273,6 +290,8 @@ var ( errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)") errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)") errStringTooLong = errors.New("character string exceeds maximum length (255)") + errParamOutOfOrder = errors.New("parameter out of order") + errTooLongSVCBValue = errors.New("value too long (>65535 bytes)") ) // Internal constants. @@ -2220,6 +2239,16 @@ func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, rb, err = unpackSRVResource(msg, off) r = &rb name = "SRV" + case TypeSVCB: + var rb SVCBResource + rb, err = unpackSVCBResource(msg, off, hdr.Length) + r = &rb + name = "SVCB" + case TypeHTTPS: + var rb HTTPSResource + rb.SVCBResource, err = unpackSVCBResource(msg, off, hdr.Length) + r = &rb + name = "HTTPS" case TypeOPT: var rb OPTResource rb, err = unpackOPTResource(msg, off, hdr.Length) diff --git a/vendor/golang.org/x/net/dns/dnsmessage/svcb.go b/vendor/golang.org/x/net/dns/dnsmessage/svcb.go new file mode 100644 index 0000000..4840516 --- /dev/null +++ b/vendor/golang.org/x/net/dns/dnsmessage/svcb.go @@ -0,0 +1,326 @@ +// Copyright 2025 The Go 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 dnsmessage + +import ( + "slices" +) + +// An SVCBResource is an SVCB Resource record. +type SVCBResource struct { + Priority uint16 + Target Name + Params []SVCParam // Must be in strict increasing order by Key. +} + +func (r *SVCBResource) realType() Type { + return TypeSVCB +} + +// GoString implements fmt.GoStringer.GoString. +func (r *SVCBResource) GoString() string { + b := []byte("dnsmessage.SVCBResource{" + + "Priority: " + printUint16(r.Priority) + ", " + + "Target: " + r.Target.GoString() + ", " + + "Params: []dnsmessage.SVCParam{") + if len(r.Params) > 0 { + b = append(b, r.Params[0].GoString()...) + for _, p := range r.Params[1:] { + b = append(b, ", "+p.GoString()...) + } + } + b = append(b, "}}"...) + return string(b) +} + +// An HTTPSResource is an HTTPS Resource record. +// It has the same format as the SVCB record. +type HTTPSResource struct { + // Alias for SVCB resource record. + SVCBResource +} + +func (r *HTTPSResource) realType() Type { + return TypeHTTPS +} + +// GoString implements fmt.GoStringer.GoString. +func (r *HTTPSResource) GoString() string { + return "dnsmessage.HTTPSResource{SVCBResource: " + r.SVCBResource.GoString() + "}" +} + +// GetParam returns a parameter value by key. +func (r *SVCBResource) GetParam(key SVCParamKey) (value []byte, ok bool) { + for i := range r.Params { + if r.Params[i].Key == key { + return r.Params[i].Value, true + } + if r.Params[i].Key > key { + break + } + } + return nil, false +} + +// SetParam sets a parameter value by key. +// The Params list is kept sorted by key. +func (r *SVCBResource) SetParam(key SVCParamKey, value []byte) { + i := 0 + for i < len(r.Params) { + if r.Params[i].Key >= key { + break + } + i++ + } + + if i < len(r.Params) && r.Params[i].Key == key { + r.Params[i].Value = value + return + } + + r.Params = slices.Insert(r.Params, i, SVCParam{Key: key, Value: value}) +} + +// DeleteParam deletes a parameter by key. +// It returns true if the parameter was present. +func (r *SVCBResource) DeleteParam(key SVCParamKey) bool { + for i := range r.Params { + if r.Params[i].Key == key { + r.Params = slices.Delete(r.Params, i, i+1) + return true + } + if r.Params[i].Key > key { + break + } + } + return false +} + +// A SVCParam is a service parameter. +type SVCParam struct { + Key SVCParamKey + Value []byte +} + +// GoString implements fmt.GoStringer.GoString. +func (p SVCParam) GoString() string { + return "dnsmessage.SVCParam{" + + "Key: " + p.Key.GoString() + ", " + + "Value: []byte{" + printByteSlice(p.Value) + "}}" +} + +// A SVCParamKey is a key for a service parameter. +type SVCParamKey uint16 + +// Values defined at https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys. +const ( + SVCParamMandatory SVCParamKey = 0 + SVCParamALPN SVCParamKey = 1 + SVCParamNoDefaultALPN SVCParamKey = 2 + SVCParamPort SVCParamKey = 3 + SVCParamIPv4Hint SVCParamKey = 4 + SVCParamECH SVCParamKey = 5 + SVCParamIPv6Hint SVCParamKey = 6 + SVCParamDOHPath SVCParamKey = 7 + SVCParamOHTTP SVCParamKey = 8 + SVCParamTLSSupportedGroups SVCParamKey = 9 +) + +var svcParamKeyNames = map[SVCParamKey]string{ + SVCParamMandatory: "Mandatory", + SVCParamALPN: "ALPN", + SVCParamNoDefaultALPN: "NoDefaultALPN", + SVCParamPort: "Port", + SVCParamIPv4Hint: "IPv4Hint", + SVCParamECH: "ECH", + SVCParamIPv6Hint: "IPv6Hint", + SVCParamDOHPath: "DOHPath", + SVCParamOHTTP: "OHTTP", + SVCParamTLSSupportedGroups: "TLSSupportedGroups", +} + +// String implements fmt.Stringer.String. +func (k SVCParamKey) String() string { + if n, ok := svcParamKeyNames[k]; ok { + return n + } + return printUint16(uint16(k)) +} + +// GoString implements fmt.GoStringer.GoString. +func (k SVCParamKey) GoString() string { + if n, ok := svcParamKeyNames[k]; ok { + return "dnsmessage.SVCParam" + n + } + return printUint16(uint16(k)) +} + +func (r *SVCBResource) pack(msg []byte, _ map[string]uint16, _ int) ([]byte, error) { + oldMsg := msg + msg = packUint16(msg, r.Priority) + // https://datatracker.ietf.org/doc/html/rfc3597#section-4 prohibits name + // compression for RR types that are not "well-known". + // https://datatracker.ietf.org/doc/html/rfc9460#section-2.2 explicitly states that + // compression of the Target is prohibited, following RFC 3597. + msg, err := r.Target.pack(msg, nil, 0) + if err != nil { + return oldMsg, &nestedError{"SVCBResource.Target", err} + } + var previousKey SVCParamKey + for i, param := range r.Params { + if i > 0 && param.Key <= previousKey { + return oldMsg, &nestedError{"SVCBResource.Params", errParamOutOfOrder} + } + if len(param.Value) > (1<<16)-1 { + return oldMsg, &nestedError{"SVCBResource.Params", errTooLongSVCBValue} + } + msg = packUint16(msg, uint16(param.Key)) + msg = packUint16(msg, uint16(len(param.Value))) + msg = append(msg, param.Value...) + } + return msg, nil +} + +func unpackSVCBResource(msg []byte, off int, length uint16) (SVCBResource, error) { + // Wire format reference: https://www.rfc-editor.org/rfc/rfc9460.html#section-2.2. + r := SVCBResource{} + paramsOff := off + bodyEnd := off + int(length) + + var err error + if r.Priority, paramsOff, err = unpackUint16(msg, paramsOff); err != nil { + return SVCBResource{}, &nestedError{"Priority", err} + } + + if paramsOff, err = r.Target.unpack(msg, paramsOff); err != nil { + return SVCBResource{}, &nestedError{"Target", err} + } + + // Two-pass parsing to avoid allocations. + // First, count the number of params. + n := 0 + var totalValueLen uint16 + off = paramsOff + var previousKey uint16 + for off < bodyEnd { + var key, len uint16 + if key, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"Params key", err} + } + if n > 0 && key <= previousKey { + // As per https://www.rfc-editor.org/rfc/rfc9460.html#section-2.2, clients MUST + // consider the RR malformed if the SvcParamKeys are not in strictly increasing numeric order + return SVCBResource{}, &nestedError{"Params", errParamOutOfOrder} + } + if len, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"Params value length", err} + } + if off+int(len) > bodyEnd { + return SVCBResource{}, errResourceLen + } + totalValueLen += len + off += int(len) + n++ + } + if off != bodyEnd { + return SVCBResource{}, errResourceLen + } + + // Second, fill in the params. + r.Params = make([]SVCParam, n) + // valuesBuf is used to hold all param values to reduce allocations. + // Each param's Value slice will point into this buffer. + valuesBuf := make([]byte, totalValueLen) + off = paramsOff + for i := 0; i < n; i++ { + p := &r.Params[i] + var key, len uint16 + if key, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"param key", err} + } + p.Key = SVCParamKey(key) + if len, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"param length", err} + } + if copy(valuesBuf, msg[off:off+int(len)]) != int(len) { + return SVCBResource{}, &nestedError{"param value", errCalcLen} + } + p.Value = valuesBuf[:len:len] + valuesBuf = valuesBuf[len:] + off += int(len) + } + + return r, nil +} + +// genericSVCBResource parses a single Resource Record compatible with SVCB. +func (p *Parser) genericSVCBResource(svcbType Type) (SVCBResource, error) { + if !p.resHeaderValid || p.resHeaderType != svcbType { + return SVCBResource{}, ErrNotStarted + } + r, err := unpackSVCBResource(p.msg, p.off, p.resHeaderLength) + if err != nil { + return SVCBResource{}, err + } + p.off += int(p.resHeaderLength) + p.resHeaderValid = false + p.index++ + return r, nil +} + +// SVCBResource parses a single SVCBResource. +// +// One of the XXXHeader methods must have been called before calling this +// method. +func (p *Parser) SVCBResource() (SVCBResource, error) { + return p.genericSVCBResource(TypeSVCB) +} + +// HTTPSResource parses a single HTTPSResource. +// +// One of the XXXHeader methods must have been called before calling this +// method. +func (p *Parser) HTTPSResource() (HTTPSResource, error) { + svcb, err := p.genericSVCBResource(TypeHTTPS) + if err != nil { + return HTTPSResource{}, err + } + return HTTPSResource{svcb}, nil +} + +// genericSVCBResource is the generic implementation for adding SVCB-like resources. +func (b *Builder) genericSVCBResource(h ResourceHeader, r SVCBResource) error { + if err := b.checkResourceSection(); err != nil { + return err + } + msg, lenOff, err := h.pack(b.msg, b.compression, b.start) + if err != nil { + return &nestedError{"ResourceHeader", err} + } + preLen := len(msg) + if msg, err = r.pack(msg, b.compression, b.start); err != nil { + return &nestedError{"ResourceBody", err} + } + if err := h.fixLen(msg, lenOff, preLen); err != nil { + return err + } + if err := b.incrementSectionCount(); err != nil { + return err + } + b.msg = msg + return nil +} + +// SVCBResource adds a single SVCBResource. +func (b *Builder) SVCBResource(h ResourceHeader, r SVCBResource) error { + h.Type = r.realType() + return b.genericSVCBResource(h, r) +} + +// HTTPSResource adds a single HTTPSResource. +func (b *Builder) HTTPSResource(h ResourceHeader, r HTTPSResource) error { + h.Type = r.realType() + return b.genericSVCBResource(h, r.SVCBResource) +} diff --git a/vendor/golang.org/x/net/http2/.gitignore b/vendor/golang.org/x/net/http2/.gitignore deleted file mode 100644 index 190f122..0000000 --- a/vendor/golang.org/x/net/http2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*~ -h2i/h2i diff --git a/vendor/golang.org/x/net/http2/ascii.go b/vendor/golang.org/x/net/http2/ascii.go deleted file mode 100644 index 17caa20..0000000 --- a/vendor/golang.org/x/net/http2/ascii.go +++ /dev/null @@ -1,53 +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 http2 - -import "strings" - -// The HTTP protocols are defined in terms of ASCII, not Unicode. This file -// contains helper functions which may use Unicode-aware functions which would -// otherwise be unsafe and could introduce vulnerabilities if used improperly. - -// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t -// are equal, ASCII-case-insensitively. -func asciiEqualFold(s, t string) bool { - if len(s) != len(t) { - return false - } - for i := 0; i < len(s); i++ { - if lower(s[i]) != lower(t[i]) { - return false - } - } - return true -} - -// lower returns the ASCII lowercase version of b. -func lower(b byte) byte { - if 'A' <= b && b <= 'Z' { - return b + ('a' - 'A') - } - return b -} - -// isASCIIPrint returns whether s is ASCII and printable according to -// https://tools.ietf.org/html/rfc20#section-4.2. -func isASCIIPrint(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] < ' ' || s[i] > '~' { - return false - } - } - return true -} - -// asciiToLower returns the lowercase version of s if s is ASCII and printable, -// and whether or not it was. -func asciiToLower(s string) (lower string, ok bool) { - if !isASCIIPrint(s) { - return "", false - } - return strings.ToLower(s), true -} diff --git a/vendor/golang.org/x/net/http2/ciphers.go b/vendor/golang.org/x/net/http2/ciphers.go deleted file mode 100644 index c9a0cf3..0000000 --- a/vendor/golang.org/x/net/http2/ciphers.go +++ /dev/null @@ -1,641 +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 http2 - -// A list of the possible cipher suite ids. Taken from -// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt - -const ( - cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000 - cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001 - cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 - cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003 - cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004 - cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006 - cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007 - cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008 - cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009 - cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A - cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B - cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C - cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D - cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E - cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F - cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010 - cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011 - cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012 - cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013 - cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014 - cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015 - cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016 - cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017 - cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018 - cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019 - cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A - cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B - // Reserved uint16 = 0x001C-1D - cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E - cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F - cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020 - cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021 - cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022 - cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023 - cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024 - cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025 - cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026 - cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027 - cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028 - cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029 - cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A - cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B - cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C - cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D - cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E - cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F - cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030 - cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031 - cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032 - cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033 - cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034 - cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036 - cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037 - cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038 - cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039 - cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A - cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B - cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C - cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D - cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E - cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F - cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040 - cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041 - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042 - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043 - cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044 - cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045 - cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046 - // Reserved uint16 = 0x0047-4F - // Reserved uint16 = 0x0050-58 - // Reserved uint16 = 0x0059-5C - // Unassigned uint16 = 0x005D-5F - // Reserved uint16 = 0x0060-66 - cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067 - cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068 - cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069 - cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A - cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B - cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C - cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D - // Unassigned uint16 = 0x006E-83 - cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084 - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085 - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086 - cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087 - cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088 - cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089 - cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A - cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B - cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C - cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D - cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E - cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F - cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090 - cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091 - cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092 - cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093 - cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094 - cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095 - cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096 - cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097 - cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098 - cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099 - cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A - cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B - cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C - cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D - cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E - cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F - cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0 - cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1 - cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2 - cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3 - cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4 - cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5 - cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6 - cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7 - cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8 - cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9 - cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA - cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB - cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC - cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD - cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE - cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF - cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0 - cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1 - cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2 - cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3 - cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4 - cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5 - cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6 - cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7 - cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8 - cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9 - cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC - cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD - cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE - cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF - cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0 - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1 - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2 - cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3 - cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4 - cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5 - // Unassigned uint16 = 0x00C6-FE - cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF - // Unassigned uint16 = 0x01-55,* - cipher_TLS_FALLBACK_SCSV uint16 = 0x5600 - // Unassigned uint16 = 0x5601 - 0xC000 - cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001 - cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002 - cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003 - cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004 - cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005 - cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006 - cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007 - cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008 - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009 - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A - cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B - cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C - cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D - cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E - cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F - cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010 - cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011 - cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012 - cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013 - cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014 - cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015 - cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016 - cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017 - cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018 - cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019 - cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A - cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B - cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C - cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D - cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E - cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F - cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020 - cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021 - cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022 - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023 - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024 - cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025 - cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026 - cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027 - cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028 - cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029 - cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C - cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D - cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E - cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F - cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030 - cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031 - cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032 - cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033 - cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034 - cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035 - cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036 - cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037 - cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038 - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039 - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B - cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C - cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D - cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E - cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F - cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040 - cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041 - cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042 - cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043 - cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044 - cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045 - cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046 - cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047 - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048 - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049 - cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A - cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B - cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C - cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D - cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E - cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F - cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050 - cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051 - cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052 - cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053 - cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054 - cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055 - cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056 - cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057 - cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058 - cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059 - cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A - cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D - cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E - cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F - cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060 - cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061 - cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062 - cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063 - cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064 - cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065 - cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066 - cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067 - cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068 - cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069 - cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A - cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B - cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C - cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D - cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E - cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F - cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070 - cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071 - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072 - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073 - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074 - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075 - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076 - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077 - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078 - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079 - cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A - cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B - cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C - cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F - cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080 - cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081 - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082 - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083 - cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084 - cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085 - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086 - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087 - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088 - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089 - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D - cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E - cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F - cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090 - cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091 - cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092 - cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093 - cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094 - cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095 - cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096 - cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097 - cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098 - cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099 - cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A - cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B - cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C - cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D - cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E - cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F - cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0 - cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1 - cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2 - cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3 - cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4 - cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5 - cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6 - cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7 - cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8 - cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9 - cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA - cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF - // Unassigned uint16 = 0xC0B0-FF - // Unassigned uint16 = 0xC1-CB,* - // Unassigned uint16 = 0xCC00-A7 - cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8 - cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9 - cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA - cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB - cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC - cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD - cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE -) - -// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. -// References: -// https://tools.ietf.org/html/rfc7540#appendix-A -// Reject cipher suites from Appendix A. -// "This list includes those cipher suites that do not -// offer an ephemeral key exchange and those that are -// based on the TLS null, stream or block cipher type" -func isBadCipher(cipher uint16) bool { - switch cipher { - case cipher_TLS_NULL_WITH_NULL_NULL, - cipher_TLS_RSA_WITH_NULL_MD5, - cipher_TLS_RSA_WITH_NULL_SHA, - cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5, - cipher_TLS_RSA_WITH_RC4_128_MD5, - cipher_TLS_RSA_WITH_RC4_128_SHA, - cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, - cipher_TLS_RSA_WITH_IDEA_CBC_SHA, - cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_RSA_WITH_DES_CBC_SHA, - cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_DH_DSS_WITH_DES_CBC_SHA, - cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_DH_RSA_WITH_DES_CBC_SHA, - cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, - cipher_TLS_DH_anon_WITH_RC4_128_MD5, - cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, - cipher_TLS_DH_anon_WITH_DES_CBC_SHA, - cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_KRB5_WITH_DES_CBC_SHA, - cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_KRB5_WITH_RC4_128_SHA, - cipher_TLS_KRB5_WITH_IDEA_CBC_SHA, - cipher_TLS_KRB5_WITH_DES_CBC_MD5, - cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5, - cipher_TLS_KRB5_WITH_RC4_128_MD5, - cipher_TLS_KRB5_WITH_IDEA_CBC_MD5, - cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, - cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, - cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA, - cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, - cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, - cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5, - cipher_TLS_PSK_WITH_NULL_SHA, - cipher_TLS_DHE_PSK_WITH_NULL_SHA, - cipher_TLS_RSA_PSK_WITH_NULL_SHA, - cipher_TLS_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA, - cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA, - cipher_TLS_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA, - cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA, - cipher_TLS_RSA_WITH_NULL_SHA256, - cipher_TLS_RSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_RSA_WITH_AES_256_CBC_SHA256, - cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256, - cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, - cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256, - cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256, - cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, - cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256, - cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256, - cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA, - cipher_TLS_PSK_WITH_RC4_128_SHA, - cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_PSK_WITH_AES_128_CBC_SHA, - cipher_TLS_PSK_WITH_AES_256_CBC_SHA, - cipher_TLS_DHE_PSK_WITH_RC4_128_SHA, - cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, - cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, - cipher_TLS_RSA_PSK_WITH_RC4_128_SHA, - cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, - cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, - cipher_TLS_RSA_WITH_SEED_CBC_SHA, - cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA, - cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA, - cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA, - cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA, - cipher_TLS_DH_anon_WITH_SEED_CBC_SHA, - cipher_TLS_RSA_WITH_AES_128_GCM_SHA256, - cipher_TLS_RSA_WITH_AES_256_GCM_SHA384, - cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256, - cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384, - cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256, - cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384, - cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256, - cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384, - cipher_TLS_PSK_WITH_AES_128_GCM_SHA256, - cipher_TLS_PSK_WITH_AES_256_GCM_SHA384, - cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, - cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, - cipher_TLS_PSK_WITH_AES_128_CBC_SHA256, - cipher_TLS_PSK_WITH_AES_256_CBC_SHA384, - cipher_TLS_PSK_WITH_NULL_SHA256, - cipher_TLS_PSK_WITH_NULL_SHA384, - cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, - cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, - cipher_TLS_DHE_PSK_WITH_NULL_SHA256, - cipher_TLS_DHE_PSK_WITH_NULL_SHA384, - cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, - cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, - cipher_TLS_RSA_PSK_WITH_NULL_SHA256, - cipher_TLS_RSA_PSK_WITH_NULL_SHA384, - cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, - cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV, - cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA, - cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, - cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDH_RSA_WITH_NULL_SHA, - cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA, - cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDHE_RSA_WITH_NULL_SHA, - cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA, - cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDH_anon_WITH_NULL_SHA, - cipher_TLS_ECDH_anon_WITH_RC4_128_SHA, - cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA, - cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA, - cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, - cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, - cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA, - cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, - cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA, - cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, - cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, - cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, - cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA, - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256, - cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384, - cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, - cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, - cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, - cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, - cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, - cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, - cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, - cipher_TLS_RSA_WITH_AES_128_CCM, - cipher_TLS_RSA_WITH_AES_256_CCM, - cipher_TLS_RSA_WITH_AES_128_CCM_8, - cipher_TLS_RSA_WITH_AES_256_CCM_8, - cipher_TLS_PSK_WITH_AES_128_CCM, - cipher_TLS_PSK_WITH_AES_256_CCM, - cipher_TLS_PSK_WITH_AES_128_CCM_8, - cipher_TLS_PSK_WITH_AES_256_CCM_8: - return true - default: - return false - } -} diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go deleted file mode 100644 index e81b73e..0000000 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Transport code's client connection pooling. - -package http2 - -import ( - "context" - "errors" - "net" - "net/http" - "sync" -) - -// ClientConnPool manages a pool of HTTP/2 client connections. -type ClientConnPool interface { - // GetClientConn returns a specific HTTP/2 connection (usually - // a TLS-TCP connection) to an HTTP/2 server. On success, the - // returned ClientConn accounts for the upcoming RoundTrip - // call, so the caller should not omit it. If the caller needs - // to, ClientConn.RoundTrip can be called with a bogus - // new(http.Request) to release the stream reservation. - GetClientConn(req *http.Request, addr string) (*ClientConn, error) - MarkDead(*ClientConn) -} - -// clientConnPoolIdleCloser is the interface implemented by ClientConnPool -// implementations which can close their idle connections. -type clientConnPoolIdleCloser interface { - ClientConnPool - closeIdleConnections() -} - -var ( - _ clientConnPoolIdleCloser = (*clientConnPool)(nil) - _ clientConnPoolIdleCloser = noDialClientConnPool{} -) - -// TODO: use singleflight for dialing and addConnCalls? -type clientConnPool struct { - t *Transport - - mu sync.Mutex // TODO: maybe switch to RWMutex - // TODO: add support for sharing conns based on cert names - // (e.g. share conn for googleapis.com and appspot.com) - conns map[string][]*ClientConn // key is host:port - dialing map[string]*dialCall // currently in-flight dials - keys map[*ClientConn][]string - addConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls -} - -func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) { - return p.getClientConn(req, addr, dialOnMiss) -} - -const ( - dialOnMiss = true - noDialOnMiss = false -) - -func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) { - // TODO(dneil): Dial a new connection when t.DisableKeepAlives is set? - if isConnectionCloseRequest(req) && dialOnMiss { - // It gets its own connection. - traceGetConn(req, addr) - const singleUse = true - cc, err := p.t.dialClientConn(req.Context(), addr, singleUse) - if err != nil { - return nil, err - } - return cc, nil - } - for { - p.mu.Lock() - for _, cc := range p.conns[addr] { - if cc.ReserveNewRequest() { - // When a connection is presented to us by the net/http package, - // the GetConn hook has already been called. - // Don't call it a second time here. - if !cc.getConnCalled { - traceGetConn(req, addr) - } - cc.getConnCalled = false - p.mu.Unlock() - return cc, nil - } - } - if !dialOnMiss { - p.mu.Unlock() - return nil, ErrNoCachedConn - } - traceGetConn(req, addr) - call := p.getStartDialLocked(req.Context(), addr) - p.mu.Unlock() - <-call.done - if shouldRetryDial(call, req) { - continue - } - cc, err := call.res, call.err - if err != nil { - return nil, err - } - if cc.ReserveNewRequest() { - return cc, nil - } - } -} - -// dialCall is an in-flight Transport dial call to a host. -type dialCall struct { - _ incomparable - p *clientConnPool - // the context associated with the request - // that created this dialCall - ctx context.Context - done chan struct{} // closed when done - res *ClientConn // valid after done is closed - err error // valid after done is closed -} - -// requires p.mu is held. -func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall { - if call, ok := p.dialing[addr]; ok { - // A dial is already in-flight. Don't start another. - return call - } - call := &dialCall{p: p, done: make(chan struct{}), ctx: ctx} - if p.dialing == nil { - p.dialing = make(map[string]*dialCall) - } - p.dialing[addr] = call - go call.dial(call.ctx, addr) - return call -} - -// run in its own goroutine. -func (c *dialCall) dial(ctx context.Context, addr string) { - const singleUse = false // shared conn - c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse) - - c.p.mu.Lock() - delete(c.p.dialing, addr) - if c.err == nil { - c.p.addConnLocked(addr, c.res) - } - c.p.mu.Unlock() - - close(c.done) -} - -// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't -// already exist. It coalesces concurrent calls with the same key. -// This is used by the http1 Transport code when it creates a new connection. Because -// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know -// the protocol), it can get into a situation where it has multiple TLS connections. -// This code decides which ones live or die. -// The return value used is whether c was used. -// c is never closed. -func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c net.Conn) (used bool, err error) { - p.mu.Lock() - for _, cc := range p.conns[key] { - if cc.CanTakeNewRequest() { - p.mu.Unlock() - return false, nil - } - } - call, dup := p.addConnCalls[key] - if !dup { - if p.addConnCalls == nil { - p.addConnCalls = make(map[string]*addConnCall) - } - call = &addConnCall{ - p: p, - done: make(chan struct{}), - } - p.addConnCalls[key] = call - go call.run(t, key, c) - } - p.mu.Unlock() - - <-call.done - if call.err != nil { - return false, call.err - } - return !dup, nil -} - -type addConnCall struct { - _ incomparable - p *clientConnPool - done chan struct{} // closed when done - err error -} - -func (c *addConnCall) run(t *Transport, key string, nc net.Conn) { - cc, err := t.NewClientConn(nc) - - p := c.p - p.mu.Lock() - if err != nil { - c.err = err - } else { - cc.getConnCalled = true // already called by the net/http package - p.addConnLocked(key, cc) - } - delete(p.addConnCalls, key) - p.mu.Unlock() - close(c.done) -} - -// p.mu must be held -func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) { - for _, v := range p.conns[key] { - if v == cc { - return - } - } - if p.conns == nil { - p.conns = make(map[string][]*ClientConn) - } - if p.keys == nil { - p.keys = make(map[*ClientConn][]string) - } - p.conns[key] = append(p.conns[key], cc) - p.keys[cc] = append(p.keys[cc], key) -} - -func (p *clientConnPool) MarkDead(cc *ClientConn) { - p.mu.Lock() - defer p.mu.Unlock() - for _, key := range p.keys[cc] { - vv, ok := p.conns[key] - if !ok { - continue - } - newList := filterOutClientConn(vv, cc) - if len(newList) > 0 { - p.conns[key] = newList - } else { - delete(p.conns, key) - } - } - delete(p.keys, cc) -} - -func (p *clientConnPool) closeIdleConnections() { - p.mu.Lock() - defer p.mu.Unlock() - // TODO: don't close a cc if it was just added to the pool - // milliseconds ago and has never been used. There's currently - // a small race window with the HTTP/1 Transport's integration - // where it can add an idle conn just before using it, and - // somebody else can concurrently call CloseIdleConns and - // break some caller's RoundTrip. - for _, vv := range p.conns { - for _, cc := range vv { - cc.closeIfIdle() - } - } -} - -func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn { - out := in[:0] - for _, v := range in { - if v != exclude { - out = append(out, v) - } - } - // If we filtered it out, zero out the last item to prevent - // the GC from seeing it. - if len(in) != len(out) { - in[len(in)-1] = nil - } - return out -} - -// noDialClientConnPool is an implementation of http2.ClientConnPool -// which never dials. We let the HTTP/1.1 client dial and use its TLS -// connection instead. -type noDialClientConnPool struct{ *clientConnPool } - -func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) { - return p.getClientConn(req, addr, noDialOnMiss) -} - -// shouldRetryDial reports whether the current request should -// retry dialing after the call finished unsuccessfully, for example -// if the dial was canceled because of a context cancellation or -// deadline expiry. -func shouldRetryDial(call *dialCall, req *http.Request) bool { - if call.err == nil { - // No error, no need to retry - return false - } - if call.ctx == req.Context() { - // If the call has the same context as the request, the dial - // should not be retried, since any cancellation will have come - // from this request. - return false - } - if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) { - // If the call error is not because of a context cancellation or a deadline expiry, - // the dial should not be retried. - return false - } - // Only retry if the error is a context cancellation error or deadline expiry - // and the context associated with the call was canceled or expired. - return call.ctx.Err() != nil -} diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go deleted file mode 100644 index ca645d9..0000000 --- a/vendor/golang.org/x/net/http2/config.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2024 The Go 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 http2 - -import ( - "math" - "net/http" - "time" -) - -// http2Config is a package-internal version of net/http.HTTP2Config. -// -// http.HTTP2Config was added in Go 1.24. -// When running with a version of net/http that includes HTTP2Config, -// we merge the configuration with the fields in Transport or Server -// to produce an http2Config. -// -// Zero valued fields in http2Config are interpreted as in the -// net/http.HTTPConfig documentation. -// -// Precedence order for reconciling configurations is: -// -// - Use the net/http.{Server,Transport}.HTTP2Config value, when non-zero. -// - Otherwise use the http2.{Server.Transport} value. -// - If the resulting value is zero or out of range, use a default. -type http2Config struct { - MaxConcurrentStreams uint32 - MaxDecoderHeaderTableSize uint32 - MaxEncoderHeaderTableSize uint32 - MaxReadFrameSize uint32 - MaxUploadBufferPerConnection int32 - MaxUploadBufferPerStream int32 - SendPingTimeout time.Duration - PingTimeout time.Duration - WriteByteTimeout time.Duration - PermitProhibitedCipherSuites bool - CountError func(errType string) -} - -// configFromServer merges configuration settings from -// net/http.Server.HTTP2Config and http2.Server. -func configFromServer(h1 *http.Server, h2 *Server) http2Config { - conf := http2Config{ - MaxConcurrentStreams: h2.MaxConcurrentStreams, - MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, - MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, - MaxReadFrameSize: h2.MaxReadFrameSize, - MaxUploadBufferPerConnection: h2.MaxUploadBufferPerConnection, - MaxUploadBufferPerStream: h2.MaxUploadBufferPerStream, - SendPingTimeout: h2.ReadIdleTimeout, - PingTimeout: h2.PingTimeout, - WriteByteTimeout: h2.WriteByteTimeout, - PermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites, - CountError: h2.CountError, - } - fillNetHTTPServerConfig(&conf, h1) - setConfigDefaults(&conf, true) - return conf -} - -// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2 -// (the net/http Transport). -func configFromTransport(h2 *Transport) http2Config { - conf := http2Config{ - MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize, - MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize, - MaxReadFrameSize: h2.MaxReadFrameSize, - SendPingTimeout: h2.ReadIdleTimeout, - PingTimeout: h2.PingTimeout, - WriteByteTimeout: h2.WriteByteTimeout, - } - - // Unlike most config fields, where out-of-range values revert to the default, - // Transport.MaxReadFrameSize clips. - if conf.MaxReadFrameSize < minMaxFrameSize { - conf.MaxReadFrameSize = minMaxFrameSize - } else if conf.MaxReadFrameSize > maxFrameSize { - conf.MaxReadFrameSize = maxFrameSize - } - - if h2.t1 != nil { - fillNetHTTPTransportConfig(&conf, h2.t1) - } - setConfigDefaults(&conf, false) - return conf -} - -func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) { - if *v < minval || *v > maxval { - *v = defval - } -} - -func setConfigDefaults(conf *http2Config, server bool) { - setDefault(&conf.MaxConcurrentStreams, 1, math.MaxUint32, defaultMaxStreams) - setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize) - setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize) - if server { - setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20) - } else { - setDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow) - } - if server { - setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, 1<<20) - } else { - setDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow) - } - setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize) - setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second) -} - -// adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header -// to an HTTP/2 MAX_HEADER_LIST_SIZE value. -func adjustHTTP1MaxHeaderSize(n int64) int64 { - // http2's count is in a slightly different unit and includes 32 bytes per pair. - // So, take the net/http.Server value and pad it up a bit, assuming 10 headers. - const perFieldOverhead = 32 // per http2 spec - const typicalHeaders = 10 // conservative - return n + typicalHeaders*perFieldOverhead -} diff --git a/vendor/golang.org/x/net/http2/config_go124.go b/vendor/golang.org/x/net/http2/config_go124.go deleted file mode 100644 index 5b516c5..0000000 --- a/vendor/golang.org/x/net/http2/config_go124.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2024 The Go 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.24 - -package http2 - -import "net/http" - -// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2. -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) { - fillNetHTTPConfig(conf, srv.HTTP2) -} - -// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2. -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) { - fillNetHTTPConfig(conf, tr.HTTP2) -} - -func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) { - if h2 == nil { - return - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxEncoderHeaderTableSize != 0 { - conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize) - } - if h2.MaxDecoderHeaderTableSize != 0 { - conf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize) - } - if h2.MaxConcurrentStreams != 0 { - conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams) - } - if h2.MaxReadFrameSize != 0 { - conf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize) - } - if h2.MaxReceiveBufferPerConnection != 0 { - conf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection) - } - if h2.MaxReceiveBufferPerStream != 0 { - conf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream) - } - if h2.SendPingTimeout != 0 { - conf.SendPingTimeout = h2.SendPingTimeout - } - if h2.PingTimeout != 0 { - conf.PingTimeout = h2.PingTimeout - } - if h2.WriteByteTimeout != 0 { - conf.WriteByteTimeout = h2.WriteByteTimeout - } - if h2.PermitProhibitedCipherSuites { - conf.PermitProhibitedCipherSuites = true - } - if h2.CountError != nil { - conf.CountError = h2.CountError - } -} diff --git a/vendor/golang.org/x/net/http2/config_pre_go124.go b/vendor/golang.org/x/net/http2/config_pre_go124.go deleted file mode 100644 index 060fd6c..0000000 --- a/vendor/golang.org/x/net/http2/config_pre_go124.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 The Go 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.24 - -package http2 - -import "net/http" - -// Pre-Go 1.24 fallback. -// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24. - -func fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {} - -func fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {} diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go deleted file mode 100644 index e6f55cb..0000000 --- a/vendor/golang.org/x/net/http2/databuffer.go +++ /dev/null @@ -1,149 +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 http2 - -import ( - "errors" - "fmt" - "sync" -) - -// Buffer chunks are allocated from a pool to reduce pressure on GC. -// The maximum wasted space per dataBuffer is 2x the largest size class, -// which happens when the dataBuffer has multiple chunks and there is -// one unread byte in both the first and last chunks. We use a few size -// classes to minimize overheads for servers that typically receive very -// small request bodies. -// -// TODO: Benchmark to determine if the pools are necessary. The GC may have -// improved enough that we can instead allocate chunks like this: -// make([]byte, max(16<<10, expectedBytesRemaining)) -var dataChunkPools = [...]sync.Pool{ - {New: func() interface{} { return new([1 << 10]byte) }}, - {New: func() interface{} { return new([2 << 10]byte) }}, - {New: func() interface{} { return new([4 << 10]byte) }}, - {New: func() interface{} { return new([8 << 10]byte) }}, - {New: func() interface{} { return new([16 << 10]byte) }}, -} - -func getDataBufferChunk(size int64) []byte { - switch { - case size <= 1<<10: - return dataChunkPools[0].Get().(*[1 << 10]byte)[:] - case size <= 2<<10: - return dataChunkPools[1].Get().(*[2 << 10]byte)[:] - case size <= 4<<10: - return dataChunkPools[2].Get().(*[4 << 10]byte)[:] - case size <= 8<<10: - return dataChunkPools[3].Get().(*[8 << 10]byte)[:] - default: - return dataChunkPools[4].Get().(*[16 << 10]byte)[:] - } -} - -func putDataBufferChunk(p []byte) { - switch len(p) { - case 1 << 10: - dataChunkPools[0].Put((*[1 << 10]byte)(p)) - case 2 << 10: - dataChunkPools[1].Put((*[2 << 10]byte)(p)) - case 4 << 10: - dataChunkPools[2].Put((*[4 << 10]byte)(p)) - case 8 << 10: - dataChunkPools[3].Put((*[8 << 10]byte)(p)) - case 16 << 10: - dataChunkPools[4].Put((*[16 << 10]byte)(p)) - default: - panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) - } -} - -// dataBuffer is an io.ReadWriter backed by a list of data chunks. -// Each dataBuffer is used to read DATA frames on a single stream. -// The buffer is divided into chunks so the server can limit the -// total memory used by a single connection without limiting the -// request body size on any single stream. -type dataBuffer struct { - chunks [][]byte - r int // next byte to read is chunks[0][r] - w int // next byte to write is chunks[len(chunks)-1][w] - size int // total buffered bytes - expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0) -} - -var errReadEmpty = errors.New("read from empty dataBuffer") - -// Read copies bytes from the buffer into p. -// It is an error to read when no data is available. -func (b *dataBuffer) Read(p []byte) (int, error) { - if b.size == 0 { - return 0, errReadEmpty - } - var ntotal int - for len(p) > 0 && b.size > 0 { - readFrom := b.bytesFromFirstChunk() - n := copy(p, readFrom) - p = p[n:] - ntotal += n - b.r += n - b.size -= n - // If the first chunk has been consumed, advance to the next chunk. - if b.r == len(b.chunks[0]) { - putDataBufferChunk(b.chunks[0]) - end := len(b.chunks) - 1 - copy(b.chunks[:end], b.chunks[1:]) - b.chunks[end] = nil - b.chunks = b.chunks[:end] - b.r = 0 - } - } - return ntotal, nil -} - -func (b *dataBuffer) bytesFromFirstChunk() []byte { - if len(b.chunks) == 1 { - return b.chunks[0][b.r:b.w] - } - return b.chunks[0][b.r:] -} - -// Len returns the number of bytes of the unread portion of the buffer. -func (b *dataBuffer) Len() int { - return b.size -} - -// Write appends p to the buffer. -func (b *dataBuffer) Write(p []byte) (int, error) { - ntotal := len(p) - for len(p) > 0 { - // If the last chunk is empty, allocate a new chunk. Try to allocate - // enough to fully copy p plus any additional bytes we expect to - // receive. However, this may allocate less than len(p). - want := int64(len(p)) - if b.expected > want { - want = b.expected - } - chunk := b.lastChunkOrAlloc(want) - n := copy(chunk[b.w:], p) - p = p[n:] - b.w += n - b.size += n - b.expected -= int64(n) - } - return ntotal, nil -} - -func (b *dataBuffer) lastChunkOrAlloc(want int64) []byte { - if len(b.chunks) != 0 { - last := b.chunks[len(b.chunks)-1] - if b.w < len(last) { - return last - } - } - chunk := getDataBufferChunk(want) - b.chunks = append(b.chunks, chunk) - b.w = 0 - return chunk -} diff --git a/vendor/golang.org/x/net/http2/errors.go b/vendor/golang.org/x/net/http2/errors.go deleted file mode 100644 index f2067da..0000000 --- a/vendor/golang.org/x/net/http2/errors.go +++ /dev/null @@ -1,145 +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 http2 - -import ( - "errors" - "fmt" -) - -// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec. -type ErrCode uint32 - -const ( - ErrCodeNo ErrCode = 0x0 - ErrCodeProtocol ErrCode = 0x1 - ErrCodeInternal ErrCode = 0x2 - ErrCodeFlowControl ErrCode = 0x3 - ErrCodeSettingsTimeout ErrCode = 0x4 - ErrCodeStreamClosed ErrCode = 0x5 - ErrCodeFrameSize ErrCode = 0x6 - ErrCodeRefusedStream ErrCode = 0x7 - ErrCodeCancel ErrCode = 0x8 - ErrCodeCompression ErrCode = 0x9 - ErrCodeConnect ErrCode = 0xa - ErrCodeEnhanceYourCalm ErrCode = 0xb - ErrCodeInadequateSecurity ErrCode = 0xc - ErrCodeHTTP11Required ErrCode = 0xd -) - -var errCodeName = map[ErrCode]string{ - ErrCodeNo: "NO_ERROR", - ErrCodeProtocol: "PROTOCOL_ERROR", - ErrCodeInternal: "INTERNAL_ERROR", - ErrCodeFlowControl: "FLOW_CONTROL_ERROR", - ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT", - ErrCodeStreamClosed: "STREAM_CLOSED", - ErrCodeFrameSize: "FRAME_SIZE_ERROR", - ErrCodeRefusedStream: "REFUSED_STREAM", - ErrCodeCancel: "CANCEL", - ErrCodeCompression: "COMPRESSION_ERROR", - ErrCodeConnect: "CONNECT_ERROR", - ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM", - ErrCodeInadequateSecurity: "INADEQUATE_SECURITY", - ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED", -} - -func (e ErrCode) String() string { - if s, ok := errCodeName[e]; ok { - return s - } - return fmt.Sprintf("unknown error code 0x%x", uint32(e)) -} - -func (e ErrCode) stringToken() string { - if s, ok := errCodeName[e]; ok { - return s - } - return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e)) -} - -// ConnectionError is an error that results in the termination of the -// entire connection. -type ConnectionError ErrCode - -func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) } - -// StreamError is an error that only affects one stream within an -// HTTP/2 connection. -type StreamError struct { - StreamID uint32 - Code ErrCode - Cause error // optional additional detail -} - -// errFromPeer is a sentinel error value for StreamError.Cause to -// indicate that the StreamError was sent from the peer over the wire -// and wasn't locally generated in the Transport. -var errFromPeer = errors.New("received from peer") - -func streamError(id uint32, code ErrCode) StreamError { - return StreamError{StreamID: id, Code: code} -} - -func (e StreamError) Error() string { - if e.Cause != nil { - return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause) - } - return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code) -} - -// 6.9.1 The Flow Control Window -// "If a sender receives a WINDOW_UPDATE that causes a flow control -// window to exceed this maximum it MUST terminate either the stream -// or the connection, as appropriate. For streams, [...]; for the -// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code." -type goAwayFlowError struct{} - -func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" } - -// connError represents an HTTP/2 ConnectionError error code, along -// with a string (for debugging) explaining why. -// -// Errors of this type are only returned by the frame parser functions -// and converted into ConnectionError(Code), after stashing away -// the Reason into the Framer's errDetail field, accessible via -// the (*Framer).ErrorDetail method. -type connError struct { - Code ErrCode // the ConnectionError error code - Reason string // additional reason -} - -func (e connError) Error() string { - return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason) -} - -type pseudoHeaderError string - -func (e pseudoHeaderError) Error() string { - return fmt.Sprintf("invalid pseudo-header %q", string(e)) -} - -type duplicatePseudoHeaderError string - -func (e duplicatePseudoHeaderError) Error() string { - return fmt.Sprintf("duplicate pseudo-header %q", string(e)) -} - -type headerFieldNameError string - -func (e headerFieldNameError) Error() string { - return fmt.Sprintf("invalid header field name %q", string(e)) -} - -type headerFieldValueError string - -func (e headerFieldValueError) Error() string { - return fmt.Sprintf("invalid header field value for %q", string(e)) -} - -var ( - errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers") - errPseudoAfterRegular = errors.New("pseudo header field after regular") -) diff --git a/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go deleted file mode 100644 index b7dbd18..0000000 --- a/vendor/golang.org/x/net/http2/flow.go +++ /dev/null @@ -1,120 +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. - -// Flow control - -package http2 - -// inflowMinRefresh is the minimum number of bytes we'll send for a -// flow control window update. -const inflowMinRefresh = 4 << 10 - -// inflow accounts for an inbound flow control window. -// It tracks both the latest window sent to the peer (used for enforcement) -// and the accumulated unsent window. -type inflow struct { - avail int32 - unsent int32 -} - -// init sets the initial window. -func (f *inflow) init(n int32) { - f.avail = n -} - -// add adds n bytes to the window, with a maximum window size of max, -// indicating that the peer can now send us more data. -// For example, the user read from a {Request,Response} body and consumed -// some of the buffered data, so the peer can now send more. -// It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer. -// Window updates are accumulated and sent when the unsent capacity -// is at least inflowMinRefresh or will at least double the peer's available window. -func (f *inflow) add(n int) (connAdd int32) { - if n < 0 { - panic("negative update") - } - unsent := int64(f.unsent) + int64(n) - // "A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets." - // RFC 7540 Section 6.9.1. - const maxWindow = 1<<31 - 1 - if unsent+int64(f.avail) > maxWindow { - panic("flow control update exceeds maximum window size") - } - f.unsent = int32(unsent) - if f.unsent < inflowMinRefresh && f.unsent < f.avail { - // If there aren't at least inflowMinRefresh bytes of window to send, - // and this update won't at least double the window, buffer the update for later. - return 0 - } - f.avail += f.unsent - f.unsent = 0 - return int32(unsent) -} - -// take attempts to take n bytes from the peer's flow control window. -// It reports whether the window has available capacity. -func (f *inflow) take(n uint32) bool { - if n > uint32(f.avail) { - return false - } - f.avail -= int32(n) - return true -} - -// takeInflows attempts to take n bytes from two inflows, -// typically connection-level and stream-level flows. -// It reports whether both windows have available capacity. -func takeInflows(f1, f2 *inflow, n uint32) bool { - if n > uint32(f1.avail) || n > uint32(f2.avail) { - return false - } - f1.avail -= int32(n) - f2.avail -= int32(n) - return true -} - -// outflow is the outbound flow control window's size. -type outflow struct { - _ incomparable - - // n is the number of DATA bytes we're allowed to send. - // An outflow is kept both on a conn and a per-stream. - n int32 - - // conn points to the shared connection-level outflow that is - // shared by all streams on that conn. It is nil for the outflow - // that's on the conn directly. - conn *outflow -} - -func (f *outflow) setConnFlow(cf *outflow) { f.conn = cf } - -func (f *outflow) available() int32 { - n := f.n - if f.conn != nil && f.conn.n < n { - n = f.conn.n - } - return n -} - -func (f *outflow) take(n int32) { - if n > f.available() { - panic("internal error: took too much") - } - f.n -= n - if f.conn != nil { - f.conn.n -= n - } -} - -// add adds n bytes (positive or negative) to the flow control window. -// It returns false if the sum would exceed 2^31-1. -func (f *outflow) add(n int32) bool { - sum := f.n + n - if (sum > n) == (f.n > 0) { - f.n = sum - return true - } - return false -} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go deleted file mode 100644 index 81faec7..0000000 --- a/vendor/golang.org/x/net/http2/frame.go +++ /dev/null @@ -1,1691 +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 http2 - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "log" - "strings" - "sync" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" -) - -const frameHeaderLen = 9 - -var padZeros = make([]byte, 255) // zeros for padding - -// A FrameType is a registered frame type as defined in -// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 -type FrameType uint8 - -const ( - FrameData FrameType = 0x0 - FrameHeaders FrameType = 0x1 - FramePriority FrameType = 0x2 - FrameRSTStream FrameType = 0x3 - FrameSettings FrameType = 0x4 - FramePushPromise FrameType = 0x5 - FramePing FrameType = 0x6 - FrameGoAway FrameType = 0x7 - FrameWindowUpdate FrameType = 0x8 - FrameContinuation FrameType = 0x9 -) - -var frameName = map[FrameType]string{ - FrameData: "DATA", - FrameHeaders: "HEADERS", - FramePriority: "PRIORITY", - FrameRSTStream: "RST_STREAM", - FrameSettings: "SETTINGS", - FramePushPromise: "PUSH_PROMISE", - FramePing: "PING", - FrameGoAway: "GOAWAY", - FrameWindowUpdate: "WINDOW_UPDATE", - FrameContinuation: "CONTINUATION", -} - -func (t FrameType) String() string { - if s, ok := frameName[t]; ok { - return s - } - return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t)) -} - -// Flags is a bitmask of HTTP/2 flags. -// The meaning of flags varies depending on the frame type. -type Flags uint8 - -// Has reports whether f contains all (0 or more) flags in v. -func (f Flags) Has(v Flags) bool { - return (f & v) == v -} - -// Frame-specific FrameHeader flag bits. -const ( - // Data Frame - FlagDataEndStream Flags = 0x1 - FlagDataPadded Flags = 0x8 - - // Headers Frame - FlagHeadersEndStream Flags = 0x1 - FlagHeadersEndHeaders Flags = 0x4 - FlagHeadersPadded Flags = 0x8 - FlagHeadersPriority Flags = 0x20 - - // Settings Frame - FlagSettingsAck Flags = 0x1 - - // Ping Frame - FlagPingAck Flags = 0x1 - - // Continuation Frame - FlagContinuationEndHeaders Flags = 0x4 - - FlagPushPromiseEndHeaders Flags = 0x4 - FlagPushPromisePadded Flags = 0x8 -) - -var flagName = map[FrameType]map[Flags]string{ - FrameData: { - FlagDataEndStream: "END_STREAM", - FlagDataPadded: "PADDED", - }, - FrameHeaders: { - FlagHeadersEndStream: "END_STREAM", - FlagHeadersEndHeaders: "END_HEADERS", - FlagHeadersPadded: "PADDED", - FlagHeadersPriority: "PRIORITY", - }, - FrameSettings: { - FlagSettingsAck: "ACK", - }, - FramePing: { - FlagPingAck: "ACK", - }, - FrameContinuation: { - FlagContinuationEndHeaders: "END_HEADERS", - }, - FramePushPromise: { - FlagPushPromiseEndHeaders: "END_HEADERS", - FlagPushPromisePadded: "PADDED", - }, -} - -// a frameParser parses a frame given its FrameHeader and payload -// bytes. The length of payload will always equal fh.Length (which -// might be 0). -type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) - -var frameParsers = map[FrameType]frameParser{ - FrameData: parseDataFrame, - FrameHeaders: parseHeadersFrame, - FramePriority: parsePriorityFrame, - FrameRSTStream: parseRSTStreamFrame, - FrameSettings: parseSettingsFrame, - FramePushPromise: parsePushPromise, - FramePing: parsePingFrame, - FrameGoAway: parseGoAwayFrame, - FrameWindowUpdate: parseWindowUpdateFrame, - FrameContinuation: parseContinuationFrame, -} - -func typeFrameParser(t FrameType) frameParser { - if f := frameParsers[t]; f != nil { - return f - } - return parseUnknownFrame -} - -// A FrameHeader is the 9 byte header of all HTTP/2 frames. -// -// See https://httpwg.org/specs/rfc7540.html#FrameHeader -type FrameHeader struct { - valid bool // caller can access []byte fields in the Frame - - // Type is the 1 byte frame type. There are ten standard frame - // types, but extension frame types may be written by WriteRawFrame - // and will be returned by ReadFrame (as UnknownFrame). - Type FrameType - - // Flags are the 1 byte of 8 potential bit flags per frame. - // They are specific to the frame type. - Flags Flags - - // Length is the length of the frame, not including the 9 byte header. - // The maximum size is one byte less than 16MB (uint24), but only - // frames up to 16KB are allowed without peer agreement. - Length uint32 - - // StreamID is which stream this frame is for. Certain frames - // are not stream-specific, in which case this field is 0. - StreamID uint32 -} - -// Header returns h. It exists so FrameHeaders can be embedded in other -// specific frame types and implement the Frame interface. -func (h FrameHeader) Header() FrameHeader { return h } - -func (h FrameHeader) String() string { - var buf bytes.Buffer - buf.WriteString("[FrameHeader ") - h.writeDebug(&buf) - buf.WriteByte(']') - return buf.String() -} - -func (h FrameHeader) writeDebug(buf *bytes.Buffer) { - buf.WriteString(h.Type.String()) - if h.Flags != 0 { - buf.WriteString(" flags=") - set := 0 - for i := uint8(0); i < 8; i++ { - if h.Flags&(1< 1 { - buf.WriteByte('|') - } - name := flagName[h.Type][Flags(1<>24), - byte(streamID>>16), - byte(streamID>>8), - byte(streamID)) -} - -func (f *Framer) endWrite() error { - // Now that we know the final size, fill in the FrameHeader in - // the space previously reserved for it. Abuse append. - length := len(f.wbuf) - frameHeaderLen - if length >= (1 << 24) { - return ErrFrameTooLarge - } - _ = append(f.wbuf[:0], - byte(length>>16), - byte(length>>8), - byte(length)) - if f.logWrites { - f.logWrite() - } - - n, err := f.w.Write(f.wbuf) - if err == nil && n != len(f.wbuf) { - err = io.ErrShortWrite - } - return err -} - -func (f *Framer) logWrite() { - if f.debugFramer == nil { - f.debugFramerBuf = new(bytes.Buffer) - f.debugFramer = NewFramer(nil, f.debugFramerBuf) - f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below - // Let us read anything, even if we accidentally wrote it - // in the wrong order: - f.debugFramer.AllowIllegalReads = true - } - f.debugFramerBuf.Write(f.wbuf) - fr, err := f.debugFramer.ReadFrame() - if err != nil { - f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f) - return - } - f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr)) -} - -func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) } -func (f *Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) } -func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) } -func (f *Framer) writeUint32(v uint32) { - f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) -} - -const ( - minMaxFrameSize = 1 << 14 - maxFrameSize = 1<<24 - 1 -) - -// SetReuseFrames allows the Framer to reuse Frames. -// If called on a Framer, Frames returned by calls to ReadFrame are only -// valid until the next call to ReadFrame. -func (fr *Framer) SetReuseFrames() { - if fr.frameCache != nil { - return - } - fr.frameCache = &frameCache{} -} - -type frameCache struct { - dataFrame DataFrame -} - -func (fc *frameCache) getDataFrame() *DataFrame { - if fc == nil { - return &DataFrame{} - } - return &fc.dataFrame -} - -// NewFramer returns a Framer that writes frames to w and reads them from r. -func NewFramer(w io.Writer, r io.Reader) *Framer { - fr := &Framer{ - w: w, - r: r, - countError: func(string) {}, - logReads: logFrameReads, - logWrites: logFrameWrites, - debugReadLoggerf: log.Printf, - debugWriteLoggerf: log.Printf, - } - fr.getReadBuf = func(size uint32) []byte { - if cap(fr.readBuf) >= int(size) { - return fr.readBuf[:size] - } - fr.readBuf = make([]byte, size) - return fr.readBuf - } - fr.SetMaxReadFrameSize(maxFrameSize) - return fr -} - -// SetMaxReadFrameSize sets the maximum size of a frame -// that will be read by a subsequent call to ReadFrame. -// It is the caller's responsibility to advertise this -// limit with a SETTINGS frame. -func (fr *Framer) SetMaxReadFrameSize(v uint32) { - if v > maxFrameSize { - v = maxFrameSize - } - fr.maxReadSize = v -} - -// ErrorDetail returns a more detailed error of the last error -// returned by Framer.ReadFrame. For instance, if ReadFrame -// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail -// will say exactly what was invalid. ErrorDetail is not guaranteed -// to return a non-nil value and like the rest of the http2 package, -// its return value is not protected by an API compatibility promise. -// ErrorDetail is reset after the next call to ReadFrame. -func (fr *Framer) ErrorDetail() error { - return fr.errDetail -} - -// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer -// sends a frame that is larger than declared with SetMaxReadFrameSize. -var ErrFrameTooLarge = errors.New("http2: frame too large") - -// terminalReadFrameError reports whether err is an unrecoverable -// error from ReadFrame and no other frames should be read. -func terminalReadFrameError(err error) bool { - if _, ok := err.(StreamError); ok { - return false - } - return err != nil -} - -// ReadFrame reads a single frame. The returned Frame is only valid -// until the next call to ReadFrame. -// -// If the frame is larger than previously set with SetMaxReadFrameSize, the -// returned error is ErrFrameTooLarge. Other errors may be of type -// ConnectionError, StreamError, or anything else from the underlying -// reader. -// -// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID -// indicates the stream responsible for the error. -func (fr *Framer) ReadFrame() (Frame, error) { - fr.errDetail = nil - if fr.lastFrame != nil { - fr.lastFrame.invalidate() - } - fh, err := readFrameHeader(fr.headerBuf[:], fr.r) - if err != nil { - return nil, err - } - if fh.Length > fr.maxReadSize { - return nil, ErrFrameTooLarge - } - payload := fr.getReadBuf(fh.Length) - if _, err := io.ReadFull(fr.r, payload); err != nil { - return nil, err - } - f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload) - if err != nil { - if ce, ok := err.(connError); ok { - return nil, fr.connError(ce.Code, ce.Reason) - } - return nil, err - } - if err := fr.checkFrameOrder(f); err != nil { - return nil, err - } - if fr.logReads { - fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f)) - } - if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil { - return fr.readMetaFrame(f.(*HeadersFrame)) - } - return f, nil -} - -// connError returns ConnectionError(code) but first -// stashes away a public reason to the caller can optionally relay it -// to the peer before hanging up on them. This might help others debug -// their implementations. -func (fr *Framer) connError(code ErrCode, reason string) error { - fr.errDetail = errors.New(reason) - return ConnectionError(code) -} - -// checkFrameOrder reports an error if f is an invalid frame to return -// next from ReadFrame. Mostly it checks whether HEADERS and -// CONTINUATION frames are contiguous. -func (fr *Framer) checkFrameOrder(f Frame) error { - last := fr.lastFrame - fr.lastFrame = f - if fr.AllowIllegalReads { - return nil - } - - fh := f.Header() - if fr.lastHeaderStream != 0 { - if fh.Type != FrameContinuation { - return fr.connError(ErrCodeProtocol, - fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d", - fh.Type, fh.StreamID, - last.Header().Type, fr.lastHeaderStream)) - } - if fh.StreamID != fr.lastHeaderStream { - return fr.connError(ErrCodeProtocol, - fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d", - fh.StreamID, fr.lastHeaderStream)) - } - } else if fh.Type == FrameContinuation { - return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID)) - } - - switch fh.Type { - case FrameHeaders, FrameContinuation: - if fh.Flags.Has(FlagHeadersEndHeaders) { - fr.lastHeaderStream = 0 - } else { - fr.lastHeaderStream = fh.StreamID - } - } - - return nil -} - -// A DataFrame conveys arbitrary, variable-length sequences of octets -// associated with a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 -type DataFrame struct { - FrameHeader - data []byte -} - -func (f *DataFrame) StreamEnded() bool { - return f.FrameHeader.Flags.Has(FlagDataEndStream) -} - -// Data returns the frame's data octets, not including any padding -// size byte or padding suffix bytes. -// The caller must not retain the returned memory past the next -// call to ReadFrame. -func (f *DataFrame) Data() []byte { - f.checkValid() - return f.data -} - -func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { - if fh.StreamID == 0 { - // DATA frames MUST be associated with a stream. If a - // DATA frame is received whose stream identifier - // field is 0x0, the recipient MUST respond with a - // connection error (Section 5.4.1) of type - // PROTOCOL_ERROR. - countError("frame_data_stream_0") - return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} - } - f := fc.getDataFrame() - f.FrameHeader = fh - - var padSize byte - if fh.Flags.Has(FlagDataPadded) { - var err error - payload, padSize, err = readByte(payload) - if err != nil { - countError("frame_data_pad_byte_short") - return nil, err - } - } - if int(padSize) > len(payload) { - // If the length of the padding is greater than the - // length of the frame payload, the recipient MUST - // treat this as a connection error. - // Filed: https://github.com/http2/http2-spec/issues/610 - countError("frame_data_pad_too_big") - return nil, connError{ErrCodeProtocol, "pad size larger than data payload"} - } - f.data = payload[:len(payload)-int(padSize)] - return f, nil -} - -var ( - errStreamID = errors.New("invalid stream ID") - errDepStreamID = errors.New("invalid dependent stream ID") - errPadLength = errors.New("pad length too large") - errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") -) - -func validStreamIDOrZero(streamID uint32) bool { - return streamID&(1<<31) == 0 -} - -func validStreamID(streamID uint32) bool { - return streamID != 0 && streamID&(1<<31) == 0 -} - -// WriteData writes a DATA frame. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility not to violate the maximum frame size -// and to not call other Write methods concurrently. -func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { - return f.WriteDataPadded(streamID, endStream, data, nil) -} - -// WriteDataPadded writes a DATA frame with optional padding. -// -// If pad is nil, the padding bit is not sent. -// The length of pad must not exceed 255 bytes. -// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility not to violate the maximum frame size -// and to not call other Write methods concurrently. -func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { - if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil { - return err - } - return f.endWrite() -} - -// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer. -// The caller should call endWrite to flush the frame to the underlying writer. -func (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error { - if !validStreamID(streamID) && !f.AllowIllegalWrites { - return errStreamID - } - if len(pad) > 0 { - if len(pad) > 255 { - return errPadLength - } - if !f.AllowIllegalWrites { - for _, b := range pad { - if b != 0 { - // "Padding octets MUST be set to zero when sending." - return errPadBytes - } - } - } - } - var flags Flags - if endStream { - flags |= FlagDataEndStream - } - if pad != nil { - flags |= FlagDataPadded - } - f.startWrite(FrameData, flags, streamID) - if pad != nil { - f.wbuf = append(f.wbuf, byte(len(pad))) - } - f.wbuf = append(f.wbuf, data...) - f.wbuf = append(f.wbuf, pad...) - return nil -} - -// A SettingsFrame conveys configuration parameters that affect how -// endpoints communicate, such as preferences and constraints on peer -// behavior. -// -// See https://httpwg.org/specs/rfc7540.html#SETTINGS -type SettingsFrame struct { - FrameHeader - p []byte -} - -func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { - // When this (ACK 0x1) bit is set, the payload of the - // SETTINGS frame MUST be empty. Receipt of a - // SETTINGS frame with the ACK flag set and a length - // field value other than 0 MUST be treated as a - // connection error (Section 5.4.1) of type - // FRAME_SIZE_ERROR. - countError("frame_settings_ack_with_length") - return nil, ConnectionError(ErrCodeFrameSize) - } - if fh.StreamID != 0 { - // SETTINGS frames always apply to a connection, - // never a single stream. The stream identifier for a - // SETTINGS frame MUST be zero (0x0). If an endpoint - // receives a SETTINGS frame whose stream identifier - // field is anything other than 0x0, the endpoint MUST - // respond with a connection error (Section 5.4.1) of - // type PROTOCOL_ERROR. - countError("frame_settings_has_stream") - return nil, ConnectionError(ErrCodeProtocol) - } - if len(p)%6 != 0 { - countError("frame_settings_mod_6") - // Expecting even number of 6 byte settings. - return nil, ConnectionError(ErrCodeFrameSize) - } - f := &SettingsFrame{FrameHeader: fh, p: p} - if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 { - countError("frame_settings_window_size_too_big") - // Values above the maximum flow control window size of 2^31 - 1 MUST - // be treated as a connection error (Section 5.4.1) of type - // FLOW_CONTROL_ERROR. - return nil, ConnectionError(ErrCodeFlowControl) - } - return f, nil -} - -func (f *SettingsFrame) IsAck() bool { - return f.FrameHeader.Flags.Has(FlagSettingsAck) -} - -func (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) { - f.checkValid() - for i := 0; i < f.NumSettings(); i++ { - if s := f.Setting(i); s.ID == id { - return s.Val, true - } - } - return 0, false -} - -// Setting returns the setting from the frame at the given 0-based index. -// The index must be >= 0 and less than f.NumSettings(). -func (f *SettingsFrame) Setting(i int) Setting { - buf := f.p - return Setting{ - ID: SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])), - Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]), - } -} - -func (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 } - -// HasDuplicates reports whether f contains any duplicate setting IDs. -func (f *SettingsFrame) HasDuplicates() bool { - num := f.NumSettings() - if num == 0 { - return false - } - // If it's small enough (the common case), just do the n^2 - // thing and avoid a map allocation. - if num < 10 { - for i := 0; i < num; i++ { - idi := f.Setting(i).ID - for j := i + 1; j < num; j++ { - idj := f.Setting(j).ID - if idi == idj { - return true - } - } - } - return false - } - seen := map[SettingID]bool{} - for i := 0; i < num; i++ { - id := f.Setting(i).ID - if seen[id] { - return true - } - seen[id] = true - } - return false -} - -// ForeachSetting runs fn for each setting. -// It stops and returns the first error. -func (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error { - f.checkValid() - for i := 0; i < f.NumSettings(); i++ { - if err := fn(f.Setting(i)); err != nil { - return err - } - } - return nil -} - -// WriteSettings writes a SETTINGS frame with zero or more settings -// specified and the ACK bit not set. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WriteSettings(settings ...Setting) error { - f.startWrite(FrameSettings, 0, 0) - for _, s := range settings { - f.writeUint16(uint16(s.ID)) - f.writeUint32(s.Val) - } - return f.endWrite() -} - -// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WriteSettingsAck() error { - f.startWrite(FrameSettings, FlagSettingsAck, 0) - return f.endWrite() -} - -// A PingFrame is a mechanism for measuring a minimal round trip time -// from the sender, as well as determining whether an idle connection -// is still functional. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 -type PingFrame struct { - FrameHeader - Data [8]byte -} - -func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } - -func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { - if len(payload) != 8 { - countError("frame_ping_length") - return nil, ConnectionError(ErrCodeFrameSize) - } - if fh.StreamID != 0 { - countError("frame_ping_has_stream") - return nil, ConnectionError(ErrCodeProtocol) - } - f := &PingFrame{FrameHeader: fh} - copy(f.Data[:], payload) - return f, nil -} - -func (f *Framer) WritePing(ack bool, data [8]byte) error { - var flags Flags - if ack { - flags = FlagPingAck - } - f.startWrite(FramePing, flags, 0) - f.writeBytes(data[:]) - return f.endWrite() -} - -// A GoAwayFrame informs the remote peer to stop creating streams on this connection. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 -type GoAwayFrame struct { - FrameHeader - LastStreamID uint32 - ErrCode ErrCode - debugData []byte -} - -// DebugData returns any debug data in the GOAWAY frame. Its contents -// are not defined. -// The caller must not retain the returned memory past the next -// call to ReadFrame. -func (f *GoAwayFrame) DebugData() []byte { - f.checkValid() - return f.debugData -} - -func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - if fh.StreamID != 0 { - countError("frame_goaway_has_stream") - return nil, ConnectionError(ErrCodeProtocol) - } - if len(p) < 8 { - countError("frame_goaway_short") - return nil, ConnectionError(ErrCodeFrameSize) - } - return &GoAwayFrame{ - FrameHeader: fh, - LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1), - ErrCode: ErrCode(binary.BigEndian.Uint32(p[4:8])), - debugData: p[8:], - }, nil -} - -func (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error { - f.startWrite(FrameGoAway, 0, 0) - f.writeUint32(maxStreamID & (1<<31 - 1)) - f.writeUint32(uint32(code)) - f.writeBytes(debugData) - return f.endWrite() -} - -// An UnknownFrame is the frame type returned when the frame type is unknown -// or no specific frame type parser exists. -type UnknownFrame struct { - FrameHeader - p []byte -} - -// Payload returns the frame's payload (after the header). It is not -// valid to call this method after a subsequent call to -// Framer.ReadFrame, nor is it valid to retain the returned slice. -// The memory is owned by the Framer and is invalidated when the next -// frame is read. -func (f *UnknownFrame) Payload() []byte { - f.checkValid() - return f.p -} - -func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - return &UnknownFrame{fh, p}, nil -} - -// A WindowUpdateFrame is used to implement flow control. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 -type WindowUpdateFrame struct { - FrameHeader - Increment uint32 // never read with high bit set -} - -func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - if len(p) != 4 { - countError("frame_windowupdate_bad_len") - return nil, ConnectionError(ErrCodeFrameSize) - } - inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit - if inc == 0 { - // A receiver MUST treat the receipt of a - // WINDOW_UPDATE frame with an flow control window - // increment of 0 as a stream error (Section 5.4.2) of - // type PROTOCOL_ERROR; errors on the connection flow - // control window MUST be treated as a connection - // error (Section 5.4.1). - if fh.StreamID == 0 { - countError("frame_windowupdate_zero_inc_conn") - return nil, ConnectionError(ErrCodeProtocol) - } - countError("frame_windowupdate_zero_inc_stream") - return nil, streamError(fh.StreamID, ErrCodeProtocol) - } - return &WindowUpdateFrame{ - FrameHeader: fh, - Increment: inc, - }, nil -} - -// WriteWindowUpdate writes a WINDOW_UPDATE frame. -// The increment value must be between 1 and 2,147,483,647, inclusive. -// If the Stream ID is zero, the window update applies to the -// connection as a whole. -func (f *Framer) WriteWindowUpdate(streamID, incr uint32) error { - // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets." - if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites { - return errors.New("illegal window increment value") - } - f.startWrite(FrameWindowUpdate, 0, streamID) - f.writeUint32(incr) - return f.endWrite() -} - -// A HeadersFrame is used to open a stream and additionally carries a -// header block fragment. -type HeadersFrame struct { - FrameHeader - - // Priority is set if FlagHeadersPriority is set in the FrameHeader. - Priority PriorityParam - - headerFragBuf []byte // not owned -} - -func (f *HeadersFrame) HeaderBlockFragment() []byte { - f.checkValid() - return f.headerFragBuf -} - -func (f *HeadersFrame) HeadersEnded() bool { - return f.FrameHeader.Flags.Has(FlagHeadersEndHeaders) -} - -func (f *HeadersFrame) StreamEnded() bool { - return f.FrameHeader.Flags.Has(FlagHeadersEndStream) -} - -func (f *HeadersFrame) HasPriority() bool { - return f.FrameHeader.Flags.Has(FlagHeadersPriority) -} - -func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { - hf := &HeadersFrame{ - FrameHeader: fh, - } - if fh.StreamID == 0 { - // HEADERS frames MUST be associated with a stream. If a HEADERS frame - // is received whose stream identifier field is 0x0, the recipient MUST - // respond with a connection error (Section 5.4.1) of type - // PROTOCOL_ERROR. - countError("frame_headers_zero_stream") - return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"} - } - var padLength uint8 - if fh.Flags.Has(FlagHeadersPadded) { - if p, padLength, err = readByte(p); err != nil { - countError("frame_headers_pad_short") - return - } - } - if fh.Flags.Has(FlagHeadersPriority) { - var v uint32 - p, v, err = readUint32(p) - if err != nil { - countError("frame_headers_prio_short") - return nil, err - } - hf.Priority.StreamDep = v & 0x7fffffff - hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set - p, hf.Priority.Weight, err = readByte(p) - if err != nil { - countError("frame_headers_prio_weight_short") - return nil, err - } - } - if len(p)-int(padLength) < 0 { - countError("frame_headers_pad_too_big") - return nil, streamError(fh.StreamID, ErrCodeProtocol) - } - hf.headerFragBuf = p[:len(p)-int(padLength)] - return hf, nil -} - -// HeadersFrameParam are the parameters for writing a HEADERS frame. -type HeadersFrameParam struct { - // StreamID is the required Stream ID to initiate. - StreamID uint32 - // BlockFragment is part (or all) of a Header Block. - BlockFragment []byte - - // EndStream indicates that the header block is the last that - // the endpoint will send for the identified stream. Setting - // this flag causes the stream to enter one of "half closed" - // states. - EndStream bool - - // EndHeaders indicates that this frame contains an entire - // header block and is not followed by any - // CONTINUATION frames. - EndHeaders bool - - // PadLength is the optional number of bytes of zeros to add - // to this frame. - PadLength uint8 - - // Priority, if non-zero, includes stream priority information - // in the HEADER frame. - Priority PriorityParam -} - -// WriteHeaders writes a single HEADERS frame. -// -// This is a low-level header writing method. Encoding headers and -// splitting them into any necessary CONTINUATION frames is handled -// elsewhere. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WriteHeaders(p HeadersFrameParam) error { - if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { - return errStreamID - } - var flags Flags - if p.PadLength != 0 { - flags |= FlagHeadersPadded - } - if p.EndStream { - flags |= FlagHeadersEndStream - } - if p.EndHeaders { - flags |= FlagHeadersEndHeaders - } - if !p.Priority.IsZero() { - flags |= FlagHeadersPriority - } - f.startWrite(FrameHeaders, flags, p.StreamID) - if p.PadLength != 0 { - f.writeByte(p.PadLength) - } - if !p.Priority.IsZero() { - v := p.Priority.StreamDep - if !validStreamIDOrZero(v) && !f.AllowIllegalWrites { - return errDepStreamID - } - if p.Priority.Exclusive { - v |= 1 << 31 - } - f.writeUint32(v) - f.writeByte(p.Priority.Weight) - } - f.wbuf = append(f.wbuf, p.BlockFragment...) - f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) - return f.endWrite() -} - -// A PriorityFrame specifies the sender-advised priority of a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 -type PriorityFrame struct { - FrameHeader - PriorityParam -} - -// PriorityParam are the stream prioritzation parameters. -type PriorityParam struct { - // StreamDep is a 31-bit stream identifier for the - // stream that this stream depends on. Zero means no - // dependency. - StreamDep uint32 - - // Exclusive is whether the dependency is exclusive. - Exclusive bool - - // Weight is the stream's zero-indexed weight. It should be - // set together with StreamDep, or neither should be set. Per - // the spec, "Add one to the value to obtain a weight between - // 1 and 256." - Weight uint8 -} - -func (p PriorityParam) IsZero() bool { - return p == PriorityParam{} -} - -func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) { - if fh.StreamID == 0 { - countError("frame_priority_zero_stream") - return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} - } - if len(payload) != 5 { - countError("frame_priority_bad_length") - return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))} - } - v := binary.BigEndian.Uint32(payload[:4]) - streamID := v & 0x7fffffff // mask off high bit - return &PriorityFrame{ - FrameHeader: fh, - PriorityParam: PriorityParam{ - Weight: payload[4], - StreamDep: streamID, - Exclusive: streamID != v, // was high bit set? - }, - }, nil -} - -// WritePriority writes a PRIORITY frame. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { - if !validStreamID(streamID) && !f.AllowIllegalWrites { - return errStreamID - } - if !validStreamIDOrZero(p.StreamDep) { - return errDepStreamID - } - f.startWrite(FramePriority, 0, streamID) - v := p.StreamDep - if p.Exclusive { - v |= 1 << 31 - } - f.writeUint32(v) - f.writeByte(p.Weight) - return f.endWrite() -} - -// A RSTStreamFrame allows for abnormal termination of a stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 -type RSTStreamFrame struct { - FrameHeader - ErrCode ErrCode -} - -func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - if len(p) != 4 { - countError("frame_rststream_bad_len") - return nil, ConnectionError(ErrCodeFrameSize) - } - if fh.StreamID == 0 { - countError("frame_rststream_zero_stream") - return nil, ConnectionError(ErrCodeProtocol) - } - return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil -} - -// WriteRSTStream writes a RST_STREAM frame. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { - if !validStreamID(streamID) && !f.AllowIllegalWrites { - return errStreamID - } - f.startWrite(FrameRSTStream, 0, streamID) - f.writeUint32(uint32(code)) - return f.endWrite() -} - -// A ContinuationFrame is used to continue a sequence of header block fragments. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 -type ContinuationFrame struct { - FrameHeader - headerFragBuf []byte -} - -func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) { - if fh.StreamID == 0 { - countError("frame_continuation_zero_stream") - return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} - } - return &ContinuationFrame{fh, p}, nil -} - -func (f *ContinuationFrame) HeaderBlockFragment() []byte { - f.checkValid() - return f.headerFragBuf -} - -func (f *ContinuationFrame) HeadersEnded() bool { - return f.FrameHeader.Flags.Has(FlagContinuationEndHeaders) -} - -// WriteContinuation writes a CONTINUATION frame. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error { - if !validStreamID(streamID) && !f.AllowIllegalWrites { - return errStreamID - } - var flags Flags - if endHeaders { - flags |= FlagContinuationEndHeaders - } - f.startWrite(FrameContinuation, flags, streamID) - f.wbuf = append(f.wbuf, headerBlockFragment...) - return f.endWrite() -} - -// A PushPromiseFrame is used to initiate a server stream. -// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 -type PushPromiseFrame struct { - FrameHeader - PromiseID uint32 - headerFragBuf []byte // not owned -} - -func (f *PushPromiseFrame) HeaderBlockFragment() []byte { - f.checkValid() - return f.headerFragBuf -} - -func (f *PushPromiseFrame) HeadersEnded() bool { - return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) -} - -func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) { - pp := &PushPromiseFrame{ - FrameHeader: fh, - } - if pp.StreamID == 0 { - // PUSH_PROMISE frames MUST be associated with an existing, - // peer-initiated stream. The stream identifier of a - // PUSH_PROMISE frame indicates the stream it is associated - // with. If the stream identifier field specifies the value - // 0x0, a recipient MUST respond with a connection error - // (Section 5.4.1) of type PROTOCOL_ERROR. - countError("frame_pushpromise_zero_stream") - return nil, ConnectionError(ErrCodeProtocol) - } - // The PUSH_PROMISE frame includes optional padding. - // Padding fields and flags are identical to those defined for DATA frames - var padLength uint8 - if fh.Flags.Has(FlagPushPromisePadded) { - if p, padLength, err = readByte(p); err != nil { - countError("frame_pushpromise_pad_short") - return - } - } - - p, pp.PromiseID, err = readUint32(p) - if err != nil { - countError("frame_pushpromise_promiseid_short") - return - } - pp.PromiseID = pp.PromiseID & (1<<31 - 1) - - if int(padLength) > len(p) { - // like the DATA frame, error out if padding is longer than the body. - countError("frame_pushpromise_pad_too_big") - return nil, ConnectionError(ErrCodeProtocol) - } - pp.headerFragBuf = p[:len(p)-int(padLength)] - return pp, nil -} - -// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame. -type PushPromiseParam struct { - // StreamID is the required Stream ID to initiate. - StreamID uint32 - - // PromiseID is the required Stream ID which this - // Push Promises - PromiseID uint32 - - // BlockFragment is part (or all) of a Header Block. - BlockFragment []byte - - // EndHeaders indicates that this frame contains an entire - // header block and is not followed by any - // CONTINUATION frames. - EndHeaders bool - - // PadLength is the optional number of bytes of zeros to add - // to this frame. - PadLength uint8 -} - -// WritePushPromise writes a single PushPromise Frame. -// -// As with Header Frames, This is the low level call for writing -// individual frames. Continuation frames are handled elsewhere. -// -// It will perform exactly one Write to the underlying Writer. -// It is the caller's responsibility to not call other Write methods concurrently. -func (f *Framer) WritePushPromise(p PushPromiseParam) error { - if !validStreamID(p.StreamID) && !f.AllowIllegalWrites { - return errStreamID - } - var flags Flags - if p.PadLength != 0 { - flags |= FlagPushPromisePadded - } - if p.EndHeaders { - flags |= FlagPushPromiseEndHeaders - } - f.startWrite(FramePushPromise, flags, p.StreamID) - if p.PadLength != 0 { - f.writeByte(p.PadLength) - } - if !validStreamID(p.PromiseID) && !f.AllowIllegalWrites { - return errStreamID - } - f.writeUint32(p.PromiseID) - f.wbuf = append(f.wbuf, p.BlockFragment...) - f.wbuf = append(f.wbuf, padZeros[:p.PadLength]...) - return f.endWrite() -} - -// WriteRawFrame writes a raw frame. This can be used to write -// extension frames unknown to this package. -func (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error { - f.startWrite(t, flags, streamID) - f.writeBytes(payload) - return f.endWrite() -} - -func readByte(p []byte) (remain []byte, b byte, err error) { - if len(p) == 0 { - return nil, 0, io.ErrUnexpectedEOF - } - return p[1:], p[0], nil -} - -func readUint32(p []byte) (remain []byte, v uint32, err error) { - if len(p) < 4 { - return nil, 0, io.ErrUnexpectedEOF - } - return p[4:], binary.BigEndian.Uint32(p[:4]), nil -} - -type streamEnder interface { - StreamEnded() bool -} - -type headersEnder interface { - HeadersEnded() bool -} - -type headersOrContinuation interface { - headersEnder - HeaderBlockFragment() []byte -} - -// A MetaHeadersFrame is the representation of one HEADERS frame and -// zero or more contiguous CONTINUATION frames and the decoding of -// their HPACK-encoded contents. -// -// This type of frame does not appear on the wire and is only returned -// by the Framer when Framer.ReadMetaHeaders is set. -type MetaHeadersFrame struct { - *HeadersFrame - - // Fields are the fields contained in the HEADERS and - // CONTINUATION frames. The underlying slice is owned by the - // Framer and must not be retained after the next call to - // ReadFrame. - // - // Fields are guaranteed to be in the correct http2 order and - // not have unknown pseudo header fields or invalid header - // field names or values. Required pseudo header fields may be - // missing, however. Use the MetaHeadersFrame.Pseudo accessor - // method access pseudo headers. - Fields []hpack.HeaderField - - // Truncated is whether the max header list size limit was hit - // and Fields is incomplete. The hpack decoder state is still - // valid, however. - Truncated bool -} - -// PseudoValue returns the given pseudo header field's value. -// The provided pseudo field should not contain the leading colon. -func (mh *MetaHeadersFrame) PseudoValue(pseudo string) string { - for _, hf := range mh.Fields { - if !hf.IsPseudo() { - return "" - } - if hf.Name[1:] == pseudo { - return hf.Value - } - } - return "" -} - -// RegularFields returns the regular (non-pseudo) header fields of mh. -// The caller does not own the returned slice. -func (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField { - for i, hf := range mh.Fields { - if !hf.IsPseudo() { - return mh.Fields[i:] - } - } - return nil -} - -// PseudoFields returns the pseudo header fields of mh. -// The caller does not own the returned slice. -func (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField { - for i, hf := range mh.Fields { - if !hf.IsPseudo() { - return mh.Fields[:i] - } - } - return mh.Fields -} - -func (mh *MetaHeadersFrame) checkPseudos() error { - var isRequest, isResponse bool - pf := mh.PseudoFields() - for i, hf := range pf { - switch hf.Name { - case ":method", ":path", ":scheme", ":authority", ":protocol": - isRequest = true - case ":status": - isResponse = true - default: - return pseudoHeaderError(hf.Name) - } - // Check for duplicates. - // This would be a bad algorithm, but N is 5. - // And this doesn't allocate. - for _, hf2 := range pf[:i] { - if hf.Name == hf2.Name { - return duplicatePseudoHeaderError(hf.Name) - } - } - } - if isRequest && isResponse { - return errMixPseudoHeaderTypes - } - return nil -} - -func (fr *Framer) maxHeaderStringLen() int { - v := int(fr.maxHeaderListSize()) - if v < 0 { - // If maxHeaderListSize overflows an int, use no limit (0). - return 0 - } - return v -} - -// readMetaFrame returns 0 or more CONTINUATION frames from fr and -// merge them into the provided hf and returns a MetaHeadersFrame -// with the decoded hpack values. -func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) { - if fr.AllowIllegalReads { - return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders") - } - mh := &MetaHeadersFrame{ - HeadersFrame: hf, - } - var remainSize = fr.maxHeaderListSize() - var sawRegular bool - - var invalid error // pseudo header field errors - hdec := fr.ReadMetaHeaders - hdec.SetEmitEnabled(true) - hdec.SetMaxStringLength(fr.maxHeaderStringLen()) - hdec.SetEmitFunc(func(hf hpack.HeaderField) { - if VerboseLogs && fr.logReads { - fr.debugReadLoggerf("http2: decoded hpack field %+v", hf) - } - if !httpguts.ValidHeaderFieldValue(hf.Value) { - // Don't include the value in the error, because it may be sensitive. - invalid = headerFieldValueError(hf.Name) - } - isPseudo := strings.HasPrefix(hf.Name, ":") - if isPseudo { - if sawRegular { - invalid = errPseudoAfterRegular - } - } else { - sawRegular = true - if !validWireHeaderFieldName(hf.Name) { - invalid = headerFieldNameError(hf.Name) - } - } - - if invalid != nil { - hdec.SetEmitEnabled(false) - return - } - - size := hf.Size() - if size > remainSize { - hdec.SetEmitEnabled(false) - mh.Truncated = true - remainSize = 0 - return - } - remainSize -= size - - mh.Fields = append(mh.Fields, hf) - }) - // Lose reference to MetaHeadersFrame: - defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) - - var hc headersOrContinuation = hf - for { - frag := hc.HeaderBlockFragment() - - // Avoid parsing large amounts of headers that we will then discard. - // If the sender exceeds the max header list size by too much, - // skip parsing the fragment and close the connection. - // - // "Too much" is either any CONTINUATION frame after we've already - // exceeded the max header list size (in which case remainSize is 0), - // or a frame whose encoded size is more than twice the remaining - // header list bytes we're willing to accept. - if int64(len(frag)) > int64(2*remainSize) { - if VerboseLogs { - log.Printf("http2: header list too large") - } - // It would be nice to send a RST_STREAM before sending the GOAWAY, - // but the structure of the server's frame writer makes this difficult. - return mh, ConnectionError(ErrCodeProtocol) - } - - // Also close the connection after any CONTINUATION frame following an - // invalid header, since we stop tracking the size of the headers after - // an invalid one. - if invalid != nil { - if VerboseLogs { - log.Printf("http2: invalid header: %v", invalid) - } - // It would be nice to send a RST_STREAM before sending the GOAWAY, - // but the structure of the server's frame writer makes this difficult. - return mh, ConnectionError(ErrCodeProtocol) - } - - if _, err := hdec.Write(frag); err != nil { - return mh, ConnectionError(ErrCodeCompression) - } - - if hc.HeadersEnded() { - break - } - if f, err := fr.ReadFrame(); err != nil { - return nil, err - } else { - hc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder - } - } - - mh.HeadersFrame.headerFragBuf = nil - mh.HeadersFrame.invalidate() - - if err := hdec.Close(); err != nil { - return mh, ConnectionError(ErrCodeCompression) - } - if invalid != nil { - fr.errDetail = invalid - if VerboseLogs { - log.Printf("http2: invalid header: %v", invalid) - } - return nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid} - } - if err := mh.checkPseudos(); err != nil { - fr.errDetail = err - if VerboseLogs { - log.Printf("http2: invalid pseudo headers: %v", err) - } - return nil, StreamError{mh.StreamID, ErrCodeProtocol, err} - } - return mh, nil -} - -func summarizeFrame(f Frame) string { - var buf bytes.Buffer - f.Header().writeDebug(&buf) - switch f := f.(type) { - case *SettingsFrame: - n := 0 - f.ForeachSetting(func(s Setting) error { - n++ - if n == 1 { - buf.WriteString(", settings:") - } - fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val) - return nil - }) - if n > 0 { - buf.Truncate(buf.Len() - 1) // remove trailing comma - } - case *DataFrame: - data := f.Data() - const max = 256 - if len(data) > max { - data = data[:max] - } - fmt.Fprintf(&buf, " data=%q", data) - if len(f.Data()) > max { - fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max) - } - case *WindowUpdateFrame: - if f.StreamID == 0 { - buf.WriteString(" (conn)") - } - fmt.Fprintf(&buf, " incr=%v", f.Increment) - case *PingFrame: - fmt.Fprintf(&buf, " ping=%q", f.Data[:]) - case *GoAwayFrame: - fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q", - f.LastStreamID, f.ErrCode, f.debugData) - case *RSTStreamFrame: - fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode) - } - return buf.String() -} diff --git a/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go deleted file mode 100644 index 9933c9f..0000000 --- a/vendor/golang.org/x/net/http2/gotrack.go +++ /dev/null @@ -1,170 +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. - -// Defensive debug-only utility to track that functions run on the -// goroutine that they're supposed to. - -package http2 - -import ( - "bytes" - "errors" - "fmt" - "os" - "runtime" - "strconv" - "sync" -) - -var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" - -type goroutineLock uint64 - -func newGoroutineLock() goroutineLock { - if !DebugGoroutines { - return 0 - } - return goroutineLock(curGoroutineID()) -} - -func (g goroutineLock) check() { - if !DebugGoroutines { - return - } - if curGoroutineID() != uint64(g) { - panic("running on the wrong goroutine") - } -} - -func (g goroutineLock) checkNotOn() { - if !DebugGoroutines { - return - } - if curGoroutineID() == uint64(g) { - panic("running on the wrong goroutine") - } -} - -var goroutineSpace = []byte("goroutine ") - -func curGoroutineID() uint64 { - bp := littleBuf.Get().(*[]byte) - defer littleBuf.Put(bp) - b := *bp - b = b[:runtime.Stack(b, false)] - // Parse the 4707 out of "goroutine 4707 [" - b = bytes.TrimPrefix(b, goroutineSpace) - i := bytes.IndexByte(b, ' ') - if i < 0 { - panic(fmt.Sprintf("No space found in %q", b)) - } - b = b[:i] - n, err := parseUintBytes(b, 10, 64) - if err != nil { - panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err)) - } - return n -} - -var littleBuf = sync.Pool{ - New: func() interface{} { - buf := make([]byte, 64) - return &buf - }, -} - -// parseUintBytes is like strconv.ParseUint, but using a []byte. -func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) { - var cutoff, maxVal uint64 - - if bitSize == 0 { - bitSize = int(strconv.IntSize) - } - - s0 := s - switch { - case len(s) < 1: - err = strconv.ErrSyntax - goto Error - - case 2 <= base && base <= 36: - // valid base; nothing to do - - case base == 0: - // Look for octal, hex prefix. - switch { - case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'): - base = 16 - s = s[2:] - if len(s) < 1 { - err = strconv.ErrSyntax - goto Error - } - case s[0] == '0': - base = 8 - default: - base = 10 - } - - default: - err = errors.New("invalid base " + strconv.Itoa(base)) - goto Error - } - - n = 0 - cutoff = cutoff64(base) - maxVal = 1<= base { - n = 0 - err = strconv.ErrSyntax - goto Error - } - - if n >= cutoff { - // n*base overflows - n = 1<<64 - 1 - err = strconv.ErrRange - goto Error - } - n *= uint64(base) - - n1 := n + uint64(v) - if n1 < n || n1 > maxVal { - // n+v overflows - n = 1<<64 - 1 - err = strconv.ErrRange - goto Error - } - n = n1 - } - - return n, nil - -Error: - return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err} -} - -// Return the first number n such that n*base >= 1<<64. -func cutoff64(base int) uint64 { - if base < 2 { - return 0 - } - return (1<<64-1)/uint64(base) + 1 -} diff --git a/vendor/golang.org/x/net/http2/h2c/h2c.go b/vendor/golang.org/x/net/http2/h2c/h2c.go deleted file mode 100644 index 2d6bf86..0000000 --- a/vendor/golang.org/x/net/http2/h2c/h2c.go +++ /dev/null @@ -1,240 +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. - -// Package h2c implements the unencrypted "h2c" form of HTTP/2. -// -// The h2c protocol is the non-TLS version of HTTP/2 which is not available from -// net/http or golang.org/x/net/http2. -package h2c - -import ( - "bufio" - "bytes" - "encoding/base64" - "errors" - "fmt" - "io" - "log" - "net" - "net/http" - "net/textproto" - "os" - "strings" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2" -) - -var ( - http2VerboseLogs bool -) - -func init() { - e := os.Getenv("GODEBUG") - if strings.Contains(e, "http2debug=1") || strings.Contains(e, "http2debug=2") { - http2VerboseLogs = true - } -} - -// h2cHandler is a Handler which implements h2c by hijacking the HTTP/1 traffic -// that should be h2c traffic. There are two ways to begin a h2c connection -// (RFC 7540 Section 3.2 and 3.4): (1) Starting with Prior Knowledge - this -// works by starting an h2c connection with a string of bytes that is valid -// HTTP/1, but unlikely to occur in practice and (2) Upgrading from HTTP/1 to -// h2c - this works by using the HTTP/1 Upgrade header to request an upgrade to -// h2c. When either of those situations occur we hijack the HTTP/1 connection, -// convert it to an HTTP/2 connection and pass the net.Conn to http2.ServeConn. -type h2cHandler struct { - Handler http.Handler - s *http2.Server -} - -// NewHandler returns an http.Handler that wraps h, intercepting any h2c -// traffic. If a request is an h2c connection, it's hijacked and redirected to -// s.ServeConn. Otherwise the returned Handler just forwards requests to h. This -// works because h2c is designed to be parseable as valid HTTP/1, but ignored by -// any HTTP server that does not handle h2c. Therefore we leverage the HTTP/1 -// compatible parts of the Go http library to parse and recognize h2c requests. -// Once a request is recognized as h2c, we hijack the connection and convert it -// to an HTTP/2 connection which is understandable to s.ServeConn. (s.ServeConn -// understands HTTP/2 except for the h2c part of it.) -// -// The first request on an h2c connection is read entirely into memory before -// the Handler is called. To limit the memory consumed by this request, wrap -// the result of NewHandler in an http.MaxBytesHandler. -func NewHandler(h http.Handler, s *http2.Server) http.Handler { - return &h2cHandler{ - Handler: h, - s: s, - } -} - -// extractServer extracts existing http.Server instance from http.Request or create an empty http.Server -func extractServer(r *http.Request) *http.Server { - server, ok := r.Context().Value(http.ServerContextKey).(*http.Server) - if ok { - return server - } - return new(http.Server) -} - -// ServeHTTP implement the h2c support that is enabled by h2c.GetH2CHandler. -func (s h2cHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Handle h2c with prior knowledge (RFC 7540 Section 3.4) - if r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0" { - if http2VerboseLogs { - log.Print("h2c: attempting h2c with prior knowledge.") - } - conn, err := initH2CWithPriorKnowledge(w) - if err != nil { - if http2VerboseLogs { - log.Printf("h2c: error h2c with prior knowledge: %v", err) - } - return - } - defer conn.Close() - s.s.ServeConn(conn, &http2.ServeConnOpts{ - Context: r.Context(), - BaseConfig: extractServer(r), - Handler: s.Handler, - SawClientPreface: true, - }) - return - } - // Handle Upgrade to h2c (RFC 7540 Section 3.2) - if isH2CUpgrade(r.Header) { - conn, settings, err := h2cUpgrade(w, r) - if err != nil { - if http2VerboseLogs { - log.Printf("h2c: error h2c upgrade: %v", err) - } - w.WriteHeader(http.StatusInternalServerError) - return - } - defer conn.Close() - s.s.ServeConn(conn, &http2.ServeConnOpts{ - Context: r.Context(), - BaseConfig: extractServer(r), - Handler: s.Handler, - UpgradeRequest: r, - Settings: settings, - }) - return - } - s.Handler.ServeHTTP(w, r) - return -} - -// initH2CWithPriorKnowledge implements creating a h2c connection with prior -// knowledge (Section 3.4) and creates a net.Conn suitable for http2.ServeConn. -// All we have to do is look for the client preface that is suppose to be part -// of the body, and reforward the client preface on the net.Conn this function -// creates. -func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) { - hijacker, ok := w.(http.Hijacker) - if !ok { - return nil, errors.New("h2c: connection does not support Hijack") - } - conn, rw, err := hijacker.Hijack() - if err != nil { - return nil, err - } - - const expectedBody = "SM\r\n\r\n" - - buf := make([]byte, len(expectedBody)) - n, err := io.ReadFull(rw, buf) - if err != nil { - return nil, fmt.Errorf("h2c: error reading client preface: %s", err) - } - - if string(buf[:n]) == expectedBody { - return newBufConn(conn, rw), nil - } - - conn.Close() - return nil, errors.New("h2c: invalid client preface") -} - -// h2cUpgrade establishes a h2c connection using the HTTP/1 upgrade (Section 3.2). -func h2cUpgrade(w http.ResponseWriter, r *http.Request) (_ net.Conn, settings []byte, err error) { - settings, err = getH2Settings(r.Header) - if err != nil { - return nil, nil, err - } - hijacker, ok := w.(http.Hijacker) - if !ok { - return nil, nil, errors.New("h2c: connection does not support Hijack") - } - - body, err := io.ReadAll(r.Body) - if err != nil { - return nil, nil, err - } - r.Body = io.NopCloser(bytes.NewBuffer(body)) - - conn, rw, err := hijacker.Hijack() - if err != nil { - return nil, nil, err - } - - rw.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n" + - "Connection: Upgrade\r\n" + - "Upgrade: h2c\r\n\r\n")) - return newBufConn(conn, rw), settings, nil -} - -// isH2CUpgrade returns true if the header properly request an upgrade to h2c -// as specified by Section 3.2. -func isH2CUpgrade(h http.Header) bool { - return httpguts.HeaderValuesContainsToken(h[textproto.CanonicalMIMEHeaderKey("Upgrade")], "h2c") && - httpguts.HeaderValuesContainsToken(h[textproto.CanonicalMIMEHeaderKey("Connection")], "HTTP2-Settings") -} - -// getH2Settings returns the settings in the HTTP2-Settings header. -func getH2Settings(h http.Header) ([]byte, error) { - vals, ok := h[textproto.CanonicalMIMEHeaderKey("HTTP2-Settings")] - if !ok { - return nil, errors.New("missing HTTP2-Settings header") - } - if len(vals) != 1 { - return nil, fmt.Errorf("expected 1 HTTP2-Settings. Got: %v", vals) - } - settings, err := base64.RawURLEncoding.DecodeString(vals[0]) - if err != nil { - return nil, err - } - return settings, nil -} - -func newBufConn(conn net.Conn, rw *bufio.ReadWriter) net.Conn { - rw.Flush() - if rw.Reader.Buffered() == 0 { - // If there's no buffered data to be read, - // we can just discard the bufio.ReadWriter. - return conn - } - return &bufConn{conn, rw.Reader} -} - -// bufConn wraps a net.Conn, but reads drain the bufio.Reader first. -type bufConn struct { - net.Conn - *bufio.Reader -} - -func (c *bufConn) Read(p []byte) (int, error) { - if c.Reader == nil { - return c.Conn.Read(p) - } - n := c.Reader.Buffered() - if n == 0 { - c.Reader = nil - return c.Conn.Read(p) - } - if n < len(p) { - p = p[:n] - } - return c.Reader.Read(p) -} diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go deleted file mode 100644 index 46219da..0000000 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ /dev/null @@ -1,245 +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 hpack - -import ( - "io" -) - -const ( - uint32Max = ^uint32(0) - initialHeaderTableSize = 4096 -) - -type Encoder struct { - dynTab dynamicTable - // minSize is the minimum table size set by - // SetMaxDynamicTableSize after the previous Header Table Size - // Update. - minSize uint32 - // maxSizeLimit is the maximum table size this encoder - // supports. This will protect the encoder from too large - // size. - maxSizeLimit uint32 - // tableSizeUpdate indicates whether "Header Table Size - // Update" is required. - tableSizeUpdate bool - w io.Writer - buf []byte -} - -// NewEncoder returns a new Encoder which performs HPACK encoding. An -// encoded data is written to w. -func NewEncoder(w io.Writer) *Encoder { - e := &Encoder{ - minSize: uint32Max, - maxSizeLimit: initialHeaderTableSize, - tableSizeUpdate: false, - w: w, - } - e.dynTab.table.init() - e.dynTab.setMaxSize(initialHeaderTableSize) - return e -} - -// WriteField encodes f into a single Write to e's underlying Writer. -// This function may also produce bytes for "Header Table Size Update" -// if necessary. If produced, it is done before encoding f. -func (e *Encoder) WriteField(f HeaderField) error { - e.buf = e.buf[:0] - - if e.tableSizeUpdate { - e.tableSizeUpdate = false - if e.minSize < e.dynTab.maxSize { - e.buf = appendTableSize(e.buf, e.minSize) - } - e.minSize = uint32Max - e.buf = appendTableSize(e.buf, e.dynTab.maxSize) - } - - idx, nameValueMatch := e.searchTable(f) - if nameValueMatch { - e.buf = appendIndexed(e.buf, idx) - } else { - indexing := e.shouldIndex(f) - if indexing { - e.dynTab.add(f) - } - - if idx == 0 { - e.buf = appendNewName(e.buf, f, indexing) - } else { - e.buf = appendIndexedName(e.buf, f, idx, indexing) - } - } - n, err := e.w.Write(e.buf) - if err == nil && n != len(e.buf) { - err = io.ErrShortWrite - } - return err -} - -// searchTable searches f in both stable and dynamic header tables. -// The static header table is searched first. Only when there is no -// exact match for both name and value, the dynamic header table is -// then searched. If there is no match, i is 0. If both name and value -// match, i is the matched index and nameValueMatch becomes true. If -// only name matches, i points to that index and nameValueMatch -// becomes false. -func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) { - i, nameValueMatch = staticTable.search(f) - if nameValueMatch { - return i, true - } - - j, nameValueMatch := e.dynTab.table.search(f) - if nameValueMatch || (i == 0 && j != 0) { - return j + uint64(staticTable.len()), nameValueMatch - } - - return i, false -} - -// SetMaxDynamicTableSize changes the dynamic header table size to v. -// The actual size is bounded by the value passed to -// SetMaxDynamicTableSizeLimit. -func (e *Encoder) SetMaxDynamicTableSize(v uint32) { - if v > e.maxSizeLimit { - v = e.maxSizeLimit - } - if v < e.minSize { - e.minSize = v - } - e.tableSizeUpdate = true - e.dynTab.setMaxSize(v) -} - -// MaxDynamicTableSize returns the current dynamic header table size. -func (e *Encoder) MaxDynamicTableSize() (v uint32) { - return e.dynTab.maxSize -} - -// SetMaxDynamicTableSizeLimit changes the maximum value that can be -// specified in SetMaxDynamicTableSize to v. By default, it is set to -// 4096, which is the same size of the default dynamic header table -// size described in HPACK specification. If the current maximum -// dynamic header table size is strictly greater than v, "Header Table -// Size Update" will be done in the next WriteField call and the -// maximum dynamic header table size is truncated to v. -func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) { - e.maxSizeLimit = v - if e.dynTab.maxSize > v { - e.tableSizeUpdate = true - e.dynTab.setMaxSize(v) - } -} - -// shouldIndex reports whether f should be indexed. -func (e *Encoder) shouldIndex(f HeaderField) bool { - return !f.Sensitive && f.Size() <= e.dynTab.maxSize -} - -// appendIndexed appends index i, as encoded in "Indexed Header Field" -// representation, to dst and returns the extended buffer. -func appendIndexed(dst []byte, i uint64) []byte { - first := len(dst) - dst = appendVarInt(dst, 7, i) - dst[first] |= 0x80 - return dst -} - -// appendNewName appends f, as encoded in one of "Literal Header field -// - New Name" representation variants, to dst and returns the -// extended buffer. -// -// If f.Sensitive is true, "Never Indexed" representation is used. If -// f.Sensitive is false and indexing is true, "Incremental Indexing" -// representation is used. -func appendNewName(dst []byte, f HeaderField, indexing bool) []byte { - dst = append(dst, encodeTypeByte(indexing, f.Sensitive)) - dst = appendHpackString(dst, f.Name) - return appendHpackString(dst, f.Value) -} - -// appendIndexedName appends f and index i referring indexed name -// entry, as encoded in one of "Literal Header field - Indexed Name" -// representation variants, to dst and returns the extended buffer. -// -// If f.Sensitive is true, "Never Indexed" representation is used. If -// f.Sensitive is false and indexing is true, "Incremental Indexing" -// representation is used. -func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte { - first := len(dst) - var n byte - if indexing { - n = 6 - } else { - n = 4 - } - dst = appendVarInt(dst, n, i) - dst[first] |= encodeTypeByte(indexing, f.Sensitive) - return appendHpackString(dst, f.Value) -} - -// appendTableSize appends v, as encoded in "Header Table Size Update" -// representation, to dst and returns the extended buffer. -func appendTableSize(dst []byte, v uint32) []byte { - first := len(dst) - dst = appendVarInt(dst, 5, uint64(v)) - dst[first] |= 0x20 - return dst -} - -// appendVarInt appends i, as encoded in variable integer form using n -// bit prefix, to dst and returns the extended buffer. -// -// See -// https://httpwg.org/specs/rfc7541.html#integer.representation -func appendVarInt(dst []byte, n byte, i uint64) []byte { - k := uint64((1 << n) - 1) - if i < k { - return append(dst, byte(i)) - } - dst = append(dst, byte(k)) - i -= k - for ; i >= 128; i >>= 7 { - dst = append(dst, byte(0x80|(i&0x7f))) - } - return append(dst, byte(i)) -} - -// appendHpackString appends s, as encoded in "String Literal" -// representation, to dst and returns the extended buffer. -// -// s will be encoded in Huffman codes only when it produces strictly -// shorter byte string. -func appendHpackString(dst []byte, s string) []byte { - huffmanLength := HuffmanEncodeLength(s) - if huffmanLength < uint64(len(s)) { - first := len(dst) - dst = appendVarInt(dst, 7, huffmanLength) - dst = AppendHuffmanString(dst, s) - dst[first] |= 0x80 - } else { - dst = appendVarInt(dst, 7, uint64(len(s))) - dst = append(dst, s...) - } - return dst -} - -// encodeTypeByte returns type byte. If sensitive is true, type byte -// for "Never Indexed" representation is returned. If sensitive is -// false and indexing is true, type byte for "Incremental Indexing" -// representation is returned. Otherwise, type byte for "Without -// Indexing" is returned. -func encodeTypeByte(indexing, sensitive bool) byte { - if sensitive { - return 0x10 - } - if indexing { - return 0x40 - } - return 0 -} diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go deleted file mode 100644 index 7a1d976..0000000 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ /dev/null @@ -1,523 +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 hpack implements HPACK, a compression format for -// efficiently representing HTTP header fields in the context of HTTP/2. -// -// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09 -package hpack - -import ( - "bytes" - "errors" - "fmt" -) - -// A DecodingError is something the spec defines as a decoding error. -type DecodingError struct { - Err error -} - -func (de DecodingError) Error() string { - return fmt.Sprintf("decoding error: %v", de.Err) -} - -// An InvalidIndexError is returned when an encoder references a table -// entry before the static table or after the end of the dynamic table. -type InvalidIndexError int - -func (e InvalidIndexError) Error() string { - return fmt.Sprintf("invalid indexed representation index %d", int(e)) -} - -// A HeaderField is a name-value pair. Both the name and value are -// treated as opaque sequences of octets. -type HeaderField struct { - Name, Value string - - // Sensitive means that this header field should never be - // indexed. - Sensitive bool -} - -// IsPseudo reports whether the header field is an http2 pseudo header. -// That is, it reports whether it starts with a colon. -// It is not otherwise guaranteed to be a valid pseudo header field, -// though. -func (hf HeaderField) IsPseudo() bool { - return len(hf.Name) != 0 && hf.Name[0] == ':' -} - -func (hf HeaderField) String() string { - var suffix string - if hf.Sensitive { - suffix = " (sensitive)" - } - return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix) -} - -// Size returns the size of an entry per RFC 7541 section 4.1. -func (hf HeaderField) Size() uint32 { - // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1 - // "The size of the dynamic table is the sum of the size of - // its entries. The size of an entry is the sum of its name's - // length in octets (as defined in Section 5.2), its value's - // length in octets (see Section 5.2), plus 32. The size of - // an entry is calculated using the length of the name and - // value without any Huffman encoding applied." - - // This can overflow if somebody makes a large HeaderField - // Name and/or Value by hand, but we don't care, because that - // won't happen on the wire because the encoding doesn't allow - // it. - return uint32(len(hf.Name) + len(hf.Value) + 32) -} - -// A Decoder is the decoding context for incremental processing of -// header blocks. -type Decoder struct { - dynTab dynamicTable - emit func(f HeaderField) - - emitEnabled bool // whether calls to emit are enabled - maxStrLen int // 0 means unlimited - - // buf is the unparsed buffer. It's only written to - // saveBuf if it was truncated in the middle of a header - // block. Because it's usually not owned, we can only - // process it under Write. - buf []byte // not owned; only valid during Write - - // saveBuf is previous data passed to Write which we weren't able - // to fully parse before. Unlike buf, we own this data. - saveBuf bytes.Buffer - - firstField bool // processing the first field of the header block -} - -// NewDecoder returns a new decoder with the provided maximum dynamic -// table size. The emitFunc will be called for each valid field -// parsed, in the same goroutine as calls to Write, before Write returns. -func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder { - d := &Decoder{ - emit: emitFunc, - emitEnabled: true, - firstField: true, - } - d.dynTab.table.init() - d.dynTab.allowedMaxSize = maxDynamicTableSize - d.dynTab.setMaxSize(maxDynamicTableSize) - return d -} - -// ErrStringLength is returned by Decoder.Write when the max string length -// (as configured by Decoder.SetMaxStringLength) would be violated. -var ErrStringLength = errors.New("hpack: string too long") - -// SetMaxStringLength sets the maximum size of a HeaderField name or -// value string. If a string exceeds this length (even after any -// decompression), Write will return ErrStringLength. -// A value of 0 means unlimited and is the default from NewDecoder. -func (d *Decoder) SetMaxStringLength(n int) { - d.maxStrLen = n -} - -// SetEmitFunc changes the callback used when new header fields -// are decoded. -// It must be non-nil. It does not affect EmitEnabled. -func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) { - d.emit = emitFunc -} - -// SetEmitEnabled controls whether the emitFunc provided to NewDecoder -// should be called. The default is true. -// -// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE -// while still decoding and keeping in-sync with decoder state, but -// without doing unnecessary decompression or generating unnecessary -// garbage for header fields past the limit. -func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v } - -// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder -// are currently enabled. The default is true. -func (d *Decoder) EmitEnabled() bool { return d.emitEnabled } - -// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their -// underlying buffers for garbage reasons. - -func (d *Decoder) SetMaxDynamicTableSize(v uint32) { - d.dynTab.setMaxSize(v) -} - -// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded -// stream (via dynamic table size updates) may set the maximum size -// to. -func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { - d.dynTab.allowedMaxSize = v -} - -type dynamicTable struct { - // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2 - table headerFieldTable - size uint32 // in bytes - maxSize uint32 // current maxSize - allowedMaxSize uint32 // maxSize may go up to this, inclusive -} - -func (dt *dynamicTable) setMaxSize(v uint32) { - dt.maxSize = v - dt.evict() -} - -func (dt *dynamicTable) add(f HeaderField) { - dt.table.addEntry(f) - dt.size += f.Size() - dt.evict() -} - -// If we're too big, evict old stuff. -func (dt *dynamicTable) evict() { - var n int - for dt.size > dt.maxSize && n < dt.table.len() { - dt.size -= dt.table.ents[n].Size() - n++ - } - dt.table.evictOldest(n) -} - -func (d *Decoder) maxTableIndex() int { - // This should never overflow. RFC 7540 Section 6.5.2 limits the size of - // the dynamic table to 2^32 bytes, where each entry will occupy more than - // one byte. Further, the staticTable has a fixed, small length. - return d.dynTab.table.len() + staticTable.len() -} - -func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) { - // See Section 2.3.3. - if i == 0 { - return - } - if i <= uint64(staticTable.len()) { - return staticTable.ents[i-1], true - } - if i > uint64(d.maxTableIndex()) { - return - } - // In the dynamic table, newer entries have lower indices. - // However, dt.ents[0] is the oldest entry. Hence, dt.ents is - // the reversed dynamic table. - dt := d.dynTab.table - return dt.ents[dt.len()-(int(i)-staticTable.len())], true -} - -// DecodeFull decodes an entire block. -// -// TODO: remove this method and make it incremental later? This is -// easier for debugging now. -func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { - var hf []HeaderField - saveFunc := d.emit - defer func() { d.emit = saveFunc }() - d.emit = func(f HeaderField) { hf = append(hf, f) } - if _, err := d.Write(p); err != nil { - return nil, err - } - if err := d.Close(); err != nil { - return nil, err - } - return hf, nil -} - -// Close declares that the decoding is complete and resets the Decoder -// to be reused again for a new header block. If there is any remaining -// data in the decoder's buffer, Close returns an error. -func (d *Decoder) Close() error { - if d.saveBuf.Len() > 0 { - d.saveBuf.Reset() - return DecodingError{errors.New("truncated headers")} - } - d.firstField = true - return nil -} - -func (d *Decoder) Write(p []byte) (n int, err error) { - if len(p) == 0 { - // Prevent state machine CPU attacks (making us redo - // work up to the point of finding out we don't have - // enough data) - return - } - // Only copy the data if we have to. Optimistically assume - // that p will contain a complete header block. - if d.saveBuf.Len() == 0 { - d.buf = p - } else { - d.saveBuf.Write(p) - d.buf = d.saveBuf.Bytes() - d.saveBuf.Reset() - } - - for len(d.buf) > 0 { - err = d.parseHeaderFieldRepr() - if err == errNeedMore { - // Extra paranoia, making sure saveBuf won't - // get too large. All the varint and string - // reading code earlier should already catch - // overlong things and return ErrStringLength, - // but keep this as a last resort. - const varIntOverhead = 8 // conservative - if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) { - return 0, ErrStringLength - } - d.saveBuf.Write(d.buf) - return len(p), nil - } - d.firstField = false - if err != nil { - break - } - } - return len(p), err -} - -// errNeedMore is an internal sentinel error value that means the -// buffer is truncated and we need to read more data before we can -// continue parsing. -var errNeedMore = errors.New("need more data") - -type indexType int - -const ( - indexedTrue indexType = iota - indexedFalse - indexedNever -) - -func (v indexType) indexed() bool { return v == indexedTrue } -func (v indexType) sensitive() bool { return v == indexedNever } - -// returns errNeedMore if there isn't enough data available. -// any other error is fatal. -// consumes d.buf iff it returns nil. -// precondition: must be called with len(d.buf) > 0 -func (d *Decoder) parseHeaderFieldRepr() error { - b := d.buf[0] - switch { - case b&128 != 0: - // Indexed representation. - // High bit set? - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1 - return d.parseFieldIndexed() - case b&192 == 64: - // 6.2.1 Literal Header Field with Incremental Indexing - // 0b10xxxxxx: top two bits are 10 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 - return d.parseFieldLiteral(6, indexedTrue) - case b&240 == 0: - // 6.2.2 Literal Header Field without Indexing - // 0b0000xxxx: top four bits are 0000 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 - return d.parseFieldLiteral(4, indexedFalse) - case b&240 == 16: - // 6.2.3 Literal Header Field never Indexed - // 0b0001xxxx: top four bits are 0001 - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 - return d.parseFieldLiteral(4, indexedNever) - case b&224 == 32: - // 6.3 Dynamic Table Size Update - // Top three bits are '001'. - // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3 - return d.parseDynamicTableSizeUpdate() - } - - return DecodingError{errors.New("invalid encoding")} -} - -// (same invariants and behavior as parseHeaderFieldRepr) -func (d *Decoder) parseFieldIndexed() error { - buf := d.buf - idx, buf, err := readVarInt(7, buf) - if err != nil { - return err - } - hf, ok := d.at(idx) - if !ok { - return DecodingError{InvalidIndexError(idx)} - } - d.buf = buf - return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value}) -} - -// (same invariants and behavior as parseHeaderFieldRepr) -func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { - buf := d.buf - nameIdx, buf, err := readVarInt(n, buf) - if err != nil { - return err - } - - var hf HeaderField - wantStr := d.emitEnabled || it.indexed() - var undecodedName undecodedString - if nameIdx > 0 { - ihf, ok := d.at(nameIdx) - if !ok { - return DecodingError{InvalidIndexError(nameIdx)} - } - hf.Name = ihf.Name - } else { - undecodedName, buf, err = d.readString(buf) - if err != nil { - return err - } - } - undecodedValue, buf, err := d.readString(buf) - if err != nil { - return err - } - if wantStr { - if nameIdx <= 0 { - hf.Name, err = d.decodeString(undecodedName) - if err != nil { - return err - } - } - hf.Value, err = d.decodeString(undecodedValue) - if err != nil { - return err - } - } - d.buf = buf - if it.indexed() { - d.dynTab.add(hf) - } - hf.Sensitive = it.sensitive() - return d.callEmit(hf) -} - -func (d *Decoder) callEmit(hf HeaderField) error { - if d.maxStrLen != 0 { - if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen { - return ErrStringLength - } - } - if d.emitEnabled { - d.emit(hf) - } - return nil -} - -// (same invariants and behavior as parseHeaderFieldRepr) -func (d *Decoder) parseDynamicTableSizeUpdate() error { - // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the - // beginning of the first header block following the change to the dynamic table size. - if !d.firstField && d.dynTab.size > 0 { - return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")} - } - - buf := d.buf - size, buf, err := readVarInt(5, buf) - if err != nil { - return err - } - if size > uint64(d.dynTab.allowedMaxSize) { - return DecodingError{errors.New("dynamic table size update too large")} - } - d.dynTab.setMaxSize(uint32(size)) - d.buf = buf - return nil -} - -var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} - -// readVarInt reads an unsigned variable length integer off the -// beginning of p. n is the parameter as described in -// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1. -// -// n must always be between 1 and 8. -// -// The returned remain buffer is either a smaller suffix of p, or err != nil. -// The error is errNeedMore if p doesn't contain a complete integer. -func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) { - if n < 1 || n > 8 { - panic("bad n") - } - if len(p) == 0 { - return 0, p, errNeedMore - } - i = uint64(p[0]) - if n < 8 { - i &= (1 << uint64(n)) - 1 - } - if i < (1< 0 { - b := p[0] - p = p[1:] - i += uint64(b&127) << m - if b&128 == 0 { - return i, p, nil - } - m += 7 - if m >= 63 { // TODO: proper overflow check. making this up. - return 0, origP, errVarintOverflow - } - } - return 0, origP, errNeedMore -} - -// readString reads an hpack string from p. -// -// It returns a reference to the encoded string data to permit deferring decode costs -// until after the caller verifies all data is present. -func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) { - if len(p) == 0 { - return u, p, errNeedMore - } - isHuff := p[0]&128 != 0 - strLen, p, err := readVarInt(7, p) - if err != nil { - return u, p, err - } - if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) { - // Returning an error here means Huffman decoding errors - // for non-indexed strings past the maximum string length - // are ignored, but the server is returning an error anyway - // and because the string is not indexed the error will not - // affect the decoding state. - return u, nil, ErrStringLength - } - if uint64(len(p)) < strLen { - return u, p, errNeedMore - } - u.isHuff = isHuff - u.b = p[:strLen] - return u, p[strLen:], nil -} - -type undecodedString struct { - isHuff bool - b []byte -} - -func (d *Decoder) decodeString(u undecodedString) (string, error) { - if !u.isHuff { - return string(u.b), nil - } - buf := bufPool.Get().(*bytes.Buffer) - buf.Reset() // don't trust others - var s string - err := huffmanDecode(buf, d.maxStrLen, u.b) - if err == nil { - s = buf.String() - } - buf.Reset() // be nice to GC - bufPool.Put(buf) - return s, err -} diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go deleted file mode 100644 index 20d083a..0000000 --- a/vendor/golang.org/x/net/http2/hpack/huffman.go +++ /dev/null @@ -1,226 +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 hpack - -import ( - "bytes" - "errors" - "io" - "sync" -) - -var bufPool = sync.Pool{ - New: func() interface{} { return new(bytes.Buffer) }, -} - -// HuffmanDecode decodes the string in v and writes the expanded -// result to w, returning the number of bytes written to w and the -// Write call's return value. At most one Write call is made. -func HuffmanDecode(w io.Writer, v []byte) (int, error) { - buf := bufPool.Get().(*bytes.Buffer) - buf.Reset() - defer bufPool.Put(buf) - if err := huffmanDecode(buf, 0, v); err != nil { - return 0, err - } - return w.Write(buf.Bytes()) -} - -// HuffmanDecodeToString decodes the string in v. -func HuffmanDecodeToString(v []byte) (string, error) { - buf := bufPool.Get().(*bytes.Buffer) - buf.Reset() - defer bufPool.Put(buf) - if err := huffmanDecode(buf, 0, v); err != nil { - return "", err - } - return buf.String(), nil -} - -// ErrInvalidHuffman is returned for errors found decoding -// Huffman-encoded strings. -var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") - -// huffmanDecode decodes v to buf. -// If maxLen is greater than 0, attempts to write more to buf than -// maxLen bytes will return ErrStringLength. -func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { - rootHuffmanNode := getRootHuffmanNode() - n := rootHuffmanNode - // cur is the bit buffer that has not been fed into n. - // cbits is the number of low order bits in cur that are valid. - // sbits is the number of bits of the symbol prefix being decoded. - cur, cbits, sbits := uint(0), uint8(0), uint8(0) - for _, b := range v { - cur = cur<<8 | uint(b) - cbits += 8 - sbits += 8 - for cbits >= 8 { - idx := byte(cur >> (cbits - 8)) - n = n.children[idx] - if n == nil { - return ErrInvalidHuffman - } - if n.children == nil { - if maxLen != 0 && buf.Len() == maxLen { - return ErrStringLength - } - buf.WriteByte(n.sym) - cbits -= n.codeLen - n = rootHuffmanNode - sbits = cbits - } else { - cbits -= 8 - } - } - } - for cbits > 0 { - n = n.children[byte(cur<<(8-cbits))] - if n == nil { - return ErrInvalidHuffman - } - if n.children != nil || n.codeLen > cbits { - break - } - if maxLen != 0 && buf.Len() == maxLen { - return ErrStringLength - } - buf.WriteByte(n.sym) - cbits -= n.codeLen - n = rootHuffmanNode - sbits = cbits - } - if sbits > 7 { - // Either there was an incomplete symbol, or overlong padding. - // Both are decoding errors per RFC 7541 section 5.2. - return ErrInvalidHuffman - } - if mask := uint(1< 8 { - codeLen -= 8 - i := uint8(code >> codeLen) - if cur.children[i] == nil { - cur.children[i] = newInternalNode() - } - cur = cur.children[i] - } - shift := 8 - codeLen - start, end := int(uint8(code<= 32 { - n %= 32 // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift - y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32 - dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y)) - } - } - // Add padding bits if necessary - if over := n % 8; over > 0 { - const ( - eosCode = 0x3fffffff - eosNBits = 30 - eosPadByte = eosCode >> (eosNBits - 8) - ) - pad := 8 - over - x = (x << pad) | (eosPadByte >> over) - n += pad // 8 now divides into n exactly - } - // n in (0, 8, 16, 24, 32) - switch n / 8 { - case 0: - return dst - case 1: - return append(dst, byte(x)) - case 2: - y := uint16(x) - return append(dst, byte(y>>8), byte(y)) - case 3: - y := uint16(x >> 8) - return append(dst, byte(y>>8), byte(y), byte(x)) - } - // case 4: - y := uint32(x) - return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y)) -} - -// HuffmanEncodeLength returns the number of bytes required to encode -// s in Huffman codes. The result is round up to byte boundary. -func HuffmanEncodeLength(s string) uint64 { - n := uint64(0) - for i := 0; i < len(s); i++ { - n += uint64(huffmanCodeLen[s[i]]) - } - return (n + 7) / 8 -} diff --git a/vendor/golang.org/x/net/http2/hpack/static_table.go b/vendor/golang.org/x/net/http2/hpack/static_table.go deleted file mode 100644 index 754a1eb..0000000 --- a/vendor/golang.org/x/net/http2/hpack/static_table.go +++ /dev/null @@ -1,188 +0,0 @@ -// go generate gen.go -// Code generated by the command above; DO NOT EDIT. - -package hpack - -var staticTable = &headerFieldTable{ - evictCount: 0, - byName: map[string]uint64{ - ":authority": 1, - ":method": 3, - ":path": 5, - ":scheme": 7, - ":status": 14, - "accept-charset": 15, - "accept-encoding": 16, - "accept-language": 17, - "accept-ranges": 18, - "accept": 19, - "access-control-allow-origin": 20, - "age": 21, - "allow": 22, - "authorization": 23, - "cache-control": 24, - "content-disposition": 25, - "content-encoding": 26, - "content-language": 27, - "content-length": 28, - "content-location": 29, - "content-range": 30, - "content-type": 31, - "cookie": 32, - "date": 33, - "etag": 34, - "expect": 35, - "expires": 36, - "from": 37, - "host": 38, - "if-match": 39, - "if-modified-since": 40, - "if-none-match": 41, - "if-range": 42, - "if-unmodified-since": 43, - "last-modified": 44, - "link": 45, - "location": 46, - "max-forwards": 47, - "proxy-authenticate": 48, - "proxy-authorization": 49, - "range": 50, - "referer": 51, - "refresh": 52, - "retry-after": 53, - "server": 54, - "set-cookie": 55, - "strict-transport-security": 56, - "transfer-encoding": 57, - "user-agent": 58, - "vary": 59, - "via": 60, - "www-authenticate": 61, - }, - byNameValue: map[pairNameValue]uint64{ - {name: ":authority", value: ""}: 1, - {name: ":method", value: "GET"}: 2, - {name: ":method", value: "POST"}: 3, - {name: ":path", value: "/"}: 4, - {name: ":path", value: "/index.html"}: 5, - {name: ":scheme", value: "http"}: 6, - {name: ":scheme", value: "https"}: 7, - {name: ":status", value: "200"}: 8, - {name: ":status", value: "204"}: 9, - {name: ":status", value: "206"}: 10, - {name: ":status", value: "304"}: 11, - {name: ":status", value: "400"}: 12, - {name: ":status", value: "404"}: 13, - {name: ":status", value: "500"}: 14, - {name: "accept-charset", value: ""}: 15, - {name: "accept-encoding", value: "gzip, deflate"}: 16, - {name: "accept-language", value: ""}: 17, - {name: "accept-ranges", value: ""}: 18, - {name: "accept", value: ""}: 19, - {name: "access-control-allow-origin", value: ""}: 20, - {name: "age", value: ""}: 21, - {name: "allow", value: ""}: 22, - {name: "authorization", value: ""}: 23, - {name: "cache-control", value: ""}: 24, - {name: "content-disposition", value: ""}: 25, - {name: "content-encoding", value: ""}: 26, - {name: "content-language", value: ""}: 27, - {name: "content-length", value: ""}: 28, - {name: "content-location", value: ""}: 29, - {name: "content-range", value: ""}: 30, - {name: "content-type", value: ""}: 31, - {name: "cookie", value: ""}: 32, - {name: "date", value: ""}: 33, - {name: "etag", value: ""}: 34, - {name: "expect", value: ""}: 35, - {name: "expires", value: ""}: 36, - {name: "from", value: ""}: 37, - {name: "host", value: ""}: 38, - {name: "if-match", value: ""}: 39, - {name: "if-modified-since", value: ""}: 40, - {name: "if-none-match", value: ""}: 41, - {name: "if-range", value: ""}: 42, - {name: "if-unmodified-since", value: ""}: 43, - {name: "last-modified", value: ""}: 44, - {name: "link", value: ""}: 45, - {name: "location", value: ""}: 46, - {name: "max-forwards", value: ""}: 47, - {name: "proxy-authenticate", value: ""}: 48, - {name: "proxy-authorization", value: ""}: 49, - {name: "range", value: ""}: 50, - {name: "referer", value: ""}: 51, - {name: "refresh", value: ""}: 52, - {name: "retry-after", value: ""}: 53, - {name: "server", value: ""}: 54, - {name: "set-cookie", value: ""}: 55, - {name: "strict-transport-security", value: ""}: 56, - {name: "transfer-encoding", value: ""}: 57, - {name: "user-agent", value: ""}: 58, - {name: "vary", value: ""}: 59, - {name: "via", value: ""}: 60, - {name: "www-authenticate", value: ""}: 61, - }, - ents: []HeaderField{ - {Name: ":authority", Value: "", Sensitive: false}, - {Name: ":method", Value: "GET", Sensitive: false}, - {Name: ":method", Value: "POST", Sensitive: false}, - {Name: ":path", Value: "/", Sensitive: false}, - {Name: ":path", Value: "/index.html", Sensitive: false}, - {Name: ":scheme", Value: "http", Sensitive: false}, - {Name: ":scheme", Value: "https", Sensitive: false}, - {Name: ":status", Value: "200", Sensitive: false}, - {Name: ":status", Value: "204", Sensitive: false}, - {Name: ":status", Value: "206", Sensitive: false}, - {Name: ":status", Value: "304", Sensitive: false}, - {Name: ":status", Value: "400", Sensitive: false}, - {Name: ":status", Value: "404", Sensitive: false}, - {Name: ":status", Value: "500", Sensitive: false}, - {Name: "accept-charset", Value: "", Sensitive: false}, - {Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false}, - {Name: "accept-language", Value: "", Sensitive: false}, - {Name: "accept-ranges", Value: "", Sensitive: false}, - {Name: "accept", Value: "", Sensitive: false}, - {Name: "access-control-allow-origin", Value: "", Sensitive: false}, - {Name: "age", Value: "", Sensitive: false}, - {Name: "allow", Value: "", Sensitive: false}, - {Name: "authorization", Value: "", Sensitive: false}, - {Name: "cache-control", Value: "", Sensitive: false}, - {Name: "content-disposition", Value: "", Sensitive: false}, - {Name: "content-encoding", Value: "", Sensitive: false}, - {Name: "content-language", Value: "", Sensitive: false}, - {Name: "content-length", Value: "", Sensitive: false}, - {Name: "content-location", Value: "", Sensitive: false}, - {Name: "content-range", Value: "", Sensitive: false}, - {Name: "content-type", Value: "", Sensitive: false}, - {Name: "cookie", Value: "", Sensitive: false}, - {Name: "date", Value: "", Sensitive: false}, - {Name: "etag", Value: "", Sensitive: false}, - {Name: "expect", Value: "", Sensitive: false}, - {Name: "expires", Value: "", Sensitive: false}, - {Name: "from", Value: "", Sensitive: false}, - {Name: "host", Value: "", Sensitive: false}, - {Name: "if-match", Value: "", Sensitive: false}, - {Name: "if-modified-since", Value: "", Sensitive: false}, - {Name: "if-none-match", Value: "", Sensitive: false}, - {Name: "if-range", Value: "", Sensitive: false}, - {Name: "if-unmodified-since", Value: "", Sensitive: false}, - {Name: "last-modified", Value: "", Sensitive: false}, - {Name: "link", Value: "", Sensitive: false}, - {Name: "location", Value: "", Sensitive: false}, - {Name: "max-forwards", Value: "", Sensitive: false}, - {Name: "proxy-authenticate", Value: "", Sensitive: false}, - {Name: "proxy-authorization", Value: "", Sensitive: false}, - {Name: "range", Value: "", Sensitive: false}, - {Name: "referer", Value: "", Sensitive: false}, - {Name: "refresh", Value: "", Sensitive: false}, - {Name: "retry-after", Value: "", Sensitive: false}, - {Name: "server", Value: "", Sensitive: false}, - {Name: "set-cookie", Value: "", Sensitive: false}, - {Name: "strict-transport-security", Value: "", Sensitive: false}, - {Name: "transfer-encoding", Value: "", Sensitive: false}, - {Name: "user-agent", Value: "", Sensitive: false}, - {Name: "vary", Value: "", Sensitive: false}, - {Name: "via", Value: "", Sensitive: false}, - {Name: "www-authenticate", Value: "", Sensitive: false}, - }, -} diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go deleted file mode 100644 index 8cbdf3f..0000000 --- a/vendor/golang.org/x/net/http2/hpack/tables.go +++ /dev/null @@ -1,403 +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 hpack - -import ( - "fmt" -) - -// headerFieldTable implements a list of HeaderFields. -// This is used to implement the static and dynamic tables. -type headerFieldTable struct { - // For static tables, entries are never evicted. - // - // For dynamic tables, entries are evicted from ents[0] and added to the end. - // Each entry has a unique id that starts at one and increments for each - // entry that is added. This unique id is stable across evictions, meaning - // it can be used as a pointer to a specific entry. As in hpack, unique ids - // are 1-based. The unique id for ents[k] is k + evictCount + 1. - // - // Zero is not a valid unique id. - // - // evictCount should not overflow in any remotely practical situation. In - // practice, we will have one dynamic table per HTTP/2 connection. If we - // assume a very powerful server that handles 1M QPS per connection and each - // request adds (then evicts) 100 entries from the table, it would still take - // 2M years for evictCount to overflow. - ents []HeaderField - evictCount uint64 - - // byName maps a HeaderField name to the unique id of the newest entry with - // the same name. See above for a definition of "unique id". - byName map[string]uint64 - - // byNameValue maps a HeaderField name/value pair to the unique id of the newest - // entry with the same name and value. See above for a definition of "unique id". - byNameValue map[pairNameValue]uint64 -} - -type pairNameValue struct { - name, value string -} - -func (t *headerFieldTable) init() { - t.byName = make(map[string]uint64) - t.byNameValue = make(map[pairNameValue]uint64) -} - -// len reports the number of entries in the table. -func (t *headerFieldTable) len() int { - return len(t.ents) -} - -// addEntry adds a new entry. -func (t *headerFieldTable) addEntry(f HeaderField) { - id := uint64(t.len()) + t.evictCount + 1 - t.byName[f.Name] = id - t.byNameValue[pairNameValue{f.Name, f.Value}] = id - t.ents = append(t.ents, f) -} - -// evictOldest evicts the n oldest entries in the table. -func (t *headerFieldTable) evictOldest(n int) { - if n > t.len() { - panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len())) - } - for k := 0; k < n; k++ { - f := t.ents[k] - id := t.evictCount + uint64(k) + 1 - if t.byName[f.Name] == id { - delete(t.byName, f.Name) - } - if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { - delete(t.byNameValue, p) - } - } - copy(t.ents, t.ents[n:]) - for k := t.len() - n; k < t.len(); k++ { - t.ents[k] = HeaderField{} // so strings can be garbage collected - } - t.ents = t.ents[:t.len()-n] - if t.evictCount+uint64(n) < t.evictCount { - panic("evictCount overflow") - } - t.evictCount += uint64(n) -} - -// search finds f in the table. If there is no match, i is 0. -// If both name and value match, i is the matched index and nameValueMatch -// becomes true. If only name matches, i points to that index and -// nameValueMatch becomes false. -// -// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says -// that index 1 should be the newest entry, but t.ents[0] is the oldest entry, -// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic -// table, the return value i actually refers to the entry t.ents[t.len()-i]. -// -// All tables are assumed to be a dynamic tables except for the global staticTable. -// -// See Section 2.3.3. -func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { - if !f.Sensitive { - if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 { - return t.idToIndex(id), true - } - } - if id := t.byName[f.Name]; id != 0 { - return t.idToIndex(id), false - } - return 0, false -} - -// idToIndex converts a unique id to an HPACK index. -// See Section 2.3.3. -func (t *headerFieldTable) idToIndex(id uint64) uint64 { - if id <= t.evictCount { - panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount)) - } - k := id - t.evictCount - 1 // convert id to an index t.ents[k] - if t != staticTable { - return uint64(t.len()) - k // dynamic table - } - return k + 1 -} - -var huffmanCodes = [256]uint32{ - 0x1ff8, - 0x7fffd8, - 0xfffffe2, - 0xfffffe3, - 0xfffffe4, - 0xfffffe5, - 0xfffffe6, - 0xfffffe7, - 0xfffffe8, - 0xffffea, - 0x3ffffffc, - 0xfffffe9, - 0xfffffea, - 0x3ffffffd, - 0xfffffeb, - 0xfffffec, - 0xfffffed, - 0xfffffee, - 0xfffffef, - 0xffffff0, - 0xffffff1, - 0xffffff2, - 0x3ffffffe, - 0xffffff3, - 0xffffff4, - 0xffffff5, - 0xffffff6, - 0xffffff7, - 0xffffff8, - 0xffffff9, - 0xffffffa, - 0xffffffb, - 0x14, - 0x3f8, - 0x3f9, - 0xffa, - 0x1ff9, - 0x15, - 0xf8, - 0x7fa, - 0x3fa, - 0x3fb, - 0xf9, - 0x7fb, - 0xfa, - 0x16, - 0x17, - 0x18, - 0x0, - 0x1, - 0x2, - 0x19, - 0x1a, - 0x1b, - 0x1c, - 0x1d, - 0x1e, - 0x1f, - 0x5c, - 0xfb, - 0x7ffc, - 0x20, - 0xffb, - 0x3fc, - 0x1ffa, - 0x21, - 0x5d, - 0x5e, - 0x5f, - 0x60, - 0x61, - 0x62, - 0x63, - 0x64, - 0x65, - 0x66, - 0x67, - 0x68, - 0x69, - 0x6a, - 0x6b, - 0x6c, - 0x6d, - 0x6e, - 0x6f, - 0x70, - 0x71, - 0x72, - 0xfc, - 0x73, - 0xfd, - 0x1ffb, - 0x7fff0, - 0x1ffc, - 0x3ffc, - 0x22, - 0x7ffd, - 0x3, - 0x23, - 0x4, - 0x24, - 0x5, - 0x25, - 0x26, - 0x27, - 0x6, - 0x74, - 0x75, - 0x28, - 0x29, - 0x2a, - 0x7, - 0x2b, - 0x76, - 0x2c, - 0x8, - 0x9, - 0x2d, - 0x77, - 0x78, - 0x79, - 0x7a, - 0x7b, - 0x7ffe, - 0x7fc, - 0x3ffd, - 0x1ffd, - 0xffffffc, - 0xfffe6, - 0x3fffd2, - 0xfffe7, - 0xfffe8, - 0x3fffd3, - 0x3fffd4, - 0x3fffd5, - 0x7fffd9, - 0x3fffd6, - 0x7fffda, - 0x7fffdb, - 0x7fffdc, - 0x7fffdd, - 0x7fffde, - 0xffffeb, - 0x7fffdf, - 0xffffec, - 0xffffed, - 0x3fffd7, - 0x7fffe0, - 0xffffee, - 0x7fffe1, - 0x7fffe2, - 0x7fffe3, - 0x7fffe4, - 0x1fffdc, - 0x3fffd8, - 0x7fffe5, - 0x3fffd9, - 0x7fffe6, - 0x7fffe7, - 0xffffef, - 0x3fffda, - 0x1fffdd, - 0xfffe9, - 0x3fffdb, - 0x3fffdc, - 0x7fffe8, - 0x7fffe9, - 0x1fffde, - 0x7fffea, - 0x3fffdd, - 0x3fffde, - 0xfffff0, - 0x1fffdf, - 0x3fffdf, - 0x7fffeb, - 0x7fffec, - 0x1fffe0, - 0x1fffe1, - 0x3fffe0, - 0x1fffe2, - 0x7fffed, - 0x3fffe1, - 0x7fffee, - 0x7fffef, - 0xfffea, - 0x3fffe2, - 0x3fffe3, - 0x3fffe4, - 0x7ffff0, - 0x3fffe5, - 0x3fffe6, - 0x7ffff1, - 0x3ffffe0, - 0x3ffffe1, - 0xfffeb, - 0x7fff1, - 0x3fffe7, - 0x7ffff2, - 0x3fffe8, - 0x1ffffec, - 0x3ffffe2, - 0x3ffffe3, - 0x3ffffe4, - 0x7ffffde, - 0x7ffffdf, - 0x3ffffe5, - 0xfffff1, - 0x1ffffed, - 0x7fff2, - 0x1fffe3, - 0x3ffffe6, - 0x7ffffe0, - 0x7ffffe1, - 0x3ffffe7, - 0x7ffffe2, - 0xfffff2, - 0x1fffe4, - 0x1fffe5, - 0x3ffffe8, - 0x3ffffe9, - 0xffffffd, - 0x7ffffe3, - 0x7ffffe4, - 0x7ffffe5, - 0xfffec, - 0xfffff3, - 0xfffed, - 0x1fffe6, - 0x3fffe9, - 0x1fffe7, - 0x1fffe8, - 0x7ffff3, - 0x3fffea, - 0x3fffeb, - 0x1ffffee, - 0x1ffffef, - 0xfffff4, - 0xfffff5, - 0x3ffffea, - 0x7ffff4, - 0x3ffffeb, - 0x7ffffe6, - 0x3ffffec, - 0x3ffffed, - 0x7ffffe7, - 0x7ffffe8, - 0x7ffffe9, - 0x7ffffea, - 0x7ffffeb, - 0xffffffe, - 0x7ffffec, - 0x7ffffed, - 0x7ffffee, - 0x7ffffef, - 0x7fffff0, - 0x3ffffee, -} - -var huffmanCodeLen = [256]uint8{ - 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, - 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, - 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, - 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, - 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5, - 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, - 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23, - 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24, - 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, - 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23, - 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25, - 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, - 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, - 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26, -} diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go deleted file mode 100644 index 6c18ea2..0000000 --- a/vendor/golang.org/x/net/http2/http2.go +++ /dev/null @@ -1,432 +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 http2 implements the HTTP/2 protocol. -// -// This package is low-level and intended to be used directly by very -// few people. Most users will use it indirectly through the automatic -// use by the net/http package (from Go 1.6 and later). -// For use in earlier Go versions see ConfigureServer. (Transport support -// requires Go 1.6 or later) -// -// See https://http2.github.io/ for more information on HTTP/2. -// -// See https://http2.golang.org/ for a test server running this code. -package http2 // import "golang.org/x/net/http2" - -import ( - "bufio" - "context" - "crypto/tls" - "errors" - "fmt" - "net" - "net/http" - "os" - "sort" - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/net/http/httpguts" -) - -var ( - VerboseLogs bool - logFrameWrites bool - logFrameReads bool - inTests bool - - // Enabling extended CONNECT by causes browsers to attempt to use - // WebSockets-over-HTTP/2. This results in problems when the server's websocket - // package doesn't support extended CONNECT. - // - // Disable extended CONNECT by default for now. - // - // Issue #71128. - disableExtendedConnectProtocol = true -) - -func init() { - e := os.Getenv("GODEBUG") - if strings.Contains(e, "http2debug=1") { - VerboseLogs = true - } - if strings.Contains(e, "http2debug=2") { - VerboseLogs = true - logFrameWrites = true - logFrameReads = true - } - if strings.Contains(e, "http2xconnect=1") { - disableExtendedConnectProtocol = false - } -} - -const ( - // ClientPreface is the string that must be sent by new - // connections from clients. - ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" - - // SETTINGS_MAX_FRAME_SIZE default - // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2 - initialMaxFrameSize = 16384 - - // NextProtoTLS is the NPN/ALPN protocol negotiated during - // HTTP/2's TLS setup. - NextProtoTLS = "h2" - - // https://httpwg.org/specs/rfc7540.html#SettingValues - initialHeaderTableSize = 4096 - - initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size - - defaultMaxReadFrameSize = 1 << 20 -) - -var ( - clientPreface = []byte(ClientPreface) -) - -type streamState int - -// HTTP/2 stream states. -// -// See http://tools.ietf.org/html/rfc7540#section-5.1. -// -// For simplicity, the server code merges "reserved (local)" into -// "half-closed (remote)". This is one less state transition to track. -// The only downside is that we send PUSH_PROMISEs slightly less -// liberally than allowable. More discussion here: -// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html -// -// "reserved (remote)" is omitted since the client code does not -// support server push. -const ( - stateIdle streamState = iota - stateOpen - stateHalfClosedLocal - stateHalfClosedRemote - stateClosed -) - -var stateName = [...]string{ - stateIdle: "Idle", - stateOpen: "Open", - stateHalfClosedLocal: "HalfClosedLocal", - stateHalfClosedRemote: "HalfClosedRemote", - stateClosed: "Closed", -} - -func (st streamState) String() string { - return stateName[st] -} - -// Setting is a setting parameter: which setting it is, and its value. -type Setting struct { - // ID is which setting is being set. - // See https://httpwg.org/specs/rfc7540.html#SettingFormat - ID SettingID - - // Val is the value. - Val uint32 -} - -func (s Setting) String() string { - return fmt.Sprintf("[%v = %d]", s.ID, s.Val) -} - -// Valid reports whether the setting is valid. -func (s Setting) Valid() error { - // Limits and error codes from 6.5.2 Defined SETTINGS Parameters - switch s.ID { - case SettingEnablePush: - if s.Val != 1 && s.Val != 0 { - return ConnectionError(ErrCodeProtocol) - } - case SettingInitialWindowSize: - if s.Val > 1<<31-1 { - return ConnectionError(ErrCodeFlowControl) - } - case SettingMaxFrameSize: - if s.Val < 16384 || s.Val > 1<<24-1 { - return ConnectionError(ErrCodeProtocol) - } - case SettingEnableConnectProtocol: - if s.Val != 1 && s.Val != 0 { - return ConnectionError(ErrCodeProtocol) - } - } - return nil -} - -// A SettingID is an HTTP/2 setting as defined in -// https://httpwg.org/specs/rfc7540.html#iana-settings -type SettingID uint16 - -const ( - SettingHeaderTableSize SettingID = 0x1 - SettingEnablePush SettingID = 0x2 - SettingMaxConcurrentStreams SettingID = 0x3 - SettingInitialWindowSize SettingID = 0x4 - SettingMaxFrameSize SettingID = 0x5 - SettingMaxHeaderListSize SettingID = 0x6 - SettingEnableConnectProtocol SettingID = 0x8 -) - -var settingName = map[SettingID]string{ - SettingHeaderTableSize: "HEADER_TABLE_SIZE", - SettingEnablePush: "ENABLE_PUSH", - SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS", - SettingInitialWindowSize: "INITIAL_WINDOW_SIZE", - SettingMaxFrameSize: "MAX_FRAME_SIZE", - SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE", - SettingEnableConnectProtocol: "ENABLE_CONNECT_PROTOCOL", -} - -func (s SettingID) String() string { - if v, ok := settingName[s]; ok { - return v - } - return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s)) -} - -// validWireHeaderFieldName reports whether v is a valid header field -// name (key). See httpguts.ValidHeaderName for the base rules. -// -// Further, http2 says: -// -// "Just as in HTTP/1.x, header field names are strings of ASCII -// characters that are compared in a case-insensitive -// fashion. However, header field names MUST be converted to -// lowercase prior to their encoding in HTTP/2. " -func validWireHeaderFieldName(v string) bool { - if len(v) == 0 { - return false - } - for _, r := range v { - if !httpguts.IsTokenRune(r) { - return false - } - if 'A' <= r && r <= 'Z' { - return false - } - } - return true -} - -func httpCodeString(code int) string { - switch code { - case 200: - return "200" - case 404: - return "404" - } - return strconv.Itoa(code) -} - -// from pkg io -type stringWriter interface { - WriteString(s string) (n int, err error) -} - -// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed). -type closeWaiter chan struct{} - -// Init makes a closeWaiter usable. -// It exists because so a closeWaiter value can be placed inside a -// larger struct and have the Mutex and Cond's memory in the same -// allocation. -func (cw *closeWaiter) Init() { - *cw = make(chan struct{}) -} - -// Close marks the closeWaiter as closed and unblocks any waiters. -func (cw closeWaiter) Close() { - close(cw) -} - -// Wait waits for the closeWaiter to become closed. -func (cw closeWaiter) Wait() { - <-cw -} - -// bufferedWriter is a buffered writer that writes to w. -// Its buffered writer is lazily allocated as needed, to minimize -// idle memory usage with many connections. -type bufferedWriter struct { - _ incomparable - group synctestGroupInterface // immutable - conn net.Conn // immutable - bw *bufio.Writer // non-nil when data is buffered - byteTimeout time.Duration // immutable, WriteByteTimeout -} - -func newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter { - return &bufferedWriter{ - group: group, - conn: conn, - byteTimeout: timeout, - } -} - -// bufWriterPoolBufferSize is the size of bufio.Writer's -// buffers created using bufWriterPool. -// -// TODO: pick a less arbitrary value? this is a bit under -// (3 x typical 1500 byte MTU) at least. Other than that, -// not much thought went into it. -const bufWriterPoolBufferSize = 4 << 10 - -var bufWriterPool = sync.Pool{ - New: func() interface{} { - return bufio.NewWriterSize(nil, bufWriterPoolBufferSize) - }, -} - -func (w *bufferedWriter) Available() int { - if w.bw == nil { - return bufWriterPoolBufferSize - } - return w.bw.Available() -} - -func (w *bufferedWriter) Write(p []byte) (n int, err error) { - if w.bw == nil { - bw := bufWriterPool.Get().(*bufio.Writer) - bw.Reset((*bufferedWriterTimeoutWriter)(w)) - w.bw = bw - } - return w.bw.Write(p) -} - -func (w *bufferedWriter) Flush() error { - bw := w.bw - if bw == nil { - return nil - } - err := bw.Flush() - bw.Reset(nil) - bufWriterPool.Put(bw) - w.bw = nil - return err -} - -type bufferedWriterTimeoutWriter bufferedWriter - -func (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) { - return writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p) -} - -// writeWithByteTimeout writes to conn. -// If more than timeout passes without any bytes being written to the connection, -// the write fails. -func writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) { - if timeout <= 0 { - return conn.Write(p) - } - for { - var now time.Time - if group == nil { - now = time.Now() - } else { - now = group.Now() - } - conn.SetWriteDeadline(now.Add(timeout)) - nn, err := conn.Write(p[n:]) - n += nn - if n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) { - // Either we finished the write, made no progress, or hit the deadline. - // Whichever it is, we're done now. - conn.SetWriteDeadline(time.Time{}) - return n, err - } - } -} - -func mustUint31(v int32) uint32 { - if v < 0 || v > 2147483647 { - panic("out of range") - } - return uint32(v) -} - -// bodyAllowedForStatus reports whether a given response status code -// permits a body. See RFC 7230, section 3.3. -func bodyAllowedForStatus(status int) bool { - switch { - case status >= 100 && status <= 199: - return false - case status == 204: - return false - case status == 304: - return false - } - return true -} - -type httpError struct { - _ incomparable - msg string - timeout bool -} - -func (e *httpError) Error() string { return e.msg } -func (e *httpError) Timeout() bool { return e.timeout } -func (e *httpError) Temporary() bool { return true } - -var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true} - -type connectionStater interface { - ConnectionState() tls.ConnectionState -} - -var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }} - -type sorter struct { - v []string // owned by sorter -} - -func (s *sorter) Len() int { return len(s.v) } -func (s *sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] } -func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] } - -// Keys returns the sorted keys of h. -// -// The returned slice is only valid until s used again or returned to -// its pool. -func (s *sorter) Keys(h http.Header) []string { - keys := s.v[:0] - for k := range h { - keys = append(keys, k) - } - s.v = keys - sort.Sort(s) - return keys -} - -func (s *sorter) SortStrings(ss []string) { - // Our sorter works on s.v, which sorter owns, so - // stash it away while we sort the user's buffer. - save := s.v - s.v = ss - sort.Sort(s) - s.v = save -} - -// incomparable is a zero-width, non-comparable type. Adding it to a struct -// makes that struct also non-comparable, and generally doesn't add -// any size (as long as it's first). -type incomparable [0]func() - -// synctestGroupInterface is the methods of synctestGroup used by Server and Transport. -// It's defined as an interface here to let us keep synctestGroup entirely test-only -// and not a part of non-test builds. -type synctestGroupInterface interface { - Join() - Now() time.Time - NewTimer(d time.Duration) timer - AfterFunc(d time.Duration, f func()) timer - ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) -} diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go deleted file mode 100644 index 3b9f06b..0000000 --- a/vendor/golang.org/x/net/http2/pipe.go +++ /dev/null @@ -1,184 +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 http2 - -import ( - "errors" - "io" - "sync" -) - -// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like -// io.Pipe except there are no PipeReader/PipeWriter halves, and the -// underlying buffer is an interface. (io.Pipe is always unbuffered) -type pipe struct { - mu sync.Mutex - c sync.Cond // c.L lazily initialized to &p.mu - b pipeBuffer // nil when done reading - unread int // bytes unread when done - err error // read error once empty. non-nil means closed. - breakErr error // immediate read error (caller doesn't see rest of b) - donec chan struct{} // closed on error - readFn func() // optional code to run in Read before error -} - -type pipeBuffer interface { - Len() int - io.Writer - io.Reader -} - -// setBuffer initializes the pipe buffer. -// It has no effect if the pipe is already closed. -func (p *pipe) setBuffer(b pipeBuffer) { - p.mu.Lock() - defer p.mu.Unlock() - if p.err != nil || p.breakErr != nil { - return - } - p.b = b -} - -func (p *pipe) Len() int { - p.mu.Lock() - defer p.mu.Unlock() - if p.b == nil { - return p.unread - } - return p.b.Len() -} - -// Read waits until data is available and copies bytes -// from the buffer into p. -func (p *pipe) Read(d []byte) (n int, err error) { - p.mu.Lock() - defer p.mu.Unlock() - if p.c.L == nil { - p.c.L = &p.mu - } - for { - if p.breakErr != nil { - return 0, p.breakErr - } - if p.b != nil && p.b.Len() > 0 { - return p.b.Read(d) - } - if p.err != nil { - if p.readFn != nil { - p.readFn() // e.g. copy trailers - p.readFn = nil // not sticky like p.err - } - p.b = nil - return 0, p.err - } - p.c.Wait() - } -} - -var ( - errClosedPipeWrite = errors.New("write on closed buffer") - errUninitializedPipeWrite = errors.New("write on uninitialized buffer") -) - -// Write copies bytes from p into the buffer and wakes a reader. -// It is an error to write more data than the buffer can hold. -func (p *pipe) Write(d []byte) (n int, err error) { - p.mu.Lock() - defer p.mu.Unlock() - if p.c.L == nil { - p.c.L = &p.mu - } - defer p.c.Signal() - if p.err != nil || p.breakErr != nil { - return 0, errClosedPipeWrite - } - // pipe.setBuffer is never invoked, leaving the buffer uninitialized. - // We shouldn't try to write to an uninitialized pipe, - // but returning an error is better than panicking. - if p.b == nil { - return 0, errUninitializedPipeWrite - } - return p.b.Write(d) -} - -// CloseWithError causes the next Read (waking up a current blocked -// Read if needed) to return the provided err after all data has been -// read. -// -// The error must be non-nil. -func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) } - -// BreakWithError causes the next Read (waking up a current blocked -// Read if needed) to return the provided err immediately, without -// waiting for unread data. -func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) } - -// closeWithErrorAndCode is like CloseWithError but also sets some code to run -// in the caller's goroutine before returning the error. -func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) } - -func (p *pipe) closeWithError(dst *error, err error, fn func()) { - if err == nil { - panic("err must be non-nil") - } - p.mu.Lock() - defer p.mu.Unlock() - if p.c.L == nil { - p.c.L = &p.mu - } - defer p.c.Signal() - if *dst != nil { - // Already been done. - return - } - p.readFn = fn - if dst == &p.breakErr { - if p.b != nil { - p.unread += p.b.Len() - } - p.b = nil - } - *dst = err - p.closeDoneLocked() -} - -// requires p.mu be held. -func (p *pipe) closeDoneLocked() { - if p.donec == nil { - return - } - // Close if unclosed. This isn't racy since we always - // hold p.mu while closing. - select { - case <-p.donec: - default: - close(p.donec) - } -} - -// Err returns the error (if any) first set by BreakWithError or CloseWithError. -func (p *pipe) Err() error { - p.mu.Lock() - defer p.mu.Unlock() - if p.breakErr != nil { - return p.breakErr - } - return p.err -} - -// Done returns a channel which is closed if and when this pipe is closed -// with CloseWithError. -func (p *pipe) Done() <-chan struct{} { - p.mu.Lock() - defer p.mu.Unlock() - if p.donec == nil { - p.donec = make(chan struct{}) - if p.err != nil || p.breakErr != nil { - // Already hit an error. - p.closeDoneLocked() - } - } - return p.donec -} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go deleted file mode 100644 index b640deb..0000000 --- a/vendor/golang.org/x/net/http2/server.go +++ /dev/null @@ -1,3347 +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. - -// TODO: turn off the serve goroutine when idle, so -// an idle conn only has the readFrames goroutine active. (which could -// also be optimized probably to pin less memory in crypto/tls). This -// would involve tracking when the serve goroutine is active (atomic -// int32 read/CAS probably?) and starting it up when frames arrive, -// and shutting it down when all handlers exit. the occasional PING -// packets could use time.AfterFunc to call sc.wakeStartServeLoop() -// (which is a no-op if already running) and then queue the PING write -// as normal. The serve loop would then exit in most cases (if no -// Handlers running) and not be woken up again until the PING packet -// returns. - -// TODO (maybe): add a mechanism for Handlers to going into -// half-closed-local mode (rw.(io.Closer) test?) but not exit their -// handler, and continue to be able to read from the -// Request.Body. This would be a somewhat semantic change from HTTP/1 -// (or at least what we expose in net/http), so I'd probably want to -// add it there too. For now, this package says that returning from -// the Handler ServeHTTP function means you're both done reading and -// done writing, without a way to stop just one or the other. - -package http2 - -import ( - "bufio" - "bytes" - "context" - "crypto/rand" - "crypto/tls" - "errors" - "fmt" - "io" - "log" - "math" - "net" - "net/http" - "net/textproto" - "net/url" - "os" - "reflect" - "runtime" - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" - "golang.org/x/net/internal/httpcommon" -) - -const ( - prefaceTimeout = 10 * time.Second - firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway - handlerChunkWriteSize = 4 << 10 - defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? - - // maxQueuedControlFrames is the maximum number of control frames like - // SETTINGS, PING and RST_STREAM that will be queued for writing before - // the connection is closed to prevent memory exhaustion attacks. - maxQueuedControlFrames = 10000 -) - -var ( - errClientDisconnected = errors.New("client disconnected") - errClosedBody = errors.New("body closed by handler") - errHandlerComplete = errors.New("http2: request body closed due to handler exiting") - errStreamClosed = errors.New("http2: stream closed") -) - -var responseWriterStatePool = sync.Pool{ - New: func() interface{} { - rws := &responseWriterState{} - rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize) - return rws - }, -} - -// Test hooks. -var ( - testHookOnConn func() - testHookGetServerConn func(*serverConn) - testHookOnPanicMu *sync.Mutex // nil except in tests - testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool) -) - -// Server is an HTTP/2 server. -type Server struct { - // MaxHandlers limits the number of http.Handler ServeHTTP goroutines - // which may run at a time over all connections. - // Negative or zero no limit. - // TODO: implement - MaxHandlers int - - // MaxConcurrentStreams optionally specifies the number of - // concurrent streams that each client may have open at a - // time. This is unrelated to the number of http.Handler goroutines - // which may be active globally, which is MaxHandlers. - // If zero, MaxConcurrentStreams defaults to at least 100, per - // the HTTP/2 spec's recommendations. - MaxConcurrentStreams uint32 - - // MaxDecoderHeaderTableSize optionally specifies the http2 - // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It - // informs the remote endpoint of the maximum size of the header compression - // table used to decode header blocks, in octets. If zero, the default value - // of 4096 is used. - MaxDecoderHeaderTableSize uint32 - - // MaxEncoderHeaderTableSize optionally specifies an upper limit for the - // header compression table used for encoding request headers. Received - // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero, - // the default value of 4096 is used. - MaxEncoderHeaderTableSize uint32 - - // MaxReadFrameSize optionally specifies the largest frame - // this server is willing to read. A valid value is between - // 16k and 16M, inclusive. If zero or otherwise invalid, a - // default value is used. - MaxReadFrameSize uint32 - - // PermitProhibitedCipherSuites, if true, permits the use of - // cipher suites prohibited by the HTTP/2 spec. - PermitProhibitedCipherSuites bool - - // IdleTimeout specifies how long until idle clients should be - // closed with a GOAWAY frame. PING frames are not considered - // activity for the purposes of IdleTimeout. - // If zero or negative, there is no timeout. - IdleTimeout time.Duration - - // ReadIdleTimeout is the timeout after which a health check using a ping - // frame will be carried out if no frame is received on the connection. - // If zero, no health check is performed. - ReadIdleTimeout time.Duration - - // PingTimeout is the timeout after which the connection will be closed - // if a response to a ping is not received. - // If zero, a default of 15 seconds is used. - PingTimeout time.Duration - - // WriteByteTimeout is the timeout after which a connection will be - // closed if no data can be written to it. The timeout begins when data is - // available to write, and is extended whenever any bytes are written. - // If zero or negative, there is no timeout. - WriteByteTimeout time.Duration - - // MaxUploadBufferPerConnection is the size of the initial flow - // control window for each connections. The HTTP/2 spec does not - // allow this to be smaller than 65535 or larger than 2^32-1. - // If the value is outside this range, a default value will be - // used instead. - MaxUploadBufferPerConnection int32 - - // MaxUploadBufferPerStream is the size of the initial flow control - // window for each stream. The HTTP/2 spec does not allow this to - // be larger than 2^32-1. If the value is zero or larger than the - // maximum, a default value will be used instead. - MaxUploadBufferPerStream int32 - - // NewWriteScheduler constructs a write scheduler for a connection. - // If nil, a default scheduler is chosen. - NewWriteScheduler func() WriteScheduler - - // CountError, if non-nil, is called on HTTP/2 server errors. - // It's intended to increment a metric for monitoring, such - // as an expvar or Prometheus metric. - // The errType consists of only ASCII word characters. - CountError func(errType string) - - // Internal state. This is a pointer (rather than embedded directly) - // so that we don't embed a Mutex in this struct, which will make the - // struct non-copyable, which might break some callers. - state *serverInternalState - - // Synchronization group used for testing. - // Outside of tests, this is nil. - group synctestGroupInterface -} - -func (s *Server) markNewGoroutine() { - if s.group != nil { - s.group.Join() - } -} - -func (s *Server) now() time.Time { - if s.group != nil { - return s.group.Now() - } - return time.Now() -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (s *Server) newTimer(d time.Duration) timer { - if s.group != nil { - return s.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (s *Server) afterFunc(d time.Duration, f func()) timer { - if s.group != nil { - return s.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} -} - -type serverInternalState struct { - mu sync.Mutex - activeConns map[*serverConn]struct{} -} - -func (s *serverInternalState) registerConn(sc *serverConn) { - if s == nil { - return // if the Server was used without calling ConfigureServer - } - s.mu.Lock() - s.activeConns[sc] = struct{}{} - s.mu.Unlock() -} - -func (s *serverInternalState) unregisterConn(sc *serverConn) { - if s == nil { - return // if the Server was used without calling ConfigureServer - } - s.mu.Lock() - delete(s.activeConns, sc) - s.mu.Unlock() -} - -func (s *serverInternalState) startGracefulShutdown() { - if s == nil { - return // if the Server was used without calling ConfigureServer - } - s.mu.Lock() - for sc := range s.activeConns { - sc.startGracefulShutdown() - } - s.mu.Unlock() -} - -// ConfigureServer adds HTTP/2 support to a net/http Server. -// -// The configuration conf may be nil. -// -// ConfigureServer must be called before s begins serving. -func ConfigureServer(s *http.Server, conf *Server) error { - if s == nil { - panic("nil *http.Server") - } - if conf == nil { - conf = new(Server) - } - conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} - if h1, h2 := s, conf; h2.IdleTimeout == 0 { - if h1.IdleTimeout != 0 { - h2.IdleTimeout = h1.IdleTimeout - } else { - h2.IdleTimeout = h1.ReadTimeout - } - } - s.RegisterOnShutdown(conf.state.startGracefulShutdown) - - if s.TLSConfig == nil { - s.TLSConfig = new(tls.Config) - } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 { - // If they already provided a TLS 1.0–1.2 CipherSuite list, return an - // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or - // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. - haveRequired := false - for _, cs := range s.TLSConfig.CipherSuites { - switch cs { - case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - // Alternative MTI cipher to not discourage ECDSA-only servers. - // See http://golang.org/cl/30721 for further information. - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - haveRequired = true - } - } - if !haveRequired { - return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)") - } - } - - // Note: not setting MinVersion to tls.VersionTLS12, - // as we don't want to interfere with HTTP/1.1 traffic - // on the user's server. We enforce TLS 1.2 later once - // we accept a connection. Ideally this should be done - // during next-proto selection, but using TLS <1.2 with - // HTTP/2 is still the client's bug. - - s.TLSConfig.PreferServerCipherSuites = true - - if !strSliceContains(s.TLSConfig.NextProtos, NextProtoTLS) { - s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS) - } - if !strSliceContains(s.TLSConfig.NextProtos, "http/1.1") { - s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1") - } - - if s.TLSNextProto == nil { - s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} - } - protoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) { - if testHookOnConn != nil { - testHookOnConn() - } - // The TLSNextProto interface predates contexts, so - // the net/http package passes down its per-connection - // base context via an exported but unadvertised - // method on the Handler. This is for internal - // net/http<=>http2 use only. - var ctx context.Context - type baseContexter interface { - BaseContext() context.Context - } - if bc, ok := h.(baseContexter); ok { - ctx = bc.BaseContext() - } - conf.ServeConn(c, &ServeConnOpts{ - Context: ctx, - Handler: h, - BaseConfig: hs, - SawClientPreface: sawClientPreface, - }) - } - s.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) { - protoHandler(hs, c, h, false) - } - // The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns. - // - // A connection passed in this method has already had the HTTP/2 preface read from it. - s.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) { - nc, err := unencryptedNetConnFromTLSConn(c) - if err != nil { - if lg := hs.ErrorLog; lg != nil { - lg.Print(err) - } else { - log.Print(err) - } - go c.Close() - return - } - protoHandler(hs, nc, h, true) - } - return nil -} - -// ServeConnOpts are options for the Server.ServeConn method. -type ServeConnOpts struct { - // Context is the base context to use. - // If nil, context.Background is used. - Context context.Context - - // BaseConfig optionally sets the base configuration - // for values. If nil, defaults are used. - BaseConfig *http.Server - - // Handler specifies which handler to use for processing - // requests. If nil, BaseConfig.Handler is used. If BaseConfig - // or BaseConfig.Handler is nil, http.DefaultServeMux is used. - Handler http.Handler - - // UpgradeRequest is an initial request received on a connection - // undergoing an h2c upgrade. The request body must have been - // completely read from the connection before calling ServeConn, - // and the 101 Switching Protocols response written. - UpgradeRequest *http.Request - - // Settings is the decoded contents of the HTTP2-Settings header - // in an h2c upgrade request. - Settings []byte - - // SawClientPreface is set if the HTTP/2 connection preface - // has already been read from the connection. - SawClientPreface bool -} - -func (o *ServeConnOpts) context() context.Context { - if o != nil && o.Context != nil { - return o.Context - } - return context.Background() -} - -func (o *ServeConnOpts) baseConfig() *http.Server { - if o != nil && o.BaseConfig != nil { - return o.BaseConfig - } - return new(http.Server) -} - -func (o *ServeConnOpts) handler() http.Handler { - if o != nil { - if o.Handler != nil { - return o.Handler - } - if o.BaseConfig != nil && o.BaseConfig.Handler != nil { - return o.BaseConfig.Handler - } - } - return http.DefaultServeMux -} - -// ServeConn serves HTTP/2 requests on the provided connection and -// blocks until the connection is no longer readable. -// -// ServeConn starts speaking HTTP/2 assuming that c has not had any -// reads or writes. It writes its initial settings frame and expects -// to be able to read the preface and settings frame from the -// client. If c has a ConnectionState method like a *tls.Conn, the -// ConnectionState is used to verify the TLS ciphersuite and to set -// the Request.TLS field in Handlers. -// -// ServeConn does not support h2c by itself. Any h2c support must be -// implemented in terms of providing a suitably-behaving net.Conn. -// -// The opts parameter is optional. If nil, default values are used. -func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { - s.serveConn(c, opts, nil) -} - -func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) { - baseCtx, cancel := serverConnBaseContext(c, opts) - defer cancel() - - http1srv := opts.baseConfig() - conf := configFromServer(http1srv, s) - sc := &serverConn{ - srv: s, - hs: http1srv, - conn: c, - baseCtx: baseCtx, - remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(s.group, c, conf.WriteByteTimeout), - handler: opts.handler(), - streams: make(map[uint32]*stream), - readFrameCh: make(chan readFrameResult), - wantWriteFrameCh: make(chan FrameWriteRequest, 8), - serveMsgCh: make(chan interface{}, 8), - wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync - bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way - doneServing: make(chan struct{}), - clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" - advMaxStreams: conf.MaxConcurrentStreams, - initialStreamSendWindowSize: initialWindowSize, - initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, - maxFrameSize: initialMaxFrameSize, - pingTimeout: conf.PingTimeout, - countErrorFunc: conf.CountError, - serveG: newGoroutineLock(), - pushEnabled: true, - sawClientPreface: opts.SawClientPreface, - } - if newf != nil { - newf(sc) - } - - s.state.registerConn(sc) - defer s.state.unregisterConn(sc) - - // The net/http package sets the write deadline from the - // http.Server.WriteTimeout during the TLS handshake, but then - // passes the connection off to us with the deadline already set. - // Write deadlines are set per stream in serverConn.newStream. - // Disarm the net.Conn write deadline here. - if sc.hs.WriteTimeout > 0 { - sc.conn.SetWriteDeadline(time.Time{}) - } - - if s.NewWriteScheduler != nil { - sc.writeSched = s.NewWriteScheduler() - } else { - sc.writeSched = newRoundRobinWriteScheduler() - } - - // These start at the RFC-specified defaults. If there is a higher - // configured value for inflow, that will be updated when we send a - // WINDOW_UPDATE shortly after sending SETTINGS. - sc.flow.add(initialWindowSize) - sc.inflow.init(initialWindowSize) - sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) - sc.hpackEncoder.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize) - - fr := NewFramer(sc.bw, c) - if conf.CountError != nil { - fr.countError = conf.CountError - } - fr.ReadMetaHeaders = hpack.NewDecoder(conf.MaxDecoderHeaderTableSize, nil) - fr.MaxHeaderListSize = sc.maxHeaderListSize() - fr.SetMaxReadFrameSize(conf.MaxReadFrameSize) - sc.framer = fr - - if tc, ok := c.(connectionStater); ok { - sc.tlsState = new(tls.ConnectionState) - *sc.tlsState = tc.ConnectionState() - // 9.2 Use of TLS Features - // An implementation of HTTP/2 over TLS MUST use TLS - // 1.2 or higher with the restrictions on feature set - // and cipher suite described in this section. Due to - // implementation limitations, it might not be - // possible to fail TLS negotiation. An endpoint MUST - // immediately terminate an HTTP/2 connection that - // does not meet the TLS requirements described in - // this section with a connection error (Section - // 5.4.1) of type INADEQUATE_SECURITY. - if sc.tlsState.Version < tls.VersionTLS12 { - sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low") - return - } - - if sc.tlsState.ServerName == "" { - // Client must use SNI, but we don't enforce that anymore, - // since it was causing problems when connecting to bare IP - // addresses during development. - // - // TODO: optionally enforce? Or enforce at the time we receive - // a new request, and verify the ServerName matches the :authority? - // But that precludes proxy situations, perhaps. - // - // So for now, do nothing here again. - } - - if !conf.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) { - // "Endpoints MAY choose to generate a connection error - // (Section 5.4.1) of type INADEQUATE_SECURITY if one of - // the prohibited cipher suites are negotiated." - // - // We choose that. In my opinion, the spec is weak - // here. It also says both parties must support at least - // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no - // excuses here. If we really must, we could allow an - // "AllowInsecureWeakCiphers" option on the server later. - // Let's see how it plays out first. - sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite)) - return - } - } - - if opts.Settings != nil { - fr := &SettingsFrame{ - FrameHeader: FrameHeader{valid: true}, - p: opts.Settings, - } - if err := fr.ForeachSetting(sc.processSetting); err != nil { - sc.rejectConn(ErrCodeProtocol, "invalid settings") - return - } - opts.Settings = nil - } - - if hook := testHookGetServerConn; hook != nil { - hook(sc) - } - - if opts.UpgradeRequest != nil { - sc.upgradeRequest(opts.UpgradeRequest) - opts.UpgradeRequest = nil - } - - sc.serve(conf) -} - -func serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) { - ctx, cancel = context.WithCancel(opts.context()) - ctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr()) - if hs := opts.baseConfig(); hs != nil { - ctx = context.WithValue(ctx, http.ServerContextKey, hs) - } - return -} - -func (sc *serverConn) rejectConn(err ErrCode, debug string) { - sc.vlogf("http2: server rejecting conn: %v, %s", err, debug) - // ignoring errors. hanging up anyway. - sc.framer.WriteGoAway(0, err, []byte(debug)) - sc.bw.Flush() - sc.conn.Close() -} - -type serverConn struct { - // Immutable: - srv *Server - hs *http.Server - conn net.Conn - bw *bufferedWriter // writing to conn - handler http.Handler - baseCtx context.Context - framer *Framer - doneServing chan struct{} // closed when serverConn.serve ends - readFrameCh chan readFrameResult // written by serverConn.readFrames - wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve - wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes - bodyReadCh chan bodyReadMsg // from handlers -> serve - serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop - flow outflow // conn-wide (not stream-specific) outbound flow control - inflow inflow // conn-wide inbound flow control - tlsState *tls.ConnectionState // shared by all handlers, like net/http - remoteAddrStr string - writeSched WriteScheduler - countErrorFunc func(errType string) - - // Everything following is owned by the serve loop; use serveG.check(): - serveG goroutineLock // used to verify funcs are on serve() - pushEnabled bool - sawClientPreface bool // preface has already been read, used in h2c upgrade - sawFirstSettings bool // got the initial SETTINGS frame after the preface - needToSendSettingsAck bool - unackedSettings int // how many SETTINGS have we sent without ACKs? - queuedControlFrames int // control frames in the writeSched queue - clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) - advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client - curClientStreams uint32 // number of open streams initiated by the client - curPushedStreams uint32 // number of open streams initiated by server push - curHandlers uint32 // number of running handler goroutines - maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests - maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes - streams map[uint32]*stream - unstartedHandlers []unstartedHandler - initialStreamSendWindowSize int32 - initialStreamRecvWindowSize int32 - maxFrameSize int32 - peerMaxHeaderListSize uint32 // zero means unknown (default) - canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case - canonHeaderKeysSize int // canonHeader keys size in bytes - writingFrame bool // started writing a frame (on serve goroutine or separate) - writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh - needsFrameFlush bool // last frame write wasn't a flush - inGoAway bool // we've started to or sent GOAWAY - inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop - needToSendGoAway bool // we need to schedule a GOAWAY frame write - pingSent bool - sentPingData [8]byte - goAwayCode ErrCode - shutdownTimer timer // nil until used - idleTimer timer // nil if unused - readIdleTimeout time.Duration - pingTimeout time.Duration - readIdleTimer timer // nil if unused - - // Owned by the writeFrameAsync goroutine: - headerWriteBuf bytes.Buffer - hpackEncoder *hpack.Encoder - - // Used by startGracefulShutdown. - shutdownOnce sync.Once -} - -func (sc *serverConn) maxHeaderListSize() uint32 { - n := sc.hs.MaxHeaderBytes - if n <= 0 { - n = http.DefaultMaxHeaderBytes - } - return uint32(adjustHTTP1MaxHeaderSize(int64(n))) -} - -func (sc *serverConn) curOpenStreams() uint32 { - sc.serveG.check() - return sc.curClientStreams + sc.curPushedStreams -} - -// stream represents a stream. This is the minimal metadata needed by -// the serve goroutine. Most of the actual stream state is owned by -// the http.Handler's goroutine in the responseWriter. Because the -// responseWriter's responseWriterState is recycled at the end of a -// handler, this struct intentionally has no pointer to the -// *responseWriter{,State} itself, as the Handler ending nils out the -// responseWriter's state field. -type stream struct { - // immutable: - sc *serverConn - id uint32 - body *pipe // non-nil if expecting DATA frames - cw closeWaiter // closed wait stream transitions to closed state - ctx context.Context - cancelCtx func() - - // owned by serverConn's serve loop: - bodyBytes int64 // body bytes seen so far - declBodyBytes int64 // or -1 if undeclared - flow outflow // limits writing from Handler to client - inflow inflow // what the client is allowed to POST/etc to us - state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - readDeadline timer // nil if unused - writeDeadline timer // nil if unused - closeErr error // set before cw is closed - - trailer http.Header // accumulated trailers - reqTrailer http.Header // handler's Request.Trailer -} - -func (sc *serverConn) Framer() *Framer { return sc.framer } -func (sc *serverConn) CloseConn() error { return sc.conn.Close() } -func (sc *serverConn) Flush() error { return sc.bw.Flush() } -func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) { - return sc.hpackEncoder, &sc.headerWriteBuf -} - -func (sc *serverConn) state(streamID uint32) (streamState, *stream) { - sc.serveG.check() - // http://tools.ietf.org/html/rfc7540#section-5.1 - if st, ok := sc.streams[streamID]; ok { - return st.state, st - } - // "The first use of a new stream identifier implicitly closes all - // streams in the "idle" state that might have been initiated by - // that peer with a lower-valued stream identifier. For example, if - // a client sends a HEADERS frame on stream 7 without ever sending a - // frame on stream 5, then stream 5 transitions to the "closed" - // state when the first frame for stream 7 is sent or received." - if streamID%2 == 1 { - if streamID <= sc.maxClientStreamID { - return stateClosed, nil - } - } else { - if streamID <= sc.maxPushPromiseID { - return stateClosed, nil - } - } - return stateIdle, nil -} - -// setConnState calls the net/http ConnState hook for this connection, if configured. -// Note that the net/http package does StateNew and StateClosed for us. -// There is currently no plan for StateHijacked or hijacking HTTP/2 connections. -func (sc *serverConn) setConnState(state http.ConnState) { - if sc.hs.ConnState != nil { - sc.hs.ConnState(sc.conn, state) - } -} - -func (sc *serverConn) vlogf(format string, args ...interface{}) { - if VerboseLogs { - sc.logf(format, args...) - } -} - -func (sc *serverConn) logf(format string, args ...interface{}) { - if lg := sc.hs.ErrorLog; lg != nil { - lg.Printf(format, args...) - } else { - log.Printf(format, args...) - } -} - -// errno returns v's underlying uintptr, else 0. -// -// TODO: remove this helper function once http2 can use build -// tags. See comment in isClosedConnError. -func errno(v error) uintptr { - if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr { - return uintptr(rv.Uint()) - } - return 0 -} - -// isClosedConnError reports whether err is an error from use of a closed -// network connection. -func isClosedConnError(err error) bool { - if err == nil { - return false - } - - if errors.Is(err, net.ErrClosed) { - return true - } - - // TODO(bradfitz): x/tools/cmd/bundle doesn't really support - // build tags, so I can't make an http2_windows.go file with - // Windows-specific stuff. Fix that and move this, once we - // have a way to bundle this into std's net/http somehow. - if runtime.GOOS == "windows" { - if oe, ok := err.(*net.OpError); ok && oe.Op == "read" { - if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" { - const WSAECONNABORTED = 10053 - const WSAECONNRESET = 10054 - if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED { - return true - } - } - } - } - return false -} - -func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { - if err == nil { - return - } - if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout { - // Boring, expected errors. - sc.vlogf(format, args...) - } else { - sc.logf(format, args...) - } -} - -// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size -// of the entries in the canonHeader cache. -// This should be larger than the size of unique, uncommon header keys likely to -// be sent by the peer, while not so high as to permit unreasonable memory usage -// if the peer sends an unbounded number of unique header keys. -const maxCachedCanonicalHeadersKeysSize = 2048 - -func (sc *serverConn) canonicalHeader(v string) string { - sc.serveG.check() - cv, ok := httpcommon.CachedCanonicalHeader(v) - if ok { - return cv - } - cv, ok = sc.canonHeader[v] - if ok { - return cv - } - if sc.canonHeader == nil { - sc.canonHeader = make(map[string]string) - } - cv = http.CanonicalHeaderKey(v) - size := 100 + len(v)*2 // 100 bytes of map overhead + key + value - if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize { - sc.canonHeader[v] = cv - sc.canonHeaderKeysSize += size - } - return cv -} - -type readFrameResult struct { - f Frame // valid until readMore is called - err error - - // readMore should be called once the consumer no longer needs or - // retains f. After readMore, f is invalid and more frames can be - // read. - readMore func() -} - -// readFrames is the loop that reads incoming frames. -// It takes care to only read one frame at a time, blocking until the -// consumer is done with the frame. -// It's run on its own goroutine. -func (sc *serverConn) readFrames() { - sc.srv.markNewGoroutine() - gate := make(chan struct{}) - gateDone := func() { gate <- struct{}{} } - for { - f, err := sc.framer.ReadFrame() - select { - case sc.readFrameCh <- readFrameResult{f, err, gateDone}: - case <-sc.doneServing: - return - } - select { - case <-gate: - case <-sc.doneServing: - return - } - if terminalReadFrameError(err) { - return - } - } -} - -// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine. -type frameWriteResult struct { - _ incomparable - wr FrameWriteRequest // what was written (or attempted) - err error // result of the writeFrame call -} - -// writeFrameAsync runs in its own goroutine and writes a single frame -// and then reports when it's done. -// At most one goroutine can be running writeFrameAsync at a time per -// serverConn. -func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) { - sc.srv.markNewGoroutine() - var err error - if wd == nil { - err = wr.write.writeFrame(sc) - } else { - err = sc.framer.endWrite() - } - sc.wroteFrameCh <- frameWriteResult{wr: wr, err: err} -} - -func (sc *serverConn) closeAllStreamsOnConnClose() { - sc.serveG.check() - for _, st := range sc.streams { - sc.closeStream(st, errClientDisconnected) - } -} - -func (sc *serverConn) stopShutdownTimer() { - sc.serveG.check() - if t := sc.shutdownTimer; t != nil { - t.Stop() - } -} - -func (sc *serverConn) notePanic() { - // Note: this is for serverConn.serve panicking, not http.Handler code. - if testHookOnPanicMu != nil { - testHookOnPanicMu.Lock() - defer testHookOnPanicMu.Unlock() - } - if testHookOnPanic != nil { - if e := recover(); e != nil { - if testHookOnPanic(sc, e) { - panic(e) - } - } - } -} - -func (sc *serverConn) serve(conf http2Config) { - sc.serveG.check() - defer sc.notePanic() - defer sc.conn.Close() - defer sc.closeAllStreamsOnConnClose() - defer sc.stopShutdownTimer() - defer close(sc.doneServing) // unblocks handlers trying to send - - if VerboseLogs { - sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs) - } - - settings := writeSettings{ - {SettingMaxFrameSize, conf.MaxReadFrameSize}, - {SettingMaxConcurrentStreams, sc.advMaxStreams}, - {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, - {SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize}, - {SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)}, - } - if !disableExtendedConnectProtocol { - settings = append(settings, Setting{SettingEnableConnectProtocol, 1}) - } - sc.writeFrame(FrameWriteRequest{ - write: settings, - }) - sc.unackedSettings++ - - // Each connection starts with initialWindowSize inflow tokens. - // If a higher value is configured, we add more tokens. - if diff := conf.MaxUploadBufferPerConnection - initialWindowSize; diff > 0 { - sc.sendWindowUpdate(nil, int(diff)) - } - - if err := sc.readPreface(); err != nil { - sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err) - return - } - // Now that we've got the preface, get us out of the - // "StateNew" state. We can't go directly to idle, though. - // Active means we read some data and anticipate a request. We'll - // do another Active when we get a HEADERS frame. - sc.setConnState(http.StateActive) - sc.setConnState(http.StateIdle) - - if sc.srv.IdleTimeout > 0 { - sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) - defer sc.idleTimer.Stop() - } - - if conf.SendPingTimeout > 0 { - sc.readIdleTimeout = conf.SendPingTimeout - sc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer) - defer sc.readIdleTimer.Stop() - } - - go sc.readFrames() // closed by defer sc.conn.Close above - - settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer) - defer settingsTimer.Stop() - - lastFrameTime := sc.srv.now() - loopNum := 0 - for { - loopNum++ - select { - case wr := <-sc.wantWriteFrameCh: - if se, ok := wr.write.(StreamError); ok { - sc.resetStream(se) - break - } - sc.writeFrame(wr) - case res := <-sc.wroteFrameCh: - sc.wroteFrame(res) - case res := <-sc.readFrameCh: - lastFrameTime = sc.srv.now() - // Process any written frames before reading new frames from the client since a - // written frame could have triggered a new stream to be started. - if sc.writingFrameAsync { - select { - case wroteRes := <-sc.wroteFrameCh: - sc.wroteFrame(wroteRes) - default: - } - } - if !sc.processFrameFromReader(res) { - return - } - res.readMore() - if settingsTimer != nil { - settingsTimer.Stop() - settingsTimer = nil - } - case m := <-sc.bodyReadCh: - sc.noteBodyRead(m.st, m.n) - case msg := <-sc.serveMsgCh: - switch v := msg.(type) { - case func(int): - v(loopNum) // for testing - case *serverMessage: - switch v { - case settingsTimerMsg: - sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) - return - case idleTimerMsg: - sc.vlogf("connection is idle") - sc.goAway(ErrCodeNo) - case readIdleTimerMsg: - sc.handlePingTimer(lastFrameTime) - case shutdownTimerMsg: - sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) - return - case gracefulShutdownMsg: - sc.startGracefulShutdownInternal() - case handlerDoneMsg: - sc.handlerDone() - default: - panic("unknown timer") - } - case *startPushRequest: - sc.startPush(v) - case func(*serverConn): - v(sc) - default: - panic(fmt.Sprintf("unexpected type %T", v)) - } - } - - // If the peer is causing us to generate a lot of control frames, - // but not reading them from us, assume they are trying to make us - // run out of memory. - if sc.queuedControlFrames > maxQueuedControlFrames { - sc.vlogf("http2: too many control frames in send queue, closing connection") - return - } - - // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY - // with no error code (graceful shutdown), don't start the timer until - // all open streams have been completed. - sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame - gracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0 - if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) { - sc.shutDownIn(goAwayTimeout) - } - } -} - -func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) { - if sc.pingSent { - sc.vlogf("timeout waiting for PING response") - sc.conn.Close() - return - } - - pingAt := lastFrameReadTime.Add(sc.readIdleTimeout) - now := sc.srv.now() - if pingAt.After(now) { - // We received frames since arming the ping timer. - // Reset it for the next possible timeout. - sc.readIdleTimer.Reset(pingAt.Sub(now)) - return - } - - sc.pingSent = true - // Ignore crypto/rand.Read errors: It generally can't fail, and worse case if it does - // is we send a PING frame containing 0s. - _, _ = rand.Read(sc.sentPingData[:]) - sc.writeFrame(FrameWriteRequest{ - write: &writePing{data: sc.sentPingData}, - }) - sc.readIdleTimer.Reset(sc.pingTimeout) -} - -type serverMessage int - -// Message values sent to serveMsgCh. -var ( - settingsTimerMsg = new(serverMessage) - idleTimerMsg = new(serverMessage) - readIdleTimerMsg = new(serverMessage) - shutdownTimerMsg = new(serverMessage) - gracefulShutdownMsg = new(serverMessage) - handlerDoneMsg = new(serverMessage) -) - -func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } -func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) } -func (sc *serverConn) onReadIdleTimer() { sc.sendServeMsg(readIdleTimerMsg) } -func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) } - -func (sc *serverConn) sendServeMsg(msg interface{}) { - sc.serveG.checkNotOn() // NOT - select { - case sc.serveMsgCh <- msg: - case <-sc.doneServing: - } -} - -var errPrefaceTimeout = errors.New("timeout waiting for client preface") - -// readPreface reads the ClientPreface greeting from the peer or -// returns errPrefaceTimeout on timeout, or an error if the greeting -// is invalid. -func (sc *serverConn) readPreface() error { - if sc.sawClientPreface { - return nil - } - errc := make(chan error, 1) - go func() { - // Read the client preface - buf := make([]byte, len(ClientPreface)) - if _, err := io.ReadFull(sc.conn, buf); err != nil { - errc <- err - } else if !bytes.Equal(buf, clientPreface) { - errc <- fmt.Errorf("bogus greeting %q", buf) - } else { - errc <- nil - } - }() - timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server? - defer timer.Stop() - select { - case <-timer.C(): - return errPrefaceTimeout - case err := <-errc: - if err == nil { - if VerboseLogs { - sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr()) - } - } - return err - } -} - -var errChanPool = sync.Pool{ - New: func() interface{} { return make(chan error, 1) }, -} - -var writeDataPool = sync.Pool{ - New: func() interface{} { return new(writeData) }, -} - -// writeDataFromHandler writes DATA response frames from a handler on -// the given stream. -func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error { - ch := errChanPool.Get().(chan error) - writeArg := writeDataPool.Get().(*writeData) - *writeArg = writeData{stream.id, data, endStream} - err := sc.writeFrameFromHandler(FrameWriteRequest{ - write: writeArg, - stream: stream, - done: ch, - }) - if err != nil { - return err - } - var frameWriteDone bool // the frame write is done (successfully or not) - select { - case err = <-ch: - frameWriteDone = true - case <-sc.doneServing: - return errClientDisconnected - case <-stream.cw: - // If both ch and stream.cw were ready (as might - // happen on the final Write after an http.Handler - // ends), prefer the write result. Otherwise this - // might just be us successfully closing the stream. - // The writeFrameAsync and serve goroutines guarantee - // that the ch send will happen before the stream.cw - // close. - select { - case err = <-ch: - frameWriteDone = true - default: - return errStreamClosed - } - } - errChanPool.Put(ch) - if frameWriteDone { - writeDataPool.Put(writeArg) - } - return err -} - -// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts -// if the connection has gone away. -// -// This must not be run from the serve goroutine itself, else it might -// deadlock writing to sc.wantWriteFrameCh (which is only mildly -// buffered and is read by serve itself). If you're on the serve -// goroutine, call writeFrame instead. -func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error { - sc.serveG.checkNotOn() // NOT - select { - case sc.wantWriteFrameCh <- wr: - return nil - case <-sc.doneServing: - // Serve loop is gone. - // Client has closed their connection to the server. - return errClientDisconnected - } -} - -// writeFrame schedules a frame to write and sends it if there's nothing -// already being written. -// -// There is no pushback here (the serve goroutine never blocks). It's -// the http.Handlers that block, waiting for their previous frames to -// make it onto the wire -// -// If you're not on the serve goroutine, use writeFrameFromHandler instead. -func (sc *serverConn) writeFrame(wr FrameWriteRequest) { - sc.serveG.check() - - // If true, wr will not be written and wr.done will not be signaled. - var ignoreWrite bool - - // We are not allowed to write frames on closed streams. RFC 7540 Section - // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on - // a closed stream." Our server never sends PRIORITY, so that exception - // does not apply. - // - // The serverConn might close an open stream while the stream's handler - // is still running. For example, the server might close a stream when it - // receives bad data from the client. If this happens, the handler might - // attempt to write a frame after the stream has been closed (since the - // handler hasn't yet been notified of the close). In this case, we simply - // ignore the frame. The handler will notice that the stream is closed when - // it waits for the frame to be written. - // - // As an exception to this rule, we allow sending RST_STREAM after close. - // This allows us to immediately reject new streams without tracking any - // state for those streams (except for the queued RST_STREAM frame). This - // may result in duplicate RST_STREAMs in some cases, but the client should - // ignore those. - if wr.StreamID() != 0 { - _, isReset := wr.write.(StreamError) - if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset { - ignoreWrite = true - } - } - - // Don't send a 100-continue response if we've already sent headers. - // See golang.org/issue/14030. - switch wr.write.(type) { - case *writeResHeaders: - wr.stream.wroteHeaders = true - case write100ContinueHeadersFrame: - if wr.stream.wroteHeaders { - // We do not need to notify wr.done because this frame is - // never written with wr.done != nil. - if wr.done != nil { - panic("wr.done != nil for write100ContinueHeadersFrame") - } - ignoreWrite = true - } - } - - if !ignoreWrite { - if wr.isControl() { - sc.queuedControlFrames++ - // For extra safety, detect wraparounds, which should not happen, - // and pull the plug. - if sc.queuedControlFrames < 0 { - sc.conn.Close() - } - } - sc.writeSched.Push(wr) - } - sc.scheduleFrameWrite() -} - -// startFrameWrite starts a goroutine to write wr (in a separate -// goroutine since that might block on the network), and updates the -// serve goroutine's state about the world, updated from info in wr. -func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) { - sc.serveG.check() - if sc.writingFrame { - panic("internal error: can only be writing one frame at a time") - } - - st := wr.stream - if st != nil { - switch st.state { - case stateHalfClosedLocal: - switch wr.write.(type) { - case StreamError, handlerPanicRST, writeWindowUpdate: - // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE - // in this state. (We never send PRIORITY from the server, so that is not checked.) - default: - panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr)) - } - case stateClosed: - panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr)) - } - } - if wpp, ok := wr.write.(*writePushPromise); ok { - var err error - wpp.promisedID, err = wpp.allocatePromisedID() - if err != nil { - sc.writingFrameAsync = false - wr.replyToWriter(err) - return - } - } - - sc.writingFrame = true - sc.needsFrameFlush = true - if wr.write.staysWithinBuffer(sc.bw.Available()) { - sc.writingFrameAsync = false - err := wr.write.writeFrame(sc) - sc.wroteFrame(frameWriteResult{wr: wr, err: err}) - } else if wd, ok := wr.write.(*writeData); ok { - // Encode the frame in the serve goroutine, to ensure we don't have - // any lingering asynchronous references to data passed to Write. - // See https://go.dev/issue/58446. - sc.framer.startWriteDataPadded(wd.streamID, wd.endStream, wd.p, nil) - sc.writingFrameAsync = true - go sc.writeFrameAsync(wr, wd) - } else { - sc.writingFrameAsync = true - go sc.writeFrameAsync(wr, nil) - } -} - -// errHandlerPanicked is the error given to any callers blocked in a read from -// Request.Body when the main goroutine panics. Since most handlers read in the -// main ServeHTTP goroutine, this will show up rarely. -var errHandlerPanicked = errors.New("http2: handler panicked") - -// wroteFrame is called on the serve goroutine with the result of -// whatever happened on writeFrameAsync. -func (sc *serverConn) wroteFrame(res frameWriteResult) { - sc.serveG.check() - if !sc.writingFrame { - panic("internal error: expected to be already writing a frame") - } - sc.writingFrame = false - sc.writingFrameAsync = false - - if res.err != nil { - sc.conn.Close() - } - - wr := res.wr - - if writeEndsStream(wr.write) { - st := wr.stream - if st == nil { - panic("internal error: expecting non-nil stream") - } - switch st.state { - case stateOpen: - // Here we would go to stateHalfClosedLocal in - // theory, but since our handler is done and - // the net/http package provides no mechanism - // for closing a ResponseWriter while still - // reading data (see possible TODO at top of - // this file), we go into closed state here - // anyway, after telling the peer we're - // hanging up on them. We'll transition to - // stateClosed after the RST_STREAM frame is - // written. - st.state = stateHalfClosedLocal - // Section 8.1: a server MAY request that the client abort - // transmission of a request without error by sending a - // RST_STREAM with an error code of NO_ERROR after sending - // a complete response. - sc.resetStream(streamError(st.id, ErrCodeNo)) - case stateHalfClosedRemote: - sc.closeStream(st, errHandlerComplete) - } - } else { - switch v := wr.write.(type) { - case StreamError: - // st may be unknown if the RST_STREAM was generated to reject bad input. - if st, ok := sc.streams[v.StreamID]; ok { - sc.closeStream(st, v) - } - case handlerPanicRST: - sc.closeStream(wr.stream, errHandlerPanicked) - } - } - - // Reply (if requested) to unblock the ServeHTTP goroutine. - wr.replyToWriter(res.err) - - sc.scheduleFrameWrite() -} - -// scheduleFrameWrite tickles the frame writing scheduler. -// -// If a frame is already being written, nothing happens. This will be called again -// when the frame is done being written. -// -// If a frame isn't being written and we need to send one, the best frame -// to send is selected by writeSched. -// -// If a frame isn't being written and there's nothing else to send, we -// flush the write buffer. -func (sc *serverConn) scheduleFrameWrite() { - sc.serveG.check() - if sc.writingFrame || sc.inFrameScheduleLoop { - return - } - sc.inFrameScheduleLoop = true - for !sc.writingFrameAsync { - if sc.needToSendGoAway { - sc.needToSendGoAway = false - sc.startFrameWrite(FrameWriteRequest{ - write: &writeGoAway{ - maxStreamID: sc.maxClientStreamID, - code: sc.goAwayCode, - }, - }) - continue - } - if sc.needToSendSettingsAck { - sc.needToSendSettingsAck = false - sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}}) - continue - } - if !sc.inGoAway || sc.goAwayCode == ErrCodeNo { - if wr, ok := sc.writeSched.Pop(); ok { - if wr.isControl() { - sc.queuedControlFrames-- - } - sc.startFrameWrite(wr) - continue - } - } - if sc.needsFrameFlush { - sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}}) - sc.needsFrameFlush = false // after startFrameWrite, since it sets this true - continue - } - break - } - sc.inFrameScheduleLoop = false -} - -// startGracefulShutdown gracefully shuts down a connection. This -// sends GOAWAY with ErrCodeNo to tell the client we're gracefully -// shutting down. The connection isn't closed until all current -// streams are done. -// -// startGracefulShutdown returns immediately; it does not wait until -// the connection has shut down. -func (sc *serverConn) startGracefulShutdown() { - sc.serveG.checkNotOn() // NOT - sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) -} - -// After sending GOAWAY with an error code (non-graceful shutdown), the -// connection will close after goAwayTimeout. -// -// If we close the connection immediately after sending GOAWAY, there may -// be unsent data in our kernel receive buffer, which will cause the kernel -// to send a TCP RST on close() instead of a FIN. This RST will abort the -// connection immediately, whether or not the client had received the GOAWAY. -// -// Ideally we should delay for at least 1 RTT + epsilon so the client has -// a chance to read the GOAWAY and stop sending messages. Measuring RTT -// is hard, so we approximate with 1 second. See golang.org/issue/18701. -// -// This is a var so it can be shorter in tests, where all requests uses the -// loopback interface making the expected RTT very small. -// -// TODO: configurable? -var goAwayTimeout = 1 * time.Second - -func (sc *serverConn) startGracefulShutdownInternal() { - sc.goAway(ErrCodeNo) -} - -func (sc *serverConn) goAway(code ErrCode) { - sc.serveG.check() - if sc.inGoAway { - if sc.goAwayCode == ErrCodeNo { - sc.goAwayCode = code - } - return - } - sc.inGoAway = true - sc.needToSendGoAway = true - sc.goAwayCode = code - sc.scheduleFrameWrite() -} - -func (sc *serverConn) shutDownIn(d time.Duration) { - sc.serveG.check() - sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer) -} - -func (sc *serverConn) resetStream(se StreamError) { - sc.serveG.check() - sc.writeFrame(FrameWriteRequest{write: se}) - if st, ok := sc.streams[se.StreamID]; ok { - st.resetQueued = true - } -} - -// processFrameFromReader processes the serve loop's read from readFrameCh from the -// frame-reading goroutine. -// processFrameFromReader returns whether the connection should be kept open. -func (sc *serverConn) processFrameFromReader(res readFrameResult) bool { - sc.serveG.check() - err := res.err - if err != nil { - if err == ErrFrameTooLarge { - sc.goAway(ErrCodeFrameSize) - return true // goAway will close the loop - } - clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) - if clientGone { - // TODO: could we also get into this state if - // the peer does a half close - // (e.g. CloseWrite) because they're done - // sending frames but they're still wanting - // our open replies? Investigate. - // TODO: add CloseWrite to crypto/tls.Conn first - // so we have a way to test this? I suppose - // just for testing we could have a non-TLS mode. - return false - } - } else { - f := res.f - if VerboseLogs { - sc.vlogf("http2: server read frame %v", summarizeFrame(f)) - } - err = sc.processFrame(f) - if err == nil { - return true - } - } - - switch ev := err.(type) { - case StreamError: - sc.resetStream(ev) - return true - case goAwayFlowError: - sc.goAway(ErrCodeFlowControl) - return true - case ConnectionError: - if res.f != nil { - if id := res.f.Header().StreamID; id > sc.maxClientStreamID { - sc.maxClientStreamID = id - } - } - sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev) - sc.goAway(ErrCode(ev)) - return true // goAway will handle shutdown - default: - if res.err != nil { - sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err) - } else { - sc.logf("http2: server closing client connection: %v", err) - } - return false - } -} - -func (sc *serverConn) processFrame(f Frame) error { - sc.serveG.check() - - // First frame received must be SETTINGS. - if !sc.sawFirstSettings { - if _, ok := f.(*SettingsFrame); !ok { - return sc.countError("first_settings", ConnectionError(ErrCodeProtocol)) - } - sc.sawFirstSettings = true - } - - // Discard frames for streams initiated after the identified last - // stream sent in a GOAWAY, or all frames after sending an error. - // We still need to return connection-level flow control for DATA frames. - // RFC 9113 Section 6.8. - if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) { - - if f, ok := f.(*DataFrame); ok { - if !sc.inflow.take(f.Length) { - return sc.countError("data_flow", streamError(f.Header().StreamID, ErrCodeFlowControl)) - } - sc.sendWindowUpdate(nil, int(f.Length)) // conn-level - } - return nil - } - - switch f := f.(type) { - case *SettingsFrame: - return sc.processSettings(f) - case *MetaHeadersFrame: - return sc.processHeaders(f) - case *WindowUpdateFrame: - return sc.processWindowUpdate(f) - case *PingFrame: - return sc.processPing(f) - case *DataFrame: - return sc.processData(f) - case *RSTStreamFrame: - return sc.processResetStream(f) - case *PriorityFrame: - return sc.processPriority(f) - case *GoAwayFrame: - return sc.processGoAway(f) - case *PushPromiseFrame: - // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE - // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. - return sc.countError("push_promise", ConnectionError(ErrCodeProtocol)) - default: - sc.vlogf("http2: server ignoring frame: %v", f.Header()) - return nil - } -} - -func (sc *serverConn) processPing(f *PingFrame) error { - sc.serveG.check() - if f.IsAck() { - if sc.pingSent && sc.sentPingData == f.Data { - // This is a response to a PING we sent. - sc.pingSent = false - sc.readIdleTimer.Reset(sc.readIdleTimeout) - } - // 6.7 PING: " An endpoint MUST NOT respond to PING frames - // containing this flag." - return nil - } - if f.StreamID != 0 { - // "PING frames are not associated with any individual - // stream. If a PING frame is received with a stream - // identifier field value other than 0x0, the recipient MUST - // respond with a connection error (Section 5.4.1) of type - // PROTOCOL_ERROR." - return sc.countError("ping_on_stream", ConnectionError(ErrCodeProtocol)) - } - sc.writeFrame(FrameWriteRequest{write: writePingAck{f}}) - return nil -} - -func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { - sc.serveG.check() - switch { - case f.StreamID != 0: // stream-level flow control - state, st := sc.state(f.StreamID) - if state == stateIdle { - // Section 5.1: "Receiving any frame other than HEADERS - // or PRIORITY on a stream in this state MUST be - // treated as a connection error (Section 5.4.1) of - // type PROTOCOL_ERROR." - return sc.countError("stream_idle", ConnectionError(ErrCodeProtocol)) - } - if st == nil { - // "WINDOW_UPDATE can be sent by a peer that has sent a - // frame bearing the END_STREAM flag. This means that a - // receiver could receive a WINDOW_UPDATE frame on a "half - // closed (remote)" or "closed" stream. A receiver MUST - // NOT treat this as an error, see Section 5.1." - return nil - } - if !st.flow.add(int32(f.Increment)) { - return sc.countError("bad_flow", streamError(f.StreamID, ErrCodeFlowControl)) - } - default: // connection-level flow control - if !sc.flow.add(int32(f.Increment)) { - return goAwayFlowError{} - } - } - sc.scheduleFrameWrite() - return nil -} - -func (sc *serverConn) processResetStream(f *RSTStreamFrame) error { - sc.serveG.check() - - state, st := sc.state(f.StreamID) - if state == stateIdle { - // 6.4 "RST_STREAM frames MUST NOT be sent for a - // stream in the "idle" state. If a RST_STREAM frame - // identifying an idle stream is received, the - // recipient MUST treat this as a connection error - // (Section 5.4.1) of type PROTOCOL_ERROR. - return sc.countError("reset_idle_stream", ConnectionError(ErrCodeProtocol)) - } - if st != nil { - st.cancelCtx() - sc.closeStream(st, streamError(f.StreamID, f.ErrCode)) - } - return nil -} - -func (sc *serverConn) closeStream(st *stream, err error) { - sc.serveG.check() - if st.state == stateIdle || st.state == stateClosed { - panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) - } - st.state = stateClosed - if st.readDeadline != nil { - st.readDeadline.Stop() - } - if st.writeDeadline != nil { - st.writeDeadline.Stop() - } - if st.isPushed() { - sc.curPushedStreams-- - } else { - sc.curClientStreams-- - } - delete(sc.streams, st.id) - if len(sc.streams) == 0 { - sc.setConnState(http.StateIdle) - if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil { - sc.idleTimer.Reset(sc.srv.IdleTimeout) - } - if h1ServerKeepAlivesDisabled(sc.hs) { - sc.startGracefulShutdownInternal() - } - } - if p := st.body; p != nil { - // Return any buffered unread bytes worth of conn-level flow control. - // See golang.org/issue/16481 - sc.sendWindowUpdate(nil, p.Len()) - - p.CloseWithError(err) - } - if e, ok := err.(StreamError); ok { - if e.Cause != nil { - err = e.Cause - } else { - err = errStreamClosed - } - } - st.closeErr = err - st.cancelCtx() - st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc - sc.writeSched.CloseStream(st.id) -} - -func (sc *serverConn) processSettings(f *SettingsFrame) error { - sc.serveG.check() - if f.IsAck() { - sc.unackedSettings-- - if sc.unackedSettings < 0 { - // Why is the peer ACKing settings we never sent? - // The spec doesn't mention this case, but - // hang up on them anyway. - return sc.countError("ack_mystery", ConnectionError(ErrCodeProtocol)) - } - return nil - } - if f.NumSettings() > 100 || f.HasDuplicates() { - // This isn't actually in the spec, but hang up on - // suspiciously large settings frames or those with - // duplicate entries. - return sc.countError("settings_big_or_dups", ConnectionError(ErrCodeProtocol)) - } - if err := f.ForeachSetting(sc.processSetting); err != nil { - return err - } - // TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be - // acknowledged individually, even if multiple are received before the ACK. - sc.needToSendSettingsAck = true - sc.scheduleFrameWrite() - return nil -} - -func (sc *serverConn) processSetting(s Setting) error { - sc.serveG.check() - if err := s.Valid(); err != nil { - return err - } - if VerboseLogs { - sc.vlogf("http2: server processing setting %v", s) - } - switch s.ID { - case SettingHeaderTableSize: - sc.hpackEncoder.SetMaxDynamicTableSize(s.Val) - case SettingEnablePush: - sc.pushEnabled = s.Val != 0 - case SettingMaxConcurrentStreams: - sc.clientMaxStreams = s.Val - case SettingInitialWindowSize: - return sc.processSettingInitialWindowSize(s.Val) - case SettingMaxFrameSize: - sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31 - case SettingMaxHeaderListSize: - sc.peerMaxHeaderListSize = s.Val - case SettingEnableConnectProtocol: - // Receipt of this parameter by a server does not - // have any impact - default: - // Unknown setting: "An endpoint that receives a SETTINGS - // frame with any unknown or unsupported identifier MUST - // ignore that setting." - if VerboseLogs { - sc.vlogf("http2: server ignoring unknown setting %v", s) - } - } - return nil -} - -func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { - sc.serveG.check() - // Note: val already validated to be within range by - // processSetting's Valid call. - - // "A SETTINGS frame can alter the initial flow control window - // size for all current streams. When the value of - // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST - // adjust the size of all stream flow control windows that it - // maintains by the difference between the new value and the - // old value." - old := sc.initialStreamSendWindowSize - sc.initialStreamSendWindowSize = int32(val) - growth := int32(val) - old // may be negative - for _, st := range sc.streams { - if !st.flow.add(growth) { - // 6.9.2 Initial Flow Control Window Size - // "An endpoint MUST treat a change to - // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow - // control window to exceed the maximum size as a - // connection error (Section 5.4.1) of type - // FLOW_CONTROL_ERROR." - return sc.countError("setting_win_size", ConnectionError(ErrCodeFlowControl)) - } - } - return nil -} - -func (sc *serverConn) processData(f *DataFrame) error { - sc.serveG.check() - id := f.Header().StreamID - - data := f.Data() - state, st := sc.state(id) - if id == 0 || state == stateIdle { - // Section 6.1: "DATA frames MUST be associated with a - // stream. If a DATA frame is received whose stream - // identifier field is 0x0, the recipient MUST respond - // with a connection error (Section 5.4.1) of type - // PROTOCOL_ERROR." - // - // Section 5.1: "Receiving any frame other than HEADERS - // or PRIORITY on a stream in this state MUST be - // treated as a connection error (Section 5.4.1) of - // type PROTOCOL_ERROR." - return sc.countError("data_on_idle", ConnectionError(ErrCodeProtocol)) - } - - // "If a DATA frame is received whose stream is not in "open" - // or "half closed (local)" state, the recipient MUST respond - // with a stream error (Section 5.4.2) of type STREAM_CLOSED." - if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued { - // This includes sending a RST_STREAM if the stream is - // in stateHalfClosedLocal (which currently means that - // the http.Handler returned, so it's done reading & - // done writing). Try to stop the client from sending - // more DATA. - - // But still enforce their connection-level flow control, - // and return any flow control bytes since we're not going - // to consume them. - if !sc.inflow.take(f.Length) { - return sc.countError("data_flow", streamError(id, ErrCodeFlowControl)) - } - sc.sendWindowUpdate(nil, int(f.Length)) // conn-level - - if st != nil && st.resetQueued { - // Already have a stream error in flight. Don't send another. - return nil - } - return sc.countError("closed", streamError(id, ErrCodeStreamClosed)) - } - if st.body == nil { - panic("internal error: should have a body in this state") - } - - // Sender sending more than they'd declared? - if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { - if !sc.inflow.take(f.Length) { - return sc.countError("data_flow", streamError(id, ErrCodeFlowControl)) - } - sc.sendWindowUpdate(nil, int(f.Length)) // conn-level - - st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) - // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the - // value of a content-length header field does not equal the sum of the - // DATA frame payload lengths that form the body. - return sc.countError("send_too_much", streamError(id, ErrCodeProtocol)) - } - if f.Length > 0 { - // Check whether the client has flow control quota. - if !takeInflows(&sc.inflow, &st.inflow, f.Length) { - return sc.countError("flow_on_data_length", streamError(id, ErrCodeFlowControl)) - } - - if len(data) > 0 { - st.bodyBytes += int64(len(data)) - wrote, err := st.body.Write(data) - if err != nil { - // The handler has closed the request body. - // Return the connection-level flow control for the discarded data, - // but not the stream-level flow control. - sc.sendWindowUpdate(nil, int(f.Length)-wrote) - return nil - } - if wrote != len(data) { - panic("internal error: bad Writer") - } - } - - // Return any padded flow control now, since we won't - // refund it later on body reads. - // Call sendWindowUpdate even if there is no padding, - // to return buffered flow control credit if the sent - // window has shrunk. - pad := int32(f.Length) - int32(len(data)) - sc.sendWindowUpdate32(nil, pad) - sc.sendWindowUpdate32(st, pad) - } - if f.StreamEnded() { - st.endStream() - } - return nil -} - -func (sc *serverConn) processGoAway(f *GoAwayFrame) error { - sc.serveG.check() - if f.ErrCode != ErrCodeNo { - sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f) - } else { - sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f) - } - sc.startGracefulShutdownInternal() - // http://tools.ietf.org/html/rfc7540#section-6.8 - // We should not create any new streams, which means we should disable push. - sc.pushEnabled = false - return nil -} - -// isPushed reports whether the stream is server-initiated. -func (st *stream) isPushed() bool { - return st.id%2 == 0 -} - -// endStream closes a Request.Body's pipe. It is called when a DATA -// frame says a request body is over (or after trailers). -func (st *stream) endStream() { - sc := st.sc - sc.serveG.check() - - if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes { - st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes", - st.declBodyBytes, st.bodyBytes)) - } else { - st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest) - st.body.CloseWithError(io.EOF) - } - st.state = stateHalfClosedRemote -} - -// copyTrailersToHandlerRequest is run in the Handler's goroutine in -// its Request.Body.Read just before it gets io.EOF. -func (st *stream) copyTrailersToHandlerRequest() { - for k, vv := range st.trailer { - if _, ok := st.reqTrailer[k]; ok { - // Only copy it over it was pre-declared. - st.reqTrailer[k] = vv - } - } -} - -// onReadTimeout is run on its own goroutine (from time.AfterFunc) -// when the stream's ReadTimeout has fired. -func (st *stream) onReadTimeout() { - if st.body != nil { - // Wrap the ErrDeadlineExceeded to avoid callers depending on us - // returning the bare error. - st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded)) - } -} - -// onWriteTimeout is run on its own goroutine (from time.AfterFunc) -// when the stream's WriteTimeout has fired. -func (st *stream) onWriteTimeout() { - st.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{ - StreamID: st.id, - Code: ErrCodeInternal, - Cause: os.ErrDeadlineExceeded, - }}) -} - -func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { - sc.serveG.check() - id := f.StreamID - // http://tools.ietf.org/html/rfc7540#section-5.1.1 - // Streams initiated by a client MUST use odd-numbered stream - // identifiers. [...] An endpoint that receives an unexpected - // stream identifier MUST respond with a connection error - // (Section 5.4.1) of type PROTOCOL_ERROR. - if id%2 != 1 { - return sc.countError("headers_even", ConnectionError(ErrCodeProtocol)) - } - // A HEADERS frame can be used to create a new stream or - // send a trailer for an open one. If we already have a stream - // open, let it process its own HEADERS frame (trailers at this - // point, if it's valid). - if st := sc.streams[f.StreamID]; st != nil { - if st.resetQueued { - // We're sending RST_STREAM to close the stream, so don't bother - // processing this frame. - return nil - } - // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than - // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in - // this state, it MUST respond with a stream error (Section 5.4.2) of - // type STREAM_CLOSED. - if st.state == stateHalfClosedRemote { - return sc.countError("headers_half_closed", streamError(id, ErrCodeStreamClosed)) - } - return st.processTrailerHeaders(f) - } - - // [...] The identifier of a newly established stream MUST be - // numerically greater than all streams that the initiating - // endpoint has opened or reserved. [...] An endpoint that - // receives an unexpected stream identifier MUST respond with - // a connection error (Section 5.4.1) of type PROTOCOL_ERROR. - if id <= sc.maxClientStreamID { - return sc.countError("stream_went_down", ConnectionError(ErrCodeProtocol)) - } - sc.maxClientStreamID = id - - if sc.idleTimer != nil { - sc.idleTimer.Stop() - } - - // http://tools.ietf.org/html/rfc7540#section-5.1.2 - // [...] Endpoints MUST NOT exceed the limit set by their peer. An - // endpoint that receives a HEADERS frame that causes their - // advertised concurrent stream limit to be exceeded MUST treat - // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR - // or REFUSED_STREAM. - if sc.curClientStreams+1 > sc.advMaxStreams { - if sc.unackedSettings == 0 { - // They should know better. - return sc.countError("over_max_streams", streamError(id, ErrCodeProtocol)) - } - // Assume it's a network race, where they just haven't - // received our last SETTINGS update. But actually - // this can't happen yet, because we don't yet provide - // a way for users to adjust server parameters at - // runtime. - return sc.countError("over_max_streams_race", streamError(id, ErrCodeRefusedStream)) - } - - initialState := stateOpen - if f.StreamEnded() { - initialState = stateHalfClosedRemote - } - st := sc.newStream(id, 0, initialState) - - if f.HasPriority() { - if err := sc.checkPriority(f.StreamID, f.Priority); err != nil { - return err - } - sc.writeSched.AdjustStream(st.id, f.Priority) - } - - rw, req, err := sc.newWriterAndRequest(st, f) - if err != nil { - return err - } - st.reqTrailer = req.Trailer - if st.reqTrailer != nil { - st.trailer = make(http.Header) - } - st.body = req.Body.(*requestBody).pipe // may be nil - st.declBodyBytes = req.ContentLength - - handler := sc.handler.ServeHTTP - if f.Truncated { - // Their header list was too long. Send a 431 error. - handler = handleHeaderListTooLong - } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil { - handler = new400Handler(err) - } - - // The net/http package sets the read deadline from the - // http.Server.ReadTimeout during the TLS handshake, but then - // passes the connection off to us with the deadline already - // set. Disarm it here after the request headers are read, - // similar to how the http1 server works. Here it's - // technically more like the http1 Server's ReadHeaderTimeout - // (in Go 1.8), though. That's a more sane option anyway. - if sc.hs.ReadTimeout > 0 { - sc.conn.SetReadDeadline(time.Time{}) - st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout) - } - - return sc.scheduleHandler(id, rw, req, handler) -} - -func (sc *serverConn) upgradeRequest(req *http.Request) { - sc.serveG.check() - id := uint32(1) - sc.maxClientStreamID = id - st := sc.newStream(id, 0, stateHalfClosedRemote) - st.reqTrailer = req.Trailer - if st.reqTrailer != nil { - st.trailer = make(http.Header) - } - rw := sc.newResponseWriter(st, req) - - // Disable any read deadline set by the net/http package - // prior to the upgrade. - if sc.hs.ReadTimeout > 0 { - sc.conn.SetReadDeadline(time.Time{}) - } - - // This is the first request on the connection, - // so start the handler directly rather than going - // through scheduleHandler. - sc.curHandlers++ - go sc.runHandler(rw, req, sc.handler.ServeHTTP) -} - -func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { - sc := st.sc - sc.serveG.check() - if st.gotTrailerHeader { - return sc.countError("dup_trailers", ConnectionError(ErrCodeProtocol)) - } - st.gotTrailerHeader = true - if !f.StreamEnded() { - return sc.countError("trailers_not_ended", streamError(st.id, ErrCodeProtocol)) - } - - if len(f.PseudoFields()) > 0 { - return sc.countError("trailers_pseudo", streamError(st.id, ErrCodeProtocol)) - } - if st.trailer != nil { - for _, hf := range f.RegularFields() { - key := sc.canonicalHeader(hf.Name) - if !httpguts.ValidTrailerHeader(key) { - // TODO: send more details to the peer somehow. But http2 has - // no way to send debug data at a stream level. Discuss with - // HTTP folk. - return sc.countError("trailers_bogus", streamError(st.id, ErrCodeProtocol)) - } - st.trailer[key] = append(st.trailer[key], hf.Value) - } - } - st.endStream() - return nil -} - -func (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error { - if streamID == p.StreamDep { - // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat - // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR." - // Section 5.3.3 says that a stream can depend on one of its dependencies, - // so it's only self-dependencies that are forbidden. - return sc.countError("priority", streamError(streamID, ErrCodeProtocol)) - } - return nil -} - -func (sc *serverConn) processPriority(f *PriorityFrame) error { - if err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil { - return err - } - sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam) - return nil -} - -func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream { - sc.serveG.check() - if id == 0 { - panic("internal error: cannot create stream with id 0") - } - - ctx, cancelCtx := context.WithCancel(sc.baseCtx) - st := &stream{ - sc: sc, - id: id, - state: state, - ctx: ctx, - cancelCtx: cancelCtx, - } - st.cw.Init() - st.flow.conn = &sc.flow // link to conn-level counter - st.flow.add(sc.initialStreamSendWindowSize) - st.inflow.init(sc.initialStreamRecvWindowSize) - if sc.hs.WriteTimeout > 0 { - st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) - } - - sc.streams[id] = st - sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID}) - if st.isPushed() { - sc.curPushedStreams++ - } else { - sc.curClientStreams++ - } - if sc.curOpenStreams() == 1 { - sc.setConnState(http.StateActive) - } - - return st -} - -func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) { - sc.serveG.check() - - rp := httpcommon.ServerRequestParam{ - Method: f.PseudoValue("method"), - Scheme: f.PseudoValue("scheme"), - Authority: f.PseudoValue("authority"), - Path: f.PseudoValue("path"), - Protocol: f.PseudoValue("protocol"), - } - - // extended connect is disabled, so we should not see :protocol - if disableExtendedConnectProtocol && rp.Protocol != "" { - return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) - } - - isConnect := rp.Method == "CONNECT" - if isConnect { - if rp.Protocol == "" && (rp.Path != "" || rp.Scheme != "" || rp.Authority == "") { - return nil, nil, sc.countError("bad_connect", streamError(f.StreamID, ErrCodeProtocol)) - } - } else if rp.Method == "" || rp.Path == "" || (rp.Scheme != "https" && rp.Scheme != "http") { - // See 8.1.2.6 Malformed Requests and Responses: - // - // Malformed requests or responses that are detected - // MUST be treated as a stream error (Section 5.4.2) - // of type PROTOCOL_ERROR." - // - // 8.1.2.3 Request Pseudo-Header Fields - // "All HTTP/2 requests MUST include exactly one valid - // value for the :method, :scheme, and :path - // pseudo-header fields" - return nil, nil, sc.countError("bad_path_method", streamError(f.StreamID, ErrCodeProtocol)) - } - - header := make(http.Header) - rp.Header = header - for _, hf := range f.RegularFields() { - header.Add(sc.canonicalHeader(hf.Name), hf.Value) - } - if rp.Authority == "" { - rp.Authority = header.Get("Host") - } - if rp.Protocol != "" { - header.Set(":protocol", rp.Protocol) - } - - rw, req, err := sc.newWriterAndRequestNoBody(st, rp) - if err != nil { - return nil, nil, err - } - bodyOpen := !f.StreamEnded() - if bodyOpen { - if vv, ok := rp.Header["Content-Length"]; ok { - if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil { - req.ContentLength = int64(cl) - } else { - req.ContentLength = 0 - } - } else { - req.ContentLength = -1 - } - req.Body.(*requestBody).pipe = &pipe{ - b: &dataBuffer{expected: req.ContentLength}, - } - } - return rw, req, nil -} - -func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) { - sc.serveG.check() - - var tlsState *tls.ConnectionState // nil if not scheme https - if rp.Scheme == "https" { - tlsState = sc.tlsState - } - - res := httpcommon.NewServerRequest(rp) - if res.InvalidReason != "" { - return nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol)) - } - - body := &requestBody{ - conn: sc, - stream: st, - needsContinue: res.NeedsContinue, - } - req := (&http.Request{ - Method: rp.Method, - URL: res.URL, - RemoteAddr: sc.remoteAddrStr, - Header: rp.Header, - RequestURI: res.RequestURI, - Proto: "HTTP/2.0", - ProtoMajor: 2, - ProtoMinor: 0, - TLS: tlsState, - Host: rp.Authority, - Body: body, - Trailer: res.Trailer, - }).WithContext(st.ctx) - rw := sc.newResponseWriter(st, req) - return rw, req, nil -} - -func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *responseWriter { - rws := responseWriterStatePool.Get().(*responseWriterState) - bwSave := rws.bw - *rws = responseWriterState{} // zero all the fields - rws.conn = sc - rws.bw = bwSave - rws.bw.Reset(chunkWriter{rws}) - rws.stream = st - rws.req = req - return &responseWriter{rws: rws} -} - -type unstartedHandler struct { - streamID uint32 - rw *responseWriter - req *http.Request - handler func(http.ResponseWriter, *http.Request) -} - -// scheduleHandler starts a handler goroutine, -// or schedules one to start as soon as an existing handler finishes. -func (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) error { - sc.serveG.check() - maxHandlers := sc.advMaxStreams - if sc.curHandlers < maxHandlers { - sc.curHandlers++ - go sc.runHandler(rw, req, handler) - return nil - } - if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) { - return sc.countError("too_many_early_resets", ConnectionError(ErrCodeEnhanceYourCalm)) - } - sc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{ - streamID: streamID, - rw: rw, - req: req, - handler: handler, - }) - return nil -} - -func (sc *serverConn) handlerDone() { - sc.serveG.check() - sc.curHandlers-- - i := 0 - maxHandlers := sc.advMaxStreams - for ; i < len(sc.unstartedHandlers); i++ { - u := sc.unstartedHandlers[i] - if sc.streams[u.streamID] == nil { - // This stream was reset before its goroutine had a chance to start. - continue - } - if sc.curHandlers >= maxHandlers { - break - } - sc.curHandlers++ - go sc.runHandler(u.rw, u.req, u.handler) - sc.unstartedHandlers[i] = unstartedHandler{} // don't retain references - } - sc.unstartedHandlers = sc.unstartedHandlers[i:] - if len(sc.unstartedHandlers) == 0 { - sc.unstartedHandlers = nil - } -} - -// Run on its own goroutine. -func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { - sc.srv.markNewGoroutine() - defer sc.sendServeMsg(handlerDoneMsg) - didPanic := true - defer func() { - rw.rws.stream.cancelCtx() - if req.MultipartForm != nil { - req.MultipartForm.RemoveAll() - } - if didPanic { - e := recover() - sc.writeFrameFromHandler(FrameWriteRequest{ - write: handlerPanicRST{rw.rws.stream.id}, - stream: rw.rws.stream, - }) - // Same as net/http: - if e != nil && e != http.ErrAbortHandler { - const size = 64 << 10 - buf := make([]byte, size) - buf = buf[:runtime.Stack(buf, false)] - sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) - } - return - } - rw.handlerDone() - }() - handler(rw, req) - didPanic = false -} - -func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) { - // 10.5.1 Limits on Header Block Size: - // .. "A server that receives a larger header block than it is - // willing to handle can send an HTTP 431 (Request Header Fields Too - // Large) status code" - const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+ - w.WriteHeader(statusRequestHeaderFieldsTooLarge) - io.WriteString(w, "

HTTP Error 431

Request Header Field(s) Too Large

") -} - -// called from handler goroutines. -// h may be nil. -func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error { - sc.serveG.checkNotOn() // NOT on - var errc chan error - if headerData.h != nil { - // If there's a header map (which we don't own), so we have to block on - // waiting for this frame to be written, so an http.Flush mid-handler - // writes out the correct value of keys, before a handler later potentially - // mutates it. - errc = errChanPool.Get().(chan error) - } - if err := sc.writeFrameFromHandler(FrameWriteRequest{ - write: headerData, - stream: st, - done: errc, - }); err != nil { - return err - } - if errc != nil { - select { - case err := <-errc: - errChanPool.Put(errc) - return err - case <-sc.doneServing: - return errClientDisconnected - case <-st.cw: - return errStreamClosed - } - } - return nil -} - -// called from handler goroutines. -func (sc *serverConn) write100ContinueHeaders(st *stream) { - sc.writeFrameFromHandler(FrameWriteRequest{ - write: write100ContinueHeadersFrame{st.id}, - stream: st, - }) -} - -// A bodyReadMsg tells the server loop that the http.Handler read n -// bytes of the DATA from the client on the given stream. -type bodyReadMsg struct { - st *stream - n int -} - -// called from handler goroutines. -// Notes that the handler for the given stream ID read n bytes of its body -// and schedules flow control tokens to be sent. -func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) { - sc.serveG.checkNotOn() // NOT on - if n > 0 { - select { - case sc.bodyReadCh <- bodyReadMsg{st, n}: - case <-sc.doneServing: - } - } -} - -func (sc *serverConn) noteBodyRead(st *stream, n int) { - sc.serveG.check() - sc.sendWindowUpdate(nil, n) // conn-level - if st.state != stateHalfClosedRemote && st.state != stateClosed { - // Don't send this WINDOW_UPDATE if the stream is closed - // remotely. - sc.sendWindowUpdate(st, n) - } -} - -// st may be nil for conn-level -func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) { - sc.sendWindowUpdate(st, int(n)) -} - -// st may be nil for conn-level -func (sc *serverConn) sendWindowUpdate(st *stream, n int) { - sc.serveG.check() - var streamID uint32 - var send int32 - if st == nil { - send = sc.inflow.add(n) - } else { - streamID = st.id - send = st.inflow.add(n) - } - if send == 0 { - return - } - sc.writeFrame(FrameWriteRequest{ - write: writeWindowUpdate{streamID: streamID, n: uint32(send)}, - stream: st, - }) -} - -// requestBody is the Handler's Request.Body type. -// Read and Close may be called concurrently. -type requestBody struct { - _ incomparable - stream *stream - conn *serverConn - closeOnce sync.Once // for use by Close only - sawEOF bool // for use by Read only - pipe *pipe // non-nil if we have an HTTP entity message body - needsContinue bool // need to send a 100-continue -} - -func (b *requestBody) Close() error { - b.closeOnce.Do(func() { - if b.pipe != nil { - b.pipe.BreakWithError(errClosedBody) - } - }) - return nil -} - -func (b *requestBody) Read(p []byte) (n int, err error) { - if b.needsContinue { - b.needsContinue = false - b.conn.write100ContinueHeaders(b.stream) - } - if b.pipe == nil || b.sawEOF { - return 0, io.EOF - } - n, err = b.pipe.Read(p) - if err == io.EOF { - b.sawEOF = true - } - if b.conn == nil && inTests { - return - } - b.conn.noteBodyReadFromHandler(b.stream, n, err) - return -} - -// responseWriter is the http.ResponseWriter implementation. It's -// intentionally small (1 pointer wide) to minimize garbage. The -// responseWriterState pointer inside is zeroed at the end of a -// request (in handlerDone) and calls on the responseWriter thereafter -// simply crash (caller's mistake), but the much larger responseWriterState -// and buffers are reused between multiple requests. -type responseWriter struct { - rws *responseWriterState -} - -// Optional http.ResponseWriter interfaces implemented. -var ( - _ http.CloseNotifier = (*responseWriter)(nil) - _ http.Flusher = (*responseWriter)(nil) - _ stringWriter = (*responseWriter)(nil) -) - -type responseWriterState struct { - // immutable within a request: - stream *stream - req *http.Request - conn *serverConn - - // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc - bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState} - - // mutated by http.Handler goroutine: - handlerHeader http.Header // nil until called - snapHeader http.Header // snapshot of handlerHeader at WriteHeader time - trailers []string // set in writeChunk - status int // status code passed to WriteHeader - wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet. - sentHeader bool // have we sent the header frame? - handlerDone bool // handler has finished - - sentContentLen int64 // non-zero if handler set a Content-Length header - wroteBytes int64 - - closeNotifierMu sync.Mutex // guards closeNotifierCh - closeNotifierCh chan bool // nil until first used -} - -type chunkWriter struct{ rws *responseWriterState } - -func (cw chunkWriter) Write(p []byte) (n int, err error) { - n, err = cw.rws.writeChunk(p) - if err == errStreamClosed { - // If writing failed because the stream has been closed, - // return the reason it was closed. - err = cw.rws.stream.closeErr - } - return n, err -} - -func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 } - -func (rws *responseWriterState) hasNonemptyTrailers() bool { - for _, trailer := range rws.trailers { - if _, ok := rws.handlerHeader[trailer]; ok { - return true - } - } - return false -} - -// declareTrailer is called for each Trailer header when the -// response header is written. It notes that a header will need to be -// written in the trailers at the end of the response. -func (rws *responseWriterState) declareTrailer(k string) { - k = http.CanonicalHeaderKey(k) - if !httpguts.ValidTrailerHeader(k) { - // Forbidden by RFC 7230, section 4.1.2. - rws.conn.logf("ignoring invalid trailer %q", k) - return - } - if !strSliceContains(rws.trailers, k) { - rws.trailers = append(rws.trailers, k) - } -} - -// writeChunk writes chunks from the bufio.Writer. But because -// bufio.Writer may bypass its chunking, sometimes p may be -// arbitrarily large. -// -// writeChunk is also responsible (on the first chunk) for sending the -// HEADER response. -func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { - if !rws.wroteHeader { - rws.writeHeader(200) - } - - if rws.handlerDone { - rws.promoteUndeclaredTrailers() - } - - isHeadResp := rws.req.Method == "HEAD" - if !rws.sentHeader { - rws.sentHeader = true - var ctype, clen string - if clen = rws.snapHeader.Get("Content-Length"); clen != "" { - rws.snapHeader.Del("Content-Length") - if cl, err := strconv.ParseUint(clen, 10, 63); err == nil { - rws.sentContentLen = int64(cl) - } else { - clen = "" - } - } - _, hasContentLength := rws.snapHeader["Content-Length"] - if !hasContentLength && clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) { - clen = strconv.Itoa(len(p)) - } - _, hasContentType := rws.snapHeader["Content-Type"] - // If the Content-Encoding is non-blank, we shouldn't - // sniff the body. See Issue golang.org/issue/31753. - ce := rws.snapHeader.Get("Content-Encoding") - hasCE := len(ce) > 0 - if !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { - ctype = http.DetectContentType(p) - } - var date string - if _, ok := rws.snapHeader["Date"]; !ok { - // TODO(bradfitz): be faster here, like net/http? measure. - date = rws.conn.srv.now().UTC().Format(http.TimeFormat) - } - - for _, v := range rws.snapHeader["Trailer"] { - foreachHeaderElement(v, rws.declareTrailer) - } - - // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2), - // but respect "Connection" == "close" to mean sending a GOAWAY and tearing - // down the TCP connection when idle, like we do for HTTP/1. - // TODO: remove more Connection-specific header fields here, in addition - // to "Connection". - if _, ok := rws.snapHeader["Connection"]; ok { - v := rws.snapHeader.Get("Connection") - delete(rws.snapHeader, "Connection") - if v == "close" { - rws.conn.startGracefulShutdown() - } - } - - endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp - err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ - streamID: rws.stream.id, - httpResCode: rws.status, - h: rws.snapHeader, - endStream: endStream, - contentType: ctype, - contentLength: clen, - date: date, - }) - if err != nil { - return 0, err - } - if endStream { - return 0, nil - } - } - if isHeadResp { - return len(p), nil - } - if len(p) == 0 && !rws.handlerDone { - return 0, nil - } - - // only send trailers if they have actually been defined by the - // server handler. - hasNonemptyTrailers := rws.hasNonemptyTrailers() - endStream := rws.handlerDone && !hasNonemptyTrailers - if len(p) > 0 || endStream { - // only send a 0 byte DATA frame if we're ending the stream. - if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { - return 0, err - } - } - - if rws.handlerDone && hasNonemptyTrailers { - err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ - streamID: rws.stream.id, - h: rws.handlerHeader, - trailers: rws.trailers, - endStream: true, - }) - return len(p), err - } - return len(p), nil -} - -// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys -// that, if present, signals that the map entry is actually for -// the response trailers, and not the response headers. The prefix -// is stripped after the ServeHTTP call finishes and the values are -// sent in the trailers. -// -// This mechanism is intended only for trailers that are not known -// prior to the headers being written. If the set of trailers is fixed -// or known before the header is written, the normal Go trailers mechanism -// is preferred: -// -// https://golang.org/pkg/net/http/#ResponseWriter -// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers -const TrailerPrefix = "Trailer:" - -// promoteUndeclaredTrailers permits http.Handlers to set trailers -// after the header has already been flushed. Because the Go -// ResponseWriter interface has no way to set Trailers (only the -// Header), and because we didn't want to expand the ResponseWriter -// interface, and because nobody used trailers, and because RFC 7230 -// says you SHOULD (but not must) predeclare any trailers in the -// header, the official ResponseWriter rules said trailers in Go must -// be predeclared, and then we reuse the same ResponseWriter.Header() -// map to mean both Headers and Trailers. When it's time to write the -// Trailers, we pick out the fields of Headers that were declared as -// trailers. That worked for a while, until we found the first major -// user of Trailers in the wild: gRPC (using them only over http2), -// and gRPC libraries permit setting trailers mid-stream without -// predeclaring them. So: change of plans. We still permit the old -// way, but we also permit this hack: if a Header() key begins with -// "Trailer:", the suffix of that key is a Trailer. Because ':' is an -// invalid token byte anyway, there is no ambiguity. (And it's already -// filtered out) It's mildly hacky, but not terrible. -// -// This method runs after the Handler is done and promotes any Header -// fields to be trailers. -func (rws *responseWriterState) promoteUndeclaredTrailers() { - for k, vv := range rws.handlerHeader { - if !strings.HasPrefix(k, TrailerPrefix) { - continue - } - trailerKey := strings.TrimPrefix(k, TrailerPrefix) - rws.declareTrailer(trailerKey) - rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv - } - - if len(rws.trailers) > 1 { - sorter := sorterPool.Get().(*sorter) - sorter.SortStrings(rws.trailers) - sorterPool.Put(sorter) - } -} - -func (w *responseWriter) SetReadDeadline(deadline time.Time) error { - st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { - // If we're setting a deadline in the past, reset the stream immediately - // so writes after SetWriteDeadline returns will fail. - st.onReadTimeout() - return nil - } - w.rws.conn.sendServeMsg(func(sc *serverConn) { - if st.readDeadline != nil { - if !st.readDeadline.Stop() { - // Deadline already exceeded, or stream has been closed. - return - } - } - if deadline.IsZero() { - st.readDeadline = nil - } else if st.readDeadline == nil { - st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout) - } else { - st.readDeadline.Reset(deadline.Sub(sc.srv.now())) - } - }) - return nil -} - -func (w *responseWriter) SetWriteDeadline(deadline time.Time) error { - st := w.rws.stream - if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) { - // If we're setting a deadline in the past, reset the stream immediately - // so writes after SetWriteDeadline returns will fail. - st.onWriteTimeout() - return nil - } - w.rws.conn.sendServeMsg(func(sc *serverConn) { - if st.writeDeadline != nil { - if !st.writeDeadline.Stop() { - // Deadline already exceeded, or stream has been closed. - return - } - } - if deadline.IsZero() { - st.writeDeadline = nil - } else if st.writeDeadline == nil { - st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout) - } else { - st.writeDeadline.Reset(deadline.Sub(sc.srv.now())) - } - }) - return nil -} - -func (w *responseWriter) EnableFullDuplex() error { - // We always support full duplex responses, so this is a no-op. - return nil -} - -func (w *responseWriter) Flush() { - w.FlushError() -} - -func (w *responseWriter) FlushError() error { - rws := w.rws - if rws == nil { - panic("Header called after Handler finished") - } - var err error - if rws.bw.Buffered() > 0 { - err = rws.bw.Flush() - } else { - // The bufio.Writer won't call chunkWriter.Write - // (writeChunk with zero bytes), so we have to do it - // ourselves to force the HTTP response header and/or - // final DATA frame (with END_STREAM) to be sent. - _, err = chunkWriter{rws}.Write(nil) - if err == nil { - select { - case <-rws.stream.cw: - err = rws.stream.closeErr - default: - } - } - } - return err -} - -func (w *responseWriter) CloseNotify() <-chan bool { - rws := w.rws - if rws == nil { - panic("CloseNotify called after Handler finished") - } - rws.closeNotifierMu.Lock() - ch := rws.closeNotifierCh - if ch == nil { - ch = make(chan bool, 1) - rws.closeNotifierCh = ch - cw := rws.stream.cw - go func() { - cw.Wait() // wait for close - ch <- true - }() - } - rws.closeNotifierMu.Unlock() - return ch -} - -func (w *responseWriter) Header() http.Header { - rws := w.rws - if rws == nil { - panic("Header called after Handler finished") - } - if rws.handlerHeader == nil { - rws.handlerHeader = make(http.Header) - } - return rws.handlerHeader -} - -// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode. -func checkWriteHeaderCode(code int) { - // Issue 22880: require valid WriteHeader status codes. - // For now we only enforce that it's three digits. - // In the future we might block things over 599 (600 and above aren't defined - // at http://httpwg.org/specs/rfc7231.html#status.codes). - // But for now any three digits. - // - // We used to send "HTTP/1.1 000 0" on the wire in responses but there's - // no equivalent bogus thing we can realistically send in HTTP/2, - // so we'll consistently panic instead and help people find their bugs - // early. (We can't return an error from WriteHeader even if we wanted to.) - if code < 100 || code > 999 { - panic(fmt.Sprintf("invalid WriteHeader code %v", code)) - } -} - -func (w *responseWriter) WriteHeader(code int) { - rws := w.rws - if rws == nil { - panic("WriteHeader called after Handler finished") - } - rws.writeHeader(code) -} - -func (rws *responseWriterState) writeHeader(code int) { - if rws.wroteHeader { - return - } - - checkWriteHeaderCode(code) - - // Handle informational headers - if code >= 100 && code <= 199 { - // Per RFC 8297 we must not clear the current header map - h := rws.handlerHeader - - _, cl := h["Content-Length"] - _, te := h["Transfer-Encoding"] - if cl || te { - h = h.Clone() - h.Del("Content-Length") - h.Del("Transfer-Encoding") - } - - rws.conn.writeHeaders(rws.stream, &writeResHeaders{ - streamID: rws.stream.id, - httpResCode: code, - h: h, - endStream: rws.handlerDone && !rws.hasTrailers(), - }) - - return - } - - rws.wroteHeader = true - rws.status = code - if len(rws.handlerHeader) > 0 { - rws.snapHeader = cloneHeader(rws.handlerHeader) - } -} - -func cloneHeader(h http.Header) http.Header { - h2 := make(http.Header, len(h)) - for k, vv := range h { - vv2 := make([]string, len(vv)) - copy(vv2, vv) - h2[k] = vv2 - } - return h2 -} - -// The Life Of A Write is like this: -// -// * Handler calls w.Write or w.WriteString -> -// * -> rws.bw (*bufio.Writer) -> -// * (Handler might call Flush) -// * -> chunkWriter{rws} -// * -> responseWriterState.writeChunk(p []byte) -// * -> responseWriterState.writeChunk (most of the magic; see comment there) -func (w *responseWriter) Write(p []byte) (n int, err error) { - return w.write(len(p), p, "") -} - -func (w *responseWriter) WriteString(s string) (n int, err error) { - return w.write(len(s), nil, s) -} - -// either dataB or dataS is non-zero. -func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) { - rws := w.rws - if rws == nil { - panic("Write called after Handler finished") - } - if !rws.wroteHeader { - w.WriteHeader(200) - } - if !bodyAllowedForStatus(rws.status) { - return 0, http.ErrBodyNotAllowed - } - rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set - if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen { - // TODO: send a RST_STREAM - return 0, errors.New("http2: handler wrote more than declared Content-Length") - } - - if dataB != nil { - return rws.bw.Write(dataB) - } else { - return rws.bw.WriteString(dataS) - } -} - -func (w *responseWriter) handlerDone() { - rws := w.rws - rws.handlerDone = true - w.Flush() - w.rws = nil - responseWriterStatePool.Put(rws) -} - -// Push errors. -var ( - ErrRecursivePush = errors.New("http2: recursive push not allowed") - ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS") -) - -var _ http.Pusher = (*responseWriter)(nil) - -func (w *responseWriter) Push(target string, opts *http.PushOptions) error { - st := w.rws.stream - sc := st.sc - sc.serveG.checkNotOn() - - // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream." - // http://tools.ietf.org/html/rfc7540#section-6.6 - if st.isPushed() { - return ErrRecursivePush - } - - if opts == nil { - opts = new(http.PushOptions) - } - - // Default options. - if opts.Method == "" { - opts.Method = "GET" - } - if opts.Header == nil { - opts.Header = http.Header{} - } - wantScheme := "http" - if w.rws.req.TLS != nil { - wantScheme = "https" - } - - // Validate the request. - u, err := url.Parse(target) - if err != nil { - return err - } - if u.Scheme == "" { - if !strings.HasPrefix(target, "/") { - return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target) - } - u.Scheme = wantScheme - u.Host = w.rws.req.Host - } else { - if u.Scheme != wantScheme { - return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme) - } - if u.Host == "" { - return errors.New("URL must have a host") - } - } - for k := range opts.Header { - if strings.HasPrefix(k, ":") { - return fmt.Errorf("promised request headers cannot include pseudo header %q", k) - } - // These headers are meaningful only if the request has a body, - // but PUSH_PROMISE requests cannot have a body. - // http://tools.ietf.org/html/rfc7540#section-8.2 - // Also disallow Host, since the promised URL must be absolute. - if asciiEqualFold(k, "content-length") || - asciiEqualFold(k, "content-encoding") || - asciiEqualFold(k, "trailer") || - asciiEqualFold(k, "te") || - asciiEqualFold(k, "expect") || - asciiEqualFold(k, "host") { - return fmt.Errorf("promised request headers cannot include %q", k) - } - } - if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil { - return err - } - - // The RFC effectively limits promised requests to GET and HEAD: - // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]" - // http://tools.ietf.org/html/rfc7540#section-8.2 - if opts.Method != "GET" && opts.Method != "HEAD" { - return fmt.Errorf("method %q must be GET or HEAD", opts.Method) - } - - msg := &startPushRequest{ - parent: st, - method: opts.Method, - url: u, - header: cloneHeader(opts.Header), - done: errChanPool.Get().(chan error), - } - - select { - case <-sc.doneServing: - return errClientDisconnected - case <-st.cw: - return errStreamClosed - case sc.serveMsgCh <- msg: - } - - select { - case <-sc.doneServing: - return errClientDisconnected - case <-st.cw: - return errStreamClosed - case err := <-msg.done: - errChanPool.Put(msg.done) - return err - } -} - -type startPushRequest struct { - parent *stream - method string - url *url.URL - header http.Header - done chan error -} - -func (sc *serverConn) startPush(msg *startPushRequest) { - sc.serveG.check() - - // http://tools.ietf.org/html/rfc7540#section-6.6. - // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that - // is in either the "open" or "half-closed (remote)" state. - if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote { - // responseWriter.Push checks that the stream is peer-initiated. - msg.done <- errStreamClosed - return - } - - // http://tools.ietf.org/html/rfc7540#section-6.6. - if !sc.pushEnabled { - msg.done <- http.ErrNotSupported - return - } - - // PUSH_PROMISE frames must be sent in increasing order by stream ID, so - // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE - // is written. Once the ID is allocated, we start the request handler. - allocatePromisedID := func() (uint32, error) { - sc.serveG.check() - - // Check this again, just in case. Technically, we might have received - // an updated SETTINGS by the time we got around to writing this frame. - if !sc.pushEnabled { - return 0, http.ErrNotSupported - } - // http://tools.ietf.org/html/rfc7540#section-6.5.2. - if sc.curPushedStreams+1 > sc.clientMaxStreams { - return 0, ErrPushLimitReached - } - - // http://tools.ietf.org/html/rfc7540#section-5.1.1. - // Streams initiated by the server MUST use even-numbered identifiers. - // A server that is unable to establish a new stream identifier can send a GOAWAY - // frame so that the client is forced to open a new connection for new streams. - if sc.maxPushPromiseID+2 >= 1<<31 { - sc.startGracefulShutdownInternal() - return 0, ErrPushLimitReached - } - sc.maxPushPromiseID += 2 - promisedID := sc.maxPushPromiseID - - // http://tools.ietf.org/html/rfc7540#section-8.2. - // Strictly speaking, the new stream should start in "reserved (local)", then - // transition to "half closed (remote)" after sending the initial HEADERS, but - // we start in "half closed (remote)" for simplicity. - // See further comments at the definition of stateHalfClosedRemote. - promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote) - rw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{ - Method: msg.method, - Scheme: msg.url.Scheme, - Authority: msg.url.Host, - Path: msg.url.RequestURI(), - Header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE - }) - if err != nil { - // Should not happen, since we've already validated msg.url. - panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err)) - } - - sc.curHandlers++ - go sc.runHandler(rw, req, sc.handler.ServeHTTP) - return promisedID, nil - } - - sc.writeFrame(FrameWriteRequest{ - write: &writePushPromise{ - streamID: msg.parent.id, - method: msg.method, - url: msg.url, - h: msg.header, - allocatePromisedID: allocatePromisedID, - }, - stream: msg.parent, - done: msg.done, - }) -} - -// foreachHeaderElement splits v according to the "#rule" construction -// in RFC 7230 section 7 and calls fn for each non-empty element. -func foreachHeaderElement(v string, fn func(string)) { - v = textproto.TrimString(v) - if v == "" { - return - } - if !strings.Contains(v, ",") { - fn(v) - return - } - for _, f := range strings.Split(v, ",") { - if f = textproto.TrimString(f); f != "" { - fn(f) - } - } -} - -// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2 -var connHeaders = []string{ - "Connection", - "Keep-Alive", - "Proxy-Connection", - "Transfer-Encoding", - "Upgrade", -} - -// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request, -// per RFC 7540 Section 8.1.2.2. -// The returned error is reported to users. -func checkValidHTTP2RequestHeaders(h http.Header) error { - for _, k := range connHeaders { - if _, ok := h[k]; ok { - return fmt.Errorf("request header %q is not valid in HTTP/2", k) - } - } - te := h["Te"] - if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) { - return errors.New(`request header "TE" may only be "trailers" in HTTP/2`) - } - return nil -} - -func new400Handler(err error) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - http.Error(w, err.Error(), http.StatusBadRequest) - } -} - -// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives -// disabled. See comments on h1ServerShutdownChan above for why -// the code is written this way. -func h1ServerKeepAlivesDisabled(hs *http.Server) bool { - var x interface{} = hs - type I interface { - doKeepAlives() bool - } - if hs, ok := x.(I); ok { - return !hs.doKeepAlives() - } - return false -} - -func (sc *serverConn) countError(name string, err error) error { - if sc == nil || sc.srv == nil { - return err - } - f := sc.countErrorFunc - if f == nil { - return err - } - var typ string - var code ErrCode - switch e := err.(type) { - case ConnectionError: - typ = "conn" - code = ErrCode(e) - case StreamError: - typ = "stream" - code = ErrCode(e.Code) - default: - return err - } - codeStr := errCodeName[code] - if codeStr == "" { - codeStr = strconv.Itoa(int(code)) - } - f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name)) - return err -} diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go deleted file mode 100644 index 0b1c17b..0000000 --- a/vendor/golang.org/x/net/http2/timer.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 The Go 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 http2 - -import "time" - -// A timer is a time.Timer, as an interface which can be replaced in tests. -type timer = interface { - C() <-chan time.Time - Reset(d time.Duration) bool - Stop() bool -} - -// timeTimer adapts a time.Timer to the timer interface. -type timeTimer struct { - *time.Timer -} - -func (t timeTimer) C() <-chan time.Time { return t.Timer.C } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go deleted file mode 100644 index f26356b..0000000 --- a/vendor/golang.org/x/net/http2/transport.go +++ /dev/null @@ -1,3287 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Transport code. - -package http2 - -import ( - "bufio" - "bytes" - "compress/gzip" - "context" - "crypto/rand" - "crypto/tls" - "errors" - "fmt" - "io" - "io/fs" - "log" - "math" - "math/bits" - mathrand "math/rand" - "net" - "net/http" - "net/http/httptrace" - "net/textproto" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" - "golang.org/x/net/idna" - "golang.org/x/net/internal/httpcommon" -) - -const ( - // transportDefaultConnFlow is how many connection-level flow control - // tokens we give the server at start-up, past the default 64k. - transportDefaultConnFlow = 1 << 30 - - // transportDefaultStreamFlow is how many stream-level flow - // control tokens we announce to the peer, and how many bytes - // we buffer per stream. - transportDefaultStreamFlow = 4 << 20 - - defaultUserAgent = "Go-http-client/2.0" - - // initialMaxConcurrentStreams is a connections maxConcurrentStreams until - // it's received servers initial SETTINGS frame, which corresponds with the - // spec's minimum recommended value. - initialMaxConcurrentStreams = 100 - - // defaultMaxConcurrentStreams is a connections default maxConcurrentStreams - // if the server doesn't include one in its initial SETTINGS frame. - defaultMaxConcurrentStreams = 1000 -) - -// Transport is an HTTP/2 Transport. -// -// A Transport internally caches connections to servers. It is safe -// for concurrent use by multiple goroutines. -type Transport struct { - // DialTLSContext specifies an optional dial function with context for - // creating TLS connections for requests. - // - // If DialTLSContext and DialTLS is nil, tls.Dial is used. - // - // If the returned net.Conn has a ConnectionState method like tls.Conn, - // it will be used to set http.Response.TLS. - DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) - - // DialTLS specifies an optional dial function for creating - // TLS connections for requests. - // - // If DialTLSContext and DialTLS is nil, tls.Dial is used. - // - // Deprecated: Use DialTLSContext instead, which allows the transport - // to cancel dials as soon as they are no longer needed. - // If both are set, DialTLSContext takes priority. - DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error) - - // TLSClientConfig specifies the TLS configuration to use with - // tls.Client. If nil, the default configuration is used. - TLSClientConfig *tls.Config - - // ConnPool optionally specifies an alternate connection pool to use. - // If nil, the default is used. - ConnPool ClientConnPool - - // DisableCompression, if true, prevents the Transport from - // requesting compression with an "Accept-Encoding: gzip" - // request header when the Request contains no existing - // Accept-Encoding value. If the Transport requests gzip on - // its own and gets a gzipped response, it's transparently - // decoded in the Response.Body. However, if the user - // explicitly requested gzip it is not automatically - // uncompressed. - DisableCompression bool - - // AllowHTTP, if true, permits HTTP/2 requests using the insecure, - // plain-text "http" scheme. Note that this does not enable h2c support. - AllowHTTP bool - - // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to - // send in the initial settings frame. It is how many bytes - // of response headers are allowed. Unlike the http2 spec, zero here - // means to use a default limit (currently 10MB). If you actually - // want to advertise an unlimited value to the peer, Transport - // interprets the highest possible value here (0xffffffff or 1<<32-1) - // to mean no limit. - MaxHeaderListSize uint32 - - // MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the - // initial settings frame. It is the size in bytes of the largest frame - // payload that the sender is willing to receive. If 0, no setting is - // sent, and the value is provided by the peer, which should be 16384 - // according to the spec: - // https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2. - // Values are bounded in the range 16k to 16M. - MaxReadFrameSize uint32 - - // MaxDecoderHeaderTableSize optionally specifies the http2 - // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It - // informs the remote endpoint of the maximum size of the header compression - // table used to decode header blocks, in octets. If zero, the default value - // of 4096 is used. - MaxDecoderHeaderTableSize uint32 - - // MaxEncoderHeaderTableSize optionally specifies an upper limit for the - // header compression table used for encoding request headers. Received - // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero, - // the default value of 4096 is used. - MaxEncoderHeaderTableSize uint32 - - // StrictMaxConcurrentStreams controls whether the server's - // SETTINGS_MAX_CONCURRENT_STREAMS should be respected - // globally. If false, new TCP connections are created to the - // server as needed to keep each under the per-connection - // SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the - // server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as - // a global limit and callers of RoundTrip block when needed, - // waiting for their turn. - StrictMaxConcurrentStreams bool - - // IdleConnTimeout is the maximum amount of time an idle - // (keep-alive) connection will remain idle before closing - // itself. - // Zero means no limit. - IdleConnTimeout time.Duration - - // ReadIdleTimeout is the timeout after which a health check using ping - // frame will be carried out if no frame is received on the connection. - // Note that a ping response will is considered a received frame, so if - // there is no other traffic on the connection, the health check will - // be performed every ReadIdleTimeout interval. - // If zero, no health check is performed. - ReadIdleTimeout time.Duration - - // PingTimeout is the timeout after which the connection will be closed - // if a response to Ping is not received. - // Defaults to 15s. - PingTimeout time.Duration - - // WriteByteTimeout is the timeout after which the connection will be - // closed no data can be written to it. The timeout begins when data is - // available to write, and is extended whenever any bytes are written. - WriteByteTimeout time.Duration - - // CountError, if non-nil, is called on HTTP/2 transport errors. - // It's intended to increment a metric for monitoring, such - // as an expvar or Prometheus metric. - // The errType consists of only ASCII word characters. - CountError func(errType string) - - // t1, if non-nil, is the standard library Transport using - // this transport. Its settings are used (but not its - // RoundTrip method, etc). - t1 *http.Transport - - connPoolOnce sync.Once - connPoolOrDef ClientConnPool // non-nil version of ConnPool - - *transportTestHooks -} - -// Hook points used for testing. -// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations. -// Inside tests, see the testSyncHooks function docs. - -type transportTestHooks struct { - newclientconn func(*ClientConn) - group synctestGroupInterface -} - -func (t *Transport) markNewGoroutine() { - if t != nil && t.transportTestHooks != nil { - t.transportTestHooks.group.Join() - } -} - -func (t *Transport) now() time.Time { - if t != nil && t.transportTestHooks != nil { - return t.transportTestHooks.group.Now() - } - return time.Now() -} - -func (t *Transport) timeSince(when time.Time) time.Duration { - if t != nil && t.transportTestHooks != nil { - return t.now().Sub(when) - } - return time.Since(when) -} - -// newTimer creates a new time.Timer, or a synthetic timer in tests. -func (t *Transport) newTimer(d time.Duration) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.NewTimer(d) - } - return timeTimer{time.NewTimer(d)} -} - -// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests. -func (t *Transport) afterFunc(d time.Duration, f func()) timer { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.AfterFunc(d, f) - } - return timeTimer{time.AfterFunc(d, f)} -} - -func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) { - if t.transportTestHooks != nil { - return t.transportTestHooks.group.ContextWithTimeout(ctx, d) - } - return context.WithTimeout(ctx, d) -} - -func (t *Transport) maxHeaderListSize() uint32 { - n := int64(t.MaxHeaderListSize) - if t.t1 != nil && t.t1.MaxResponseHeaderBytes != 0 { - n = t.t1.MaxResponseHeaderBytes - if n > 0 { - n = adjustHTTP1MaxHeaderSize(n) - } - } - if n <= 0 { - return 10 << 20 - } - if n >= 0xffffffff { - return 0 - } - return uint32(n) -} - -func (t *Transport) disableCompression() bool { - return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) -} - -// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. -// It returns an error if t1 has already been HTTP/2-enabled. -// -// Use ConfigureTransports instead to configure the HTTP/2 Transport. -func ConfigureTransport(t1 *http.Transport) error { - _, err := ConfigureTransports(t1) - return err -} - -// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2. -// It returns a new HTTP/2 Transport for further configuration. -// It returns an error if t1 has already been HTTP/2-enabled. -func ConfigureTransports(t1 *http.Transport) (*Transport, error) { - return configureTransports(t1) -} - -func configureTransports(t1 *http.Transport) (*Transport, error) { - connPool := new(clientConnPool) - t2 := &Transport{ - ConnPool: noDialClientConnPool{connPool}, - t1: t1, - } - connPool.t = t2 - if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil { - return nil, err - } - if t1.TLSClientConfig == nil { - t1.TLSClientConfig = new(tls.Config) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") { - t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...) - } - if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") { - t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1") - } - upgradeFn := func(scheme, authority string, c net.Conn) http.RoundTripper { - addr := authorityAddr(scheme, authority) - if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil { - go c.Close() - return erringRoundTripper{err} - } else if !used { - // Turns out we don't need this c. - // For example, two goroutines made requests to the same host - // at the same time, both kicking off TCP dials. (since protocol - // was unknown) - go c.Close() - } - if scheme == "http" { - return (*unencryptedTransport)(t2) - } - return t2 - } - if t1.TLSNextProto == nil { - t1.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper) - } - t1.TLSNextProto[NextProtoTLS] = func(authority string, c *tls.Conn) http.RoundTripper { - return upgradeFn("https", authority, c) - } - // The "unencrypted_http2" TLSNextProto key is used to pass off non-TLS HTTP/2 conns. - t1.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) http.RoundTripper { - nc, err := unencryptedNetConnFromTLSConn(c) - if err != nil { - go c.Close() - return erringRoundTripper{err} - } - return upgradeFn("http", authority, nc) - } - return t2, nil -} - -// unencryptedTransport is a Transport with a RoundTrip method that -// always permits http:// URLs. -type unencryptedTransport Transport - -func (t *unencryptedTransport) RoundTrip(req *http.Request) (*http.Response, error) { - return (*Transport)(t).RoundTripOpt(req, RoundTripOpt{allowHTTP: true}) -} - -func (t *Transport) connPool() ClientConnPool { - t.connPoolOnce.Do(t.initConnPool) - return t.connPoolOrDef -} - -func (t *Transport) initConnPool() { - if t.ConnPool != nil { - t.connPoolOrDef = t.ConnPool - } else { - t.connPoolOrDef = &clientConnPool{t: t} - } -} - -// ClientConn is the state of a single HTTP/2 client connection to an -// HTTP/2 server. -type ClientConn struct { - t *Transport - tconn net.Conn // usually *tls.Conn, except specialized impls - tlsState *tls.ConnectionState // nil only for specialized impls - atomicReused uint32 // whether conn is being reused; atomic - singleUse bool // whether being used for a single http.Request - getConnCalled bool // used by clientConnPool - - // readLoop goroutine fields: - readerDone chan struct{} // closed on error - readerErr error // set before readerDone is closed - - idleTimeout time.Duration // or 0 for never - idleTimer timer - - mu sync.Mutex // guards following - cond *sync.Cond // hold mu; broadcast on flow/closed changes - flow outflow // our conn-level flow control quota (cs.outflow is per stream) - inflow inflow // peer's conn-level flow control - doNotReuse bool // whether conn is marked to not be reused for any future requests - closing bool - closed bool - closedOnIdle bool // true if conn was closed for idleness - seenSettings bool // true if we've seen a settings frame, false otherwise - seenSettingsChan chan struct{} // closed when seenSettings is true or frame reading fails - wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back - goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received - goAwayDebug string // goAway frame's debug data, retained as a string - streams map[uint32]*clientStream // client-initiated - streamsReserved int // incr by ReserveNewRequest; decr on RoundTrip - nextStreamID uint32 - pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams - pings map[[8]byte]chan struct{} // in flight ping data to notification channel - br *bufio.Reader - lastActive time.Time - lastIdle time.Time // time last idle - // Settings from peer: (also guarded by wmu) - maxFrameSize uint32 - maxConcurrentStreams uint32 - peerMaxHeaderListSize uint64 - peerMaxHeaderTableSize uint32 - initialWindowSize uint32 - initialStreamRecvWindowSize int32 - readIdleTimeout time.Duration - pingTimeout time.Duration - extendedConnectAllowed bool - - // rstStreamPingsBlocked works around an unfortunate gRPC behavior. - // gRPC strictly limits the number of PING frames that it will receive. - // The default is two pings per two hours, but the limit resets every time - // the gRPC endpoint sends a HEADERS or DATA frame. See golang/go#70575. - // - // rstStreamPingsBlocked is set after receiving a response to a PING frame - // bundled with an RST_STREAM (see pendingResets below), and cleared after - // receiving a HEADERS or DATA frame. - rstStreamPingsBlocked bool - - // pendingResets is the number of RST_STREAM frames we have sent to the peer, - // without confirming that the peer has received them. When we send a RST_STREAM, - // we bundle it with a PING frame, unless a PING is already in flight. We count - // the reset stream against the connection's concurrency limit until we get - // a PING response. This limits the number of requests we'll try to send to a - // completely unresponsive connection. - pendingResets int - - // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. - // Write to reqHeaderMu to lock it, read from it to unlock. - // Lock reqmu BEFORE mu or wmu. - reqHeaderMu chan struct{} - - // wmu is held while writing. - // Acquire BEFORE mu when holding both, to avoid blocking mu on network writes. - // Only acquire both at the same time when changing peer settings. - wmu sync.Mutex - bw *bufio.Writer - fr *Framer - werr error // first write error that has occurred - hbuf bytes.Buffer // HPACK encoder writes into this - henc *hpack.Encoder -} - -// clientStream is the state for a single HTTP/2 stream. One of these -// is created for each Transport.RoundTrip call. -type clientStream struct { - cc *ClientConn - - // Fields of Request that we may access even after the response body is closed. - ctx context.Context - reqCancel <-chan struct{} - - trace *httptrace.ClientTrace // or nil - ID uint32 - bufPipe pipe // buffered pipe with the flow-controlled response payload - requestedGzip bool - isHead bool - - abortOnce sync.Once - abort chan struct{} // closed to signal stream should end immediately - abortErr error // set if abort is closed - - peerClosed chan struct{} // closed when the peer sends an END_STREAM flag - donec chan struct{} // closed after the stream is in the closed state - on100 chan struct{} // buffered; written to if a 100 is received - - respHeaderRecv chan struct{} // closed when headers are received - res *http.Response // set if respHeaderRecv is closed - - flow outflow // guarded by cc.mu - inflow inflow // guarded by cc.mu - bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read - readErr error // sticky read error; owned by transportResponseBody.Read - - reqBody io.ReadCloser - reqBodyContentLength int64 // -1 means unknown - reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done - - // owned by writeRequest: - sentEndStream bool // sent an END_STREAM flag to the peer - sentHeaders bool - - // owned by clientConnReadLoop: - firstByte bool // got the first response byte - pastHeaders bool // got first MetaHeadersFrame (actual headers) - pastTrailers bool // got optional second MetaHeadersFrame (trailers) - readClosed bool // peer sent an END_STREAM flag - readAborted bool // read loop reset the stream - totalHeaderSize int64 // total size of 1xx headers seen - - trailer http.Header // accumulated trailers - resTrailer *http.Header // client's Response.Trailer -} - -var got1xxFuncForTests func(int, textproto.MIMEHeader) error - -// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func, -// if any. It returns nil if not set or if the Go version is too old. -func (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error { - if fn := got1xxFuncForTests; fn != nil { - return fn - } - return traceGot1xxResponseFunc(cs.trace) -} - -func (cs *clientStream) abortStream(err error) { - cs.cc.mu.Lock() - defer cs.cc.mu.Unlock() - cs.abortStreamLocked(err) -} - -func (cs *clientStream) abortStreamLocked(err error) { - cs.abortOnce.Do(func() { - cs.abortErr = err - close(cs.abort) - }) - if cs.reqBody != nil { - cs.closeReqBodyLocked() - } - // TODO(dneil): Clean up tests where cs.cc.cond is nil. - if cs.cc.cond != nil { - // Wake up writeRequestBody if it is waiting on flow control. - cs.cc.cond.Broadcast() - } -} - -func (cs *clientStream) abortRequestBodyWrite() { - cc := cs.cc - cc.mu.Lock() - defer cc.mu.Unlock() - if cs.reqBody != nil && cs.reqBodyClosed == nil { - cs.closeReqBodyLocked() - cc.cond.Broadcast() - } -} - -func (cs *clientStream) closeReqBodyLocked() { - if cs.reqBodyClosed != nil { - return - } - cs.reqBodyClosed = make(chan struct{}) - reqBodyClosed := cs.reqBodyClosed - go func() { - cs.cc.t.markNewGoroutine() - cs.reqBody.Close() - close(reqBodyClosed) - }() -} - -type stickyErrWriter struct { - group synctestGroupInterface - conn net.Conn - timeout time.Duration - err *error -} - -func (sew stickyErrWriter) Write(p []byte) (n int, err error) { - if *sew.err != nil { - return 0, *sew.err - } - n, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p) - *sew.err = err - return n, err -} - -// noCachedConnError is the concrete type of ErrNoCachedConn, which -// needs to be detected by net/http regardless of whether it's its -// bundled version (in h2_bundle.go with a rewritten type name) or -// from a user's x/net/http2. As such, as it has a unique method name -// (IsHTTP2NoCachedConnError) that net/http sniffs for via func -// isNoCachedConnError. -type noCachedConnError struct{} - -func (noCachedConnError) IsHTTP2NoCachedConnError() {} -func (noCachedConnError) Error() string { return "http2: no cached connection was available" } - -// isNoCachedConnError reports whether err is of type noCachedConnError -// or its equivalent renamed type in net/http2's h2_bundle.go. Both types -// may coexist in the same running program. -func isNoCachedConnError(err error) bool { - _, ok := err.(interface{ IsHTTP2NoCachedConnError() }) - return ok -} - -var ErrNoCachedConn error = noCachedConnError{} - -// RoundTripOpt are options for the Transport.RoundTripOpt method. -type RoundTripOpt struct { - // OnlyCachedConn controls whether RoundTripOpt may - // create a new TCP connection. If set true and - // no cached connection is available, RoundTripOpt - // will return ErrNoCachedConn. - OnlyCachedConn bool - - allowHTTP bool // allow http:// URLs -} - -func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { - return t.RoundTripOpt(req, RoundTripOpt{}) -} - -// authorityAddr returns a given authority (a host/IP, or host:port / ip:port) -// and returns a host:port. The port 443 is added if needed. -func authorityAddr(scheme string, authority string) (addr string) { - host, port, err := net.SplitHostPort(authority) - if err != nil { // authority didn't have a port - host = authority - port = "" - } - if port == "" { // authority's port was empty - port = "443" - if scheme == "http" { - port = "80" - } - } - if a, err := idna.ToASCII(host); err == nil { - host = a - } - // IPv6 address literal, without a port: - if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") { - return host + ":" + port - } - return net.JoinHostPort(host, port) -} - -// RoundTripOpt is like RoundTrip, but takes options. -func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { - switch req.URL.Scheme { - case "https": - // Always okay. - case "http": - if !t.AllowHTTP && !opt.allowHTTP { - return nil, errors.New("http2: unencrypted HTTP/2 not enabled") - } - default: - return nil, errors.New("http2: unsupported scheme") - } - - addr := authorityAddr(req.URL.Scheme, req.URL.Host) - for retry := 0; ; retry++ { - cc, err := t.connPool().GetClientConn(req, addr) - if err != nil { - t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) - return nil, err - } - reused := !atomic.CompareAndSwapUint32(&cc.atomicReused, 0, 1) - traceGotConn(req, cc, reused) - res, err := cc.RoundTrip(req) - if err != nil && retry <= 6 { - roundTripErr := err - if req, err = shouldRetryRequest(req, err); err == nil { - // After the first retry, do exponential backoff with 10% jitter. - if retry == 0 { - t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) - continue - } - backoff := float64(uint(1) << (uint(retry) - 1)) - backoff += backoff * (0.1 * mathrand.Float64()) - d := time.Second * time.Duration(backoff) - tm := t.newTimer(d) - select { - case <-tm.C(): - t.vlogf("RoundTrip retrying after failure: %v", roundTripErr) - continue - case <-req.Context().Done(): - tm.Stop() - err = req.Context().Err() - } - } - } - if err == errClientConnNotEstablished { - // This ClientConn was created recently, - // this is the first request to use it, - // and the connection is closed and not usable. - // - // In this state, cc.idleTimer will remove the conn from the pool - // when it fires. Stop the timer and remove it here so future requests - // won't try to use this connection. - // - // If the timer has already fired and we're racing it, the redundant - // call to MarkDead is harmless. - if cc.idleTimer != nil { - cc.idleTimer.Stop() - } - t.connPool().MarkDead(cc) - } - if err != nil { - t.vlogf("RoundTrip failure: %v", err) - return nil, err - } - return res, nil - } -} - -// CloseIdleConnections closes any connections which were previously -// connected from previous requests but are now sitting idle. -// It does not interrupt any connections currently in use. -func (t *Transport) CloseIdleConnections() { - if cp, ok := t.connPool().(clientConnPoolIdleCloser); ok { - cp.closeIdleConnections() - } -} - -var ( - errClientConnClosed = errors.New("http2: client conn is closed") - errClientConnUnusable = errors.New("http2: client conn not usable") - errClientConnNotEstablished = errors.New("http2: client conn could not be established") - errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY") -) - -// shouldRetryRequest is called by RoundTrip when a request fails to get -// response headers. It is always called with a non-nil error. -// It returns either a request to retry (either the same request, or a -// modified clone), or an error if the request can't be replayed. -func shouldRetryRequest(req *http.Request, err error) (*http.Request, error) { - if !canRetryError(err) { - return nil, err - } - // If the Body is nil (or http.NoBody), it's safe to reuse - // this request and its Body. - if req.Body == nil || req.Body == http.NoBody { - return req, nil - } - - // If the request body can be reset back to its original - // state via the optional req.GetBody, do that. - if req.GetBody != nil { - body, err := req.GetBody() - if err != nil { - return nil, err - } - newReq := *req - newReq.Body = body - return &newReq, nil - } - - // The Request.Body can't reset back to the beginning, but we - // don't seem to have started to read from it yet, so reuse - // the request directly. - if err == errClientConnUnusable { - return req, nil - } - - return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err) -} - -func canRetryError(err error) bool { - if err == errClientConnUnusable || err == errClientConnGotGoAway { - return true - } - if se, ok := err.(StreamError); ok { - if se.Code == ErrCodeProtocol && se.Cause == errFromPeer { - // See golang/go#47635, golang/go#42777 - return true - } - return se.Code == ErrCodeRefusedStream - } - return false -} - -func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { - if t.transportTestHooks != nil { - return t.newClientConn(nil, singleUse) - } - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host)) - if err != nil { - return nil, err - } - return t.newClientConn(tconn, singleUse) -} - -func (t *Transport) newTLSConfig(host string) *tls.Config { - cfg := new(tls.Config) - if t.TLSClientConfig != nil { - *cfg = *t.TLSClientConfig.Clone() - } - if !strSliceContains(cfg.NextProtos, NextProtoTLS) { - cfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...) - } - if cfg.ServerName == "" { - cfg.ServerName = host - } - return cfg -} - -func (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) { - if t.DialTLSContext != nil { - return t.DialTLSContext(ctx, network, addr, tlsCfg) - } else if t.DialTLS != nil { - return t.DialTLS(network, addr, tlsCfg) - } - - tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg) - if err != nil { - return nil, err - } - state := tlsCn.ConnectionState() - if p := state.NegotiatedProtocol; p != NextProtoTLS { - return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) - } - if !state.NegotiatedProtocolIsMutual { - return nil, errors.New("http2: could not negotiate protocol mutually") - } - return tlsCn, nil -} - -// disableKeepAlives reports whether connections should be closed as -// soon as possible after handling the first request. -func (t *Transport) disableKeepAlives() bool { - return t.t1 != nil && t.t1.DisableKeepAlives -} - -func (t *Transport) expectContinueTimeout() time.Duration { - if t.t1 == nil { - return 0 - } - return t.t1.ExpectContinueTimeout -} - -func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) -} - -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { - conf := configFromTransport(t) - cc := &ClientConn{ - t: t, - tconn: c, - readerDone: make(chan struct{}), - nextStreamID: 1, - maxFrameSize: 16 << 10, // spec default - initialWindowSize: 65535, // spec default - initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream, - maxConcurrentStreams: initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings. - peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead. - streams: make(map[uint32]*clientStream), - singleUse: singleUse, - seenSettingsChan: make(chan struct{}), - wantSettingsAck: true, - readIdleTimeout: conf.SendPingTimeout, - pingTimeout: conf.PingTimeout, - pings: make(map[[8]byte]chan struct{}), - reqHeaderMu: make(chan struct{}, 1), - lastActive: t.now(), - } - var group synctestGroupInterface - if t.transportTestHooks != nil { - t.markNewGoroutine() - t.transportTestHooks.newclientconn(cc) - c = cc.tconn - group = t.group - } - if VerboseLogs { - t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) - } - - cc.cond = sync.NewCond(&cc.mu) - cc.flow.add(int32(initialWindowSize)) - - // TODO: adjust this writer size to account for frame size + - // MTU + crypto/tls record padding. - cc.bw = bufio.NewWriter(stickyErrWriter{ - group: group, - conn: c, - timeout: conf.WriteByteTimeout, - err: &cc.werr, - }) - cc.br = bufio.NewReader(c) - cc.fr = NewFramer(cc.bw, cc.br) - cc.fr.SetMaxReadFrameSize(conf.MaxReadFrameSize) - if t.CountError != nil { - cc.fr.countError = t.CountError - } - maxHeaderTableSize := conf.MaxDecoderHeaderTableSize - cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil) - cc.fr.MaxHeaderListSize = t.maxHeaderListSize() - - cc.henc = hpack.NewEncoder(&cc.hbuf) - cc.henc.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize) - cc.peerMaxHeaderTableSize = initialHeaderTableSize - - if cs, ok := c.(connectionStater); ok { - state := cs.ConnectionState() - cc.tlsState = &state - } - - initialSettings := []Setting{ - {ID: SettingEnablePush, Val: 0}, - {ID: SettingInitialWindowSize, Val: uint32(cc.initialStreamRecvWindowSize)}, - } - initialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: conf.MaxReadFrameSize}) - if max := t.maxHeaderListSize(); max != 0 { - initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) - } - if maxHeaderTableSize != initialHeaderTableSize { - initialSettings = append(initialSettings, Setting{ID: SettingHeaderTableSize, Val: maxHeaderTableSize}) - } - - cc.bw.Write(clientPreface) - cc.fr.WriteSettings(initialSettings...) - cc.fr.WriteWindowUpdate(0, uint32(conf.MaxUploadBufferPerConnection)) - cc.inflow.init(conf.MaxUploadBufferPerConnection + initialWindowSize) - cc.bw.Flush() - if cc.werr != nil { - cc.Close() - return nil, cc.werr - } - - // Start the idle timer after the connection is fully initialized. - if d := t.idleConnTimeout(); d != 0 { - cc.idleTimeout = d - cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout) - } - - go cc.readLoop() - return cc, nil -} - -func (cc *ClientConn) healthCheck() { - pingTimeout := cc.pingTimeout - // We don't need to periodically ping in the health check, because the readLoop of ClientConn will - // trigger the healthCheck again if there is no frame received. - ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout) - defer cancel() - cc.vlogf("http2: Transport sending health check") - err := cc.Ping(ctx) - if err != nil { - cc.vlogf("http2: Transport health check failure: %v", err) - cc.closeForLostPing() - } else { - cc.vlogf("http2: Transport health check success") - } -} - -// SetDoNotReuse marks cc as not reusable for future HTTP requests. -func (cc *ClientConn) SetDoNotReuse() { - cc.mu.Lock() - defer cc.mu.Unlock() - cc.doNotReuse = true -} - -func (cc *ClientConn) setGoAway(f *GoAwayFrame) { - cc.mu.Lock() - defer cc.mu.Unlock() - - old := cc.goAway - cc.goAway = f - - // Merge the previous and current GoAway error frames. - if cc.goAwayDebug == "" { - cc.goAwayDebug = string(f.DebugData()) - } - if old != nil && old.ErrCode != ErrCodeNo { - cc.goAway.ErrCode = old.ErrCode - } - last := f.LastStreamID - for streamID, cs := range cc.streams { - if streamID <= last { - // The server's GOAWAY indicates that it received this stream. - // It will either finish processing it, or close the connection - // without doing so. Either way, leave the stream alone for now. - continue - } - if streamID == 1 && cc.goAway.ErrCode != ErrCodeNo { - // Don't retry the first stream on a connection if we get a non-NO error. - // If the server is sending an error on a new connection, - // retrying the request on a new one probably isn't going to work. - cs.abortStreamLocked(fmt.Errorf("http2: Transport received GOAWAY from server ErrCode:%v", cc.goAway.ErrCode)) - } else { - // Aborting the stream with errClentConnGotGoAway indicates that - // the request should be retried on a new connection. - cs.abortStreamLocked(errClientConnGotGoAway) - } - } -} - -// CanTakeNewRequest reports whether the connection can take a new request, -// meaning it has not been closed or received or sent a GOAWAY. -// -// If the caller is going to immediately make a new request on this -// connection, use ReserveNewRequest instead. -func (cc *ClientConn) CanTakeNewRequest() bool { - cc.mu.Lock() - defer cc.mu.Unlock() - return cc.canTakeNewRequestLocked() -} - -// ReserveNewRequest is like CanTakeNewRequest but also reserves a -// concurrent stream in cc. The reservation is decremented on the -// next call to RoundTrip. -func (cc *ClientConn) ReserveNewRequest() bool { - cc.mu.Lock() - defer cc.mu.Unlock() - if st := cc.idleStateLocked(); !st.canTakeNewRequest { - return false - } - cc.streamsReserved++ - return true -} - -// ClientConnState describes the state of a ClientConn. -type ClientConnState struct { - // Closed is whether the connection is closed. - Closed bool - - // Closing is whether the connection is in the process of - // closing. It may be closing due to shutdown, being a - // single-use connection, being marked as DoNotReuse, or - // having received a GOAWAY frame. - Closing bool - - // StreamsActive is how many streams are active. - StreamsActive int - - // StreamsReserved is how many streams have been reserved via - // ClientConn.ReserveNewRequest. - StreamsReserved int - - // StreamsPending is how many requests have been sent in excess - // of the peer's advertised MaxConcurrentStreams setting and - // are waiting for other streams to complete. - StreamsPending int - - // MaxConcurrentStreams is how many concurrent streams the - // peer advertised as acceptable. Zero means no SETTINGS - // frame has been received yet. - MaxConcurrentStreams uint32 - - // LastIdle, if non-zero, is when the connection last - // transitioned to idle state. - LastIdle time.Time -} - -// State returns a snapshot of cc's state. -func (cc *ClientConn) State() ClientConnState { - cc.wmu.Lock() - maxConcurrent := cc.maxConcurrentStreams - if !cc.seenSettings { - maxConcurrent = 0 - } - cc.wmu.Unlock() - - cc.mu.Lock() - defer cc.mu.Unlock() - return ClientConnState{ - Closed: cc.closed, - Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, - StreamsActive: len(cc.streams) + cc.pendingResets, - StreamsReserved: cc.streamsReserved, - StreamsPending: cc.pendingRequests, - LastIdle: cc.lastIdle, - MaxConcurrentStreams: maxConcurrent, - } -} - -// clientConnIdleState describes the suitability of a client -// connection to initiate a new RoundTrip request. -type clientConnIdleState struct { - canTakeNewRequest bool -} - -func (cc *ClientConn) idleState() clientConnIdleState { - cc.mu.Lock() - defer cc.mu.Unlock() - return cc.idleStateLocked() -} - -func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { - if cc.singleUse && cc.nextStreamID > 1 { - return - } - var maxConcurrentOkay bool - if cc.t.StrictMaxConcurrentStreams { - // We'll tell the caller we can take a new request to - // prevent the caller from dialing a new TCP - // connection, but then we'll block later before - // writing it. - maxConcurrentOkay = true - } else { - // We can take a new request if the total of - // - active streams; - // - reservation slots for new streams; and - // - streams for which we have sent a RST_STREAM and a PING, - // but received no subsequent frame - // is less than the concurrency limit. - maxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) - } - - st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && - !cc.doNotReuse && - int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && - !cc.tooIdleLocked() - - // If this connection has never been used for a request and is closed, - // then let it take a request (which will fail). - // If the conn was closed for idleness, we're racing the idle timer; - // don't try to use the conn. (Issue #70515.) - // - // This avoids a situation where an error early in a connection's lifetime - // goes unreported. - if cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle { - st.canTakeNewRequest = true - } - - return -} - -// currentRequestCountLocked reports the number of concurrency slots currently in use, -// including active streams, reserved slots, and reset streams waiting for acknowledgement. -func (cc *ClientConn) currentRequestCountLocked() int { - return len(cc.streams) + cc.streamsReserved + cc.pendingResets -} - -func (cc *ClientConn) canTakeNewRequestLocked() bool { - st := cc.idleStateLocked() - return st.canTakeNewRequest -} - -// tooIdleLocked reports whether this connection has been been sitting idle -// for too much wall time. -func (cc *ClientConn) tooIdleLocked() bool { - // The Round(0) strips the monontonic clock reading so the - // times are compared based on their wall time. We don't want - // to reuse a connection that's been sitting idle during - // VM/laptop suspend if monotonic time was also frozen. - return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout -} - -// onIdleTimeout is called from a time.AfterFunc goroutine. It will -// only be called when we're idle, but because we're coming from a new -// goroutine, there could be a new request coming in at the same time, -// so this simply calls the synchronized closeIfIdle to shut down this -// connection. The timer could just call closeIfIdle, but this is more -// clear. -func (cc *ClientConn) onIdleTimeout() { - cc.closeIfIdle() -} - -func (cc *ClientConn) closeConn() { - t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn) - defer t.Stop() - cc.tconn.Close() -} - -// A tls.Conn.Close can hang for a long time if the peer is unresponsive. -// Try to shut it down more aggressively. -func (cc *ClientConn) forceCloseConn() { - tc, ok := cc.tconn.(*tls.Conn) - if !ok { - return - } - if nc := tc.NetConn(); nc != nil { - nc.Close() - } -} - -func (cc *ClientConn) closeIfIdle() { - cc.mu.Lock() - if len(cc.streams) > 0 || cc.streamsReserved > 0 { - cc.mu.Unlock() - return - } - cc.closed = true - cc.closedOnIdle = true - nextID := cc.nextStreamID - // TODO: do clients send GOAWAY too? maybe? Just Close: - cc.mu.Unlock() - - if VerboseLogs { - cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2) - } - cc.closeConn() -} - -func (cc *ClientConn) isDoNotReuseAndIdle() bool { - cc.mu.Lock() - defer cc.mu.Unlock() - return cc.doNotReuse && len(cc.streams) == 0 -} - -var shutdownEnterWaitStateHook = func() {} - -// Shutdown gracefully closes the client connection, waiting for running streams to complete. -func (cc *ClientConn) Shutdown(ctx context.Context) error { - if err := cc.sendGoAway(); err != nil { - return err - } - // Wait for all in-flight streams to complete or connection to close - done := make(chan struct{}) - cancelled := false // guarded by cc.mu - go func() { - cc.t.markNewGoroutine() - cc.mu.Lock() - defer cc.mu.Unlock() - for { - if len(cc.streams) == 0 || cc.closed { - cc.closed = true - close(done) - break - } - if cancelled { - break - } - cc.cond.Wait() - } - }() - shutdownEnterWaitStateHook() - select { - case <-done: - cc.closeConn() - return nil - case <-ctx.Done(): - cc.mu.Lock() - // Free the goroutine above - cancelled = true - cc.cond.Broadcast() - cc.mu.Unlock() - return ctx.Err() - } -} - -func (cc *ClientConn) sendGoAway() error { - cc.mu.Lock() - closing := cc.closing - cc.closing = true - maxStreamID := cc.nextStreamID - cc.mu.Unlock() - if closing { - // GOAWAY sent already - return nil - } - - cc.wmu.Lock() - defer cc.wmu.Unlock() - // Send a graceful shutdown frame to server - if err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil { - return err - } - if err := cc.bw.Flush(); err != nil { - return err - } - // Prevent new requests - return nil -} - -// closes the client connection immediately. In-flight requests are interrupted. -// err is sent to streams. -func (cc *ClientConn) closeForError(err error) { - cc.mu.Lock() - cc.closed = true - for _, cs := range cc.streams { - cs.abortStreamLocked(err) - } - cc.cond.Broadcast() - cc.mu.Unlock() - cc.closeConn() -} - -// Close closes the client connection immediately. -// -// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead. -func (cc *ClientConn) Close() error { - err := errors.New("http2: client connection force closed via ClientConn.Close") - cc.closeForError(err) - return nil -} - -// closes the client connection immediately. In-flight requests are interrupted. -func (cc *ClientConn) closeForLostPing() { - err := errors.New("http2: client connection lost") - if f := cc.t.CountError; f != nil { - f("conn_close_lost_ping") - } - cc.closeForError(err) -} - -// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not -// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests. -var errRequestCanceled = errors.New("net/http: request canceled") - -func (cc *ClientConn) responseHeaderTimeout() time.Duration { - if cc.t.t1 != nil { - return cc.t.t1.ResponseHeaderTimeout - } - // No way to do this (yet?) with just an http2.Transport. Probably - // no need. Request.Cancel this is the new way. We only need to support - // this for compatibility with the old http.Transport fields when - // we're doing transparent http2. - return 0 -} - -// actualContentLength returns a sanitized version of -// req.ContentLength, where 0 actually means zero (not unknown) and -1 -// means unknown. -func actualContentLength(req *http.Request) int64 { - if req.Body == nil || req.Body == http.NoBody { - return 0 - } - if req.ContentLength != 0 { - return req.ContentLength - } - return -1 -} - -func (cc *ClientConn) decrStreamReservations() { - cc.mu.Lock() - defer cc.mu.Unlock() - cc.decrStreamReservationsLocked() -} - -func (cc *ClientConn) decrStreamReservationsLocked() { - if cc.streamsReserved > 0 { - cc.streamsReserved-- - } -} - -func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { - return cc.roundTrip(req, nil) -} - -func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) { - ctx := req.Context() - cs := &clientStream{ - cc: cc, - ctx: ctx, - reqCancel: req.Cancel, - isHead: req.Method == "HEAD", - reqBody: req.Body, - reqBodyContentLength: actualContentLength(req), - trace: httptrace.ContextClientTrace(ctx), - peerClosed: make(chan struct{}), - abort: make(chan struct{}), - respHeaderRecv: make(chan struct{}), - donec: make(chan struct{}), - } - - cs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression()) - - go cs.doRequest(req, streamf) - - waitDone := func() error { - select { - case <-cs.donec: - return nil - case <-ctx.Done(): - return ctx.Err() - case <-cs.reqCancel: - return errRequestCanceled - } - } - - handleResponseHeaders := func() (*http.Response, error) { - res := cs.res - if res.StatusCode > 299 { - // On error or status code 3xx, 4xx, 5xx, etc abort any - // ongoing write, assuming that the server doesn't care - // about our request body. If the server replied with 1xx or - // 2xx, however, then assume the server DOES potentially - // want our body (e.g. full-duplex streaming: - // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully - // we can keep it. - cs.abortRequestBodyWrite() - } - res.Request = req - res.TLS = cc.tlsState - if res.Body == noBody && actualContentLength(req) == 0 { - // If there isn't a request or response body still being - // written, then wait for the stream to be closed before - // RoundTrip returns. - if err := waitDone(); err != nil { - return nil, err - } - } - return res, nil - } - - cancelRequest := func(cs *clientStream, err error) error { - cs.cc.mu.Lock() - bodyClosed := cs.reqBodyClosed - cs.cc.mu.Unlock() - // Wait for the request body to be closed. - // - // If nothing closed the body before now, abortStreamLocked - // will have started a goroutine to close it. - // - // Closing the body before returning avoids a race condition - // with net/http checking its readTrackingBody to see if the - // body was read from or closed. See golang/go#60041. - // - // The body is closed in a separate goroutine without the - // connection mutex held, but dropping the mutex before waiting - // will keep us from holding it indefinitely if the body - // close is slow for some reason. - if bodyClosed != nil { - <-bodyClosed - } - return err - } - - for { - select { - case <-cs.respHeaderRecv: - return handleResponseHeaders() - case <-cs.abort: - select { - case <-cs.respHeaderRecv: - // If both cs.respHeaderRecv and cs.abort are signaling, - // pick respHeaderRecv. The server probably wrote the - // response and immediately reset the stream. - // golang.org/issue/49645 - return handleResponseHeaders() - default: - waitDone() - return nil, cs.abortErr - } - case <-ctx.Done(): - err := ctx.Err() - cs.abortStream(err) - return nil, cancelRequest(cs, err) - case <-cs.reqCancel: - cs.abortStream(errRequestCanceled) - return nil, cancelRequest(cs, errRequestCanceled) - } - } -} - -// doRequest runs for the duration of the request lifetime. -// -// It sends the request and performs post-request cleanup (closing Request.Body, etc.). -func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) { - cs.cc.t.markNewGoroutine() - err := cs.writeRequest(req, streamf) - cs.cleanupWriteRequest(err) -} - -var errExtendedConnectNotSupported = errors.New("net/http: extended connect not supported by peer") - -// writeRequest sends a request. -// -// It returns nil after the request is written, the response read, -// and the request stream is half-closed by the peer. -// -// It returns non-nil if the request ends otherwise. -// If the returned error is StreamError, the error Code may be used in resetting the stream. -func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) { - cc := cs.cc - ctx := cs.ctx - - // wait for setting frames to be received, a server can change this value later, - // but we just wait for the first settings frame - var isExtendedConnect bool - if req.Method == "CONNECT" && req.Header.Get(":protocol") != "" { - isExtendedConnect = true - } - - // Acquire the new-request lock by writing to reqHeaderMu. - // This lock guards the critical section covering allocating a new stream ID - // (requires mu) and creating the stream (requires wmu). - if cc.reqHeaderMu == nil { - panic("RoundTrip on uninitialized ClientConn") // for tests - } - if isExtendedConnect { - select { - case <-cs.reqCancel: - return errRequestCanceled - case <-ctx.Done(): - return ctx.Err() - case <-cc.seenSettingsChan: - if !cc.extendedConnectAllowed { - return errExtendedConnectNotSupported - } - } - } - select { - case cc.reqHeaderMu <- struct{}{}: - case <-cs.reqCancel: - return errRequestCanceled - case <-ctx.Done(): - return ctx.Err() - } - - cc.mu.Lock() - if cc.idleTimer != nil { - cc.idleTimer.Stop() - } - cc.decrStreamReservationsLocked() - if err := cc.awaitOpenSlotForStreamLocked(cs); err != nil { - cc.mu.Unlock() - <-cc.reqHeaderMu - return err - } - cc.addStreamLocked(cs) // assigns stream ID - if isConnectionCloseRequest(req) { - cc.doNotReuse = true - } - cc.mu.Unlock() - - if streamf != nil { - streamf(cs) - } - - continueTimeout := cc.t.expectContinueTimeout() - if continueTimeout != 0 { - if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") { - continueTimeout = 0 - } else { - cs.on100 = make(chan struct{}, 1) - } - } - - // Past this point (where we send request headers), it is possible for - // RoundTrip to return successfully. Since the RoundTrip contract permits - // the caller to "mutate or reuse" the Request after closing the Response's Body, - // we must take care when referencing the Request from here on. - err = cs.encodeAndWriteHeaders(req) - <-cc.reqHeaderMu - if err != nil { - return err - } - - hasBody := cs.reqBodyContentLength != 0 - if !hasBody { - cs.sentEndStream = true - } else { - if continueTimeout != 0 { - traceWait100Continue(cs.trace) - timer := time.NewTimer(continueTimeout) - select { - case <-timer.C: - err = nil - case <-cs.on100: - err = nil - case <-cs.abort: - err = cs.abortErr - case <-ctx.Done(): - err = ctx.Err() - case <-cs.reqCancel: - err = errRequestCanceled - } - timer.Stop() - if err != nil { - traceWroteRequest(cs.trace, err) - return err - } - } - - if err = cs.writeRequestBody(req); err != nil { - if err != errStopReqBodyWrite { - traceWroteRequest(cs.trace, err) - return err - } - } else { - cs.sentEndStream = true - } - } - - traceWroteRequest(cs.trace, err) - - var respHeaderTimer <-chan time.Time - var respHeaderRecv chan struct{} - if d := cc.responseHeaderTimeout(); d != 0 { - timer := cc.t.newTimer(d) - defer timer.Stop() - respHeaderTimer = timer.C() - respHeaderRecv = cs.respHeaderRecv - } - // Wait until the peer half-closes its end of the stream, - // or until the request is aborted (via context, error, or otherwise), - // whichever comes first. - for { - select { - case <-cs.peerClosed: - return nil - case <-respHeaderTimer: - return errTimeout - case <-respHeaderRecv: - respHeaderRecv = nil - respHeaderTimer = nil // keep waiting for END_STREAM - case <-cs.abort: - return cs.abortErr - case <-ctx.Done(): - return ctx.Err() - case <-cs.reqCancel: - return errRequestCanceled - } - } -} - -func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error { - cc := cs.cc - ctx := cs.ctx - - cc.wmu.Lock() - defer cc.wmu.Unlock() - - // If the request was canceled while waiting for cc.mu, just quit. - select { - case <-cs.abort: - return cs.abortErr - case <-ctx.Done(): - return ctx.Err() - case <-cs.reqCancel: - return errRequestCanceled - default: - } - - // Encode headers. - // - // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is - // sent by writeRequestBody below, along with any Trailers, - // again in form HEADERS{1}, CONTINUATION{0,}) - cc.hbuf.Reset() - res, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) { - cc.writeHeader(name, value) - }) - if err != nil { - return fmt.Errorf("http2: %w", err) - } - hdrs := cc.hbuf.Bytes() - - // Write the request. - endStream := !res.HasBody && !res.HasTrailers - cs.sentHeaders = true - err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) - traceWroteHeaders(cs.trace) - return err -} - -func encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) { - return httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{ - Request: httpcommon.Request{ - Header: req.Header, - Trailer: req.Trailer, - URL: req.URL, - Host: req.Host, - Method: req.Method, - ActualContentLength: actualContentLength(req), - }, - AddGzipHeader: addGzipHeader, - PeerMaxHeaderListSize: peerMaxHeaderListSize, - DefaultUserAgent: defaultUserAgent, - }, headerf) -} - -// cleanupWriteRequest performs post-request tasks. -// -// If err (the result of writeRequest) is non-nil and the stream is not closed, -// cleanupWriteRequest will send a reset to the peer. -func (cs *clientStream) cleanupWriteRequest(err error) { - cc := cs.cc - - if cs.ID == 0 { - // We were canceled before creating the stream, so return our reservation. - cc.decrStreamReservations() - } - - // TODO: write h12Compare test showing whether - // Request.Body is closed by the Transport, - // and in multiple cases: server replies <=299 and >299 - // while still writing request body - cc.mu.Lock() - mustCloseBody := false - if cs.reqBody != nil && cs.reqBodyClosed == nil { - mustCloseBody = true - cs.reqBodyClosed = make(chan struct{}) - } - bodyClosed := cs.reqBodyClosed - closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil - cc.mu.Unlock() - if mustCloseBody { - cs.reqBody.Close() - close(bodyClosed) - } - if bodyClosed != nil { - <-bodyClosed - } - - if err != nil && cs.sentEndStream { - // If the connection is closed immediately after the response is read, - // we may be aborted before finishing up here. If the stream was closed - // cleanly on both sides, there is no error. - select { - case <-cs.peerClosed: - err = nil - default: - } - } - if err != nil { - cs.abortStream(err) // possibly redundant, but harmless - if cs.sentHeaders { - if se, ok := err.(StreamError); ok { - if se.Cause != errFromPeer { - cc.writeStreamReset(cs.ID, se.Code, false, err) - } - } else { - // We're cancelling an in-flight request. - // - // This could be due to the server becoming unresponsive. - // To avoid sending too many requests on a dead connection, - // we let the request continue to consume a concurrency slot - // until we can confirm the server is still responding. - // We do this by sending a PING frame along with the RST_STREAM - // (unless a ping is already in flight). - // - // For simplicity, we don't bother tracking the PING payload: - // We reset cc.pendingResets any time we receive a PING ACK. - // - // We skip this if the conn is going to be closed on idle, - // because it's short lived and will probably be closed before - // we get the ping response. - ping := false - if !closeOnIdle { - cc.mu.Lock() - // rstStreamPingsBlocked works around a gRPC behavior: - // see comment on the field for details. - if !cc.rstStreamPingsBlocked { - if cc.pendingResets == 0 { - ping = true - } - cc.pendingResets++ - } - cc.mu.Unlock() - } - cc.writeStreamReset(cs.ID, ErrCodeCancel, ping, err) - } - } - cs.bufPipe.CloseWithError(err) // no-op if already closed - } else { - if cs.sentHeaders && !cs.sentEndStream { - cc.writeStreamReset(cs.ID, ErrCodeNo, false, nil) - } - cs.bufPipe.CloseWithError(errRequestCanceled) - } - if cs.ID != 0 { - cc.forgetStreamID(cs.ID) - } - - cc.wmu.Lock() - werr := cc.werr - cc.wmu.Unlock() - if werr != nil { - cc.Close() - } - - close(cs.donec) -} - -// awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams. -// Must hold cc.mu. -func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { - for { - if cc.closed && cc.nextStreamID == 1 && cc.streamsReserved == 0 { - // This is the very first request sent to this connection. - // Return a fatal error which aborts the retry loop. - return errClientConnNotEstablished - } - cc.lastActive = cc.t.now() - if cc.closed || !cc.canTakeNewRequestLocked() { - return errClientConnUnusable - } - cc.lastIdle = time.Time{} - if cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) { - return nil - } - cc.pendingRequests++ - cc.cond.Wait() - cc.pendingRequests-- - select { - case <-cs.abort: - return cs.abortErr - default: - } - } -} - -// requires cc.wmu be held -func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error { - first := true // first frame written (HEADERS is first, then CONTINUATION) - for len(hdrs) > 0 && cc.werr == nil { - chunk := hdrs - if len(chunk) > maxFrameSize { - chunk = chunk[:maxFrameSize] - } - hdrs = hdrs[len(chunk):] - endHeaders := len(hdrs) == 0 - if first { - cc.fr.WriteHeaders(HeadersFrameParam{ - StreamID: streamID, - BlockFragment: chunk, - EndStream: endStream, - EndHeaders: endHeaders, - }) - first = false - } else { - cc.fr.WriteContinuation(streamID, endHeaders, chunk) - } - } - cc.bw.Flush() - return cc.werr -} - -// internal error values; they don't escape to callers -var ( - // abort request body write; don't send cancel - errStopReqBodyWrite = errors.New("http2: aborting request body write") - - // abort request body write, but send stream reset of cancel. - errStopReqBodyWriteAndCancel = errors.New("http2: canceling request") - - errReqBodyTooLong = errors.New("http2: request body larger than specified content length") -) - -// frameScratchBufferLen returns the length of a buffer to use for -// outgoing request bodies to read/write to/from. -// -// It returns max(1, min(peer's advertised max frame size, -// Request.ContentLength+1, 512KB)). -func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int { - const max = 512 << 10 - n := int64(maxFrameSize) - if n > max { - n = max - } - if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n { - // Add an extra byte past the declared content-length to - // give the caller's Request.Body io.Reader a chance to - // give us more bytes than they declared, so we can catch it - // early. - n = cl + 1 - } - if n < 1 { - return 1 - } - return int(n) // doesn't truncate; max is 512K -} - -// Seven bufPools manage different frame sizes. This helps to avoid scenarios where long-running -// streaming requests using small frame sizes occupy large buffers initially allocated for prior -// requests needing big buffers. The size ranges are as follows: -// {0 KB, 16 KB], {16 KB, 32 KB], {32 KB, 64 KB], {64 KB, 128 KB], {128 KB, 256 KB], -// {256 KB, 512 KB], {512 KB, infinity} -// In practice, the maximum scratch buffer size should not exceed 512 KB due to -// frameScratchBufferLen(maxFrameSize), thus the "infinity pool" should never be used. -// It exists mainly as a safety measure, for potential future increases in max buffer size. -var bufPools [7]sync.Pool // of *[]byte -func bufPoolIndex(size int) int { - if size <= 16384 { - return 0 - } - size -= 1 - bits := bits.Len(uint(size)) - index := bits - 14 - if index >= len(bufPools) { - return len(bufPools) - 1 - } - return index -} - -func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { - cc := cs.cc - body := cs.reqBody - sentEnd := false // whether we sent the final DATA frame w/ END_STREAM - - hasTrailers := req.Trailer != nil - remainLen := cs.reqBodyContentLength - hasContentLen := remainLen != -1 - - cc.mu.Lock() - maxFrameSize := int(cc.maxFrameSize) - cc.mu.Unlock() - - // Scratch buffer for reading into & writing from. - scratchLen := cs.frameScratchBufferLen(maxFrameSize) - var buf []byte - index := bufPoolIndex(scratchLen) - if bp, ok := bufPools[index].Get().(*[]byte); ok && len(*bp) >= scratchLen { - defer bufPools[index].Put(bp) - buf = *bp - } else { - buf = make([]byte, scratchLen) - defer bufPools[index].Put(&buf) - } - - var sawEOF bool - for !sawEOF { - n, err := body.Read(buf) - if hasContentLen { - remainLen -= int64(n) - if remainLen == 0 && err == nil { - // The request body's Content-Length was predeclared and - // we just finished reading it all, but the underlying io.Reader - // returned the final chunk with a nil error (which is one of - // the two valid things a Reader can do at EOF). Because we'd prefer - // to send the END_STREAM bit early, double-check that we're actually - // at EOF. Subsequent reads should return (0, EOF) at this point. - // If either value is different, we return an error in one of two ways below. - var scratch [1]byte - var n1 int - n1, err = body.Read(scratch[:]) - remainLen -= int64(n1) - } - if remainLen < 0 { - err = errReqBodyTooLong - return err - } - } - if err != nil { - cc.mu.Lock() - bodyClosed := cs.reqBodyClosed != nil - cc.mu.Unlock() - switch { - case bodyClosed: - return errStopReqBodyWrite - case err == io.EOF: - sawEOF = true - err = nil - default: - return err - } - } - - remain := buf[:n] - for len(remain) > 0 && err == nil { - var allowed int32 - allowed, err = cs.awaitFlowControl(len(remain)) - if err != nil { - return err - } - cc.wmu.Lock() - data := remain[:allowed] - remain = remain[allowed:] - sentEnd = sawEOF && len(remain) == 0 && !hasTrailers - err = cc.fr.WriteData(cs.ID, sentEnd, data) - if err == nil { - // TODO(bradfitz): this flush is for latency, not bandwidth. - // Most requests won't need this. Make this opt-in or - // opt-out? Use some heuristic on the body type? Nagel-like - // timers? Based on 'n'? Only last chunk of this for loop, - // unless flow control tokens are low? For now, always. - // If we change this, see comment below. - err = cc.bw.Flush() - } - cc.wmu.Unlock() - } - if err != nil { - return err - } - } - - if sentEnd { - // Already sent END_STREAM (which implies we have no - // trailers) and flushed, because currently all - // WriteData frames above get a flush. So we're done. - return nil - } - - // Since the RoundTrip contract permits the caller to "mutate or reuse" - // a request after the Response's Body is closed, verify that this hasn't - // happened before accessing the trailers. - cc.mu.Lock() - trailer := req.Trailer - err = cs.abortErr - cc.mu.Unlock() - if err != nil { - return err - } - - cc.wmu.Lock() - defer cc.wmu.Unlock() - var trls []byte - if len(trailer) > 0 { - trls, err = cc.encodeTrailers(trailer) - if err != nil { - return err - } - } - - // Two ways to send END_STREAM: either with trailers, or - // with an empty DATA frame. - if len(trls) > 0 { - err = cc.writeHeaders(cs.ID, true, maxFrameSize, trls) - } else { - err = cc.fr.WriteData(cs.ID, true, nil) - } - if ferr := cc.bw.Flush(); ferr != nil && err == nil { - err = ferr - } - return err -} - -// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow -// control tokens from the server. -// It returns either the non-zero number of tokens taken or an error -// if the stream is dead. -func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) { - cc := cs.cc - ctx := cs.ctx - cc.mu.Lock() - defer cc.mu.Unlock() - for { - if cc.closed { - return 0, errClientConnClosed - } - if cs.reqBodyClosed != nil { - return 0, errStopReqBodyWrite - } - select { - case <-cs.abort: - return 0, cs.abortErr - case <-ctx.Done(): - return 0, ctx.Err() - case <-cs.reqCancel: - return 0, errRequestCanceled - default: - } - if a := cs.flow.available(); a > 0 { - take := a - if int(take) > maxBytes { - - take = int32(maxBytes) // can't truncate int; take is int32 - } - if take > int32(cc.maxFrameSize) { - take = int32(cc.maxFrameSize) - } - cs.flow.take(take) - return take, nil - } - cc.cond.Wait() - } -} - -// requires cc.wmu be held. -func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { - cc.hbuf.Reset() - - hlSize := uint64(0) - for k, vv := range trailer { - for _, v := range vv { - hf := hpack.HeaderField{Name: k, Value: v} - hlSize += uint64(hf.Size()) - } - } - if hlSize > cc.peerMaxHeaderListSize { - return nil, errRequestHeaderListSize - } - - for k, vv := range trailer { - lowKey, ascii := httpcommon.LowerHeader(k) - if !ascii { - // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header - // field names have to be ASCII characters (just as in HTTP/1.x). - continue - } - // Transfer-Encoding, etc.. have already been filtered at the - // start of RoundTrip - for _, v := range vv { - cc.writeHeader(lowKey, v) - } - } - return cc.hbuf.Bytes(), nil -} - -func (cc *ClientConn) writeHeader(name, value string) { - if VerboseLogs { - log.Printf("http2: Transport encoding header %q = %q", name, value) - } - cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value}) -} - -type resAndError struct { - _ incomparable - res *http.Response - err error -} - -// requires cc.mu be held. -func (cc *ClientConn) addStreamLocked(cs *clientStream) { - cs.flow.add(int32(cc.initialWindowSize)) - cs.flow.setConnFlow(&cc.flow) - cs.inflow.init(cc.initialStreamRecvWindowSize) - cs.ID = cc.nextStreamID - cc.nextStreamID += 2 - cc.streams[cs.ID] = cs - if cs.ID == 0 { - panic("assigned stream ID 0") - } -} - -func (cc *ClientConn) forgetStreamID(id uint32) { - cc.mu.Lock() - slen := len(cc.streams) - delete(cc.streams, id) - if len(cc.streams) != slen-1 { - panic("forgetting unknown stream id") - } - cc.lastActive = cc.t.now() - if len(cc.streams) == 0 && cc.idleTimer != nil { - cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = cc.t.now() - } - // Wake up writeRequestBody via clientStream.awaitFlowControl and - // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() - - closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil - if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { - if VerboseLogs { - cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2) - } - cc.closed = true - defer cc.closeConn() - } - - cc.mu.Unlock() -} - -// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. -type clientConnReadLoop struct { - _ incomparable - cc *ClientConn -} - -// readLoop runs in its own goroutine and reads and dispatches frames. -func (cc *ClientConn) readLoop() { - cc.t.markNewGoroutine() - rl := &clientConnReadLoop{cc: cc} - defer rl.cleanup() - cc.readerErr = rl.run() - if ce, ok := cc.readerErr.(ConnectionError); ok { - cc.wmu.Lock() - cc.fr.WriteGoAway(0, ErrCode(ce), nil) - cc.wmu.Unlock() - } -} - -// GoAwayError is returned by the Transport when the server closes the -// TCP connection after sending a GOAWAY frame. -type GoAwayError struct { - LastStreamID uint32 - ErrCode ErrCode - DebugData string -} - -func (e GoAwayError) Error() string { - return fmt.Sprintf("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q", - e.LastStreamID, e.ErrCode, e.DebugData) -} - -func isEOFOrNetReadError(err error) bool { - if err == io.EOF { - return true - } - ne, ok := err.(*net.OpError) - return ok && ne.Op == "read" -} - -func (rl *clientConnReadLoop) cleanup() { - cc := rl.cc - defer cc.closeConn() - defer close(cc.readerDone) - - if cc.idleTimer != nil { - cc.idleTimer.Stop() - } - - // Close any response bodies if the server closes prematurely. - // TODO: also do this if we've written the headers but not - // gotten a response yet. - err := cc.readerErr - cc.mu.Lock() - if cc.goAway != nil && isEOFOrNetReadError(err) { - err = GoAwayError{ - LastStreamID: cc.goAway.LastStreamID, - ErrCode: cc.goAway.ErrCode, - DebugData: cc.goAwayDebug, - } - } else if err == io.EOF { - err = io.ErrUnexpectedEOF - } - cc.closed = true - - // If the connection has never been used, and has been open for only a short time, - // leave it in the connection pool for a little while. - // - // This avoids a situation where new connections are constantly created, - // added to the pool, fail, and are removed from the pool, without any error - // being surfaced to the user. - unusedWaitTime := 5 * time.Second - if cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout { - unusedWaitTime = cc.idleTimeout - } - idleTime := cc.t.now().Sub(cc.lastActive) - if atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle { - cc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() { - cc.t.connPool().MarkDead(cc) - }) - } else { - cc.mu.Unlock() // avoid any deadlocks in MarkDead - cc.t.connPool().MarkDead(cc) - cc.mu.Lock() - } - - for _, cs := range cc.streams { - select { - case <-cs.peerClosed: - // The server closed the stream before closing the conn, - // so no need to interrupt it. - default: - cs.abortStreamLocked(err) - } - } - cc.cond.Broadcast() - cc.mu.Unlock() - - if !cc.seenSettings { - // If we have a pending request that wants extended CONNECT, - // let it continue and fail with the connection error. - cc.extendedConnectAllowed = true - close(cc.seenSettingsChan) - } -} - -// countReadFrameError calls Transport.CountError with a string -// representing err. -func (cc *ClientConn) countReadFrameError(err error) { - f := cc.t.CountError - if f == nil || err == nil { - return - } - if ce, ok := err.(ConnectionError); ok { - errCode := ErrCode(ce) - f(fmt.Sprintf("read_frame_conn_error_%s", errCode.stringToken())) - return - } - if errors.Is(err, io.EOF) { - f("read_frame_eof") - return - } - if errors.Is(err, io.ErrUnexpectedEOF) { - f("read_frame_unexpected_eof") - return - } - if errors.Is(err, ErrFrameTooLarge) { - f("read_frame_too_large") - return - } - f("read_frame_other") -} - -func (rl *clientConnReadLoop) run() error { - cc := rl.cc - gotSettings := false - readIdleTimeout := cc.readIdleTimeout - var t timer - if readIdleTimeout != 0 { - t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck) - } - for { - f, err := cc.fr.ReadFrame() - if t != nil { - t.Reset(readIdleTimeout) - } - if err != nil { - cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) - } - if se, ok := err.(StreamError); ok { - if cs := rl.streamByID(se.StreamID, notHeaderOrDataFrame); cs != nil { - if se.Cause == nil { - se.Cause = cc.fr.errDetail - } - rl.endStreamError(cs, se) - } - continue - } else if err != nil { - cc.countReadFrameError(err) - return err - } - if VerboseLogs { - cc.vlogf("http2: Transport received %s", summarizeFrame(f)) - } - if !gotSettings { - if _, ok := f.(*SettingsFrame); !ok { - cc.logf("protocol error: received %T before a SETTINGS frame", f) - return ConnectionError(ErrCodeProtocol) - } - gotSettings = true - } - - switch f := f.(type) { - case *MetaHeadersFrame: - err = rl.processHeaders(f) - case *DataFrame: - err = rl.processData(f) - case *GoAwayFrame: - err = rl.processGoAway(f) - case *RSTStreamFrame: - err = rl.processResetStream(f) - case *SettingsFrame: - err = rl.processSettings(f) - case *PushPromiseFrame: - err = rl.processPushPromise(f) - case *WindowUpdateFrame: - err = rl.processWindowUpdate(f) - case *PingFrame: - err = rl.processPing(f) - default: - cc.logf("Transport: unhandled response frame type %T", f) - } - if err != nil { - if VerboseLogs { - cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, summarizeFrame(f), err) - } - return err - } - } -} - -func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { - cs := rl.streamByID(f.StreamID, headerOrDataFrame) - if cs == nil { - // We'd get here if we canceled a request while the - // server had its response still in flight. So if this - // was just something we canceled, ignore it. - return nil - } - if cs.readClosed { - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeProtocol, - Cause: errors.New("protocol error: headers after END_STREAM"), - }) - return nil - } - if !cs.firstByte { - if cs.trace != nil { - // TODO(bradfitz): move first response byte earlier, - // when we first read the 9 byte header, not waiting - // until all the HEADERS+CONTINUATION frames have been - // merged. This works for now. - traceFirstResponseByte(cs.trace) - } - cs.firstByte = true - } - if !cs.pastHeaders { - cs.pastHeaders = true - } else { - return rl.processTrailers(cs, f) - } - - res, err := rl.handleResponse(cs, f) - if err != nil { - if _, ok := err.(ConnectionError); ok { - return err - } - // Any other error type is a stream error. - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeProtocol, - Cause: err, - }) - return nil // return nil from process* funcs to keep conn alive - } - if res == nil { - // (nil, nil) special case. See handleResponse docs. - return nil - } - cs.resTrailer = &res.Trailer - cs.res = res - close(cs.respHeaderRecv) - if f.StreamEnded() { - rl.endStream(cs) - } - return nil -} - -// may return error types nil, or ConnectionError. Any other error value -// is a StreamError of type ErrCodeProtocol. The returned error in that case -// is the detail. -// -// As a special case, handleResponse may return (nil, nil) to skip the -// frame (currently only used for 1xx responses). -func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) { - if f.Truncated { - return nil, errResponseHeaderListSize - } - - status := f.PseudoValue("status") - if status == "" { - return nil, errors.New("malformed response from server: missing status pseudo header") - } - statusCode, err := strconv.Atoi(status) - if err != nil { - return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header") - } - - regularFields := f.RegularFields() - strs := make([]string, len(regularFields)) - header := make(http.Header, len(regularFields)) - res := &http.Response{ - Proto: "HTTP/2.0", - ProtoMajor: 2, - Header: header, - StatusCode: statusCode, - Status: status + " " + http.StatusText(statusCode), - } - for _, hf := range regularFields { - key := httpcommon.CanonicalHeader(hf.Name) - if key == "Trailer" { - t := res.Trailer - if t == nil { - t = make(http.Header) - res.Trailer = t - } - foreachHeaderElement(hf.Value, func(v string) { - t[httpcommon.CanonicalHeader(v)] = nil - }) - } else { - vv := header[key] - if vv == nil && len(strs) > 0 { - // More than likely this will be a single-element key. - // Most headers aren't multi-valued. - // Set the capacity on strs[0] to 1, so any future append - // won't extend the slice into the other strings. - vv, strs = strs[:1:1], strs[1:] - vv[0] = hf.Value - header[key] = vv - } else { - header[key] = append(vv, hf.Value) - } - } - } - - if statusCode >= 100 && statusCode <= 199 { - if f.StreamEnded() { - return nil, errors.New("1xx informational response with END_STREAM flag") - } - if fn := cs.get1xxTraceFunc(); fn != nil { - // If the 1xx response is being delivered to the user, - // then they're responsible for limiting the number - // of responses. - if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil { - return nil, err - } - } else { - // If the user didn't examine the 1xx response, then we - // limit the size of all 1xx headers. - // - // This differs a bit from the HTTP/1 implementation, which - // limits the size of all 1xx headers plus the final response. - // Use the larger limit of MaxHeaderListSize and - // net/http.Transport.MaxResponseHeaderBytes. - limit := int64(cs.cc.t.maxHeaderListSize()) - if t1 := cs.cc.t.t1; t1 != nil && t1.MaxResponseHeaderBytes > limit { - limit = t1.MaxResponseHeaderBytes - } - for _, h := range f.Fields { - cs.totalHeaderSize += int64(h.Size()) - } - if cs.totalHeaderSize > limit { - if VerboseLogs { - log.Printf("http2: 1xx informational responses too large") - } - return nil, errors.New("header list too large") - } - } - if statusCode == 100 { - traceGot100Continue(cs.trace) - select { - case cs.on100 <- struct{}{}: - default: - } - } - cs.pastHeaders = false // do it all again - return nil, nil - } - - res.ContentLength = -1 - if clens := res.Header["Content-Length"]; len(clens) == 1 { - if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil { - res.ContentLength = int64(cl) - } else { - // TODO: care? unlike http/1, it won't mess up our framing, so it's - // more safe smuggling-wise to ignore. - } - } else if len(clens) > 1 { - // TODO: care? unlike http/1, it won't mess up our framing, so it's - // more safe smuggling-wise to ignore. - } else if f.StreamEnded() && !cs.isHead { - res.ContentLength = 0 - } - - if cs.isHead { - res.Body = noBody - return res, nil - } - - if f.StreamEnded() { - if res.ContentLength > 0 { - res.Body = missingBody{} - } else { - res.Body = noBody - } - return res, nil - } - - cs.bufPipe.setBuffer(&dataBuffer{expected: res.ContentLength}) - cs.bytesRemain = res.ContentLength - res.Body = transportResponseBody{cs} - - if cs.requestedGzip && asciiEqualFold(res.Header.Get("Content-Encoding"), "gzip") { - res.Header.Del("Content-Encoding") - res.Header.Del("Content-Length") - res.ContentLength = -1 - res.Body = &gzipReader{body: res.Body} - res.Uncompressed = true - } - return res, nil -} - -func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error { - if cs.pastTrailers { - // Too many HEADERS frames for this stream. - return ConnectionError(ErrCodeProtocol) - } - cs.pastTrailers = true - if !f.StreamEnded() { - // We expect that any headers for trailers also - // has END_STREAM. - return ConnectionError(ErrCodeProtocol) - } - if len(f.PseudoFields()) > 0 { - // No pseudo header fields are defined for trailers. - // TODO: ConnectionError might be overly harsh? Check. - return ConnectionError(ErrCodeProtocol) - } - - trailer := make(http.Header) - for _, hf := range f.RegularFields() { - key := httpcommon.CanonicalHeader(hf.Name) - trailer[key] = append(trailer[key], hf.Value) - } - cs.trailer = trailer - - rl.endStream(cs) - return nil -} - -// transportResponseBody is the concrete type of Transport.RoundTrip's -// Response.Body. It is an io.ReadCloser. -type transportResponseBody struct { - cs *clientStream -} - -func (b transportResponseBody) Read(p []byte) (n int, err error) { - cs := b.cs - cc := cs.cc - - if cs.readErr != nil { - return 0, cs.readErr - } - n, err = b.cs.bufPipe.Read(p) - if cs.bytesRemain != -1 { - if int64(n) > cs.bytesRemain { - n = int(cs.bytesRemain) - if err == nil { - err = errors.New("net/http: server replied with more than declared Content-Length; truncated") - cs.abortStream(err) - } - cs.readErr = err - return int(cs.bytesRemain), err - } - cs.bytesRemain -= int64(n) - if err == io.EOF && cs.bytesRemain > 0 { - err = io.ErrUnexpectedEOF - cs.readErr = err - return n, err - } - } - if n == 0 { - // No flow control tokens to send back. - return - } - - cc.mu.Lock() - connAdd := cc.inflow.add(n) - var streamAdd int32 - if err == nil { // No need to refresh if the stream is over or failed. - streamAdd = cs.inflow.add(n) - } - cc.mu.Unlock() - - if connAdd != 0 || streamAdd != 0 { - cc.wmu.Lock() - defer cc.wmu.Unlock() - if connAdd != 0 { - cc.fr.WriteWindowUpdate(0, mustUint31(connAdd)) - } - if streamAdd != 0 { - cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd)) - } - cc.bw.Flush() - } - return -} - -var errClosedResponseBody = errors.New("http2: response body closed") - -func (b transportResponseBody) Close() error { - cs := b.cs - cc := cs.cc - - cs.bufPipe.BreakWithError(errClosedResponseBody) - cs.abortStream(errClosedResponseBody) - - unread := cs.bufPipe.Len() - if unread > 0 { - cc.mu.Lock() - // Return connection-level flow control. - connAdd := cc.inflow.add(unread) - cc.mu.Unlock() - - // TODO(dneil): Acquiring this mutex can block indefinitely. - // Move flow control return to a goroutine? - cc.wmu.Lock() - // Return connection-level flow control. - if connAdd > 0 { - cc.fr.WriteWindowUpdate(0, uint32(connAdd)) - } - cc.bw.Flush() - cc.wmu.Unlock() - } - - select { - case <-cs.donec: - case <-cs.ctx.Done(): - // See golang/go#49366: The net/http package can cancel the - // request context after the response body is fully read. - // Don't treat this as an error. - return nil - case <-cs.reqCancel: - return errRequestCanceled - } - return nil -} - -func (rl *clientConnReadLoop) processData(f *DataFrame) error { - cc := rl.cc - cs := rl.streamByID(f.StreamID, headerOrDataFrame) - data := f.Data() - if cs == nil { - cc.mu.Lock() - neverSent := cc.nextStreamID - cc.mu.Unlock() - if f.StreamID >= neverSent { - // We never asked for this. - cc.logf("http2: Transport received unsolicited DATA frame; closing connection") - return ConnectionError(ErrCodeProtocol) - } - // We probably did ask for this, but canceled. Just ignore it. - // TODO: be stricter here? only silently ignore things which - // we canceled, but not things which were closed normally - // by the peer? Tough without accumulating too much state. - - // But at least return their flow control: - if f.Length > 0 { - cc.mu.Lock() - ok := cc.inflow.take(f.Length) - connAdd := cc.inflow.add(int(f.Length)) - cc.mu.Unlock() - if !ok { - return ConnectionError(ErrCodeFlowControl) - } - if connAdd > 0 { - cc.wmu.Lock() - cc.fr.WriteWindowUpdate(0, uint32(connAdd)) - cc.bw.Flush() - cc.wmu.Unlock() - } - } - return nil - } - if cs.readClosed { - cc.logf("protocol error: received DATA after END_STREAM") - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeProtocol, - }) - return nil - } - if !cs.pastHeaders { - cc.logf("protocol error: received DATA before a HEADERS frame") - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeProtocol, - }) - return nil - } - if f.Length > 0 { - if cs.isHead && len(data) > 0 { - cc.logf("protocol error: received DATA on a HEAD request") - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeProtocol, - }) - return nil - } - // Check connection-level flow control. - cc.mu.Lock() - if !takeInflows(&cc.inflow, &cs.inflow, f.Length) { - cc.mu.Unlock() - return ConnectionError(ErrCodeFlowControl) - } - // Return any padded flow control now, since we won't - // refund it later on body reads. - var refund int - if pad := int(f.Length) - len(data); pad > 0 { - refund += pad - } - - didReset := false - var err error - if len(data) > 0 { - if _, err = cs.bufPipe.Write(data); err != nil { - // Return len(data) now if the stream is already closed, - // since data will never be read. - didReset = true - refund += len(data) - } - } - - sendConn := cc.inflow.add(refund) - var sendStream int32 - if !didReset { - sendStream = cs.inflow.add(refund) - } - cc.mu.Unlock() - - if sendConn > 0 || sendStream > 0 { - cc.wmu.Lock() - if sendConn > 0 { - cc.fr.WriteWindowUpdate(0, uint32(sendConn)) - } - if sendStream > 0 { - cc.fr.WriteWindowUpdate(cs.ID, uint32(sendStream)) - } - cc.bw.Flush() - cc.wmu.Unlock() - } - - if err != nil { - rl.endStreamError(cs, err) - return nil - } - } - - if f.StreamEnded() { - rl.endStream(cs) - } - return nil -} - -func (rl *clientConnReadLoop) endStream(cs *clientStream) { - // TODO: check that any declared content-length matches, like - // server.go's (*stream).endStream method. - if !cs.readClosed { - cs.readClosed = true - // Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a - // race condition: The caller can read io.EOF from Response.Body - // and close the body before we close cs.peerClosed, causing - // cleanupWriteRequest to send a RST_STREAM. - rl.cc.mu.Lock() - defer rl.cc.mu.Unlock() - cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers) - close(cs.peerClosed) - } -} - -func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { - cs.readAborted = true - cs.abortStream(err) -} - -// Constants passed to streamByID for documentation purposes. -const ( - headerOrDataFrame = true - notHeaderOrDataFrame = false -) - -// streamByID returns the stream with the given id, or nil if no stream has that id. -// If headerOrData is true, it clears rst.StreamPingsBlocked. -func (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientStream { - rl.cc.mu.Lock() - defer rl.cc.mu.Unlock() - if headerOrData { - // Work around an unfortunate gRPC behavior. - // See comment on ClientConn.rstStreamPingsBlocked for details. - rl.cc.rstStreamPingsBlocked = false - } - cs := rl.cc.streams[id] - if cs != nil && !cs.readAborted { - return cs - } - return nil -} - -func (cs *clientStream) copyTrailers() { - for k, vv := range cs.trailer { - t := cs.resTrailer - if *t == nil { - *t = make(http.Header) - } - (*t)[k] = vv - } -} - -func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error { - cc := rl.cc - cc.t.connPool().MarkDead(cc) - if f.ErrCode != 0 { - // TODO: deal with GOAWAY more. particularly the error code - cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode) - if fn := cc.t.CountError; fn != nil { - fn("recv_goaway_" + f.ErrCode.stringToken()) - } - } - cc.setGoAway(f) - return nil -} - -func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { - cc := rl.cc - // Locking both mu and wmu here allows frame encoding to read settings with only wmu held. - // Acquiring wmu when f.IsAck() is unnecessary, but convenient and mostly harmless. - cc.wmu.Lock() - defer cc.wmu.Unlock() - - if err := rl.processSettingsNoWrite(f); err != nil { - return err - } - if !f.IsAck() { - cc.fr.WriteSettingsAck() - cc.bw.Flush() - } - return nil -} - -func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { - cc := rl.cc - cc.mu.Lock() - defer cc.mu.Unlock() - - if f.IsAck() { - if cc.wantSettingsAck { - cc.wantSettingsAck = false - return nil - } - return ConnectionError(ErrCodeProtocol) - } - - var seenMaxConcurrentStreams bool - err := f.ForeachSetting(func(s Setting) error { - switch s.ID { - case SettingMaxFrameSize: - cc.maxFrameSize = s.Val - case SettingMaxConcurrentStreams: - cc.maxConcurrentStreams = s.Val - seenMaxConcurrentStreams = true - case SettingMaxHeaderListSize: - cc.peerMaxHeaderListSize = uint64(s.Val) - case SettingInitialWindowSize: - // Values above the maximum flow-control - // window size of 2^31-1 MUST be treated as a - // connection error (Section 5.4.1) of type - // FLOW_CONTROL_ERROR. - if s.Val > math.MaxInt32 { - return ConnectionError(ErrCodeFlowControl) - } - - // Adjust flow control of currently-open - // frames by the difference of the old initial - // window size and this one. - delta := int32(s.Val) - int32(cc.initialWindowSize) - for _, cs := range cc.streams { - cs.flow.add(delta) - } - cc.cond.Broadcast() - - cc.initialWindowSize = s.Val - case SettingHeaderTableSize: - cc.henc.SetMaxDynamicTableSize(s.Val) - cc.peerMaxHeaderTableSize = s.Val - case SettingEnableConnectProtocol: - if err := s.Valid(); err != nil { - return err - } - // If the peer wants to send us SETTINGS_ENABLE_CONNECT_PROTOCOL, - // we require that it do so in the first SETTINGS frame. - // - // When we attempt to use extended CONNECT, we wait for the first - // SETTINGS frame to see if the server supports it. If we let the - // server enable the feature with a later SETTINGS frame, then - // users will see inconsistent results depending on whether we've - // seen that frame or not. - if !cc.seenSettings { - cc.extendedConnectAllowed = s.Val == 1 - } - default: - cc.vlogf("Unhandled Setting: %v", s) - } - return nil - }) - if err != nil { - return err - } - - if !cc.seenSettings { - if !seenMaxConcurrentStreams { - // This was the servers initial SETTINGS frame and it - // didn't contain a MAX_CONCURRENT_STREAMS field so - // increase the number of concurrent streams this - // connection can establish to our default. - cc.maxConcurrentStreams = defaultMaxConcurrentStreams - } - close(cc.seenSettingsChan) - cc.seenSettings = true - } - - return nil -} - -func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { - cc := rl.cc - cs := rl.streamByID(f.StreamID, notHeaderOrDataFrame) - if f.StreamID != 0 && cs == nil { - return nil - } - - cc.mu.Lock() - defer cc.mu.Unlock() - - fl := &cc.flow - if cs != nil { - fl = &cs.flow - } - if !fl.add(int32(f.Increment)) { - // For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR - if cs != nil { - rl.endStreamError(cs, StreamError{ - StreamID: f.StreamID, - Code: ErrCodeFlowControl, - }) - return nil - } - - return ConnectionError(ErrCodeFlowControl) - } - cc.cond.Broadcast() - return nil -} - -func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { - cs := rl.streamByID(f.StreamID, notHeaderOrDataFrame) - if cs == nil { - // TODO: return error if server tries to RST_STREAM an idle stream - return nil - } - serr := streamError(cs.ID, f.ErrCode) - serr.Cause = errFromPeer - if f.ErrCode == ErrCodeProtocol { - rl.cc.SetDoNotReuse() - } - if fn := cs.cc.t.CountError; fn != nil { - fn("recv_rststream_" + f.ErrCode.stringToken()) - } - cs.abortStream(serr) - - cs.bufPipe.CloseWithError(serr) - return nil -} - -// Ping sends a PING frame to the server and waits for the ack. -func (cc *ClientConn) Ping(ctx context.Context) error { - c := make(chan struct{}) - // Generate a random payload - var p [8]byte - for { - if _, err := rand.Read(p[:]); err != nil { - return err - } - cc.mu.Lock() - // check for dup before insert - if _, found := cc.pings[p]; !found { - cc.pings[p] = c - cc.mu.Unlock() - break - } - cc.mu.Unlock() - } - var pingError error - errc := make(chan struct{}) - go func() { - cc.t.markNewGoroutine() - cc.wmu.Lock() - defer cc.wmu.Unlock() - if pingError = cc.fr.WritePing(false, p); pingError != nil { - close(errc) - return - } - if pingError = cc.bw.Flush(); pingError != nil { - close(errc) - return - } - }() - select { - case <-c: - return nil - case <-errc: - return pingError - case <-ctx.Done(): - return ctx.Err() - case <-cc.readerDone: - // connection closed - return cc.readerErr - } -} - -func (rl *clientConnReadLoop) processPing(f *PingFrame) error { - if f.IsAck() { - cc := rl.cc - cc.mu.Lock() - defer cc.mu.Unlock() - // If ack, notify listener if any - if c, ok := cc.pings[f.Data]; ok { - close(c) - delete(cc.pings, f.Data) - } - if cc.pendingResets > 0 { - // See clientStream.cleanupWriteRequest. - cc.pendingResets = 0 - cc.rstStreamPingsBlocked = true - cc.cond.Broadcast() - } - return nil - } - cc := rl.cc - cc.wmu.Lock() - defer cc.wmu.Unlock() - if err := cc.fr.WritePing(true, f.Data); err != nil { - return err - } - return cc.bw.Flush() -} - -func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { - // We told the peer we don't want them. - // Spec says: - // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH - // setting of the peer endpoint is set to 0. An endpoint that - // has set this setting and has received acknowledgement MUST - // treat the receipt of a PUSH_PROMISE frame as a connection - // error (Section 5.4.1) of type PROTOCOL_ERROR." - return ConnectionError(ErrCodeProtocol) -} - -// writeStreamReset sends a RST_STREAM frame. -// When ping is true, it also sends a PING frame with a random payload. -func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, err error) { - // TODO: map err to more interesting error codes, once the - // HTTP community comes up with some. But currently for - // RST_STREAM there's no equivalent to GOAWAY frame's debug - // data, and the error codes are all pretty vague ("cancel"). - cc.wmu.Lock() - cc.fr.WriteRSTStream(streamID, code) - if ping { - var payload [8]byte - rand.Read(payload[:]) - cc.fr.WritePing(false, payload) - } - cc.bw.Flush() - cc.wmu.Unlock() -} - -var ( - errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") - errRequestHeaderListSize = httpcommon.ErrRequestHeaderListSize -) - -func (cc *ClientConn) logf(format string, args ...interface{}) { - cc.t.logf(format, args...) -} - -func (cc *ClientConn) vlogf(format string, args ...interface{}) { - cc.t.vlogf(format, args...) -} - -func (t *Transport) vlogf(format string, args ...interface{}) { - if VerboseLogs { - t.logf(format, args...) - } -} - -func (t *Transport) logf(format string, args ...interface{}) { - log.Printf(format, args...) -} - -var noBody io.ReadCloser = noBodyReader{} - -type noBodyReader struct{} - -func (noBodyReader) Close() error { return nil } -func (noBodyReader) Read([]byte) (int, error) { return 0, io.EOF } - -type missingBody struct{} - -func (missingBody) Close() error { return nil } -func (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF } - -func strSliceContains(ss []string, s string) bool { - for _, v := range ss { - if v == s { - return true - } - } - return false -} - -type erringRoundTripper struct{ err error } - -func (rt erringRoundTripper) RoundTripErr() error { return rt.err } -func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } - -// gzipReader wraps a response body so it can lazily -// call gzip.NewReader on the first call to Read -type gzipReader struct { - _ incomparable - body io.ReadCloser // underlying Response.Body - zr *gzip.Reader // lazily-initialized gzip reader - zerr error // sticky error -} - -func (gz *gzipReader) Read(p []byte) (n int, err error) { - if gz.zerr != nil { - return 0, gz.zerr - } - if gz.zr == nil { - gz.zr, err = gzip.NewReader(gz.body) - if err != nil { - gz.zerr = err - return 0, err - } - } - return gz.zr.Read(p) -} - -func (gz *gzipReader) Close() error { - if err := gz.body.Close(); err != nil { - return err - } - gz.zerr = fs.ErrClosed - return nil -} - -type errorReader struct{ err error } - -func (r errorReader) Read(p []byte) (int, error) { return 0, r.err } - -// isConnectionCloseRequest reports whether req should use its own -// connection for a single request and then close the connection. -func isConnectionCloseRequest(req *http.Request) bool { - return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close") -} - -// registerHTTPSProtocol calls Transport.RegisterProtocol but -// converting panics into errors. -func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("%v", e) - } - }() - t.RegisterProtocol("https", rt) - return nil -} - -// noDialH2RoundTripper is a RoundTripper which only tries to complete the request -// if there's already has a cached connection to the host. -// (The field is exported so it can be accessed via reflect from net/http; tested -// by TestNoDialH2RoundTripperType) -type noDialH2RoundTripper struct{ *Transport } - -func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - res, err := rt.Transport.RoundTrip(req) - if isNoCachedConnError(err) { - return nil, http.ErrSkipAltProtocol - } - return res, err -} - -func (t *Transport) idleConnTimeout() time.Duration { - // to keep things backwards compatible, we use non-zero values of - // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying - // http1 transport, followed by 0 - if t.IdleConnTimeout != 0 { - return t.IdleConnTimeout - } - - if t.t1 != nil { - return t.t1.IdleConnTimeout - } - - return 0 -} - -func traceGetConn(req *http.Request, hostPort string) { - trace := httptrace.ContextClientTrace(req.Context()) - if trace == nil || trace.GetConn == nil { - return - } - trace.GetConn(hostPort) -} - -func traceGotConn(req *http.Request, cc *ClientConn, reused bool) { - trace := httptrace.ContextClientTrace(req.Context()) - if trace == nil || trace.GotConn == nil { - return - } - ci := httptrace.GotConnInfo{Conn: cc.tconn} - ci.Reused = reused - cc.mu.Lock() - ci.WasIdle = len(cc.streams) == 0 && reused - if ci.WasIdle && !cc.lastActive.IsZero() { - ci.IdleTime = cc.t.timeSince(cc.lastActive) - } - cc.mu.Unlock() - - trace.GotConn(ci) -} - -func traceWroteHeaders(trace *httptrace.ClientTrace) { - if trace != nil && trace.WroteHeaders != nil { - trace.WroteHeaders() - } -} - -func traceGot100Continue(trace *httptrace.ClientTrace) { - if trace != nil && trace.Got100Continue != nil { - trace.Got100Continue() - } -} - -func traceWait100Continue(trace *httptrace.ClientTrace) { - if trace != nil && trace.Wait100Continue != nil { - trace.Wait100Continue() - } -} - -func traceWroteRequest(trace *httptrace.ClientTrace, err error) { - if trace != nil && trace.WroteRequest != nil { - trace.WroteRequest(httptrace.WroteRequestInfo{Err: err}) - } -} - -func traceFirstResponseByte(trace *httptrace.ClientTrace) { - if trace != nil && trace.GotFirstResponseByte != nil { - trace.GotFirstResponseByte() - } -} - -func traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error { - if trace != nil { - return trace.Got1xxResponse - } - return nil -} - -// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS -// connection. -func (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) { - dialer := &tls.Dialer{ - Config: cfg, - } - cn, err := dialer.DialContext(ctx, network, addr) - if err != nil { - return nil, err - } - tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed - return tlsCn, nil -} diff --git a/vendor/golang.org/x/net/http2/unencrypted.go b/vendor/golang.org/x/net/http2/unencrypted.go deleted file mode 100644 index b2de211..0000000 --- a/vendor/golang.org/x/net/http2/unencrypted.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2024 The Go 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 http2 - -import ( - "crypto/tls" - "errors" - "net" -) - -const nextProtoUnencryptedHTTP2 = "unencrypted_http2" - -// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn. -// -// TLSNextProto functions accept a *tls.Conn. -// -// When passing an unencrypted HTTP/2 connection to a TLSNextProto function, -// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection. -// To be extra careful about mistakes (accidentally dropping TLS encryption in a place -// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method -// that returns the actual connection we want to use. -func unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) { - conner, ok := tc.NetConn().(interface { - UnencryptedNetConn() net.Conn - }) - if !ok { - return nil, errors.New("http2: TLS conn unexpectedly found in unencrypted handoff") - } - return conner.UnencryptedNetConn(), nil -} diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go deleted file mode 100644 index fdb35b9..0000000 --- a/vendor/golang.org/x/net/http2/write.go +++ /dev/null @@ -1,381 +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 http2 - -import ( - "bytes" - "fmt" - "log" - "net/http" - "net/url" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" - "golang.org/x/net/internal/httpcommon" -) - -// writeFramer is implemented by any type that is used to write frames. -type writeFramer interface { - writeFrame(writeContext) error - - // staysWithinBuffer reports whether this writer promises that - // it will only write less than or equal to size bytes, and it - // won't Flush the write context. - staysWithinBuffer(size int) bool -} - -// writeContext is the interface needed by the various frame writer -// types below. All the writeFrame methods below are scheduled via the -// frame writing scheduler (see writeScheduler in writesched.go). -// -// This interface is implemented by *serverConn. -// -// TODO: decide whether to a) use this in the client code (which didn't -// end up using this yet, because it has a simpler design, not -// currently implementing priorities), or b) delete this and -// make the server code a bit more concrete. -type writeContext interface { - Framer() *Framer - Flush() error - CloseConn() error - // HeaderEncoder returns an HPACK encoder that writes to the - // returned buffer. - HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) -} - -// writeEndsStream reports whether w writes a frame that will transition -// the stream to a half-closed local state. This returns false for RST_STREAM, -// which closes the entire stream (not just the local half). -func writeEndsStream(w writeFramer) bool { - switch v := w.(type) { - case *writeData: - return v.endStream - case *writeResHeaders: - return v.endStream - case nil: - // This can only happen if the caller reuses w after it's - // been intentionally nil'ed out to prevent use. Keep this - // here to catch future refactoring breaking it. - panic("writeEndsStream called on nil writeFramer") - } - return false -} - -type flushFrameWriter struct{} - -func (flushFrameWriter) writeFrame(ctx writeContext) error { - return ctx.Flush() -} - -func (flushFrameWriter) staysWithinBuffer(max int) bool { return false } - -type writeSettings []Setting - -func (s writeSettings) staysWithinBuffer(max int) bool { - const settingSize = 6 // uint16 + uint32 - return frameHeaderLen+settingSize*len(s) <= max - -} - -func (s writeSettings) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteSettings([]Setting(s)...) -} - -type writeGoAway struct { - maxStreamID uint32 - code ErrCode -} - -func (p *writeGoAway) writeFrame(ctx writeContext) error { - err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil) - ctx.Flush() // ignore error: we're hanging up on them anyway - return err -} - -func (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes - -type writeData struct { - streamID uint32 - p []byte - endStream bool -} - -func (w *writeData) String() string { - return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream) -} - -func (w *writeData) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteData(w.streamID, w.endStream, w.p) -} - -func (w *writeData) staysWithinBuffer(max int) bool { - return frameHeaderLen+len(w.p) <= max -} - -// handlerPanicRST is the message sent from handler goroutines when -// the handler panics. -type handlerPanicRST struct { - StreamID uint32 -} - -func (hp handlerPanicRST) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal) -} - -func (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } - -func (se StreamError) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteRSTStream(se.StreamID, se.Code) -} - -func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } - -type writePing struct { - data [8]byte -} - -func (w writePing) writeFrame(ctx writeContext) error { - return ctx.Framer().WritePing(false, w.data) -} - -func (w writePing) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.data) <= max } - -type writePingAck struct{ pf *PingFrame } - -func (w writePingAck) writeFrame(ctx writeContext) error { - return ctx.Framer().WritePing(true, w.pf.Data) -} - -func (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max } - -type writeSettingsAck struct{} - -func (writeSettingsAck) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteSettingsAck() -} - -func (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max } - -// splitHeaderBlock splits headerBlock into fragments so that each fragment fits -// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true -// for the first/last fragment, respectively. -func splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error { - // For now we're lazy and just pick the minimum MAX_FRAME_SIZE - // that all peers must support (16KB). Later we could care - // more and send larger frames if the peer advertised it, but - // there's little point. Most headers are small anyway (so we - // generally won't have CONTINUATION frames), and extra frames - // only waste 9 bytes anyway. - const maxFrameSize = 16384 - - first := true - for len(headerBlock) > 0 { - frag := headerBlock - if len(frag) > maxFrameSize { - frag = frag[:maxFrameSize] - } - headerBlock = headerBlock[len(frag):] - if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil { - return err - } - first = false - } - return nil -} - -// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames -// for HTTP response headers or trailers from a server handler. -type writeResHeaders struct { - streamID uint32 - httpResCode int // 0 means no ":status" line - h http.Header // may be nil - trailers []string // if non-nil, which keys of h to write. nil means all. - endStream bool - - date string - contentType string - contentLength string -} - -func encKV(enc *hpack.Encoder, k, v string) { - if VerboseLogs { - log.Printf("http2: server encoding header %q = %q", k, v) - } - enc.WriteField(hpack.HeaderField{Name: k, Value: v}) -} - -func (w *writeResHeaders) staysWithinBuffer(max int) bool { - // TODO: this is a common one. It'd be nice to return true - // here and get into the fast path if we could be clever and - // calculate the size fast enough, or at least a conservative - // upper bound that usually fires. (Maybe if w.h and - // w.trailers are nil, so we don't need to enumerate it.) - // Otherwise I'm afraid that just calculating the length to - // answer this question would be slower than the ~2µs benefit. - return false -} - -func (w *writeResHeaders) writeFrame(ctx writeContext) error { - enc, buf := ctx.HeaderEncoder() - buf.Reset() - - if w.httpResCode != 0 { - encKV(enc, ":status", httpCodeString(w.httpResCode)) - } - - encodeHeaders(enc, w.h, w.trailers) - - if w.contentType != "" { - encKV(enc, "content-type", w.contentType) - } - if w.contentLength != "" { - encKV(enc, "content-length", w.contentLength) - } - if w.date != "" { - encKV(enc, "date", w.date) - } - - headerBlock := buf.Bytes() - if len(headerBlock) == 0 && w.trailers == nil { - panic("unexpected empty hpack") - } - - return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock) -} - -func (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error { - if firstFrag { - return ctx.Framer().WriteHeaders(HeadersFrameParam{ - StreamID: w.streamID, - BlockFragment: frag, - EndStream: w.endStream, - EndHeaders: lastFrag, - }) - } else { - return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag) - } -} - -// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames. -type writePushPromise struct { - streamID uint32 // pusher stream - method string // for :method - url *url.URL // for :scheme, :authority, :path - h http.Header - - // Creates an ID for a pushed stream. This runs on serveG just before - // the frame is written. The returned ID is copied to promisedID. - allocatePromisedID func() (uint32, error) - promisedID uint32 -} - -func (w *writePushPromise) staysWithinBuffer(max int) bool { - // TODO: see writeResHeaders.staysWithinBuffer - return false -} - -func (w *writePushPromise) writeFrame(ctx writeContext) error { - enc, buf := ctx.HeaderEncoder() - buf.Reset() - - encKV(enc, ":method", w.method) - encKV(enc, ":scheme", w.url.Scheme) - encKV(enc, ":authority", w.url.Host) - encKV(enc, ":path", w.url.RequestURI()) - encodeHeaders(enc, w.h, nil) - - headerBlock := buf.Bytes() - if len(headerBlock) == 0 { - panic("unexpected empty hpack") - } - - return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock) -} - -func (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error { - if firstFrag { - return ctx.Framer().WritePushPromise(PushPromiseParam{ - StreamID: w.streamID, - PromiseID: w.promisedID, - BlockFragment: frag, - EndHeaders: lastFrag, - }) - } else { - return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag) - } -} - -type write100ContinueHeadersFrame struct { - streamID uint32 -} - -func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error { - enc, buf := ctx.HeaderEncoder() - buf.Reset() - encKV(enc, ":status", "100") - return ctx.Framer().WriteHeaders(HeadersFrameParam{ - StreamID: w.streamID, - BlockFragment: buf.Bytes(), - EndStream: false, - EndHeaders: true, - }) -} - -func (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool { - // Sloppy but conservative: - return 9+2*(len(":status")+len("100")) <= max -} - -type writeWindowUpdate struct { - streamID uint32 // or 0 for conn-level - n uint32 -} - -func (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max } - -func (wu writeWindowUpdate) writeFrame(ctx writeContext) error { - return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n) -} - -// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k]) -// is encoded only if k is in keys. -func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { - if keys == nil { - sorter := sorterPool.Get().(*sorter) - // Using defer here, since the returned keys from the - // sorter.Keys method is only valid until the sorter - // is returned: - defer sorterPool.Put(sorter) - keys = sorter.Keys(h) - } - for _, k := range keys { - vv := h[k] - k, ascii := httpcommon.LowerHeader(k) - if !ascii { - // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header - // field names have to be ASCII characters (just as in HTTP/1.x). - continue - } - if !validWireHeaderFieldName(k) { - // Skip it as backup paranoia. Per - // golang.org/issue/14048, these should - // already be rejected at a higher level. - continue - } - isTE := k == "transfer-encoding" - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // TODO: return an error? golang.org/issue/14048 - // For now just omit it. - continue - } - // TODO: more of "8.1.2.2 Connection-Specific Header Fields" - if isTE && v != "trailers" { - continue - } - encKV(enc, k, v) - } - } -} diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go deleted file mode 100644 index cc893ad..0000000 --- a/vendor/golang.org/x/net/http2/writesched.go +++ /dev/null @@ -1,251 +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 http2 - -import "fmt" - -// WriteScheduler is the interface implemented by HTTP/2 write schedulers. -// Methods are never called concurrently. -type WriteScheduler interface { - // OpenStream opens a new stream in the write scheduler. - // It is illegal to call this with streamID=0 or with a streamID that is - // already open -- the call may panic. - OpenStream(streamID uint32, options OpenStreamOptions) - - // CloseStream closes a stream in the write scheduler. Any frames queued on - // this stream should be discarded. It is illegal to call this on a stream - // that is not open -- the call may panic. - CloseStream(streamID uint32) - - // AdjustStream adjusts the priority of the given stream. This may be called - // on a stream that has not yet been opened or has been closed. Note that - // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See: - // https://tools.ietf.org/html/rfc7540#section-5.1 - AdjustStream(streamID uint32, priority PriorityParam) - - // Push queues a frame in the scheduler. In most cases, this will not be - // called with wr.StreamID()!=0 unless that stream is currently open. The one - // exception is RST_STREAM frames, which may be sent on idle or closed streams. - Push(wr FrameWriteRequest) - - // Pop dequeues the next frame to write. Returns false if no frames can - // be written. Frames with a given wr.StreamID() are Pop'd in the same - // order they are Push'd, except RST_STREAM frames. No frames should be - // discarded except by CloseStream. - Pop() (wr FrameWriteRequest, ok bool) -} - -// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream. -type OpenStreamOptions struct { - // PusherID is zero if the stream was initiated by the client. Otherwise, - // PusherID names the stream that pushed the newly opened stream. - PusherID uint32 -} - -// FrameWriteRequest is a request to write a frame. -type FrameWriteRequest struct { - // write is the interface value that does the writing, once the - // WriteScheduler has selected this frame to write. The write - // functions are all defined in write.go. - write writeFramer - - // stream is the stream on which this frame will be written. - // nil for non-stream frames like PING and SETTINGS. - // nil for RST_STREAM streams, which use the StreamError.StreamID field instead. - stream *stream - - // done, if non-nil, must be a buffered channel with space for - // 1 message and is sent the return value from write (or an - // earlier error) when the frame has been written. - done chan error -} - -// StreamID returns the id of the stream this frame will be written to. -// 0 is used for non-stream frames such as PING and SETTINGS. -func (wr FrameWriteRequest) StreamID() uint32 { - if wr.stream == nil { - if se, ok := wr.write.(StreamError); ok { - // (*serverConn).resetStream doesn't set - // stream because it doesn't necessarily have - // one. So special case this type of write - // message. - return se.StreamID - } - return 0 - } - return wr.stream.id -} - -// isControl reports whether wr is a control frame for MaxQueuedControlFrames -// purposes. That includes non-stream frames and RST_STREAM frames. -func (wr FrameWriteRequest) isControl() bool { - return wr.stream == nil -} - -// DataSize returns the number of flow control bytes that must be consumed -// to write this entire frame. This is 0 for non-DATA frames. -func (wr FrameWriteRequest) DataSize() int { - if wd, ok := wr.write.(*writeData); ok { - return len(wd.p) - } - return 0 -} - -// Consume consumes min(n, available) bytes from this frame, where available -// is the number of flow control bytes available on the stream. Consume returns -// 0, 1, or 2 frames, where the integer return value gives the number of frames -// returned. -// -// If flow control prevents consuming any bytes, this returns (_, _, 0). If -// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this -// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and -// 'rest' contains the remaining bytes. The consumed bytes are deducted from the -// underlying stream's flow control budget. -func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) { - var empty FrameWriteRequest - - // Non-DATA frames are always consumed whole. - wd, ok := wr.write.(*writeData) - if !ok || len(wd.p) == 0 { - return wr, empty, 1 - } - - // Might need to split after applying limits. - allowed := wr.stream.flow.available() - if n < allowed { - allowed = n - } - if wr.stream.sc.maxFrameSize < allowed { - allowed = wr.stream.sc.maxFrameSize - } - if allowed <= 0 { - return empty, empty, 0 - } - if len(wd.p) > int(allowed) { - wr.stream.flow.take(allowed) - consumed := FrameWriteRequest{ - stream: wr.stream, - write: &writeData{ - streamID: wd.streamID, - p: wd.p[:allowed], - // Even if the original had endStream set, there - // are bytes remaining because len(wd.p) > allowed, - // so we know endStream is false. - endStream: false, - }, - // Our caller is blocking on the final DATA frame, not - // this intermediate frame, so no need to wait. - done: nil, - } - rest := FrameWriteRequest{ - stream: wr.stream, - write: &writeData{ - streamID: wd.streamID, - p: wd.p[allowed:], - endStream: wd.endStream, - }, - done: wr.done, - } - return consumed, rest, 2 - } - - // The frame is consumed whole. - // NB: This cast cannot overflow because allowed is <= math.MaxInt32. - wr.stream.flow.take(int32(len(wd.p))) - return wr, empty, 1 -} - -// String is for debugging only. -func (wr FrameWriteRequest) String() string { - var des string - if s, ok := wr.write.(fmt.Stringer); ok { - des = s.String() - } else { - des = fmt.Sprintf("%T", wr.write) - } - return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des) -} - -// replyToWriter sends err to wr.done and panics if the send must block -// This does nothing if wr.done is nil. -func (wr *FrameWriteRequest) replyToWriter(err error) { - if wr.done == nil { - return - } - select { - case wr.done <- err: - default: - panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write)) - } - wr.write = nil // prevent use (assume it's tainted after wr.done send) -} - -// writeQueue is used by implementations of WriteScheduler. -type writeQueue struct { - s []FrameWriteRequest - prev, next *writeQueue -} - -func (q *writeQueue) empty() bool { return len(q.s) == 0 } - -func (q *writeQueue) push(wr FrameWriteRequest) { - q.s = append(q.s, wr) -} - -func (q *writeQueue) shift() FrameWriteRequest { - if len(q.s) == 0 { - panic("invalid use of queue") - } - wr := q.s[0] - // TODO: less copy-happy queue. - copy(q.s, q.s[1:]) - q.s[len(q.s)-1] = FrameWriteRequest{} - q.s = q.s[:len(q.s)-1] - return wr -} - -// consume consumes up to n bytes from q.s[0]. If the frame is -// entirely consumed, it is removed from the queue. If the frame -// is partially consumed, the frame is kept with the consumed -// bytes removed. Returns true iff any bytes were consumed. -func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) { - if len(q.s) == 0 { - return FrameWriteRequest{}, false - } - consumed, rest, numresult := q.s[0].Consume(n) - switch numresult { - case 0: - return FrameWriteRequest{}, false - case 1: - q.shift() - case 2: - q.s[0] = rest - } - return consumed, true -} - -type writeQueuePool []*writeQueue - -// put inserts an unused writeQueue into the pool. -func (p *writeQueuePool) put(q *writeQueue) { - for i := range q.s { - q.s[i] = FrameWriteRequest{} - } - q.s = q.s[:0] - *p = append(*p, q) -} - -// get returns an empty writeQueue. -func (p *writeQueuePool) get() *writeQueue { - ln := len(*p) - if ln == 0 { - return new(writeQueue) - } - x := ln - 1 - q := (*p)[x] - (*p)[x] = nil - *p = (*p)[:x] - return q -} diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go deleted file mode 100644 index f678333..0000000 --- a/vendor/golang.org/x/net/http2/writesched_priority.go +++ /dev/null @@ -1,451 +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 http2 - -import ( - "fmt" - "math" - "sort" -) - -// RFC 7540, Section 5.3.5: the default weight is 16. -const priorityDefaultWeight = 15 // 16 = 15 + 1 - -// PriorityWriteSchedulerConfig configures a priorityWriteScheduler. -type PriorityWriteSchedulerConfig struct { - // MaxClosedNodesInTree controls the maximum number of closed streams to - // retain in the priority tree. Setting this to zero saves a small amount - // of memory at the cost of performance. - // - // See RFC 7540, Section 5.3.4: - // "It is possible for a stream to become closed while prioritization - // information ... is in transit. ... This potentially creates suboptimal - // prioritization, since the stream could be given a priority that is - // different from what is intended. To avoid these problems, an endpoint - // SHOULD retain stream prioritization state for a period after streams - // become closed. The longer state is retained, the lower the chance that - // streams are assigned incorrect or default priority values." - MaxClosedNodesInTree int - - // MaxIdleNodesInTree controls the maximum number of idle streams to - // retain in the priority tree. Setting this to zero saves a small amount - // of memory at the cost of performance. - // - // See RFC 7540, Section 5.3.4: - // Similarly, streams that are in the "idle" state can be assigned - // priority or become a parent of other streams. This allows for the - // creation of a grouping node in the dependency tree, which enables - // more flexible expressions of priority. Idle streams begin with a - // default priority (Section 5.3.5). - MaxIdleNodesInTree int - - // ThrottleOutOfOrderWrites enables write throttling to help ensure that - // data is delivered in priority order. This works around a race where - // stream B depends on stream A and both streams are about to call Write - // to queue DATA frames. If B wins the race, a naive scheduler would eagerly - // write as much data from B as possible, but this is suboptimal because A - // is a higher-priority stream. With throttling enabled, we write a small - // amount of data from B to minimize the amount of bandwidth that B can - // steal from A. - ThrottleOutOfOrderWrites bool -} - -// NewPriorityWriteScheduler constructs a WriteScheduler that schedules -// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3. -// If cfg is nil, default options are used. -func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler { - if cfg == nil { - // For justification of these defaults, see: - // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY - cfg = &PriorityWriteSchedulerConfig{ - MaxClosedNodesInTree: 10, - MaxIdleNodesInTree: 10, - ThrottleOutOfOrderWrites: false, - } - } - - ws := &priorityWriteScheduler{ - nodes: make(map[uint32]*priorityNode), - maxClosedNodesInTree: cfg.MaxClosedNodesInTree, - maxIdleNodesInTree: cfg.MaxIdleNodesInTree, - enableWriteThrottle: cfg.ThrottleOutOfOrderWrites, - } - ws.nodes[0] = &ws.root - if cfg.ThrottleOutOfOrderWrites { - ws.writeThrottleLimit = 1024 - } else { - ws.writeThrottleLimit = math.MaxInt32 - } - return ws -} - -type priorityNodeState int - -const ( - priorityNodeOpen priorityNodeState = iota - priorityNodeClosed - priorityNodeIdle -) - -// priorityNode is a node in an HTTP/2 priority tree. -// Each node is associated with a single stream ID. -// See RFC 7540, Section 5.3. -type priorityNode struct { - q writeQueue // queue of pending frames to write - id uint32 // id of the stream, or 0 for the root of the tree - weight uint8 // the actual weight is weight+1, so the value is in [1,256] - state priorityNodeState // open | closed | idle - bytes int64 // number of bytes written by this node, or 0 if closed - subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree - - // These links form the priority tree. - parent *priorityNode - kids *priorityNode // start of the kids list - prev, next *priorityNode // doubly-linked list of siblings -} - -func (n *priorityNode) setParent(parent *priorityNode) { - if n == parent { - panic("setParent to self") - } - if n.parent == parent { - return - } - // Unlink from current parent. - if parent := n.parent; parent != nil { - if n.prev == nil { - parent.kids = n.next - } else { - n.prev.next = n.next - } - if n.next != nil { - n.next.prev = n.prev - } - } - // Link to new parent. - // If parent=nil, remove n from the tree. - // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder). - n.parent = parent - if parent == nil { - n.next = nil - n.prev = nil - } else { - n.next = parent.kids - n.prev = nil - if n.next != nil { - n.next.prev = n - } - parent.kids = n - } -} - -func (n *priorityNode) addBytes(b int64) { - n.bytes += b - for ; n != nil; n = n.parent { - n.subtreeBytes += b - } -} - -// walkReadyInOrder iterates over the tree in priority order, calling f for each node -// with a non-empty write queue. When f returns true, this function returns true and the -// walk halts. tmp is used as scratch space for sorting. -// -// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true -// if any ancestor p of n is still open (ignoring the root node). -func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool { - if !n.q.empty() && f(n, openParent) { - return true - } - if n.kids == nil { - return false - } - - // Don't consider the root "open" when updating openParent since - // we can't send data frames on the root stream (only control frames). - if n.id != 0 { - openParent = openParent || (n.state == priorityNodeOpen) - } - - // Common case: only one kid or all kids have the same weight. - // Some clients don't use weights; other clients (like web browsers) - // use mostly-linear priority trees. - w := n.kids.weight - needSort := false - for k := n.kids.next; k != nil; k = k.next { - if k.weight != w { - needSort = true - break - } - } - if !needSort { - for k := n.kids; k != nil; k = k.next { - if k.walkReadyInOrder(openParent, tmp, f) { - return true - } - } - return false - } - - // Uncommon case: sort the child nodes. We remove the kids from the parent, - // then re-insert after sorting so we can reuse tmp for future sort calls. - *tmp = (*tmp)[:0] - for n.kids != nil { - *tmp = append(*tmp, n.kids) - n.kids.setParent(nil) - } - sort.Sort(sortPriorityNodeSiblings(*tmp)) - for i := len(*tmp) - 1; i >= 0; i-- { - (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids - } - for k := n.kids; k != nil; k = k.next { - if k.walkReadyInOrder(openParent, tmp, f) { - return true - } - } - return false -} - -type sortPriorityNodeSiblings []*priorityNode - -func (z sortPriorityNodeSiblings) Len() int { return len(z) } -func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] } -func (z sortPriorityNodeSiblings) Less(i, k int) bool { - // Prefer the subtree that has sent fewer bytes relative to its weight. - // See sections 5.3.2 and 5.3.4. - wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes) - wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes) - if bi == 0 && bk == 0 { - return wi >= wk - } - if bk == 0 { - return false - } - return bi/bk <= wi/wk -} - -type priorityWriteScheduler struct { - // root is the root of the priority tree, where root.id = 0. - // The root queues control frames that are not associated with any stream. - root priorityNode - - // nodes maps stream ids to priority tree nodes. - nodes map[uint32]*priorityNode - - // maxID is the maximum stream id in nodes. - maxID uint32 - - // lists of nodes that have been closed or are idle, but are kept in - // the tree for improved prioritization. When the lengths exceed either - // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded. - closedNodes, idleNodes []*priorityNode - - // From the config. - maxClosedNodesInTree int - maxIdleNodesInTree int - writeThrottleLimit int32 - enableWriteThrottle bool - - // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations. - tmp []*priorityNode - - // pool of empty queues for reuse. - queuePool writeQueuePool -} - -func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { - // The stream may be currently idle but cannot be opened or closed. - if curr := ws.nodes[streamID]; curr != nil { - if curr.state != priorityNodeIdle { - panic(fmt.Sprintf("stream %d already opened", streamID)) - } - curr.state = priorityNodeOpen - return - } - - // RFC 7540, Section 5.3.5: - // "All streams are initially assigned a non-exclusive dependency on stream 0x0. - // Pushed streams initially depend on their associated stream. In both cases, - // streams are assigned a default weight of 16." - parent := ws.nodes[options.PusherID] - if parent == nil { - parent = &ws.root - } - n := &priorityNode{ - q: *ws.queuePool.get(), - id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeOpen, - } - n.setParent(parent) - ws.nodes[streamID] = n - if streamID > ws.maxID { - ws.maxID = streamID - } -} - -func (ws *priorityWriteScheduler) CloseStream(streamID uint32) { - if streamID == 0 { - panic("violation of WriteScheduler interface: cannot close stream 0") - } - if ws.nodes[streamID] == nil { - panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID)) - } - if ws.nodes[streamID].state != priorityNodeOpen { - panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID)) - } - - n := ws.nodes[streamID] - n.state = priorityNodeClosed - n.addBytes(-n.bytes) - - q := n.q - ws.queuePool.put(&q) - n.q.s = nil - if ws.maxClosedNodesInTree > 0 { - ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n) - } else { - ws.removeNode(n) - } -} - -func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { - if streamID == 0 { - panic("adjustPriority on root") - } - - // If streamID does not exist, there are two cases: - // - A closed stream that has been removed (this will have ID <= maxID) - // - An idle stream that is being used for "grouping" (this will have ID > maxID) - n := ws.nodes[streamID] - if n == nil { - if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 { - return - } - ws.maxID = streamID - n = &priorityNode{ - q: *ws.queuePool.get(), - id: streamID, - weight: priorityDefaultWeight, - state: priorityNodeIdle, - } - n.setParent(&ws.root) - ws.nodes[streamID] = n - ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n) - } - - // Section 5.3.1: A dependency on a stream that is not currently in the tree - // results in that stream being given a default priority (Section 5.3.5). - parent := ws.nodes[priority.StreamDep] - if parent == nil { - n.setParent(&ws.root) - n.weight = priorityDefaultWeight - return - } - - // Ignore if the client tries to make a node its own parent. - if n == parent { - return - } - - // Section 5.3.3: - // "If a stream is made dependent on one of its own dependencies, the - // formerly dependent stream is first moved to be dependent on the - // reprioritized stream's previous parent. The moved dependency retains - // its weight." - // - // That is: if parent depends on n, move parent to depend on n.parent. - for x := parent.parent; x != nil; x = x.parent { - if x == n { - parent.setParent(n.parent) - break - } - } - - // Section 5.3.3: The exclusive flag causes the stream to become the sole - // dependency of its parent stream, causing other dependencies to become - // dependent on the exclusive stream. - if priority.Exclusive { - k := parent.kids - for k != nil { - next := k.next - if k != n { - k.setParent(n) - } - k = next - } - } - - n.setParent(parent) - n.weight = priority.Weight -} - -func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) { - var n *priorityNode - if wr.isControl() { - n = &ws.root - } else { - id := wr.StreamID() - n = ws.nodes[id] - if n == nil { - // id is an idle or closed stream. wr should not be a HEADERS or - // DATA frame. In other case, we push wr onto the root, rather - // than creating a new priorityNode. - if wr.DataSize() > 0 { - panic("add DATA on non-open stream") - } - n = &ws.root - } - } - n.q.push(wr) -} - -func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) { - ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool { - limit := int32(math.MaxInt32) - if openParent { - limit = ws.writeThrottleLimit - } - wr, ok = n.q.consume(limit) - if !ok { - return false - } - n.addBytes(int64(wr.DataSize())) - // If B depends on A and B continuously has data available but A - // does not, gradually increase the throttling limit to allow B to - // steal more and more bandwidth from A. - if openParent { - ws.writeThrottleLimit += 1024 - if ws.writeThrottleLimit < 0 { - ws.writeThrottleLimit = math.MaxInt32 - } - } else if ws.enableWriteThrottle { - ws.writeThrottleLimit = 1024 - } - return true - }) - return wr, ok -} - -func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) { - if maxSize == 0 { - return - } - if len(*list) == maxSize { - // Remove the oldest node, then shift left. - ws.removeNode((*list)[0]) - x := (*list)[1:] - copy(*list, x) - *list = (*list)[:len(x)] - } - *list = append(*list, n) -} - -func (ws *priorityWriteScheduler) removeNode(n *priorityNode) { - for n.kids != nil { - n.kids.setParent(n.parent) - } - n.setParent(nil) - delete(ws.nodes, n.id) -} diff --git a/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go deleted file mode 100644 index f2e55e0..0000000 --- a/vendor/golang.org/x/net/http2/writesched_random.go +++ /dev/null @@ -1,77 +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 http2 - -import "math" - -// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2 -// priorities. Control frames like SETTINGS and PING are written before DATA -// frames, but if no control frames are queued and multiple streams have queued -// HEADERS or DATA frames, Pop selects a ready stream arbitrarily. -func NewRandomWriteScheduler() WriteScheduler { - return &randomWriteScheduler{sq: make(map[uint32]*writeQueue)} -} - -type randomWriteScheduler struct { - // zero are frames not associated with a specific stream. - zero writeQueue - - // sq contains the stream-specific queues, keyed by stream ID. - // When a stream is idle, closed, or emptied, it's deleted - // from the map. - sq map[uint32]*writeQueue - - // pool of empty queues for reuse. - queuePool writeQueuePool -} - -func (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { - // no-op: idle streams are not tracked -} - -func (ws *randomWriteScheduler) CloseStream(streamID uint32) { - q, ok := ws.sq[streamID] - if !ok { - return - } - delete(ws.sq, streamID) - ws.queuePool.put(q) -} - -func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) { - // no-op: priorities are ignored -} - -func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) { - if wr.isControl() { - ws.zero.push(wr) - return - } - id := wr.StreamID() - q, ok := ws.sq[id] - if !ok { - q = ws.queuePool.get() - ws.sq[id] = q - } - q.push(wr) -} - -func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) { - // Control and RST_STREAM frames first. - if !ws.zero.empty() { - return ws.zero.shift(), true - } - // Iterate over all non-idle streams until finding one that can be consumed. - for streamID, q := range ws.sq { - if wr, ok := q.consume(math.MaxInt32); ok { - if q.empty() { - delete(ws.sq, streamID) - ws.queuePool.put(q) - } - return wr, true - } - } - return FrameWriteRequest{}, false -} diff --git a/vendor/golang.org/x/net/http2/writesched_roundrobin.go b/vendor/golang.org/x/net/http2/writesched_roundrobin.go deleted file mode 100644 index 54fe863..0000000 --- a/vendor/golang.org/x/net/http2/writesched_roundrobin.go +++ /dev/null @@ -1,119 +0,0 @@ -// 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. - -package http2 - -import ( - "fmt" - "math" -) - -type roundRobinWriteScheduler struct { - // control contains control frames (SETTINGS, PING, etc.). - control writeQueue - - // streams maps stream ID to a queue. - streams map[uint32]*writeQueue - - // stream queues are stored in a circular linked list. - // head is the next stream to write, or nil if there are no streams open. - head *writeQueue - - // pool of empty queues for reuse. - queuePool writeQueuePool -} - -// newRoundRobinWriteScheduler constructs a new write scheduler. -// The round robin scheduler priorizes control frames -// like SETTINGS and PING over DATA frames. -// When there are no control frames to send, it performs a round-robin -// selection from the ready streams. -func newRoundRobinWriteScheduler() WriteScheduler { - ws := &roundRobinWriteScheduler{ - streams: make(map[uint32]*writeQueue), - } - return ws -} - -func (ws *roundRobinWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) { - if ws.streams[streamID] != nil { - panic(fmt.Errorf("stream %d already opened", streamID)) - } - q := ws.queuePool.get() - ws.streams[streamID] = q - if ws.head == nil { - ws.head = q - q.next = q - q.prev = q - } else { - // Queues are stored in a ring. - // Insert the new stream before ws.head, putting it at the end of the list. - q.prev = ws.head.prev - q.next = ws.head - q.prev.next = q - q.next.prev = q - } -} - -func (ws *roundRobinWriteScheduler) CloseStream(streamID uint32) { - q := ws.streams[streamID] - if q == nil { - return - } - if q.next == q { - // This was the only open stream. - ws.head = nil - } else { - q.prev.next = q.next - q.next.prev = q.prev - if ws.head == q { - ws.head = q.next - } - } - delete(ws.streams, streamID) - ws.queuePool.put(q) -} - -func (ws *roundRobinWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {} - -func (ws *roundRobinWriteScheduler) Push(wr FrameWriteRequest) { - if wr.isControl() { - ws.control.push(wr) - return - } - q := ws.streams[wr.StreamID()] - if q == nil { - // This is a closed stream. - // wr should not be a HEADERS or DATA frame. - // We push the request onto the control queue. - if wr.DataSize() > 0 { - panic("add DATA on non-open stream") - } - ws.control.push(wr) - return - } - q.push(wr) -} - -func (ws *roundRobinWriteScheduler) Pop() (FrameWriteRequest, bool) { - // Control and RST_STREAM frames first. - if !ws.control.empty() { - return ws.control.shift(), true - } - if ws.head == nil { - return FrameWriteRequest{}, false - } - q := ws.head - for { - if wr, ok := q.consume(math.MaxInt32); ok { - ws.head = q.next - return wr, true - } - q = q.next - if q == ws.head { - break - } - } - return FrameWriteRequest{}, false -} diff --git a/vendor/golang.org/x/net/internal/httpcommon/ascii.go b/vendor/golang.org/x/net/internal/httpcommon/ascii.go deleted file mode 100644 index ed14da5..0000000 --- a/vendor/golang.org/x/net/internal/httpcommon/ascii.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2025 The Go 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 httpcommon - -import "strings" - -// The HTTP protocols are defined in terms of ASCII, not Unicode. This file -// contains helper functions which may use Unicode-aware functions which would -// otherwise be unsafe and could introduce vulnerabilities if used improperly. - -// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t -// are equal, ASCII-case-insensitively. -func asciiEqualFold(s, t string) bool { - if len(s) != len(t) { - return false - } - for i := 0; i < len(s); i++ { - if lower(s[i]) != lower(t[i]) { - return false - } - } - return true -} - -// lower returns the ASCII lowercase version of b. -func lower(b byte) byte { - if 'A' <= b && b <= 'Z' { - return b + ('a' - 'A') - } - return b -} - -// isASCIIPrint returns whether s is ASCII and printable according to -// https://tools.ietf.org/html/rfc20#section-4.2. -func isASCIIPrint(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] < ' ' || s[i] > '~' { - return false - } - } - return true -} - -// asciiToLower returns the lowercase version of s if s is ASCII and printable, -// and whether or not it was. -func asciiToLower(s string) (lower string, ok bool) { - if !isASCIIPrint(s) { - return "", false - } - return strings.ToLower(s), true -} diff --git a/vendor/golang.org/x/net/internal/httpcommon/headermap.go b/vendor/golang.org/x/net/internal/httpcommon/headermap.go deleted file mode 100644 index 92483d8..0000000 --- a/vendor/golang.org/x/net/internal/httpcommon/headermap.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2025 The Go 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 httpcommon - -import ( - "net/textproto" - "sync" -) - -var ( - commonBuildOnce sync.Once - commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case - commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case -) - -func buildCommonHeaderMapsOnce() { - commonBuildOnce.Do(buildCommonHeaderMaps) -} - -func buildCommonHeaderMaps() { - common := []string{ - "accept", - "accept-charset", - "accept-encoding", - "accept-language", - "accept-ranges", - "age", - "access-control-allow-credentials", - "access-control-allow-headers", - "access-control-allow-methods", - "access-control-allow-origin", - "access-control-expose-headers", - "access-control-max-age", - "access-control-request-headers", - "access-control-request-method", - "allow", - "authorization", - "cache-control", - "content-disposition", - "content-encoding", - "content-language", - "content-length", - "content-location", - "content-range", - "content-type", - "cookie", - "date", - "etag", - "expect", - "expires", - "from", - "host", - "if-match", - "if-modified-since", - "if-none-match", - "if-unmodified-since", - "last-modified", - "link", - "location", - "max-forwards", - "origin", - "proxy-authenticate", - "proxy-authorization", - "range", - "referer", - "refresh", - "retry-after", - "server", - "set-cookie", - "strict-transport-security", - "trailer", - "transfer-encoding", - "user-agent", - "vary", - "via", - "www-authenticate", - "x-forwarded-for", - "x-forwarded-proto", - } - commonLowerHeader = make(map[string]string, len(common)) - commonCanonHeader = make(map[string]string, len(common)) - for _, v := range common { - chk := textproto.CanonicalMIMEHeaderKey(v) - commonLowerHeader[chk] = v - commonCanonHeader[v] = chk - } -} - -// LowerHeader returns the lowercase form of a header name, -// used on the wire for HTTP/2 and HTTP/3 requests. -func LowerHeader(v string) (lower string, ascii bool) { - buildCommonHeaderMapsOnce() - if s, ok := commonLowerHeader[v]; ok { - return s, true - } - return asciiToLower(v) -} - -// CanonicalHeader canonicalizes a header name. (For example, "host" becomes "Host".) -func CanonicalHeader(v string) string { - buildCommonHeaderMapsOnce() - if s, ok := commonCanonHeader[v]; ok { - return s - } - return textproto.CanonicalMIMEHeaderKey(v) -} - -// CachedCanonicalHeader returns the canonical form of a well-known header name. -func CachedCanonicalHeader(v string) (string, bool) { - buildCommonHeaderMapsOnce() - s, ok := commonCanonHeader[v] - return s, ok -} diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go deleted file mode 100644 index 4b70553..0000000 --- a/vendor/golang.org/x/net/internal/httpcommon/request.go +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright 2025 The Go 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 httpcommon - -import ( - "context" - "errors" - "fmt" - "net/http/httptrace" - "net/textproto" - "net/url" - "sort" - "strconv" - "strings" - - "golang.org/x/net/http/httpguts" - "golang.org/x/net/http2/hpack" -) - -var ( - ErrRequestHeaderListSize = errors.New("request header list larger than peer's advertised limit") -) - -// Request is a subset of http.Request. -// It'd be simpler to pass an *http.Request, of course, but we can't depend on net/http -// without creating a dependency cycle. -type Request struct { - URL *url.URL - Method string - Host string - Header map[string][]string - Trailer map[string][]string - ActualContentLength int64 // 0 means 0, -1 means unknown -} - -// EncodeHeadersParam is parameters to EncodeHeaders. -type EncodeHeadersParam struct { - Request Request - - // AddGzipHeader indicates that an "accept-encoding: gzip" header should be - // added to the request. - AddGzipHeader bool - - // PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting. - PeerMaxHeaderListSize uint64 - - // DefaultUserAgent is the User-Agent header to send when the request - // neither contains a User-Agent nor disables it. - DefaultUserAgent string -} - -// EncodeHeadersParam is the result of EncodeHeaders. -type EncodeHeadersResult struct { - HasBody bool - HasTrailers bool -} - -// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3. -// It validates a request and calls headerf with each pseudo-header and header -// for the request. -// The headerf function is called with the validated, canonicalized header name. -func EncodeHeaders(ctx context.Context, param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) { - req := param.Request - - // Check for invalid connection-level headers. - if err := checkConnHeaders(req.Header); err != nil { - return res, err - } - - if req.URL == nil { - return res, errors.New("Request.URL is nil") - } - - host := req.Host - if host == "" { - host = req.URL.Host - } - host, err := httpguts.PunycodeHostPort(host) - if err != nil { - return res, err - } - if !httpguts.ValidHostHeader(host) { - return res, errors.New("invalid Host header") - } - - // isNormalConnect is true if this is a non-extended CONNECT request. - isNormalConnect := false - var protocol string - if vv := req.Header[":protocol"]; len(vv) > 0 { - protocol = vv[0] - } - if req.Method == "CONNECT" && protocol == "" { - isNormalConnect = true - } else if protocol != "" && req.Method != "CONNECT" { - return res, errors.New("invalid :protocol header in non-CONNECT request") - } - - // Validate the path, except for non-extended CONNECT requests which have no path. - var path string - if !isNormalConnect { - path = req.URL.RequestURI() - if !validPseudoPath(path) { - orig := path - path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host) - if !validPseudoPath(path) { - if req.URL.Opaque != "" { - return res, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque) - } else { - return res, fmt.Errorf("invalid request :path %q", orig) - } - } - } - } - - // Check for any invalid headers+trailers and return an error before we - // potentially pollute our hpack state. (We want to be able to - // continue to reuse the hpack encoder for future requests) - if err := validateHeaders(req.Header); err != "" { - return res, fmt.Errorf("invalid HTTP header %s", err) - } - if err := validateHeaders(req.Trailer); err != "" { - return res, fmt.Errorf("invalid HTTP trailer %s", err) - } - - trailers, err := commaSeparatedTrailers(req.Trailer) - if err != nil { - return res, err - } - - enumerateHeaders := func(f func(name, value string)) { - // 8.1.2.3 Request Pseudo-Header Fields - // The :path pseudo-header field includes the path and query parts of the - // target URI (the path-absolute production and optionally a '?' character - // followed by the query production, see Sections 3.3 and 3.4 of - // [RFC3986]). - f(":authority", host) - m := req.Method - if m == "" { - m = "GET" - } - f(":method", m) - if !isNormalConnect { - f(":path", path) - f(":scheme", req.URL.Scheme) - } - if protocol != "" { - f(":protocol", protocol) - } - if trailers != "" { - f("trailer", trailers) - } - - var didUA bool - for k, vv := range req.Header { - if asciiEqualFold(k, "host") || asciiEqualFold(k, "content-length") { - // Host is :authority, already sent. - // Content-Length is automatic, set below. - continue - } else if asciiEqualFold(k, "connection") || - asciiEqualFold(k, "proxy-connection") || - asciiEqualFold(k, "transfer-encoding") || - asciiEqualFold(k, "upgrade") || - asciiEqualFold(k, "keep-alive") { - // Per 8.1.2.2 Connection-Specific Header - // Fields, don't send connection-specific - // fields. We have already checked if any - // are error-worthy so just ignore the rest. - continue - } else if asciiEqualFold(k, "user-agent") { - // Match Go's http1 behavior: at most one - // User-Agent. If set to nil or empty string, - // then omit it. Otherwise if not mentioned, - // include the default (below). - didUA = true - if len(vv) < 1 { - continue - } - vv = vv[:1] - if vv[0] == "" { - continue - } - } else if asciiEqualFold(k, "cookie") { - // Per 8.1.2.5 To allow for better compression efficiency, the - // Cookie header field MAY be split into separate header fields, - // each with one or more cookie-pairs. - for _, v := range vv { - for { - p := strings.IndexByte(v, ';') - if p < 0 { - break - } - f("cookie", v[:p]) - p++ - // strip space after semicolon if any. - for p+1 <= len(v) && v[p] == ' ' { - p++ - } - v = v[p:] - } - if len(v) > 0 { - f("cookie", v) - } - } - continue - } else if k == ":protocol" { - // :protocol pseudo-header was already sent above. - continue - } - - for _, v := range vv { - f(k, v) - } - } - if shouldSendReqContentLength(req.Method, req.ActualContentLength) { - f("content-length", strconv.FormatInt(req.ActualContentLength, 10)) - } - if param.AddGzipHeader { - f("accept-encoding", "gzip") - } - if !didUA { - f("user-agent", param.DefaultUserAgent) - } - } - - // Do a first pass over the headers counting bytes to ensure - // we don't exceed cc.peerMaxHeaderListSize. This is done as a - // separate pass before encoding the headers to prevent - // modifying the hpack state. - if param.PeerMaxHeaderListSize > 0 { - hlSize := uint64(0) - enumerateHeaders(func(name, value string) { - hf := hpack.HeaderField{Name: name, Value: value} - hlSize += uint64(hf.Size()) - }) - - if hlSize > param.PeerMaxHeaderListSize { - return res, ErrRequestHeaderListSize - } - } - - trace := httptrace.ContextClientTrace(ctx) - - // Header list size is ok. Write the headers. - enumerateHeaders(func(name, value string) { - name, ascii := LowerHeader(name) - if !ascii { - // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header - // field names have to be ASCII characters (just as in HTTP/1.x). - return - } - - headerf(name, value) - - if trace != nil && trace.WroteHeaderField != nil { - trace.WroteHeaderField(name, []string{value}) - } - }) - - res.HasBody = req.ActualContentLength != 0 - res.HasTrailers = trailers != "" - return res, nil -} - -// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header -// for a request. -func IsRequestGzip(method string, header map[string][]string, disableCompression bool) bool { - // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? - if !disableCompression && - len(header["Accept-Encoding"]) == 0 && - len(header["Range"]) == 0 && - method != "HEAD" { - // Request gzip only, not deflate. Deflate is ambiguous and - // not as universally supported anyway. - // See: https://zlib.net/zlib_faq.html#faq39 - // - // Note that we don't request this for HEAD requests, - // due to a bug in nginx: - // http://trac.nginx.org/nginx/ticket/358 - // https://golang.org/issue/5522 - // - // We don't request gzip if the request is for a range, since - // auto-decoding a portion of a gzipped document will just fail - // anyway. See https://golang.org/issue/8923 - return true - } - return false -} - -// checkConnHeaders checks whether req has any invalid connection-level headers. -// -// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3 -// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1 -// -// Certain headers are special-cased as okay but not transmitted later. -// For example, we allow "Transfer-Encoding: chunked", but drop the header when encoding. -func checkConnHeaders(h map[string][]string) error { - if vv := h["Upgrade"]; len(vv) > 0 && (vv[0] != "" && vv[0] != "chunked") { - return fmt.Errorf("invalid Upgrade request header: %q", vv) - } - if vv := h["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") { - return fmt.Errorf("invalid Transfer-Encoding request header: %q", vv) - } - if vv := h["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !asciiEqualFold(vv[0], "close") && !asciiEqualFold(vv[0], "keep-alive")) { - return fmt.Errorf("invalid Connection request header: %q", vv) - } - return nil -} - -func commaSeparatedTrailers(trailer map[string][]string) (string, error) { - keys := make([]string, 0, len(trailer)) - for k := range trailer { - k = CanonicalHeader(k) - switch k { - case "Transfer-Encoding", "Trailer", "Content-Length": - return "", fmt.Errorf("invalid Trailer key %q", k) - } - keys = append(keys, k) - } - if len(keys) > 0 { - sort.Strings(keys) - return strings.Join(keys, ","), nil - } - return "", nil -} - -// validPseudoPath reports whether v is a valid :path pseudo-header -// value. It must be either: -// -// - a non-empty string starting with '/' -// - the string '*', for OPTIONS requests. -// -// For now this is only used a quick check for deciding when to clean -// up Opaque URLs before sending requests from the Transport. -// See golang.org/issue/16847 -// -// We used to enforce that the path also didn't start with "//", but -// Google's GFE accepts such paths and Chrome sends them, so ignore -// that part of the spec. See golang.org/issue/19103. -func validPseudoPath(v string) bool { - return (len(v) > 0 && v[0] == '/') || v == "*" -} - -func validateHeaders(hdrs map[string][]string) string { - for k, vv := range hdrs { - if !httpguts.ValidHeaderFieldName(k) && k != ":protocol" { - return fmt.Sprintf("name %q", k) - } - for _, v := range vv { - if !httpguts.ValidHeaderFieldValue(v) { - // Don't include the value in the error, - // because it may be sensitive. - return fmt.Sprintf("value for header %q", k) - } - } - } - return "" -} - -// shouldSendReqContentLength reports whether we should send -// a "content-length" request header. This logic is basically a copy of the net/http -// transferWriter.shouldSendContentLength. -// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). -// -1 means unknown. -func shouldSendReqContentLength(method string, contentLength int64) bool { - if contentLength > 0 { - return true - } - if contentLength < 0 { - return false - } - // For zero bodies, whether we send a content-length depends on the method. - // It also kinda doesn't matter for http2 either way, with END_STREAM. - switch method { - case "POST", "PUT", "PATCH": - return true - default: - return false - } -} - -// ServerRequestParam is parameters to NewServerRequest. -type ServerRequestParam struct { - Method string - Scheme, Authority, Path string - Protocol string - Header map[string][]string -} - -// ServerRequestResult is the result of NewServerRequest. -type ServerRequestResult struct { - // Various http.Request fields. - URL *url.URL - RequestURI string - Trailer map[string][]string - - NeedsContinue bool // client provided an "Expect: 100-continue" header - - // If the request should be rejected, this is a short string suitable for passing - // to the http2 package's CountError function. - // It might be a bit odd to return errors this way rather than returing an error, - // but this ensures we don't forget to include a CountError reason. - InvalidReason string -} - -func NewServerRequest(rp ServerRequestParam) ServerRequestResult { - needsContinue := httpguts.HeaderValuesContainsToken(rp.Header["Expect"], "100-continue") - if needsContinue { - delete(rp.Header, "Expect") - } - // Merge Cookie headers into one "; "-delimited value. - if cookies := rp.Header["Cookie"]; len(cookies) > 1 { - rp.Header["Cookie"] = []string{strings.Join(cookies, "; ")} - } - - // Setup Trailers - var trailer map[string][]string - for _, v := range rp.Header["Trailer"] { - for _, key := range strings.Split(v, ",") { - key = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(key)) - switch key { - case "Transfer-Encoding", "Trailer", "Content-Length": - // Bogus. (copy of http1 rules) - // Ignore. - default: - if trailer == nil { - trailer = make(map[string][]string) - } - trailer[key] = nil - } - } - } - delete(rp.Header, "Trailer") - - // "':authority' MUST NOT include the deprecated userinfo subcomponent - // for "http" or "https" schemed URIs." - // https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.8 - if strings.IndexByte(rp.Authority, '@') != -1 && (rp.Scheme == "http" || rp.Scheme == "https") { - return ServerRequestResult{ - InvalidReason: "userinfo_in_authority", - } - } - - var url_ *url.URL - var requestURI string - if rp.Method == "CONNECT" && rp.Protocol == "" { - url_ = &url.URL{Host: rp.Authority} - requestURI = rp.Authority // mimic HTTP/1 server behavior - } else { - var err error - url_, err = url.ParseRequestURI(rp.Path) - if err != nil { - return ServerRequestResult{ - InvalidReason: "bad_path", - } - } - requestURI = rp.Path - } - - return ServerRequestResult{ - URL: url_, - NeedsContinue: needsContinue, - RequestURI: requestURI, - Trailer: trailer, - } -} diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go index 84fcc32..8eedb84 100644 --- a/vendor/golang.org/x/net/internal/socks/socks.go +++ b/vendor/golang.org/x/net/internal/socks/socks.go @@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancelation if + // TODO(mikio): handle IO deadlines and cancellation if // necessary if _, err := rw.Write(b); err != nil { return err diff --git a/vendor/golang.org/x/oauth2/.travis.yml b/vendor/golang.org/x/oauth2/.travis.yml new file mode 100644 index 0000000..fa139db --- /dev/null +++ b/vendor/golang.org/x/oauth2/.travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + - tip + +install: + - export GOPATH="$HOME/gopath" + - mkdir -p "$GOPATH/src/golang.org/x" + - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2" + - go get -v -t -d golang.org/x/oauth2/... + +script: + - go test -v golang.org/x/oauth2/... diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/vendor/golang.org/x/oauth2/CONTRIBUTING.md new file mode 100644 index 0000000..dfbed62 --- /dev/null +++ b/vendor/golang.org/x/oauth2/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + +## Filing issues + +When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. +The gophers there will answer or ask you to file an issue if you've tripped over a bug. + +## Contributing code + +Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) +before sending patches. + +Unless otherwise noted, the Go source files are distributed under +the BSD-style license found in the LICENSE file. diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/oauth2/LICENSE similarity index 100% rename from vendor/golang.org/x/mod/LICENSE rename to vendor/golang.org/x/oauth2/LICENSE diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md new file mode 100644 index 0000000..48dbb9d --- /dev/null +++ b/vendor/golang.org/x/oauth2/README.md @@ -0,0 +1,35 @@ +# OAuth2 for Go + +[![Go Reference](https://pkg.go.dev/badge/golang.org/x/oauth2.svg)](https://pkg.go.dev/golang.org/x/oauth2) +[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) + +oauth2 package contains a client implementation for OAuth 2.0 spec. + +See pkg.go.dev for further documentation and examples. + +* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) +* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google) + +## Policy for new endpoints + +We no longer accept new provider-specific packages in this repo if all +they do is add a single endpoint variable. If you just want to add a +single endpoint, add it to the +[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints) +package. + +## Report Issues / Send Patches + +The main issue tracker for the oauth2 repository is located at +https://github.com/golang/oauth2/issues. + +This repository uses Gerrit for code changes. To learn how to submit changes to +this repository, see https://go.dev/doc/contribute. + +The git repository is https://go.googlesource.com/oauth2. + +Note: + +* Excluding trivial changes, all contributions should be connected to an existing issue. +* API changes must go through the [change proposal process](https://go.dev/s/proposal-process) before they can be accepted. +* The code owners are listed at [dev.golang.org/owners](https://dev.golang.org/owners#:~:text=x/oauth2). diff --git a/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go b/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go new file mode 100644 index 0000000..e86346e --- /dev/null +++ b/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go @@ -0,0 +1,124 @@ +// 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 clientcredentials implements the OAuth2.0 "client credentials" token flow, +// also known as the "two-legged OAuth 2.0". +// +// This should be used when the client is acting on its own behalf or when the client +// is the resource owner. It may also be used when requesting access to protected +// resources based on an authorization previously arranged with the authorization +// server. +// +// See https://tools.ietf.org/html/rfc6749#section-4.4 +package clientcredentials // import "golang.org/x/oauth2/clientcredentials" + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/internal" +) + +// Config describes a 2-legged OAuth2 flow, with both the +// client application information and the server's endpoint URLs. +type Config struct { + // ClientID is the application's ID. + ClientID string + + // ClientSecret is the application's secret. + ClientSecret string + + // TokenURL is the resource server's token endpoint + // URL. This is a constant specific to each server. + TokenURL string + + // Scopes specifies optional requested permissions. + Scopes []string + + // EndpointParams specifies additional parameters for requests to the token endpoint. + EndpointParams url.Values + + // AuthStyle optionally specifies how the endpoint wants the + // client ID & client secret sent. The zero value means to + // auto-detect. + AuthStyle oauth2.AuthStyle + + // authStyleCache caches which auth style to use when Endpoint.AuthStyle is + // the zero value (AuthStyleAutoDetect). + authStyleCache internal.LazyAuthStyleCache +} + +// Token uses client credentials to retrieve a token. +// +// The provided context optionally controls which HTTP client is used. See the [oauth2.HTTPClient] variable. +func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) { + return c.TokenSource(ctx).Token() +} + +// Client returns an HTTP client using the provided token. +// The token will auto-refresh as necessary. +// +// The provided context optionally controls which HTTP client +// is returned. See the [oauth2.HTTPClient] variable. +// +// The returned [http.Client] and its Transport should not be modified. +func (c *Config) Client(ctx context.Context) *http.Client { + return oauth2.NewClient(ctx, c.TokenSource(ctx)) +} + +// TokenSource returns a [oauth2.TokenSource] that returns t until t expires, +// automatically refreshing it as necessary using the provided context and the +// client ID and client secret. +// +// Most users will use [Config.Client] instead. +func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource { + source := &tokenSource{ + ctx: ctx, + conf: c, + } + return oauth2.ReuseTokenSource(nil, source) +} + +type tokenSource struct { + ctx context.Context + conf *Config +} + +// Token refreshes the token by using a new client credentials request. +// tokens received this way do not include a refresh token +func (c *tokenSource) Token() (*oauth2.Token, error) { + v := url.Values{ + "grant_type": {"client_credentials"}, + } + if len(c.conf.Scopes) > 0 { + v.Set("scope", strings.Join(c.conf.Scopes, " ")) + } + for k, p := range c.conf.EndpointParams { + // Allow grant_type to be overridden to allow interoperability with + // non-compliant implementations. + if _, ok := v[k]; ok && k != "grant_type" { + return nil, fmt.Errorf("oauth2: cannot overwrite parameter %q", k) + } + v[k] = p + } + + tk, err := internal.RetrieveToken(c.ctx, c.conf.ClientID, c.conf.ClientSecret, c.conf.TokenURL, v, internal.AuthStyle(c.conf.AuthStyle), c.conf.authStyleCache.Get()) + if err != nil { + if rErr, ok := err.(*internal.RetrieveError); ok { + return nil, (*oauth2.RetrieveError)(rErr) + } + return nil, err + } + t := &oauth2.Token{ + AccessToken: tk.AccessToken, + TokenType: tk.TokenType, + RefreshToken: tk.RefreshToken, + Expiry: tk.Expiry, + } + return t.WithExtra(tk.Raw), nil +} diff --git a/vendor/golang.org/x/oauth2/deviceauth.go b/vendor/golang.org/x/oauth2/deviceauth.go new file mode 100644 index 0000000..e99c92f --- /dev/null +++ b/vendor/golang.org/x/oauth2/deviceauth.go @@ -0,0 +1,198 @@ +package oauth2 + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "golang.org/x/oauth2/internal" +) + +// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5 +const ( + errAuthorizationPending = "authorization_pending" + errSlowDown = "slow_down" + errAccessDenied = "access_denied" + errExpiredToken = "expired_token" +) + +// DeviceAuthResponse describes a successful RFC 8628 Device Authorization Response +// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2 +type DeviceAuthResponse struct { + // DeviceCode + DeviceCode string `json:"device_code"` + // UserCode is the code the user should enter at the verification uri + UserCode string `json:"user_code"` + // VerificationURI is where user should enter the user code + VerificationURI string `json:"verification_uri"` + // VerificationURIComplete (if populated) includes the user code in the verification URI. This is typically shown to the user in non-textual form, such as a QR code. + VerificationURIComplete string `json:"verification_uri_complete,omitempty"` + // Expiry is when the device code and user code expire + Expiry time.Time `json:"expires_in,omitempty"` + // Interval is the duration in seconds that Poll should wait between requests + Interval int64 `json:"interval,omitempty"` +} + +func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) { + type Alias DeviceAuthResponse + var expiresIn int64 + if !d.Expiry.IsZero() { + expiresIn = int64(time.Until(d.Expiry).Seconds()) + } + return json.Marshal(&struct { + ExpiresIn int64 `json:"expires_in,omitempty"` + *Alias + }{ + ExpiresIn: expiresIn, + Alias: (*Alias)(&d), + }) + +} + +func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error { + type Alias DeviceAuthResponse + aux := &struct { + ExpiresIn int64 `json:"expires_in"` + // workaround misspelling of verification_uri + VerificationURL string `json:"verification_url"` + *Alias + }{ + Alias: (*Alias)(c), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + if aux.ExpiresIn != 0 { + c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn)) + } + if c.VerificationURI == "" { + c.VerificationURI = aux.VerificationURL + } + return nil +} + +// DeviceAuth returns a device auth struct which contains a device code +// and authorization information provided for users to enter on another device. +func (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) { + // https://datatracker.ietf.org/doc/html/rfc8628#section-3.1 + v := url.Values{ + "client_id": {c.ClientID}, + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + for _, opt := range opts { + opt.setValue(v) + } + return retrieveDeviceAuth(ctx, c, v) +} + +func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) { + if c.Endpoint.DeviceAuthURL == "" { + return nil, errors.New("endpoint missing DeviceAuthURL") + } + + req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Accept", "application/json") + + t := time.Now() + r, err := internal.ContextClient(ctx).Do(req) + if err != nil { + return nil, err + } + + body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) + if err != nil { + return nil, fmt.Errorf("oauth2: cannot auth device: %v", err) + } + if code := r.StatusCode; code < 200 || code > 299 { + return nil, &RetrieveError{ + Response: r, + Body: body, + } + } + + da := &DeviceAuthResponse{} + err = json.Unmarshal(body, &da) + if err != nil { + return nil, fmt.Errorf("unmarshal %s", err) + } + + if !da.Expiry.IsZero() { + // Make a small adjustment to account for time taken by the request + da.Expiry = da.Expiry.Add(-time.Since(t)) + } + + return da, nil +} + +// DeviceAccessToken polls the server to exchange a device code for a token. +func (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) { + if !da.Expiry.IsZero() { + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, da.Expiry) + defer cancel() + } + + // https://datatracker.ietf.org/doc/html/rfc8628#section-3.4 + v := url.Values{ + "client_id": {c.ClientID}, + "grant_type": {"urn:ietf:params:oauth:grant-type:device_code"}, + "device_code": {da.DeviceCode}, + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + for _, opt := range opts { + opt.setValue(v) + } + + // "If no value is provided, clients MUST use 5 as the default." + // https://datatracker.ietf.org/doc/html/rfc8628#section-3.2 + interval := da.Interval + if interval == 0 { + interval = 5 + } + + ticker := time.NewTicker(time.Duration(interval) * time.Second) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-ticker.C: + tok, err := retrieveToken(ctx, c, v) + if err == nil { + return tok, nil + } + + e, ok := err.(*RetrieveError) + if !ok { + return nil, err + } + switch e.ErrorCode { + case errSlowDown: + // https://datatracker.ietf.org/doc/html/rfc8628#section-3.5 + // "the interval MUST be increased by 5 seconds for this and all subsequent requests" + interval += 5 + ticker.Reset(time.Duration(interval) * time.Second) + case errAuthorizationPending: + // Do nothing. + case errAccessDenied, errExpiredToken: + fallthrough + default: + return tok, err + } + } + } +} diff --git a/vendor/golang.org/x/oauth2/internal/doc.go b/vendor/golang.org/x/oauth2/internal/doc.go new file mode 100644 index 0000000..8c7c475 --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/doc.go @@ -0,0 +1,6 @@ +// 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 internal contains support packages for [golang.org/x/oauth2]. +package internal diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go new file mode 100644 index 0000000..71ea6ad --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/oauth2.go @@ -0,0 +1,37 @@ +// 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 internal + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" +) + +// ParseKey converts the binary contents of a private key file +// to an [*rsa.PrivateKey]. It detects whether the private key is in a +// PEM container or not. If so, it extracts the private key +// from PEM container before conversion. It only supports PEM +// containers with no passphrase. +func ParseKey(key []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(key) + if block != nil { + key = block.Bytes + } + parsedKey, err := x509.ParsePKCS8PrivateKey(key) + if err != nil { + parsedKey, err = x509.ParsePKCS1PrivateKey(key) + if err != nil { + return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v", err) + } + } + parsed, ok := parsedKey.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("private key is invalid") + } + return parsed, nil +} diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go new file mode 100644 index 0000000..8389f24 --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/token.go @@ -0,0 +1,356 @@ +// 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 internal + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "mime" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" +) + +// Token represents the credentials used to authorize +// the requests to access protected resources on the OAuth 2.0 +// provider's backend. +// +// This type is a mirror of [golang.org/x/oauth2.Token] and exists to break +// an otherwise-circular dependency. Other internal packages +// should convert this Token into an [golang.org/x/oauth2.Token] before use. +type Token struct { + // AccessToken is the token that authorizes and authenticates + // the requests. + AccessToken string + + // TokenType is the type of token. + // The Type method returns either this or "Bearer", the default. + TokenType string + + // RefreshToken is a token that's used by the application + // (as opposed to the user) to refresh the access token + // if it expires. + RefreshToken string + + // Expiry is the optional expiration time of the access token. + // + // If zero, TokenSource implementations will reuse the same + // token forever and RefreshToken or equivalent + // mechanisms for that TokenSource will not be used. + Expiry time.Time + + // ExpiresIn is the OAuth2 wire format "expires_in" field, + // which specifies how many seconds later the token expires, + // relative to an unknown time base approximately around "now". + // It is the application's responsibility to populate + // `Expiry` from `ExpiresIn` when required. + ExpiresIn int64 `json:"expires_in,omitempty"` + + // Raw optionally contains extra metadata from the server + // when updating a token. + Raw any +} + +// tokenJSON is the struct representing the HTTP response from OAuth2 +// providers returning a token or error in JSON form. +// https://datatracker.ietf.org/doc/html/rfc6749#section-5.1 +type tokenJSON struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number + // error fields + // https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 + ErrorCode string `json:"error"` + ErrorDescription string `json:"error_description"` + ErrorURI string `json:"error_uri"` +} + +func (e *tokenJSON) expiry() (t time.Time) { + if v := e.ExpiresIn; v != 0 { + return time.Now().Add(time.Duration(v) * time.Second) + } + return +} + +type expirationTime int32 + +func (e *expirationTime) UnmarshalJSON(b []byte) error { + if len(b) == 0 || string(b) == "null" { + return nil + } + var n json.Number + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + i, err := n.Int64() + if err != nil { + return err + } + if i > math.MaxInt32 { + i = math.MaxInt32 + } + *e = expirationTime(i) + return nil +} + +// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type. +type AuthStyle int + +const ( + AuthStyleUnknown AuthStyle = 0 + AuthStyleInParams AuthStyle = 1 + AuthStyleInHeader AuthStyle = 2 +) + +// LazyAuthStyleCache is a backwards compatibility compromise to let Configs +// have a lazily-initialized AuthStyleCache. +// +// The two users of this, oauth2.Config and oauth2/clientcredentials.Config, +// both would ideally just embed an unexported AuthStyleCache but because both +// were historically allowed to be copied by value we can't retroactively add an +// uncopyable Mutex to them. +// +// We could use an atomic.Pointer, but that was added recently enough (in Go +// 1.18) that we'd break Go 1.17 users where the tests as of 2023-08-03 +// still pass. By using an atomic.Value, it supports both Go 1.17 and +// copying by value, even if that's not ideal. +type LazyAuthStyleCache struct { + v atomic.Value // of *AuthStyleCache +} + +func (lc *LazyAuthStyleCache) Get() *AuthStyleCache { + if c, ok := lc.v.Load().(*AuthStyleCache); ok { + return c + } + c := new(AuthStyleCache) + if !lc.v.CompareAndSwap(nil, c) { + c = lc.v.Load().(*AuthStyleCache) + } + return c +} + +type authStyleCacheKey struct { + url string + clientID string +} + +// AuthStyleCache is the set of tokenURLs we've successfully used via +// RetrieveToken and which style auth we ended up using. +// It's called a cache, but it doesn't (yet?) shrink. It's expected that +// the set of OAuth2 servers a program contacts over time is fixed and +// small. +type AuthStyleCache struct { + mu sync.Mutex + m map[authStyleCacheKey]AuthStyle +} + +// lookupAuthStyle reports which auth style we last used with tokenURL +// when calling RetrieveToken and whether we have ever done so. +func (c *AuthStyleCache) lookupAuthStyle(tokenURL, clientID string) (style AuthStyle, ok bool) { + c.mu.Lock() + defer c.mu.Unlock() + style, ok = c.m[authStyleCacheKey{tokenURL, clientID}] + return +} + +// setAuthStyle adds an entry to authStyleCache, documented above. +func (c *AuthStyleCache) setAuthStyle(tokenURL, clientID string, v AuthStyle) { + c.mu.Lock() + defer c.mu.Unlock() + if c.m == nil { + c.m = make(map[authStyleCacheKey]AuthStyle) + } + c.m[authStyleCacheKey{tokenURL, clientID}] = v +} + +// newTokenRequest returns a new *http.Request to retrieve a new token +// from tokenURL using the provided clientID, clientSecret, and POST +// body parameters. +// +// inParams is whether the clientID & clientSecret should be encoded +// as the POST body. An 'inParams' value of true means to send it in +// the POST body (along with any values in v); false means to send it +// in the Authorization header. +func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) { + if authStyle == AuthStyleInParams { + v = cloneURLValues(v) + if clientID != "" { + v.Set("client_id", clientID) + } + if clientSecret != "" { + v.Set("client_secret", clientSecret) + } + } + req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + if authStyle == AuthStyleInHeader { + req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret)) + } + return req, nil +} + +func cloneURLValues(v url.Values) url.Values { + v2 := make(url.Values, len(v)) + for k, vv := range v { + v2[k] = append([]string(nil), vv...) + } + return v2 +} + +func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle, styleCache *AuthStyleCache) (*Token, error) { + needsAuthStyleProbe := authStyle == AuthStyleUnknown + if needsAuthStyleProbe { + if style, ok := styleCache.lookupAuthStyle(tokenURL, clientID); ok { + authStyle = style + needsAuthStyleProbe = false + } else { + authStyle = AuthStyleInHeader // the first way we'll try + } + } + req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle) + if err != nil { + return nil, err + } + token, err := doTokenRoundTrip(ctx, req) + if err != nil && needsAuthStyleProbe { + // If we get an error, assume the server wants the + // clientID & clientSecret in a different form. + // See https://code.google.com/p/goauth2/issues/detail?id=31 for background. + // In summary: + // - Reddit only accepts client secret in the Authorization header + // - Dropbox accepts either it in URL param or Auth header, but not both. + // - Google only accepts URL param (not spec compliant?), not Auth header + // - Stripe only accepts client secret in Auth header with Bearer method, not Basic + // + // We used to maintain a big table in this code of all the sites and which way + // they went, but maintaining it didn't scale & got annoying. + // So just try both ways. + authStyle = AuthStyleInParams // the second way we'll try + req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle) + token, err = doTokenRoundTrip(ctx, req) + } + if needsAuthStyleProbe && err == nil { + styleCache.setAuthStyle(tokenURL, clientID, authStyle) + } + // Don't overwrite `RefreshToken` with an empty value + // if this was a token refreshing request. + if token != nil && token.RefreshToken == "" { + token.RefreshToken = v.Get("refresh_token") + } + return token, err +} + +func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) { + r, err := ContextClient(ctx).Do(req.WithContext(ctx)) + if err != nil { + return nil, err + } + body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) + r.Body.Close() + if err != nil { + return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) + } + + failureStatus := r.StatusCode < 200 || r.StatusCode > 299 + retrieveError := &RetrieveError{ + Response: r, + Body: body, + // attempt to populate error detail below + } + + var token *Token + content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type")) + switch content { + case "application/x-www-form-urlencoded", "text/plain": + // some endpoints return a query string + vals, err := url.ParseQuery(string(body)) + if err != nil { + if failureStatus { + return nil, retrieveError + } + return nil, fmt.Errorf("oauth2: cannot parse response: %v", err) + } + retrieveError.ErrorCode = vals.Get("error") + retrieveError.ErrorDescription = vals.Get("error_description") + retrieveError.ErrorURI = vals.Get("error_uri") + token = &Token{ + AccessToken: vals.Get("access_token"), + TokenType: vals.Get("token_type"), + RefreshToken: vals.Get("refresh_token"), + Raw: vals, + } + e := vals.Get("expires_in") + expires, _ := strconv.Atoi(e) + if expires != 0 { + token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) + } + default: + var tj tokenJSON + if err = json.Unmarshal(body, &tj); err != nil { + if failureStatus { + return nil, retrieveError + } + return nil, fmt.Errorf("oauth2: cannot parse json: %v", err) + } + retrieveError.ErrorCode = tj.ErrorCode + retrieveError.ErrorDescription = tj.ErrorDescription + retrieveError.ErrorURI = tj.ErrorURI + token = &Token{ + AccessToken: tj.AccessToken, + TokenType: tj.TokenType, + RefreshToken: tj.RefreshToken, + Expiry: tj.expiry(), + ExpiresIn: int64(tj.ExpiresIn), + Raw: make(map[string]any), + } + json.Unmarshal(body, &token.Raw) // no error checks for optional fields + } + // according to spec, servers should respond status 400 in error case + // https://www.rfc-editor.org/rfc/rfc6749#section-5.2 + // but some unorthodox servers respond 200 in error case + if failureStatus || retrieveError.ErrorCode != "" { + return nil, retrieveError + } + if token.AccessToken == "" { + return nil, errors.New("oauth2: server response missing access_token") + } + return token, nil +} + +// mirrors oauth2.RetrieveError +type RetrieveError struct { + Response *http.Response + Body []byte + ErrorCode string + ErrorDescription string + ErrorURI string +} + +func (r *RetrieveError) Error() string { + if r.ErrorCode != "" { + s := fmt.Sprintf("oauth2: %q", r.ErrorCode) + if r.ErrorDescription != "" { + s += fmt.Sprintf(" %q", r.ErrorDescription) + } + if r.ErrorURI != "" { + s += fmt.Sprintf(" %q", r.ErrorURI) + } + return s + } + return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body) +} diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go new file mode 100644 index 0000000..afc0aeb --- /dev/null +++ b/vendor/golang.org/x/oauth2/internal/transport.go @@ -0,0 +1,28 @@ +// 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 internal + +import ( + "context" + "net/http" +) + +// HTTPClient is the context key to use with [context.WithValue] +// to associate an [*http.Client] value with a context. +var HTTPClient ContextKey + +// ContextKey is just an empty struct. It exists so HTTPClient can be +// an immutable public variable with a unique type. It's immutable +// because nobody else can create a ContextKey, being unexported. +type ContextKey struct{} + +func ContextClient(ctx context.Context) *http.Client { + if ctx != nil { + if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { + return hc + } + } + return http.DefaultClient +} diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go new file mode 100644 index 0000000..3e3b630 --- /dev/null +++ b/vendor/golang.org/x/oauth2/oauth2.go @@ -0,0 +1,423 @@ +// 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 oauth2 provides support for making +// OAuth2 authorized and authenticated HTTP requests, +// as specified in RFC 6749. +// It can additionally grant authorization with Bearer JWT. +package oauth2 // import "golang.org/x/oauth2" + +import ( + "context" + "errors" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "golang.org/x/oauth2/internal" +) + +// NoContext is the default context you should supply if not using +// your own [context.Context]. +// +// Deprecated: Use [context.Background] or [context.TODO] instead. +var NoContext = context.TODO() + +// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op. +// +// Deprecated: this function no longer does anything. Caller code that +// wants to avoid potential extra HTTP requests made during +// auto-probing of the provider's auth style should set +// Endpoint.AuthStyle. +func RegisterBrokenAuthHeaderProvider(tokenURL string) {} + +// Config describes a typical 3-legged OAuth2 flow, with both the +// client application information and the server's endpoint URLs. +// For the client credentials 2-legged OAuth2 flow, see the +// [golang.org/x/oauth2/clientcredentials] package. +type Config struct { + // ClientID is the application's ID. + ClientID string + + // ClientSecret is the application's secret. + ClientSecret string + + // Endpoint contains the authorization server's token endpoint + // URLs. These are constants specific to each server and are + // often available via site-specific packages, such as + // google.Endpoint or github.Endpoint. + Endpoint Endpoint + + // RedirectURL is the URL to redirect users going through + // the OAuth flow, after the resource owner's URLs. + RedirectURL string + + // Scopes specifies optional requested permissions. + Scopes []string + + // authStyleCache caches which auth style to use when Endpoint.AuthStyle is + // the zero value (AuthStyleAutoDetect). + authStyleCache internal.LazyAuthStyleCache +} + +// A TokenSource is anything that can return a token. +type TokenSource interface { + // Token returns a token or an error. + // Token must be safe for concurrent use by multiple goroutines. + // The returned Token must not be modified. + Token() (*Token, error) +} + +// Endpoint represents an OAuth 2.0 provider's authorization and token +// endpoint URLs. +type Endpoint struct { + AuthURL string + DeviceAuthURL string + TokenURL string + + // AuthStyle optionally specifies how the endpoint wants the + // client ID & client secret sent. The zero value means to + // auto-detect. + AuthStyle AuthStyle +} + +// AuthStyle represents how requests for tokens are authenticated +// to the server. +type AuthStyle int + +const ( + // AuthStyleAutoDetect means to auto-detect which authentication + // style the provider wants by trying both ways and caching + // the successful way for the future. + AuthStyleAutoDetect AuthStyle = 0 + + // AuthStyleInParams sends the "client_id" and "client_secret" + // in the POST body as application/x-www-form-urlencoded parameters. + AuthStyleInParams AuthStyle = 1 + + // AuthStyleInHeader sends the client_id and client_password + // using HTTP Basic Authorization. This is an optional style + // described in the OAuth2 RFC 6749 section 2.3.1. + AuthStyleInHeader AuthStyle = 2 +) + +var ( + // AccessTypeOnline and AccessTypeOffline are options passed + // to the Options.AuthCodeURL method. They modify the + // "access_type" field that gets sent in the URL returned by + // AuthCodeURL. + // + // Online is the default if neither is specified. If your + // application needs to refresh access tokens when the user + // is not present at the browser, then use offline. This will + // result in your application obtaining a refresh token the + // first time your application exchanges an authorization + // code for a user. + AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online") + AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline") + + // ApprovalForce forces the users to view the consent dialog + // and confirm the permissions request at the URL returned + // from AuthCodeURL, even if they've already done so. + ApprovalForce AuthCodeOption = SetAuthURLParam("prompt", "consent") +) + +// An AuthCodeOption is passed to Config.AuthCodeURL. +type AuthCodeOption interface { + setValue(url.Values) +} + +type setParam struct{ k, v string } + +func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) } + +// SetAuthURLParam builds an [AuthCodeOption] which passes key/value parameters +// to a provider's authorization endpoint. +func SetAuthURLParam(key, value string) AuthCodeOption { + return setParam{key, value} +} + +// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page +// that asks for permissions for the required scopes explicitly. +// +// State is an opaque value used by the client to maintain state between the +// request and callback. The authorization server includes this value when +// redirecting the user agent back to the client. +// +// Opts may include [AccessTypeOnline] or [AccessTypeOffline], as well +// as [ApprovalForce]. +// +// To protect against CSRF attacks, opts should include a PKCE challenge +// (S256ChallengeOption). Not all servers support PKCE. An alternative is to +// generate a random state parameter and verify it after exchange. +// See https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 (predating +// PKCE), https://www.oauth.com/oauth2-servers/pkce/ and +// https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.html#name-cross-site-request-forgery (describing both approaches) +func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { + var buf strings.Builder + buf.WriteString(c.Endpoint.AuthURL) + v := url.Values{ + "response_type": {"code"}, + "client_id": {c.ClientID}, + } + if c.RedirectURL != "" { + v.Set("redirect_uri", c.RedirectURL) + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + if state != "" { + v.Set("state", state) + } + for _, opt := range opts { + opt.setValue(v) + } + if strings.Contains(c.Endpoint.AuthURL, "?") { + buf.WriteByte('&') + } else { + buf.WriteByte('?') + } + buf.WriteString(v.Encode()) + return buf.String() +} + +// PasswordCredentialsToken converts a resource owner username and password +// pair into a token. +// +// Per the RFC, this grant type should only be used "when there is a high +// degree of trust between the resource owner and the client (e.g., the client +// is part of the device operating system or a highly privileged application), +// and when other authorization grant types are not available." +// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info. +// +// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable. +func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) { + v := url.Values{ + "grant_type": {"password"}, + "username": {username}, + "password": {password}, + } + if len(c.Scopes) > 0 { + v.Set("scope", strings.Join(c.Scopes, " ")) + } + return retrieveToken(ctx, c, v) +} + +// Exchange converts an authorization code into a token. +// +// It is used after a resource provider redirects the user back +// to the Redirect URI (the URL obtained from AuthCodeURL). +// +// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable. +// +// The code will be in the [http.Request.FormValue]("code"). Before +// calling Exchange, be sure to validate [http.Request.FormValue]("state") if you are +// using it to protect against CSRF attacks. +// +// If using PKCE to protect against CSRF attacks, opts should include a +// VerifierOption. +func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) { + v := url.Values{ + "grant_type": {"authorization_code"}, + "code": {code}, + } + if c.RedirectURL != "" { + v.Set("redirect_uri", c.RedirectURL) + } + for _, opt := range opts { + opt.setValue(v) + } + return retrieveToken(ctx, c, v) +} + +// Client returns an HTTP client using the provided token. +// The token will auto-refresh as necessary. The underlying +// HTTP transport will be obtained using the provided context. +// The returned client and its Transport should not be modified. +func (c *Config) Client(ctx context.Context, t *Token) *http.Client { + return NewClient(ctx, c.TokenSource(ctx, t)) +} + +// TokenSource returns a [TokenSource] that returns t until t expires, +// automatically refreshing it as necessary using the provided context. +// +// Most users will use [Config.Client] instead. +func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource { + tkr := &tokenRefresher{ + ctx: ctx, + conf: c, + } + if t != nil { + tkr.refreshToken = t.RefreshToken + } + return &reuseTokenSource{ + t: t, + new: tkr, + } +} + +// tokenRefresher is a TokenSource that makes "grant_type=refresh_token" +// HTTP requests to renew a token using a RefreshToken. +type tokenRefresher struct { + ctx context.Context // used to get HTTP requests + conf *Config + refreshToken string +} + +// WARNING: Token is not safe for concurrent access, as it +// updates the tokenRefresher's refreshToken field. +// Within this package, it is used by reuseTokenSource which +// synchronizes calls to this method with its own mutex. +func (tf *tokenRefresher) Token() (*Token, error) { + if tf.refreshToken == "" { + return nil, errors.New("oauth2: token expired and refresh token is not set") + } + + tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{ + "grant_type": {"refresh_token"}, + "refresh_token": {tf.refreshToken}, + }) + + if err != nil { + return nil, err + } + if tf.refreshToken != tk.RefreshToken { + tf.refreshToken = tk.RefreshToken + } + return tk, nil +} + +// reuseTokenSource is a TokenSource that holds a single token in memory +// and validates its expiry before each call to retrieve it with +// Token. If it's expired, it will be auto-refreshed using the +// new TokenSource. +type reuseTokenSource struct { + new TokenSource // called when t is expired. + + mu sync.Mutex // guards t + t *Token + + expiryDelta time.Duration +} + +// Token returns the current token if it's still valid, else will +// refresh the current token and return the new one. +func (s *reuseTokenSource) Token() (*Token, error) { + s.mu.Lock() + defer s.mu.Unlock() + if s.t.Valid() { + return s.t, nil + } + t, err := s.new.Token() + if err != nil { + return nil, err + } + t.expiryDelta = s.expiryDelta + s.t = t + return t, nil +} + +// StaticTokenSource returns a [TokenSource] that always returns the same token. +// Because the provided token t is never refreshed, StaticTokenSource is only +// useful for tokens that never expire. +func StaticTokenSource(t *Token) TokenSource { + return staticTokenSource{t} +} + +// staticTokenSource is a TokenSource that always returns the same Token. +type staticTokenSource struct { + t *Token +} + +func (s staticTokenSource) Token() (*Token, error) { + return s.t, nil +} + +// HTTPClient is the context key to use with [context.WithValue] +// to associate a [*http.Client] value with a context. +var HTTPClient internal.ContextKey + +// NewClient creates an [*http.Client] from a [context.Context] and [TokenSource]. +// The returned client is not valid beyond the lifetime of the context. +// +// Note that if a custom [*http.Client] is provided via the [context.Context] it +// is used only for token acquisition and is not used to configure the +// [*http.Client] returned from NewClient. +// +// As a special case, if src is nil, a non-OAuth2 client is returned +// using the provided context. This exists to support related OAuth2 +// packages. +func NewClient(ctx context.Context, src TokenSource) *http.Client { + if src == nil { + return internal.ContextClient(ctx) + } + cc := internal.ContextClient(ctx) + return &http.Client{ + Transport: &Transport{ + Base: cc.Transport, + Source: ReuseTokenSource(nil, src), + }, + CheckRedirect: cc.CheckRedirect, + Jar: cc.Jar, + Timeout: cc.Timeout, + } +} + +// ReuseTokenSource returns a [TokenSource] which repeatedly returns the +// same token as long as it's valid, starting with t. +// When its cached token is invalid, a new token is obtained from src. +// +// ReuseTokenSource is typically used to reuse tokens from a cache +// (such as a file on disk) between runs of a program, rather than +// obtaining new tokens unnecessarily. +// +// The initial token t may be nil, in which case the [TokenSource] is +// wrapped in a caching version if it isn't one already. This also +// means it's always safe to wrap ReuseTokenSource around any other +// [TokenSource] without adverse effects. +func ReuseTokenSource(t *Token, src TokenSource) TokenSource { + // Don't wrap a reuseTokenSource in itself. That would work, + // but cause an unnecessary number of mutex operations. + // Just build the equivalent one. + if rt, ok := src.(*reuseTokenSource); ok { + if t == nil { + // Just use it directly. + return rt + } + src = rt.new + } + return &reuseTokenSource{ + t: t, + new: src, + } +} + +// ReuseTokenSourceWithExpiry returns a [TokenSource] that acts in the same manner as the +// [TokenSource] returned by [ReuseTokenSource], except the expiry buffer is +// configurable. The expiration time of a token is calculated as +// t.Expiry.Add(-earlyExpiry). +func ReuseTokenSourceWithExpiry(t *Token, src TokenSource, earlyExpiry time.Duration) TokenSource { + // Don't wrap a reuseTokenSource in itself. That would work, + // but cause an unnecessary number of mutex operations. + // Just build the equivalent one. + if rt, ok := src.(*reuseTokenSource); ok { + if t == nil { + // Just use it directly, but set the expiryDelta to earlyExpiry, + // so the behavior matches what the user expects. + rt.expiryDelta = earlyExpiry + return rt + } + src = rt.new + } + if t != nil { + t.expiryDelta = earlyExpiry + } + return &reuseTokenSource{ + t: t, + new: src, + expiryDelta: earlyExpiry, + } +} diff --git a/vendor/golang.org/x/oauth2/pkce.go b/vendor/golang.org/x/oauth2/pkce.go new file mode 100644 index 0000000..cea8374 --- /dev/null +++ b/vendor/golang.org/x/oauth2/pkce.go @@ -0,0 +1,69 @@ +// 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. + +package oauth2 + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "net/url" +) + +const ( + codeChallengeKey = "code_challenge" + codeChallengeMethodKey = "code_challenge_method" + codeVerifierKey = "code_verifier" +) + +// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness. +// This follows recommendations in RFC 7636. +// +// A fresh verifier should be generated for each authorization. +// The resulting verifier should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth] +// with [S256ChallengeOption], and to [Config.Exchange] or [Config.DeviceAccessToken] +// with [VerifierOption]. +func GenerateVerifier() string { + // "RECOMMENDED that the output of a suitable random number generator be + // used to create a 32-octet sequence. The octet sequence is then + // base64url-encoded to produce a 43-octet URL-safe string to use as the + // code verifier." + // https://datatracker.ietf.org/doc/html/rfc7636#section-4.1 + data := make([]byte, 32) + if _, err := rand.Read(data); err != nil { + panic(err) + } + return base64.RawURLEncoding.EncodeToString(data) +} + +// VerifierOption returns a PKCE code verifier [AuthCodeOption]. It should only be +// passed to [Config.Exchange] or [Config.DeviceAccessToken]. +func VerifierOption(verifier string) AuthCodeOption { + return setParam{k: codeVerifierKey, v: verifier} +} + +// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256. +// +// Prefer to use [S256ChallengeOption] where possible. +func S256ChallengeFromVerifier(verifier string) string { + sha := sha256.Sum256([]byte(verifier)) + return base64.RawURLEncoding.EncodeToString(sha[:]) +} + +// S256ChallengeOption derives a PKCE code challenge derived from verifier with +// method S256. It should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth] +// only. +func S256ChallengeOption(verifier string) AuthCodeOption { + return challengeOption{ + challenge_method: "S256", + challenge: S256ChallengeFromVerifier(verifier), + } +} + +type challengeOption struct{ challenge_method, challenge string } + +func (p challengeOption) setValue(m url.Values) { + m.Set(codeChallengeMethodKey, p.challenge_method) + m.Set(codeChallengeKey, p.challenge) +} diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go new file mode 100644 index 0000000..239ec32 --- /dev/null +++ b/vendor/golang.org/x/oauth2/token.go @@ -0,0 +1,213 @@ +// 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 oauth2 + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "golang.org/x/oauth2/internal" +) + +// defaultExpiryDelta determines how earlier a token should be considered +// expired than its actual expiration time. It is used to avoid late +// expirations due to client-server time mismatches. +const defaultExpiryDelta = 10 * time.Second + +// Token represents the credentials used to authorize +// the requests to access protected resources on the OAuth 2.0 +// provider's backend. +// +// Most users of this package should not access fields of Token +// directly. They're exported mostly for use by related packages +// implementing derivative OAuth2 flows. +type Token struct { + // AccessToken is the token that authorizes and authenticates + // the requests. + AccessToken string `json:"access_token"` + + // TokenType is the type of token. + // The Type method returns either this or "Bearer", the default. + TokenType string `json:"token_type,omitempty"` + + // RefreshToken is a token that's used by the application + // (as opposed to the user) to refresh the access token + // if it expires. + RefreshToken string `json:"refresh_token,omitempty"` + + // Expiry is the optional expiration time of the access token. + // + // If zero, [TokenSource] implementations will reuse the same + // token forever and RefreshToken or equivalent + // mechanisms for that TokenSource will not be used. + Expiry time.Time `json:"expiry,omitempty"` + + // ExpiresIn is the OAuth2 wire format "expires_in" field, + // which specifies how many seconds later the token expires, + // relative to an unknown time base approximately around "now". + // It is the application's responsibility to populate + // `Expiry` from `ExpiresIn` when required. + ExpiresIn int64 `json:"expires_in,omitempty"` + + // raw optionally contains extra metadata from the server + // when updating a token. + raw any + + // expiryDelta is used to calculate when a token is considered + // expired, by subtracting from Expiry. If zero, defaultExpiryDelta + // is used. + expiryDelta time.Duration +} + +// Type returns t.TokenType if non-empty, else "Bearer". +func (t *Token) Type() string { + if strings.EqualFold(t.TokenType, "bearer") { + return "Bearer" + } + if strings.EqualFold(t.TokenType, "mac") { + return "MAC" + } + if strings.EqualFold(t.TokenType, "basic") { + return "Basic" + } + if t.TokenType != "" { + return t.TokenType + } + return "Bearer" +} + +// SetAuthHeader sets the Authorization header to r using the access +// token in t. +// +// This method is unnecessary when using [Transport] or an HTTP Client +// returned by this package. +func (t *Token) SetAuthHeader(r *http.Request) { + r.Header.Set("Authorization", t.Type()+" "+t.AccessToken) +} + +// WithExtra returns a new [Token] that's a clone of t, but using the +// provided raw extra map. This is only intended for use by packages +// implementing derivative OAuth2 flows. +func (t *Token) WithExtra(extra any) *Token { + t2 := new(Token) + *t2 = *t + t2.raw = extra + return t2 +} + +// Extra returns an extra field. +// Extra fields are key-value pairs returned by the server as a +// part of the token retrieval response. +func (t *Token) Extra(key string) any { + if raw, ok := t.raw.(map[string]any); ok { + return raw[key] + } + + vals, ok := t.raw.(url.Values) + if !ok { + return nil + } + + v := vals.Get(key) + switch s := strings.TrimSpace(v); strings.Count(s, ".") { + case 0: // Contains no "."; try to parse as int + if i, err := strconv.ParseInt(s, 10, 64); err == nil { + return i + } + case 1: // Contains a single "."; try to parse as float + if f, err := strconv.ParseFloat(s, 64); err == nil { + return f + } + } + + return v +} + +// timeNow is time.Now but pulled out as a variable for tests. +var timeNow = time.Now + +// expired reports whether the token is expired. +// t must be non-nil. +func (t *Token) expired() bool { + if t.Expiry.IsZero() { + return false + } + + expiryDelta := defaultExpiryDelta + if t.expiryDelta != 0 { + expiryDelta = t.expiryDelta + } + return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow()) +} + +// Valid reports whether t is non-nil, has an AccessToken, and is not expired. +func (t *Token) Valid() bool { + return t != nil && t.AccessToken != "" && !t.expired() +} + +// tokenFromInternal maps an *internal.Token struct into +// a *Token struct. +func tokenFromInternal(t *internal.Token) *Token { + if t == nil { + return nil + } + return &Token{ + AccessToken: t.AccessToken, + TokenType: t.TokenType, + RefreshToken: t.RefreshToken, + Expiry: t.Expiry, + ExpiresIn: t.ExpiresIn, + raw: t.Raw, + } +} + +// retrieveToken takes a *Config and uses that to retrieve an *internal.Token. +// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along +// with an error. +func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) { + tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle), c.authStyleCache.Get()) + if err != nil { + if rErr, ok := err.(*internal.RetrieveError); ok { + return nil, (*RetrieveError)(rErr) + } + return nil, err + } + return tokenFromInternal(tk), nil +} + +// RetrieveError is the error returned when the token endpoint returns a +// non-2XX HTTP status code or populates RFC 6749's 'error' parameter. +// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2 +type RetrieveError struct { + Response *http.Response + // Body is the body that was consumed by reading Response.Body. + // It may be truncated. + Body []byte + // ErrorCode is RFC 6749's 'error' parameter. + ErrorCode string + // ErrorDescription is RFC 6749's 'error_description' parameter. + ErrorDescription string + // ErrorURI is RFC 6749's 'error_uri' parameter. + ErrorURI string +} + +func (r *RetrieveError) Error() string { + if r.ErrorCode != "" { + s := fmt.Sprintf("oauth2: %q", r.ErrorCode) + if r.ErrorDescription != "" { + s += fmt.Sprintf(" %q", r.ErrorDescription) + } + if r.ErrorURI != "" { + s += fmt.Sprintf(" %q", r.ErrorURI) + } + return s + } + return fmt.Sprintf("oauth2: cannot fetch token: %v\nResponse: %s", r.Response.Status, r.Body) +} diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go new file mode 100644 index 0000000..8bbebba --- /dev/null +++ b/vendor/golang.org/x/oauth2/transport.go @@ -0,0 +1,75 @@ +// 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 oauth2 + +import ( + "errors" + "log" + "net/http" + "sync" +) + +// Transport is an [http.RoundTripper] that makes OAuth 2.0 HTTP requests, +// wrapping a base [http.RoundTripper] and adding an Authorization header +// with a token from the supplied [TokenSource]. +// +// Transport is a low-level mechanism. Most code will use the +// higher-level [Config.Client] method instead. +type Transport struct { + // Source supplies the token to add to outgoing requests' + // Authorization headers. + Source TokenSource + + // Base is the base RoundTripper used to make HTTP requests. + // If nil, http.DefaultTransport is used. + Base http.RoundTripper +} + +// RoundTrip authorizes and authenticates the request with an +// access token from Transport's Source. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + reqBodyClosed := false + if req.Body != nil { + defer func() { + if !reqBodyClosed { + req.Body.Close() + } + }() + } + + if t.Source == nil { + return nil, errors.New("oauth2: Transport's Source is nil") + } + token, err := t.Source.Token() + if err != nil { + return nil, err + } + + req2 := req.Clone(req.Context()) + token.SetAuthHeader(req2) + + // req.Body is assumed to be closed by the base RoundTripper. + reqBodyClosed = true + return t.base().RoundTrip(req2) +} + +var cancelOnce sync.Once + +// CancelRequest does nothing. It used to be a legacy cancellation mechanism +// but now only it only logs on first use to warn that it's deprecated. +// +// Deprecated: use contexts for cancellation instead. +func (t *Transport) CancelRequest(req *http.Request) { + cancelOnce.Do(func() { + log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts") + }) +} + +func (t *Transport) base() http.RoundTripper { + if t.Base != nil { + return t.Base + } + return http.DefaultTransport +} diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b832259..f69fd75 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -3,7 +3,7 @@ // 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. +// cancellation 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. @@ -18,7 +18,7 @@ import ( type token struct{} // A Group is a collection of goroutines working on subtasks that are part of -// the same overall task. +// the same overall task. A Group should not be reused for different tasks. // // A zero Group is valid, has no limit on the number of active goroutines, // and does not cancel on error. @@ -46,7 +46,7 @@ func (g *Group) done() { // 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) + ctx, cancel := context.WithCancelCause(ctx) return &Group{cancel: cancel}, ctx } @@ -61,11 +61,14 @@ func (g *Group) Wait() error { } // 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. +// The first call to Go must happen before a Wait. +// It blocks until the new goroutine can be added without the number of +// goroutines in the group exceeding the configured limit. +// +// The first goroutine in the group that returns a non-nil error will +// cancel the associated Context, if any. The error will be returned +// by Wait. func (g *Group) Go(f func() error) { if g.sem != nil { g.sem <- token{} @@ -75,6 +78,18 @@ func (g *Group) Go(f func() error) { go func() { defer g.done() + // It is tempting to propagate panics from f() + // up to the goroutine that calls Wait, but + // it creates more problems than it solves: + // - it delays panics arbitrarily, + // making bugs harder to detect; + // - it turns f's panic stack into a mere value, + // hiding it from crash-monitoring tools; + // - it risks deadlocks that hide the panic entirely, + // if f's panic leaves the program in a state + // that prevents the Wait call from being reached. + // See #53757, #74275, #74304, #74306. + if err := f(); err != nil { g.errOnce.Do(func() { g.err = err @@ -129,8 +144,8 @@ func (g *Group) SetLimit(n int) { 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))) + if active := len(g.sem); active != 0 { + panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", active)) } 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 deleted file mode 100644 index f93c740..0000000 --- a/vendor/golang.org/x/sync/errgroup/go120.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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 deleted file mode 100644 index 88ce334..0000000 --- a/vendor/golang.org/x/sync/errgroup/pre_go120.go +++ /dev/null @@ -1,14 +0,0 @@ -// 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/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 9c105f2..6354199 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -149,6 +149,18 @@ var ARM struct { _ CacheLinePad } +// The booleans in Loong64 contain the correspondingly named cpu feature bit. +// The struct is padded to avoid false sharing. +var Loong64 struct { + _ CacheLinePad + HasLSX bool // support 128-bit vector extension + HasLASX bool // support 256-bit vector extension + HasCRC32 bool // support CRC instruction + HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction + HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} instruction + _ CacheLinePad +} + // MIPS64X contains the supported CPU features of the current mips64/mips64le // platforms. If the current platform is not mips64/mips64le or the current // operating system is not Linux then all feature flags are false. @@ -220,6 +232,17 @@ var RISCV64 struct { HasZba bool // Address generation instructions extension HasZbb bool // Basic bit-manipulation extension HasZbs bool // Single-bit instructions extension + HasZvbb bool // Vector Basic Bit-manipulation + HasZvbc bool // Vector Carryless Multiplication + HasZvkb bool // Vector Cryptography Bit-manipulation + HasZvkt bool // Vector Data-Independent Execution Latency + HasZvkg bool // Vector GCM/GMAC + HasZvkn bool // NIST Algorithm Suite (AES/SHA256/SHA512) + HasZvknc bool // NIST Algorithm Suite with carryless multiply + HasZvkng bool // NIST Algorithm Suite with GCM + HasZvks bool // ShangMi Algorithm Suite + HasZvksc bool // ShangMi Algorithm Suite with carryless multiplication + HasZvksg bool // ShangMi Algorithm Suite with GCM _ CacheLinePad } diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s index 22cc998..3b0450a 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s @@ -9,31 +9,27 @@ // func getisar0() uint64 TEXT ·getisar0(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 0 into x0 - // mrs x0, ID_AA64ISAR0_EL1 = d5380600 - WORD $0xd5380600 + MRS ID_AA64ISAR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getisar1() uint64 TEXT ·getisar1(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 1 into x0 - // mrs x0, ID_AA64ISAR1_EL1 = d5380620 - WORD $0xd5380620 + MRS ID_AA64ISAR1_EL1, R0 MOVD R0, ret+0(FP) RET // func getpfr0() uint64 TEXT ·getpfr0(SB),NOSPLIT,$0-8 // get Processor Feature Register 0 into x0 - // mrs x0, ID_AA64PFR0_EL1 = d5380400 - WORD $0xd5380400 + MRS ID_AA64PFR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getzfr0() uint64 TEXT ·getzfr0(SB),NOSPLIT,$0-8 // get SVE Feature Register 0 into x0 - // mrs x0, ID_AA64ZFR0_EL1 = d5380480 - WORD $0xd5380480 + MRS ID_AA64ZFR0_EL1, R0 MOVD R0, ret+0(FP) RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go new file mode 100644 index 0000000..4f34114 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go @@ -0,0 +1,22 @@ +// Copyright 2025 The Go 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 cpu + +// HWCAP bits. These are exposed by the Linux kernel. +const ( + hwcap_LOONGARCH_LSX = 1 << 4 + hwcap_LOONGARCH_LASX = 1 << 5 +) + +func doinit() { + // TODO: Features that require kernel support like LSX and LASX can + // be detected here once needed in std library or by the compiler. + Loong64.HasLSX = hwcIsSet(hwCap, hwcap_LOONGARCH_LSX) + Loong64.HasLASX = hwcIsSet(hwCap, hwcap_LOONGARCH_LASX) +} + +func hwcIsSet(hwc uint, val uint) bool { + return hwc&val != 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go index 7d902b6..a428dec 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 +//go:build linux && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 package cpu diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go index cb4a0c5..ad74153 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go @@ -58,6 +58,15 @@ const ( riscv_HWPROBE_EXT_ZBA = 0x8 riscv_HWPROBE_EXT_ZBB = 0x10 riscv_HWPROBE_EXT_ZBS = 0x20 + riscv_HWPROBE_EXT_ZVBB = 0x20000 + riscv_HWPROBE_EXT_ZVBC = 0x40000 + riscv_HWPROBE_EXT_ZVKB = 0x80000 + riscv_HWPROBE_EXT_ZVKG = 0x100000 + riscv_HWPROBE_EXT_ZVKNED = 0x200000 + riscv_HWPROBE_EXT_ZVKNHB = 0x800000 + riscv_HWPROBE_EXT_ZVKSED = 0x1000000 + riscv_HWPROBE_EXT_ZVKSH = 0x2000000 + riscv_HWPROBE_EXT_ZVKT = 0x4000000 riscv_HWPROBE_KEY_CPUPERF_0 = 0x5 riscv_HWPROBE_MISALIGNED_FAST = 0x3 riscv_HWPROBE_MISALIGNED_MASK = 0x7 @@ -99,6 +108,20 @@ func doinit() { RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA) RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB) RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS) + RISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB) + RISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC) + RISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB) + RISCV64.HasZvkg = isSet(v, riscv_HWPROBE_EXT_ZVKG) + RISCV64.HasZvkt = isSet(v, riscv_HWPROBE_EXT_ZVKT) + // Cryptography shorthand extensions + RISCV64.HasZvkn = isSet(v, riscv_HWPROBE_EXT_ZVKNED) && + isSet(v, riscv_HWPROBE_EXT_ZVKNHB) && RISCV64.HasZvkb && RISCV64.HasZvkt + RISCV64.HasZvknc = RISCV64.HasZvkn && RISCV64.HasZvbc + RISCV64.HasZvkng = RISCV64.HasZvkn && RISCV64.HasZvkg + RISCV64.HasZvks = isSet(v, riscv_HWPROBE_EXT_ZVKSED) && + isSet(v, riscv_HWPROBE_EXT_ZVKSH) && RISCV64.HasZvkb && RISCV64.HasZvkt + RISCV64.HasZvksc = RISCV64.HasZvks && RISCV64.HasZvbc + RISCV64.HasZvksg = RISCV64.HasZvks && RISCV64.HasZvkg } if pairs[1].key != -1 { v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK diff --git a/vendor/golang.org/x/sys/cpu/cpu_loong64.go b/vendor/golang.org/x/sys/cpu/cpu_loong64.go index 5586358..45ecb29 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_loong64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_loong64.go @@ -8,5 +8,43 @@ package cpu const cacheLineSize = 64 +// Bit fields for CPUCFG registers, Related reference documents: +// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_cpucfg +const ( + // CPUCFG1 bits + cpucfg1_CRC32 = 1 << 25 + + // CPUCFG2 bits + cpucfg2_LAM_BH = 1 << 27 + cpucfg2_LAMCAS = 1 << 28 +) + func initOptions() { + options = []option{ + {Name: "lsx", Feature: &Loong64.HasLSX}, + {Name: "lasx", Feature: &Loong64.HasLASX}, + {Name: "crc32", Feature: &Loong64.HasCRC32}, + {Name: "lam_bh", Feature: &Loong64.HasLAM_BH}, + {Name: "lamcas", Feature: &Loong64.HasLAMCAS}, + } + + // The CPUCFG data on Loong64 only reflects the hardware capabilities, + // not the kernel support status, so features such as LSX and LASX that + // require kernel support cannot be obtained from the CPUCFG data. + // + // These features only require hardware capability support and do not + // require kernel specific support, so they can be obtained directly + // through CPUCFG + cfg1 := get_cpucfg(1) + cfg2 := get_cpucfg(2) + + Loong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32) + Loong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS) + Loong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH) +} + +func get_cpucfg(reg uint32) uint32 + +func cfgIsSet(cfg uint32, val uint32) bool { + return cfg&val != 0 } diff --git a/vendor/golang.org/x/sys/cpu/cpu_loong64.s b/vendor/golang.org/x/sys/cpu/cpu_loong64.s new file mode 100644 index 0000000..71cbaf1 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_loong64.s @@ -0,0 +1,13 @@ +// Copyright 2025 The Go 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" + +// func get_cpucfg(reg uint32) uint32 +TEXT ·get_cpucfg(SB), NOSPLIT|NOFRAME, $0 + MOVW reg+0(FP), R5 + // CPUCFG R5, R4 = 0x00006ca4 + WORD $0x00006ca4 + MOVW R4, ret+8(FP) + RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go index aca3199..0f617ae 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go @@ -16,5 +16,17 @@ func initOptions() { {Name: "zba", Feature: &RISCV64.HasZba}, {Name: "zbb", Feature: &RISCV64.HasZbb}, {Name: "zbs", Feature: &RISCV64.HasZbs}, + // RISC-V Cryptography Extensions + {Name: "zvbb", Feature: &RISCV64.HasZvbb}, + {Name: "zvbc", Feature: &RISCV64.HasZvbc}, + {Name: "zvkb", Feature: &RISCV64.HasZvkb}, + {Name: "zvkg", Feature: &RISCV64.HasZvkg}, + {Name: "zvkt", Feature: &RISCV64.HasZvkt}, + {Name: "zvkn", Feature: &RISCV64.HasZvkn}, + {Name: "zvknc", Feature: &RISCV64.HasZvknc}, + {Name: "zvkng", Feature: &RISCV64.HasZvkng}, + {Name: "zvks", Feature: &RISCV64.HasZvks}, + {Name: "zvksc", Feature: &RISCV64.HasZvksc}, + {Name: "zvksg", Feature: &RISCV64.HasZvksg}, } } diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go index 1e642f3..f5723d4 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_x86.go +++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go @@ -64,6 +64,80 @@ func initOptions() { func archInit() { + // From internal/cpu + const ( + // eax bits + cpuid_AVXVNNI = 1 << 4 + + // ecx bits + cpuid_SSE3 = 1 << 0 + cpuid_PCLMULQDQ = 1 << 1 + cpuid_AVX512VBMI = 1 << 1 + cpuid_AVX512VBMI2 = 1 << 6 + cpuid_SSSE3 = 1 << 9 + cpuid_AVX512GFNI = 1 << 8 + cpuid_AVX512VAES = 1 << 9 + cpuid_AVX512VNNI = 1 << 11 + cpuid_AVX512BITALG = 1 << 12 + cpuid_FMA = 1 << 12 + cpuid_AVX512VPOPCNTDQ = 1 << 14 + cpuid_SSE41 = 1 << 19 + cpuid_SSE42 = 1 << 20 + cpuid_POPCNT = 1 << 23 + cpuid_AES = 1 << 25 + cpuid_OSXSAVE = 1 << 27 + cpuid_AVX = 1 << 28 + + // "Extended Feature Flag" bits returned in EBX for CPUID EAX=0x7 ECX=0x0 + cpuid_BMI1 = 1 << 3 + cpuid_AVX2 = 1 << 5 + cpuid_BMI2 = 1 << 8 + cpuid_ERMS = 1 << 9 + cpuid_AVX512F = 1 << 16 + cpuid_AVX512DQ = 1 << 17 + cpuid_ADX = 1 << 19 + cpuid_AVX512CD = 1 << 28 + cpuid_SHA = 1 << 29 + cpuid_AVX512BW = 1 << 30 + cpuid_AVX512VL = 1 << 31 + + // "Extended Feature Flag" bits returned in ECX for CPUID EAX=0x7 ECX=0x0 + cpuid_AVX512_VBMI = 1 << 1 + cpuid_AVX512_VBMI2 = 1 << 6 + cpuid_GFNI = 1 << 8 + cpuid_AVX512VPCLMULQDQ = 1 << 10 + cpuid_AVX512_BITALG = 1 << 12 + + // edx bits + cpuid_FSRM = 1 << 4 + // edx bits for CPUID 0x80000001 + cpuid_RDTSCP = 1 << 27 + ) + // Additional constants not in internal/cpu + const ( + // eax=1: edx + cpuid_SSE2 = 1 << 26 + // eax=1: ecx + cpuid_CX16 = 1 << 13 + cpuid_RDRAND = 1 << 30 + // eax=7,ecx=0: ebx + cpuid_RDSEED = 1 << 18 + cpuid_AVX512IFMA = 1 << 21 + cpuid_AVX512PF = 1 << 26 + cpuid_AVX512ER = 1 << 27 + // eax=7,ecx=0: edx + cpuid_AVX5124VNNIW = 1 << 2 + cpuid_AVX5124FMAPS = 1 << 3 + cpuid_AMXBF16 = 1 << 22 + cpuid_AMXTile = 1 << 24 + cpuid_AMXInt8 = 1 << 25 + // eax=7,ecx=1: eax + cpuid_AVX512BF16 = 1 << 5 + cpuid_AVXIFMA = 1 << 23 + // eax=7,ecx=1: edx + cpuid_AVXVNNIInt8 = 1 << 4 + ) + Initialized = true maxID, _, _, _ := cpuid(0, 0) @@ -73,90 +147,90 @@ func archInit() { } _, _, ecx1, edx1 := cpuid(1, 0) - X86.HasSSE2 = isSet(26, edx1) + X86.HasSSE2 = isSet(edx1, cpuid_SSE2) - X86.HasSSE3 = isSet(0, ecx1) - X86.HasPCLMULQDQ = isSet(1, ecx1) - X86.HasSSSE3 = isSet(9, ecx1) - X86.HasFMA = isSet(12, ecx1) - X86.HasCX16 = isSet(13, ecx1) - X86.HasSSE41 = isSet(19, ecx1) - X86.HasSSE42 = isSet(20, ecx1) - X86.HasPOPCNT = isSet(23, ecx1) - X86.HasAES = isSet(25, ecx1) - X86.HasOSXSAVE = isSet(27, ecx1) - X86.HasRDRAND = isSet(30, ecx1) + X86.HasSSE3 = isSet(ecx1, cpuid_SSE3) + X86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ) + X86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3) + X86.HasFMA = isSet(ecx1, cpuid_FMA) + X86.HasCX16 = isSet(ecx1, cpuid_CX16) + X86.HasSSE41 = isSet(ecx1, cpuid_SSE41) + X86.HasSSE42 = isSet(ecx1, cpuid_SSE42) + X86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT) + X86.HasAES = isSet(ecx1, cpuid_AES) + X86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE) + X86.HasRDRAND = isSet(ecx1, cpuid_RDRAND) var osSupportsAVX, osSupportsAVX512 bool // For XGETBV, OSXSAVE bit is required and sufficient. if X86.HasOSXSAVE { eax, _ := xgetbv() // Check if XMM and YMM registers have OS support. - osSupportsAVX = isSet(1, eax) && isSet(2, eax) + osSupportsAVX = isSet(eax, 1<<1) && isSet(eax, 1<<2) if runtime.GOOS == "darwin" { // Darwin requires special AVX512 checks, see cpu_darwin_x86.go osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512() } else { // Check if OPMASK and ZMM registers have OS support. - osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) + osSupportsAVX512 = osSupportsAVX && isSet(eax, 1<<5) && isSet(eax, 1<<6) && isSet(eax, 1<<7) } } - X86.HasAVX = isSet(28, ecx1) && osSupportsAVX + X86.HasAVX = isSet(ecx1, cpuid_AVX) && osSupportsAVX if maxID < 7 { return } eax7, ebx7, ecx7, edx7 := cpuid(7, 0) - X86.HasBMI1 = isSet(3, ebx7) - X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX - X86.HasBMI2 = isSet(8, ebx7) - X86.HasERMS = isSet(9, ebx7) - X86.HasRDSEED = isSet(18, ebx7) - X86.HasADX = isSet(19, ebx7) + X86.HasBMI1 = isSet(ebx7, cpuid_BMI1) + X86.HasAVX2 = isSet(ebx7, cpuid_AVX2) && osSupportsAVX + X86.HasBMI2 = isSet(ebx7, cpuid_BMI2) + X86.HasERMS = isSet(ebx7, cpuid_ERMS) + X86.HasRDSEED = isSet(ebx7, cpuid_RDSEED) + X86.HasADX = isSet(ebx7, cpuid_ADX) - X86.HasAVX512 = isSet(16, ebx7) && osSupportsAVX512 // Because avx-512 foundation is the core required extension + X86.HasAVX512 = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512 // Because avx-512 foundation is the core required extension if X86.HasAVX512 { X86.HasAVX512F = true - X86.HasAVX512CD = isSet(28, ebx7) - X86.HasAVX512ER = isSet(27, ebx7) - X86.HasAVX512PF = isSet(26, ebx7) - X86.HasAVX512VL = isSet(31, ebx7) - X86.HasAVX512BW = isSet(30, ebx7) - X86.HasAVX512DQ = isSet(17, ebx7) - X86.HasAVX512IFMA = isSet(21, ebx7) - X86.HasAVX512VBMI = isSet(1, ecx7) - X86.HasAVX5124VNNIW = isSet(2, edx7) - X86.HasAVX5124FMAPS = isSet(3, edx7) - X86.HasAVX512VPOPCNTDQ = isSet(14, ecx7) - X86.HasAVX512VPCLMULQDQ = isSet(10, ecx7) - X86.HasAVX512VNNI = isSet(11, ecx7) - X86.HasAVX512GFNI = isSet(8, ecx7) - X86.HasAVX512VAES = isSet(9, ecx7) - X86.HasAVX512VBMI2 = isSet(6, ecx7) - X86.HasAVX512BITALG = isSet(12, ecx7) + X86.HasAVX512CD = isSet(ebx7, cpuid_AVX512CD) + X86.HasAVX512ER = isSet(ebx7, cpuid_AVX512ER) + X86.HasAVX512PF = isSet(ebx7, cpuid_AVX512PF) + X86.HasAVX512VL = isSet(ebx7, cpuid_AVX512VL) + X86.HasAVX512BW = isSet(ebx7, cpuid_AVX512BW) + X86.HasAVX512DQ = isSet(ebx7, cpuid_AVX512DQ) + X86.HasAVX512IFMA = isSet(ebx7, cpuid_AVX512IFMA) + X86.HasAVX512VBMI = isSet(ecx7, cpuid_AVX512_VBMI) + X86.HasAVX5124VNNIW = isSet(edx7, cpuid_AVX5124VNNIW) + X86.HasAVX5124FMAPS = isSet(edx7, cpuid_AVX5124FMAPS) + X86.HasAVX512VPOPCNTDQ = isSet(ecx7, cpuid_AVX512VPOPCNTDQ) + X86.HasAVX512VPCLMULQDQ = isSet(ecx7, cpuid_AVX512VPCLMULQDQ) + X86.HasAVX512VNNI = isSet(ecx7, cpuid_AVX512VNNI) + X86.HasAVX512GFNI = isSet(ecx7, cpuid_AVX512GFNI) + X86.HasAVX512VAES = isSet(ecx7, cpuid_AVX512VAES) + X86.HasAVX512VBMI2 = isSet(ecx7, cpuid_AVX512VBMI2) + X86.HasAVX512BITALG = isSet(ecx7, cpuid_AVX512BITALG) } - X86.HasAMXTile = isSet(24, edx7) - X86.HasAMXInt8 = isSet(25, edx7) - X86.HasAMXBF16 = isSet(22, edx7) + X86.HasAMXTile = isSet(edx7, cpuid_AMXTile) + X86.HasAMXInt8 = isSet(edx7, cpuid_AMXInt8) + X86.HasAMXBF16 = isSet(edx7, cpuid_AMXBF16) // These features depend on the second level of extended features. if eax7 >= 1 { eax71, _, _, edx71 := cpuid(7, 1) if X86.HasAVX512 { - X86.HasAVX512BF16 = isSet(5, eax71) + X86.HasAVX512BF16 = isSet(eax71, cpuid_AVX512BF16) } if X86.HasAVX { - X86.HasAVXIFMA = isSet(23, eax71) - X86.HasAVXVNNI = isSet(4, eax71) - X86.HasAVXVNNIInt8 = isSet(4, edx71) + X86.HasAVXIFMA = isSet(eax71, cpuid_AVXIFMA) + X86.HasAVXVNNI = isSet(eax71, cpuid_AVXVNNI) + X86.HasAVXVNNIInt8 = isSet(edx71, cpuid_AVXVNNIInt8) } } } -func isSet(bitpos uint, value uint32) bool { - return value&(1< #include #include +#include #include #include #include @@ -255,6 +256,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -349,6 +351,9 @@ struct ltchars { #define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN) #define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN) +// Renamed in v6.16, commit c6d732c38f93 ("net: ethtool: remove duplicate defines for family info") +#define ETHTOOL_FAMILY_NAME ETHTOOL_GENL_NAME +#define ETHTOOL_FAMILY_VERSION ETHTOOL_GENL_VERSION ' includes_NetBSD=' @@ -526,6 +531,7 @@ ccflags="$@" $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || + $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ || $2 ~ /^O?XTABS$/ || $2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^IN_/ || @@ -608,7 +614,7 @@ ccflags="$@" $2 !~ /IOC_MAGIC/ && $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || $2 ~ /^(VM|VMADDR)_/ || - $2 ~ /^IOCTL_VM_SOCKETS_/ || + $2 ~ /^(IOCTL_VM_SOCKETS_|IOCTL_MEI_)/ || $2 ~ /^(TASKSTATS|TS)_/ || $2 ~ /^CGROUPSTATS_/ || $2 ~ /^GENL_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 099867d..7838ca5 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -602,6 +602,95 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI return } +const minIovec = 8 + +func Readv(fd int, iovs [][]byte) (n int, err error) { + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + n, err = readv(fd, iovecs) + readvRacedetect(iovecs, n, err) + return n, err +} + +func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + n, err = preadv(fd, iovecs, offset) + readvRacedetect(iovecs, n, err) + return n, err +} + +func Writev(fd int, iovs [][]byte) (n int, err error) { + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + n, err = writev(fd, iovecs) + writevRacedetect(iovecs, n) + return n, err +} + +func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + n, err = pwritev(fd, iovecs, offset) + writevRacedetect(iovecs, n) + return n, err +} + +func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { + for _, b := range bs { + var v Iovec + v.SetLen(len(b)) + if len(b) > 0 { + v.Base = &b[0] + } else { + v.Base = (*byte)(unsafe.Pointer(&_zero)) + } + vecs = append(vecs, v) + } + return vecs +} + +func writevRacedetect(iovecs []Iovec, n int) { + if !raceenabled { + return + } + for i := 0; n > 0 && i < len(iovecs); i++ { + m := int(iovecs[i].Len) + if m > n { + m = n + } + n -= m + if m > 0 { + raceReadRange(unsafe.Pointer(iovecs[i].Base), m) + } + } +} + +func readvRacedetect(iovecs []Iovec, n int, err error) { + if !raceenabled { + return + } + for i := 0; n > 0 && i < len(iovecs); i++ { + m := int(iovecs[i].Len) + if m > n { + m = n + } + n -= m + if m > 0 { + raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) + } + } + if err == nil { + raceAcquire(unsafe.Pointer(&ioSync)) + } +} + //sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) @@ -705,3 +794,7 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) +//sys readv(fd int, iovecs []Iovec) (n int, err error) +//sys preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) +//sys writev(fd int, iovecs []Iovec) (n int, err error) +//sys pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 230a945..06c0eea 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -13,6 +13,7 @@ package unix import ( "encoding/binary" + "slices" "strconv" "syscall" "time" @@ -417,7 +418,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { return nil, 0, EINVAL } sa.raw.Family = AF_UNIX - for i := 0; i < n; i++ { + for i := range n { sa.raw.Path[i] = int8(name[i]) } // length is family (uint16), name, NUL. @@ -507,7 +508,7 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) psm[0] = byte(sa.PSM) psm[1] = byte(sa.PSM >> 8) - for i := 0; i < len(sa.Addr); i++ { + for i := range len(sa.Addr) { sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] } cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) @@ -589,11 +590,11 @@ func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { sa.raw.Family = AF_CAN sa.raw.Ifindex = int32(sa.Ifindex) rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i] = rx[i] } tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i+4] = tx[i] } return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil @@ -618,11 +619,11 @@ func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { sa.raw.Family = AF_CAN sa.raw.Ifindex = int32(sa.Ifindex) n := (*[8]byte)(unsafe.Pointer(&sa.Name)) - for i := 0; i < 8; i++ { + for i := range 8 { sa.raw.Addr[i] = n[i] } p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i+8] = p[i] } sa.raw.Addr[12] = sa.Addr @@ -800,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { // one. The kernel expects SID to be in network byte order. binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) copy(sa.raw[8:14], sa.Remote) - for i := 14; i < 14+IFNAMSIZ; i++ { - sa.raw[i] = 0 - } + clear(sa.raw[14 : 14+IFNAMSIZ]) copy(sa.raw[14:], sa.Dev) return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil } @@ -911,7 +910,7 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { // These are EBCDIC encoded by the kernel, but we still need to pad them // with blanks. Initializing with blanks allows the caller to feed in either // a padded or an unpadded string. - for i := 0; i < 8; i++ { + for i := range 8 { sa.raw.Nodeid[i] = ' ' sa.raw.User_id[i] = ' ' sa.raw.Name[i] = ' ' @@ -1148,7 +1147,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { var user [8]byte var name [8]byte - for i := 0; i < 8; i++ { + for i := range 8 { user[i] = byte(pp.User_id[i]) name[i] = byte(pp.Name[i]) } @@ -1173,11 +1172,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { Ifindex: int(pp.Ifindex), } name := (*[8]byte)(unsafe.Pointer(&sa.Name)) - for i := 0; i < 8; i++ { + for i := range 8 { name[i] = pp.Addr[i] } pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) - for i := 0; i < 4; i++ { + for i := range 4 { pgn[i] = pp.Addr[i+8] } addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) @@ -1188,11 +1187,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { Ifindex: int(pp.Ifindex), } rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) - for i := 0; i < 4; i++ { + for i := range 4 { rx[i] = pp.Addr[i] } tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) - for i := 0; i < 4; i++ { + for i := range 4 { tx[i] = pp.Addr[i+4] } return sa, nil @@ -2216,10 +2215,7 @@ func readvRacedetect(iovecs []Iovec, n int, err error) { return } for i := 0; n > 0 && i < len(iovecs); i++ { - m := int(iovecs[i].Len) - if m > n { - m = n - } + m := min(int(iovecs[i].Len), n) n -= m if m > 0 { raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) @@ -2270,10 +2266,7 @@ func writevRacedetect(iovecs []Iovec, n int) { return } for i := 0; n > 0 && i < len(iovecs); i++ { - m := int(iovecs[i].Len) - if m > n { - m = n - } + m := min(int(iovecs[i].Len), n) n -= m if m > 0 { raceReadRange(unsafe.Pointer(iovecs[i].Base), m) @@ -2320,12 +2313,7 @@ func isGroupMember(gid int) bool { return false } - for _, g := range groups { - if g == gid { - return true - } - } - return false + return slices.Contains(groups, gid) } func isCapDacOverrideSet() bool { @@ -2655,3 +2643,9 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) //sys Mseal(b []byte, flags uint) (err error) + +//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY + +func SetMemPolicy(mode int, mask *CPUSet) error { + return setMemPolicy(mode, mask, _CPU_SETSIZE) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 8816209..34a4676 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { return Statvfs1(path, buf, ST_WAIT) } +func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) { + var ( + _p0 unsafe.Pointer + bufsize uintptr + ) + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf)) + } + r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index abc3955..18a3d9b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -629,7 +629,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Kill(pid int, signum syscall.Signal) (err error) //sys Lchown(path string, uid int, gid int) (err error) //sys Link(path string, link string) (err error) -//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten +//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_listen //sys Lstat(path string, stat *Stat_t) (err error) //sys Madvise(b []byte, advice int) (err error) //sys Mkdir(path string, mode uint32) (err error) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 4f432bf..120a7b3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -319,6 +319,7 @@ const ( AUDIT_INTEGRITY_POLICY_RULE = 0x70f AUDIT_INTEGRITY_RULE = 0x70d AUDIT_INTEGRITY_STATUS = 0x70a + AUDIT_INTEGRITY_USERSPACE = 0x710 AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f AUDIT_IPE_ACCESS = 0x58c @@ -327,6 +328,8 @@ const ( AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 + AUDIT_LANDLOCK_ACCESS = 0x58f + AUDIT_LANDLOCK_DOMAIN = 0x590 AUDIT_LAST_FEATURE = 0x1 AUDIT_LAST_KERN_ANOM_MSG = 0x707 AUDIT_LAST_USER_MSG = 0x4af @@ -491,6 +494,7 @@ const ( BPF_F_BEFORE = 0x8 BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 + BPF_F_PREORDER = 0x40 BPF_F_QUERY_EFFECTIVE = 0x1 BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 @@ -527,6 +531,7 @@ const ( BPF_LDX = 0x1 BPF_LEN = 0x80 BPF_LL_OFF = -0x200000 + BPF_LOAD_ACQ = 0x100 BPF_LSH = 0x60 BPF_MAJOR_VERSION = 0x1 BPF_MAXINSNS = 0x1000 @@ -554,6 +559,7 @@ const ( BPF_RET = 0x6 BPF_RSH = 0x70 BPF_ST = 0x2 + BPF_STORE_REL = 0x110 BPF_STX = 0x3 BPF_SUB = 0x10 BPF_TAG_SIZE = 0x8 @@ -843,24 +849,90 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2023-03-01)" + DM_VERSION_EXTRA = "-ioctl (2025-04-28)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x30 + DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 + DT_ADDRRNGHI = 0x6ffffeff + DT_ADDRRNGLO = 0x6ffffe00 DT_BLK = 0x6 DT_CHR = 0x2 + DT_DEBUG = 0x15 DT_DIR = 0x4 + DT_ENCODING = 0x20 DT_FIFO = 0x1 + DT_FINI = 0xd + DT_FLAGS_1 = 0x6ffffffb + DT_GNU_HASH = 0x6ffffef5 + DT_HASH = 0x4 + DT_HIOS = 0x6ffff000 + DT_HIPROC = 0x7fffffff + DT_INIT = 0xc + DT_JMPREL = 0x17 DT_LNK = 0xa + DT_LOOS = 0x6000000d + DT_LOPROC = 0x70000000 + DT_NEEDED = 0x1 + DT_NULL = 0x0 + DT_PLTGOT = 0x3 + DT_PLTREL = 0x14 + DT_PLTRELSZ = 0x2 DT_REG = 0x8 + DT_REL = 0x11 + DT_RELA = 0x7 + DT_RELACOUNT = 0x6ffffff9 + DT_RELAENT = 0x9 + DT_RELASZ = 0x8 + DT_RELCOUNT = 0x6ffffffa + DT_RELENT = 0x13 + DT_RELSZ = 0x12 + DT_RPATH = 0xf DT_SOCK = 0xc + DT_SONAME = 0xe + DT_STRSZ = 0xa + DT_STRTAB = 0x5 + DT_SYMBOLIC = 0x10 + DT_SYMENT = 0xb + DT_SYMTAB = 0x6 + DT_TEXTREL = 0x16 DT_UNKNOWN = 0x0 + DT_VALRNGHI = 0x6ffffdff + DT_VALRNGLO = 0x6ffffd00 + DT_VERDEF = 0x6ffffffc + DT_VERDEFNUM = 0x6ffffffd + DT_VERNEED = 0x6ffffffe + DT_VERNEEDNUM = 0x6fffffff + DT_VERSYM = 0x6ffffff0 DT_WHT = 0xe ECHO = 0x8 ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_SEMAPHORE = 0x1 EFIVARFS_MAGIC = 0xde5e81e4 EFS_SUPER_MAGIC = 0x414a53 + EI_CLASS = 0x4 + EI_DATA = 0x5 + EI_MAG0 = 0x0 + EI_MAG1 = 0x1 + EI_MAG2 = 0x2 + EI_MAG3 = 0x3 + EI_NIDENT = 0x10 + EI_OSABI = 0x7 + EI_PAD = 0x8 + EI_VERSION = 0x6 + ELFCLASS32 = 0x1 + ELFCLASS64 = 0x2 + ELFCLASSNONE = 0x0 + ELFCLASSNUM = 0x3 + ELFDATA2LSB = 0x1 + ELFDATA2MSB = 0x2 + ELFDATANONE = 0x0 + ELFMAG = "\177ELF" + ELFMAG0 = 0x7f + ELFMAG1 = 'E' + ELFMAG2 = 'L' + ELFMAG3 = 'F' + ELFOSABI_LINUX = 0x3 + ELFOSABI_NONE = 0x0 EM_386 = 0x3 EM_486 = 0x6 EM_68K = 0x4 @@ -936,11 +1008,10 @@ const ( EPOLL_CTL_MOD = 0x3 EPOLL_IOC_TYPE = 0x8a EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 - ESP_V4_FLOW = 0xa - ESP_V6_FLOW = 0xc - ETHER_FLOW = 0x12 ETHTOOL_BUSINFO_LEN = 0x20 ETHTOOL_EROMVERS_LEN = 0x20 + ETHTOOL_FAMILY_NAME = "ethtool" + ETHTOOL_FAMILY_VERSION = 0x1 ETHTOOL_FEC_AUTO = 0x2 ETHTOOL_FEC_BASER = 0x10 ETHTOOL_FEC_LLRS = 0x20 @@ -1147,14 +1218,24 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + ET_CORE = 0x4 + ET_DYN = 0x3 + ET_EXEC = 0x2 + ET_HIPROC = 0xffff + ET_LOPROC = 0xff00 + ET_NONE = 0x0 + ET_REL = 0x1 EV_ABS = 0x3 EV_CNT = 0x20 + EV_CURRENT = 0x1 EV_FF = 0x15 EV_FF_STATUS = 0x17 EV_KEY = 0x1 EV_LED = 0x11 EV_MAX = 0x1f EV_MSC = 0x4 + EV_NONE = 0x0 + EV_NUM = 0x2 EV_PWR = 0x16 EV_REL = 0x2 EV_REP = 0x14 @@ -1203,13 +1284,18 @@ const ( FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 FAN_EPIDFD = -0x2 + FAN_ERRNO_BITS = 0x8 + FAN_ERRNO_MASK = 0xff + FAN_ERRNO_SHIFT = 0x18 FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_ERROR = 0x5 FAN_EVENT_INFO_TYPE_FID = 0x1 + FAN_EVENT_INFO_TYPE_MNT = 0x7 FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa FAN_EVENT_INFO_TYPE_PIDFD = 0x4 + FAN_EVENT_INFO_TYPE_RANGE = 0x6 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 @@ -1224,9 +1310,12 @@ const ( FAN_MARK_IGNORED_SURV_MODIFY = 0x40 FAN_MARK_IGNORE_SURV = 0x440 FAN_MARK_INODE = 0x0 + FAN_MARK_MNTNS = 0x110 FAN_MARK_MOUNT = 0x10 FAN_MARK_ONLYDIR = 0x8 FAN_MARK_REMOVE = 0x2 + FAN_MNT_ATTACH = 0x1000000 + FAN_MNT_DETACH = 0x2000000 FAN_MODIFY = 0x2 FAN_MOVE = 0xc0 FAN_MOVED_FROM = 0x40 @@ -1240,6 +1329,7 @@ const ( FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 + FAN_PRE_ACCESS = 0x100000 FAN_Q_OVERFLOW = 0x4000 FAN_RENAME = 0x10000000 FAN_REPORT_DFID_NAME = 0xc00 @@ -1247,6 +1337,7 @@ const ( FAN_REPORT_DIR_FID = 0x400 FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 + FAN_REPORT_MNT = 0x4000 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 FAN_REPORT_TARGET_FID = 0x1000 @@ -1266,6 +1357,7 @@ const ( FIB_RULE_PERMANENT = 0x1 FIB_RULE_UNRESOLVED = 0x4 FIDEDUPERANGE = 0xc0189436 + FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED = 0x1 FSCRYPT_KEY_DESCRIPTOR_SIZE = 0x8 FSCRYPT_KEY_DESC_PREFIX = "fscrypt:" FSCRYPT_KEY_DESC_PREFIX_SIZE = 0x8 @@ -1523,6 +1615,8 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_MEI_CONNECT_CLIENT = 0xc0104801 + IOCTL_MEI_CONNECT_CLIENT_VTAG = 0xc0144804 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c @@ -1574,7 +1668,6 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b - IPV6_FLOW = 0x11 IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 @@ -1625,7 +1718,6 @@ const ( IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 IPV6_UNICAST_IF = 0x4c - IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a IPV6_VERSION = 0x60 IPV6_VERSION_MASK = 0xf0 @@ -1687,7 +1779,6 @@ const ( IP_TTL = 0x2 IP_UNBLOCK_SOURCE = 0x25 IP_UNICAST_IF = 0x32 - IP_USER_FLOW = 0xd IP_XFRM_POLICY = 0x11 ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 @@ -1809,7 +1900,11 @@ const ( LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 + LANDLOCK_CREATE_RULESET_ERRATA = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON = 0x2 + LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF = 0x4 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 @@ -2259,7 +2354,167 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 + NN_386_IOPERM = "LINUX" + NN_386_TLS = "LINUX" + NN_ARC_V2 = "LINUX" + NN_ARM_FPMR = "LINUX" + NN_ARM_GCS = "LINUX" + NN_ARM_HW_BREAK = "LINUX" + NN_ARM_HW_WATCH = "LINUX" + NN_ARM_PACA_KEYS = "LINUX" + NN_ARM_PACG_KEYS = "LINUX" + NN_ARM_PAC_ENABLED_KEYS = "LINUX" + NN_ARM_PAC_MASK = "LINUX" + NN_ARM_POE = "LINUX" + NN_ARM_SSVE = "LINUX" + NN_ARM_SVE = "LINUX" + NN_ARM_SYSTEM_CALL = "LINUX" + NN_ARM_TAGGED_ADDR_CTRL = "LINUX" + NN_ARM_TLS = "LINUX" + NN_ARM_VFP = "LINUX" + NN_ARM_ZA = "LINUX" + NN_ARM_ZT = "LINUX" + NN_AUXV = "CORE" + NN_FILE = "CORE" + NN_GNU_PROPERTY_TYPE_0 = "GNU" + NN_LOONGARCH_CPUCFG = "LINUX" + NN_LOONGARCH_CSR = "LINUX" + NN_LOONGARCH_HW_BREAK = "LINUX" + NN_LOONGARCH_HW_WATCH = "LINUX" + NN_LOONGARCH_LASX = "LINUX" + NN_LOONGARCH_LBT = "LINUX" + NN_LOONGARCH_LSX = "LINUX" + NN_MIPS_DSP = "LINUX" + NN_MIPS_FP_MODE = "LINUX" + NN_MIPS_MSA = "LINUX" + NN_PPC_DEXCR = "LINUX" + NN_PPC_DSCR = "LINUX" + NN_PPC_EBB = "LINUX" + NN_PPC_HASHKEYR = "LINUX" + NN_PPC_PKEY = "LINUX" + NN_PPC_PMU = "LINUX" + NN_PPC_PPR = "LINUX" + NN_PPC_SPE = "LINUX" + NN_PPC_TAR = "LINUX" + NN_PPC_TM_CDSCR = "LINUX" + NN_PPC_TM_CFPR = "LINUX" + NN_PPC_TM_CGPR = "LINUX" + NN_PPC_TM_CPPR = "LINUX" + NN_PPC_TM_CTAR = "LINUX" + NN_PPC_TM_CVMX = "LINUX" + NN_PPC_TM_CVSX = "LINUX" + NN_PPC_TM_SPR = "LINUX" + NN_PPC_VMX = "LINUX" + NN_PPC_VSX = "LINUX" + NN_PRFPREG = "CORE" + NN_PRPSINFO = "CORE" + NN_PRSTATUS = "CORE" + NN_PRXFPREG = "LINUX" + NN_RISCV_CSR = "LINUX" + NN_RISCV_TAGGED_ADDR_CTRL = "LINUX" + NN_RISCV_VECTOR = "LINUX" + NN_S390_CTRS = "LINUX" + NN_S390_GS_BC = "LINUX" + NN_S390_GS_CB = "LINUX" + NN_S390_HIGH_GPRS = "LINUX" + NN_S390_LAST_BREAK = "LINUX" + NN_S390_PREFIX = "LINUX" + NN_S390_PV_CPU_DATA = "LINUX" + NN_S390_RI_CB = "LINUX" + NN_S390_SYSTEM_CALL = "LINUX" + NN_S390_TDB = "LINUX" + NN_S390_TIMER = "LINUX" + NN_S390_TODCMP = "LINUX" + NN_S390_TODPREG = "LINUX" + NN_S390_VXRS_HIGH = "LINUX" + NN_S390_VXRS_LOW = "LINUX" + NN_SIGINFO = "CORE" + NN_TASKSTRUCT = "CORE" + NN_VMCOREDD = "LINUX" + NN_X86_SHSTK = "LINUX" + NN_X86_XSAVE_LAYOUT = "LINUX" + NN_X86_XSTATE = "LINUX" NSFS_MAGIC = 0x6e736673 + NT_386_IOPERM = 0x201 + NT_386_TLS = 0x200 + NT_ARC_V2 = 0x600 + NT_ARM_FPMR = 0x40e + NT_ARM_GCS = 0x410 + NT_ARM_HW_BREAK = 0x402 + NT_ARM_HW_WATCH = 0x403 + NT_ARM_PACA_KEYS = 0x407 + NT_ARM_PACG_KEYS = 0x408 + NT_ARM_PAC_ENABLED_KEYS = 0x40a + NT_ARM_PAC_MASK = 0x406 + NT_ARM_POE = 0x40f + NT_ARM_SSVE = 0x40b + NT_ARM_SVE = 0x405 + NT_ARM_SYSTEM_CALL = 0x404 + NT_ARM_TAGGED_ADDR_CTRL = 0x409 + NT_ARM_TLS = 0x401 + NT_ARM_VFP = 0x400 + NT_ARM_ZA = 0x40c + NT_ARM_ZT = 0x40d + NT_AUXV = 0x6 + NT_FILE = 0x46494c45 + NT_GNU_PROPERTY_TYPE_0 = 0x5 + NT_LOONGARCH_CPUCFG = 0xa00 + NT_LOONGARCH_CSR = 0xa01 + NT_LOONGARCH_HW_BREAK = 0xa05 + NT_LOONGARCH_HW_WATCH = 0xa06 + NT_LOONGARCH_LASX = 0xa03 + NT_LOONGARCH_LBT = 0xa04 + NT_LOONGARCH_LSX = 0xa02 + NT_MIPS_DSP = 0x800 + NT_MIPS_FP_MODE = 0x801 + NT_MIPS_MSA = 0x802 + NT_PPC_DEXCR = 0x111 + NT_PPC_DSCR = 0x105 + NT_PPC_EBB = 0x106 + NT_PPC_HASHKEYR = 0x112 + NT_PPC_PKEY = 0x110 + NT_PPC_PMU = 0x107 + NT_PPC_PPR = 0x104 + NT_PPC_SPE = 0x101 + NT_PPC_TAR = 0x103 + NT_PPC_TM_CDSCR = 0x10f + NT_PPC_TM_CFPR = 0x109 + NT_PPC_TM_CGPR = 0x108 + NT_PPC_TM_CPPR = 0x10e + NT_PPC_TM_CTAR = 0x10d + NT_PPC_TM_CVMX = 0x10a + NT_PPC_TM_CVSX = 0x10b + NT_PPC_TM_SPR = 0x10c + NT_PPC_VMX = 0x100 + NT_PPC_VSX = 0x102 + NT_PRFPREG = 0x2 + NT_PRPSINFO = 0x3 + NT_PRSTATUS = 0x1 + NT_PRXFPREG = 0x46e62b7f + NT_RISCV_CSR = 0x900 + NT_RISCV_TAGGED_ADDR_CTRL = 0x902 + NT_RISCV_VECTOR = 0x901 + NT_S390_CTRS = 0x304 + NT_S390_GS_BC = 0x30c + NT_S390_GS_CB = 0x30b + NT_S390_HIGH_GPRS = 0x300 + NT_S390_LAST_BREAK = 0x306 + NT_S390_PREFIX = 0x305 + NT_S390_PV_CPU_DATA = 0x30e + NT_S390_RI_CB = 0x30d + NT_S390_SYSTEM_CALL = 0x307 + NT_S390_TDB = 0x308 + NT_S390_TIMER = 0x301 + NT_S390_TODCMP = 0x302 + NT_S390_TODPREG = 0x303 + NT_S390_VXRS_HIGH = 0x30a + NT_S390_VXRS_LOW = 0x309 + NT_SIGINFO = 0x53494749 + NT_TASKSTRUCT = 0x4 + NT_VMCOREDD = 0x700 + NT_X86_SHSTK = 0x204 + NT_X86_XSAVE_LAYOUT = 0x205 + NT_X86_XSTATE = 0x202 OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 @@ -2446,6 +2701,59 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 + PF_ALG = 0x26 + PF_APPLETALK = 0x5 + PF_ASH = 0x12 + PF_ATMPVC = 0x8 + PF_ATMSVC = 0x14 + PF_AX25 = 0x3 + PF_BLUETOOTH = 0x1f + PF_BRIDGE = 0x7 + PF_CAIF = 0x25 + PF_CAN = 0x1d + PF_DECnet = 0xc + PF_ECONET = 0x13 + PF_FILE = 0x1 + PF_IB = 0x1b + PF_IEEE802154 = 0x24 + PF_INET = 0x2 + PF_INET6 = 0xa + PF_IPX = 0x4 + PF_IRDA = 0x17 + PF_ISDN = 0x22 + PF_IUCV = 0x20 + PF_KCM = 0x29 + PF_KEY = 0xf + PF_LLC = 0x1a + PF_LOCAL = 0x1 + PF_MAX = 0x2e + PF_MCTP = 0x2d + PF_MPLS = 0x1c + PF_NETBEUI = 0xd + PF_NETLINK = 0x10 + PF_NETROM = 0x6 + PF_NFC = 0x27 + PF_PACKET = 0x11 + PF_PHONET = 0x23 + PF_PPPOX = 0x18 + PF_QIPCRTR = 0x2a + PF_R = 0x4 + PF_RDS = 0x15 + PF_ROSE = 0xb + PF_ROUTE = 0x10 + PF_RXRPC = 0x21 + PF_SECURITY = 0xe + PF_SMC = 0x2b + PF_SNA = 0x16 + PF_TIPC = 0x1e + PF_UNIX = 0x1 + PF_UNSPEC = 0x0 + PF_VSOCK = 0x28 + PF_W = 0x2 + PF_WANPIPE = 0x19 + PF_X = 0x1 + PF_X25 = 0x9 + PF_XDP = 0x2c PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c @@ -2485,6 +2793,10 @@ const ( PR_FP_EXC_UND = 0x40000 PR_FP_MODE_FR = 0x1 PR_FP_MODE_FRE = 0x2 + PR_FUTEX_HASH = 0x4e + PR_FUTEX_HASH_GET_IMMUTABLE = 0x3 + PR_FUTEX_HASH_GET_SLOTS = 0x2 + PR_FUTEX_HASH_SET_SLOTS = 0x1 PR_GET_AUXV = 0x41555856 PR_GET_CHILD_SUBREAPER = 0x25 PR_GET_DUMPABLE = 0x3 @@ -2644,6 +2956,10 @@ const ( PR_TAGGED_ADDR_ENABLE = 0x1 PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 + PR_TIMER_CREATE_RESTORE_IDS = 0x4d + PR_TIMER_CREATE_RESTORE_IDS_GET = 0x2 + PR_TIMER_CREATE_RESTORE_IDS_OFF = 0x0 + PR_TIMER_CREATE_RESTORE_IDS_ON = 0x1 PR_TIMING_STATISTICAL = 0x0 PR_TIMING_TIMESTAMP = 0x1 PR_TSC_ENABLE = 0x1 @@ -2724,6 +3040,7 @@ const ( PTRACE_SETREGSET = 0x4205 PTRACE_SETSIGINFO = 0x4203 PTRACE_SETSIGMASK = 0x420b + PTRACE_SET_SYSCALL_INFO = 0x4212 PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 @@ -2732,6 +3049,23 @@ const ( PTRACE_SYSCALL_INFO_NONE = 0x0 PTRACE_SYSCALL_INFO_SECCOMP = 0x3 PTRACE_TRACEME = 0x0 + PT_AARCH64_MEMTAG_MTE = 0x70000002 + PT_DYNAMIC = 0x2 + PT_GNU_EH_FRAME = 0x6474e550 + PT_GNU_PROPERTY = 0x6474e553 + PT_GNU_RELRO = 0x6474e552 + PT_GNU_STACK = 0x6474e551 + PT_HIOS = 0x6fffffff + PT_HIPROC = 0x7fffffff + PT_INTERP = 0x3 + PT_LOAD = 0x1 + PT_LOOS = 0x60000000 + PT_LOPROC = 0x70000000 + PT_NOTE = 0x4 + PT_NULL = 0x0 + PT_PHDR = 0x6 + PT_SHLIB = 0x5 + PT_TLS = 0x7 P_ALL = 0x0 P_PGID = 0x2 P_PID = 0x1 @@ -2787,7 +3121,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1e + RTA_MAX = 0x1f RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -2864,10 +3198,12 @@ const ( RTM_DELACTION = 0x31 RTM_DELADDR = 0x15 RTM_DELADDRLABEL = 0x49 + RTM_DELANYCAST = 0x3d RTM_DELCHAIN = 0x65 RTM_DELLINK = 0x11 RTM_DELLINKPROP = 0x6d RTM_DELMDB = 0x55 + RTM_DELMULTICAST = 0x39 RTM_DELNEIGH = 0x1d RTM_DELNETCONF = 0x51 RTM_DELNEXTHOP = 0x69 @@ -2917,11 +3253,13 @@ const ( RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWANYCAST = 0x3c RTM_NEWCACHEREPORT = 0x60 RTM_NEWCHAIN = 0x64 RTM_NEWLINK = 0x10 RTM_NEWLINKPROP = 0x6c RTM_NEWMDB = 0x54 + RTM_NEWMULTICAST = 0x38 RTM_NEWNDUSEROPT = 0x44 RTM_NEWNEIGH = 0x1c RTM_NEWNEIGHTBL = 0x40 @@ -2970,6 +3308,7 @@ const ( RTPROT_NTK = 0xf RTPROT_OPENR = 0x63 RTPROT_OSPF = 0xbc + RTPROT_OVN = 0x54 RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 RTPROT_RIP = 0xbd @@ -2987,11 +3326,12 @@ const ( RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 RWF_ATOMIC = 0x40 + RWF_DONTCACHE = 0x80 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x7f + RWF_SUPPORTED = 0xff RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3059,6 +3399,47 @@ const ( SEEK_MAX = 0x4 SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c + SHF_ALLOC = 0x2 + SHF_EXCLUDE = 0x8000000 + SHF_EXECINSTR = 0x4 + SHF_GROUP = 0x200 + SHF_INFO_LINK = 0x40 + SHF_LINK_ORDER = 0x80 + SHF_MASKOS = 0xff00000 + SHF_MASKPROC = 0xf0000000 + SHF_MERGE = 0x10 + SHF_ORDERED = 0x4000000 + SHF_OS_NONCONFORMING = 0x100 + SHF_RELA_LIVEPATCH = 0x100000 + SHF_RO_AFTER_INIT = 0x200000 + SHF_STRINGS = 0x20 + SHF_TLS = 0x400 + SHF_WRITE = 0x1 + SHN_ABS = 0xfff1 + SHN_COMMON = 0xfff2 + SHN_HIPROC = 0xff1f + SHN_HIRESERVE = 0xffff + SHN_LIVEPATCH = 0xff20 + SHN_LOPROC = 0xff00 + SHN_LORESERVE = 0xff00 + SHN_UNDEF = 0x0 + SHT_DYNAMIC = 0x6 + SHT_DYNSYM = 0xb + SHT_HASH = 0x5 + SHT_HIPROC = 0x7fffffff + SHT_HIUSER = 0xffffffff + SHT_LOPROC = 0x70000000 + SHT_LOUSER = 0x80000000 + SHT_NOBITS = 0x8 + SHT_NOTE = 0x7 + SHT_NULL = 0x0 + SHT_NUM = 0xc + SHT_PROGBITS = 0x1 + SHT_REL = 0x9 + SHT_RELA = 0x4 + SHT_SHLIB = 0xa + SHT_STRTAB = 0x3 + SHT_SYMTAB = 0x2 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -3271,6 +3652,7 @@ const ( STATX_BTIME = 0x800 STATX_CTIME = 0x80 STATX_DIOALIGN = 0x2000 + STATX_DIO_READ_ALIGN = 0x20000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3284,6 +3666,16 @@ const ( STATX_UID = 0x8 STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 + STB_GLOBAL = 0x1 + STB_LOCAL = 0x0 + STB_WEAK = 0x2 + STT_COMMON = 0x5 + STT_FILE = 0x4 + STT_FUNC = 0x2 + STT_NOTYPE = 0x0 + STT_OBJECT = 0x1 + STT_SECTION = 0x3 + STT_TLS = 0x6 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 SYNC_FILE_RANGE_WRITE = 0x2 @@ -3322,7 +3714,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xe + TASKSTATS_VERSION = 0x10 TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3392,8 +3784,6 @@ const ( TCP_TX_DELAY = 0x25 TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 - TCP_V4_FLOW = 0x1 - TCP_V6_FLOW = 0x5 TCP_WINDOW_CLAMP = 0xa TCP_ZEROCOPY_RECEIVE = 0x23 TFD_TIMER_ABSTIME = 0x1 @@ -3503,6 +3893,7 @@ const ( TP_STATUS_WRONG_FORMAT = 0x4 TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 + UBI_IOCECNFO = 0xc01c6f06 UDF_SUPER_MAGIC = 0x15013346 UDP_CORK = 0x1 UDP_ENCAP = 0x64 @@ -3515,14 +3906,14 @@ const ( UDP_NO_CHECK6_RX = 0x66 UDP_NO_CHECK6_TX = 0x65 UDP_SEGMENT = 0x67 - UDP_V4_FLOW = 0x2 - UDP_V6_FLOW = 0x6 UMOUNT_NOFOLLOW = 0x8 USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe V9FS_MAGIC = 0x1021997 VERASE = 0x2 + VER_FLG_BASE = 0x1 + VER_FLG_WEAK = 0x2 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf @@ -3559,7 +3950,7 @@ const ( WDIOS_TEMPPANIC = 0x4 WDIOS_UNKNOWN = -0x1 WEXITED = 0x4 - WGALLOWEDIP_A_MAX = 0x3 + WGALLOWEDIP_A_MAX = 0x4 WGDEVICE_A_MAX = 0x8 WGPEER_A_MAX = 0xa WG_CMD_MAX = 0x1 @@ -3673,6 +4064,7 @@ const ( XDP_SHARED_UMEM = 0x1 XDP_STATISTICS = 0x7 XDP_TXMD_FLAGS_CHECKSUM = 0x2 + XDP_TXMD_FLAGS_LAUNCH_TIME = 0x4 XDP_TXMD_FLAGS_TIMESTAMP = 0x1 XDP_TX_METADATA = 0x2 XDP_TX_RING = 0x3 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 7520761..97a61fc 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -115,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -360,6 +363,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -372,6 +376,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c68acda..a0d6d49 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -115,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -361,6 +364,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -373,6 +377,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a8c607a..dd9c903 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -366,6 +369,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -378,6 +382,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 18563dd..384c61c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -119,6 +120,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -359,6 +362,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -371,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 22912cd..6384c98 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -115,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -353,6 +356,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -365,6 +369,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 29344eb..553c1c6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -359,6 +362,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 20d51fb..b3339f2 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -359,6 +362,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 321b609..177091d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -359,6 +362,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 9bacdf1..c5abf15 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -359,6 +362,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c224272..f1f3fad 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -414,6 +417,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -426,6 +430,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 6270c8e..203ad9c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -418,6 +421,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +434,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 9966c19..4b9abcb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -418,6 +421,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +434,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 848e5fc..f879830 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -350,6 +353,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -362,6 +366,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 669b2ad..64347eb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -114,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -422,6 +425,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -434,6 +438,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 4834e57..7d71911 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -71,6 +71,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -118,6 +119,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x400000 IN_NONBLOCK = 0x4000 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff @@ -461,6 +464,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x2 SO_PASSPIDFD = 0x55 + SO_PASSRIGHTS = 0x5c SO_PASSSEC = 0x1f SO_PEEK_OFF = 0x26 SO_PEERCRED = 0x40 @@ -473,6 +477,7 @@ const ( SO_RCVBUFFORCE = 0x100b SO_RCVLOWAT = 0x800 SO_RCVMARK = 0x54 + SO_RCVPRIORITY = 0x5b SO_RCVTIMEO = 0x2000 SO_RCVTIMEO_NEW = 0x44 SO_RCVTIMEO_OLD = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 24b346e..813c05b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func readv(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_preadv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writev(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_writev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwritev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index ebd2131..fda3285 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) +TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readv(SB) +GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB) + +TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_preadv(SB) +GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB) + +TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_writev(SB) +GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB) + +TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwritev(SB) +GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB) + TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat64(SB) GLOBL ·libc_fstat64_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 824b9c2..e6f58f3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func readv(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_preadv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writev(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_writev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwritev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 4f178a2..7f8998b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) +TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readv(SB) +GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB) + +TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_preadv(SB) +GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB) + +TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_writev(SB) +GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB) + +TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwritev(SB) +GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB) + TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 5cc1e8e..8935d10 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2238,3 +2238,13 @@ func Mseal(b []byte, flags uint) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setMemPolicy(mode int, mask *CPUSet, size int) (err error) { + _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index c654541..b4609c2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -72,7 +72,7 @@ import ( //go:cgo_import_dynamic libc_kill kill "libc.so" //go:cgo_import_dynamic libc_lchown lchown "libc.so" //go:cgo_import_dynamic libc_link link "libc.so" -//go:cgo_import_dynamic libc___xnet_llisten __xnet_llisten "libsocket.so" +//go:cgo_import_dynamic libc___xnet_listen __xnet_listen "libsocket.so" //go:cgo_import_dynamic libc_lstat lstat "libc.so" //go:cgo_import_dynamic libc_madvise madvise "libc.so" //go:cgo_import_dynamic libc_mkdir mkdir "libc.so" @@ -221,7 +221,7 @@ import ( //go:linkname procKill libc_kill //go:linkname procLchown libc_lchown //go:linkname procLink libc_link -//go:linkname proc__xnet_llisten libc___xnet_llisten +//go:linkname proc__xnet_listen libc___xnet_listen //go:linkname procLstat libc_lstat //go:linkname procMadvise libc_madvise //go:linkname procMkdir libc_mkdir @@ -371,7 +371,7 @@ var ( procKill, procLchown, procLink, - proc__xnet_llisten, + proc__xnet_listen, procLstat, procMadvise, procMkdir, @@ -1178,7 +1178,7 @@ func Link(path string, link string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Listen(s int, backlog int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_llisten)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_listen)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index c79aaff..aca56ee 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -462,4 +462,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 5eb4506..2ea1ef5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -385,4 +385,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 05e5029..d22c8af 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -426,4 +426,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 38c53ec..5ee264a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -329,4 +329,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 31d2e71..f9f03eb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -325,4 +325,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index f4184a3..87c2118 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 05b9962..391ad10 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 43a256e..5656157 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index eea5ddf..0482b52 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index 0d777bf..71806f0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -453,4 +453,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index b446365..e35a710 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 0c7d21c..2aea476 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 8405391..6c9bb4e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -330,4 +330,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index fcf1b79..680bc99 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -391,4 +391,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 52d15b5..620f271 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -404,4 +404,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index a46abe6..c1a4670 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -114,8 +114,10 @@ type Statx_t struct { Atomic_write_unit_min uint32 Atomic_write_unit_max uint32 Atomic_write_segments_max uint32 + Dio_read_offset_align uint32 + Atomic_write_unit_max_opt uint32 _ [1]uint32 - _ [9]uint64 + _ [8]uint64 } type Fsid struct { @@ -199,7 +201,8 @@ type FscryptAddKeyArg struct { Key_spec FscryptKeySpecifier Raw_size uint32 Key_id uint32 - _ [8]uint32 + Flags uint32 + _ [7]uint32 } type FscryptRemoveKeyArg struct { @@ -629,6 +632,8 @@ const ( IFA_FLAGS = 0x8 IFA_RT_PRIORITY = 0x9 IFA_TARGET_NETNSID = 0xa + IFAL_LABEL = 0x2 + IFAL_ADDRESS = 0x1 RT_SCOPE_UNIVERSE = 0x0 RT_SCOPE_SITE = 0xc8 RT_SCOPE_LINK = 0xfd @@ -686,6 +691,7 @@ const ( SizeofRtAttr = 0x4 SizeofIfInfomsg = 0x10 SizeofIfAddrmsg = 0x8 + SizeofIfAddrlblmsg = 0xc SizeofIfaCacheinfo = 0x10 SizeofRtMsg = 0xc SizeofRtNexthop = 0x8 @@ -737,6 +743,15 @@ type IfAddrmsg struct { Index uint32 } +type IfAddrlblmsg struct { + Family uint8 + _ uint8 + Prefixlen uint8 + Flags uint8 + Index uint32 + Seq uint32 +} + type IfaCacheinfo struct { Prefered uint32 Valid uint32 @@ -2226,8 +2241,11 @@ const ( NFT_PAYLOAD_LL_HEADER = 0x0 NFT_PAYLOAD_NETWORK_HEADER = 0x1 NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_INNER_HEADER = 0x3 + NFT_PAYLOAD_TUN_HEADER = 0x4 NFT_PAYLOAD_CSUM_NONE = 0x0 NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_CSUM_SCTP = 0x2 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 NFTA_PAYLOAD_UNSPEC = 0x0 NFTA_PAYLOAD_DREG = 0x1 @@ -2314,6 +2332,11 @@ const ( NFT_CT_AVGPKT = 0x10 NFT_CT_ZONE = 0x11 NFT_CT_EVENTMASK = 0x12 + NFT_CT_SRC_IP = 0x13 + NFT_CT_DST_IP = 0x14 + NFT_CT_SRC_IP6 = 0x15 + NFT_CT_DST_IP6 = 0x16 + NFT_CT_ID = 0x17 NFTA_CT_UNSPEC = 0x0 NFTA_CT_DREG = 0x1 NFTA_CT_KEY = 0x2 @@ -2594,8 +2617,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x20000 - SOF_TIMESTAMPING_MASK = 0x3ffff + SOF_TIMESTAMPING_LAST = 0x40000 + SOF_TIMESTAMPING_MASK = 0x7ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3041,6 +3064,23 @@ const ( ) const ( + TCA_UNSPEC = 0x0 + TCA_KIND = 0x1 + TCA_OPTIONS = 0x2 + TCA_STATS = 0x3 + TCA_XSTATS = 0x4 + TCA_RATE = 0x5 + TCA_FCNT = 0x6 + TCA_STATS2 = 0x7 + TCA_STAB = 0x8 + TCA_PAD = 0x9 + TCA_DUMP_INVISIBLE = 0xa + TCA_CHAIN = 0xb + TCA_HW_OFFLOAD = 0xc + TCA_INGRESS_BLOCK = 0xd + TCA_EGRESS_BLOCK = 0xe + TCA_DUMP_FLAGS = 0xf + TCA_EXT_WARN_MSG = 0x10 RTNLGRP_NONE = 0x0 RTNLGRP_LINK = 0x1 RTNLGRP_NOTIFY = 0x2 @@ -3075,6 +3115,18 @@ const ( RTNLGRP_IPV6_MROUTE_R = 0x1f RTNLGRP_NEXTHOP = 0x20 RTNLGRP_BRVLAN = 0x21 + RTNLGRP_MCTP_IFADDR = 0x22 + RTNLGRP_TUNNEL = 0x23 + RTNLGRP_STATS = 0x24 + RTNLGRP_IPV4_MCADDR = 0x25 + RTNLGRP_IPV6_MCADDR = 0x26 + RTNLGRP_IPV6_ACADDR = 0x27 + TCA_ROOT_UNSPEC = 0x0 + TCA_ROOT_TAB = 0x1 + TCA_ROOT_FLAGS = 0x2 + TCA_ROOT_COUNT = 0x3 + TCA_ROOT_TIME_DELTA = 0x4 + TCA_ROOT_EXT_WARN_MSG = 0x5 ) type CapUserHeader struct { @@ -3538,6 +3590,8 @@ type Nhmsg struct { Flags uint32 } +const SizeofNhmsg = 0x8 + type NexthopGrp struct { Id uint32 Weight uint8 @@ -3545,6 +3599,8 @@ type NexthopGrp struct { Resvd2 uint16 } +const SizeofNexthopGrp = 0x8 + const ( NHA_UNSPEC = 0x0 NHA_ID = 0x1 @@ -3802,7 +3858,16 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2d + ETHTOOL_MSG_PLCA_GET_CFG = 0x27 + ETHTOOL_MSG_PLCA_SET_CFG = 0x28 + ETHTOOL_MSG_PLCA_GET_STATUS = 0x29 + ETHTOOL_MSG_MM_GET = 0x2a + ETHTOOL_MSG_MM_SET = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_ACT = 0x2c + ETHTOOL_MSG_PHY_GET = 0x2d + ETHTOOL_MSG_TSCONFIG_GET = 0x2e + ETHTOOL_MSG_TSCONFIG_SET = 0x2f + ETHTOOL_MSG_USER_MAX = 0x2f ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3907,17 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_MSG_PLCA_GET_CFG_REPLY = 0x27 + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY = 0x28 + ETHTOOL_MSG_PLCA_NTF = 0x29 + ETHTOOL_MSG_MM_GET_REPLY = 0x2a + ETHTOOL_MSG_MM_NTF = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_NTF = 0x2c + ETHTOOL_MSG_PHY_GET_REPLY = 0x2d + ETHTOOL_MSG_PHY_NTF = 0x2e + ETHTOOL_MSG_TSCONFIG_GET_REPLY = 0x2f + ETHTOOL_MSG_TSCONFIG_SET_REPLY = 0x30 + ETHTOOL_MSG_KERNEL_MAX = 0x30 ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3949,7 +4024,12 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0x10 + ETHTOOL_A_RINGS_RX_PUSH = 0xe + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN = 0xf + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX = 0x10 + ETHTOOL_A_RINGS_HDS_THRESH = 0x11 + ETHTOOL_A_RINGS_HDS_THRESH_MAX = 0x12 + ETHTOOL_A_RINGS_MAX = 0x12 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -4015,7 +4095,9 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x6 + ETHTOOL_A_TSINFO_STATS = 0x6 + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER = 0x7 + ETHTOOL_A_TSINFO_MAX = 0x9 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4101,6 +4183,19 @@ const ( ETHTOOL_A_TUNNEL_INFO_MAX = 0x2 ) +const ( + TCP_V4_FLOW = 0x1 + UDP_V4_FLOW = 0x2 + TCP_V6_FLOW = 0x5 + UDP_V6_FLOW = 0x6 + ESP_V4_FLOW = 0xa + ESP_V6_FLOW = 0xc + IP_USER_FLOW = 0xd + IPV6_USER_FLOW = 0xe + IPV6_FLOW = 0x11 + ETHER_FLOW = 0x12 +) + const SPEED_UNKNOWN = -0x1 type EthtoolDrvinfo struct { @@ -4613,6 +4708,7 @@ const ( NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 + NL80211_ATTR_ASSOC_SPP_AMSDU = 0x14a NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4623,6 +4719,7 @@ const ( NL80211_ATTR_BSS_BASIC_RATES = 0x24 NL80211_ATTR_BSS = 0x2f NL80211_ATTR_BSS_CTS_PROT = 0x1c + NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA = 0x147 NL80211_ATTR_BSS_HT_OPMODE = 0x6d NL80211_ATTR_BSSID = 0xf5 NL80211_ATTR_BSS_SELECT = 0xe3 @@ -4682,6 +4779,7 @@ const ( NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EMA_RNR_ELEMS = 0x145 NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa @@ -4717,6 +4815,7 @@ const ( NL80211_ATTR_HIDDEN_SSID = 0x7e NL80211_ATTR_HT_CAPABILITY = 0x1f NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 + NL80211_ATTR_HW_TIMESTAMP_ENABLED = 0x144 NL80211_ATTR_IE_ASSOC_RESP = 0x80 NL80211_ATTR_IE = 0x2a NL80211_ATTR_IE_PROBE_RESP = 0x7f @@ -4747,9 +4846,10 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14d + NL80211_ATTR_MAX = 0x151 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS = 0x143 NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 @@ -4774,9 +4874,12 @@ const ( NL80211_ATTR_MGMT_SUBTYPE = 0x29 NL80211_ATTR_MLD_ADDR = 0x13a NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_DISABLED = 0x146 NL80211_ATTR_MLO_LINK_ID = 0x139 NL80211_ATTR_MLO_LINKS = 0x138 NL80211_ATTR_MLO_SUPPORT = 0x13b + NL80211_ATTR_MLO_TTLM_DLINK = 0x148 + NL80211_ATTR_MLO_TTLM_ULINK = 0x149 NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4809,12 +4912,14 @@ const ( NL80211_ATTR_PORT_AUTHORIZED = 0x103 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 + NL80211_ATTR_POWER_RULE_PSD = 0x8 NL80211_ATTR_PREV_BSSID = 0x4f NL80211_ATTR_PRIVACY = 0x46 NL80211_ATTR_PROBE_RESP = 0x91 NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d + NL80211_ATTR_PUNCT_BITMAP = 0x142 NL80211_ATTR_QOS_MAP = 0xc7 NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 @@ -4943,7 +5048,9 @@ const ( NL80211_ATTR_WIPHY_FREQ = 0x26 NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS = 0x14c NL80211_ATTR_WIPHY_NAME = 0x2 + NL80211_ATTR_WIPHY_RADIOS = 0x14b NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 @@ -4978,6 +5085,8 @@ const ( NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 + NL80211_BAND_ATTR_S1G_CAPA = 0xd + NL80211_BAND_ATTR_S1G_MCS_NSS_SET = 0xc NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 @@ -5001,6 +5110,10 @@ const ( NL80211_BSS_BEACON_INTERVAL = 0x4 NL80211_BSS_BEACON_TSF = 0xd NL80211_BSS_BSSID = 0x1 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 0x2 + NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 0x1 + NL80211_BSS_CANNOT_USE_REASONS = 0x18 + NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 0x2 NL80211_BSS_CAPABILITY = 0x5 NL80211_BSS_CHAIN_SIGNAL = 0x13 NL80211_BSS_CHAN_WIDTH_10 = 0x1 @@ -5032,6 +5145,9 @@ const ( NL80211_BSS_STATUS = 0x9 NL80211_BSS_STATUS_IBSS_JOINED = 0x2 NL80211_BSS_TSF = 0x3 + NL80211_BSS_USE_FOR = 0x17 + NL80211_BSS_USE_FOR_MLD_LINK = 0x2 + NL80211_BSS_USE_FOR_NORMAL = 0x1 NL80211_CHAN_HT20 = 0x1 NL80211_CHAN_HT40MINUS = 0x2 NL80211_CHAN_HT40PLUS = 0x3 @@ -5117,7 +5233,8 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x9b + NL80211_CMD_LINKS_REMOVED = 0x9a + NL80211_CMD_MAX = 0x9d NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5161,6 +5278,7 @@ const ( NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f NL80211_CMD_SET_FILS_AAD = 0x92 + NL80211_CMD_SET_HW_TIMESTAMP = 0x99 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -5180,6 +5298,7 @@ const ( NL80211_CMD_SET_SAR_SPECS = 0x8c NL80211_CMD_SET_STATION = 0x12 NL80211_CMD_SET_TID_CONFIG = 0x89 + NL80211_CMD_SET_TID_TO_LINK_MAPPING = 0x9b NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 NL80211_CMD_SET_WDS_PEER = 0x42 NL80211_CMD_SET_WIPHY = 0x2 @@ -5247,6 +5366,7 @@ const ( NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 NL80211_EXT_FEATURE_AQL = 0x28 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA = 0x40 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 NL80211_EXT_FEATURE_BEACON_RATE_HE = 0x36 @@ -5262,6 +5382,7 @@ const ( NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c + NL80211_EXT_FEATURE_DFS_CONCURRENT = 0x43 NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 @@ -5281,9 +5402,12 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_OWE_OFFLOAD_AP = 0x42 + NL80211_EXT_FEATURE_OWE_OFFLOAD = 0x41 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_PUNCT = 0x3e NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 @@ -5295,8 +5419,10 @@ const ( NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc NL80211_EXT_FEATURE_SECURE_LTF = 0x37 + NL80211_EXT_FEATURE_SECURE_NAN = 0x3f NL80211_EXT_FEATURE_SECURE_RTT = 0x38 NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 + NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT = 0x44 NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 NL80211_EXT_FEATURE_TXQS = 0x1c NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 @@ -5343,7 +5469,10 @@ const ( NL80211_FREQUENCY_ATTR_2MHZ = 0x16 NL80211_FREQUENCY_ATTR_4MHZ = 0x17 NL80211_FREQUENCY_ATTR_8MHZ = 0x18 + NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP = 0x21 + NL80211_FREQUENCY_ATTR_CAN_MONITOR = 0x20 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd + NL80211_FREQUENCY_ATTR_DFS_CONCURRENT = 0x1d NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 NL80211_FREQUENCY_ATTR_DISABLED = 0x2 @@ -5351,12 +5480,14 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x21 + NL80211_FREQUENCY_ATTR_MAX = 0x22 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a + NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 @@ -5364,8 +5495,11 @@ const ( NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 NL80211_FREQUENCY_ATTR_NO_IR = 0x3 + NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_OFFSET = 0x14 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 + NL80211_FREQUENCY_ATTR_PSD = 0x1c NL80211_FREQUENCY_ATTR_RADAR = 0x5 NL80211_FREQUENCY_ATTR_WMM = 0x12 NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 @@ -5430,6 +5564,7 @@ const ( NL80211_IFTYPE_STATION = 0x2 NL80211_IFTYPE_UNSPECIFIED = 0x0 NL80211_IFTYPE_WDS = 0x5 + NL80211_KCK_EXT_LEN_32 = 0x20 NL80211_KCK_EXT_LEN = 0x18 NL80211_KCK_LEN = 0x10 NL80211_KEK_EXT_LEN = 0x20 @@ -5458,9 +5593,10 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MAX_SUPP_SELECTORS = 0x80 NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 - NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 + NL80211_MBSSID_CONFIG_ATTR_MAX = 0x6 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY = 0x2 NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES = 0x1 NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX = 0x4 @@ -5703,11 +5839,16 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_16_MHZ_WIDTH = 0x1d + NL80211_RATE_INFO_1_MHZ_WIDTH = 0x19 + NL80211_RATE_INFO_2_MHZ_WIDTH = 0x1a NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 + NL80211_RATE_INFO_4_MHZ_WIDTH = 0x1b NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 + NL80211_RATE_INFO_8_MHZ_WIDTH = 0x1c NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 @@ -5753,6 +5894,8 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 + NL80211_RATE_INFO_S1G_MCS = 0x17 + NL80211_RATE_INFO_S1G_NSS = 0x18 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 NL80211_RATE_INFO_VHT_NSS = 0x7 @@ -5770,14 +5913,19 @@ const ( NL80211_REKEY_DATA_KEK = 0x1 NL80211_REKEY_DATA_REPLAY_CTR = 0x3 NL80211_REPLAY_CTR_LEN = 0x8 + NL80211_RRF_ALLOW_6GHZ_VLP_AP = 0x1000000 NL80211_RRF_AUTO_BW = 0x800 NL80211_RRF_DFS = 0x10 + NL80211_RRF_DFS_CONCURRENT = 0x200000 NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 NL80211_RRF_NO_320MHZ = 0x40000 + NL80211_RRF_NO_6GHZ_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_6GHZ_VLP_CLIENT = 0x400000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 + NL80211_RRF_NO_EHT = 0x80000 NL80211_RRF_NO_HE = 0x20000 NL80211_RRF_NO_HT40 = 0x6000 NL80211_RRF_NO_HT40MINUS = 0x2000 @@ -5788,7 +5936,10 @@ const ( NL80211_RRF_NO_IR = 0x80 NL80211_RRF_NO_OFDM = 0x1 NL80211_RRF_NO_OUTDOOR = 0x8 + NL80211_RRF_NO_UHB_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_UHB_VLP_CLIENT = 0x400000 NL80211_RRF_PASSIVE_SCAN = 0x80 + NL80211_RRF_PSD = 0x100000 NL80211_RRF_PTMP_ONLY = 0x40 NL80211_RRF_PTP_ONLY = 0x20 NL80211_RXMGMT_FLAG_ANSWERED = 0x1 @@ -5849,6 +6000,7 @@ const ( NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 + NL80211_STA_FLAG_SPP_AMSDU = 0x8 NL80211_STA_FLAG_TDLS_PEER = 0x6 NL80211_STA_FLAG_WME = 0x3 NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 @@ -6007,6 +6159,13 @@ const ( NL80211_VHT_CAPABILITY_LEN = 0xc NL80211_VHT_NSS_MAX = 0x8 NL80211_WIPHY_NAME_MAXLEN = 0x40 + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE = 0x2 + NL80211_WIPHY_RADIO_ATTR_INDEX = 0x1 + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION = 0x3 + NL80211_WIPHY_RADIO_ATTR_MAX = 0x4 + NL80211_WIPHY_RADIO_FREQ_ATTR_END = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_START = 0x1 NL80211_WMMR_AIFSN = 0x3 NL80211_WMMR_CW_MAX = 0x2 NL80211_WMMR_CW_MIN = 0x1 @@ -6038,6 +6197,7 @@ const ( NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe + NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC = 0x14 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc @@ -6176,3 +6336,30 @@ type SockDiagReq struct { } const RTM_NEWNVLAN = 0x70 + +const ( + MPOL_BIND = 0x2 + MPOL_DEFAULT = 0x0 + MPOL_F_ADDR = 0x2 + MPOL_F_MEMS_ALLOWED = 0x4 + MPOL_F_MOF = 0x8 + MPOL_F_MORON = 0x10 + MPOL_F_NODE = 0x1 + MPOL_F_NUMA_BALANCING = 0x2000 + MPOL_F_RELATIVE_NODES = 0x4000 + MPOL_F_SHARED = 0x1 + MPOL_F_STATIC_NODES = 0x8000 + MPOL_INTERLEAVE = 0x3 + MPOL_LOCAL = 0x4 + MPOL_MAX = 0x7 + MPOL_MF_INTERNAL = 0x10 + MPOL_MF_LAZY = 0x8 + MPOL_MF_MOVE_ALL = 0x4 + MPOL_MF_MOVE = 0x2 + MPOL_MF_STRICT = 0x1 + MPOL_MF_VALID = 0x7 + MPOL_MODE_FLAGS = 0xe000 + MPOL_PREFERRED = 0x1 + MPOL_PREFERRED_MANY = 0x5 + MPOL_WEIGHTED_INTERLEAVE = 0x6 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index fd402da..485f2d3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -282,7 +282,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -338,6 +338,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index eb7a5e1..ecbd1ad 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -351,6 +351,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d78ac10..02f0463 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -91,7 +91,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -273,7 +273,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -329,6 +329,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index cd06d47..6f4d400 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -330,6 +330,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 2f28fe2..cd532cf 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -331,6 +331,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 71d6cac..4133620 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 8596d45..eaa37eb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index cd60ea1..98ae6a1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index b0ae420..cae1961 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 8359728..6ce3b4e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -90,7 +90,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -285,7 +285,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -341,6 +341,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 69eb6a5..c7429c6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 5f583cb..4bf4baf 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index ad05b51..e9709d7 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -358,6 +358,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cf3ce90..fb44268 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -353,6 +353,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 590b567..9c38265 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -335,6 +335,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 439548e..50e8e64 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -104,7 +104,7 @@ type Statvfs_t struct { Fsid uint32 Namemax uint32 Owner uint32 - Spare [4]uint32 + Spare [4]uint64 Fstypename [32]byte Mntonname [1024]byte Mntfromname [1024]byte diff --git a/vendor/golang.org/x/sys/windows/registry/key.go b/vendor/golang.org/x/sys/windows/registry/key.go index fd86324..39aeeb6 100644 --- a/vendor/golang.org/x/sys/windows/registry/key.go +++ b/vendor/golang.org/x/sys/windows/registry/key.go @@ -164,7 +164,12 @@ loopItems: func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) { var h syscall.Handle var d uint32 - err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path), + var pathPointer *uint16 + pathPointer, err = syscall.UTF16PtrFromString(path) + if err != nil { + return 0, false, err + } + err = regCreateKeyEx(syscall.Handle(k), pathPointer, 0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d) if err != nil { return 0, false, err @@ -174,7 +179,11 @@ func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool // DeleteKey deletes the subkey path of key k and its values. func DeleteKey(k Key, path string) error { - return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path)) + pathPointer, err := syscall.UTF16PtrFromString(path) + if err != nil { + return err + } + return regDeleteKey(syscall.Handle(k), pathPointer) } // A KeyInfo describes the statistics of a key. It is returned by Stat. diff --git a/vendor/golang.org/x/sys/windows/registry/value.go b/vendor/golang.org/x/sys/windows/registry/value.go index 74db26b..a1bcbb2 100644 --- a/vendor/golang.org/x/sys/windows/registry/value.go +++ b/vendor/golang.org/x/sys/windows/registry/value.go @@ -340,7 +340,11 @@ func (k Key) SetBinaryValue(name string, value []byte) error { // DeleteValue removes a named value from the key k. func (k Key) DeleteValue(name string) error { - return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name)) + namePointer, err := syscall.UTF16PtrFromString(name) + if err != nil { + return err + } + return regDeleteValue(syscall.Handle(k), namePointer) } // ReadValueNames returns the value names of key k. diff --git a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go index fc1835d..bc1ce43 100644 --- a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go @@ -52,7 +52,7 @@ var ( ) func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result))) + r0, _, _ := syscall.SyscallN(procRegConnectRegistryW.Addr(), uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -60,7 +60,7 @@ func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall } func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition))) + r0, _, _ := syscall.SyscallN(procRegCreateKeyExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -68,7 +68,7 @@ func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class * } func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0) + r0, _, _ := syscall.SyscallN(procRegDeleteKeyW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -76,7 +76,7 @@ func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) { } func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0) + r0, _, _ := syscall.SyscallN(procRegDeleteValueW.Addr(), uintptr(key), uintptr(unsafe.Pointer(name))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -84,7 +84,7 @@ func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { } func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0) + r0, _, _ := syscall.SyscallN(procRegEnumValueW.Addr(), uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -92,7 +92,7 @@ func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint3 } func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0) + r0, _, _ := syscall.SyscallN(procRegLoadMUIStringW.Addr(), uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -100,7 +100,7 @@ func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint } func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) + r0, _, _ := syscall.SyscallN(procRegSetValueExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -108,7 +108,7 @@ func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype } func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procExpandEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index b6e1ab7..a8b0364 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -1303,7 +1303,10 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE return nil, err } if absoluteSDSize > 0 { - absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0])) + absoluteSD = new(SECURITY_DESCRIPTOR) + if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) { + panic("sizeof(SECURITY_DESCRIPTOR) too small") + } } var ( dacl *ACL @@ -1312,19 +1315,55 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE group *SID ) if daclSize > 0 { - dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0])) + dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize)))) } if saclSize > 0 { - sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0])) + sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize)))) } if ownerSize > 0 { - owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0])) + owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize)))) } if groupSize > 0 { - group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0])) + group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize)))) } + // We call into Windows via makeAbsoluteSD, which sets up + // pointers within absoluteSD that point to other chunks of memory + // we pass into makeAbsoluteSD, and that happens outside the view of the GC. + // We therefore take some care here to then verify the pointers are as we expect + // and set them explicitly in view of the GC. See https://go.dev/issue/73199. + // TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575. err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize, dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize) + if err != nil { + // Don't return absoluteSD, which might be partially initialized. + return nil, err + } + // Before using any fields, verify absoluteSD is in the format we expect according to Windows. + // See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors + absControl, _, err := absoluteSD.Control() + if err != nil { + panic("absoluteSD: " + err.Error()) + } + if absControl&SE_SELF_RELATIVE != 0 { + panic("absoluteSD not in absolute format") + } + if absoluteSD.dacl != dacl { + panic("dacl pointer mismatch") + } + if absoluteSD.sacl != sacl { + panic("sacl pointer mismatch") + } + if absoluteSD.owner != owner { + panic("owner pointer mismatch") + } + if absoluteSD.group != group { + panic("group pointer mismatch") + } + absoluteSD.dacl = dacl + absoluteSD.sacl = sacl + absoluteSD.owner = owner + absoluteSD.group = group + return } diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/config.go b/vendor/golang.org/x/sys/windows/svc/mgr/config.go index 3c7ba08..ec01f96 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/config.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/config.go @@ -121,7 +121,11 @@ func (s *Service) Config() (Config, error) { } func updateDescription(handle windows.Handle, desc string) error { - d := windows.SERVICE_DESCRIPTION{Description: toPtr(desc)} + descPointer, err := toPtr(desc) + if err != nil { + return err + } + d := windows.SERVICE_DESCRIPTION{Description: descPointer} return windows.ChangeServiceConfig2(handle, windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d))) } @@ -141,10 +145,30 @@ func updateStartUp(handle windows.Handle, isDelayed bool) error { // UpdateConfig updates service s configuration parameters. func (s *Service) UpdateConfig(c Config) error { - err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType, - c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup), - nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), - toPtr(c.Password), toPtr(c.DisplayName)) + binaryPathNamePointer, err := toPtr(c.BinaryPathName) + if err != nil { + return err + } + loadOrderGroupPointer, err := toPtr(c.LoadOrderGroup) + if err != nil { + return err + } + serviceStartNamePointer, err := toPtr(c.ServiceStartName) + if err != nil { + return err + } + passwordPointer, err := toPtr(c.Password) + if err != nil { + return err + } + displayNamePointer, err := toPtr(c.DisplayName) + if err != nil { + return err + } + err = windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType, + c.ErrorControl, binaryPathNamePointer, loadOrderGroupPointer, + nil, toStringBlock(c.Dependencies), serviceStartNamePointer, + passwordPointer, displayNamePointer) if err != nil { return err } diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go b/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go index dbfd729..7475594 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go @@ -34,7 +34,11 @@ func Connect() (*Mgr, error) { func ConnectRemote(host string) (*Mgr, error) { var s *uint16 if host != "" { - s = syscall.StringToUTF16Ptr(host) + var err error + s, err = syscall.UTF16PtrFromString(host) + if err != nil { + return nil, err + } } h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS) if err != nil { @@ -78,11 +82,11 @@ func (m *Mgr) LockStatus() (*LockStatus, error) { } } -func toPtr(s string) *uint16 { +func toPtr(s string) (*uint16, error) { if len(s) == 0 { - return nil + return nil, nil } - return syscall.StringToUTF16Ptr(s) + return syscall.UTF16PtrFromString(s) } // toStringBlock terminates strings in ss with 0, and then @@ -122,10 +126,34 @@ func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Se for _, v := range args { s += " " + syscall.EscapeArg(v) } - h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName), + namePointer, err := toPtr(name) + if err != nil { + return nil, err + } + displayNamePointer, err := toPtr(c.DisplayName) + if err != nil { + return nil, err + } + sPointer, err := toPtr(s) + if err != nil { + return nil, err + } + loadOrderGroupPointer, err := toPtr(c.LoadOrderGroup) + if err != nil { + return nil, err + } + serviceStartNamePointer, err := toPtr(c.ServiceStartName) + if err != nil { + return nil, err + } + passwordPointer, err := toPtr(c.Password) + if err != nil { + return nil, err + } + h, err := windows.CreateService(m.Handle, namePointer, displayNamePointer, windows.SERVICE_ALL_ACCESS, c.ServiceType, - c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup), - nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password)) + c.StartType, c.ErrorControl, sPointer, loadOrderGroupPointer, + nil, toStringBlock(c.Dependencies), serviceStartNamePointer, passwordPointer) if err != nil { return nil, err } @@ -159,7 +187,12 @@ func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Se // OpenService retrieves access to service name, so it can // be interrogated and controlled. func (m *Mgr) OpenService(name string) (*Service, error) { - h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS) + namePointer, err := syscall.UTF16PtrFromString(name) + if err != nil { + return nil, err + } + + h, err := windows.OpenService(m.Handle, namePointer, windows.SERVICE_ALL_ACCESS) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go b/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go index ef2a687..1a07374 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/recovery.go @@ -99,8 +99,13 @@ func (s *Service) ResetPeriod() (uint32, error) { // SetRebootMessage sets service s reboot message. // If msg is "", the reboot message is deleted and no message is broadcast. func (s *Service) SetRebootMessage(msg string) error { + msgPointer, err := syscall.UTF16PtrFromString(msg) + if err != nil { + return err + } + rActions := windows.SERVICE_FAILURE_ACTIONS{ - RebootMsg: syscall.StringToUTF16Ptr(msg), + RebootMsg: msgPointer, } return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions))) } @@ -118,8 +123,13 @@ func (s *Service) RebootMessage() (string, error) { // SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action. // If cmd is "", the command is deleted and no program is run when the service fails. func (s *Service) SetRecoveryCommand(cmd string) error { + cmdPointer, err := syscall.UTF16PtrFromString(cmd) + if err != nil { + return err + } + rActions := windows.SERVICE_FAILURE_ACTIONS{ - Command: syscall.StringToUTF16Ptr(cmd), + Command: cmdPointer, } return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions))) } diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/service.go b/vendor/golang.org/x/sys/windows/svc/mgr/service.go index c9740ef..9f59eab 100644 --- a/vendor/golang.org/x/sys/windows/svc/mgr/service.go +++ b/vendor/golang.org/x/sys/windows/svc/mgr/service.go @@ -37,7 +37,11 @@ func (s *Service) Start(args ...string) error { if len(args) > 0 { vs := make([]*uint16, len(args)) for i := range vs { - vs[i] = syscall.StringToUTF16Ptr(args[i]) + argPointer, err := syscall.UTF16PtrFromString(args[i]) + if err != nil { + return err + } + vs[i] = argPointer } p = &vs[0] } diff --git a/vendor/golang.org/x/sys/windows/svc/service.go b/vendor/golang.org/x/sys/windows/svc/service.go index c4f7492..a9b1c19 100644 --- a/vendor/golang.org/x/sys/windows/svc/service.go +++ b/vendor/golang.org/x/sys/windows/svc/service.go @@ -132,10 +132,10 @@ type ctlEvent struct { // service provides access to windows service api. type service struct { - name string - h windows.Handle - c chan ctlEvent - handler Handler + namePointer *uint16 + h windows.Handle + c chan ctlEvent + handler Handler } type exitCode struct { @@ -209,7 +209,7 @@ var theService service // This is, unfortunately, a global, which means only one // serviceMain is the entry point called by the service manager, registered earlier by // the call to StartServiceCtrlDispatcher. func serviceMain(argc uint32, argv **uint16) uintptr { - handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, 0) + handle, err := windows.RegisterServiceCtrlHandlerEx(theService.namePointer, ctlHandlerCallback, 0) if sysErr, ok := err.(windows.Errno); ok { return uintptr(sysErr) } else if err != nil { @@ -280,15 +280,21 @@ loop: // Run executes service name by calling appropriate handler function. func Run(name string, handler Handler) error { + // Check to make sure that the service name is valid. + namePointer, err := windows.UTF16PtrFromString(name) + if err != nil { + return err + } + initCallbacks.Do(func() { ctlHandlerCallback = windows.NewCallback(ctlHandler) serviceMainCallback = windows.NewCallback(serviceMain) }) - theService.name = name + theService.namePointer = namePointer theService.handler = handler theService.c = make(chan ctlEvent) t := []windows.SERVICE_TABLE_ENTRY{ - {ServiceName: windows.StringToUTF16Ptr(theService.name), ServiceProc: serviceMainCallback}, + {ServiceName: namePointer, ServiceProc: serviceMainCallback}, {ServiceName: nil, ServiceProc: 0}, } return windows.StartServiceCtrlDispatcher(&t[0]) diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 4a32543..69439df 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents +//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW @@ -870,6 +872,7 @@ const socket_error = uintptr(^uint32(0)) //sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom //sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo //sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW +//sys WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW //sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname //sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname //sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs @@ -889,8 +892,12 @@ const socket_error = uintptr(^uint32(0)) //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx //sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 +//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 //sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable //sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 //sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange //sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 @@ -913,6 +920,17 @@ type RawSockaddrInet6 struct { Scope_id uint32 } +// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See +// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. +// +// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using +// unsafe, depending on the address family. +type RawSockaddrInet struct { + Family uint16 + Port uint16 + Data [6]uint32 +} + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -1698,8 +1716,9 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) { // Slice returns a uint16 slice that aliases the data in the NTUnicodeString. func (s *NTUnicodeString) Slice() []uint16 { - slice := unsafe.Slice(s.Buffer, s.MaximumLength) - return slice[:s.Length] + // Note: this rounds the length down, if it happens + // to (incorrectly) be odd. Probably safer than rounding up. + return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2] } func (s *NTUnicodeString) String() string { diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 9d138de..6e4f50e 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -65,6 +65,22 @@ var signals = [...]string{ 15: "terminated", } +// File flags for [os.OpenFile]. The O_ prefix is used to indicate +// that these flags are specific to the OpenFile function. +const ( + O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL + O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT + O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE + O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH +) + const ( FILE_READ_DATA = 0x00000001 FILE_READ_ATTRIBUTES = 0x00000080 @@ -1074,6 +1090,7 @@ const ( IP_ADD_MEMBERSHIP = 0xc IP_DROP_MEMBERSHIP = 0xd IP_PKTINFO = 0x13 + IP_MTU_DISCOVER = 0x47 IPV6_V6ONLY = 0x1b IPV6_UNICAST_HOPS = 0x4 @@ -1083,6 +1100,7 @@ const ( IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd IPV6_PKTINFO = 0x13 + IPV6_MTU_DISCOVER = 0x47 MSG_OOB = 0x1 MSG_PEEK = 0x2 @@ -1132,6 +1150,15 @@ const ( WSASYS_STATUS_LEN = 128 ) +// enum PMTUD_STATE from ws2ipdef.h +const ( + IP_PMTUDISC_NOT_SET = 0 + IP_PMTUDISC_DO = 1 + IP_PMTUDISC_DONT = 2 + IP_PMTUDISC_PROBE = 3 + IP_PMTUDISC_MAX = 4 +) + type WSABuf struct { Len uint32 Buf *byte @@ -1146,6 +1173,22 @@ type WSAMsg struct { Flags uint32 } +type WSACMSGHDR struct { + Len uintptr + Level int32 + Type int32 +} + +type IN_PKTINFO struct { + Addr [4]byte + Ifindex uint32 +} + +type IN6_PKTINFO struct { + Addr [16]byte + Ifindex uint32 +} + // Flags for WSASocket const ( WSA_FLAG_OVERLAPPED = 0x01 @@ -1949,6 +1992,12 @@ const ( SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 ) +// FILE_ZERO_DATA_INFORMATION from winioctl.h +type FileZeroDataInformation struct { + FileOffset int64 + BeyondFinalZero int64 +} + const ( ComputerNameNetBIOS = 0 ComputerNameDnsHostname = 1 @@ -2271,6 +2320,82 @@ type MibIfRow2 struct { OutQLen uint64 } +// IP_ADDRESS_PREFIX stores an IP address prefix. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. +type IpAddressPrefix struct { + Prefix RawSockaddrInet + PrefixLength uint8 +} + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. +const ( + NlroManual = 0 + NlroWellKnown = 1 + NlroDHCP = 2 + NlroRouterAdvertisement = 3 + Nlro6to4 = 4 +) + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. +const ( + MIB_IPPROTO_OTHER = 1 + MIB_IPPROTO_LOCAL = 2 + MIB_IPPROTO_NETMGMT = 3 + MIB_IPPROTO_ICMP = 4 + MIB_IPPROTO_EGP = 5 + MIB_IPPROTO_GGP = 6 + MIB_IPPROTO_HELLO = 7 + MIB_IPPROTO_RIP = 8 + MIB_IPPROTO_IS_IS = 9 + MIB_IPPROTO_ES_IS = 10 + MIB_IPPROTO_CISCO = 11 + MIB_IPPROTO_BBN = 12 + MIB_IPPROTO_OSPF = 13 + MIB_IPPROTO_BGP = 14 + MIB_IPPROTO_IDPR = 15 + MIB_IPPROTO_EIGRP = 16 + MIB_IPPROTO_DVMRP = 17 + MIB_IPPROTO_RPL = 18 + MIB_IPPROTO_DHCP = 19 + MIB_IPPROTO_NT_AUTOSTATIC = 10002 + MIB_IPPROTO_NT_STATIC = 10006 + MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 +) + +// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. +type MibIpForwardRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + DestinationPrefix IpAddressPrefix + NextHop RawSockaddrInet + SitePrefixLength uint8 + ValidLifetime uint32 + PreferredLifetime uint32 + Metric uint32 + Protocol uint32 + Loopback uint8 + AutoconfigureAddress uint8 + Publish uint8 + Immortal uint8 + Age uint32 + Origin uint32 +} + +// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. +type MibIpForwardTable2 struct { + NumEntries uint32 + Table [1]MibIpForwardRow2 +} + +// Rows returns the IP route entries in the table. +func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { + return unsafe.Slice(&t.Table[0], t.NumEntries) +} + // MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See // https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. type MibUnicastIpAddressRow struct { @@ -2673,6 +2798,8 @@ type CommTimeouts struct { // NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING. type NTUnicodeString struct { + // Note: Length and MaximumLength are in *bytes*, not uint16s. + // They should always be even. Length uint16 MaximumLength uint16 Buffer *uint16 @@ -3601,3 +3728,213 @@ const ( KLF_NOTELLSHELL = 0x00000080 KLF_SETFORPROCESS = 0x00000100 ) + +// Virtual Key codes +// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +const ( + VK_LBUTTON = 0x01 + VK_RBUTTON = 0x02 + VK_CANCEL = 0x03 + VK_MBUTTON = 0x04 + VK_XBUTTON1 = 0x05 + VK_XBUTTON2 = 0x06 + VK_BACK = 0x08 + VK_TAB = 0x09 + VK_CLEAR = 0x0C + VK_RETURN = 0x0D + VK_SHIFT = 0x10 + VK_CONTROL = 0x11 + VK_MENU = 0x12 + VK_PAUSE = 0x13 + VK_CAPITAL = 0x14 + VK_KANA = 0x15 + VK_HANGEUL = 0x15 + VK_HANGUL = 0x15 + VK_IME_ON = 0x16 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_IME_OFF = 0x1A + VK_ESCAPE = 0x1B + VK_CONVERT = 0x1C + VK_NONCONVERT = 0x1D + VK_ACCEPT = 0x1E + VK_MODECHANGE = 0x1F + VK_SPACE = 0x20 + VK_PRIOR = 0x21 + VK_NEXT = 0x22 + VK_END = 0x23 + VK_HOME = 0x24 + VK_LEFT = 0x25 + VK_UP = 0x26 + VK_RIGHT = 0x27 + VK_DOWN = 0x28 + VK_SELECT = 0x29 + VK_PRINT = 0x2A + VK_EXECUTE = 0x2B + VK_SNAPSHOT = 0x2C + VK_INSERT = 0x2D + VK_DELETE = 0x2E + VK_HELP = 0x2F + VK_LWIN = 0x5B + VK_RWIN = 0x5C + VK_APPS = 0x5D + VK_SLEEP = 0x5F + VK_NUMPAD0 = 0x60 + VK_NUMPAD1 = 0x61 + VK_NUMPAD2 = 0x62 + VK_NUMPAD3 = 0x63 + VK_NUMPAD4 = 0x64 + VK_NUMPAD5 = 0x65 + VK_NUMPAD6 = 0x66 + VK_NUMPAD7 = 0x67 + VK_NUMPAD8 = 0x68 + VK_NUMPAD9 = 0x69 + VK_MULTIPLY = 0x6A + VK_ADD = 0x6B + VK_SEPARATOR = 0x6C + VK_SUBTRACT = 0x6D + VK_DECIMAL = 0x6E + VK_DIVIDE = 0x6F + VK_F1 = 0x70 + VK_F2 = 0x71 + VK_F3 = 0x72 + VK_F4 = 0x73 + VK_F5 = 0x74 + VK_F6 = 0x75 + VK_F7 = 0x76 + VK_F8 = 0x77 + VK_F9 = 0x78 + VK_F10 = 0x79 + VK_F11 = 0x7A + VK_F12 = 0x7B + VK_F13 = 0x7C + VK_F14 = 0x7D + VK_F15 = 0x7E + VK_F16 = 0x7F + VK_F17 = 0x80 + VK_F18 = 0x81 + VK_F19 = 0x82 + VK_F20 = 0x83 + VK_F21 = 0x84 + VK_F22 = 0x85 + VK_F23 = 0x86 + VK_F24 = 0x87 + VK_NUMLOCK = 0x90 + VK_SCROLL = 0x91 + VK_OEM_NEC_EQUAL = 0x92 + VK_OEM_FJ_JISHO = 0x92 + VK_OEM_FJ_MASSHOU = 0x93 + VK_OEM_FJ_TOUROKU = 0x94 + VK_OEM_FJ_LOYA = 0x95 + VK_OEM_FJ_ROYA = 0x96 + VK_LSHIFT = 0xA0 + VK_RSHIFT = 0xA1 + VK_LCONTROL = 0xA2 + VK_RCONTROL = 0xA3 + VK_LMENU = 0xA4 + VK_RMENU = 0xA5 + VK_BROWSER_BACK = 0xA6 + VK_BROWSER_FORWARD = 0xA7 + VK_BROWSER_REFRESH = 0xA8 + VK_BROWSER_STOP = 0xA9 + VK_BROWSER_SEARCH = 0xAA + VK_BROWSER_FAVORITES = 0xAB + VK_BROWSER_HOME = 0xAC + VK_VOLUME_MUTE = 0xAD + VK_VOLUME_DOWN = 0xAE + VK_VOLUME_UP = 0xAF + VK_MEDIA_NEXT_TRACK = 0xB0 + VK_MEDIA_PREV_TRACK = 0xB1 + VK_MEDIA_STOP = 0xB2 + VK_MEDIA_PLAY_PAUSE = 0xB3 + VK_LAUNCH_MAIL = 0xB4 + VK_LAUNCH_MEDIA_SELECT = 0xB5 + VK_LAUNCH_APP1 = 0xB6 + VK_LAUNCH_APP2 = 0xB7 + VK_OEM_1 = 0xBA + VK_OEM_PLUS = 0xBB + VK_OEM_COMMA = 0xBC + VK_OEM_MINUS = 0xBD + VK_OEM_PERIOD = 0xBE + VK_OEM_2 = 0xBF + VK_OEM_3 = 0xC0 + VK_OEM_4 = 0xDB + VK_OEM_5 = 0xDC + VK_OEM_6 = 0xDD + VK_OEM_7 = 0xDE + VK_OEM_8 = 0xDF + VK_OEM_AX = 0xE1 + VK_OEM_102 = 0xE2 + VK_ICO_HELP = 0xE3 + VK_ICO_00 = 0xE4 + VK_PROCESSKEY = 0xE5 + VK_ICO_CLEAR = 0xE6 + VK_OEM_RESET = 0xE9 + VK_OEM_JUMP = 0xEA + VK_OEM_PA1 = 0xEB + VK_OEM_PA2 = 0xEC + VK_OEM_PA3 = 0xED + VK_OEM_WSCTRL = 0xEE + VK_OEM_CUSEL = 0xEF + VK_OEM_ATTN = 0xF0 + VK_OEM_FINISH = 0xF1 + VK_OEM_COPY = 0xF2 + VK_OEM_AUTO = 0xF3 + VK_OEM_ENLW = 0xF4 + VK_OEM_BACKTAB = 0xF5 + VK_ATTN = 0xF6 + VK_CRSEL = 0xF7 + VK_EXSEL = 0xF8 + VK_EREOF = 0xF9 + VK_PLAY = 0xFA + VK_ZOOM = 0xFB + VK_NONAME = 0xFC + VK_PA1 = 0xFD + VK_OEM_CLEAR = 0xFE +) + +// Mouse button constants. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001 + RIGHTMOST_BUTTON_PRESSED = 0x0002 + FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004 + FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008 + FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010 +) + +// Control key state constaints. +// https://docs.microsoft.com/en-us/windows/console/key-event-record-str +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 + LEFT_ALT_PRESSED = 0x0002 + LEFT_CTRL_PRESSED = 0x0008 + NUMLOCK_ON = 0x0020 + RIGHT_ALT_PRESSED = 0x0001 + RIGHT_CTRL_PRESSED = 0x0004 + SCROLLLOCK_ON = 0x0040 + SHIFT_PRESSED = 0x0010 +) + +// Mouse event record event flags. +// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str +const ( + MOUSE_MOVED = 0x0001 + DOUBLE_CLICK = 0x0002 + MOUSE_WHEELED = 0x0004 + MOUSE_HWHEELED = 0x0008 +) + +// Input Record Event Types +// https://learn.microsoft.com/en-us/windows/console/input-record-str +const ( + FOCUS_EVENT = 0x0010 + KEY_EVENT = 0x0001 + MENU_EVENT = 0x0008 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 +) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 01c0716..f25b730 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -182,13 +182,17 @@ var ( procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") + procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") + procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") @@ -238,6 +242,7 @@ var ( procFindResourceW = modkernel32.NewProc("FindResourceW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") procFormatMessageW = modkernel32.NewProc("FormatMessageW") @@ -284,6 +289,7 @@ var ( procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") + procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -511,6 +517,7 @@ var ( procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") procWSACleanup = modws2_32.NewProc("WSACleanup") + procWSADuplicateSocketW = modws2_32.NewProc("WSADuplicateSocketW") procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW") procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") procWSAIoctl = modws2_32.NewProc("WSAIoctl") @@ -545,25 +552,25 @@ var ( ) func cm_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_DevNode_Status.Addr(), 4, uintptr(unsafe.Pointer(status)), uintptr(unsafe.Pointer(problemNumber)), uintptr(devInst), uintptr(flags), 0, 0) + r0, _, _ := syscall.SyscallN(procCM_Get_DevNode_Status.Addr(), uintptr(unsafe.Pointer(status)), uintptr(unsafe.Pointer(problemNumber)), uintptr(devInst), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_Get_Device_Interface_List(interfaceClass *GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_ListW.Addr(), 5, uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags), 0) + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_ListW.Addr(), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *GUID, deviceID *uint16, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_List_SizeW.Addr(), 4, uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags), 0, 0) + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_List_SizeW.Addr(), uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_MapCrToWin32Err(configRet CONFIGRET, defaultWin32Error Errno) (ret Errno) { - r0, _, _ := syscall.Syscall(procCM_MapCrToWin32Err.Addr(), 2, uintptr(configRet), uintptr(defaultWin32Error), 0) + r0, _, _ := syscall.SyscallN(procCM_MapCrToWin32Err.Addr(), uintptr(configRet), uintptr(defaultWin32Error)) ret = Errno(r0) return } @@ -573,7 +580,7 @@ func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, if resetToDefault { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procAdjustTokenGroups.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + r1, _, e1 := syscall.SyscallN(procAdjustTokenGroups.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) if r1 == 0 { err = errnoErr(e1) } @@ -585,7 +592,7 @@ func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tok if disableAllPrivileges { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + r1, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) if r1 == 0 { err = errnoErr(e1) } @@ -593,7 +600,7 @@ func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tok } func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) + r1, _, e1 := syscall.SyscallN(procAllocateAndInitializeSid.Addr(), uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid))) if r1 == 0 { err = errnoErr(e1) } @@ -601,7 +608,7 @@ func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, s } func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procBuildSecurityDescriptorW.Addr(), 9, uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) + r0, _, _ := syscall.SyscallN(procBuildSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -609,7 +616,7 @@ func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries } func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) + r1, _, e1 := syscall.SyscallN(procChangeServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -617,7 +624,7 @@ func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err err } func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) + r1, _, e1 := syscall.SyscallN(procChangeServiceConfigW.Addr(), uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName))) if r1 == 0 { err = errnoErr(e1) } @@ -625,7 +632,7 @@ func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, e } func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { - r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + r1, _, e1 := syscall.SyscallN(procCheckTokenMembership.Addr(), uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) if r1 == 0 { err = errnoErr(e1) } @@ -633,7 +640,7 @@ func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) ( } func CloseServiceHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procCloseServiceHandle.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -641,7 +648,7 @@ func CloseServiceHandle(handle Handle) (err error) { } func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) + r1, _, e1 := syscall.SyscallN(procControlService.Addr(), uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -649,7 +656,7 @@ func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err } func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen)), 0) + r1, _, e1 := syscall.SyscallN(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen))) if r1 == 0 { err = errnoErr(e1) } @@ -657,7 +664,7 @@ func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR } func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) + r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid))) if r1 == 0 { err = errnoErr(e1) } @@ -674,7 +681,7 @@ func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision ui } func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -682,7 +689,7 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision } func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) + r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid))) if r1 == 0 { err = errnoErr(e1) } @@ -690,7 +697,7 @@ func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { } func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) + r1, _, e1 := syscall.SyscallN(procCopySid.Addr(), uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) if r1 == 0 { err = errnoErr(e1) } @@ -702,7 +709,7 @@ func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, proc if inheritHandles { _p0 = 1 } - r1, _, e1 := syscall.Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0) + r1, _, e1 := syscall.SyscallN(procCreateProcessAsUserW.Addr(), uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) if r1 == 0 { err = errnoErr(e1) } @@ -710,7 +717,7 @@ func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, proc } func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -719,7 +726,7 @@ func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access } func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreateWellKnownSid.Addr(), 4, uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreateWellKnownSid.Addr(), uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid))) if r1 == 0 { err = errnoErr(e1) } @@ -727,7 +734,7 @@ func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, s } func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptAcquireContextW.Addr(), uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -735,7 +742,7 @@ func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16 } func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { - r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + r1, _, e1 := syscall.SyscallN(procCryptGenRandom.Addr(), uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) if r1 == 0 { err = errnoErr(e1) } @@ -743,7 +750,7 @@ func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { } func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptReleaseContext.Addr(), uintptr(provhandle), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -751,7 +758,7 @@ func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { } func DeleteService(service Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteService.Addr(), uintptr(service)) if r1 == 0 { err = errnoErr(e1) } @@ -759,7 +766,7 @@ func DeleteService(service Handle) (err error) { } func DeregisterEventSource(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeregisterEventSource.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -767,7 +774,7 @@ func DeregisterEventSource(handle Handle) (err error) { } func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) { - r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) + r1, _, e1 := syscall.SyscallN(procDuplicateTokenEx.Addr(), uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) if r1 == 0 { err = errnoErr(e1) } @@ -775,7 +782,7 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes } func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumDependentServicesW.Addr(), 6, uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) + r1, _, e1 := syscall.SyscallN(procEnumDependentServicesW.Addr(), uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) if r1 == 0 { err = errnoErr(e1) } @@ -783,7 +790,7 @@ func EnumDependentServices(service Handle, activityState uint32, services *ENUM_ } func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) + r1, _, e1 := syscall.SyscallN(procEnumServicesStatusExW.Addr(), uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName))) if r1 == 0 { err = errnoErr(e1) } @@ -791,13 +798,13 @@ func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serv } func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { - r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) + r0, _, _ := syscall.SyscallN(procEqualSid.Addr(), uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2))) isEqual = r0 != 0 return } func FreeSid(sid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeSid.Addr(), uintptr(unsafe.Pointer(sid))) if r1 != 0 { err = errnoErr(e1) } @@ -805,7 +812,7 @@ func FreeSid(sid *SID) (err error) { } func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { - r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) + r1, _, e1 := syscall.SyscallN(procGetAce.Addr(), uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) if r1 == 0 { err = errnoErr(e1) } @@ -813,7 +820,7 @@ func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { } func GetLengthSid(sid *SID) (len uint32) { - r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetLengthSid.Addr(), uintptr(unsafe.Pointer(sid))) len = uint32(r0) return } @@ -828,7 +835,7 @@ func getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, security } func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetNamedSecurityInfoW.Addr(), 8, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + r0, _, _ := syscall.SyscallN(procGetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -836,7 +843,7 @@ func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securi } func getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) if r1 == 0 { err = errnoErr(e1) } @@ -852,7 +859,7 @@ func getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl if *daclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1))) *daclPresent = _p0 != 0 *daclDefaulted = _p1 != 0 if r1 == 0 { @@ -866,7 +873,7 @@ func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefau if *groupDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) *groupDefaulted = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -875,7 +882,7 @@ func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefau } func getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorLength.Addr(), uintptr(unsafe.Pointer(sd))) len = uint32(r0) return } @@ -885,7 +892,7 @@ func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefau if *ownerDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) *ownerDefaulted = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -894,7 +901,7 @@ func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefau } func getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -910,7 +917,7 @@ func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl if *saclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1))) *saclPresent = _p0 != 0 *saclDefaulted = _p1 != 0 if r1 == 0 { @@ -920,7 +927,7 @@ func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl } func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + r0, _, _ := syscall.SyscallN(procGetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -928,25 +935,25 @@ func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformati } func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) { - r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSidIdentifierAuthority.Addr(), uintptr(unsafe.Pointer(sid))) authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0)) return } func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(index), 0) + r0, _, _ := syscall.SyscallN(procGetSidSubAuthority.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(index)) subAuthority = (*uint32)(unsafe.Pointer(r0)) return } func getSidSubAuthorityCount(sid *SID) (count *uint8) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSidSubAuthorityCount.Addr(), uintptr(unsafe.Pointer(sid))) count = (*uint8)(unsafe.Pointer(r0)) return } func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) + r1, _, e1 := syscall.SyscallN(procGetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen))) if r1 == 0 { err = errnoErr(e1) } @@ -954,7 +961,7 @@ func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint } func ImpersonateSelf(impersonationlevel uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) + r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(impersonationlevel)) if r1 == 0 { err = errnoErr(e1) } @@ -962,7 +969,7 @@ func ImpersonateSelf(impersonationlevel uint32) (err error) { } func initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) { - r1, _, e1 := syscall.Syscall(procInitializeSecurityDescriptor.Addr(), 2, uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision), 0) + r1, _, e1 := syscall.SyscallN(procInitializeSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision)) if r1 == 0 { err = errnoErr(e1) } @@ -978,7 +985,7 @@ func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint if rebootAfterShutdown { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procInitiateSystemShutdownExW.Addr(), 6, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) + r1, _, e1 := syscall.SyscallN(procInitiateSystemShutdownExW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) if r1 == 0 { err = errnoErr(e1) } @@ -986,7 +993,7 @@ func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint } func isTokenRestricted(tokenHandle Token) (ret bool, err error) { - r0, _, e1 := syscall.Syscall(procIsTokenRestricted.Addr(), 1, uintptr(tokenHandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procIsTokenRestricted.Addr(), uintptr(tokenHandle)) ret = r0 != 0 if !ret { err = errnoErr(e1) @@ -995,25 +1002,25 @@ func isTokenRestricted(tokenHandle Token) (ret bool, err error) { } func isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSecurityDescriptor.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + r0, _, _ := syscall.SyscallN(procIsValidSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(sd))) isValid = r0 != 0 return } func isValidSid(sid *SID) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procIsValidSid.Addr(), uintptr(unsafe.Pointer(sid))) isValid = r0 != 0 return } func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) { - r0, _, _ := syscall.Syscall(procIsWellKnownSid.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(sidType), 0) + r0, _, _ := syscall.SyscallN(procIsWellKnownSid.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(sidType)) isWellKnown = r0 != 0 return } func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) if r1 == 0 { err = errnoErr(e1) } @@ -1021,7 +1028,7 @@ func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen } func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) if r1 == 0 { err = errnoErr(e1) } @@ -1029,7 +1036,7 @@ func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint3 } func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { err = errnoErr(e1) } @@ -1037,7 +1044,7 @@ func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err err } func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall12(procMakeAbsoluteSD.Addr(), 11, uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize)), 0) + r1, _, e1 := syscall.SyscallN(procMakeAbsoluteSD.Addr(), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize))) if r1 == 0 { err = errnoErr(e1) } @@ -1045,7 +1052,7 @@ func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DE } func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMakeSelfRelativeSD.Addr(), 3, uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) + r1, _, e1 := syscall.SyscallN(procMakeSelfRelativeSD.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) if r1 == 0 { err = errnoErr(e1) } @@ -1053,7 +1060,7 @@ func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURIT } func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) { - r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) + r0, _, _ := syscall.SyscallN(procNotifyServiceStatusChangeW.Addr(), uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1061,7 +1068,7 @@ func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERV } func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) + r1, _, e1 := syscall.SyscallN(procOpenProcessToken.Addr(), uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } @@ -1069,7 +1076,7 @@ func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { } func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + r0, _, e1 := syscall.SyscallN(procOpenSCManagerW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1078,7 +1085,7 @@ func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (ha } func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + r0, _, e1 := syscall.SyscallN(procOpenServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1091,7 +1098,7 @@ func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token if openAsSelf { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) + r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } @@ -1099,7 +1106,7 @@ func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token } func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1107,7 +1114,7 @@ func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize } func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceConfigW.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1119,7 +1126,7 @@ func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInf if err != nil { return } - r1, _, e1 := syscall.Syscall(procQueryServiceDynamicInformation.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo)) + r1, _, e1 := syscall.SyscallN(procQueryServiceDynamicInformation.Addr(), uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo)) if r1 == 0 { err = errnoErr(e1) } @@ -1127,7 +1134,7 @@ func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInf } func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceLockStatusW.Addr(), 4, uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceLockStatusW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1135,7 +1142,7 @@ func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, b } func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -1143,7 +1150,7 @@ func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { } func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceStatusEx.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1151,7 +1158,7 @@ func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize } func RegCloseKey(key Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) + r0, _, _ := syscall.SyscallN(procRegCloseKey.Addr(), uintptr(key)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1159,7 +1166,7 @@ func RegCloseKey(key Handle) (regerrno error) { } func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) + r0, _, _ := syscall.SyscallN(procRegEnumKeyExW.Addr(), uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1175,7 +1182,7 @@ func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, if asynchronous { _p1 = 1 } - r0, _, _ := syscall.Syscall6(procRegNotifyChangeKeyValue.Addr(), 5, uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1), 0) + r0, _, _ := syscall.SyscallN(procRegNotifyChangeKeyValue.Addr(), uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1183,7 +1190,7 @@ func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, } func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) + r0, _, _ := syscall.SyscallN(procRegOpenKeyExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1191,7 +1198,7 @@ func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint } func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + r0, _, _ := syscall.SyscallN(procRegQueryInfoKeyW.Addr(), uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1199,7 +1206,7 @@ func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint } func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + r0, _, _ := syscall.SyscallN(procRegQueryValueExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1207,7 +1214,7 @@ func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32 } func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) + r0, _, e1 := syscall.SyscallN(procRegisterEventSourceW.Addr(), uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1216,7 +1223,7 @@ func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Hand } func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterServiceCtrlHandlerExW.Addr(), 3, uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) + r0, _, e1 := syscall.SyscallN(procRegisterServiceCtrlHandlerExW.Addr(), uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1225,7 +1232,7 @@ func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, cont } func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) + r1, _, e1 := syscall.SyscallN(procReportEventW.Addr(), uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) if r1 == 0 { err = errnoErr(e1) } @@ -1233,7 +1240,7 @@ func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrS } func RevertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) + r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr()) if r1 == 0 { err = errnoErr(e1) } @@ -1241,7 +1248,7 @@ func RevertToSelf() (err error) { } func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) { - r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetEntriesInAclW.Addr(), uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1249,7 +1256,7 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE } func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { - r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) + r1, _, e1 := syscall.SyscallN(procSetKernelObjectSecurity.Addr(), uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) if r1 == 0 { err = errnoErr(e1) } @@ -1266,7 +1273,7 @@ func SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, security } func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfoW.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1274,7 +1281,7 @@ func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securi } func setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) { - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) if r1 == 0 { err = errnoErr(e1) } @@ -1290,7 +1297,7 @@ func setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl * if daclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1)) if r1 == 0 { err = errnoErr(e1) } @@ -1302,7 +1309,7 @@ func setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaul if groupDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -1314,7 +1321,7 @@ func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaul if ownerDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -1322,7 +1329,7 @@ func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaul } func setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) { - syscall.Syscall(procSetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) + syscall.SyscallN(procSetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) return } @@ -1335,7 +1342,7 @@ func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl * if saclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1)) if r1 == 0 { err = errnoErr(e1) } @@ -1343,7 +1350,7 @@ func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl * } func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1351,7 +1358,7 @@ func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformati } func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) + r1, _, e1 := syscall.SyscallN(procSetServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceStatus))) if r1 == 0 { err = errnoErr(e1) } @@ -1359,7 +1366,7 @@ func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) } func SetThreadToken(thread *Handle, token Token) (err error) { - r1, _, e1 := syscall.Syscall(procSetThreadToken.Addr(), 2, uintptr(unsafe.Pointer(thread)), uintptr(token), 0) + r1, _, e1 := syscall.SyscallN(procSetThreadToken.Addr(), uintptr(unsafe.Pointer(thread)), uintptr(token)) if r1 == 0 { err = errnoErr(e1) } @@ -1367,7 +1374,7 @@ func SetThreadToken(thread *Handle, token Token) (err error) { } func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen)) if r1 == 0 { err = errnoErr(e1) } @@ -1375,7 +1382,7 @@ func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint } func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) + r1, _, e1 := syscall.SyscallN(procStartServiceCtrlDispatcherW.Addr(), uintptr(unsafe.Pointer(serviceTable))) if r1 == 0 { err = errnoErr(e1) } @@ -1383,7 +1390,7 @@ func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { } func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) + r1, _, e1 := syscall.SyscallN(procStartServiceW.Addr(), uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) if r1 == 0 { err = errnoErr(e1) } @@ -1391,7 +1398,7 @@ func StartService(service Handle, numArgs uint32, argVectors **uint16) (err erro } func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { - r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertAddCertificateContextToStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext))) if r1 == 0 { err = errnoErr(e1) } @@ -1399,7 +1406,7 @@ func CertAddCertificateContextToStore(store Handle, certContext *CertContext, ad } func CertCloseStore(store Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCertCloseStore.Addr(), uintptr(store), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -1407,7 +1414,7 @@ func CertCloseStore(store Handle, flags uint32) (err error) { } func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + r0, _, e1 := syscall.SyscallN(procCertCreateCertificateContext.Addr(), uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) context = (*CertContext)(unsafe.Pointer(r0)) if context == nil { err = errnoErr(e1) @@ -1416,7 +1423,7 @@ func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, en } func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertDeleteCertificateFromStore.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertDeleteCertificateFromStore.Addr(), uintptr(unsafe.Pointer(certContext))) if r1 == 0 { err = errnoErr(e1) } @@ -1424,13 +1431,13 @@ func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { } func CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) { - r0, _, _ := syscall.Syscall(procCertDuplicateCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) + r0, _, _ := syscall.SyscallN(procCertDuplicateCertificateContext.Addr(), uintptr(unsafe.Pointer(certContext))) dupContext = (*CertContext)(unsafe.Pointer(r0)) return } func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) + r0, _, e1 := syscall.SyscallN(procCertEnumCertificatesInStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(prevContext))) context = (*CertContext)(unsafe.Pointer(r0)) if context == nil { err = errnoErr(e1) @@ -1439,7 +1446,7 @@ func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (contex } func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) { - r0, _, e1 := syscall.Syscall6(procCertFindCertificateInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext))) + r0, _, e1 := syscall.SyscallN(procCertFindCertificateInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext))) cert = (*CertContext)(unsafe.Pointer(r0)) if cert == nil { err = errnoErr(e1) @@ -1448,7 +1455,7 @@ func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags } func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) { - r0, _, e1 := syscall.Syscall6(procCertFindChainInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext))) + r0, _, e1 := syscall.SyscallN(procCertFindChainInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext))) certchain = (*CertChainContext)(unsafe.Pointer(r0)) if certchain == nil { err = errnoErr(e1) @@ -1457,18 +1464,18 @@ func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint3 } func CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) { - r0, _, _ := syscall.Syscall(procCertFindExtension.Addr(), 3, uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) + r0, _, _ := syscall.SyscallN(procCertFindExtension.Addr(), uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) ret = (*CertExtension)(unsafe.Pointer(r0)) return } func CertFreeCertificateChain(ctx *CertChainContext) { - syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + syscall.SyscallN(procCertFreeCertificateChain.Addr(), uintptr(unsafe.Pointer(ctx))) return } func CertFreeCertificateContext(ctx *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertFreeCertificateContext.Addr(), uintptr(unsafe.Pointer(ctx))) if r1 == 0 { err = errnoErr(e1) } @@ -1476,7 +1483,7 @@ func CertFreeCertificateContext(ctx *CertContext) (err error) { } func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { - r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) + r1, _, e1 := syscall.SyscallN(procCertGetCertificateChain.Addr(), uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx))) if r1 == 0 { err = errnoErr(e1) } @@ -1484,13 +1491,13 @@ func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, a } func CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) { - r0, _, _ := syscall.Syscall6(procCertGetNameStringW.Addr(), 6, uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) + r0, _, _ := syscall.SyscallN(procCertGetNameStringW.Addr(), uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) chars = uint32(r0) return } func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) + r0, _, e1 := syscall.SyscallN(procCertOpenStore.Addr(), uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1499,7 +1506,7 @@ func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptPr } func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) + r0, _, e1 := syscall.SyscallN(procCertOpenSystemStoreW.Addr(), uintptr(hprov), uintptr(unsafe.Pointer(name))) store = Handle(r0) if store == 0 { err = errnoErr(e1) @@ -1508,7 +1515,7 @@ func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { } func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { - r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertVerifyCertificateChainPolicy.Addr(), uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -1520,7 +1527,7 @@ func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, paramete if *callerFreeProvOrNCryptKey { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procCryptAcquireCertificatePrivateKey.Addr(), 6, uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procCryptAcquireCertificatePrivateKey.Addr(), uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0))) *callerFreeProvOrNCryptKey = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -1529,7 +1536,7 @@ func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, paramete } func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptDecodeObject.Addr(), 7, uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptDecodeObject.Addr(), uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen))) if r1 == 0 { err = errnoErr(e1) } @@ -1537,7 +1544,7 @@ func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte } func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptProtectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptProtectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) if r1 == 0 { err = errnoErr(e1) } @@ -1545,7 +1552,7 @@ func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, } func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0) + r1, _, e1 := syscall.SyscallN(procCryptQueryObject.Addr(), uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context))) if r1 == 0 { err = errnoErr(e1) } @@ -1553,7 +1560,7 @@ func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentT } func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptUnprotectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptUnprotectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) if r1 == 0 { err = errnoErr(e1) } @@ -1561,7 +1568,7 @@ func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBl } func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procPFXImportCertStore.Addr(), uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) store = Handle(r0) if store == 0 { err = errnoErr(e1) @@ -1570,7 +1577,7 @@ func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (sto } func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { - r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) + r0, _, _ := syscall.SyscallN(procDnsNameCompare_W.Addr(), uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2))) same = r0 != 0 return } @@ -1585,7 +1592,7 @@ func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSR } func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + r0, _, _ := syscall.SyscallN(procDnsQuery_W.Addr(), uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) if r0 != 0 { status = syscall.Errno(r0) } @@ -1593,12 +1600,12 @@ func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DN } func DnsRecordListFree(rl *DNSRecord, freetype uint32) { - syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) + syscall.SyscallN(procDnsRecordListFree.Addr(), uintptr(unsafe.Pointer(rl)), uintptr(freetype)) return } func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procDwmGetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + r0, _, _ := syscall.SyscallN(procDwmGetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1606,7 +1613,7 @@ func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si } func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procDwmSetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + r0, _, _ := syscall.SyscallN(procDwmSetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1614,15 +1621,20 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si } func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { - r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0) + r0, _, _ := syscall.SyscallN(procCancelMibChangeNotify2.Addr(), uintptr(notificationHandle)) if r0 != 0 { errcode = syscall.Errno(r0) } return } +func FreeMibTable(memory unsafe.Pointer) { + syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { - r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1630,7 +1642,7 @@ func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapter } func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) + r0, _, _ := syscall.SyscallN(procGetAdaptersInfo.Addr(), uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1638,7 +1650,7 @@ func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { } func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetBestInterfaceEx.Addr(), 2, uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex)), 0) + r0, _, _ := syscall.SyscallN(procGetBestInterfaceEx.Addr(), uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1646,7 +1658,7 @@ func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcod } func GetIfEntry(pIfRow *MibIfRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetIfEntry.Addr(), uintptr(unsafe.Pointer(pIfRow))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1654,7 +1666,23 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { } func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0) + r0, _, _ := syscall.SyscallN(procGetIfEntry2Ex.Addr(), uintptr(level), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1662,7 +1690,7 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { } func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1674,7 +1702,19 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa if initialNotification { _p0 = 1 } - r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + r0, _, _ := syscall.SyscallN(procNotifyIpInterfaceChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1686,7 +1726,7 @@ func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext if initialNotification { _p0 = 1 } - r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + r0, _, _ := syscall.SyscallN(procNotifyUnicastIpAddressChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1694,7 +1734,7 @@ func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext } func AddDllDirectory(path *uint16) (cookie uintptr, err error) { - r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r0, _, e1 := syscall.SyscallN(procAddDllDirectory.Addr(), uintptr(unsafe.Pointer(path))) cookie = uintptr(r0) if cookie == 0 { err = errnoErr(e1) @@ -1703,7 +1743,7 @@ func AddDllDirectory(path *uint16) (cookie uintptr, err error) { } func AssignProcessToJobObject(job Handle, process Handle) (err error) { - r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0) + r1, _, e1 := syscall.SyscallN(procAssignProcessToJobObject.Addr(), uintptr(job), uintptr(process)) if r1 == 0 { err = errnoErr(e1) } @@ -1711,7 +1751,7 @@ func AssignProcessToJobObject(job Handle, process Handle) (err error) { } func CancelIo(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) + r1, _, e1 := syscall.SyscallN(procCancelIo.Addr(), uintptr(s)) if r1 == 0 { err = errnoErr(e1) } @@ -1719,7 +1759,7 @@ func CancelIo(s Handle) (err error) { } func CancelIoEx(s Handle, o *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) + r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(s), uintptr(unsafe.Pointer(o))) if r1 == 0 { err = errnoErr(e1) } @@ -1727,7 +1767,7 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) { } func ClearCommBreak(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procClearCommBreak.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1735,7 +1775,7 @@ func ClearCommBreak(handle Handle) (err error) { } func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) { - r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) + r1, _, e1 := syscall.SyscallN(procClearCommError.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) if r1 == 0 { err = errnoErr(e1) } @@ -1743,7 +1783,7 @@ func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error } func CloseHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procCloseHandle.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1751,12 +1791,12 @@ func CloseHandle(handle Handle) (err error) { } func ClosePseudoConsole(console Handle) { - syscall.Syscall(procClosePseudoConsole.Addr(), 1, uintptr(console), 0, 0) + syscall.SyscallN(procClosePseudoConsole.Addr(), uintptr(console)) return } func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -1764,7 +1804,7 @@ func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { } func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { - r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) + r1, _, e1 := syscall.SyscallN(procCreateDirectoryW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa))) if r1 == 0 { err = errnoErr(e1) } @@ -1772,7 +1812,7 @@ func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { } func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateEventExW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1781,7 +1821,7 @@ func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, d } func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateEventW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1790,7 +1830,7 @@ func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialStat } func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procCreateFileMappingW.Addr(), uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1799,7 +1839,7 @@ func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxS } func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1808,7 +1848,7 @@ func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes } func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procCreateHardLinkW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) if r1&0xff == 0 { err = errnoErr(e1) } @@ -1816,7 +1856,7 @@ func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr } func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1825,7 +1865,7 @@ func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, thr } func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateJobObjectW.Addr(), 2, uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name)), 0) + r0, _, e1 := syscall.SyscallN(procCreateJobObjectW.Addr(), uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1834,7 +1874,7 @@ func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, } func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateMutexExW.Addr(), 4, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateMutexExW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1847,7 +1887,7 @@ func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16 if initialOwner { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procCreateMutexW.Addr(), 3, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procCreateMutexW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1856,7 +1896,7 @@ func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16 } func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) + r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa))) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1865,7 +1905,7 @@ func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances u } func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreatePipe.Addr(), uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -1877,7 +1917,7 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA if inheritHandles { _p0 = 1 } - r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreateProcessW.Addr(), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) if r1 == 0 { err = errnoErr(e1) } @@ -1885,7 +1925,7 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA } func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) { - r0, _, _ := syscall.Syscall6(procCreatePseudoConsole.Addr(), 5, uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole)), 0) + r0, _, _ := syscall.SyscallN(procCreatePseudoConsole.Addr(), uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole))) if r0 != 0 { hr = syscall.Errno(r0) } @@ -1893,7 +1933,7 @@ func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pcons } func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procCreateSymbolicLinkW.Addr(), uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) if r1&0xff == 0 { err = errnoErr(e1) } @@ -1901,7 +1941,7 @@ func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags u } func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) + r0, _, e1 := syscall.SyscallN(procCreateToolhelp32Snapshot.Addr(), uintptr(flags), uintptr(processId)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1910,7 +1950,7 @@ func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, er } func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + r1, _, e1 := syscall.SyscallN(procDefineDosDeviceW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) if r1 == 0 { err = errnoErr(e1) } @@ -1918,7 +1958,7 @@ func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err } func DeleteFile(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteFileW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -1926,12 +1966,12 @@ func DeleteFile(path *uint16) (err error) { } func deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) { - syscall.Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0) + syscall.SyscallN(procDeleteProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist))) return } func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint))) if r1 == 0 { err = errnoErr(e1) } @@ -1939,7 +1979,7 @@ func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { } func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procDeviceIoControl.Addr(), uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -1947,7 +1987,7 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff } func DisconnectNamedPipe(pipe Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0) + r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe)) if r1 == 0 { err = errnoErr(e1) } @@ -1959,7 +1999,7 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP if bInheritHandle { _p0 = 1 } - r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + r1, _, e1 := syscall.SyscallN(procDuplicateHandle.Addr(), uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions)) if r1 == 0 { err = errnoErr(e1) } @@ -1967,7 +2007,7 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP } func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0) + r1, _, e1 := syscall.SyscallN(procEscapeCommFunction.Addr(), uintptr(handle), uintptr(dwFunc)) if r1 == 0 { err = errnoErr(e1) } @@ -1975,12 +2015,12 @@ func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { } func ExitProcess(exitcode uint32) { - syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) + syscall.SyscallN(procExitProcess.Addr(), uintptr(exitcode)) return } func ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procExpandEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -1989,7 +2029,7 @@ func ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, } func FindClose(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindClose.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1997,7 +2037,7 @@ func FindClose(handle Handle) (err error) { } func FindCloseChangeNotification(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindCloseChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindCloseChangeNotification.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2018,7 +2058,7 @@ func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter if watchSubtree { _p1 = 1 } - r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) + r0, _, e1 := syscall.SyscallN(procFindFirstChangeNotificationW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2027,7 +2067,7 @@ func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter } func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) + r0, _, e1 := syscall.SyscallN(procFindFirstFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data))) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2036,7 +2076,7 @@ func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err erro } func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2045,7 +2085,7 @@ func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, b } func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2054,7 +2094,7 @@ func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, er } func FindNextChangeNotification(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindNextChangeNotification.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2062,7 +2102,7 @@ func FindNextChangeNotification(handle Handle) (err error) { } func findNextFile1(handle Handle, data *win32finddata1) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + r1, _, e1 := syscall.SyscallN(procFindNextFileW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) if r1 == 0 { err = errnoErr(e1) } @@ -2070,7 +2110,7 @@ func findNextFile1(handle Handle, data *win32finddata1) (err error) { } func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procFindNextVolumeMountPointW.Addr(), uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2078,7 +2118,7 @@ func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uin } func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procFindNextVolumeW.Addr(), uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2086,7 +2126,7 @@ func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) } func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindResourceW.Addr(), 3, uintptr(module), uintptr(name), uintptr(resType)) + r0, _, e1 := syscall.SyscallN(procFindResourceW.Addr(), uintptr(module), uintptr(name), uintptr(resType)) resInfo = Handle(r0) if resInfo == 0 { err = errnoErr(e1) @@ -2095,7 +2135,7 @@ func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, } func FindVolumeClose(findVolume Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindVolumeClose.Addr(), uintptr(findVolume)) if r1 == 0 { err = errnoErr(e1) } @@ -2103,7 +2143,15 @@ func FindVolumeClose(findVolume Handle) (err error) { } func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindVolumeMountPointClose.Addr(), uintptr(findVolumeMountPoint)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FlushConsoleInputBuffer(console Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) if r1 == 0 { err = errnoErr(e1) } @@ -2111,7 +2159,7 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { } func FlushFileBuffers(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2119,7 +2167,7 @@ func FlushFileBuffers(handle Handle) (err error) { } func FlushViewOfFile(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procFlushViewOfFile.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -2131,7 +2179,7 @@ func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, bu if len(buf) > 0 { _p0 = &buf[0] } - r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) + r0, _, e1 := syscall.SyscallN(procFormatMessageW.Addr(), uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2140,7 +2188,7 @@ func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, bu } func FreeEnvironmentStrings(envs *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(envs))) if r1 == 0 { err = errnoErr(e1) } @@ -2148,7 +2196,7 @@ func FreeEnvironmentStrings(envs *uint16) (err error) { } func FreeLibrary(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeLibrary.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2156,7 +2204,7 @@ func FreeLibrary(handle Handle) (err error) { } func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGenerateConsoleCtrlEvent.Addr(), 2, uintptr(ctrlEvent), uintptr(processGroupID), 0) + r1, _, e1 := syscall.SyscallN(procGenerateConsoleCtrlEvent.Addr(), uintptr(ctrlEvent), uintptr(processGroupID)) if r1 == 0 { err = errnoErr(e1) } @@ -2164,19 +2212,19 @@ func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err erro } func GetACP() (acp uint32) { - r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetACP.Addr()) acp = uint32(r0) return } func GetActiveProcessorCount(groupNumber uint16) (ret uint32) { - r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) + r0, _, _ := syscall.SyscallN(procGetActiveProcessorCount.Addr(), uintptr(groupNumber)) ret = uint32(r0) return } func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommModemStatus.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpModemStat))) if r1 == 0 { err = errnoErr(e1) } @@ -2184,7 +2232,7 @@ func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { } func GetCommState(handle Handle, lpDCB *DCB) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) if r1 == 0 { err = errnoErr(e1) } @@ -2192,7 +2240,7 @@ func GetCommState(handle Handle, lpDCB *DCB) (err error) { } func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) if r1 == 0 { err = errnoErr(e1) } @@ -2200,13 +2248,13 @@ func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { } func GetCommandLine() (cmd *uint16) { - r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCommandLineW.Addr()) cmd = (*uint16)(unsafe.Pointer(r0)) return } func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + r1, _, e1 := syscall.SyscallN(procGetComputerNameExW.Addr(), uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { err = errnoErr(e1) } @@ -2214,7 +2262,7 @@ func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { } func GetComputerName(buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) + r1, _, e1 := syscall.SyscallN(procGetComputerNameW.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { err = errnoErr(e1) } @@ -2222,7 +2270,7 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { } func GetConsoleCP() (cp uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetConsoleCP.Addr()) cp = uint32(r0) if cp == 0 { err = errnoErr(e1) @@ -2231,7 +2279,7 @@ func GetConsoleCP() (cp uint32, err error) { } func GetConsoleMode(console Handle, mode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) + r1, _, e1 := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(console), uintptr(unsafe.Pointer(mode))) if r1 == 0 { err = errnoErr(e1) } @@ -2239,7 +2287,7 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { } func GetConsoleOutputCP() (cp uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetConsoleOutputCP.Addr()) cp = uint32(r0) if cp == 0 { err = errnoErr(e1) @@ -2248,7 +2296,7 @@ func GetConsoleOutputCP() (cp uint32, err error) { } func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) + r1, _, e1 := syscall.SyscallN(procGetConsoleScreenBufferInfo.Addr(), uintptr(console), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -2256,7 +2304,7 @@ func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) ( } func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + r0, _, e1 := syscall.SyscallN(procGetCurrentDirectoryW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2265,19 +2313,19 @@ func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { } func GetCurrentProcessId() (pid uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCurrentProcessId.Addr()) pid = uint32(r0) return } func GetCurrentThreadId() (id uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCurrentThreadId.Addr()) id = uint32(r0) return } func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { - r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetDiskFreeSpaceExW.Addr(), uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes))) if r1 == 0 { err = errnoErr(e1) } @@ -2285,13 +2333,13 @@ func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint6 } func GetDriveType(rootPathName *uint16) (driveType uint32) { - r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetDriveTypeW.Addr(), uintptr(unsafe.Pointer(rootPathName))) driveType = uint32(r0) return } func GetEnvironmentStrings() (envs *uint16, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetEnvironmentStringsW.Addr()) envs = (*uint16)(unsafe.Pointer(r0)) if envs == nil { err = errnoErr(e1) @@ -2300,7 +2348,7 @@ func GetEnvironmentStrings() (envs *uint16, err error) { } func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procGetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2309,7 +2357,7 @@ func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32 } func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) + r1, _, e1 := syscall.SyscallN(procGetExitCodeProcess.Addr(), uintptr(handle), uintptr(unsafe.Pointer(exitcode))) if r1 == 0 { err = errnoErr(e1) } @@ -2317,7 +2365,7 @@ func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { } func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) + r1, _, e1 := syscall.SyscallN(procGetFileAttributesExW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -2325,7 +2373,7 @@ func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { } func GetFileAttributes(name *uint16) (attrs uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name))) attrs = uint32(r0) if attrs == INVALID_FILE_ATTRIBUTES { err = errnoErr(e1) @@ -2334,7 +2382,7 @@ func GetFileAttributes(name *uint16) (attrs uint32, err error) { } func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandle.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) if r1 == 0 { err = errnoErr(e1) } @@ -2342,7 +2390,7 @@ func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (e } func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandleEx.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen)) if r1 == 0 { err = errnoErr(e1) } @@ -2350,7 +2398,7 @@ func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, } func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) if r1 == 0 { err = errnoErr(e1) } @@ -2358,7 +2406,7 @@ func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim } func GetFileType(filehandle Handle) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFileType.Addr(), uintptr(filehandle)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2367,7 +2415,7 @@ func GetFileType(filehandle Handle) (n uint32, err error) { } func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFinalPathNameByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2376,7 +2424,7 @@ func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32 } func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFullPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2385,13 +2433,13 @@ func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) ( } func GetLargePageMinimum() (size uintptr) { - r0, _, _ := syscall.Syscall(procGetLargePageMinimum.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetLargePageMinimum.Addr()) size = uintptr(r0) return } func GetLastError() (lasterr error) { - r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetLastError.Addr()) if r0 != 0 { lasterr = syscall.Errno(r0) } @@ -2399,7 +2447,7 @@ func GetLastError() (lasterr error) { } func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + r0, _, e1 := syscall.SyscallN(procGetLogicalDriveStringsW.Addr(), uintptr(bufferLength), uintptr(unsafe.Pointer(buffer))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2408,7 +2456,7 @@ func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err } func GetLogicalDrives() (drivesBitMask uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetLogicalDrives.Addr()) drivesBitMask = uint32(r0) if drivesBitMask == 0 { err = errnoErr(e1) @@ -2417,7 +2465,7 @@ func GetLogicalDrives() (drivesBitMask uint32, err error) { } func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + r0, _, e1 := syscall.SyscallN(procGetLongPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2426,13 +2474,13 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er } func GetMaximumProcessorCount(groupNumber uint16) (ret uint32) { - r0, _, _ := syscall.Syscall(procGetMaximumProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) + r0, _, _ := syscall.SyscallN(procGetMaximumProcessorCount.Addr(), uintptr(groupNumber)) ret = uint32(r0) return } func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procGetModuleFileNameW.Addr(), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2441,7 +2489,7 @@ func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, } func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) { - r1, _, e1 := syscall.Syscall(procGetModuleHandleExW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) + r1, _, e1 := syscall.SyscallN(procGetModuleHandleExW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) if r1 == 0 { err = errnoErr(e1) } @@ -2449,7 +2497,7 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er } func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeClientProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID))) if r1 == 0 { err = errnoErr(e1) } @@ -2457,7 +2505,7 @@ func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err erro } func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2465,7 +2513,7 @@ func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, m } func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances))) if r1 == 0 { err = errnoErr(e1) } @@ -2473,7 +2521,15 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3 } func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeServerProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) if r1 == 0 { err = errnoErr(e1) } @@ -2485,7 +2541,7 @@ func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wa if wait { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetOverlappedResult.Addr(), uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -2493,7 +2549,7 @@ func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wa } func GetPriorityClass(process Handle) (ret uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetPriorityClass.Addr(), 1, uintptr(process), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetPriorityClass.Addr(), uintptr(process)) ret = uint32(r0) if ret == 0 { err = errnoErr(e1) @@ -2511,7 +2567,7 @@ func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { } func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) + r0, _, e1 := syscall.SyscallN(procGetProcAddress.Addr(), uintptr(module), uintptr(unsafe.Pointer(procname))) proc = uintptr(r0) if proc == 0 { err = errnoErr(e1) @@ -2520,7 +2576,7 @@ func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { } func GetProcessId(process Handle) (id uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetProcessId.Addr(), 1, uintptr(process), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetProcessId.Addr(), uintptr(process)) id = uint32(r0) if id == 0 { err = errnoErr(e1) @@ -2529,7 +2585,7 @@ func GetProcessId(process Handle) (id uint32, err error) { } func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetProcessPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2537,7 +2593,7 @@ func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uin } func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessShutdownParameters.Addr(), 2, uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags)), 0) + r1, _, e1 := syscall.SyscallN(procGetProcessShutdownParameters.Addr(), uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags))) if r1 == 0 { err = errnoErr(e1) } @@ -2545,7 +2601,7 @@ func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { } func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + r1, _, e1 := syscall.SyscallN(procGetProcessTimes.Addr(), uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) if r1 == 0 { err = errnoErr(e1) } @@ -2553,12 +2609,12 @@ func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, } func GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) { - syscall.Syscall6(procGetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags)), 0, 0) + syscall.SyscallN(procGetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags))) return } func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) + r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout)) if r1 == 0 { err = errnoErr(e1) } @@ -2566,7 +2622,7 @@ func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overl } func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + r0, _, e1 := syscall.SyscallN(procGetShortPathNameW.Addr(), uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2575,12 +2631,12 @@ func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uin } func getStartupInfo(startupInfo *StartupInfo) { - syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) + syscall.SyscallN(procGetStartupInfoW.Addr(), uintptr(unsafe.Pointer(startupInfo))) return } func GetStdHandle(stdhandle uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetStdHandle.Addr(), uintptr(stdhandle)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2589,7 +2645,7 @@ func GetStdHandle(stdhandle uint32) (handle Handle, err error) { } func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetSystemDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2598,7 +2654,7 @@ func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { } func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetSystemPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSystemPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2606,17 +2662,17 @@ func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint } func GetSystemTimeAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + syscall.SyscallN(procGetSystemTimeAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) return } func GetSystemTimePreciseAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + syscall.SyscallN(procGetSystemTimePreciseAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) return } func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetSystemWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2625,7 +2681,7 @@ func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err erro } func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + r0, _, e1 := syscall.SyscallN(procGetTempPathW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2634,7 +2690,7 @@ func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { } func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetThreadPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetThreadPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2642,13 +2698,13 @@ func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint } func getTickCount64() (ms uint64) { - r0, _, _ := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetTickCount64.Addr()) ms = uint64(r0) return } func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetTimeZoneInformation.Addr(), uintptr(unsafe.Pointer(tzi))) rc = uint32(r0) if rc == 0xffffffff { err = errnoErr(e1) @@ -2657,7 +2713,7 @@ func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { } func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetUserPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetUserPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2665,7 +2721,7 @@ func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16 } func GetVersion() (ver uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetVersion.Addr()) ver = uint32(r0) if ver == 0 { err = errnoErr(e1) @@ -2674,7 +2730,7 @@ func GetVersion() (ver uint32, err error) { } func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2682,7 +2738,7 @@ func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeN } func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2690,7 +2746,7 @@ func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volume } func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) + r1, _, e1 := syscall.SyscallN(procGetVolumeNameForVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) if r1 == 0 { err = errnoErr(e1) } @@ -2698,7 +2754,7 @@ func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint } func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procGetVolumePathNameW.Addr(), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2706,7 +2762,7 @@ func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength ui } func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetVolumePathNamesForVolumeNameW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength))) if r1 == 0 { err = errnoErr(e1) } @@ -2714,7 +2770,7 @@ func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16 } func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2723,7 +2779,7 @@ func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { } func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procInitializeProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -2735,7 +2791,7 @@ func IsWow64Process(handle Handle, isWow64 *bool) (err error) { if *isWow64 { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procIsWow64Process.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(&_p0)), 0) + r1, _, e1 := syscall.SyscallN(procIsWow64Process.Addr(), uintptr(handle), uintptr(unsafe.Pointer(&_p0))) *isWow64 = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -2748,7 +2804,7 @@ func IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint1 if err != nil { return } - r1, _, e1 := syscall.Syscall(procIsWow64Process2.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) + r1, _, e1 := syscall.SyscallN(procIsWow64Process2.Addr(), uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) if r1 == 0 { err = errnoErr(e1) } @@ -2765,7 +2821,7 @@ func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, e } func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procLoadLibraryExW.Addr(), uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2783,7 +2839,7 @@ func LoadLibrary(libname string) (handle Handle, err error) { } func _LoadLibrary(libname *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) + r0, _, e1 := syscall.SyscallN(procLoadLibraryW.Addr(), uintptr(unsafe.Pointer(libname))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2792,7 +2848,7 @@ func _LoadLibrary(libname *uint16) (handle Handle, err error) { } func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0) + r0, _, e1 := syscall.SyscallN(procLoadResource.Addr(), uintptr(module), uintptr(resInfo)) resData = Handle(r0) if resData == 0 { err = errnoErr(e1) @@ -2801,7 +2857,7 @@ func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) { } func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) { - r0, _, e1 := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(length), 0) + r0, _, e1 := syscall.SyscallN(procLocalAlloc.Addr(), uintptr(flags), uintptr(length)) ptr = uintptr(r0) if ptr == 0 { err = errnoErr(e1) @@ -2810,7 +2866,7 @@ func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) { } func LocalFree(hmem Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) + r0, _, e1 := syscall.SyscallN(procLocalFree.Addr(), uintptr(hmem)) handle = Handle(r0) if handle != 0 { err = errnoErr(e1) @@ -2819,7 +2875,7 @@ func LocalFree(hmem Handle) (handle Handle, err error) { } func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) + r1, _, e1 := syscall.SyscallN(procLockFileEx.Addr(), uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -2827,7 +2883,7 @@ func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, byt } func LockResource(resData Handle) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall(procLockResource.Addr(), 1, uintptr(resData), 0, 0) + r0, _, e1 := syscall.SyscallN(procLockResource.Addr(), uintptr(resData)) addr = uintptr(r0) if addr == 0 { err = errnoErr(e1) @@ -2836,7 +2892,7 @@ func LockResource(resData Handle) (addr uintptr, err error) { } func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) + r0, _, e1 := syscall.SyscallN(procMapViewOfFile.Addr(), uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length)) addr = uintptr(r0) if addr == 0 { err = errnoErr(e1) @@ -2845,7 +2901,7 @@ func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow ui } func Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procModule32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0) + r1, _, e1 := syscall.SyscallN(procModule32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2853,7 +2909,7 @@ func Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { } func Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procModule32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0) + r1, _, e1 := syscall.SyscallN(procModule32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2861,7 +2917,7 @@ func Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { } func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procMoveFileExW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -2869,7 +2925,7 @@ func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { } func MoveFile(from *uint16, to *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) + r1, _, e1 := syscall.SyscallN(procMoveFileW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to))) if r1 == 0 { err = errnoErr(e1) } @@ -2877,7 +2933,7 @@ func MoveFile(from *uint16, to *uint16) (err error) { } func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { - r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + r0, _, e1 := syscall.SyscallN(procMultiByteToWideChar.Addr(), uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) nwrite = int32(r0) if nwrite == 0 { err = errnoErr(e1) @@ -2890,7 +2946,7 @@ func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle H if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procOpenEventW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2903,7 +2959,7 @@ func OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle H if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenMutexW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procOpenMutexW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2916,7 +2972,7 @@ func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (ha if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) + r0, _, e1 := syscall.SyscallN(procOpenProcess.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2929,7 +2985,7 @@ func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (hand if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenThread.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) + r0, _, e1 := syscall.SyscallN(procOpenThread.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2938,7 +2994,7 @@ func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (hand } func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) + r1, _, e1 := syscall.SyscallN(procPostQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -2946,7 +3002,7 @@ func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overla } func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + r1, _, e1 := syscall.SyscallN(procProcess32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2954,7 +3010,7 @@ func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { } func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + r1, _, e1 := syscall.SyscallN(procProcess32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2962,7 +3018,7 @@ func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { } func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procProcessIdToSessionId.Addr(), 2, uintptr(pid), uintptr(unsafe.Pointer(sessionid)), 0) + r1, _, e1 := syscall.SyscallN(procProcessIdToSessionId.Addr(), uintptr(pid), uintptr(unsafe.Pointer(sessionid))) if r1 == 0 { err = errnoErr(e1) } @@ -2970,7 +3026,7 @@ func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { } func PulseEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procPulseEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -2978,7 +3034,7 @@ func PulseEvent(event Handle) (err error) { } func PurgeComm(handle Handle, dwFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0) + r1, _, e1 := syscall.SyscallN(procPurgeComm.Addr(), uintptr(handle), uintptr(dwFlags)) if r1 == 0 { err = errnoErr(e1) } @@ -2986,7 +3042,7 @@ func PurgeComm(handle Handle, dwFlags uint32) (err error) { } func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + r0, _, e1 := syscall.SyscallN(procQueryDosDeviceW.Addr(), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2995,7 +3051,7 @@ func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint3 } func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryFullProcessImageNameW.Addr(), 4, uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryFullProcessImageNameW.Addr(), uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -3003,7 +3059,7 @@ func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size } func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0) + r1, _, e1 := syscall.SyscallN(procQueryInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen))) if r1 == 0 { err = errnoErr(e1) } @@ -3011,7 +3067,7 @@ func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobO } func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) + r1, _, e1 := syscall.SyscallN(procReadConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl))) if r1 == 0 { err = errnoErr(e1) } @@ -3023,7 +3079,7 @@ func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree if watchSubTree { _p0 = 1 } - r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + r1, _, e1 := syscall.SyscallN(procReadDirectoryChangesW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) if r1 == 0 { err = errnoErr(e1) } @@ -3035,7 +3091,7 @@ func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) ( if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procReadFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3043,7 +3099,7 @@ func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) ( } func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead)), 0) + r1, _, e1 := syscall.SyscallN(procReadProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead))) if r1 == 0 { err = errnoErr(e1) } @@ -3051,7 +3107,7 @@ func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size u } func ReleaseMutex(mutex Handle) (err error) { - r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0) + r1, _, e1 := syscall.SyscallN(procReleaseMutex.Addr(), uintptr(mutex)) if r1 == 0 { err = errnoErr(e1) } @@ -3059,7 +3115,7 @@ func ReleaseMutex(mutex Handle) (err error) { } func RemoveDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procRemoveDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3067,7 +3123,7 @@ func RemoveDirectory(path *uint16) (err error) { } func RemoveDllDirectory(cookie uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0) + r1, _, e1 := syscall.SyscallN(procRemoveDllDirectory.Addr(), uintptr(cookie)) if r1 == 0 { err = errnoErr(e1) } @@ -3075,7 +3131,7 @@ func RemoveDllDirectory(cookie uintptr) (err error) { } func ResetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procResetEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -3083,7 +3139,7 @@ func ResetEvent(event Handle) (err error) { } func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { - r0, _, _ := syscall.Syscall(procResizePseudoConsole.Addr(), 2, uintptr(pconsole), uintptr(size), 0) + r0, _, _ := syscall.SyscallN(procResizePseudoConsole.Addr(), uintptr(pconsole), uintptr(size)) if r0 != 0 { hr = syscall.Errno(r0) } @@ -3091,7 +3147,7 @@ func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { } func ResumeThread(thread Handle) (ret uint32, err error) { - r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0) + r0, _, e1 := syscall.SyscallN(procResumeThread.Addr(), uintptr(thread)) ret = uint32(r0) if ret == 0xffffffff { err = errnoErr(e1) @@ -3100,7 +3156,7 @@ func ResumeThread(thread Handle) (ret uint32, err error) { } func SetCommBreak(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetCommBreak.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3108,7 +3164,7 @@ func SetCommBreak(handle Handle) (err error) { } func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0) + r1, _, e1 := syscall.SyscallN(procSetCommMask.Addr(), uintptr(handle), uintptr(dwEvtMask)) if r1 == 0 { err = errnoErr(e1) } @@ -3116,7 +3172,7 @@ func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { } func SetCommState(handle Handle, lpDCB *DCB) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + r1, _, e1 := syscall.SyscallN(procSetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) if r1 == 0 { err = errnoErr(e1) } @@ -3124,7 +3180,7 @@ func SetCommState(handle Handle, lpDCB *DCB) (err error) { } func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + r1, _, e1 := syscall.SyscallN(procSetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) if r1 == 0 { err = errnoErr(e1) } @@ -3132,7 +3188,7 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { } func SetConsoleCP(cp uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleCP.Addr(), uintptr(cp)) if r1 == 0 { err = errnoErr(e1) } @@ -3140,7 +3196,7 @@ func SetConsoleCP(cp uint32) (err error) { } func setConsoleCursorPosition(console Handle, position uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleCursorPosition.Addr(), uintptr(console), uintptr(position)) if r1 == 0 { err = errnoErr(e1) } @@ -3148,7 +3204,7 @@ func setConsoleCursorPosition(console Handle, position uint32) (err error) { } func SetConsoleMode(console Handle, mode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(console), uintptr(mode)) if r1 == 0 { err = errnoErr(e1) } @@ -3156,7 +3212,7 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { } func SetConsoleOutputCP(cp uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleOutputCP.Addr(), uintptr(cp)) if r1 == 0 { err = errnoErr(e1) } @@ -3164,7 +3220,7 @@ func SetConsoleOutputCP(cp uint32) (err error) { } func SetCurrentDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetCurrentDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3172,7 +3228,7 @@ func SetCurrentDirectory(path *uint16) (err error) { } func SetDefaultDllDirectories(directoryFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetDefaultDllDirectories.Addr(), 1, uintptr(directoryFlags), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetDefaultDllDirectories.Addr(), uintptr(directoryFlags)) if r1 == 0 { err = errnoErr(e1) } @@ -3189,7 +3245,7 @@ func SetDllDirectory(path string) (err error) { } func _SetDllDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetDllDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetDllDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3197,7 +3253,7 @@ func _SetDllDirectory(path *uint16) (err error) { } func SetEndOfFile(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetEndOfFile.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3205,7 +3261,7 @@ func SetEndOfFile(handle Handle) (err error) { } func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) + r1, _, e1 := syscall.SyscallN(procSetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value))) if r1 == 0 { err = errnoErr(e1) } @@ -3213,13 +3269,13 @@ func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { } func SetErrorMode(mode uint32) (ret uint32) { - r0, _, _ := syscall.Syscall(procSetErrorMode.Addr(), 1, uintptr(mode), 0, 0) + r0, _, _ := syscall.SyscallN(procSetErrorMode.Addr(), uintptr(mode)) ret = uint32(r0) return } func SetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -3227,7 +3283,7 @@ func SetEvent(event Handle) (err error) { } func SetFileAttributes(name *uint16, attrs uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + r1, _, e1 := syscall.SyscallN(procSetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(attrs)) if r1 == 0 { err = errnoErr(e1) } @@ -3235,7 +3291,7 @@ func SetFileAttributes(name *uint16, attrs uint32) (err error) { } func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(handle), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3243,7 +3299,7 @@ func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) } func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetFileInformationByHandle.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen)) if r1 == 0 { err = errnoErr(e1) } @@ -3251,7 +3307,7 @@ func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inB } func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { - r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetFilePointer.Addr(), uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence)) newlowoffset = uint32(r0) if newlowoffset == 0xffffffff { err = errnoErr(e1) @@ -3260,7 +3316,7 @@ func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence } func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) if r1 == 0 { err = errnoErr(e1) } @@ -3268,7 +3324,7 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim } func SetFileValidData(handle Handle, validDataLength int64) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + r1, _, e1 := syscall.SyscallN(procSetFileValidData.Addr(), uintptr(handle), uintptr(validDataLength)) if r1 == 0 { err = errnoErr(e1) } @@ -3276,7 +3332,7 @@ func SetFileValidData(handle Handle, validDataLength int64) (err error) { } func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procSetHandleInformation.Addr(), uintptr(handle), uintptr(mask), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3284,7 +3340,7 @@ func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) } func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { - r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength)) ret = int(r0) if ret == 0 { err = errnoErr(e1) @@ -3293,7 +3349,7 @@ func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobOb } func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetNamedPipeHandleState.Addr(), 4, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetNamedPipeHandleState.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout))) if r1 == 0 { err = errnoErr(e1) } @@ -3301,7 +3357,7 @@ func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uin } func SetPriorityClass(process Handle, priorityClass uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetPriorityClass.Addr(), 2, uintptr(process), uintptr(priorityClass), 0) + r1, _, e1 := syscall.SyscallN(procSetPriorityClass.Addr(), uintptr(process), uintptr(priorityClass)) if r1 == 0 { err = errnoErr(e1) } @@ -3313,7 +3369,7 @@ func SetProcessPriorityBoost(process Handle, disable bool) (err error) { if disable { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetProcessPriorityBoost.Addr(), 2, uintptr(process), uintptr(_p0), 0) + r1, _, e1 := syscall.SyscallN(procSetProcessPriorityBoost.Addr(), uintptr(process), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -3321,7 +3377,7 @@ func SetProcessPriorityBoost(process Handle, disable bool) (err error) { } func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetProcessShutdownParameters.Addr(), 2, uintptr(level), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetProcessShutdownParameters.Addr(), uintptr(level), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3329,7 +3385,7 @@ func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { } func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3337,7 +3393,7 @@ func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr } func SetStdHandle(stdhandle uint32, handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + r1, _, e1 := syscall.SyscallN(procSetStdHandle.Addr(), uintptr(stdhandle), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3345,7 +3401,7 @@ func SetStdHandle(stdhandle uint32, handle Handle) (err error) { } func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) + r1, _, e1 := syscall.SyscallN(procSetVolumeLabelW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName))) if r1 == 0 { err = errnoErr(e1) } @@ -3353,7 +3409,7 @@ func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { } func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) + r1, _, e1 := syscall.SyscallN(procSetVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName))) if r1 == 0 { err = errnoErr(e1) } @@ -3361,7 +3417,7 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro } func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) + r1, _, e1 := syscall.SyscallN(procSetupComm.Addr(), uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) if r1 == 0 { err = errnoErr(e1) } @@ -3369,7 +3425,7 @@ func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { } func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) { - r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0) + r0, _, e1 := syscall.SyscallN(procSizeofResource.Addr(), uintptr(module), uintptr(resInfo)) size = uint32(r0) if size == 0 { err = errnoErr(e1) @@ -3382,13 +3438,13 @@ func SleepEx(milliseconds uint32, alertable bool) (ret uint32) { if alertable { _p0 = 1 } - r0, _, _ := syscall.Syscall(procSleepEx.Addr(), 2, uintptr(milliseconds), uintptr(_p0), 0) + r0, _, _ := syscall.SyscallN(procSleepEx.Addr(), uintptr(milliseconds), uintptr(_p0)) ret = uint32(r0) return } func TerminateJobObject(job Handle, exitCode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateJobObject.Addr(), 2, uintptr(job), uintptr(exitCode), 0) + r1, _, e1 := syscall.SyscallN(procTerminateJobObject.Addr(), uintptr(job), uintptr(exitCode)) if r1 == 0 { err = errnoErr(e1) } @@ -3396,7 +3452,7 @@ func TerminateJobObject(job Handle, exitCode uint32) (err error) { } func TerminateProcess(handle Handle, exitcode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + r1, _, e1 := syscall.SyscallN(procTerminateProcess.Addr(), uintptr(handle), uintptr(exitcode)) if r1 == 0 { err = errnoErr(e1) } @@ -3404,7 +3460,7 @@ func TerminateProcess(handle Handle, exitcode uint32) (err error) { } func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32First.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) + r1, _, e1 := syscall.SyscallN(procThread32First.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -3412,7 +3468,7 @@ func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { } func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32Next.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) + r1, _, e1 := syscall.SyscallN(procThread32Next.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -3420,7 +3476,7 @@ func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { } func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procUnlockFileEx.Addr(), uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3428,7 +3484,7 @@ func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint3 } func UnmapViewOfFile(addr uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) + r1, _, e1 := syscall.SyscallN(procUnmapViewOfFile.Addr(), uintptr(addr)) if r1 == 0 { err = errnoErr(e1) } @@ -3436,7 +3492,7 @@ func UnmapViewOfFile(addr uintptr) (err error) { } func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procUpdateProcThreadAttribute.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize))) if r1 == 0 { err = errnoErr(e1) } @@ -3444,7 +3500,7 @@ func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, } func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) + r0, _, e1 := syscall.SyscallN(procVirtualAlloc.Addr(), uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect)) value = uintptr(r0) if value == 0 { err = errnoErr(e1) @@ -3453,7 +3509,7 @@ func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint3 } func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) + r1, _, e1 := syscall.SyscallN(procVirtualFree.Addr(), uintptr(address), uintptr(size), uintptr(freetype)) if r1 == 0 { err = errnoErr(e1) } @@ -3461,7 +3517,7 @@ func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { } func VirtualLock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procVirtualLock.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3469,7 +3525,7 @@ func VirtualLock(addr uintptr, length uintptr) (err error) { } func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) + r1, _, e1 := syscall.SyscallN(procVirtualProtect.Addr(), uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect))) if r1 == 0 { err = errnoErr(e1) } @@ -3477,7 +3533,7 @@ func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect } func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtectEx.Addr(), 5, uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect)), 0) + r1, _, e1 := syscall.SyscallN(procVirtualProtectEx.Addr(), uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect))) if r1 == 0 { err = errnoErr(e1) } @@ -3485,7 +3541,7 @@ func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect } func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) + r1, _, e1 := syscall.SyscallN(procVirtualQuery.Addr(), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3493,7 +3549,7 @@ func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintpt } func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualQueryEx.Addr(), 4, uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length), 0, 0) + r1, _, e1 := syscall.SyscallN(procVirtualQueryEx.Addr(), uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3501,7 +3557,7 @@ func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformat } func VirtualUnlock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procVirtualUnlock.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3509,13 +3565,13 @@ func VirtualUnlock(addr uintptr, length uintptr) (err error) { } func WTSGetActiveConsoleSessionId() (sessionID uint32) { - r0, _, _ := syscall.Syscall(procWTSGetActiveConsoleSessionId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procWTSGetActiveConsoleSessionId.Addr()) sessionID = uint32(r0) return } func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) + r1, _, e1 := syscall.SyscallN(procWaitCommEvent.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3527,7 +3583,7 @@ func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMil if waitAll { _p0 = 1 } - r0, _, e1 := syscall.Syscall6(procWaitForMultipleObjects.Addr(), 4, uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds), 0, 0) + r0, _, e1 := syscall.SyscallN(procWaitForMultipleObjects.Addr(), uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds)) event = uint32(r0) if event == 0xffffffff { err = errnoErr(e1) @@ -3536,7 +3592,7 @@ func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMil } func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { - r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) + r0, _, e1 := syscall.SyscallN(procWaitForSingleObject.Addr(), uintptr(handle), uintptr(waitMilliseconds)) event = uint32(r0) if event == 0xffffffff { err = errnoErr(e1) @@ -3545,7 +3601,7 @@ func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, } func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) + r1, _, e1 := syscall.SyscallN(procWriteConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved))) if r1 == 0 { err = errnoErr(e1) } @@ -3557,7 +3613,7 @@ func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procWriteFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3565,7 +3621,7 @@ func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) } func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten)), 0) + r1, _, e1 := syscall.SyscallN(procWriteProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten))) if r1 == 0 { err = errnoErr(e1) } @@ -3573,7 +3629,7 @@ func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size } func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procAcceptEx.Addr(), uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3581,12 +3637,12 @@ func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32 } func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { - syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) + syscall.SyscallN(procGetAcceptExSockaddrs.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen))) return } func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) + r1, _, e1 := syscall.SyscallN(procTransmitFile.Addr(), uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3594,7 +3650,7 @@ func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint } func NetApiBufferFree(buf *byte) (neterr error) { - r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) + r0, _, _ := syscall.SyscallN(procNetApiBufferFree.Addr(), uintptr(unsafe.Pointer(buf))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3602,7 +3658,7 @@ func NetApiBufferFree(buf *byte) (neterr error) { } func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { - r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + r0, _, _ := syscall.SyscallN(procNetGetJoinInformation.Addr(), uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3610,7 +3666,7 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete } func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) { - r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0) + r0, _, _ := syscall.SyscallN(procNetUserEnum.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3618,7 +3674,7 @@ func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, pr } func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { - r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) + r0, _, _ := syscall.SyscallN(procNetUserGetInfo.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3626,7 +3682,7 @@ func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **by } func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength), 0) + r0, _, _ := syscall.SyscallN(procNtCreateFile.Addr(), uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3634,7 +3690,7 @@ func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO } func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) { - r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) + r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3642,7 +3698,7 @@ func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, i } func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen)), 0) + r0, _, _ := syscall.SyscallN(procNtQueryInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3650,7 +3706,7 @@ func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe } func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen)), 0, 0) + r0, _, _ := syscall.SyscallN(procNtQuerySystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3658,7 +3714,7 @@ func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInf } func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class), 0) + r0, _, _ := syscall.SyscallN(procNtSetInformationFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3666,7 +3722,7 @@ func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, } func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtSetInformationProcess.Addr(), 4, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), 0, 0) + r0, _, _ := syscall.SyscallN(procNtSetInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3674,7 +3730,7 @@ func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.P } func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall(procNtSetSystemInformation.Addr(), 3, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) + r0, _, _ := syscall.SyscallN(procNtSetSystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3682,13 +3738,13 @@ func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoL } func RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) { - r0, _, _ := syscall.Syscall(procRtlAddFunctionTable.Addr(), 3, uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) + r0, _, _ := syscall.SyscallN(procRtlAddFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) ret = r0 != 0 return } func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { - r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(acl)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(acl))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3696,13 +3752,13 @@ func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { } func RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) { - r0, _, _ := syscall.Syscall(procRtlDeleteFunctionTable.Addr(), 1, uintptr(unsafe.Pointer(functionTable)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDeleteFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable))) ret = r0 != 0 return } func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3710,7 +3766,7 @@ func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFile } func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3718,18 +3774,18 @@ func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString } func RtlGetCurrentPeb() (peb *PEB) { - r0, _, _ := syscall.Syscall(procRtlGetCurrentPeb.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procRtlGetCurrentPeb.Addr()) peb = (*PEB)(unsafe.Pointer(r0)) return } func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { - syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) + syscall.SyscallN(procRtlGetNtVersionNumbers.Addr(), uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) return } func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { - r0, _, _ := syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlGetVersion.Addr(), uintptr(unsafe.Pointer(info))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3737,23 +3793,23 @@ func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { } func RtlInitString(destinationString *NTString, sourceString *byte) { - syscall.Syscall(procRtlInitString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0) + syscall.SyscallN(procRtlInitString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) return } func RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) { - syscall.Syscall(procRtlInitUnicodeString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0) + syscall.SyscallN(procRtlInitUnicodeString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) return } func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { - r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(ntstatus)) ret = syscall.Errno(r0) return } func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0) + r0, _, _ := syscall.SyscallN(procCLSIDFromString.Addr(), uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3761,7 +3817,7 @@ func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { } func coCreateGuid(pguid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCoCreateGuid.Addr(), 1, uintptr(unsafe.Pointer(pguid)), 0, 0) + r0, _, _ := syscall.SyscallN(procCoCreateGuid.Addr(), uintptr(unsafe.Pointer(pguid))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3769,7 +3825,7 @@ func coCreateGuid(pguid *GUID) (ret error) { } func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) { - r0, _, _ := syscall.Syscall6(procCoGetObject.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable)), 0, 0) + r0, _, _ := syscall.SyscallN(procCoGetObject.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3777,7 +3833,7 @@ func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable * } func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) { - r0, _, _ := syscall.Syscall(procCoInitializeEx.Addr(), 2, uintptr(reserved), uintptr(coInit), 0) + r0, _, _ := syscall.SyscallN(procCoInitializeEx.Addr(), uintptr(reserved), uintptr(coInit)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3785,23 +3841,23 @@ func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) { } func CoTaskMemFree(address unsafe.Pointer) { - syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(address), 0, 0) + syscall.SyscallN(procCoTaskMemFree.Addr(), uintptr(address)) return } func CoUninitialize() { - syscall.Syscall(procCoUninitialize.Addr(), 0, 0, 0, 0) + syscall.SyscallN(procCoUninitialize.Addr()) return } func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) { - r0, _, _ := syscall.Syscall(procStringFromGUID2.Addr(), 3, uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) + r0, _, _ := syscall.SyscallN(procStringFromGUID2.Addr(), uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) chars = int32(r0) return } func EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumProcessModules.Addr(), 4, uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procEnumProcessModules.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -3809,7 +3865,7 @@ func EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uin } func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumProcessModulesEx.Addr(), 5, uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), uintptr(filterFlag), 0) + r1, _, e1 := syscall.SyscallN(procEnumProcessModulesEx.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), uintptr(filterFlag)) if r1 == 0 { err = errnoErr(e1) } @@ -3817,7 +3873,7 @@ func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *u } func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) + r1, _, e1 := syscall.SyscallN(procEnumProcesses.Addr(), uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { err = errnoErr(e1) } @@ -3825,7 +3881,7 @@ func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err } func GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleBaseNameW.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(baseName)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleBaseNameW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(baseName)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -3833,7 +3889,7 @@ func GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uin } func GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleFileNameExW.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleFileNameExW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -3841,7 +3897,7 @@ func GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size u } func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleInformation.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(modinfo)), uintptr(cb), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleInformation.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(modinfo)), uintptr(cb)) if r1 == 0 { err = errnoErr(e1) } @@ -3849,7 +3905,7 @@ func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb } func QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall(procQueryWorkingSetEx.Addr(), 3, uintptr(process), uintptr(pv), uintptr(cb)) + r1, _, e1 := syscall.SyscallN(procQueryWorkingSetEx.Addr(), uintptr(process), uintptr(pv), uintptr(cb)) if r1 == 0 { err = errnoErr(e1) } @@ -3861,7 +3917,7 @@ func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callb if ret != nil { return } - r0, _, _ := syscall.Syscall6(procSubscribeServiceChangeNotifications.Addr(), 5, uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription)), 0) + r0, _, _ := syscall.SyscallN(procSubscribeServiceChangeNotifications.Addr(), uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3873,12 +3929,12 @@ func UnsubscribeServiceChangeNotifications(subscription uintptr) (err error) { if err != nil { return } - syscall.Syscall(procUnsubscribeServiceChangeNotifications.Addr(), 1, uintptr(subscription), 0, 0) + syscall.SyscallN(procUnsubscribeServiceChangeNotifications.Addr(), uintptr(subscription)) return } func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + r1, _, e1 := syscall.SyscallN(procGetUserNameExW.Addr(), uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) if r1&0xff == 0 { err = errnoErr(e1) } @@ -3886,7 +3942,7 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er } func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) + r1, _, e1 := syscall.SyscallN(procTranslateNameW.Addr(), uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize))) if r1&0xff == 0 { err = errnoErr(e1) } @@ -3894,7 +3950,7 @@ func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint } func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiBuildDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + r1, _, e1 := syscall.SyscallN(procSetupDiBuildDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) if r1 == 0 { err = errnoErr(e1) } @@ -3902,7 +3958,7 @@ func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCallClassInstaller.Addr(), 3, uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiCallClassInstaller.Addr(), uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3910,7 +3966,7 @@ func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInf } func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCancelDriverInfoSearch.Addr(), 1, uintptr(deviceInfoSet), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiCancelDriverInfoSearch.Addr(), uintptr(deviceInfoSet)) if r1 == 0 { err = errnoErr(e1) } @@ -3918,7 +3974,7 @@ func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { } func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassGuidsFromNameExW.Addr(), 6, uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupDiClassGuidsFromNameExW.Addr(), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -3926,7 +3982,7 @@ func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGu } func setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassNameFromGuidExW.Addr(), 6, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupDiClassNameFromGuidExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -3934,7 +3990,7 @@ func setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSiz } func setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiCreateDeviceInfoListExW.Addr(), 4, uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoListExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) handle = DevInfo(r0) if handle == DevInfo(InvalidHandle) { err = errnoErr(e1) @@ -3943,7 +3999,7 @@ func setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineN } func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiCreateDeviceInfoW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3951,7 +4007,7 @@ func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUI } func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDeviceInfoList.Addr(), 1, uintptr(deviceInfoSet), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDeviceInfoList.Addr(), uintptr(deviceInfoSet)) if r1 == 0 { err = errnoErr(e1) } @@ -3959,7 +4015,7 @@ func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { } func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) if r1 == 0 { err = errnoErr(e1) } @@ -3967,7 +4023,7 @@ func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDeviceInfo.Addr(), uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3975,7 +4031,7 @@ func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfo } func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiEnumDriverInfoW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDriverInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3983,7 +4039,7 @@ func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, d } func setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall9(procSetupDiGetClassDevsExW.Addr(), 7, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetupDiGetClassDevsExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) handle = DevInfo(r0) if handle == DevInfo(InvalidHandle) { err = errnoErr(e1) @@ -3992,7 +4048,7 @@ func setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintp } func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetClassInstallParamsW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4000,7 +4056,7 @@ func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInfoListDetailW.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInfoListDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData))) if r1 == 0 { err = errnoErr(e1) } @@ -4008,7 +4064,7 @@ func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailDa } func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) if r1 == 0 { err = errnoErr(e1) } @@ -4016,7 +4072,7 @@ func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInf } func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstanceIdW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4024,7 +4080,7 @@ func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY, propertyType *DEVPROPTYPE, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiGetDevicePropertyW.Addr(), 8, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDevicePropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -4032,7 +4088,7 @@ func setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiGetDeviceRegistryPropertyW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4040,7 +4096,7 @@ func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev } func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDriverInfoDetailW.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDriverInfoDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4048,7 +4104,7 @@ func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4056,7 +4112,7 @@ func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4064,7 +4120,7 @@ func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key Handle, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) + r0, _, e1 := syscall.SyscallN(procSetupDiOpenDevRegKey.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) key = Handle(r0) if key == InvalidHandle { err = errnoErr(e1) @@ -4073,7 +4129,7 @@ func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Sc } func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetClassInstallParamsW.Addr(), 4, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize)) if r1 == 0 { err = errnoErr(e1) } @@ -4081,7 +4137,7 @@ func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) if r1 == 0 { err = errnoErr(e1) } @@ -4089,7 +4145,7 @@ func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInf } func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetDeviceRegistryPropertyW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize)) if r1 == 0 { err = errnoErr(e1) } @@ -4097,7 +4153,7 @@ func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev } func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4105,7 +4161,7 @@ func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4113,7 +4169,7 @@ func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procSetupUninstallOEMInfW.Addr(), 3, uintptr(unsafe.Pointer(infFileName)), uintptr(flags), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupUninstallOEMInfW.Addr(), uintptr(unsafe.Pointer(infFileName)), uintptr(flags), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -4121,7 +4177,7 @@ func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (er } func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { - r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) + r0, _, e1 := syscall.SyscallN(procCommandLineToArgvW.Addr(), uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc))) argv = (**uint16)(unsafe.Pointer(r0)) if argv == nil { err = errnoErr(e1) @@ -4130,7 +4186,7 @@ func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { } func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) { - r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path)), 0, 0) + r0, _, _ := syscall.SyscallN(procSHGetKnownFolderPath.Addr(), uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -4138,7 +4194,7 @@ func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **u } func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { - r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) + r1, _, e1 := syscall.SyscallN(procShellExecuteW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) if r1 <= 32 { err = errnoErr(e1) } @@ -4146,12 +4202,12 @@ func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *ui } func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) { - syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param)) + syscall.SyscallN(procEnumChildWindows.Addr(), uintptr(hwnd), uintptr(enumFunc), uintptr(param)) return } func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0) + r1, _, e1 := syscall.SyscallN(procEnumWindows.Addr(), uintptr(enumFunc), uintptr(param)) if r1 == 0 { err = errnoErr(e1) } @@ -4159,7 +4215,7 @@ func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { } func ExitWindowsEx(flags uint32, reason uint32) (err error) { - r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) + r1, _, e1 := syscall.SyscallN(procExitWindowsEx.Addr(), uintptr(flags), uintptr(reason)) if r1 == 0 { err = errnoErr(e1) } @@ -4167,7 +4223,7 @@ func ExitWindowsEx(flags uint32, reason uint32) (err error) { } func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) { - r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) + r0, _, e1 := syscall.SyscallN(procGetClassNameW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) copied = int32(r0) if copied == 0 { err = errnoErr(e1) @@ -4176,19 +4232,19 @@ func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, e } func GetDesktopWindow() (hwnd HWND) { - r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetDesktopWindow.Addr()) hwnd = HWND(r0) return } func GetForegroundWindow() (hwnd HWND) { - r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetForegroundWindow.Addr()) hwnd = HWND(r0) return } func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0) + r1, _, e1 := syscall.SyscallN(procGetGUIThreadInfo.Addr(), uintptr(thread), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -4196,19 +4252,19 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { } func GetKeyboardLayout(tid uint32) (hkl Handle) { - r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0) + r0, _, _ := syscall.SyscallN(procGetKeyboardLayout.Addr(), uintptr(tid)) hkl = Handle(r0) return } func GetShellWindow() (shellWindow HWND) { - r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetShellWindow.Addr()) shellWindow = HWND(r0) return } func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0) + r0, _, e1 := syscall.SyscallN(procGetWindowThreadProcessId.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(pid))) tid = uint32(r0) if tid == 0 { err = errnoErr(e1) @@ -4217,25 +4273,25 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { } func IsWindow(hwnd HWND) (isWindow bool) { - r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindow.Addr(), uintptr(hwnd)) isWindow = r0 != 0 return } func IsWindowUnicode(hwnd HWND) (isUnicode bool) { - r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindowUnicode.Addr(), uintptr(hwnd)) isUnicode = r0 != 0 return } func IsWindowVisible(hwnd HWND) (isVisible bool) { - r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindowVisible.Addr(), uintptr(hwnd)) isVisible = r0 != 0 return } func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0) + r0, _, e1 := syscall.SyscallN(procLoadKeyboardLayoutW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags)) hkl = Handle(r0) if hkl == 0 { err = errnoErr(e1) @@ -4244,7 +4300,7 @@ func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { } func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { - r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) + r0, _, e1 := syscall.SyscallN(procMessageBoxW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype)) ret = int32(r0) if ret == 0 { err = errnoErr(e1) @@ -4253,13 +4309,13 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i } func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) { - r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0) + r0, _, _ := syscall.SyscallN(procToUnicodeEx.Addr(), uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl)) ret = int32(r0) return } func UnloadKeyboardLayout(hkl Handle) (err error) { - r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0) + r1, _, e1 := syscall.SyscallN(procUnloadKeyboardLayout.Addr(), uintptr(hkl)) if r1 == 0 { err = errnoErr(e1) } @@ -4271,7 +4327,7 @@ func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) ( if inheritExisting { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procCreateEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -4279,7 +4335,7 @@ func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) ( } func DestroyEnvironmentBlock(block *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDestroyEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block))) if r1 == 0 { err = errnoErr(e1) } @@ -4287,7 +4343,7 @@ func DestroyEnvironmentBlock(block *uint16) (err error) { } func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) + r1, _, e1 := syscall.SyscallN(procGetUserProfileDirectoryW.Addr(), uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) if r1 == 0 { err = errnoErr(e1) } @@ -4304,7 +4360,7 @@ func GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32 } func _GetFileVersionInfoSize(filename *uint16, zeroHandle *Handle) (bufSize uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileVersionInfoSizeW.Addr(), 2, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle)), 0) + r0, _, e1 := syscall.SyscallN(procGetFileVersionInfoSizeW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle))) bufSize = uint32(r0) if bufSize == 0 { err = errnoErr(e1) @@ -4322,7 +4378,7 @@ func GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer u } func _GetFileVersionInfo(filename *uint16, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileVersionInfoW.Addr(), 4, uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileVersionInfoW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer)) if r1 == 0 { err = errnoErr(e1) } @@ -4339,7 +4395,7 @@ func VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer } func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVerQueryValueW.Addr(), 4, uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procVerQueryValueW.Addr(), uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4347,7 +4403,7 @@ func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPoint } func TimeBeginPeriod(period uint32) (err error) { - r1, _, e1 := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) + r1, _, e1 := syscall.SyscallN(proctimeBeginPeriod.Addr(), uintptr(period)) if r1 != 0 { err = errnoErr(e1) } @@ -4355,7 +4411,7 @@ func TimeBeginPeriod(period uint32) (err error) { } func TimeEndPeriod(period uint32) (err error) { - r1, _, e1 := syscall.Syscall(proctimeEndPeriod.Addr(), 1, uintptr(period), 0, 0) + r1, _, e1 := syscall.SyscallN(proctimeEndPeriod.Addr(), uintptr(period)) if r1 != 0 { err = errnoErr(e1) } @@ -4363,7 +4419,7 @@ func TimeEndPeriod(period uint32) (err error) { } func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) { - r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) + r0, _, _ := syscall.SyscallN(procWinVerifyTrustEx.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -4371,12 +4427,12 @@ func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) } func FreeAddrInfoW(addrinfo *AddrinfoW) { - syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) + syscall.SyscallN(procFreeAddrInfoW.Addr(), uintptr(unsafe.Pointer(addrinfo))) return } func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { - r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetAddrInfoW.Addr(), uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result))) if r0 != 0 { sockerr = syscall.Errno(r0) } @@ -4384,15 +4440,23 @@ func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, resul } func WSACleanup() (err error) { - r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) + r1, _, e1 := syscall.SyscallN(procWSACleanup.Addr()) if r1 == socket_error { err = errnoErr(e1) } return } +func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) { + r1, _, e1 := syscall.SyscallN(procWSADuplicateSocketW.Addr(), uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info))) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { - r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + r0, _, e1 := syscall.SyscallN(procWSAEnumProtocolsW.Addr(), uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) n = int32(r0) if n == -1 { err = errnoErr(e1) @@ -4405,7 +4469,7 @@ func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, f if wait { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) + r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags))) if r1 == 0 { err = errnoErr(e1) } @@ -4413,7 +4477,7 @@ func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, f } func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + r1, _, e1 := syscall.SyscallN(procWSAIoctl.Addr(), uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) if r1 == socket_error { err = errnoErr(e1) } @@ -4421,7 +4485,7 @@ func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbo } func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) { - r1, _, e1 := syscall.Syscall(procWSALookupServiceBeginW.Addr(), 3, uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceBeginW.Addr(), uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) if r1 == socket_error { err = errnoErr(e1) } @@ -4429,7 +4493,7 @@ func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) } func WSALookupServiceEnd(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procWSALookupServiceEnd.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceEnd.Addr(), uintptr(handle)) if r1 == socket_error { err = errnoErr(e1) } @@ -4437,7 +4501,7 @@ func WSALookupServiceEnd(handle Handle) (err error) { } func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) { - r1, _, e1 := syscall.Syscall6(procWSALookupServiceNextW.Addr(), 4, uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceNextW.Addr(), uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet))) if r1 == socket_error { err = errnoErr(e1) } @@ -4445,7 +4509,7 @@ func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WS } func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSARecv.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4453,7 +4517,7 @@ func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32 } func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + r1, _, e1 := syscall.SyscallN(procWSARecvFrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4461,7 +4525,7 @@ func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *ui } func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSASend.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4469,7 +4533,7 @@ func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, } func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + r1, _, e1 := syscall.SyscallN(procWSASendTo.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4477,7 +4541,7 @@ func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32 } func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procWSASocketW.Addr(), uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -4486,7 +4550,7 @@ func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, } func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { - r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) + r0, _, _ := syscall.SyscallN(procWSAStartup.Addr(), uintptr(verreq), uintptr(unsafe.Pointer(data))) if r0 != 0 { sockerr = syscall.Errno(r0) } @@ -4494,7 +4558,7 @@ func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { } func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4502,7 +4566,7 @@ func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { } func Closesocket(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) + r1, _, e1 := syscall.SyscallN(procclosesocket.Addr(), uintptr(s)) if r1 == socket_error { err = errnoErr(e1) } @@ -4510,7 +4574,7 @@ func Closesocket(s Handle) (err error) { } func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + r1, _, e1 := syscall.SyscallN(procconnect.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4527,7 +4591,7 @@ func GetHostByName(name string) (h *Hostent, err error) { } func _GetHostByName(name *byte) (h *Hostent, err error) { - r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procgethostbyname.Addr(), uintptr(unsafe.Pointer(name))) h = (*Hostent)(unsafe.Pointer(r0)) if h == nil { err = errnoErr(e1) @@ -4536,7 +4600,7 @@ func _GetHostByName(name *byte) (h *Hostent, err error) { } func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4553,7 +4617,7 @@ func GetProtoByName(name string) (p *Protoent, err error) { } func _GetProtoByName(name *byte) (p *Protoent, err error) { - r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procgetprotobyname.Addr(), uintptr(unsafe.Pointer(name))) p = (*Protoent)(unsafe.Pointer(r0)) if p == nil { err = errnoErr(e1) @@ -4576,7 +4640,7 @@ func GetServByName(name string, proto string) (s *Servent, err error) { } func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { - r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) + r0, _, e1 := syscall.SyscallN(procgetservbyname.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto))) s = (*Servent)(unsafe.Pointer(r0)) if s == nil { err = errnoErr(e1) @@ -4585,7 +4649,7 @@ func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { } func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4593,7 +4657,7 @@ func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { } func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { - r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + r1, _, e1 := syscall.SyscallN(procgetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4601,7 +4665,7 @@ func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int3 } func listen(s Handle, backlog int32) (err error) { - r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) + r1, _, e1 := syscall.SyscallN(proclisten.Addr(), uintptr(s), uintptr(backlog)) if r1 == socket_error { err = errnoErr(e1) } @@ -4609,7 +4673,7 @@ func listen(s Handle, backlog int32) (err error) { } func Ntohs(netshort uint16) (u uint16) { - r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) + r0, _, _ := syscall.SyscallN(procntohs.Addr(), uintptr(netshort)) u = uint16(r0) return } @@ -4619,7 +4683,7 @@ func recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen * if len(buf) > 0 { _p0 = &buf[0] } - r0, _, e1 := syscall.Syscall6(procrecvfrom.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + r0, _, e1 := syscall.SyscallN(procrecvfrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) n = int32(r0) if n == -1 { err = errnoErr(e1) @@ -4632,7 +4696,7 @@ func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) ( if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) + r1, _, e1 := syscall.SyscallN(procsendto.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4640,7 +4704,7 @@ func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) ( } func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { - r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) + r1, _, e1 := syscall.SyscallN(procsetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4648,7 +4712,7 @@ func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32 } func shutdown(s Handle, how int32) (err error) { - r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) + r1, _, e1 := syscall.SyscallN(procshutdown.Addr(), uintptr(s), uintptr(how)) if r1 == socket_error { err = errnoErr(e1) } @@ -4656,7 +4720,7 @@ func shutdown(s Handle, how int32) (err error) { } func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) + r0, _, e1 := syscall.SyscallN(procsocket.Addr(), uintptr(af), uintptr(typ), uintptr(protocol)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -4665,7 +4729,7 @@ func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { } func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procWTSEnumerateSessionsW.Addr(), 5, uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count)), 0) + r1, _, e1 := syscall.SyscallN(procWTSEnumerateSessionsW.Addr(), uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count))) if r1 == 0 { err = errnoErr(e1) } @@ -4673,12 +4737,12 @@ func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessio } func WTSFreeMemory(ptr uintptr) { - syscall.Syscall(procWTSFreeMemory.Addr(), 1, uintptr(ptr), 0, 0) + syscall.SyscallN(procWTSFreeMemory.Addr(), uintptr(ptr)) return } func WTSQueryUserToken(session uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procWTSQueryUserToken.Addr(), 2, uintptr(session), uintptr(unsafe.Pointer(token)), 0) + r1, _, e1 := syscall.SyscallN(procWTSQueryUserToken.Addr(), uintptr(session), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/term/term_windows.go b/vendor/golang.org/x/term/term_windows.go index df6bf94..0ddd81c 100644 --- a/vendor/golang.org/x/term/term_windows.go +++ b/vendor/golang.org/x/term/term_windows.go @@ -20,12 +20,14 @@ func isTerminal(fd int) bool { return err == nil } +// This is intended to be used on a console input handle. +// See https://learn.microsoft.com/en-us/windows/console/setconsolemode func makeRaw(fd int) (*State, error) { var st uint32 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { return nil, err } - raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT) raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { return nil, err diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go index f636667..9255449 100644 --- a/vendor/golang.org/x/term/terminal.go +++ b/vendor/golang.org/x/term/terminal.go @@ -6,6 +6,7 @@ package term import ( "bytes" + "fmt" "io" "runtime" "strconv" @@ -36,6 +37,26 @@ var vt100EscapeCodes = EscapeCodes{ Reset: []byte{keyEscape, '[', '0', 'm'}, } +// A History provides a (possibly bounded) queue of input lines read by [Terminal.ReadLine]. +type History interface { + // Add will be called by [Terminal.ReadLine] to add + // a new, most recent entry to the history. + // It is allowed to drop any entry, including + // the entry being added (e.g., if it's deemed an invalid entry), + // the least-recent entry (e.g., to keep the history bounded), + // or any other entry. + Add(entry string) + + // Len returns the number of entries in the history. + Len() int + + // At returns an entry from the history. + // Index 0 is the most-recently added entry and + // index Len()-1 is the least-recently added entry. + // If index is < 0 or >= Len(), it panics. + At(idx int) string +} + // Terminal contains the state for running a VT100 terminal that is capable of // reading lines of input. type Terminal struct { @@ -44,6 +65,8 @@ type Terminal struct { // bytes, as an index into |line|). If it returns ok=false, the key // press is processed normally. Otherwise it returns a replacement line // and the new cursor position. + // + // This will be disabled during ReadPassword. AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) // Escape contains a pointer to the escape codes for this terminal. @@ -84,9 +107,14 @@ type Terminal struct { remainder []byte inBuf [256]byte - // history contains previously entered commands so that they can be - // accessed with the up and down keys. - history stRingBuffer + // History records and retrieves lines of input read by [ReadLine] which + // a user can retrieve and navigate using the up and down arrow keys. + // + // It is not safe to call ReadLine concurrently with any methods on History. + // + // [NewTerminal] sets this to a default implementation that records the + // last 100 lines of input. + History History // historyIndex stores the currently accessed history entry, where zero // means the immediately previous entry. historyIndex int @@ -109,6 +137,7 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal { termHeight: 24, echo: true, historyIndex: -1, + History: &stRingBuffer{}, } } @@ -117,6 +146,7 @@ const ( keyCtrlD = 4 keyCtrlU = 21 keyEnter = '\r' + keyLF = '\n' keyEscape = 27 keyBackspace = 127 keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota @@ -383,7 +413,7 @@ func (t *Terminal) eraseNPreviousChars(n int) { } } -// countToLeftWord returns then number of characters from the cursor to the +// countToLeftWord returns the number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { @@ -408,7 +438,7 @@ func (t *Terminal) countToLeftWord() int { return t.pos - pos } -// countToRightWord returns then number of characters from the cursor to the +// countToRightWord returns the number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos @@ -448,10 +478,27 @@ func visualLength(runes []rune) int { return length } +// historyAt unlocks the terminal and relocks it while calling History.At. +func (t *Terminal) historyAt(idx int) (string, bool) { + t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. + defer t.lock.Lock() // panic in At (or Len) protection. + if idx < 0 || idx >= t.History.Len() { + return "", false + } + return t.History.At(idx), true +} + +// historyAdd unlocks the terminal and relocks it while calling History.Add. +func (t *Terminal) historyAdd(entry string) { + t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. + defer t.lock.Lock() // panic in Add protection. + t.History.Add(entry) +} + // handleKey processes the given key and, optionally, returns a line of text // that the user has entered. func (t *Terminal) handleKey(key rune) (line string, ok bool) { - if t.pasteActive && key != keyEnter { + if t.pasteActive && key != keyEnter && key != keyLF { t.addKeyToLine(key) return } @@ -495,7 +542,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) { t.pos = len(t.line) t.moveCursorToPos(t.pos) case keyUp: - entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) + entry, ok := t.historyAt(t.historyIndex + 1) if !ok { return "", false } @@ -514,14 +561,14 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) { t.setLine(runes, len(runes)) t.historyIndex-- default: - entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) + entry, ok := t.historyAt(t.historyIndex - 1) if ok { t.historyIndex-- runes := []rune(entry) t.setLine(runes, len(runes)) } } - case keyEnter: + case keyEnter, keyLF: t.moveCursorToPos(len(t.line)) t.queue([]rune("\r\n")) line = string(t.line) @@ -692,6 +739,8 @@ func (t *Terminal) Write(buf []byte) (n int, err error) { // ReadPassword temporarily changes the prompt and reads a password, without // echo, from the terminal. +// +// The AutoCompleteCallback is disabled during this call. func (t *Terminal) ReadPassword(prompt string) (line string, err error) { t.lock.Lock() defer t.lock.Unlock() @@ -699,6 +748,11 @@ func (t *Terminal) ReadPassword(prompt string) (line string, err error) { oldPrompt := t.prompt t.prompt = []rune(prompt) t.echo = false + oldAutoCompleteCallback := t.AutoCompleteCallback + t.AutoCompleteCallback = nil + defer func() { + t.AutoCompleteCallback = oldAutoCompleteCallback + }() line, err = t.readLine() @@ -759,6 +813,10 @@ func (t *Terminal) readLine() (line string, err error) { if !t.pasteActive { lineIsPasted = false } + // If we have CR, consume LF if present (CRLF sequence) to avoid returning an extra empty line. + if key == keyEnter && len(rest) > 0 && rest[0] == keyLF { + rest = rest[1:] + } line, lineOk = t.handleKey(key) } if len(rest) > 0 { @@ -772,7 +830,7 @@ func (t *Terminal) readLine() (line string, err error) { if lineOk { if t.echo { t.historyIndex = -1 - t.history.Add(line) + t.historyAdd(line) } if lineIsPasted { err = ErrPasteIndicator @@ -929,19 +987,23 @@ func (s *stRingBuffer) Add(a string) { } } -// NthPreviousEntry returns the value passed to the nth previous call to Add. +func (s *stRingBuffer) Len() int { + return s.size +} + +// At returns the value passed to the nth previous call to Add. // If n is zero then the immediately prior value is returned, if one, then the // next most recent, and so on. If such an element doesn't exist then ok is // false. -func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { +func (s *stRingBuffer) At(n int) string { if n < 0 || n >= s.size { - return "", false + panic(fmt.Sprintf("term: history index [%d] out of range [0,%d)", n, s.size)) } index := s.head - n if index < 0 { index += s.max } - return s.entries[index], true + return s.entries[index] } // readPasswordLine reads from reader until it finds \n or io.EOF. diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index 9d2ae54..fb82732 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -427,13 +427,6 @@ type isolatingRunSequence struct { func (i *isolatingRunSequence) Len() int { return len(i.indexes) } -func maxLevel(a, b level) level { - if a > b { - return a - } - return b -} - // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, // either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { @@ -474,8 +467,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { indexes: indexes, types: types, level: level, - sos: typeForLevel(maxLevel(prevLevel, level)), - eos: typeForLevel(maxLevel(succLevel, level)), + sos: typeForLevel(max(prevLevel, level)), + eos: typeForLevel(max(succLevel, level)), } } diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go index ec5f0cd..794b2e3 100644 --- a/vendor/golang.org/x/time/rate/rate.go +++ b/vendor/golang.org/x/time/rate/rate.go @@ -85,7 +85,7 @@ func (lim *Limiter) Burst() int { // TokensAt returns the number of tokens available at time t. func (lim *Limiter) TokensAt(t time.Time) float64 { lim.mu.Lock() - _, tokens := lim.advance(t) // does not mutate lim + tokens := lim.advance(t) // does not mutate lim lim.mu.Unlock() return tokens } @@ -186,7 +186,7 @@ func (r *Reservation) CancelAt(t time.Time) { return } // advance time to now - t, tokens := r.lim.advance(t) + tokens := r.lim.advance(t) // calculate new number of tokens tokens += restoreTokens if burst := float64(r.lim.burst); tokens > burst { @@ -307,7 +307,7 @@ func (lim *Limiter) SetLimitAt(t time.Time, newLimit Limit) { lim.mu.Lock() defer lim.mu.Unlock() - t, tokens := lim.advance(t) + tokens := lim.advance(t) lim.last = t lim.tokens = tokens @@ -324,7 +324,7 @@ func (lim *Limiter) SetBurstAt(t time.Time, newBurst int) { lim.mu.Lock() defer lim.mu.Unlock() - t, tokens := lim.advance(t) + tokens := lim.advance(t) lim.last = t lim.tokens = tokens @@ -347,7 +347,7 @@ func (lim *Limiter) reserveN(t time.Time, n int, maxFutureReserve time.Duration) } } - t, tokens := lim.advance(t) + tokens := lim.advance(t) // Calculate the remaining number of tokens resulting from the request. tokens -= float64(n) @@ -380,10 +380,11 @@ func (lim *Limiter) reserveN(t time.Time, n int, maxFutureReserve time.Duration) return r } -// advance calculates and returns an updated state for lim resulting from the passage of time. +// advance calculates and returns an updated number of tokens for lim +// resulting from the passage of time. // lim is not changed. // advance requires that lim.mu is held. -func (lim *Limiter) advance(t time.Time) (newT time.Time, newTokens float64) { +func (lim *Limiter) advance(t time.Time) (newTokens float64) { last := lim.last if t.Before(last) { last = t @@ -396,7 +397,7 @@ func (lim *Limiter) advance(t time.Time) (newT time.Time, newTokens float64) { if burst := float64(lim.burst); tokens > burst { tokens = burst } - return t, tokens + return tokens } // durationFromTokens is a unit conversion function from the number of tokens to the duration diff --git a/vendor/golang.org/x/time/rate/sometimes.go b/vendor/golang.org/x/time/rate/sometimes.go index 6ba99dd..9b83932 100644 --- a/vendor/golang.org/x/time/rate/sometimes.go +++ b/vendor/golang.org/x/time/rate/sometimes.go @@ -61,7 +61,9 @@ func (s *Sometimes) Do(f func()) { (s.Every > 0 && s.count%s.Every == 0) || (s.Interval > 0 && time.Since(s.last) >= s.Interval) { f() - s.last = time.Now() + if s.Interval > 0 { + s.last = time.Now() + } } s.count++ } diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE deleted file mode 100644 index 2a7cf70..0000000 --- a/vendor/golang.org/x/tools/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -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 -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS deleted file mode 100644 index 7330990..0000000 --- a/vendor/golang.org/x/tools/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -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/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go deleted file mode 100644 index 65fe262..0000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ /dev/null @@ -1,239 +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 gcexportdata provides functions for reading and writing -// export data, which is a serialized description of the API of a Go -// package including the names, kinds, types, and locations of all -// exported declarations. -// -// The standard Go compiler (cmd/compile) writes an export data file -// for each package it compiles, which it later reads when compiling -// packages that import the earlier one. The compiler must thus -// contain logic to both write and read export data. -// (See the "Export" section in the cmd/compile/README file.) -// -// The [Read] function in this package can read files produced by the -// compiler, producing [go/types] data structures. As a matter of -// policy, Read supports export data files produced by only the last -// two Go releases plus tip; see https://go.dev/issue/68898. The -// export data files produced by the compiler contain additional -// details related to generics, inlining, and other optimizations that -// cannot be decoded by the [Read] function. -// -// In files written by the compiler, the export data is not at the -// start of the file. Before calling Read, use [NewReader] to locate -// the desired portion of the file. -// -// The [Write] function in this package encodes the exported API of a -// Go package ([types.Package]) as a file. Such files can be later -// decoded by Read, but cannot be consumed by the compiler. -// -// # Future changes -// -// Although Read supports the formats written by both Write and the -// compiler, the two are quite different, and there is an open -// proposal (https://go.dev/issue/69491) to separate these APIs. -// -// Under that proposal, this package would ultimately provide only the -// Read operation for compiler export data, which must be defined in -// this module (golang.org/x/tools), not in the standard library, to -// avoid version skew for developer tools that need to read compiler -// export data both before and after a Go release, such as from Go -// 1.23 to Go 1.24. Because this package lives in the tools module, -// clients can update their version of the module some time before the -// Go 1.24 release and rebuild and redeploy their tools, which will -// then be able to consume both Go 1.23 and Go 1.24 export data files, -// so they will work before and after the Go update. (See discussion -// at https://go.dev/issue/15651.) -// -// The operations to import and export [go/types] data structures -// would be defined in the go/types package as Import and Export. -// [Write] would (eventually) delegate to Export, -// and [Read], when it detects a file produced by Export, -// would delegate to Import. -// -// # Deprecations -// -// The [NewImporter] and [Find] functions are deprecated and should -// not be used in new code. The [WriteBundle] and [ReadBundle] -// functions are experimental, and there is an open proposal to -// deprecate them (https://go.dev/issue/69573). -package gcexportdata - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "go/token" - "go/types" - "io" - "os/exec" - - "golang.org/x/tools/internal/gcimporter" -) - -// Find returns the name of an object (.o) or archive (.a) file -// containing type information for the specified import path, -// using the go command. -// If no file was found, an empty filename is returned. -// -// A relative srcDir is interpreted relative to the current working directory. -// -// Find also returns the package's resolved (canonical) import path, -// reflecting the effects of srcDir and vendoring on importPath. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func Find(importPath, srcDir string) (filename, path string) { - cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) - cmd.Dir = srcDir - out, err := cmd.Output() - if err != nil { - return "", "" - } - var data struct { - ImportPath string - Export string - } - json.Unmarshal(out, &data) - return data.Export, data.ImportPath -} - -// NewReader returns a reader for the export data section of an object -// (.o) or archive (.a) file read from r. The new reader may provide -// additional trailing data beyond the end of the export data. -func NewReader(r io.Reader) (io.Reader, error) { - buf := bufio.NewReader(r) - size, err := gcimporter.FindExportData(buf) - if err != nil { - return nil, err - } - - // We were given an archive and found the __.PKGDEF in it. - // This tells us the size of the export data, and we don't - // need to return the entire file. - return &io.LimitedReader{ - R: buf, - N: size, - }, nil -} - -// readAll works the same way as io.ReadAll, but avoids allocations and copies -// by preallocating a byte slice of the necessary size if the size is known up -// front. This is always possible when the input is an archive. In that case, -// NewReader will return the known size using an io.LimitedReader. -func readAll(r io.Reader) ([]byte, error) { - if lr, ok := r.(*io.LimitedReader); ok { - data := make([]byte, lr.N) - _, err := io.ReadFull(lr, data) - return data, err - } - return io.ReadAll(r) -} - -// Read reads export data from in, decodes it, and returns type -// information for the package. -// -// Read is capable of reading export data produced by [Write] at the -// same source code version, or by the last two Go releases (plus tip) -// of the standard Go compiler. Reading files from older compilers may -// produce an error. -// -// The package path (effectively its linker symbol prefix) is -// specified by path, since unlike the package name, this information -// may not be recorded in the export data. -// -// File position information is added to fset. -// -// Read may inspect and add to the imports map to ensure that references -// within the export data to other packages are consistent. The caller -// must ensure that imports[path] does not exist, or exists but is -// incomplete (see types.Package.Complete), and Read inserts the -// resulting package into this map entry. -// -// On return, the state of the reader is undefined. -func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export data for %q: %v", path, err) - } - - if bytes.HasPrefix(data, []byte("!")) { - return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) - } - - // The indexed export format starts with an 'i'; the older - // binary export format starts with a 'c', 'd', or 'v' - // (from "version"). Select appropriate importer. - if len(data) > 0 { - switch data[0] { - case 'v', 'c', 'd': - // binary, produced by cmd/compile till go1.10 - return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) - - case 'i': - // indexed, produced by cmd/compile till go1.19, - // and also by [Write]. - // - // If proposal #69491 is accepted, go/types - // serialization will be implemented by - // types.Export, to which Write would eventually - // delegate (explicitly dropping any pretence at - // inter-version Write-Read compatibility). - // This [Read] function would delegate to types.Import - // when it detects that the file was produced by Export. - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - - case 'u': - // unified, produced by cmd/compile since go1.20 - _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) - return pkg, err - - default: - l := len(data) - if l > 10 { - l = 10 - } - return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) - } - } - return nil, fmt.Errorf("empty export data for %s", path) -} - -// Write writes encoded type information for the specified package to out. -// The FileSet provides file position information for named objects. -func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - if _, err := io.WriteString(out, "i"); err != nil { - return err - } - return gcimporter.IExportData(out, fset, pkg) -} - -// ReadBundle reads an export bundle from in, decodes it, and returns type -// information for the packages. -// File position information is added to fset. -// -// ReadBundle may inspect and add to the imports map to ensure that references -// within the export bundle to other packages are consistent. -// -// On return, the state of the reader is undefined. -// -// Experimental: This API is experimental and may change in the future. -func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export bundle: %v", err) - } - return gcimporter.IImportBundle(fset, imports, data) -} - -// WriteBundle writes encoded type information for the specified packages to out. -// The FileSet provides file position information for named objects. -// -// Experimental: This API is experimental and may change in the future. -func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - return gcimporter.IExportBundle(out, fset, pkgs) -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go deleted file mode 100644 index 37a7247..0000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ /dev/null @@ -1,75 +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 gcexportdata - -import ( - "fmt" - "go/token" - "go/types" - "os" -) - -// NewImporter returns a new instance of the types.Importer interface -// that reads type information from export data files written by gc. -// The Importer also satisfies types.ImporterFrom. -// -// Export data files are located using "go build" workspace conventions -// and the build.Default context. -// -// Use this importer instead of go/importer.For("gc", ...) to avoid the -// version-skew problems described in the documentation of this package, -// or to control the FileSet or access the imports map populated during -// package loading. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { - return importer{fset, imports} -} - -type importer struct { - fset *token.FileSet - imports map[string]*types.Package -} - -func (imp importer) Import(importPath string) (*types.Package, error) { - return imp.ImportFrom(importPath, "", 0) -} - -func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { - filename, path := Find(importPath, srcDir) - if filename == "" { - if importPath == "unsafe" { - // Even for unsafe, call Find first in case - // the package was vendored. - return types.Unsafe, nil - } - return nil, fmt.Errorf("can't find import: %s", importPath) - } - - if pkg, ok := imp.imports[path]; ok && pkg.Complete() { - return pkg, nil // cache hit - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - f.Close() - if err != nil { - // add file name to error - err = fmt.Errorf("reading export data: %s: %v", filename, err) - } - }() - - r, err := NewReader(f) - if err != nil { - return nil, err - } - - return Read(r, imp.fset, imp.imports, path) -} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go deleted file mode 100644 index f1931d1..0000000 --- a/vendor/golang.org/x/tools/go/packages/doc.go +++ /dev/null @@ -1,251 +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. - -/* -Package packages loads Go packages for inspection and analysis. - -The [Load] function takes as input a list of patterns and returns a -list of [Package] values describing individual packages matched by those -patterns. -A [Config] specifies configuration options, the most important of which is -the [LoadMode], which controls the amount of detail in the loaded packages. - -Load passes most patterns directly to the underlying build tool. -The default build tool is the go command. -Its supported patterns are described at -https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. -Other build systems may be supported by providing a "driver"; -see [The driver protocol]. - -All patterns with the prefix "query=", where query is a -non-empty string of letters from [a-z], are reserved and may be -interpreted as query operators. - -Two query operators are currently supported: "file" and "pattern". - -The query "file=path/to/file.go" matches the package or packages enclosing -the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" -might return the packages "fmt" and "fmt [fmt.test]". - -The query "pattern=string" causes "string" to be passed directly to -the underlying build tool. In most cases this is unnecessary, -but an application can use Load("pattern=" + x) as an escaping mechanism -to ensure that x is not interpreted as a query operator if it contains '='. - -All other query operators are reserved for future use and currently -cause Load to report an error. - -The Package struct provides basic information about the package, including - - - ID, a unique identifier for the package in the returned set; - - GoFiles, the names of the package's Go source files; - - Imports, a map from source import strings to the Packages they name; - - Types, the type information for the package's exported symbols; - - Syntax, the parsed syntax trees for the package's source code; and - - TypesInfo, the result of a complete type-check of the package syntax trees. - -(See the documentation for type Package for the complete list of fields -and more detailed descriptions.) - -For example, - - Load(nil, "bytes", "unicode...") - -returns four Package structs describing the standard library packages -bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern -can match multiple packages and that a package might be matched by -multiple patterns: in general it is not possible to determine which -packages correspond to which patterns. - -Note that the list returned by Load contains only the packages matched -by the patterns. Their dependencies can be found by walking the import -graph using the Imports fields. - -The Load function can be configured by passing a pointer to a Config as -the first argument. A nil Config is equivalent to the zero Config, which -causes Load to run in [LoadFiles] mode, collecting minimal information. -See the documentation for type Config for details. - -As noted earlier, the Config.Mode controls the amount of detail -reported about the loaded packages. See the documentation for type LoadMode -for details. - -Most tools should pass their command-line arguments (after any flags) -uninterpreted to Load, so that it can interpret them -according to the conventions of the underlying build system. - -See the Example function for typical usage. - -# The driver protocol - -Load may be used to load Go packages even in Go projects that use -alternative build systems, by installing an appropriate "driver" -program for the build system and specifying its location in the -GOPACKAGESDRIVER environment variable. -For example, -https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration -explains how to use the driver for Bazel. - -The driver program is responsible for interpreting patterns in its -preferred notation and reporting information about the packages that -those patterns identify. Drivers must also support the special "file=" -and "pattern=" patterns described above. - -The patterns are provided as positional command-line arguments. A -JSON-encoded [DriverRequest] message providing additional information -is written to the driver's standard input. The driver must write a -JSON-encoded [DriverResponse] message to its standard output. (This -message differs from the JSON schema produced by 'go list'.) - -The value of the PWD environment variable seen by the driver process -is the preferred name of its working directory. (The working directory -may have other aliases due to symbolic links; see the comment on the -Dir field of [exec.Cmd] for related information.) -When the driver process emits in its response the name of a file -that is a descendant of this directory, it must use an absolute path -that has the value of PWD as a prefix, to ensure that the returned -filenames satisfy the original query. -*/ -package packages // import "golang.org/x/tools/go/packages" - -/* - -Motivation and design considerations - -The new package's design solves problems addressed by two existing -packages: go/build, which locates and describes packages, and -golang.org/x/tools/go/loader, which loads, parses and type-checks them. -The go/build.Package structure encodes too much of the 'go build' way -of organizing projects, leaving us in need of a data type that describes a -package of Go source code independent of the underlying build system. -We wanted something that works equally well with go build and vgo, and -also other build systems such as Bazel and Blaze, making it possible to -construct analysis tools that work in all these environments. -Tools such as errcheck and staticcheck were essentially unavailable to -the Go community at Google, and some of Google's internal tools for Go -are unavailable externally. -This new package provides a uniform way to obtain package metadata by -querying each of these build systems, optionally supporting their -preferred command-line notations for packages, so that tools integrate -neatly with users' build environments. The Metadata query function -executes an external query tool appropriate to the current workspace. - -Loading packages always returns the complete import graph "all the way down", -even if all you want is information about a single package, because the query -mechanisms of all the build systems we currently support ({go,vgo} list, and -blaze/bazel aspect-based query) cannot provide detailed information -about one package without visiting all its dependencies too, so there is -no additional asymptotic cost to providing transitive information. -(This property might not be true of a hypothetical 5th build system.) - -In calls to TypeCheck, all initial packages, and any package that -transitively depends on one of them, must be loaded from source. -Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from -source; D may be loaded from export data, and E may not be loaded at all -(though it's possible that D's export data mentions it, so a -types.Package may be created for it and exposed.) - -The old loader had a feature to suppress type-checking of function -bodies on a per-package basis, primarily intended to reduce the work of -obtaining type information for imported packages. Now that imports are -satisfied by export data, the optimization no longer seems necessary. - -Despite some early attempts, the old loader did not exploit export data, -instead always using the equivalent of WholeProgram mode. This was due -to the complexity of mixing source and export data packages (now -resolved by the upward traversal mentioned above), and because export data -files were nearly always missing or stale. Now that 'go build' supports -caching, all the underlying build systems can guarantee to produce -export data in a reasonable (amortized) time. - -Test "main" packages synthesized by the build system are now reported as -first-class packages, avoiding the need for clients (such as go/ssa) to -reinvent this generation logic. - -One way in which go/packages is simpler than the old loader is in its -treatment of in-package tests. In-package tests are packages that -consist of all the files of the library under test, plus the test files. -The old loader constructed in-package tests by a two-phase process of -mutation called "augmentation": first it would construct and type check -all the ordinary library packages and type-check the packages that -depend on them; then it would add more (test) files to the package and -type-check again. This two-phase approach had four major problems: -1) in processing the tests, the loader modified the library package, - leaving no way for a client application to see both the test - package and the library package; one would mutate into the other. -2) because test files can declare additional methods on types defined in - the library portion of the package, the dispatch of method calls in - the library portion was affected by the presence of the test files. - This should have been a clue that the packages were logically - different. -3) this model of "augmentation" assumed at most one in-package test - per library package, which is true of projects using 'go build', - but not other build systems. -4) because of the two-phase nature of test processing, all packages that - import the library package had to be processed before augmentation, - forcing a "one-shot" API and preventing the client from calling Load - in several times in sequence as is now possible in WholeProgram mode. - (TypeCheck mode has a similar one-shot restriction for a different reason.) - -Early drafts of this package supported "multi-shot" operation. -Although it allowed clients to make a sequence of calls (or concurrent -calls) to Load, building up the graph of Packages incrementally, -it was of marginal value: it complicated the API -(since it allowed some options to vary across calls but not others), -it complicated the implementation, -it cannot be made to work in Types mode, as explained above, -and it was less efficient than making one combined call (when this is possible). -Among the clients we have inspected, none made multiple calls to load -but could not be easily and satisfactorily modified to make only a single call. -However, applications changes may be required. -For example, the ssadump command loads the user-specified packages -and in addition the runtime package. It is tempting to simply append -"runtime" to the user-provided list, but that does not work if the user -specified an ad-hoc package such as [a.go b.go]. -Instead, ssadump no longer requests the runtime package, -but seeks it among the dependencies of the user-specified packages, -and emits an error if it is not found. - -Questions & Tasks - -- Add GOARCH/GOOS? - They are not portable concepts, but could be made portable. - Our goal has been to allow users to express themselves using the conventions - of the underlying build system: if the build system honors GOARCH - during a build and during a metadata query, then so should - applications built atop that query mechanism. - Conversely, if the target architecture of the build is determined by - command-line flags, the application can pass the relevant - flags through to the build system using a command such as: - myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" - However, this approach is low-level, unwieldy, and non-portable. - GOOS and GOARCH seem important enough to warrant a dedicated option. - -- How should we handle partial failures such as a mixture of good and - malformed patterns, existing and non-existent packages, successful and - failed builds, import failures, import cycles, and so on, in a call to - Load? - -- Support bazel, blaze, and go1.10 list, not just go1.11 list. - -- Handle (and test) various partial success cases, e.g. - a mixture of good packages and: - invalid patterns - nonexistent packages - empty packages - packages with malformed package or import declarations - unreadable files - import cycles - other parse errors - type errors - Make sure we record errors at the correct place in the graph. - -- Missing packages among initial arguments are not reported. - Return bogus packages for them, like golist does. - -- "undeclared name" errors (for example) are reported out of source file - order. I suspect this is due to the breadth-first resolution now used - by go/types. Is that a bug? Discuss with gri. - -*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go deleted file mode 100644 index 91bd62e..0000000 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ /dev/null @@ -1,153 +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. - -package packages - -// This file defines the protocol that enables an external "driver" -// tool to supply package metadata in place of 'go list'. - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "slices" - "strings" -) - -// DriverRequest defines the schema of a request for package metadata -// from an external driver program. The JSON-encoded DriverRequest -// message is provided to the driver program's standard input. The -// query patterns are provided as command-line arguments. -// -// See the package documentation for an overview. -type DriverRequest struct { - Mode LoadMode `json:"mode"` - - // Env specifies the environment the underlying build system should be run in. - Env []string `json:"env"` - - // BuildFlags are flags that should be passed to the underlying build system. - BuildFlags []string `json:"build_flags"` - - // Tests specifies whether the patterns should also return test packages. - Tests bool `json:"tests"` - - // Overlay maps file paths (relative to the driver's working directory) - // to the contents of overlay files (see Config.Overlay). - Overlay map[string][]byte `json:"overlay"` -} - -// DriverResponse defines the schema of a response from an external -// driver program, providing the results of a query for package -// metadata. The driver program must write a JSON-encoded -// DriverResponse message to its standard output. -// -// See the package documentation for an overview. -type DriverResponse struct { - // NotHandled is returned if the request can't be handled by the current - // driver. If an external driver returns a response with NotHandled, the - // rest of the DriverResponse is ignored, and go/packages will fallback - // to the next driver. If go/packages is extended in the future to support - // lists of multiple drivers, go/packages will fall back to the next driver. - NotHandled bool - - // Compiler and Arch are the arguments pass of types.SizesFor - // to get a types.Sizes to use when type checking. - Compiler string - Arch string - - // Roots is the set of package IDs that make up the root packages. - // We have to encode this separately because when we encode a single package - // we cannot know if it is one of the roots as that requires knowledge of the - // graph it is part of. - Roots []string `json:",omitempty"` - - // Packages is the full set of packages in the graph. - // The packages are not connected into a graph. - // The Imports if populated will be stubs that only have their ID set. - // Imports will be connected and then type and syntax information added in a - // later pass (see refine). - Packages []*Package - - // GoVersion is the minor version number used by the driver - // (e.g. the go command on the PATH) when selecting .go files. - // Zero means unknown. - GoVersion int -} - -// driver is the type for functions that query the build system for the -// packages named by the patterns. -type driver func(cfg *Config, patterns []string) (*DriverResponse, error) - -// findExternalDriver returns the file path of a tool that supplies -// the build system package structure, or "" if not found. -// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its -// value, otherwise it searches for a binary named gopackagesdriver on the PATH. -func findExternalDriver(cfg *Config) driver { - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range cfg.Env { - if val := strings.TrimPrefix(env, toolPrefix); val != env { - tool = val - } - } - if tool != "" && tool == "off" { - return nil - } - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - return nil - } - } - return func(cfg *Config, patterns []string) (*DriverResponse, error) { - req, err := json.Marshal(DriverRequest{ - Mode: cfg.Mode, - Env: cfg.Env, - BuildFlags: cfg.BuildFlags, - Tests: cfg.Tests, - Overlay: cfg.Overlay, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - stderr := new(bytes.Buffer) - cmd := exec.CommandContext(cfg.Context, tool, patterns...) - cmd.Dir = cfg.Dir - // The cwd gets resolved to the real path. On Darwin, where - // /tmp is a symlink, this breaks anything that expects the - // working directory to keep the original path, including the - // go command when dealing with modules. - // - // os.Getwd stdlib has a special feature where if the - // cwd and the PWD are the same node then it trusts - // the PWD, so by setting it in the env for the child - // process we fix up all the paths returned by the go - // command. - // - // (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go) - cmd.Env = append(slices.Clip(cfg.Env), "PWD="+cfg.Dir) - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = stderr - - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { - fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) - } - - var response DriverResponse - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return &response, nil - } -} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go deleted file mode 100644 index 0458b4f..0000000 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ /dev/null @@ -1,1086 +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. - -package packages - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" -) - -// debug controls verbose logging. -var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) - -// A goTooOldError reports that the go command -// found by exec.LookPath is too old to use the new go list behavior. -type goTooOldError struct { - error -} - -// responseDeduper wraps a DriverResponse, deduplicating its contents. -type responseDeduper struct { - seenRoots map[string]bool - seenPackages map[string]*Package - dr *DriverResponse -} - -func newDeduper() *responseDeduper { - return &responseDeduper{ - dr: &DriverResponse{}, - seenRoots: map[string]bool{}, - seenPackages: map[string]*Package{}, - } -} - -// addAll fills in r with a DriverResponse. -func (r *responseDeduper) addAll(dr *DriverResponse) { - for _, pkg := range dr.Packages { - r.addPackage(pkg) - } - for _, root := range dr.Roots { - r.addRoot(root) - } - r.dr.GoVersion = dr.GoVersion -} - -func (r *responseDeduper) addPackage(p *Package) { - if r.seenPackages[p.ID] != nil { - return - } - r.seenPackages[p.ID] = p - r.dr.Packages = append(r.dr.Packages, p) -} - -func (r *responseDeduper) addRoot(id string) { - if r.seenRoots[id] { - return - } - r.seenRoots[id] = true - r.dr.Roots = append(r.dr.Roots, id) -} - -type golistState struct { - cfg *Config - ctx context.Context - - runner *gocommand.Runner - - // overlay is the JSON file that encodes the Config.Overlay - // mapping, used by 'go list -overlay=...'. - overlay string - - envOnce sync.Once - goEnvError error - goEnv map[string]string - - rootsOnce sync.Once - rootDirsError error - rootDirs map[string]string - - goVersionOnce sync.Once - goVersionError error - goVersion int // The X in Go 1.X. - - // vendorDirs caches the (non)existence of vendor directories. - vendorDirs map[string]bool -} - -// getEnv returns Go environment variables. Only specific variables are -// populated -- computing all of them is slow. -func (state *golistState) getEnv() (map[string]string, error) { - state.envOnce.Do(func() { - var b *bytes.Buffer - b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") - if state.goEnvError != nil { - return - } - - state.goEnv = make(map[string]string) - decoder := json.NewDecoder(b) - if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { - return - } - }) - return state.goEnv, state.goEnvError -} - -// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. -func (state *golistState) mustGetEnv() map[string]string { - env, err := state.getEnv() - if err != nil { - panic(fmt.Sprintf("mustGetEnv: %v", err)) - } - return env -} - -// goListDriver uses the go list command to interpret the patterns and produce -// the build system package structure. -// See driver for more details. -// -// overlay is the JSON file that encodes the cfg.Overlay -// mapping, used by 'go list -overlay=...' -func goListDriver(cfg *Config, runner *gocommand.Runner, overlay string, patterns []string) (_ *DriverResponse, err error) { - // Make sure that any asynchronous go commands are killed when we return. - parentCtx := cfg.Context - if parentCtx == nil { - parentCtx = context.Background() - } - ctx, cancel := context.WithCancel(parentCtx) - defer cancel() - - response := newDeduper() - - state := &golistState{ - cfg: cfg, - ctx: ctx, - vendorDirs: map[string]bool{}, - overlay: overlay, - runner: runner, - } - - // Fill in response.Sizes asynchronously if necessary. - if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - errCh := make(chan error) - go func() { - compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), runner) - response.dr.Compiler = compiler - response.dr.Arch = arch - errCh <- err - }() - defer func() { - if sizesErr := <-errCh; sizesErr != nil { - err = sizesErr - } - }() - } - - // Determine files requested in contains patterns - var containFiles []string - restPatterns := make([]string, 0, len(patterns)) - // Extract file= and other [querytype]= patterns. Report an error if querytype - // doesn't exist. -extractQueries: - for _, pattern := range patterns { - eqidx := strings.Index(pattern, "=") - if eqidx < 0 { - restPatterns = append(restPatterns, pattern) - } else { - query, value := pattern[:eqidx], pattern[eqidx+len("="):] - switch query { - case "file": - containFiles = append(containFiles, value) - case "pattern": - restPatterns = append(restPatterns, value) - case "": // not a reserved query - restPatterns = append(restPatterns, pattern) - default: - for _, rune := range query { - if rune < 'a' || rune > 'z' { // not a reserved query - restPatterns = append(restPatterns, pattern) - continue extractQueries - } - } - // Reject all other patterns containing "=" - return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) - } - } - } - - // See if we have any patterns to pass through to go list. Zero initial - // patterns also requires a go list call, since it's the equivalent of - // ".". - if len(restPatterns) > 0 || len(patterns) == 0 { - dr, err := state.createDriverResponse(restPatterns...) - if err != nil { - return nil, err - } - response.addAll(dr) - } - - if len(containFiles) != 0 { - if err := state.runContainsQueries(response, containFiles); err != nil { - return nil, err - } - } - - // (We may yet return an error due to defer.) - return response.dr, nil -} - -func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { - for _, query := range queries { - // TODO(matloob): Do only one query per directory. - fdir := filepath.Dir(query) - // Pass absolute path of directory to go list so that it knows to treat it as a directory, - // not a package path. - pattern, err := filepath.Abs(fdir) - if err != nil { - return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) - } - dirResponse, err := state.createDriverResponse(pattern) - - // If there was an error loading the package, or no packages are returned, - // or the package is returned with errors, try to load the file as an - // ad-hoc package. - // Usually the error will appear in a returned package, but may not if we're - // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && - len(dirResponse.Packages[0].Errors) == 1 { - var queryErr error - if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { - return err // return the original error - } - } - isRoot := make(map[string]bool, len(dirResponse.Roots)) - for _, root := range dirResponse.Roots { - isRoot[root] = true - } - for _, pkg := range dirResponse.Packages { - // Add any new packages to the main set - // We don't bother to filter packages that will be dropped by the changes of roots, - // that will happen anyway during graph construction outside this function. - // Over-reporting packages is not a problem. - response.addPackage(pkg) - // if the package was not a root one, it cannot have the file - if !isRoot[pkg.ID] { - continue - } - for _, pkgFile := range pkg.GoFiles { - if filepath.Base(query) == filepath.Base(pkgFile) { - response.addRoot(pkg.ID) - break - } - } - } - } - return nil -} - -// adhocPackage attempts to load or construct an ad-hoc package for a given -// query, if the original call to the driver produced inadequate results. -func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) { - response, err := state.createDriverResponse(query) - if err != nil { - return nil, err - } - // If we get nothing back from `go list`, - // try to make this file into its own ad-hoc package. - // TODO(rstambler): Should this check against the original response? - if len(response.Packages) == 0 { - response.Packages = append(response.Packages, &Package{ - ID: "command-line-arguments", - PkgPath: query, - GoFiles: []string{query}, - CompiledGoFiles: []string{query}, - Imports: make(map[string]*Package), - }) - response.Roots = append(response.Roots, "command-line-arguments") - } - // Handle special cases. - if len(response.Packages) == 1 { - // golang/go#33482: If this is a file= query for ad-hoc packages where - // the file only exists on an overlay, and exists outside of a module, - // add the file to the package and remove the errors. - if response.Packages[0].ID == "command-line-arguments" || - filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { - if len(response.Packages[0].GoFiles) == 0 { - filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath - // TODO(matloob): check if the file is outside of a root dir? - for path := range state.cfg.Overlay { - if path == filename { - response.Packages[0].Errors = nil - response.Packages[0].GoFiles = []string{path} - response.Packages[0].CompiledGoFiles = []string{path} - } - } - } - } - } - return response, nil -} - -// Fields must match go list; -// see $GOROOT/src/cmd/go/internal/load/pkg.go. -type jsonPackage struct { - ImportPath string - Dir string - Name string - Target string - Export string - GoFiles []string - CompiledGoFiles []string - IgnoredGoFiles []string - IgnoredOtherFiles []string - EmbedPatterns []string - EmbedFiles []string - CFiles []string - CgoFiles []string - CXXFiles []string - MFiles []string - HFiles []string - FFiles []string - SFiles []string - SwigFiles []string - SwigCXXFiles []string - SysoFiles []string - Imports []string - ImportMap map[string]string - Deps []string - Module *Module - TestGoFiles []string - TestImports []string - XTestGoFiles []string - XTestImports []string - ForTest string // q in a "p [q.test]" package, else "" - DepOnly bool - - Error *packagesinternal.PackageError - DepsErrors []*packagesinternal.PackageError -} - -type jsonPackageError struct { - ImportStack []string - Pos string - Err string -} - -func otherFiles(p *jsonPackage) [][]string { - return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} -} - -// createDriverResponse uses the "go list" command to expand the pattern -// words and return a response for the specified packages. -func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) { - // go list uses the following identifiers in ImportPath and Imports: - // - // "p" -- importable package or main (command) - // "q.test" -- q's test executable - // "p [q.test]" -- variant of p as built for q's test executable - // "q_test [q.test]" -- q's external test package - // - // The packages p that are built differently for a test q.test - // are q itself, plus any helpers used by the external test q_test, - // typically including "testing" and all its dependencies. - - // Run "go list" for complete - // information on the specified packages. - goVersion, err := state.getGoVersion() - if err != nil { - return nil, err - } - buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) - if err != nil { - return nil, err - } - - seen := make(map[string]*jsonPackage) - pkgs := make(map[string]*Package) - additionalErrors := make(map[string][]Error) - // Decode the JSON and convert it to Package form. - response := &DriverResponse{ - GoVersion: goVersion, - } - for dec := json.NewDecoder(buf); dec.More(); { - p := new(jsonPackage) - if err := dec.Decode(p); err != nil { - return nil, fmt.Errorf("JSON decoding failed: %v", err) - } - - if p.ImportPath == "" { - // The documentation for go list says that “[e]rroneous packages will have - // a non-empty ImportPath”. If for some reason it comes back empty, we - // prefer to error out rather than silently discarding data or handing - // back a package without any way to refer to it. - if p.Error != nil { - return nil, Error{ - Pos: p.Error.Pos, - Msg: p.Error.Err, - } - } - return nil, fmt.Errorf("package missing import path: %+v", p) - } - - // Work around https://golang.org/issue/33157: - // go list -e, when given an absolute path, will find the package contained at - // that directory. But when no package exists there, it will return a fake package - // with an error and the ImportPath set to the absolute path provided to go list. - // Try to convert that absolute path to what its package path would be if it's - // contained in a known module or GOPATH entry. This will allow the package to be - // properly "reclaimed" when overlays are processed. - if filepath.IsAbs(p.ImportPath) && p.Error != nil { - pkgPath, ok, err := state.getPkgPath(p.ImportPath) - if err != nil { - return nil, err - } - if ok { - p.ImportPath = pkgPath - } - } - - if old, found := seen[p.ImportPath]; found { - // If one version of the package has an error, and the other doesn't, assume - // that this is a case where go list is reporting a fake dependency variant - // of the imported package: When a package tries to invalidly import another - // package, go list emits a variant of the imported package (with the same - // import path, but with an error on it, and the package will have a - // DepError set on it). An example of when this can happen is for imports of - // main packages: main packages can not be imported, but they may be - // separately matched and listed by another pattern. - // See golang.org/issue/36188 for more details. - - // The plan is that eventually, hopefully in Go 1.15, the error will be - // reported on the importing package rather than the duplicate "fake" - // version of the imported package. Once all supported versions of Go - // have the new behavior this logic can be deleted. - // TODO(matloob): delete the workaround logic once all supported versions of - // Go return the errors on the proper package. - - // There should be exactly one version of a package that doesn't have an - // error. - if old.Error == nil && p.Error == nil { - if !reflect.DeepEqual(p, old) { - return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) - } - continue - } - - // Determine if this package's error needs to be bubbled up. - // This is a hack, and we expect for go list to eventually set the error - // on the package. - if old.Error != nil { - var errkind string - if strings.Contains(old.Error.Err, "not an importable package") { - errkind = "not an importable package" - } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { - errkind = "use of internal package not allowed" - } - if errkind != "" { - if len(old.Error.ImportStack) < 1 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) - } - importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] - if importingPkg == old.ImportPath { - // Using an older version of Go which put this package itself on top of import - // stack, instead of the importer. Look for importer in second from top - // position. - if len(old.Error.ImportStack) < 2 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) - } - importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] - } - additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ - Pos: old.Error.Pos, - Msg: old.Error.Err, - Kind: ListError, - }) - } - } - - // Make sure that if there's a version of the package without an error, - // that's the one reported to the user. - if old.Error == nil { - continue - } - - // This package will replace the old one at the end of the loop. - } - seen[p.ImportPath] = p - - pkg := &Package{ - Name: p.Name, - ID: p.ImportPath, - Dir: p.Dir, - Target: p.Target, - GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), - CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), - OtherFiles: absJoin(p.Dir, otherFiles(p)...), - EmbedFiles: absJoin(p.Dir, p.EmbedFiles), - EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), - IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), - ForTest: p.ForTest, - depsErrors: p.DepsErrors, - Module: p.Module, - } - - if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { - if len(p.CompiledGoFiles) > len(p.GoFiles) { - // We need the cgo definitions, which are in the first - // CompiledGoFile after the non-cgo ones. This is a hack but there - // isn't currently a better way to find it. We also need the pure - // Go files and unprocessed cgo files, all of which are already - // in pkg.GoFiles. - cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] - pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) - } else { - // golang/go#38990: go list silently fails to do cgo processing - pkg.CompiledGoFiles = nil - pkg.Errors = append(pkg.Errors, Error{ - Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.", - Kind: ListError, - }) - } - } - - // Work around https://golang.org/issue/28749: - // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. - // Remove files from CompiledGoFiles that are non-go files - // (or are not files that look like they are from the cache). - if len(pkg.CompiledGoFiles) > 0 { - out := pkg.CompiledGoFiles[:0] - for _, f := range pkg.CompiledGoFiles { - if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file - continue - } - out = append(out, f) - } - pkg.CompiledGoFiles = out - } - - // Extract the PkgPath from the package's ID. - if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { - pkg.PkgPath = pkg.ID[:i] - } else { - pkg.PkgPath = pkg.ID - } - - if pkg.PkgPath == "unsafe" { - pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929) - } else if len(pkg.CompiledGoFiles) == 0 { - // Work around for pre-go.1.11 versions of go list. - // TODO(matloob): they should be handled by the fallback. - // Can we delete this? - pkg.CompiledGoFiles = pkg.GoFiles - } - - // Assume go list emits only absolute paths for Dir. - if p.Dir != "" && !filepath.IsAbs(p.Dir) { - log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) - } - - if p.Export != "" && !filepath.IsAbs(p.Export) { - pkg.ExportFile = filepath.Join(p.Dir, p.Export) - } else { - pkg.ExportFile = p.Export - } - - // imports - // - // Imports contains the IDs of all imported packages. - // ImportsMap records (path, ID) only where they differ. - ids := make(map[string]bool) - for _, id := range p.Imports { - ids[id] = true - } - pkg.Imports = make(map[string]*Package) - for path, id := range p.ImportMap { - pkg.Imports[path] = &Package{ID: id} // non-identity import - delete(ids, id) - } - for id := range ids { - if id == "C" { - continue - } - - pkg.Imports[id] = &Package{ID: id} // identity import - } - if !p.DepOnly { - response.Roots = append(response.Roots, pkg.ID) - } - - // Temporary work-around for golang/go#39986. Parse filenames out of - // error messages. This happens if there are unrecoverable syntax - // errors in the source, so we can't match on a specific error message. - // - // TODO(rfindley): remove this heuristic, in favor of considering - // InvalidGoFiles from the list driver. - if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { - addFilenameFromPos := func(pos string) bool { - split := strings.Split(pos, ":") - if len(split) < 1 { - return false - } - filename := strings.TrimSpace(split[0]) - if filename == "" { - return false - } - if !filepath.IsAbs(filename) { - filename = filepath.Join(state.cfg.Dir, filename) - } - info, _ := os.Stat(filename) - if info == nil { - return false - } - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) - pkg.GoFiles = append(pkg.GoFiles, filename) - return true - } - found := addFilenameFromPos(err.Pos) - // In some cases, go list only reports the error position in the - // error text, not the error position. One such case is when the - // file's package name is a keyword (see golang.org/issue/39763). - if !found { - addFilenameFromPos(err.Err) - } - } - - if p.Error != nil { - msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. - // Address golang.org/issue/35964 by appending import stack to error message. - if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { - msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) - } - pkg.Errors = append(pkg.Errors, Error{ - Pos: p.Error.Pos, - Msg: msg, - Kind: ListError, - }) - } - - pkgs[pkg.ID] = pkg - } - - for id, errs := range additionalErrors { - if p, ok := pkgs[id]; ok { - p.Errors = append(p.Errors, errs...) - } - } - for _, pkg := range pkgs { - response.Packages = append(response.Packages, pkg) - } - sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) - - return response, nil -} - -func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { - if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { - return false - } - - goV, err := state.getGoVersion() - if err != nil { - return false - } - - // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. - // The import stack behaves differently for these versions than newer Go versions. - if goV < 15 { - return len(p.Error.ImportStack) == 0 - } - - // On Go 1.15 and later, only parse filenames out of error if there's no import stack, - // or the current package is at the top of the import stack. This is not guaranteed - // to work perfectly, but should avoid some cases where files in errors don't belong to this - // package. - return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath -} - -// getGoVersion returns the effective minor version of the go command. -func (state *golistState) getGoVersion() (int, error) { - state.goVersionOnce.Do(func() { - state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.runner) - }) - return state.goVersion, state.goVersionError -} - -// getPkgPath finds the package path of a directory if it's relative to a root -// directory. -func (state *golistState) getPkgPath(dir string) (string, bool, error) { - absDir, err := filepath.Abs(dir) - if err != nil { - return "", false, err - } - roots, err := state.determineRootDirs() - if err != nil { - return "", false, err - } - - for rdir, rpath := range roots { - // Make sure that the directory is in the module, - // to avoid creating a path relative to another module. - if !strings.HasPrefix(absDir, rdir) { - continue - } - // TODO(matloob): This doesn't properly handle symlinks. - r, err := filepath.Rel(rdir, dir) - if err != nil { - continue - } - if rpath != "" { - // We choose only one root even though the directory even it can belong in multiple modules - // or GOPATH entries. This is okay because we only need to work with absolute dirs when a - // file is missing from disk, for instance when gopls calls go/packages in an overlay. - // Once the file is saved, gopls, or the next invocation of the tool will get the correct - // result straight from golist. - // TODO(matloob): Implement module tiebreaking? - return path.Join(rpath, filepath.ToSlash(r)), true, nil - } - return filepath.ToSlash(r), true, nil - } - return "", false, nil -} - -// absJoin absolutizes and flattens the lists of files. -func absJoin(dir string, fileses ...[]string) (res []string) { - for _, files := range fileses { - for _, file := range files { - if !filepath.IsAbs(file) { - file = filepath.Join(dir, file) - } - res = append(res, file) - } - } - return res -} - -func jsonFlag(cfg *Config, goVersion int) string { - if goVersion < 19 { - return "-json" - } - var fields []string - added := make(map[string]bool) - addFields := func(fs ...string) { - for _, f := range fs { - if !added[f] { - added[f] = true - fields = append(fields, f) - } - } - } - addFields("Name", "ImportPath", "Error") // These fields are always needed - if cfg.Mode&NeedFiles != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", - "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", - "SwigFiles", "SwigCXXFiles", "SysoFiles") - if cfg.Tests { - addFields("TestGoFiles", "XTestGoFiles") - } - } - if cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, - // even when -compiled isn't passed in. - // TODO(#52435): Should we make the test ask for -compiled, or automatically - // request CompiledGoFiles in certain circumstances? - addFields("Dir", "CompiledGoFiles") - } - if cfg.Mode&NeedCompiledGoFiles != 0 { - addFields("Dir", "CompiledGoFiles", "Export") - } - if cfg.Mode&NeedImports != 0 { - // When imports are requested, DepOnly is used to distinguish between packages - // explicitly requested and transitive imports of those packages. - addFields("DepOnly", "Imports", "ImportMap") - if cfg.Tests { - addFields("TestImports", "XTestImports") - } - } - if cfg.Mode&NeedDeps != 0 { - addFields("DepOnly") - } - if usesExportData(cfg) { - // Request Dir in the unlikely case Export is not absolute. - addFields("Dir", "Export") - } - if cfg.Mode&NeedForTest != 0 { - addFields("ForTest") - } - if cfg.Mode&needInternalDepsErrors != 0 { - addFields("DepsErrors") - } - if cfg.Mode&NeedModule != 0 { - addFields("Module") - } - if cfg.Mode&NeedEmbedFiles != 0 { - addFields("EmbedFiles") - } - if cfg.Mode&NeedEmbedPatterns != 0 { - addFields("EmbedPatterns") - } - if cfg.Mode&NeedTarget != 0 { - addFields("Target") - } - return "-json=" + strings.Join(fields, ",") -} - -func golistargs(cfg *Config, words []string, goVersion int) []string { - const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo - fullargs := []string{ - "-e", jsonFlag(cfg, goVersion), - fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), - fmt.Sprintf("-test=%t", cfg.Tests), - fmt.Sprintf("-export=%t", usesExportData(cfg)), - fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), - // go list doesn't let you pass -test and -find together, - // probably because you'd just get the TestMain. - fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), - } - - // golang/go#60456: with go1.21 and later, go list serves pgo variants, which - // can be costly to compute and may result in redundant processing for the - // caller. Disable these variants. If someone wants to add e.g. a NeedPGO - // mode flag, that should be a separate proposal. - if goVersion >= 21 { - fullargs = append(fullargs, "-pgo=off") - } - - fullargs = append(fullargs, cfg.BuildFlags...) - fullargs = append(fullargs, "--") - fullargs = append(fullargs, words...) - return fullargs -} - -// cfgInvocation returns an Invocation that reflects cfg's settings. -func (state *golistState) cfgInvocation() gocommand.Invocation { - cfg := state.cfg - return gocommand.Invocation{ - BuildFlags: cfg.BuildFlags, - ModFile: cfg.modFile, - ModFlag: cfg.modFlag, - CleanEnv: cfg.Env != nil, - Env: cfg.Env, - Logf: cfg.Logf, - WorkingDir: cfg.Dir, - Overlay: state.overlay, - } -} - -// invokeGo returns the stdout of a go command invocation. -func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { - cfg := state.cfg - - inv := state.cfgInvocation() - inv.Verb = verb - inv.Args = args - - stdout, stderr, friendlyErr, err := state.runner.RunRaw(cfg.Context, inv) - if err != nil { - // Check for 'go' executable not being found. - if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) - } - - exitErr, ok := err.(*exec.ExitError) - if !ok { - // Catastrophic error: - // - context cancellation - return nil, fmt.Errorf("couldn't run 'go': %w", err) - } - - // Old go version? - if strings.Contains(stderr.String(), "flag provided but not defined") { - return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} - } - - // Related to #24854 - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { - return nil, friendlyErr - } - - // Return an error if 'go list' failed due to missing tools in - // $GOROOT/pkg/tool/$GOOS_$GOARCH (#69606). - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), `go: no such tool`) { - return nil, friendlyErr - } - - // Is there an error running the C compiler in cgo? This will be reported in the "Error" field - // and should be suppressed by go list -e. - // - // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. - isPkgPathRune := func(r rune) bool { - // From https://golang.org/ref/spec#Import_declarations: - // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings - // using only characters belonging to Unicode's L, M, N, P, and S general categories - // (the Graphic characters without spaces) and may also exclude the - // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. - return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && - !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) - } - // golang/go#36770: Handle case where cmd/go prints module download messages before the error. - msg := stderr.String() - for strings.HasPrefix(msg, "go: downloading") { - msg = msg[strings.IndexRune(msg, '\n')+1:] - } - if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { - msg := msg[len("# "):] - if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { - return stdout, nil - } - // Treat pkg-config errors as a special case (golang.org/issue/36770). - if strings.HasPrefix(msg, "pkg-config") { - return stdout, nil - } - } - - // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show - // the error in the Err section of stdout in case -e option is provided. - // This fix is provided for backwards compatibility. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Similar to the previous error, but currently lacks a fix in Go. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. - // If the package doesn't exist, put the absolute path of the directory into the error message, - // as Go 1.13 list does. - const noSuchDirectory = "no such directory" - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { - errstr := stderr.String() - abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - abspath, strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. - // Note that the error message we look for in this case is different that the one looked for above. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a - // directory outside any module. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Another variation of the previous error - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit - // status if there's a dependency on a package that doesn't exist. But it should return - // a zero exit status and set an error on that package. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { - // Don't clobber stdout if `go list` actually returned something. - if len(stdout.String()) > 0 { - return stdout, nil - } - // try to extract package name from string - stderrStr := stderr.String() - var importPath string - colon := strings.Index(stderrStr, ":") - if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { - importPath = stderrStr[len("go build "):colon] - } - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - importPath, strings.Trim(stderrStr, "\n")) - return bytes.NewBufferString(output), nil - } - - // Export mode entails a build. - // If that build fails, errors appear on stderr - // (despite the -e flag) and the Export field is blank. - // Do not fail in that case. - // The same is true if an ad-hoc package given to go list doesn't exist. - // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when - // packages don't exist or a build fails. - if !usesExportData(cfg) && !containsGoFile(args) { - return nil, friendlyErr - } - } - return stdout, nil -} - -func containsGoFile(s []string) bool { - for _, f := range s { - if strings.HasSuffix(f, ".go") { - return true - } - } - return false -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - k, v := split[0], split[1] - env[k] = v - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} - -// getSizesForArgs queries 'go list' for the appropriate -// Compiler and GOARCH arguments to pass to [types.SizesFor]. -func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { - inv.Verb = "list" - inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} - stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) - var goarch, compiler string - if rawErr != nil { - rawErrMsg := rawErr.Error() - if strings.Contains(rawErrMsg, "cannot find main module") || - strings.Contains(rawErrMsg, "go.mod file not found") { - // User's running outside of a module. - // All bets are off. Get GOARCH and guess compiler is gc. - // TODO(matloob): Is this a problem in practice? - inv.Verb = "env" - inv.Args = []string{"GOARCH"} - envout, enverr := gocmdRunner.Run(ctx, inv) - if enverr != nil { - return "", "", enverr - } - goarch = strings.TrimSpace(envout.String()) - compiler = "gc" - } else if friendlyErr != nil { - return "", "", friendlyErr - } else { - // This should be unreachable, but be defensive - // in case RunRaw's error results are inconsistent. - return "", "", rawErr - } - } else { - fields := strings.Fields(stdout.String()) - if len(fields) < 2 { - return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", - stdout.String(), stderr.String()) - } - goarch = fields[0] - compiler = fields[1] - } - return compiler, goarch, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go deleted file mode 100644 index d823c47..0000000 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ /dev/null @@ -1,83 +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. - -package packages - -import ( - "encoding/json" - "path/filepath" - - "golang.org/x/tools/internal/gocommand" -) - -// determineRootDirs returns a mapping from absolute directories that could -// contain code to their corresponding import path prefixes. -func (state *golistState) determineRootDirs() (map[string]string, error) { - env, err := state.getEnv() - if err != nil { - return nil, err - } - if env["GOMOD"] != "" { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsModules() - }) - } else { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() - }) - } - return state.rootDirs, state.rootDirsError -} - -func (state *golistState) determineRootDirsModules() (map[string]string, error) { - // List all of the modules--the first will be the directory for the main - // module. Any replaced modules will also need to be treated as roots. - // Editing files in the module cache isn't a great idea, so we don't - // plan to ever support that. - out, err := state.invokeGo("list", "-m", "-json", "all") - if err != nil { - // 'go list all' will fail if we're outside of a module and - // GO111MODULE=on. Try falling back without 'all'. - var innerErr error - out, innerErr = state.invokeGo("list", "-m", "-json") - if innerErr != nil { - return nil, err - } - } - roots := map[string]string{} - modules := map[string]string{} - var i int - for dec := json.NewDecoder(out); dec.More(); { - mod := new(gocommand.ModuleJSON) - if err := dec.Decode(mod); err != nil { - return nil, err - } - if mod.Dir != "" && mod.Path != "" { - // This is a valid module; add it to the map. - absDir, err := filepath.Abs(mod.Dir) - if err != nil { - return nil, err - } - modules[absDir] = mod.Path - // The first result is the main module. - if i == 0 || mod.Replace != nil && mod.Replace.Path != "" { - roots[absDir] = mod.Path - } - } - i++ - } - return roots, nil -} - -func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { - m := map[string]string{} - for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { - absDir, err := filepath.Abs(dir) - if err != nil { - return nil, err - } - m[filepath.Join(absDir, "src")] = "" - } - return m, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go deleted file mode 100644 index 69eec9f..0000000 --- a/vendor/golang.org/x/tools/go/packages/loadmode_string.go +++ /dev/null @@ -1,56 +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. - -package packages - -import ( - "fmt" - "strings" -) - -var modes = [...]struct { - mode LoadMode - name string -}{ - {NeedName, "NeedName"}, - {NeedFiles, "NeedFiles"}, - {NeedCompiledGoFiles, "NeedCompiledGoFiles"}, - {NeedImports, "NeedImports"}, - {NeedDeps, "NeedDeps"}, - {NeedExportFile, "NeedExportFile"}, - {NeedTypes, "NeedTypes"}, - {NeedSyntax, "NeedSyntax"}, - {NeedTypesInfo, "NeedTypesInfo"}, - {NeedTypesSizes, "NeedTypesSizes"}, - {NeedForTest, "NeedForTest"}, - {NeedModule, "NeedModule"}, - {NeedEmbedFiles, "NeedEmbedFiles"}, - {NeedEmbedPatterns, "NeedEmbedPatterns"}, - {NeedTarget, "NeedTarget"}, -} - -func (mode LoadMode) String() string { - if mode == 0 { - return "LoadMode(0)" - } - var out []string - // named bits - for _, item := range modes { - if (mode & item.mode) != 0 { - mode ^= item.mode - out = append(out, item.name) - } - } - // unnamed residue - if mode != 0 { - if out == nil { - return fmt.Sprintf("LoadMode(%#x)", int(mode)) - } - out = append(out, fmt.Sprintf("%#x", int(mode))) - } - if len(out) == 1 { - return out[0] - } - return "(" + strings.Join(out, "|") + ")" -} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go deleted file mode 100644 index c3a59b8..0000000 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ /dev/null @@ -1,1571 +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. - -package packages - -// See doc.go for package documentation and implementation notes. - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "log" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/sync/errgroup" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/typesinternal" -) - -// A LoadMode controls the amount of detail to return when loading. -// The bits below can be combined to specify which fields should be -// filled in the result packages. -// -// The zero value is a special case, equivalent to combining -// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. -// -// ID and Errors (if present) will always be filled. -// [Load] may return more information than requested. -// -// The Mode flag is a union of several bits named NeedName, -// NeedFiles, and so on, each of which determines whether -// a given field of Package (Name, Files, etc) should be -// populated. -// -// For convenience, we provide named constants for the most -// common combinations of Need flags: -// -// [LoadFiles] lists of files in each package -// [LoadImports] ... plus imports -// [LoadTypes] ... plus type information -// [LoadSyntax] ... plus type-annotated syntax -// [LoadAllSyntax] ... for all dependencies -// -// Unfortunately there are a number of open bugs related to -// interactions among the LoadMode bits: -// - https://go.dev/issue/56633 -// - https://go.dev/issue/56677 -// - https://go.dev/issue/58726 -// - https://go.dev/issue/63517 -type LoadMode int - -const ( - // NeedName adds Name and PkgPath. - NeedName LoadMode = 1 << iota - - // NeedFiles adds Dir, GoFiles, OtherFiles, and IgnoredFiles - NeedFiles - - // NeedCompiledGoFiles adds CompiledGoFiles. - NeedCompiledGoFiles - - // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain - // "placeholder" Packages with only the ID set. - NeedImports - - // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. - NeedDeps - - // NeedExportFile adds ExportFile. - NeedExportFile - - // NeedTypes adds Types, Fset, and IllTyped. - NeedTypes - - // NeedSyntax adds Syntax and Fset. - NeedSyntax - - // NeedTypesInfo adds TypesInfo and Fset. - NeedTypesInfo - - // NeedTypesSizes adds TypesSizes. - NeedTypesSizes - - // needInternalDepsErrors adds the internal deps errors field for use by gopls. - needInternalDepsErrors - - // NeedForTest adds ForTest. - // - // Tests must also be set on the context for this field to be populated. - NeedForTest - - // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. - // Modifies CompiledGoFiles and Types, and has no effect on its own. - typecheckCgo - - // NeedModule adds Module. - NeedModule - - // NeedEmbedFiles adds EmbedFiles. - NeedEmbedFiles - - // NeedEmbedPatterns adds EmbedPatterns. - NeedEmbedPatterns - - // NeedTarget adds Target. - NeedTarget - - // Be sure to update loadmode_string.go when adding new items! -) - -const ( - // LoadFiles loads the name and file names for the initial packages. - LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles - - // LoadImports loads the name, file names, and import mapping for the initial packages. - LoadImports = LoadFiles | NeedImports - - // LoadTypes loads exported type information for the initial packages. - LoadTypes = LoadImports | NeedTypes | NeedTypesSizes - - // LoadSyntax loads typed syntax for the initial packages. - LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo - - // LoadAllSyntax loads typed syntax for the initial packages and all dependencies. - LoadAllSyntax = LoadSyntax | NeedDeps - - // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. - NeedExportsFile = NeedExportFile -) - -// A Config specifies details about how packages should be loaded. -// The zero value is a valid configuration. -// -// Calls to [Load] do not modify this struct. -type Config struct { - // Mode controls the level of information returned for each package. - Mode LoadMode - - // Context specifies the context for the load operation. - // Cancelling the context may cause [Load] to abort and - // return an error. - Context context.Context - - // Logf is the logger for the config. - // If the user provides a logger, debug logging is enabled. - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the logger is nil, default to log.Printf. - Logf func(format string, args ...interface{}) - - // Dir is the directory in which to run the build system's query tool - // that provides information about the packages. - // If Dir is empty, the tool is run in the current directory. - Dir string - - // Env is the environment to use when invoking the build system's query tool. - // If Env is nil, the current environment is used. - // As in os/exec's Cmd, only the last value in the slice for - // each environment key is used. To specify the setting of only - // a few variables, append to the current environment, as in: - // - // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") - // - Env []string - - // BuildFlags is a list of command-line flags to be passed through to - // the build system's query tool. - BuildFlags []string - - // Fset provides source position information for syntax trees and types. - // If Fset is nil, Load will use a new fileset, but preserve Fset's value. - Fset *token.FileSet - - // ParseFile is called to read and parse each file - // when preparing a package's type-checked syntax tree. - // It must be safe to call ParseFile simultaneously from multiple goroutines. - // If ParseFile is nil, the loader will uses parser.ParseFile. - // - // ParseFile should parse the source from src and use filename only for - // recording position information. - // - // An application may supply a custom implementation of ParseFile - // to change the effective file contents or the behavior of the parser, - // or to modify the syntax tree. For example, selectively eliminating - // unwanted function bodies can significantly accelerate type checking. - ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) - - // If Tests is set, the loader includes not just the packages - // matching a particular pattern but also any related test packages, - // including test-only variants of the package and the test executable. - // - // For example, when using the go command, loading "fmt" with Tests=true - // returns four packages, with IDs "fmt" (the standard package), - // "fmt [fmt.test]" (the package as compiled for the test), - // "fmt_test" (the test functions from source files in package fmt_test), - // and "fmt.test" (the test binary). - // - // In build systems with explicit names for tests, - // setting Tests may have no effect. - Tests bool - - // Overlay is a mapping from absolute file paths to file contents. - // - // For each map entry, [Load] uses the alternative file - // contents provided by the overlay mapping instead of reading - // from the file system. This mechanism can be used to enable - // editor-integrated tools to correctly analyze the contents - // of modified but unsaved buffers, for example. - // - // The overlay mapping is passed to the build system's driver - // (see "The driver protocol") so that it too can report - // consistent package metadata about unsaved files. However, - // drivers may vary in their level of support for overlays. - Overlay map[string][]byte - - // -- Hidden configuration fields only for use in x/tools -- - - // modFile will be used for -modfile in go command invocations. - modFile string - - // modFlag will be used for -modfile in go command invocations. - modFlag string -} - -// Load loads and returns the Go packages named by the given patterns. -// -// The cfg parameter specifies loading options; nil behaves the same as an empty [Config]. -// -// The [Config.Mode] field is a set of bits that determine what kinds -// of information should be computed and returned. Modes that require -// more information tend to be slower. See [LoadMode] for details -// and important caveats. Its zero value is equivalent to -// [NeedName] | [NeedFiles] | [NeedCompiledGoFiles]. -// -// Each call to Load returns a new set of [Package] instances. -// The Packages and their Imports form a directed acyclic graph. -// -// If the [NeedTypes] mode flag was set, each call to Load uses a new -// [types.Importer], so [types.Object] and [types.Type] values from -// different calls to Load must not be mixed as they will have -// inconsistent notions of type identity. -// -// If any of the patterns was invalid as defined by the -// underlying build system, Load returns an error. -// It may return an empty list of packages without an error, -// for instance for an empty expansion of a valid wildcard. -// Errors associated with a particular package are recorded in the -// corresponding Package's Errors list, and do not cause Load to -// return an error. Clients may need to handle such errors before -// proceeding with further analysis. The [PrintErrors] function is -// provided for convenient display of all errors. -func Load(cfg *Config, patterns ...string) ([]*Package, error) { - ld := newLoader(cfg) - response, external, err := defaultDriver(&ld.Config, patterns...) - if err != nil { - return nil, err - } - - ld.sizes = types.SizesFor(response.Compiler, response.Arch) - if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { - // Type size information is needed but unavailable. - if external { - // An external driver may fail to populate the Compiler/GOARCH fields, - // especially since they are relatively new (see #63700). - // Provide a sensible fallback in this case. - ld.sizes = types.SizesFor("gc", runtime.GOARCH) - if ld.sizes == nil { // gccgo-only arch - ld.sizes = types.SizesFor("gc", "amd64") - } - } else { - // Go list should never fail to deliver accurate size information. - // Reject the whole Load since the error is the same for every package. - return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", - response.Compiler, response.Arch) - } - } - - return ld.refine(response) -} - -// defaultDriver is a driver that implements go/packages' fallback behavior. -// It will try to request to an external driver, if one exists. If there's -// no external driver, or the driver returns a response with NotHandled set, -// defaultDriver will fall back to the go list driver. -// The boolean result indicates that an external driver handled the request. -func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) { - const ( - // windowsArgMax specifies the maximum command line length for - // the Windows' CreateProcess function. - windowsArgMax = 32767 - // maxEnvSize is a very rough estimation of the maximum environment - // size of a user. - maxEnvSize = 16384 - // safeArgMax specifies the maximum safe command line length to use - // by the underlying driver excl. the environment. We choose the Windows' - // ARG_MAX as the starting point because it's one of the lowest ARG_MAX - // constants out of the different supported platforms, - // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results. - safeArgMax = windowsArgMax - maxEnvSize - ) - chunks, err := splitIntoChunks(patterns, safeArgMax) - if err != nil { - return nil, false, err - } - - if driver := findExternalDriver(cfg); driver != nil { - response, err := callDriverOnChunks(driver, cfg, chunks) - if err != nil { - return nil, false, err - } else if !response.NotHandled { - return response, true, nil - } - // not handled: fall through - } - - // go list fallback - - // Write overlays once, as there are many calls - // to 'go list' (one per chunk plus others too). - overlayFile, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay) - if err != nil { - return nil, false, err - } - defer cleanupOverlay() - - var runner gocommand.Runner // (shared across many 'go list' calls) - driver := func(cfg *Config, patterns []string) (*DriverResponse, error) { - return goListDriver(cfg, &runner, overlayFile, patterns) - } - response, err := callDriverOnChunks(driver, cfg, chunks) - if err != nil { - return nil, false, err - } - return response, false, err -} - -// splitIntoChunks chunks the slice so that the total number of characters -// in a chunk is no longer than argMax. -func splitIntoChunks(patterns []string, argMax int) ([][]string, error) { - if argMax <= 0 { - return nil, errors.New("failed to split patterns into chunks, negative safe argMax value") - } - var chunks [][]string - charsInChunk := 0 - nextChunkStart := 0 - for i, v := range patterns { - vChars := len(v) - if vChars > argMax { - // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen - return nil, errors.New("failed to split patterns into chunks, a pattern is too long") - } - charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too - if charsInChunk > argMax { - chunks = append(chunks, patterns[nextChunkStart:i]) - nextChunkStart = i - charsInChunk = vChars - } - } - // add the last chunk - if nextChunkStart < len(patterns) { - chunks = append(chunks, patterns[nextChunkStart:]) - } - return chunks, nil -} - -func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) { - if len(chunks) == 0 { - return driver(cfg, nil) - } - responses := make([]*DriverResponse, len(chunks)) - errNotHandled := errors.New("driver returned NotHandled") - var g errgroup.Group - for i, chunk := range chunks { - g.Go(func() (err error) { - responses[i], err = driver(cfg, chunk) - if responses[i] != nil && responses[i].NotHandled { - err = errNotHandled - } - return err - }) - } - if err := g.Wait(); err != nil { - if errors.Is(err, errNotHandled) { - return &DriverResponse{NotHandled: true}, nil - } - return nil, err - } - return mergeResponses(responses...), nil -} - -func mergeResponses(responses ...*DriverResponse) *DriverResponse { - if len(responses) == 0 { - return nil - } - response := newDeduper() - response.dr.NotHandled = false - response.dr.Compiler = responses[0].Compiler - response.dr.Arch = responses[0].Arch - response.dr.GoVersion = responses[0].GoVersion - for _, v := range responses { - response.addAll(v) - } - return response.dr -} - -// A Package describes a loaded Go package. -// -// It also defines part of the JSON schema of [DriverResponse]. -// See the package documentation for an overview. -type Package struct { - // ID is a unique identifier for a package, - // in a syntax provided by the underlying build system. - // - // Because the syntax varies based on the build system, - // clients should treat IDs as opaque and not attempt to - // interpret them. - ID string - - // Name is the package name as it appears in the package source code. - Name string - - // PkgPath is the package path as used by the go/types package. - PkgPath string - - // Dir is the directory associated with the package, if it exists. - // - // For packages listed by the go command, this is the directory containing - // the package files. - Dir string - - // Errors contains any errors encountered querying the metadata - // of the package, or while parsing or type-checking its files. - Errors []Error - - // TypeErrors contains the subset of errors produced during type checking. - TypeErrors []types.Error - - // GoFiles lists the absolute file paths of the package's Go source files. - // It may include files that should not be compiled, for example because - // they contain non-matching build tags, are documentary pseudo-files such as - // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing. - GoFiles []string - - // CompiledGoFiles lists the absolute file paths of the package's source - // files that are suitable for type checking. - // This may differ from GoFiles if files are processed before compilation. - CompiledGoFiles []string - - // OtherFiles lists the absolute file paths of the package's non-Go source files, - // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. - OtherFiles []string - - // EmbedFiles lists the absolute file paths of the package's files - // embedded with go:embed. - EmbedFiles []string - - // EmbedPatterns lists the absolute file patterns of the package's - // files embedded with go:embed. - EmbedPatterns []string - - // IgnoredFiles lists source files that are not part of the package - // using the current build configuration but that might be part of - // the package using other build configurations. - IgnoredFiles []string - - // ExportFile is the absolute path to a file containing type - // information for the package as provided by the build system. - ExportFile string - - // Target is the absolute install path of the .a file, for libraries, - // and of the executable file, for binaries. - Target string - - // Imports maps import paths appearing in the package's Go source files - // to corresponding loaded Packages. - Imports map[string]*Package - - // Module is the module information for the package if it exists. - // - // Note: it may be missing for std and cmd; see Go issue #65816. - Module *Module - - // -- The following fields are not part of the driver JSON schema. -- - - // Types provides type information for the package. - // The NeedTypes LoadMode bit sets this field for packages matching the - // patterns; type information for dependencies may be missing or incomplete, - // unless NeedDeps and NeedImports are also set. - // - // Each call to [Load] returns a consistent set of type - // symbols, as defined by the comment at [types.Identical]. - // Avoid mixing type information from two or more calls to [Load]. - Types *types.Package `json:"-"` - - // Fset provides position information for Types, TypesInfo, and Syntax. - // It is set only when Types is set. - Fset *token.FileSet `json:"-"` - - // IllTyped indicates whether the package or any dependency contains errors. - // It is set only when Types is set. - IllTyped bool `json:"-"` - - // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. - // - // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. - // If NeedDeps and NeedImports are also set, this field will also be populated - // for dependencies. - // - // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are - // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. - Syntax []*ast.File `json:"-"` - - // TypesInfo provides type information about the package's syntax trees. - // It is set only when Syntax is set. - TypesInfo *types.Info `json:"-"` - - // TypesSizes provides the effective size function for types in TypesInfo. - TypesSizes types.Sizes `json:"-"` - - // -- internal -- - - // ForTest is the package under test, if any. - ForTest string - - // depsErrors is the DepsErrors field from the go list response, if any. - depsErrors []*packagesinternal.PackageError -} - -// Module provides module information for a package. -// -// It also defines part of the JSON schema of [DriverResponse]. -// See the package documentation for an overview. -type Module struct { - Path string // module path - Version string // module version - Replace *Module // replaced by this module - Time *time.Time // time version was created - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module - Error *ModuleError // error loading module -} - -// ModuleError holds errors loading a module. -type ModuleError struct { - Err string // the error itself -} - -func init() { - packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError { - return p.(*Package).depsErrors - } - packagesinternal.SetModFile = func(config interface{}, value string) { - config.(*Config).modFile = value - } - packagesinternal.SetModFlag = func(config interface{}, value string) { - config.(*Config).modFlag = value - } - packagesinternal.TypecheckCgo = int(typecheckCgo) - packagesinternal.DepsErrors = int(needInternalDepsErrors) -} - -// An Error describes a problem with a package's metadata, syntax, or types. -type Error struct { - Pos string // "file:line:col" or "file:line" or "" or "-" - Msg string - Kind ErrorKind -} - -// ErrorKind describes the source of the error, allowing the user to -// differentiate between errors generated by the driver, the parser, or the -// type-checker. -type ErrorKind int - -const ( - UnknownError ErrorKind = iota - ListError - ParseError - TypeError -) - -func (err Error) Error() string { - pos := err.Pos - if pos == "" { - pos = "-" // like token.Position{}.String() - } - return pos + ": " + err.Msg -} - -// flatPackage is the JSON form of Package -// It drops all the type and syntax fields, and transforms the Imports -// -// TODO(adonovan): identify this struct with Package, effectively -// publishing the JSON protocol. -type flatPackage struct { - ID string - Name string `json:",omitempty"` - PkgPath string `json:",omitempty"` - Errors []Error `json:",omitempty"` - GoFiles []string `json:",omitempty"` - CompiledGoFiles []string `json:",omitempty"` - OtherFiles []string `json:",omitempty"` - EmbedFiles []string `json:",omitempty"` - EmbedPatterns []string `json:",omitempty"` - IgnoredFiles []string `json:",omitempty"` - ExportFile string `json:",omitempty"` - Imports map[string]string `json:",omitempty"` -} - -// MarshalJSON returns the Package in its JSON form. -// For the most part, the structure fields are written out unmodified, and -// the type and syntax fields are skipped. -// The imports are written out as just a map of path to package id. -// The errors are written using a custom type that tries to preserve the -// structure of error types we know about. -// -// This method exists to enable support for additional build systems. It is -// not intended for use by clients of the API and we may change the format. -func (p *Package) MarshalJSON() ([]byte, error) { - flat := &flatPackage{ - ID: p.ID, - Name: p.Name, - PkgPath: p.PkgPath, - Errors: p.Errors, - GoFiles: p.GoFiles, - CompiledGoFiles: p.CompiledGoFiles, - OtherFiles: p.OtherFiles, - EmbedFiles: p.EmbedFiles, - EmbedPatterns: p.EmbedPatterns, - IgnoredFiles: p.IgnoredFiles, - ExportFile: p.ExportFile, - } - if len(p.Imports) > 0 { - flat.Imports = make(map[string]string, len(p.Imports)) - for path, ipkg := range p.Imports { - flat.Imports[path] = ipkg.ID - } - } - return json.Marshal(flat) -} - -// UnmarshalJSON reads in a Package from its JSON format. -// See MarshalJSON for details about the format accepted. -func (p *Package) UnmarshalJSON(b []byte) error { - flat := &flatPackage{} - if err := json.Unmarshal(b, &flat); err != nil { - return err - } - *p = Package{ - ID: flat.ID, - Name: flat.Name, - PkgPath: flat.PkgPath, - Errors: flat.Errors, - GoFiles: flat.GoFiles, - CompiledGoFiles: flat.CompiledGoFiles, - OtherFiles: flat.OtherFiles, - EmbedFiles: flat.EmbedFiles, - EmbedPatterns: flat.EmbedPatterns, - IgnoredFiles: flat.IgnoredFiles, - ExportFile: flat.ExportFile, - } - if len(flat.Imports) > 0 { - p.Imports = make(map[string]*Package, len(flat.Imports)) - for path, id := range flat.Imports { - p.Imports[path] = &Package{ID: id} - } - } - return nil -} - -func (p *Package) String() string { return p.ID } - -// loaderPackage augments Package with state used during the loading phase -type loaderPackage struct { - *Package - importErrors map[string]error // maps each bad import to its error - preds []*loaderPackage // packages that import this one - unfinishedSuccs atomic.Int32 // number of direct imports not yet loaded - color uint8 // for cycle detection - needsrc bool // load from source (Mode >= LoadTypes) - needtypes bool // type information is either requested or depended on - initial bool // package was matched by a pattern - goVersion int // minor version number of go command on PATH -} - -// loader holds the working state of a single call to load. -type loader struct { - pkgs map[string]*loaderPackage // keyed by Package.ID - Config - sizes types.Sizes // non-nil if needed by mode - parseCache map[string]*parseValue - parseCacheMu sync.Mutex - exportMu sync.Mutex // enforces mutual exclusion of exportdata operations - - // Config.Mode contains the implied mode (see impliedLoadMode). - // Implied mode contains all the fields we need the data for. - // In requestedMode there are the actually requested fields. - // We'll zero them out before returning packages to the user. - // This makes it easier for us to get the conditions where - // we need certain modes right. - requestedMode LoadMode -} - -type parseValue struct { - f *ast.File - err error - ready chan struct{} -} - -func newLoader(cfg *Config) *loader { - ld := &loader{ - parseCache: map[string]*parseValue{}, - } - if cfg != nil { - ld.Config = *cfg - // If the user has provided a logger, use it. - ld.Config.Logf = cfg.Logf - } - if ld.Config.Logf == nil { - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the user has not provided a logger, default to log.Printf. - if debug { - ld.Config.Logf = log.Printf - } else { - ld.Config.Logf = func(format string, args ...interface{}) {} - } - } - if ld.Config.Mode == 0 { - ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. - } - if ld.Config.Env == nil { - ld.Config.Env = os.Environ() - } - if ld.Context == nil { - ld.Context = context.Background() - } - if ld.Dir == "" { - if dir, err := os.Getwd(); err == nil { - ld.Dir = dir - } - } - - // Save the actually requested fields. We'll zero them out before returning packages to the user. - ld.requestedMode = ld.Mode - ld.Mode = impliedLoadMode(ld.Mode) - - if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - if ld.Fset == nil { - ld.Fset = token.NewFileSet() - } - - // ParseFile is required even in LoadTypes mode - // because we load source if export data is missing. - if ld.ParseFile == nil { - ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { - // We implicitly promise to keep doing ast.Object resolution. :( - const mode = parser.AllErrors | parser.ParseComments - return parser.ParseFile(fset, filename, src, mode) - } - } - } - - return ld -} - -// refine connects the supplied packages into a graph and then adds type -// and syntax information as requested by the LoadMode. -func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { - roots := response.Roots - rootMap := make(map[string]int, len(roots)) - for i, root := range roots { - rootMap[root] = i - } - ld.pkgs = make(map[string]*loaderPackage) - // first pass, fixup and build the map and roots - var initial = make([]*loaderPackage, len(roots)) - for _, pkg := range response.Packages { - rootIndex := -1 - if i, found := rootMap[pkg.ID]; found { - rootIndex = i - } - - // Overlays can invalidate export data. - // TODO(matloob): make this check fine-grained based on dependencies on overlaid files - exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" - // This package needs type information if the caller requested types and the package is - // either a root, or it's a non-root and the user requested dependencies ... - needtypes := (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) - // This package needs source if the call requested source (or types info, which implies source) - // and the package is either a root, or itas a non- root and the user requested dependencies... - needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || - // ... or if we need types and the exportData is invalid. We fall back to (incompletely) - // typechecking packages from source if they fail to compile. - (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" - lpkg := &loaderPackage{ - Package: pkg, - needtypes: needtypes, - needsrc: needsrc, - goVersion: response.GoVersion, - } - ld.pkgs[lpkg.ID] = lpkg - if rootIndex >= 0 { - initial[rootIndex] = lpkg - lpkg.initial = true - } - } - for i, root := range roots { - if initial[i] == nil { - return nil, fmt.Errorf("root package %v is missing", root) - } - } - - // Materialize the import graph if it is needed (NeedImports), - // or if we'll be using loadPackages (Need{Syntax|Types|TypesInfo}). - var leaves []*loaderPackage // packages with no unfinished successors - if ld.Mode&(NeedImports|NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - const ( - white = 0 // new - grey = 1 // in progress - black = 2 // complete - ) - - // visit traverses the import graph, depth-first, - // and materializes the graph as Packages.Imports. - // - // Valid imports are saved in the Packages.Import map. - // Invalid imports (cycles and missing nodes) are saved in the importErrors map. - // Thus, even in the presence of both kinds of errors, - // the Import graph remains a DAG. - // - // visit returns whether the package needs src or has a transitive - // dependency on a package that does. These are the only packages - // for which we load source code. - var stack []*loaderPackage - var visit func(from, lpkg *loaderPackage) bool - visit = func(from, lpkg *loaderPackage) bool { - if lpkg.color == grey { - panic("internal error: grey node") - } - if lpkg.color == white { - lpkg.color = grey - stack = append(stack, lpkg) // push - stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports - lpkg.Imports = make(map[string]*Package, len(stubs)) - for importPath, ipkg := range stubs { - var importErr error - imp := ld.pkgs[ipkg.ID] - if imp == nil { - // (includes package "C" when DisableCgo) - importErr = fmt.Errorf("missing package: %q", ipkg.ID) - } else if imp.color == grey { - importErr = fmt.Errorf("import cycle: %s", stack) - } - if importErr != nil { - if lpkg.importErrors == nil { - lpkg.importErrors = make(map[string]error) - } - lpkg.importErrors[importPath] = importErr - continue - } - - if visit(lpkg, imp) { - lpkg.needsrc = true - } - lpkg.Imports[importPath] = imp.Package - } - - // -- postorder -- - - // Complete type information is required for the - // immediate dependencies of each source package. - if lpkg.needsrc && ld.Mode&NeedTypes != 0 { - for _, ipkg := range lpkg.Imports { - ld.pkgs[ipkg.ID].needtypes = true - } - } - - // NeedTypeSizes causes TypeSizes to be set even - // on packages for which types aren't needed. - if ld.Mode&NeedTypesSizes != 0 { - lpkg.TypesSizes = ld.sizes - } - - // Add packages with no imports directly to the queue of leaves. - if len(lpkg.Imports) == 0 { - leaves = append(leaves, lpkg) - } - - stack = stack[:len(stack)-1] // pop - lpkg.color = black - } - - // Add edge from predecessor. - if from != nil { - from.unfinishedSuccs.Add(+1) // incref - lpkg.preds = append(lpkg.preds, from) - } - - return lpkg.needsrc - } - - // For each initial package, create its import DAG. - for _, lpkg := range initial { - visit(nil, lpkg) - } - - } else { - // !NeedImports: drop the stub (ID-only) import packages - // that we are not even going to try to resolve. - for _, lpkg := range initial { - lpkg.Imports = nil - } - } - - // Load type data and syntax if needed, starting at - // the initial packages (roots of the import DAG). - if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - - // We avoid using g.SetLimit to limit concurrency as - // it makes g.Go stop accepting work, which prevents - // workers from enqeuing, and thus finishing, and thus - // allowing the group to make progress: deadlock. - // - // Instead we use the ioLimit and cpuLimit semaphores. - g, _ := errgroup.WithContext(ld.Context) - - // enqueues adds a package to the type-checking queue. - // It must have no unfinished successors. - var enqueue func(*loaderPackage) - enqueue = func(lpkg *loaderPackage) { - g.Go(func() error { - // Parse and type-check. - ld.loadPackage(lpkg) - - // Notify each waiting predecessor, - // and enqueue it when it becomes a leaf. - for _, pred := range lpkg.preds { - if pred.unfinishedSuccs.Add(-1) == 0 { // decref - enqueue(pred) - } - } - - return nil - }) - } - - // Load leaves first, adding new packages - // to the queue as they become leaves. - for _, leaf := range leaves { - enqueue(leaf) - } - - if err := g.Wait(); err != nil { - return nil, err // cancelled - } - } - - // If the context is done, return its error and - // throw out [likely] incomplete packages. - if err := ld.Context.Err(); err != nil { - return nil, err - } - - result := make([]*Package, len(initial)) - for i, lpkg := range initial { - result[i] = lpkg.Package - } - for i := range ld.pkgs { - // Clear all unrequested fields, - // to catch programs that use more than they request. - if ld.requestedMode&NeedName == 0 { - ld.pkgs[i].Name = "" - ld.pkgs[i].PkgPath = "" - } - if ld.requestedMode&NeedFiles == 0 { - ld.pkgs[i].GoFiles = nil - ld.pkgs[i].OtherFiles = nil - ld.pkgs[i].IgnoredFiles = nil - } - if ld.requestedMode&NeedEmbedFiles == 0 { - ld.pkgs[i].EmbedFiles = nil - } - if ld.requestedMode&NeedEmbedPatterns == 0 { - ld.pkgs[i].EmbedPatterns = nil - } - if ld.requestedMode&NeedCompiledGoFiles == 0 { - ld.pkgs[i].CompiledGoFiles = nil - } - if ld.requestedMode&NeedImports == 0 { - ld.pkgs[i].Imports = nil - } - if ld.requestedMode&NeedExportFile == 0 { - ld.pkgs[i].ExportFile = "" - } - if ld.requestedMode&NeedTypes == 0 { - ld.pkgs[i].Types = nil - ld.pkgs[i].IllTyped = false - } - if ld.requestedMode&NeedSyntax == 0 { - ld.pkgs[i].Syntax = nil - } - if ld.requestedMode&(NeedSyntax|NeedTypes|NeedTypesInfo) == 0 { - ld.pkgs[i].Fset = nil - } - if ld.requestedMode&NeedTypesInfo == 0 { - ld.pkgs[i].TypesInfo = nil - } - if ld.requestedMode&NeedTypesSizes == 0 { - ld.pkgs[i].TypesSizes = nil - } - if ld.requestedMode&NeedModule == 0 { - ld.pkgs[i].Module = nil - } - } - - return result, nil -} - -// loadPackage loads/parses/typechecks the specified package. -// It must be called only once per Package, -// after immediate dependencies are loaded. -// Precondition: ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0. -func (ld *loader) loadPackage(lpkg *loaderPackage) { - if lpkg.PkgPath == "unsafe" { - // Fill in the blanks to avoid surprises. - lpkg.Types = types.Unsafe - lpkg.Fset = ld.Fset - lpkg.Syntax = []*ast.File{} - lpkg.TypesInfo = new(types.Info) - lpkg.TypesSizes = ld.sizes - return - } - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) - lpkg.Fset = ld.Fset - - // Start shutting down if the context is done and do not load - // source or export data files. - // Packages that import this one will have ld.Context.Err() != nil. - // ld.Context.Err() will be returned later by refine. - if ld.Context.Err() != nil { - return - } - - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - // (Hence this return is after the Types assignment.) - // The Diamond test exercises this case. - if !lpkg.needtypes && !lpkg.needsrc { - return - } - - // TODO(adonovan): this condition looks wrong: - // I think it should be lpkg.needtypes && !lpg.needsrc, - // so that NeedSyntax without NeedTypes can be satisfied by export data. - if !lpkg.needsrc { - if err := ld.loadFromExportData(lpkg); err != nil { - lpkg.Errors = append(lpkg.Errors, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, // e.g. can't find/open/parse export data - }) - } - return // not a source package, don't get syntax trees - } - - appendError := func(err error) { - // Convert various error types into the one true Error. - var errs []Error - switch err := err.(type) { - case Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: ParseError, - }) - } - - case types.Error: - // from type checker - lpkg.TypeErrors = append(lpkg.TypeErrors, err) - errs = append(errs, Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, - }) - - // If you see this error message, please file a bug. - log.Printf("internal error: error %q (%T) without position", err, err) - } - - lpkg.Errors = append(lpkg.Errors, errs...) - } - - // If the go command on the PATH is newer than the runtime, - // then the go/{scanner,ast,parser,types} packages from the - // standard library may be unable to process the files - // selected by go list. - // - // There is currently no way to downgrade the effective - // version of the go command (see issue 52078), so we proceed - // with the newer go command but, in case of parse or type - // errors, we emit an additional diagnostic. - // - // See: - // - golang.org/issue/52078 (flag to set release tags) - // - golang.org/issue/50825 (gopls legacy version support) - // - golang.org/issue/55883 (go/packages confusing error) - // - // Should we assert a hard minimum of (currently) go1.16 here? - var runtimeVersion int - if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { - defer func() { - if len(lpkg.Errors) > 0 { - appendError(Error{ - Pos: "-", - Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), - Kind: UnknownError, - }) - } - }() - } - - if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { - // The config requested loading sources and types, but sources are missing. - // Add an error to the package and fall back to loading from export data. - appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) - _ = ld.loadFromExportData(lpkg) // ignore any secondary errors - - return // can't get syntax trees for this package - } - - files, errs := ld.parseFiles(lpkg.CompiledGoFiles) - for _, err := range errs { - appendError(err) - } - - lpkg.Syntax = files - if ld.Config.Mode&(NeedTypes|NeedTypesInfo) == 0 { - return - } - - // Start shutting down if the context is done and do not type check. - // Packages that import this one will have ld.Context.Err() != nil. - // ld.Context.Err() will be returned later by refine. - if ld.Context.Err() != nil { - return - } - - // Populate TypesInfo only if needed, as it - // causes the type checker to work much harder. - if ld.Config.Mode&NeedTypesInfo != 0 { - lpkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Instances: make(map[*ast.Ident]types.Instance), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - FileVersions: make(map[*ast.File]string), - } - } - lpkg.TypesSizes = ld.sizes - - importer := importerFunc(func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - - // The imports map is keyed by import path. - ipkg := lpkg.Imports[path] - if ipkg == nil { - if err := lpkg.importErrors[path]; err != nil { - return nil, err - } - // There was skew between the metadata and the - // import declarations, likely due to an edit - // race, or because the ParseFile feature was - // used to supply alternative file contents. - return nil, fmt.Errorf("no metadata for %s", path) - } - - if ipkg.Types != nil && ipkg.Types.Complete() { - return ipkg.Types, nil - } - log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) - panic("unreachable") - }) - - // type-check - tc := &types.Config{ - Importer: importer, - - // Type-check bodies of functions only in initial packages. - // Example: for import graph A->B->C and initial packages {A,C}, - // we can ignore function bodies in B. - IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, - - Error: appendError, - Sizes: ld.sizes, // may be nil - } - if lpkg.Module != nil && lpkg.Module.GoVersion != "" { - tc.GoVersion = "go" + lpkg.Module.GoVersion - } - if (ld.Mode & typecheckCgo) != 0 { - if !typesinternal.SetUsesCgo(tc) { - appendError(Error{ - Msg: "typecheckCgo requires Go 1.15+", - Kind: ListError, - }) - return - } - } - - // Type-checking is CPU intensive. - cpuLimit <- unit{} // acquire a token - defer func() { <-cpuLimit }() // release a token - - typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) - lpkg.importErrors = nil // no longer needed - - // In go/types go1.21 and go1.22, Checker.Files failed fast with a - // a "too new" error, without calling tc.Error and without - // proceeding to type-check the package (#66525). - // We rely on the runtimeVersion error to give the suggested remedy. - if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 { - if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") { - appendError(types.Error{ - Fset: ld.Fset, - Pos: lpkg.Syntax[0].Package, - Msg: msg, - }) - } - } - - // If !Cgo, the type-checker uses FakeImportC mode, so - // it doesn't invoke the importer for import "C", - // nor report an error for the import, - // or for any undefined C.f reference. - // We must detect this explicitly and correctly - // mark the package as IllTyped (by reporting an error). - // TODO(adonovan): if these errors are annoying, - // we could just set IllTyped quietly. - if tc.FakeImportC { - outer: - for _, f := range lpkg.Syntax { - for _, imp := range f.Imports { - if imp.Path.Value == `"C"` { - err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} - appendError(err) - break outer - } - } - } - } - - // If types.Checker.Files had an error that was unreported, - // make sure to report the unknown error so the package is illTyped. - if typErr != nil && len(lpkg.Errors) == 0 { - appendError(typErr) - } - - // Record accumulated errors. - illTyped := len(lpkg.Errors) > 0 - if !illTyped { - for _, imp := range lpkg.Imports { - if imp.IllTyped { - illTyped = true - break - } - } - } - lpkg.IllTyped = illTyped -} - -// An importFunc is an implementation of the single-method -// types.Importer interface based on a function value. -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } - -// We use a counting semaphore to limit -// the number of parallel I/O calls or CPU threads per process. -var ( - ioLimit = make(chan unit, 20) - cpuLimit = make(chan unit, runtime.GOMAXPROCS(0)) -) - -func (ld *loader) parseFile(filename string) (*ast.File, error) { - ld.parseCacheMu.Lock() - v, ok := ld.parseCache[filename] - if ok { - // cache hit - ld.parseCacheMu.Unlock() - <-v.ready - } else { - // cache miss - v = &parseValue{ready: make(chan struct{})} - ld.parseCache[filename] = v - ld.parseCacheMu.Unlock() - - var src []byte - for f, contents := range ld.Config.Overlay { - // TODO(adonovan): Inefficient for large overlays. - // Do an exact name-based map lookup - // (for nonexistent files) followed by a - // FileID-based map lookup (for existing ones). - if sameFile(f, filename) { - src = contents - break - } - } - var err error - if src == nil { - ioLimit <- unit{} // acquire a token - src, err = os.ReadFile(filename) - <-ioLimit // release a token - } - if err != nil { - v.err = err - } else { - // Parsing is CPU intensive. - cpuLimit <- unit{} // acquire a token - v.f, v.err = ld.ParseFile(ld.Fset, filename, src) - <-cpuLimit // release a token - } - - close(v.ready) - } - return v.f, v.err -} - -// parseFiles reads and parses the Go source files and returns the ASTs -// of the ones that could be at least partially parsed, along with a -// list of I/O and parse errors encountered. -// -// Because files are scanned in parallel, the token.Pos -// positions of the resulting ast.Files are not ordered. -func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { - var ( - n = len(filenames) - parsed = make([]*ast.File, n) - errors = make([]error, n) - ) - var g errgroup.Group - for i, filename := range filenames { - // This creates goroutines unnecessarily in the - // cache-hit case, but that case is uncommon. - g.Go(func() error { - parsed[i], errors[i] = ld.parseFile(filename) - return nil - }) - } - g.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// sameFile returns true if x and y have the same basename and denote -// the same file. -func sameFile(x, y string) bool { - if x == y { - // It could be the case that y doesn't exist. - // For instance, it may be an overlay file that - // hasn't been written to disk. To handle that case - // let x == y through. (We added the exact absolute path - // string to the CompiledGoFiles list, so the unwritten - // overlay case implies x==y.) - return true - } - if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) - if xi, err := os.Stat(x); err == nil { - if yi, err := os.Stat(y); err == nil { - return os.SameFile(xi, yi) - } - } - } - return false -} - -// loadFromExportData ensures that type information is present for the specified -// package, loading it from an export data file on the first request. -// On success it sets lpkg.Types to a new Package. -func (ld *loader) loadFromExportData(lpkg *loaderPackage) error { - if lpkg.PkgPath == "" { - log.Fatalf("internal error: Package %s has no PkgPath", lpkg) - } - - // Because gcexportdata.Read has the potential to create or - // modify the types.Package for each node in the transitive - // closure of dependencies of lpkg, all exportdata operations - // must be sequential. (Finer-grained locking would require - // changes to the gcexportdata API.) - // - // The exportMu lock guards the lpkg.Types field and the - // types.Package it points to, for each loaderPackage in the graph. - // - // Not all accesses to Package.Pkg need to be protected by exportMu: - // graph ordering ensures that direct dependencies of source - // packages are fully loaded before the importer reads their Pkg field. - ld.exportMu.Lock() - defer ld.exportMu.Unlock() - - if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { - return nil // cache hit - } - - lpkg.IllTyped = true // fail safe - - if lpkg.ExportFile == "" { - // Errors while building export data will have been printed to stderr. - return fmt.Errorf("no export data file") - } - f, err := os.Open(lpkg.ExportFile) - if err != nil { - return err - } - defer f.Close() - - // Read gc export data. - // - // We don't currently support gccgo export data because all - // underlying workspaces use the gc toolchain. (Even build - // systems that support gccgo don't use it for workspace - // queries.) - r, err := gcexportdata.NewReader(f) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - - // Build the view. - // - // The gcexportdata machinery has no concept of package ID. - // It identifies packages by their PkgPath, which although not - // globally unique is unique within the scope of one invocation - // of the linker, type-checker, or gcexportdata. - // - // So, we must build a PkgPath-keyed view of the global - // (conceptually ID-keyed) cache of packages and pass it to - // gcexportdata. The view must contain every existing - // package that might possibly be mentioned by the - // current package---its transitive closure. - // - // In loadPackage, we unconditionally create a types.Package for - // each dependency so that export data loading does not - // create new ones. - // - // TODO(adonovan): it would be simpler and more efficient - // if the export data machinery invoked a callback to - // get-or-create a package instead of a map. - // - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*loaderPackage]bool) // all visited packages - var visit func(pkgs map[string]*Package) - visit = func(pkgs map[string]*Package) { - for _, p := range pkgs { - lpkg := ld.pkgs[p.ID] - if !seen[lpkg] { - seen[lpkg] = true - view[lpkg.PkgPath] = lpkg.Types - visit(lpkg.Imports) - } - } - } - visit(lpkg.Imports) - - viewLen := len(view) + 1 // adding the self package - // Parse the export data. - // (May modify incomplete packages in view but not create new ones.) - tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - if _, ok := view["go.shape"]; ok { - // Account for the pseudopackage "go.shape" that gets - // created by generic code. - viewLen++ - } - if viewLen != len(view) { - log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) - } - - lpkg.Types = tpkg - lpkg.IllTyped = false - return nil -} - -// impliedLoadMode returns loadMode with its dependencies. -func impliedLoadMode(loadMode LoadMode) LoadMode { - if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { - // All these things require knowing the import graph. - loadMode |= NeedImports - } - if loadMode&NeedTypes != 0 { - // Types require the GoVersion from Module. - loadMode |= NeedModule - } - - return loadMode -} - -func usesExportData(cfg *Config) bool { - return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 -} - -type unit struct{} diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go deleted file mode 100644 index df14ffd..0000000 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ /dev/null @@ -1,68 +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. - -package packages - -import ( - "fmt" - "os" - "sort" -) - -// Visit visits all the packages in the import graph whose roots are -// pkgs, calling the optional pre function the first time each package -// is encountered (preorder), and the optional post function after a -// package's dependencies have been visited (postorder). -// The boolean result of pre(pkg) determines whether -// the imports of package pkg are visited. -func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { - seen := make(map[*Package]bool) - var visit func(*Package) - visit = func(pkg *Package) { - if !seen[pkg] { - seen[pkg] = true - - if pre == nil || pre(pkg) { - paths := make([]string, 0, len(pkg.Imports)) - for path := range pkg.Imports { - paths = append(paths, path) - } - sort.Strings(paths) // Imports is a map, this makes visit stable - for _, path := range paths { - visit(pkg.Imports[path]) - } - } - - if post != nil { - post(pkg) - } - } - } - for _, pkg := range pkgs { - visit(pkg) - } -} - -// PrintErrors prints to os.Stderr the accumulated errors of all -// packages in the import graph rooted at pkgs, dependencies first. -// PrintErrors returns the number of errors printed. -func PrintErrors(pkgs []*Package) int { - var n int - errModules := make(map[*Module]bool) - Visit(pkgs, nil, func(pkg *Package) { - for _, err := range pkg.Errors { - fmt.Fprintln(os.Stderr, err) - n++ - } - - // Print pkg.Module.Error once if present. - mod := pkg.Module - if mod != nil && mod.Error != nil && !errModules[mod] { - errModules[mod] = true - fmt.Fprintln(os.Stderr, mod.Error.Err) - n++ - } - }) - return n -} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go deleted file mode 100644 index 16ed3c1..0000000 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ /dev/null @@ -1,817 +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. - -// Package objectpath defines a naming scheme for types.Objects -// (that is, named entities in Go programs) relative to their enclosing -// package. -// -// Type-checker objects are canonical, so they are usually identified by -// their address in memory (a pointer), but a pointer has meaning only -// within one address space. By contrast, objectpath names allow the -// identity of an object to be sent from one program to another, -// establishing a correspondence between types.Object variables that are -// distinct but logically equivalent. -// -// A single object may have multiple paths. In this example, -// -// type A struct{ X int } -// type B A -// -// the field X has two paths due to its membership of both A and B. -// The For(obj) function always returns one of these paths, arbitrarily -// but consistently. -package objectpath - -import ( - "fmt" - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/internal/aliases" - "golang.org/x/tools/internal/typesinternal" -) - -// TODO(adonovan): think about generic aliases. - -// A Path is an opaque name that identifies a types.Object -// relative to its package. Conceptually, the name consists of a -// sequence of destructuring operations applied to the package scope -// to obtain the original object. -// The name does not include the package itself. -type Path string - -// Encoding -// -// An object path is a textual and (with training) human-readable encoding -// of a sequence of destructuring operators, starting from a types.Package. -// The sequences represent a path through the package/object/type graph. -// We classify these operators by their type: -// -// PO package->object Package.Scope.Lookup -// OT object->type Object.Type -// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa] -// TO type->object Type.{At,Field,Method,Obj} [AFMO] -// -// All valid paths start with a package and end at an object -// and thus may be defined by the regular language: -// -// objectpath = PO (OT TT* TO)* -// -// The concrete encoding follows directly: -// - The only PO operator is Package.Scope.Lookup, which requires an identifier. -// - The only OT operator is Object.Type, -// which we encode as '.' because dot cannot appear in an identifier. -// - The TT operators are encoded as [EKPRUTrCa]; -// two of these ({,Recv}TypeParams) require an integer operand, -// which is encoded as a string of decimal digits. -// - The TO operators are encoded as [AFMO]; -// three of these (At,Field,Method) require an integer operand, -// which is encoded as a string of decimal digits. -// These indices are stable across different representations -// of the same package, even source and export data. -// The indices used are implementation specific and may not correspond to -// the argument to the go/types function. -// -// In the example below, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// field X has the path "T.UM0.RA1.F0", -// representing the following sequence of operations: -// -// p.Lookup("T") T -// .Type().Underlying().Method(0). f -// .Type().Results().At(1) b -// .Type().Field(0) X -// -// The encoding is not maximally compact---every R or P is -// followed by an A, for example---but this simplifies the -// encoder and decoder. -const ( - // object->type operators - opType = '.' // .Type() (Object) - - // type->type operators - opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) - opKey = 'K' // .Key() (Map) - opParams = 'P' // .Params() (Signature) - opResults = 'R' // .Results() (Signature) - opUnderlying = 'U' // .Underlying() (Named) - opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) - opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature) - opConstraint = 'C' // .Constraint() (TypeParam) - opRhs = 'a' // .Rhs() (Alias) - - // type->object operators - opAt = 'A' // .At(i) (Tuple) - opField = 'F' // .Field(i) (Struct) - opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) - opObj = 'O' // .Obj() (Named, TypeParam) -) - -// For is equivalent to new(Encoder).For(obj). -// -// It may be more efficient to reuse a single Encoder across several calls. -func For(obj types.Object) (Path, error) { - return new(Encoder).For(obj) -} - -// An Encoder amortizes the cost of encoding the paths of multiple objects. -// The zero value of an Encoder is ready to use. -type Encoder struct { - scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects -} - -// For returns the path to an object relative to its package, -// or an error if the object is not accessible from the package's Scope. -// -// The For function guarantees to return a path only for the following objects: -// - package-level types -// - exported package-level non-types -// - methods -// - parameter and result variables -// - struct fields -// These objects are sufficient to define the API of their package. -// The objects described by a package's export data are drawn from this set. -// -// The set of objects accessible from a package's Scope depends on -// whether the package was produced by type-checking syntax, or -// reading export data; the latter may have a smaller Scope since -// export data trims objects that are not reachable from an exported -// declaration. For example, the For function will return a path for -// an exported method of an unexported type that is not reachable -// from any public declaration; this path will cause the Object -// function to fail if called on a package loaded from export data. -// TODO(adonovan): is this a bug or feature? Should this package -// compute accessibility in the same way? -// -// For does not return a path for predeclared names, imported package -// names, local names, and unexported package-level names (except -// types). -// -// Example: given this definition, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// For(X) would return a path that denotes the following sequence of operations: -// -// p.Scope().Lookup("T") (TypeName T) -// .Type().Underlying().Method(0). (method Func f) -// .Type().Results().At(1) (field Var b) -// .Type().Field(0) (field Var X) -// -// where p is the package (*types.Package) to which X belongs. -func (enc *Encoder) For(obj types.Object) (Path, error) { - pkg := obj.Pkg() - - // This table lists the cases of interest. - // - // Object Action - // ------ ------ - // nil reject - // builtin reject - // pkgname reject - // label reject - // var - // package-level accept - // func param/result accept - // local reject - // struct field accept - // const - // package-level accept - // local reject - // func - // package-level accept - // init functions reject - // concrete method accept - // interface method accept - // type - // package-level accept - // local reject - // - // The only accessible package-level objects are members of pkg itself. - // - // The cases are handled in four steps: - // - // 1. reject nil and builtin - // 2. accept package-level objects - // 3. reject obviously invalid objects - // 4. search the API for the path to the param/result/field/method. - - // 1. reference to nil or builtin? - if pkg == nil { - return "", fmt.Errorf("predeclared %s has no path", obj) - } - scope := pkg.Scope() - - // 2. package-level object? - if scope.Lookup(obj.Name()) == obj { - // Only exported objects (and non-exported types) have a path. - // Non-exported types may be referenced by other objects. - if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { - return "", fmt.Errorf("no path for non-exported %v", obj) - } - return Path(obj.Name()), nil - } - - // 3. Not a package-level object. - // Reject obviously non-viable cases. - switch obj := obj.(type) { - case *types.TypeName: - if _, ok := types.Unalias(obj.Type()).(*types.TypeParam); !ok { - // With the exception of type parameters, only package-level type names - // have a path. - return "", fmt.Errorf("no path for %v", obj) - } - case *types.Const, // Only package-level constants have a path. - *types.Label, // Labels are function-local. - *types.PkgName: // PkgNames are file-local. - return "", fmt.Errorf("no path for %v", obj) - - case *types.Var: - // Could be: - // - a field (obj.IsField()) - // - a func parameter or result - // - a local var. - // Sadly there is no way to distinguish - // a param/result from a local - // so we must proceed to the find. - - case *types.Func: - // A func, if not package-level, must be a method. - if recv := obj.Type().(*types.Signature).Recv(); recv == nil { - return "", fmt.Errorf("func is not a method: %v", obj) - } - - if path, ok := enc.concreteMethod(obj); ok { - // Fast path for concrete methods that avoids looping over scope. - return path, nil - } - - default: - panic(obj) - } - - // 4. Search the API for the path to the var (field/param/result) or method. - - // First inspect package-level named types. - // In the presence of path aliases, these give - // the best paths because non-types may - // refer to types, but not the reverse. - empty := make([]byte, 0, 48) // initial space - objs := enc.scopeObjects(scope) - for _, o := range objs { - tname, ok := o.(*types.TypeName) - if !ok { - continue // handle non-types in second pass - } - - path := append(empty, o.Name()...) - path = append(path, opType) - - T := o.Type() - if alias, ok := T.(*types.Alias); ok { - if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam); r != nil { - return Path(r), nil - } - if r := find(obj, aliases.Rhs(alias), append(path, opRhs)); r != nil { - return Path(r), nil - } - - } else if tname.IsAlias() { - // legacy alias - if r := find(obj, T, path); r != nil { - return Path(r), nil - } - - } else if named, ok := T.(*types.Named); ok { - // defined (named) type - if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam); r != nil { - return Path(r), nil - } - if r := find(obj, named.Underlying(), append(path, opUnderlying)); r != nil { - return Path(r), nil - } - } - } - - // Then inspect everything else: - // non-types, and declared methods of defined types. - for _, o := range objs { - path := append(empty, o.Name()...) - if _, ok := o.(*types.TypeName); !ok { - if o.Exported() { - // exported non-type (const, var, func) - if r := find(obj, o.Type(), append(path, opType)); r != nil { - return Path(r), nil - } - } - continue - } - - // Inspect declared methods of defined types. - if T, ok := types.Unalias(o.Type()).(*types.Named); ok { - path = append(path, opType) - // The method index here is always with respect - // to the underlying go/types data structures, - // which ultimately derives from source order - // and must be preserved by export data. - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType)); r != nil { - return Path(r), nil - } - } - } - } - - return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) -} - -func appendOpArg(path []byte, op byte, arg int) []byte { - path = append(path, op) - path = strconv.AppendInt(path, int64(arg), 10) - return path -} - -// concreteMethod returns the path for meth, which must have a non-nil receiver. -// The second return value indicates success and may be false if the method is -// an interface method or if it is an instantiated method. -// -// This function is just an optimization that avoids the general scope walking -// approach. You are expected to fall back to the general approach if this -// function fails. -func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { - // Concrete methods can only be declared on package-scoped named types. For - // that reason we can skip the expensive walk over the package scope: the - // path will always be package -> named type -> method. We can trivially get - // the type name from the receiver, and only have to look over the type's - // methods to find the method index. - // - // Methods on generic types require special consideration, however. Consider - // the following package: - // - // L1: type S[T any] struct{} - // L2: func (recv S[A]) Foo() { recv.Bar() } - // L3: func (recv S[B]) Bar() { } - // L4: type Alias = S[int] - // L5: func _[T any]() { var s S[int]; s.Foo() } - // - // The receivers of methods on generic types are instantiations. L2 and L3 - // instantiate S with the type-parameters A and B, which are scoped to the - // respective methods. L4 and L5 each instantiate S with int. Each of these - // instantiations has its own method set, full of methods (and thus objects) - // with receivers whose types are the respective instantiations. In other - // words, we have - // - // S[A].Foo, S[A].Bar - // S[B].Foo, S[B].Bar - // S[int].Foo, S[int].Bar - // - // We may thus be trying to produce object paths for any of these objects. - // - // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo - // and S.Bar, which are the paths that this function naturally produces. - // - // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that - // don't correspond to the origin methods. For S[int], this is significant. - // The most precise object path for S[int].Foo, for example, is Alias.Foo, - // not S.Foo. Our function, however, would produce S.Foo, which would - // resolve to a different object. - // - // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are - // still the correct paths, since only the origin methods have meaningful - // paths. But this is likely only true for trivial cases and has edge cases. - // Since this function is only an optimization, we err on the side of giving - // up, deferring to the slower but definitely correct algorithm. Most users - // of objectpath will only be giving us origin methods, anyway, as referring - // to instantiated methods is usually not useful. - - if meth.Origin() != meth { - return "", false - } - - _, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv()) - if named == nil { - return "", false - } - - if types.IsInterface(named) { - // Named interfaces don't have to be package-scoped - // - // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface - // methods, too, I think. - return "", false - } - - // Preallocate space for the name, opType, opMethod, and some digits. - name := named.Obj().Name() - path := make([]byte, 0, len(name)+8) - path = append(path, name...) - path = append(path, opType) - - // Method indices are w.r.t. the go/types data structures, - // ultimately deriving from source order, - // which is preserved by export data. - for i := 0; i < named.NumMethods(); i++ { - if named.Method(i) == meth { - path = appendOpArg(path, opMethod, i) - return Path(path), true - } - } - - // Due to golang/go#59944, go/types fails to associate the receiver with - // certain methods on cgo types. - // - // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go - // versions gopls supports. - return "", false - // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named))) -} - -// find finds obj within type T, returning the path to it, or nil if not found. -// -// The seen map is used to short circuit cycles through type parameters. If -// nil, it will be allocated as necessary. -// -// The seenMethods map is used internally to short circuit cycles through -// interface methods, such as occur in the following example: -// -// type I interface { f() interface{I} } -// -// See golang/go#68046 for details. -func find(obj types.Object, T types.Type, path []byte) []byte { - return (&finder{obj: obj}).find(T, path) -} - -// finder closes over search state for a call to find. -type finder struct { - obj types.Object // the sought object - seenTParamNames map[*types.TypeName]bool // for cycle breaking through type parameters - seenMethods map[*types.Func]bool // for cycle breaking through recursive interfaces -} - -func (f *finder) find(T types.Type, path []byte) []byte { - switch T := T.(type) { - case *types.Alias: - return f.find(types.Unalias(T), path) - case *types.Basic, *types.Named: - // Named types belonging to pkg were handled already, - // so T must belong to another package. No path. - return nil - case *types.Pointer: - return f.find(T.Elem(), append(path, opElem)) - case *types.Slice: - return f.find(T.Elem(), append(path, opElem)) - case *types.Array: - return f.find(T.Elem(), append(path, opElem)) - case *types.Chan: - return f.find(T.Elem(), append(path, opElem)) - case *types.Map: - if r := f.find(T.Key(), append(path, opKey)); r != nil { - return r - } - return f.find(T.Elem(), append(path, opElem)) - case *types.Signature: - if r := f.findTypeParam(T.RecvTypeParams(), path, opRecvTypeParam); r != nil { - return r - } - if r := f.findTypeParam(T.TypeParams(), path, opTypeParam); r != nil { - return r - } - if r := f.find(T.Params(), append(path, opParams)); r != nil { - return r - } - return f.find(T.Results(), append(path, opResults)) - case *types.Struct: - for i := 0; i < T.NumFields(); i++ { - fld := T.Field(i) - path2 := appendOpArg(path, opField, i) - if fld == f.obj { - return path2 // found field var - } - if r := f.find(fld.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Tuple: - for i := 0; i < T.Len(); i++ { - v := T.At(i) - path2 := appendOpArg(path, opAt, i) - if v == f.obj { - return path2 // found param/result var - } - if r := f.find(v.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Interface: - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - if f.seenMethods[m] { - return nil - } - path2 := appendOpArg(path, opMethod, i) - if m == f.obj { - return path2 // found interface method - } - if f.seenMethods == nil { - f.seenMethods = make(map[*types.Func]bool) - } - f.seenMethods[m] = true - if r := f.find(m.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.TypeParam: - name := T.Obj() - if f.seenTParamNames[name] { - return nil - } - if name == f.obj { - return append(path, opObj) - } - if f.seenTParamNames == nil { - f.seenTParamNames = make(map[*types.TypeName]bool) - } - f.seenTParamNames[name] = true - if r := f.find(T.Constraint(), append(path, opConstraint)); r != nil { - return r - } - return nil - } - panic(T) -} - -func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte) []byte { - return (&finder{obj: obj}).findTypeParam(list, path, op) -} - -func (f *finder) findTypeParam(list *types.TypeParamList, path []byte, op byte) []byte { - for i := 0; i < list.Len(); i++ { - tparam := list.At(i) - path2 := appendOpArg(path, op, i) - if r := f.find(tparam, path2); r != nil { - return r - } - } - return nil -} - -// Object returns the object denoted by path p within the package pkg. -func Object(pkg *types.Package, p Path) (types.Object, error) { - pathstr := string(p) - if pathstr == "" { - return nil, fmt.Errorf("empty path") - } - - var pkgobj, suffix string - if dot := strings.IndexByte(pathstr, opType); dot < 0 { - pkgobj = pathstr - } else { - pkgobj = pathstr[:dot] - suffix = pathstr[dot:] // suffix starts with "." - } - - obj := pkg.Scope().Lookup(pkgobj) - if obj == nil { - return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) - } - - // abstraction of *types.{Pointer,Slice,Array,Chan,Map} - type hasElem interface { - Elem() types.Type - } - // abstraction of *types.{Named,Signature} - type hasTypeParams interface { - TypeParams() *types.TypeParamList - } - // abstraction of *types.{Named,TypeParam} - type hasObj interface { - Obj() *types.TypeName - } - - // The loop state is the pair (t, obj), - // exactly one of which is non-nil, initially obj. - // All suffixes start with '.' (the only object->type operation), - // followed by optional type->type operations, - // then a type->object operation. - // The cycle then repeats. - var t types.Type - for suffix != "" { - code := suffix[0] - suffix = suffix[1:] - - // Codes [AFMTr] have an integer operand. - var index int - switch code { - case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: - rest := strings.TrimLeft(suffix, "0123456789") - numerals := suffix[:len(suffix)-len(rest)] - suffix = rest - i, err := strconv.Atoi(numerals) - if err != nil { - return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) - } - index = int(i) - case opObj: - // no operand - default: - // The suffix must end with a type->object operation. - if suffix == "" { - return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) - } - } - - if code == opType { - if t != nil { - return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) - } - t = obj.Type() - obj = nil - continue - } - - if t == nil { - return nil, fmt.Errorf("invalid path: code %q in object context", code) - } - - // Inv: t != nil, obj == nil - - t = types.Unalias(t) - switch code { - case opElem: - hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) - } - t = hasElem.Elem() - - case opKey: - mapType, ok := t.(*types.Map) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) - } - t = mapType.Key() - - case opParams: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Params() - - case opResults: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Results() - - case opUnderlying: - named, ok := t.(*types.Named) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t) - } - t = named.Underlying() - - case opRhs: - if alias, ok := t.(*types.Alias); ok { - t = aliases.Rhs(alias) - } else if false && aliases.Enabled() { - // The Enabled check is too expensive, so for now we - // simply assume that aliases are not enabled. - // TODO(adonovan): replace with "if true {" when go1.24 is assured. - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) - } - - case opTypeParam: - hasTypeParams, ok := t.(hasTypeParams) // Named, Signature - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t) - } - tparams := hasTypeParams.TypeParams() - if n := tparams.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - t = tparams.At(index) - - case opRecvTypeParam: - sig, ok := t.(*types.Signature) // Signature - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - rtparams := sig.RecvTypeParams() - if n := rtparams.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - t = rtparams.At(index) - - case opConstraint: - tparam, ok := t.(*types.TypeParam) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) - } - t = tparam.Constraint() - - case opAt: - tuple, ok := t.(*types.Tuple) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t) - } - if n := tuple.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - obj = tuple.At(index) - t = nil - - case opField: - structType, ok := t.(*types.Struct) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) - } - if n := structType.NumFields(); index >= n { - return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) - } - obj = structType.Field(index) - t = nil - - case opMethod: - switch t := t.(type) { - case *types.Interface: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) // Id-ordered - - case *types.Named: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) - - default: - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) - } - t = nil - - case opObj: - hasObj, ok := t.(hasObj) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t) - } - obj = hasObj.Obj() - t = nil - - default: - return nil, fmt.Errorf("invalid path: unknown code %q", code) - } - } - - if obj == nil { - panic(p) // path does not end in an object-valued operator - } - - if obj.Pkg() != pkg { - return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) - } - - return obj, nil // success -} - -// scopeObjects is a memoization of scope objects. -// Callers must not modify the result. -func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object { - m := enc.scopeMemo - if m == nil { - m = make(map[*types.Scope][]types.Object) - enc.scopeMemo = m - } - objs, ok := m[scope] - if !ok { - names := scope.Names() // allocates and sorts - objs = make([]types.Object, len(names)) - for i, name := range names { - objs[i] = scope.Lookup(name) - } - m[scope] = objs - } - return objs -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go deleted file mode 100644 index 7543803..0000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,68 +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. - -package typeutil - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/internal/typeparams" -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -// -// Functions and methods may potentially have type parameters. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - fun := ast.Unparen(call.Fun) - - // Look through type instantiation if necessary. - isInstance := false - switch fun.(type) { - case *ast.IndexExpr, *ast.IndexListExpr: - // When extracting the callee from an *IndexExpr, we need to check that - // it is a *types.Func and not a *types.Var. - // Example: Don't match a slice m within the expression `m[0]()`. - isInstance = true - fun, _, _, _ = typeparams.UnpackIndexExpr(fun) - } - - var obj types.Object - switch fun := fun.(type) { - case *ast.Ident: - obj = info.Uses[fun] // type, var, builtin, or declared func - case *ast.SelectorExpr: - if sel, ok := info.Selections[fun]; ok { - obj = sel.Obj() // method or field - } else { - obj = info.Uses[fun.Sel] // qualified identifier? - } - } - if _, ok := obj.(*types.TypeName); ok { - return nil // T(x) is a conversion, not a call - } - // A Func is required to match instantiations. - if _, ok := obj.(*types.Func); isInstance && !ok { - return nil // Was not a Func. - } - return obj -} - -// StaticCallee returns the target (function or method) of a static function -// call, if any. It returns nil for calls to builtins. -// -// Note: for calls of instantiated functions and methods, StaticCallee returns -// the corresponding generic function or method on the generic type. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) { - return f - } - return nil -} - -func interfaceMethod(f *types.Func) bool { - recv := f.Type().(*types.Signature).Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go deleted file mode 100644 index b81ce0c..0000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,30 +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 typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go deleted file mode 100644 index 4326114..0000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ /dev/null @@ -1,470 +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 typeutil defines various utilities for types, such as [Map], -// a hash table that maps [types.Type] to any value. -package typeutil - -import ( - "bytes" - "fmt" - "go/types" - "hash/maphash" - "unsafe" - - "golang.org/x/tools/internal/typeparams" -) - -// Map is a hash-table-based mapping from types (types.Type) to -// arbitrary values. The concrete types that implement -// the Type interface are pointers. Since they are not canonicalized, -// == cannot be used to check for equivalence, and thus we cannot -// simply use a Go map. -// -// Just as with map[K]V, a nil *Map is a valid empty map. -// -// Read-only map operations ([Map.At], [Map.Len], and so on) may -// safely be called concurrently. -// -// TODO(adonovan): deprecate in favor of https://go.dev/issues/69420 -// and 69559, if the latter proposals for a generic hash-map type and -// a types.Hash function are accepted. -type Map struct { - table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused - length int // number of map entries -} - -// entry is an entry (key/value association) in a hash bucket. -type entry struct { - key types.Type - value any -} - -// SetHasher has no effect. -// -// It is a relic of an optimization that is no longer profitable. Do -// not use [Hasher], [MakeHasher], or [SetHasher] in new code. -func (m *Map) SetHasher(Hasher) {} - -// Delete removes the entry with the given key, if any. -// It returns true if the entry was found. -func (m *Map) Delete(key types.Type) bool { - if m != nil && m.table != nil { - hash := hash(key) - bucket := m.table[hash] - for i, e := range bucket { - if e.key != nil && types.Identical(key, e.key) { - // We can't compact the bucket as it - // would disturb iterators. - bucket[i] = entry{} - m.length-- - return true - } - } - } - return false -} - -// At returns the map entry for the given key. -// The result is nil if the entry is not present. -func (m *Map) At(key types.Type) any { - if m != nil && m.table != nil { - for _, e := range m.table[hash(key)] { - if e.key != nil && types.Identical(key, e.key) { - return e.value - } - } - } - return nil -} - -// Set sets the map entry for key to val, -// and returns the previous entry, if any. -func (m *Map) Set(key types.Type, value any) (prev any) { - if m.table != nil { - hash := hash(key) - bucket := m.table[hash] - var hole *entry - for i, e := range bucket { - if e.key == nil { - hole = &bucket[i] - } else if types.Identical(key, e.key) { - prev = e.value - bucket[i].value = value - return - } - } - - if hole != nil { - *hole = entry{key, value} // overwrite deleted entry - } else { - m.table[hash] = append(bucket, entry{key, value}) - } - } else { - hash := hash(key) - m.table = map[uint32][]entry{hash: {entry{key, value}}} - } - - m.length++ - return -} - -// Len returns the number of map entries. -func (m *Map) Len() int { - if m != nil { - return m.length - } - return 0 -} - -// Iterate calls function f on each entry in the map in unspecified order. -// -// If f should mutate the map, Iterate provides the same guarantees as -// Go maps: if f deletes a map entry that Iterate has not yet reached, -// f will not be invoked for it, but if f inserts a map entry that -// Iterate has not yet reached, whether or not f will be invoked for -// it is unspecified. -func (m *Map) Iterate(f func(key types.Type, value any)) { - if m != nil { - for _, bucket := range m.table { - for _, e := range bucket { - if e.key != nil { - f(e.key, e.value) - } - } - } - } -} - -// Keys returns a new slice containing the set of map keys. -// The order is unspecified. -func (m *Map) Keys() []types.Type { - keys := make([]types.Type, 0, m.Len()) - m.Iterate(func(key types.Type, _ any) { - keys = append(keys, key) - }) - return keys -} - -func (m *Map) toString(values bool) string { - if m == nil { - return "{}" - } - var buf bytes.Buffer - fmt.Fprint(&buf, "{") - sep := "" - m.Iterate(func(key types.Type, value any) { - fmt.Fprint(&buf, sep) - sep = ", " - fmt.Fprint(&buf, key) - if values { - fmt.Fprintf(&buf, ": %q", value) - } - }) - fmt.Fprint(&buf, "}") - return buf.String() -} - -// String returns a string representation of the map's entries. -// Values are printed using fmt.Sprintf("%v", v). -// Order is unspecified. -func (m *Map) String() string { - return m.toString(true) -} - -// KeysString returns a string representation of the map's key set. -// Order is unspecified. -func (m *Map) KeysString() string { - return m.toString(false) -} - -// -- Hasher -- - -// hash returns the hash of type t. -// TODO(adonovan): replace by types.Hash when Go proposal #69420 is accepted. -func hash(t types.Type) uint32 { - return theHasher.Hash(t) -} - -// A Hasher provides a [Hasher.Hash] method to map a type to its hash value. -// Hashers are stateless, and all are equivalent. -type Hasher struct{} - -var theHasher Hasher - -// MakeHasher returns Hasher{}. -// Hashers are stateless; all are equivalent. -func MakeHasher() Hasher { return theHasher } - -// Hash computes a hash value for the given type t such that -// Identical(t, t') => Hash(t) == Hash(t'). -func (h Hasher) Hash(t types.Type) uint32 { - return hasher{inGenericSig: false}.hash(t) -} - -// hasher holds the state of a single Hash traversal: whether we are -// inside the signature of a generic function; this is used to -// optimize [hasher.hashTypeParam]. -type hasher struct{ inGenericSig bool } - -// hashString computes the Fowler–Noll–Vo hash of s. -func hashString(s string) uint32 { - var h uint32 - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// hash computes the hash of t. -func (h hasher) hash(t types.Type) uint32 { - // See Identical for rationale. - switch t := t.(type) { - case *types.Basic: - return uint32(t.Kind()) - - case *types.Alias: - return h.hash(types.Unalias(t)) - - case *types.Array: - return 9043 + 2*uint32(t.Len()) + 3*h.hash(t.Elem()) - - case *types.Slice: - return 9049 + 2*h.hash(t.Elem()) - - case *types.Struct: - var hash uint32 = 9059 - for i, n := 0, t.NumFields(); i < n; i++ { - f := t.Field(i) - if f.Anonymous() { - hash += 8861 - } - hash += hashString(t.Tag(i)) - hash += hashString(f.Name()) // (ignore f.Pkg) - hash += h.hash(f.Type()) - } - return hash - - case *types.Pointer: - return 9067 + 2*h.hash(t.Elem()) - - case *types.Signature: - var hash uint32 = 9091 - if t.Variadic() { - hash *= 8863 - } - - tparams := t.TypeParams() - if n := tparams.Len(); n > 0 { - h.inGenericSig = true // affects constraints, params, and results - - for i := range n { - tparam := tparams.At(i) - hash += 7 * h.hash(tparam.Constraint()) - } - } - - return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) - - case *types.Union: - return h.hashUnion(t) - - case *types.Interface: - // Interfaces are identical if they have the same set of methods, with - // identical names and types, and they have the same set of type - // restrictions. See go/types.identical for more details. - var hash uint32 = 9103 - - // Hash methods. - for i, n := 0, t.NumMethods(); i < n; i++ { - // Method order is not significant. - // Ignore m.Pkg(). - m := t.Method(i) - // Use shallow hash on method signature to - // avoid anonymous interface cycles. - hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type()) - } - - // Hash type restrictions. - terms, err := typeparams.InterfaceTermSet(t) - // if err != nil t has invalid type restrictions. - if err == nil { - hash += h.hashTermSet(terms) - } - - return hash - - case *types.Map: - return 9109 + 2*h.hash(t.Key()) + 3*h.hash(t.Elem()) - - case *types.Chan: - return 9127 + 2*uint32(t.Dir()) + 3*h.hash(t.Elem()) - - case *types.Named: - hash := h.hashTypeName(t.Obj()) - targs := t.TypeArgs() - for i := 0; i < targs.Len(); i++ { - targ := targs.At(i) - hash += 2 * h.hash(targ) - } - return hash - - case *types.TypeParam: - return h.hashTypeParam(t) - - case *types.Tuple: - return h.hashTuple(t) - } - - panic(fmt.Sprintf("%T: %v", t, t)) -} - -func (h hasher) hashTuple(tuple *types.Tuple) uint32 { - // See go/types.identicalTypes for rationale. - n := tuple.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 3 * h.hash(tuple.At(i).Type()) - } - return hash -} - -func (h hasher) hashUnion(t *types.Union) uint32 { - // Hash type restrictions. - terms, err := typeparams.UnionTermSet(t) - // if err != nil t has invalid type restrictions. Fall back on a non-zero - // hash. - if err != nil { - return 9151 - } - return h.hashTermSet(terms) -} - -func (h hasher) hashTermSet(terms []*types.Term) uint32 { - hash := 9157 + 2*uint32(len(terms)) - for _, term := range terms { - // term order is not significant. - termHash := h.hash(term.Type()) - if term.Tilde() { - termHash *= 9161 - } - hash += 3 * termHash - } - return hash -} - -// hashTypeParam returns the hash of a type parameter. -func (h hasher) hashTypeParam(t *types.TypeParam) uint32 { - // Within the signature of a generic function, TypeParams are - // identical if they have the same index and constraint, so we - // hash them based on index. - // - // When we are outside a generic function, free TypeParams are - // identical iff they are the same object, so we can use a - // more discriminating hash consistent with object identity. - // This optimization saves [Map] about 4% when hashing all the - // types.Info.Types in the forward closure of net/http. - if !h.inGenericSig { - // Optimization: outside a generic function signature, - // use a more discrimating hash consistent with object identity. - return h.hashTypeName(t.Obj()) - } - return 9173 + 3*uint32(t.Index()) -} - -var theSeed = maphash.MakeSeed() - -// hashTypeName hashes the pointer of tname. -func (hasher) hashTypeName(tname *types.TypeName) uint32 { - // Since types.Identical uses == to compare TypeNames, - // the Hash function uses maphash.Comparable. - // TODO(adonovan): or will, when it becomes available in go1.24. - // In the meantime we use the pointer's numeric value. - // - // hash := maphash.Comparable(theSeed, tname) - // - // (Another approach would be to hash the name and package - // path, and whether or not it is a package-level typename. It - // is rare for a package to define multiple local types with - // the same name.) - hash := uintptr(unsafe.Pointer(tname)) - return uint32(hash ^ (hash >> 32)) -} - -// shallowHash computes a hash of t without looking at any of its -// element Types, to avoid potential anonymous cycles in the types of -// interface methods. -// -// When an unnamed non-empty interface type appears anywhere among the -// arguments or results of an interface method, there is a potential -// for endless recursion. Consider: -// -// type X interface { m() []*interface { X } } -// -// The problem is that the Methods of the interface in m's result type -// include m itself; there is no mention of the named type X that -// might help us break the cycle. -// (See comment in go/types.identical, case *Interface, for more.) -func (h hasher) shallowHash(t types.Type) uint32 { - // t is the type of an interface method (Signature), - // its params or results (Tuples), or their immediate - // elements (mostly Slice, Pointer, Basic, Named), - // so there's no need to optimize anything else. - switch t := t.(type) { - case *types.Alias: - return h.shallowHash(types.Unalias(t)) - - case *types.Signature: - var hash uint32 = 604171 - if t.Variadic() { - hash *= 971767 - } - // The Signature/Tuple recursion is always finite - // and invariably shallow. - return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results()) - - case *types.Tuple: - n := t.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 53471161 * h.shallowHash(t.At(i).Type()) - } - return hash - - case *types.Basic: - return 45212177 * uint32(t.Kind()) - - case *types.Array: - return 1524181 + 2*uint32(t.Len()) - - case *types.Slice: - return 2690201 - - case *types.Struct: - return 3326489 - - case *types.Pointer: - return 4393139 - - case *types.Union: - return 562448657 - - case *types.Interface: - return 2124679 // no recursion here - - case *types.Map: - return 9109 - - case *types.Chan: - return 9127 - - case *types.Named: - return h.hashTypeName(t.Obj()) - - case *types.TypeParam: - return h.hashTypeParam(t) - } - panic(fmt.Sprintf("shallowHash: %T: %v", t, t)) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index f766602..0000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,71 +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. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := types.Unalias(T).(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := types.Unalias(T.Elem()).(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9dda6a2..0000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,53 +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 typeutil - -// This file defines utilities for user interfaces that display types. - -import ( - "go/types" -) - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := types.Unalias(T).(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go deleted file mode 100644 index b9425f5..0000000 --- a/vendor/golang.org/x/tools/internal/aliases/aliases.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 The Go 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 aliases - -import ( - "go/token" - "go/types" -) - -// Package aliases defines backward compatible shims -// for the types.Alias type representation added in 1.22. -// This defines placeholders for x/tools until 1.26. - -// NewAlias creates a new TypeName in Package pkg that -// is an alias for the type rhs. -// -// The enabled parameter determines whether the resulting [TypeName]'s -// type is an [types.Alias]. Its value must be the result of a call to -// [Enabled], which computes the effective value of -// GODEBUG=gotypesalias=... by invoking the type checker. The Enabled -// function is expensive and should be called once per task (e.g. -// package import), not once per call to NewAlias. -// -// Precondition: enabled || len(tparams)==0. -// If materialized aliases are disabled, there must not be any type parameters. -func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { - if enabled { - tname := types.NewTypeName(pos, pkg, name, nil) - SetTypeParams(types.NewAlias(tname, rhs), tparams) - return tname - } - if len(tparams) > 0 { - panic("cannot create an alias with type parameters when gotypesalias is not enabled") - } - return types.NewTypeName(pos, pkg, name, rhs) -} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go deleted file mode 100644 index 7716a33..0000000 --- a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2024 The Go 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 aliases - -import ( - "go/ast" - "go/parser" - "go/token" - "go/types" -) - -// Rhs returns the type on the right-hand side of the alias declaration. -func Rhs(alias *types.Alias) types.Type { - if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok { - return alias.Rhs() // go1.23+ - } - - // go1.22's Alias didn't have the Rhs method, - // so Unalias is the best we can do. - return types.Unalias(alias) -} - -// TypeParams returns the type parameter list of the alias. -func TypeParams(alias *types.Alias) *types.TypeParamList { - if alias, ok := any(alias).(interface{ TypeParams() *types.TypeParamList }); ok { - return alias.TypeParams() // go1.23+ - } - return nil -} - -// SetTypeParams sets the type parameters of the alias type. -func SetTypeParams(alias *types.Alias, tparams []*types.TypeParam) { - if alias, ok := any(alias).(interface { - SetTypeParams(tparams []*types.TypeParam) - }); ok { - alias.SetTypeParams(tparams) // go1.23+ - } else if len(tparams) > 0 { - panic("cannot set type parameters of an Alias type in go1.22") - } -} - -// TypeArgs returns the type arguments used to instantiate the Alias type. -func TypeArgs(alias *types.Alias) *types.TypeList { - if alias, ok := any(alias).(interface{ TypeArgs() *types.TypeList }); ok { - return alias.TypeArgs() // go1.23+ - } - return nil // empty (go1.22) -} - -// Origin returns the generic Alias type of which alias is an instance. -// If alias is not an instance of a generic alias, Origin returns alias. -func Origin(alias *types.Alias) *types.Alias { - if alias, ok := any(alias).(interface{ Origin() *types.Alias }); ok { - return alias.Origin() // go1.23+ - } - return alias // not an instance of a generic alias (go1.22) -} - -// Enabled reports whether [NewAlias] should create [types.Alias] types. -// -// This function is expensive! Call it sparingly. -func Enabled() bool { - // The only reliable way to compute the answer is to invoke go/types. - // We don't parse the GODEBUG environment variable, because - // (a) it's tricky to do so in a manner that is consistent - // with the godebug package; in particular, a simple - // substring check is not good enough. The value is a - // rightmost-wins list of options. But more importantly: - // (b) it is impossible to detect changes to the effective - // setting caused by os.Setenv("GODEBUG"), as happens in - // many tests. Therefore any attempt to cache the result - // is just incorrect. - fset := token.NewFileSet() - f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", parser.SkipObjectResolution) - pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil) - _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias) - return enabled -} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go deleted file mode 100644 index a6cf0e6..0000000 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ /dev/null @@ -1,85 +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. - -// Package core provides support for event based telemetry. -package core - -import ( - "fmt" - "time" - - "golang.org/x/tools/internal/event/label" -) - -// Event holds the information about an event of note that occurred. -type Event struct { - at time.Time - - // As events are often on the stack, storing the first few labels directly - // in the event can avoid an allocation at all for the very common cases of - // simple events. - // The length needs to be large enough to cope with the majority of events - // but no so large as to cause undue stack pressure. - // A log message with two values will use 3 labels (one for each value and - // one for the message itself). - - static [3]label.Label // inline storage for the first few labels - dynamic []label.Label // dynamically sized storage for remaining labels -} - -// eventLabelMap implements label.Map for a the labels of an Event. -type eventLabelMap struct { - event Event -} - -func (ev Event) At() time.Time { return ev.at } - -func (ev Event) Format(f fmt.State, r rune) { - if !ev.at.IsZero() { - fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) - } - for index := 0; ev.Valid(index); index++ { - if l := ev.Label(index); l.Valid() { - fmt.Fprintf(f, "\n\t%v", l) - } - } -} - -func (ev Event) Valid(index int) bool { - return index >= 0 && index < len(ev.static)+len(ev.dynamic) -} - -func (ev Event) Label(index int) label.Label { - if index < len(ev.static) { - return ev.static[index] - } - return ev.dynamic[index-len(ev.static)] -} - -func (ev Event) Find(key label.Key) label.Label { - for _, l := range ev.static { - if l.Key() == key { - return l - } - } - for _, l := range ev.dynamic { - if l.Key() == key { - return l - } - } - return label.Label{} -} - -func MakeEvent(static [3]label.Label, labels []label.Label) Event { - return Event{ - static: static, - dynamic: labels, - } -} - -// CloneEvent event returns a copy of the event with the time adjusted to at. -func CloneEvent(ev Event, at time.Time) Event { - ev.at = at - return ev -} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go deleted file mode 100644 index 05f3a9a..0000000 --- a/vendor/golang.org/x/tools/internal/event/core/export.go +++ /dev/null @@ -1,70 +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. - -package core - -import ( - "context" - "sync/atomic" - "time" - "unsafe" - - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, Event, label.Map) context.Context - -var ( - exporter unsafe.Pointer -) - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - p := unsafe.Pointer(&e) - if e == nil { - // &e is always valid, and so p is always valid, but for the early abort - // of ProcessEvent to be efficient it needs to make the nil check on the - // pointer without having to dereference it, so we make the nil function - // also a nil pointer - p = nil - } - atomic.StorePointer(&exporter, p) -} - -// deliver is called to deliver an event to the supplied exporter. -// it will fill in the time. -func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { - // add the current time to the event - ev.at = time.Now() - // hand the event off to the current exporter - return exporter(ctx, ev, ev) -} - -// Export is called to deliver an event to the global exporter if set. -func Export(ctx context.Context, ev Event) context.Context { - // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) - if exporterPtr == nil { - return ctx - } - return deliver(ctx, *exporterPtr, ev) -} - -// ExportPair is called to deliver a start event to the supplied exporter. -// It also returns a function that will deliver the end event to the same -// exporter. -// It will fill in the time. -func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { - // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) - if exporterPtr == nil { - return ctx, func() {} - } - ctx = deliver(ctx, *exporterPtr, begin) - return ctx, func() { deliver(ctx, *exporterPtr, end) } -} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go deleted file mode 100644 index 06c1d46..0000000 --- a/vendor/golang.org/x/tools/internal/event/core/fast.go +++ /dev/null @@ -1,77 +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. - -package core - -import ( - "context" - - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Log1 takes a message and one label delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log1(ctx context.Context, message string, t1 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - }, nil)) -} - -// Log2 takes a message and two labels and delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - t2, - }, nil)) -} - -// Metric1 sends a label event to the exporter with the supplied labels. -func Metric1(ctx context.Context, t1 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - }, nil)) -} - -// Metric2 sends a label event to the exporter with the supplied labels. -func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - t2, - }, nil)) -} - -// Start1 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// Start2 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - t2, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go deleted file mode 100644 index 5dc6e6b..0000000 --- a/vendor/golang.org/x/tools/internal/event/doc.go +++ /dev/null @@ -1,7 +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. - -// Package event provides a set of packages that cover the main -// concepts of telemetry in an implementation agnostic way. -package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go deleted file mode 100644 index 4d55e57..0000000 --- a/vendor/golang.org/x/tools/internal/event/event.go +++ /dev/null @@ -1,127 +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. - -package event - -import ( - "context" - - "golang.org/x/tools/internal/event/core" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, core.Event, label.Map) context.Context - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - core.SetExporter(core.Exporter(e)) -} - -// Log takes a message and a label list and combines them into a single event -// before delivering them to the exporter. -func Log(ctx context.Context, message string, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - }, labels)) -} - -// IsLog returns true if the event was built by the Log function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLog(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg -} - -// Error takes a message and a label list and combines them into a single event -// before delivering them to the exporter. It captures the error in the -// delivered event. -func Error(ctx context.Context, message string, err error, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - keys.Err.Of(err), - }, labels)) -} - -// IsError returns true if the event was built by the Error function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsError(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg && - ev.Label(1).Key() == keys.Err -} - -// Metric sends a label event to the exporter with the supplied labels. -func Metric(ctx context.Context, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Metric.New(), - }, labels)) -} - -// IsMetric returns true if the event was built by the Metric function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsMetric(ev core.Event) bool { - return ev.Label(0).Key() == keys.Metric -} - -// Label sends a label event to the exporter with the supplied labels. -func Label(ctx context.Context, labels ...label.Label) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Label.New(), - }, labels)) -} - -// IsLabel returns true if the event was built by the Label function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLabel(ev core.Event) bool { - return ev.Label(0).Key() == keys.Label -} - -// Start sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { - return core.ExportPair(ctx, - core.MakeEvent([3]label.Label{ - keys.Start.Of(name), - }, labels), - core.MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// IsStart returns true if the event was built by the Start function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsStart(ev core.Event) bool { - return ev.Label(0).Key() == keys.Start -} - -// IsEnd returns true if the event was built by the End function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsEnd(ev core.Event) bool { - return ev.Label(0).Key() == keys.End -} - -// Detach returns a context without an associated span. -// This allows the creation of spans that are not children of the current span. -func Detach(ctx context.Context) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Detach.New(), - }, nil)) -} - -// IsDetach returns true if the event was built by the Detach function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsDetach(ev core.Event) bool { - return ev.Label(0).Key() == keys.Detach -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go deleted file mode 100644 index a02206e..0000000 --- a/vendor/golang.org/x/tools/internal/event/keys/keys.go +++ /dev/null @@ -1,564 +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. - -package keys - -import ( - "fmt" - "io" - "math" - "strconv" - - "golang.org/x/tools/internal/event/label" -) - -// Value represents a key for untyped values. -type Value struct { - name string - description string -} - -// New creates a new Key for untyped values. -func New(name, description string) *Value { - return &Value{name: name, description: description} -} - -func (k *Value) Name() string { return k.name } -func (k *Value) Description() string { return k.description } - -func (k *Value) Format(w io.Writer, buf []byte, l label.Label) { - fmt.Fprint(w, k.From(l)) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Value) Get(lm label.Map) interface{} { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From can be used to get a value from a Label. -func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() } - -// Of creates a new Label with this key and the supplied value. -func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) } - -// Tag represents a key for tagging labels that have no value. -// These are used when the existence of the label is the entire information it -// carries, such as marking events to be of a specific kind, or from a specific -// package. -type Tag struct { - name string - description string -} - -// NewTag creates a new Key for tagging labels. -func NewTag(name, description string) *Tag { - return &Tag{name: name, description: description} -} - -func (k *Tag) Name() string { return k.name } -func (k *Tag) Description() string { return k.description } - -func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {} - -// New creates a new Label with this key. -func (k *Tag) New() label.Label { return label.OfValue(k, nil) } - -// Int represents a key -type Int struct { - name string - description string -} - -// NewInt creates a new Key for int values. -func NewInt(name, description string) *Int { - return &Int{name: name, description: description} -} - -func (k *Int) Name() string { return k.name } -func (k *Int) Description() string { return k.description } - -func (k *Int) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int) Get(lm label.Map) int { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int) From(t label.Label) int { return int(t.Unpack64()) } - -// Int8 represents a key -type Int8 struct { - name string - description string -} - -// NewInt8 creates a new Key for int8 values. -func NewInt8(name, description string) *Int8 { - return &Int8{name: name, description: description} -} - -func (k *Int8) Name() string { return k.name } -func (k *Int8) Description() string { return k.description } - -func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int8) Get(lm label.Map) int8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) } - -// Int16 represents a key -type Int16 struct { - name string - description string -} - -// NewInt16 creates a new Key for int16 values. -func NewInt16(name, description string) *Int16 { - return &Int16{name: name, description: description} -} - -func (k *Int16) Name() string { return k.name } -func (k *Int16) Description() string { return k.description } - -func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int16) Get(lm label.Map) int16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) } - -// Int32 represents a key -type Int32 struct { - name string - description string -} - -// NewInt32 creates a new Key for int32 values. -func NewInt32(name, description string) *Int32 { - return &Int32{name: name, description: description} -} - -func (k *Int32) Name() string { return k.name } -func (k *Int32) Description() string { return k.description } - -func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int32) Get(lm label.Map) int32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) } - -// Int64 represents a key -type Int64 struct { - name string - description string -} - -// NewInt64 creates a new Key for int64 values. -func NewInt64(name, description string) *Int64 { - return &Int64{name: name, description: description} -} - -func (k *Int64) Name() string { return k.name } -func (k *Int64) Description() string { return k.description } - -func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int64) Get(lm label.Map) int64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) } - -// UInt represents a key -type UInt struct { - name string - description string -} - -// NewUInt creates a new Key for uint values. -func NewUInt(name, description string) *UInt { - return &UInt{name: name, description: description} -} - -func (k *UInt) Name() string { return k.name } -func (k *UInt) Description() string { return k.description } - -func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt) Get(lm label.Map) uint { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) } - -// UInt8 represents a key -type UInt8 struct { - name string - description string -} - -// NewUInt8 creates a new Key for uint8 values. -func NewUInt8(name, description string) *UInt8 { - return &UInt8{name: name, description: description} -} - -func (k *UInt8) Name() string { return k.name } -func (k *UInt8) Description() string { return k.description } - -func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt8) Get(lm label.Map) uint8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) } - -// UInt16 represents a key -type UInt16 struct { - name string - description string -} - -// NewUInt16 creates a new Key for uint16 values. -func NewUInt16(name, description string) *UInt16 { - return &UInt16{name: name, description: description} -} - -func (k *UInt16) Name() string { return k.name } -func (k *UInt16) Description() string { return k.description } - -func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt16) Get(lm label.Map) uint16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) } - -// UInt32 represents a key -type UInt32 struct { - name string - description string -} - -// NewUInt32 creates a new Key for uint32 values. -func NewUInt32(name, description string) *UInt32 { - return &UInt32{name: name, description: description} -} - -func (k *UInt32) Name() string { return k.name } -func (k *UInt32) Description() string { return k.description } - -func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt32) Get(lm label.Map) uint32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) } - -// UInt64 represents a key -type UInt64 struct { - name string - description string -} - -// NewUInt64 creates a new Key for uint64 values. -func NewUInt64(name, description string) *UInt64 { - return &UInt64{name: name, description: description} -} - -func (k *UInt64) Name() string { return k.name } -func (k *UInt64) Description() string { return k.description } - -func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt64) Get(lm label.Map) uint64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() } - -// Float32 represents a key -type Float32 struct { - name string - description string -} - -// NewFloat32 creates a new Key for float32 values. -func NewFloat32(name, description string) *Float32 { - return &Float32{name: name, description: description} -} - -func (k *Float32) Name() string { return k.name } -func (k *Float32) Description() string { return k.description } - -func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float32) Of(v float32) label.Label { - return label.Of64(k, uint64(math.Float32bits(v))) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Float32) Get(lm label.Map) float32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Float32) From(t label.Label) float32 { - return math.Float32frombits(uint32(t.Unpack64())) -} - -// Float64 represents a key -type Float64 struct { - name string - description string -} - -// NewFloat64 creates a new Key for int64 values. -func NewFloat64(name, description string) *Float64 { - return &Float64{name: name, description: description} -} - -func (k *Float64) Name() string { return k.name } -func (k *Float64) Description() string { return k.description } - -func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float64) Of(v float64) label.Label { - return label.Of64(k, math.Float64bits(v)) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Float64) Get(lm label.Map) float64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Float64) From(t label.Label) float64 { - return math.Float64frombits(t.Unpack64()) -} - -// String represents a key -type String struct { - name string - description string -} - -// NewString creates a new Key for int64 values. -func NewString(name, description string) *String { - return &String{name: name, description: description} -} - -func (k *String) Name() string { return k.name } -func (k *String) Description() string { return k.description } - -func (k *String) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendQuote(buf, k.From(l))) -} - -// Of creates a new Label with this key and the supplied value. -func (k *String) Of(v string) label.Label { return label.OfString(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *String) Get(lm label.Map) string { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return "" -} - -// From can be used to get a value from a Label. -func (k *String) From(t label.Label) string { return t.UnpackString() } - -// Boolean represents a key -type Boolean struct { - name string - description string -} - -// NewBoolean creates a new Key for bool values. -func NewBoolean(name, description string) *Boolean { - return &Boolean{name: name, description: description} -} - -func (k *Boolean) Name() string { return k.name } -func (k *Boolean) Description() string { return k.description } - -func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendBool(buf, k.From(l))) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Boolean) Of(v bool) label.Label { - if v { - return label.Of64(k, 1) - } - return label.Of64(k, 0) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Boolean) Get(lm label.Map) bool { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return false -} - -// From can be used to get a value from a Label. -func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 } - -// Error represents a key -type Error struct { - name string - description string -} - -// NewError creates a new Key for int64 values. -func NewError(name, description string) *Error { - return &Error{name: name, description: description} -} - -func (k *Error) Name() string { return k.name } -func (k *Error) Description() string { return k.description } - -func (k *Error) Format(w io.Writer, buf []byte, l label.Label) { - io.WriteString(w, k.From(l).Error()) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Error) Get(lm label.Map) error { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From can be used to get a value from a Label. -func (k *Error) From(t label.Label) error { - err, _ := t.UnpackValue().(error) - return err -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go deleted file mode 100644 index 7e95866..0000000 --- a/vendor/golang.org/x/tools/internal/event/keys/standard.go +++ /dev/null @@ -1,22 +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 keys - -var ( - // Msg is a key used to add message strings to label lists. - Msg = NewString("message", "a readable message") - // Label is a key used to indicate an event adds labels to the context. - Label = NewTag("label", "a label context marker") - // Start is used for things like traces that have a name. - Start = NewString("start", "span start") - // Metric is a key used to indicate an event records metrics. - End = NewTag("end", "a span end marker") - // Metric is a key used to indicate an event records metrics. - Detach = NewTag("detach", "a span detach marker") - // Err is a key used to add error values to label lists. - Err = NewError("error", "an error that occurred") - // Metric is a key used to indicate an event records metrics. - Metric = NewTag("metric", "a metric event marker") -) diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go deleted file mode 100644 index c0e8e73..0000000 --- a/vendor/golang.org/x/tools/internal/event/keys/util.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -package keys - -import ( - "sort" - "strings" -) - -// Join returns a canonical join of the keys in S: -// a sorted comma-separated string list. -func Join[S ~[]T, T ~string](s S) string { - strs := make([]string, 0, len(s)) - for _, v := range s { - strs = append(strs, string(v)) - } - sort.Strings(strs) - return strings.Join(strs, ",") -} diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go deleted file mode 100644 index 0f526e1..0000000 --- a/vendor/golang.org/x/tools/internal/event/label/label.go +++ /dev/null @@ -1,215 +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. - -package label - -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -// Key is used as the identity of a Label. -// Keys are intended to be compared by pointer only, the name should be unique -// for communicating with external systems, but it is not required or enforced. -type Key interface { - // Name returns the key name. - Name() string - // Description returns a string that can be used to describe the value. - Description() string - - // Format is used in formatting to append the value of the label to the - // supplied buffer. - // The formatter may use the supplied buf as a scratch area to avoid - // allocations. - Format(w io.Writer, buf []byte, l Label) -} - -// Label holds a key and value pair. -// It is normally used when passing around lists of labels. -type Label struct { - key Key - packed uint64 - untyped interface{} -} - -// Map is the interface to a collection of Labels indexed by key. -type Map interface { - // Find returns the label that matches the supplied key. - Find(key Key) Label -} - -// List is the interface to something that provides an iterable -// list of labels. -// Iteration should start from 0 and continue until Valid returns false. -type List interface { - // Valid returns true if the index is within range for the list. - // It does not imply the label at that index will itself be valid. - Valid(index int) bool - // Label returns the label at the given index. - Label(index int) Label -} - -// list implements LabelList for a list of Labels. -type list struct { - labels []Label -} - -// filter wraps a LabelList filtering out specific labels. -type filter struct { - keys []Key - underlying List -} - -// listMap implements LabelMap for a simple list of labels. -type listMap struct { - labels []Label -} - -// mapChain implements LabelMap for a list of underlying LabelMap. -type mapChain struct { - maps []Map -} - -// OfValue creates a new label from the key and value. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} } - -// UnpackValue assumes the label was built using LabelOfValue and returns the value -// that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackValue() interface{} { return t.untyped } - -// Of64 creates a new label from a key and a uint64. This is often -// used for non uint64 values that can be packed into a uint64. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } - -// Unpack64 assumes the label was built using LabelOf64 and returns the value that -// was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) Unpack64() uint64 { return t.packed } - -type stringptr unsafe.Pointer - -// OfString creates a new label from a key and a string. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfString(k Key, v string) Label { - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) - return Label{ - key: k, - packed: uint64(hdr.Len), - untyped: stringptr(hdr.Data), - } -} - -// UnpackString assumes the label was built using LabelOfString and returns the -// value that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackString() string { - var v string - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) - hdr.Data = uintptr(t.untyped.(stringptr)) - hdr.Len = int(t.packed) - return v -} - -// Valid returns true if the Label is a valid one (it has a key). -func (t Label) Valid() bool { return t.key != nil } - -// Key returns the key of this Label. -func (t Label) Key() Key { return t.key } - -// Format is used for debug printing of labels. -func (t Label) Format(f fmt.State, r rune) { - if !t.Valid() { - io.WriteString(f, `nil`) - return - } - io.WriteString(f, t.Key().Name()) - io.WriteString(f, "=") - var buf [128]byte - t.Key().Format(f, buf[:0], t) -} - -func (l *list) Valid(index int) bool { - return index >= 0 && index < len(l.labels) -} - -func (l *list) Label(index int) Label { - return l.labels[index] -} - -func (f *filter) Valid(index int) bool { - return f.underlying.Valid(index) -} - -func (f *filter) Label(index int) Label { - l := f.underlying.Label(index) - for _, f := range f.keys { - if l.Key() == f { - return Label{} - } - } - return l -} - -func (lm listMap) Find(key Key) Label { - for _, l := range lm.labels { - if l.Key() == key { - return l - } - } - return Label{} -} - -func (c mapChain) Find(key Key) Label { - for _, src := range c.maps { - l := src.Find(key) - if l.Valid() { - return l - } - } - return Label{} -} - -var emptyList = &list{} - -func NewList(labels ...Label) List { - if len(labels) == 0 { - return emptyList - } - return &list{labels: labels} -} - -func Filter(l List, keys ...Key) List { - if len(keys) == 0 { - return l - } - return &filter{keys: keys, underlying: l} -} - -func NewMap(labels ...Label) Map { - return listMap{labels: labels} -} - -func MergeMaps(srcs ...Map) Map { - var nonNil []Map - for _, src := range srcs { - if src != nil { - nonNil = append(nonNil, src) - } - } - if len(nonNil) == 1 { - return nonNil[0] - } - return mapChain{maps: nonNil} -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go deleted file mode 100644 index d79a605..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains the remaining vestiges of -// $GOROOT/src/go/internal/gcimporter/bimport.go. - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sync" -) - -func errorf(format string, args ...interface{}) { - panic(fmt.Sprintf(format, args...)) -} - -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go - -// Synthesize a token.Pos -type fakeFileSet struct { - fset *token.FileSet - files map[string]*fileInfo -} - -type fileInfo struct { - file *token.File - lastline int -} - -const maxlines = 64 * 1024 - -func (s *fakeFileSet) pos(file string, line, column int) token.Pos { - // TODO(mdempsky): Make use of column. - - // Since we don't know the set of needed file positions, we reserve maxlines - // positions per file. We delay calling token.File.SetLines until all - // positions have been calculated (by way of fakeFileSet.setLines), so that - // we can avoid setting unnecessary lines. See also golang/go#46586. - f := s.files[file] - if f == nil { - f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} - s.files[file] = f - } - if line > maxlines { - line = 1 - } - if line > f.lastline { - f.lastline = line - } - - // Return a fake position assuming that f.file consists only of newlines. - return token.Pos(f.file.Base() + line - 1) -} - -func (s *fakeFileSet) setLines() { - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - for _, f := range s.files { - f.file.SetLines(fakeLines[:f.lastline]) - } -} - -var ( - fakeLines []int - fakeLinesOnce sync.Once -) - -func chanDir(d int) types.ChanDir { - // tag values must match the constants in cmd/compile/internal/gc/go.go - switch d { - case 1 /* Crecv */ : - return types.RecvOnly - case 2 /* Csend */ : - return types.SendOnly - case 3 /* Cboth */ : - return types.SendRecv - default: - errorf("unexpected channel dir %d", d) - return 0 - } -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go deleted file mode 100644 index 5662a31..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file should be kept in sync with $GOROOT/src/internal/exportdata/exportdata.go. -// This file also additionally implements FindExportData for gcexportdata.NewReader. - -package gcimporter - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "go/build" - "io" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" -) - -// FindExportData positions the reader r at the beginning of the -// export data section of an underlying cmd/compile created archive -// file by reading from it. The reader must be positioned at the -// start of the file before calling this function. -// This returns the length of the export data in bytes. -// -// This function is needed by [gcexportdata.Read], which must -// accept inputs produced by the last two releases of cmd/compile, -// plus tip. -func FindExportData(r *bufio.Reader) (size int64, err error) { - arsize, err := FindPackageDefinition(r) - if err != nil { - return - } - size = int64(arsize) - - objapi, headers, err := ReadObjectHeaders(r) - if err != nil { - return - } - size -= int64(len(objapi)) - for _, h := range headers { - size -= int64(len(h)) - } - - // Check for the binary export data section header "$$B\n". - // TODO(taking): Unify with ReadExportDataHeader so that it stops at the 'u' instead of reading - line, err := r.ReadSlice('\n') - if err != nil { - return - } - hdr := string(line) - if hdr != "$$B\n" { - err = fmt.Errorf("unknown export data header: %q", hdr) - return - } - size -= int64(len(hdr)) - - // For files with a binary export data header "$$B\n", - // these are always terminated by an end-of-section marker "\n$$\n". - // So the last bytes must always be this constant. - // - // The end-of-section marker is not a part of the export data itself. - // Do not include these in size. - // - // It would be nice to have sanity check that the final bytes after - // the export data are indeed the end-of-section marker. The split - // of gcexportdata.NewReader and gcexportdata.Read make checking this - // ugly so gcimporter gives up enforcing this. The compiler and go/types - // importer do enforce this, which seems good enough. - const endofsection = "\n$$\n" - size -= int64(len(endofsection)) - - if size < 0 { - err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", arsize, size) - return - } - - return -} - -// ReadUnified reads the contents of the unified export data from a reader r -// that contains the contents of a GC-created archive file. -// -// On success, the reader will be positioned after the end-of-section marker "\n$$\n". -// -// Supported GC-created archive files have 4 layers of nesting: -// - An archive file containing a package definition file. -// - The package definition file contains headers followed by a data section. -// Headers are lines (≤ 4kb) that do not start with "$$". -// - The data section starts with "$$B\n" followed by export data followed -// by an end of section marker "\n$$\n". (The section start "$$\n" is no -// longer supported.) -// - The export data starts with a format byte ('u') followed by the in -// the given format. (See ReadExportDataHeader for older formats.) -// -// Putting this together, the bytes in a GC-created archive files are expected -// to look like the following. -// See cmd/internal/archive for more details on ar file headers. -// -// | \n | ar file signature -// | __.PKGDEF...size...\n | ar header for __.PKGDEF including size. -// | go object <...>\n | objabi header -// | \n | other headers such as build id -// | $$B\n | binary format marker -// | u\n | unified export -// | $$\n | end-of-section marker -// | [optional padding] | padding byte (0x0A) if size is odd -// | [ar file header] | other ar files -// | [ar file data] | -func ReadUnified(r *bufio.Reader) (data []byte, err error) { - // We historically guaranteed headers at the default buffer size (4096) work. - // This ensures we can use ReadSlice throughout. - const minBufferSize = 4096 - r = bufio.NewReaderSize(r, minBufferSize) - - size, err := FindPackageDefinition(r) - if err != nil { - return - } - n := size - - objapi, headers, err := ReadObjectHeaders(r) - if err != nil { - return - } - n -= len(objapi) - for _, h := range headers { - n -= len(h) - } - - hdrlen, err := ReadExportDataHeader(r) - if err != nil { - return - } - n -= hdrlen - - // size also includes the end of section marker. Remove that many bytes from the end. - const marker = "\n$$\n" - n -= len(marker) - - if n < 0 { - err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", size, n) - return - } - - // Read n bytes from buf. - data = make([]byte, n) - _, err = io.ReadFull(r, data) - if err != nil { - return - } - - // Check for marker at the end. - var suffix [len(marker)]byte - _, err = io.ReadFull(r, suffix[:]) - if err != nil { - return - } - if s := string(suffix[:]); s != marker { - err = fmt.Errorf("read %q instead of end-of-section marker (%q)", s, marker) - return - } - - return -} - -// FindPackageDefinition positions the reader r at the beginning of a package -// definition file ("__.PKGDEF") within a GC-created archive by reading -// from it, and returns the size of the package definition file in the archive. -// -// The reader must be positioned at the start of the archive file before calling -// this function, and "__.PKGDEF" is assumed to be the first file in the archive. -// -// See cmd/internal/archive for details on the archive format. -func FindPackageDefinition(r *bufio.Reader) (size int, err error) { - // Uses ReadSlice to limit risk of malformed inputs. - - // Read first line to make sure this is an object file. - line, err := r.ReadSlice('\n') - if err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - - // Is the first line an archive file signature? - if string(line) != "!\n" { - err = fmt.Errorf("not the start of an archive file (%q)", line) - return - } - - // package export block should be first - size = readArchiveHeader(r, "__.PKGDEF") - if size <= 0 { - err = fmt.Errorf("not a package file") - return - } - - return -} - -// ReadObjectHeaders reads object headers from the reader. Object headers are -// lines that do not start with an end-of-section marker "$$". The first header -// is the objabi header. On success, the reader will be positioned at the beginning -// of the end-of-section marker. -// -// It returns an error if any header does not fit in r.Size() bytes. -func ReadObjectHeaders(r *bufio.Reader) (objapi string, headers []string, err error) { - // line is a temporary buffer for headers. - // Use bounded reads (ReadSlice, Peek) to limit risk of malformed inputs. - var line []byte - - // objapi header should be the first line - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - objapi = string(line) - - // objapi header begins with "go object ". - if !strings.HasPrefix(objapi, "go object ") { - err = fmt.Errorf("not a go object file: %s", objapi) - return - } - - // process remaining object header lines - for { - // check for an end of section marker "$$" - line, err = r.Peek(2) - if err != nil { - return - } - if string(line) == "$$" { - return // stop - } - - // read next header - line, err = r.ReadSlice('\n') - if err != nil { - return - } - headers = append(headers, string(line)) - } -} - -// ReadExportDataHeader reads the export data header and format from r. -// It returns the number of bytes read, or an error if the format is no longer -// supported or it failed to read. -// -// The only currently supported format is binary export data in the -// unified export format. -func ReadExportDataHeader(r *bufio.Reader) (n int, err error) { - // Read export data header. - line, err := r.ReadSlice('\n') - if err != nil { - return - } - - hdr := string(line) - switch hdr { - case "$$\n": - err = fmt.Errorf("old textual export format no longer supported (recompile package)") - return - - case "$$B\n": - var format byte - format, err = r.ReadByte() - if err != nil { - return - } - // The unified export format starts with a 'u'. - switch format { - case 'u': - default: - // Older no longer supported export formats include: - // indexed export format which started with an 'i'; and - // the older binary export format which started with a 'c', - // 'd', or 'v' (from "version"). - err = fmt.Errorf("binary export format %q is no longer supported (recompile package)", format) - return - } - - default: - err = fmt.Errorf("unknown export data header: %q", hdr) - return - } - - n = len(hdr) + 1 // + 1 is for 'u' - return -} - -// FindPkg returns the filename and unique package id for an import -// path based on package information provided by build.Import (using -// the build.Default build.Context). A relative srcDir is interpreted -// relative to the current working directory. -// -// FindPkg is only used in tests within x/tools. -func FindPkg(path, srcDir string) (filename, id string, err error) { - // TODO(taking): Move internal/exportdata.FindPkg into its own file, - // and then this copy into a _test package. - if path == "" { - return "", "", errors.New("path is empty") - } - - var noext string - switch { - default: - // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" - // Don't require the source files to be present. - if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 - srcDir = abs - } - var bp *build.Package - bp, err = build.Import(path, srcDir, build.FindOnly|build.AllowBinary) - if bp.PkgObj == "" { - if bp.Goroot && bp.Dir != "" { - filename, err = lookupGorootExport(bp.Dir) - if err == nil { - _, err = os.Stat(filename) - } - if err == nil { - return filename, bp.ImportPath, nil - } - } - goto notfound - } else { - noext = strings.TrimSuffix(bp.PkgObj, ".a") - } - id = bp.ImportPath - - case build.IsLocalImport(path): - // "./x" -> "/this/directory/x.ext", "/this/directory/x" - noext = filepath.Join(srcDir, path) - id = noext - - case filepath.IsAbs(path): - // for completeness only - go/build.Import - // does not support absolute imports - // "/x" -> "/x.ext", "/x" - noext = path - id = path - } - - if false { // for debugging - if path != id { - fmt.Printf("%s -> %s\n", path, id) - } - } - - // try extensions - for _, ext := range pkgExts { - filename = noext + ext - f, statErr := os.Stat(filename) - if statErr == nil && !f.IsDir() { - return filename, id, nil - } - if err == nil { - err = statErr - } - } - -notfound: - if err == nil { - return "", path, fmt.Errorf("can't find import: %q", path) - } - return "", path, fmt.Errorf("can't find import: %q: %w", path, err) -} - -var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension - -var exportMap sync.Map // package dir → func() (string, error) - -// lookupGorootExport returns the location of the export data -// (normally found in the build cache, but located in GOROOT/pkg -// in prior Go releases) for the package located in pkgDir. -// -// (We use the package's directory instead of its import path -// mainly to simplify handling of the packages in src/vendor -// and cmd/vendor.) -// -// lookupGorootExport is only used in tests within x/tools. -func lookupGorootExport(pkgDir string) (string, error) { - f, ok := exportMap.Load(pkgDir) - if !ok { - var ( - listOnce sync.Once - exportPath string - err error - ) - f, _ = exportMap.LoadOrStore(pkgDir, func() (string, error) { - listOnce.Do(func() { - cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir) - cmd.Dir = build.Default.GOROOT - cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT) - var output []byte - output, err = cmd.Output() - if err != nil { - if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { - err = errors.New(string(ee.Stderr)) - } - return - } - - exports := strings.Split(string(bytes.TrimSpace(output)), "\n") - if len(exports) != 1 { - err = fmt.Errorf("go list reported %d exports; expected 1", len(exports)) - return - } - - exportPath = exports[0] - }) - - return exportPath, err - }) - } - - return f.(func() (string, error))() -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go deleted file mode 100644 index 3dbd21d..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go. - -// Package gcimporter provides various functions for reading -// gc-generated object files that can be used to implement the -// Importer interface defined by the Go 1.5 standard library package. -// -// The encoding is deterministic: if the encoder is applied twice to -// the same types.Package data structure, both encodings are equal. -// This property may be important to avoid spurious changes in -// applications such as build systems. -// -// However, the encoder is not necessarily idempotent. Importing an -// exported package may yield a types.Package that, while it -// represents the same set of Go types as the original, may differ in -// the details of its internal representation. Because of these -// differences, re-encoding the imported package may yield a -// different, but equally valid, encoding of the package. -package gcimporter // import "golang.org/x/tools/internal/gcimporter" - -import ( - "bufio" - "fmt" - "go/token" - "go/types" - "io" - "os" -) - -const ( - // Enable debug during development: it adds some additional checks, and - // prevents errors from being recovered. - debug = false - - // If trace is set, debugging output is printed to std out. - trace = false -) - -// Import imports a gc-generated package given its import path and srcDir, adds -// the corresponding package object to the packages map, and returns the object. -// The packages map must contain all packages already imported. -// -// Import is only used in tests. -func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { - var rc io.ReadCloser - var id string - if lookup != nil { - // With custom lookup specified, assume that caller has - // converted path to a canonical import path for use in the map. - if path == "unsafe" { - return types.Unsafe, nil - } - id = path - - // No need to re-import if the package was imported completely before. - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - f, err := lookup(path) - if err != nil { - return nil, err - } - rc = f - } else { - var filename string - filename, id, err = FindPkg(path, srcDir) - if filename == "" { - if path == "unsafe" { - return types.Unsafe, nil - } - return nil, err - } - - // no need to re-import if the package was imported completely before - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - // add file name to error - err = fmt.Errorf("%s: %v", filename, err) - } - }() - rc = f - } - defer rc.Close() - - buf := bufio.NewReader(rc) - data, err := ReadUnified(buf) - if err != nil { - err = fmt.Errorf("import %q: %v", path, err) - return - } - - // unified: emitted by cmd/compile since go1.20. - _, pkg, err = UImportData(fset, packages, data, id) - - return -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go deleted file mode 100644 index 7dfc31a..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ /dev/null @@ -1,1588 +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. - -// Indexed package export. -// -// The indexed export data format is an evolution of the previous -// binary export data format. Its chief contribution is introducing an -// index table, which allows efficient random access of individual -// declarations and inline function bodies. In turn, this allows -// avoiding unnecessary work for compilation units that import large -// packages. -// -// -// The top-level data format is structured as: -// -// Header struct { -// Tag byte // 'i' -// Version uvarint -// StringSize uvarint -// DataSize uvarint -// } -// -// Strings [StringSize]byte -// Data [DataSize]byte -// -// MainIndex []struct{ -// PkgPath stringOff -// PkgName stringOff -// PkgHeight uvarint -// -// Decls []struct{ -// Name stringOff -// Offset declOff -// } -// } -// -// Fingerprint [8]byte -// -// uvarint means a uint64 written out using uvarint encoding. -// -// []T means a uvarint followed by that many T objects. In other -// words: -// -// Len uvarint -// Elems [Len]T -// -// stringOff means a uvarint that indicates an offset within the -// Strings section. At that offset is another uvarint, followed by -// that many bytes, which form the string value. -// -// declOff means a uvarint that indicates an offset within the Data -// section where the associated declaration can be found. -// -// -// There are five kinds of declarations, distinguished by their first -// byte: -// -// type Var struct { -// Tag byte // 'V' -// Pos Pos -// Type typeOff -// } -// -// type Func struct { -// Tag byte // 'F' or 'G' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'G' -// Signature Signature -// } -// -// type Const struct { -// Tag byte // 'C' -// Pos Pos -// Value Value -// } -// -// type Type struct { -// Tag byte // 'T' or 'U' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'U' -// Underlying typeOff -// -// Methods []struct{ // omitted if Underlying is an interface type -// Pos Pos -// Name stringOff -// Recv Param -// Signature Signature -// } -// } -// -// type Alias struct { -// Tag byte // 'A' or 'B' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'B' -// Type typeOff -// } -// -// // "Automatic" declaration of each typeparam -// type TypeParam struct { -// Tag byte // 'P' -// Pos Pos -// Implicit bool -// Constraint typeOff -// } -// -// typeOff means a uvarint that either indicates a predeclared type, -// or an offset into the Data section. If the uvarint is less than -// predeclReserved, then it indicates the index into the predeclared -// types list (see predeclared in bexport.go for order). Otherwise, -// subtracting predeclReserved yields the offset of a type descriptor. -// -// Value means a type, kind, and type-specific value. See -// (*exportWriter).value for details. -// -// -// There are twelve kinds of type descriptors, distinguished by an itag: -// -// type DefinedType struct { -// Tag itag // definedType -// Name stringOff -// PkgPath stringOff -// } -// -// type PointerType struct { -// Tag itag // pointerType -// Elem typeOff -// } -// -// type SliceType struct { -// Tag itag // sliceType -// Elem typeOff -// } -// -// type ArrayType struct { -// Tag itag // arrayType -// Len uint64 -// Elem typeOff -// } -// -// type ChanType struct { -// Tag itag // chanType -// Dir uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv -// Elem typeOff -// } -// -// type MapType struct { -// Tag itag // mapType -// Key typeOff -// Elem typeOff -// } -// -// type FuncType struct { -// Tag itag // signatureType -// PkgPath stringOff -// Signature Signature -// } -// -// type StructType struct { -// Tag itag // structType -// PkgPath stringOff -// Fields []struct { -// Pos Pos -// Name stringOff -// Type typeOff -// Embedded bool -// Note stringOff -// } -// } -// -// type InterfaceType struct { -// Tag itag // interfaceType -// PkgPath stringOff -// Embeddeds []struct { -// Pos Pos -// Type typeOff -// } -// Methods []struct { -// Pos Pos -// Name stringOff -// Signature Signature -// } -// } -// -// // Reference to a type param declaration -// type TypeParamType struct { -// Tag itag // typeParamType -// Name stringOff -// PkgPath stringOff -// } -// -// // Instantiation of a generic type (like List[T2] or List[int]) -// type InstanceType struct { -// Tag itag // instanceType -// Pos pos -// TypeArgs []typeOff -// BaseType typeOff -// } -// -// type UnionType struct { -// Tag itag // interfaceType -// Terms []struct { -// tilde bool -// Type typeOff -// } -// } -// -// -// -// type Signature struct { -// Params []Param -// Results []Param -// Variadic bool // omitted if Results is empty -// } -// -// type Param struct { -// Pos Pos -// Name stringOff -// Type typOff -// } -// -// -// Pos encodes a file:line:column triple, incorporating a simple delta -// encoding scheme within a data object. See exportWriter.pos for -// details. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "reflect" - "sort" - "strconv" - "strings" - - "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/aliases" -) - -// IExportShallow encodes "shallow" export data for the specified package. -// -// For types, we use "shallow" export data. Historically, the Go -// compiler always produced a summary of the types for a given package -// that included types from other packages that it indirectly -// referenced: "deep" export data. This had the advantage that the -// compiler (and analogous tools such as gopls) need only load one -// file per direct import. However, it meant that the files tended to -// get larger based on the level of the package in the import -// graph. For example, higher-level packages in the kubernetes module -// have over 1MB of "deep" export data, even when they have almost no -// content of their own, merely because they mention a major type that -// references many others. In pathological cases the export data was -// 300x larger than the source for a package due to this quadratic -// growth. -// -// "Shallow" export data means that the serialized types describe only -// a single package. If those types mention types from other packages, -// the type checker may need to request additional packages beyond -// just the direct imports. Type information for the entire transitive -// closure of imports is provided (lazily) by the DAG. -// -// No promises are made about the encoding other than that it can be decoded by -// the same version of IIExportShallow. If you plan to save export data in the -// file system, be sure to include a cryptographic digest of the executable in -// the key to avoid version skew. -// -// If the provided reportf func is non-nil, it will be used for reporting bugs -// encountered during export. -// TODO(rfindley): remove reportf when we are confident enough in the new -// objectpath encoding. -func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) { - // In principle this operation can only fail if out.Write fails, - // but that's impossible for bytes.Buffer---and as a matter of - // fact iexportCommon doesn't even check for I/O errors. - // TODO(adonovan): handle I/O errors properly. - // TODO(adonovan): use byte slices throughout, avoiding copying. - const bundle, shallow = false, true - var out bytes.Buffer - err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) - return out.Bytes(), err -} - -// IImportShallow decodes "shallow" types.Package data encoded by -// [IExportShallow] in the same executable. This function cannot import data -// from cmd/compile or gcexportdata.Write. -// -// The importer calls getPackages to obtain package symbols for all -// packages mentioned in the export data, including the one being -// decoded. -// -// If the provided reportf func is non-nil, it will be used for reporting bugs -// encountered during import. -// TODO(rfindley): remove reportf when we are confident enough in the new -// objectpath encoding. -func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) { - const bundle = false - const shallow = true - pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf) - if err != nil { - return nil, err - } - return pkgs[0], nil -} - -// ReportFunc is the type of a function used to report formatted bugs. -type ReportFunc = func(string, ...interface{}) - -// Current bundled export format version. Increase with each format change. -// 0: initial implementation -const bundleVersion = 0 - -// IExportData writes indexed export data for pkg to out. -// -// If no file set is provided, position info will be missing. -// The package path of the top-level package will not be recorded, -// so that calls to IImportData can override with a provided package path. -func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - const bundle, shallow = false, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}) -} - -// IExportBundle writes an indexed export bundle for pkgs to out. -func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - const bundle, shallow = true, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs) -} - -func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) { - if !debug { - defer func() { - if e := recover(); e != nil { - if ierr, ok := e.(internalError); ok { - err = ierr - return - } - // Not an internal error; panic again. - panic(e) - } - }() - } - - p := iexporter{ - fset: fset, - version: version, - shallow: shallow, - allPkgs: map[*types.Package]bool{}, - stringIndex: map[string]uint64{}, - declIndex: map[types.Object]uint64{}, - tparamNames: map[types.Object]string{}, - typIndex: map[types.Type]uint64{}, - } - if !bundle { - p.localpkg = pkgs[0] - } - - for i, pt := range predeclared() { - p.typIndex[pt] = uint64(i) - } - if len(p.typIndex) > predeclReserved { - panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) - } - - // Initialize work queue with exported declarations. - for _, pkg := range pkgs { - scope := pkg.Scope() - for _, name := range scope.Names() { - if token.IsExported(name) { - p.pushDecl(scope.Lookup(name)) - } - } - - if bundle { - // Ensure pkg and its imports are included in the index. - p.allPkgs[pkg] = true - for _, imp := range pkg.Imports() { - p.allPkgs[imp] = true - } - } - } - - // Loop until no more work. - for !p.declTodo.empty() { - p.doDecl(p.declTodo.popHead()) - } - - // Produce index of offset of each file record in files. - var files intWriter - var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i - if p.shallow { - fileOffset = make([]uint64, len(p.fileInfos)) - for i, info := range p.fileInfos { - fileOffset[i] = uint64(files.Len()) - p.encodeFile(&files, info.file, info.needed) - } - } - - // Append indices to data0 section. - dataLen := uint64(p.data0.Len()) - w := p.newWriter() - w.writeIndex(p.declIndex) - - if bundle { - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.pkg(pkg) - imps := pkg.Imports() - w.uint64(uint64(len(imps))) - for _, imp := range imps { - w.pkg(imp) - } - } - } - w.flush() - - // Assemble header. - var hdr intWriter - if bundle { - hdr.uint64(bundleVersion) - } - hdr.uint64(uint64(p.version)) - hdr.uint64(uint64(p.strings.Len())) - if p.shallow { - hdr.uint64(uint64(files.Len())) - hdr.uint64(uint64(len(fileOffset))) - for _, offset := range fileOffset { - hdr.uint64(offset) - } - } - hdr.uint64(dataLen) - - // Flush output. - io.Copy(out, &hdr) - io.Copy(out, &p.strings) - if p.shallow { - io.Copy(out, &files) - } - io.Copy(out, &p.data0) - - return nil -} - -// encodeFile writes to w a representation of the file sufficient to -// faithfully restore position information about all needed offsets. -// Mutates the needed array. -func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) { - _ = needed[0] // precondition: needed is non-empty - - w.uint64(p.stringOff(file.Name())) - - size := uint64(file.Size()) - w.uint64(size) - - // Sort the set of needed offsets. Duplicates are harmless. - sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] }) - - lines := file.Lines() // byte offset of each line start - w.uint64(uint64(len(lines))) - - // Rather than record the entire array of line start offsets, - // we save only a sparse list of (index, offset) pairs for - // the start of each line that contains a needed position. - var sparse [][2]int // (index, offset) pairs -outer: - for i, lineStart := range lines { - lineEnd := size - if i < len(lines)-1 { - lineEnd = uint64(lines[i+1]) - } - // Does this line contains a needed offset? - if needed[0] < lineEnd { - sparse = append(sparse, [2]int{i, lineStart}) - for needed[0] < lineEnd { - needed = needed[1:] - if len(needed) == 0 { - break outer - } - } - } - } - - // Delta-encode the columns. - w.uint64(uint64(len(sparse))) - var prev [2]int - for _, pair := range sparse { - w.uint64(uint64(pair[0] - prev[0])) - w.uint64(uint64(pair[1] - prev[1])) - prev = pair - } -} - -// writeIndex writes out an object index. mainIndex indicates whether -// we're writing out the main index, which is also read by -// non-compiler tools and includes a complete package description -// (i.e., name and height). -func (w *exportWriter) writeIndex(index map[types.Object]uint64) { - type pkgObj struct { - obj types.Object - name string // qualified name; differs from obj.Name for type params - } - // Build a map from packages to objects from that package. - pkgObjs := map[*types.Package][]pkgObj{} - - // For the main index, make sure to include every package that - // we reference, even if we're not exporting (or reexporting) - // any symbols from it. - if w.p.localpkg != nil { - pkgObjs[w.p.localpkg] = nil - } - for pkg := range w.p.allPkgs { - pkgObjs[pkg] = nil - } - - for obj := range index { - name := w.p.exportName(obj) - pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) - } - - var pkgs []*types.Package - for pkg, objs := range pkgObjs { - pkgs = append(pkgs, pkg) - - sort.Slice(objs, func(i, j int) bool { - return objs[i].name < objs[j].name - }) - } - - sort.Slice(pkgs, func(i, j int) bool { - return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) - }) - - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.string(w.exportPath(pkg)) - w.string(pkg.Name()) - w.uint64(uint64(0)) // package height is not needed for go/types - - objs := pkgObjs[pkg] - w.uint64(uint64(len(objs))) - for _, obj := range objs { - w.string(obj.name) - w.uint64(index[obj.obj]) - } - } -} - -// exportName returns the 'exported' name of an object. It differs from -// obj.Name() only for type parameters (see tparamExportName for details). -func (p *iexporter) exportName(obj types.Object) (res string) { - if name := p.tparamNames[obj]; name != "" { - return name - } - return obj.Name() -} - -type iexporter struct { - fset *token.FileSet - out *bytes.Buffer - version int - - shallow bool // don't put types from other packages in the index - objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated - localpkg *types.Package // (nil in bundle mode) - - // allPkgs tracks all packages that have been referenced by - // the export data, so we can ensure to include them in the - // main index. - allPkgs map[*types.Package]bool - - declTodo objQueue - - strings intWriter - stringIndex map[string]uint64 - - // In shallow mode, object positions are encoded as (file, offset). - // Each file is recorded as a line-number table. - // Only the lines of needed positions are saved faithfully. - fileInfo map[*token.File]uint64 // value is index in fileInfos - fileInfos []*filePositions - - data0 intWriter - declIndex map[types.Object]uint64 - tparamNames map[types.Object]string // typeparam->exported name - typIndex map[types.Type]uint64 - - indent int // for tracing support -} - -type filePositions struct { - file *token.File - needed []uint64 // unordered list of needed file offsets -} - -func (p *iexporter) trace(format string, args ...interface{}) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -// objectpathEncoder returns the lazily allocated objectpath.Encoder to use -// when encoding objects in other packages during shallow export. -// -// Using a shared Encoder amortizes some of cost of objectpath search. -func (p *iexporter) objectpathEncoder() *objectpath.Encoder { - if p.objEncoder == nil { - p.objEncoder = new(objectpath.Encoder) - } - return p.objEncoder -} - -// stringOff returns the offset of s within the string section. -// If not already present, it's added to the end. -func (p *iexporter) stringOff(s string) uint64 { - off, ok := p.stringIndex[s] - if !ok { - off = uint64(p.strings.Len()) - p.stringIndex[s] = off - - p.strings.uint64(uint64(len(s))) - p.strings.WriteString(s) - } - return off -} - -// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it. -func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) { - index, ok := p.fileInfo[file] - if !ok { - index = uint64(len(p.fileInfo)) - p.fileInfos = append(p.fileInfos, &filePositions{file: file}) - if p.fileInfo == nil { - p.fileInfo = make(map[*token.File]uint64) - } - p.fileInfo[file] = index - } - // Record each needed offset. - info := p.fileInfos[index] - offset := uint64(file.Offset(pos)) - info.needed = append(info.needed, offset) - - return index, offset -} - -// pushDecl adds n to the declaration work queue, if not already present. -func (p *iexporter) pushDecl(obj types.Object) { - // Package unsafe is known to the compiler and predeclared. - // Caller should not ask us to do export it. - if obj.Pkg() == types.Unsafe { - panic("cannot export package unsafe") - } - - // Shallow export data: don't index decls from other packages. - if p.shallow && obj.Pkg() != p.localpkg { - return - } - - if _, ok := p.declIndex[obj]; ok { - return - } - - p.declIndex[obj] = ^uint64(0) // mark obj present in work queue - p.declTodo.pushTail(obj) -} - -// exportWriter handles writing out individual data section chunks. -type exportWriter struct { - p *iexporter - - data intWriter - prevFile string - prevLine int64 - prevColumn int64 -} - -func (w *exportWriter) exportPath(pkg *types.Package) string { - if pkg == w.p.localpkg { - return "" - } - return pkg.Path() -} - -func (p *iexporter) doDecl(obj types.Object) { - if trace { - p.trace("exporting decl %v (%T)", obj, obj) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", obj) - }() - } - w := p.newWriter() - - switch obj := obj.(type) { - case *types.Var: - w.tag(varTag) - w.pos(obj.Pos()) - w.typ(obj.Type(), obj.Pkg()) - - case *types.Func: - sig, _ := obj.Type().(*types.Signature) - if sig.Recv() != nil { - // We shouldn't see methods in the package scope, - // but the type checker may repair "func () F() {}" - // to "func (Invalid) F()" and then treat it like "func F()", - // so allow that. See golang/go#57729. - if sig.Recv().Type() != types.Typ[types.Invalid] { - panic(internalErrorf("unexpected method: %v", sig)) - } - } - - // Function. - if sig.TypeParams().Len() == 0 { - w.tag(funcTag) - } else { - w.tag(genericFuncTag) - } - w.pos(obj.Pos()) - // The tparam list of the function type is the declaration of the type - // params. So, write out the type params right now. Then those type params - // will be referenced via their type offset (via typOff) in all other - // places in the signature and function where they are used. - // - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - if tparams := sig.TypeParams(); tparams.Len() > 0 { - w.tparamList(obj.Name(), tparams, obj.Pkg()) - } - w.signature(sig) - - case *types.Const: - w.tag(constTag) - w.pos(obj.Pos()) - w.value(obj.Type(), obj.Val()) - - case *types.TypeName: - t := obj.Type() - - if tparam, ok := types.Unalias(t).(*types.TypeParam); ok { - w.tag(typeParamTag) - w.pos(obj.Pos()) - constraint := tparam.Constraint() - if p.version >= iexportVersionGo1_18 { - implicit := false - if iface, _ := types.Unalias(constraint).(*types.Interface); iface != nil { - implicit = iface.IsImplicit() - } - w.bool(implicit) - } - w.typ(constraint, obj.Pkg()) - break - } - - if obj.IsAlias() { - alias, materialized := t.(*types.Alias) // may fail when aliases are not enabled - - var tparams *types.TypeParamList - if materialized { - tparams = aliases.TypeParams(alias) - } - if tparams.Len() == 0 { - w.tag(aliasTag) - } else { - w.tag(genericAliasTag) - } - w.pos(obj.Pos()) - if tparams.Len() > 0 { - w.tparamList(obj.Name(), tparams, obj.Pkg()) - } - if materialized { - // Preserve materialized aliases, - // even of non-exported types. - t = aliases.Rhs(alias) - } - w.typ(t, obj.Pkg()) - break - } - - // Defined type. - named, ok := t.(*types.Named) - if !ok { - panic(internalErrorf("%s is not a defined type", t)) - } - - if named.TypeParams().Len() == 0 { - w.tag(typeTag) - } else { - w.tag(genericTypeTag) - } - w.pos(obj.Pos()) - - if named.TypeParams().Len() > 0 { - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) - } - - underlying := named.Underlying() - w.typ(underlying, obj.Pkg()) - - if types.IsInterface(t) { - break - } - - n := named.NumMethods() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - m := named.Method(i) - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - - // Receiver type parameters are type arguments of the receiver type, so - // their name must be qualified before exporting recv. - if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { - prefix := obj.Name() + "." + m.Name() - for i := 0; i < rparams.Len(); i++ { - rparam := rparams.At(i) - name := tparamExportName(prefix, rparam) - w.p.tparamNames[rparam.Obj()] = name - } - } - w.param(sig.Recv()) - w.signature(sig) - } - - default: - panic(internalErrorf("unexpected object: %v", obj)) - } - - p.declIndex[obj] = w.flush() -} - -func (w *exportWriter) tag(tag byte) { - w.data.WriteByte(tag) -} - -func (w *exportWriter) pos(pos token.Pos) { - if w.p.shallow { - w.posV2(pos) - } else if w.p.version >= iexportVersionPosCol { - w.posV1(pos) - } else { - w.posV0(pos) - } -} - -// posV2 encoding (used only in shallow mode) records positions as -// (file, offset), where file is the index in the token.File table -// (which records the file name and newline offsets) and offset is a -// byte offset. It effectively ignores //line directives. -func (w *exportWriter) posV2(pos token.Pos) { - if pos == token.NoPos { - w.uint64(0) - return - } - file := w.p.fset.File(pos) // fset must be non-nil - index, offset := w.p.fileIndexAndOffset(file, pos) - w.uint64(1 + index) - w.uint64(offset) -} - -func (w *exportWriter) posV1(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - column := int64(p.Column) - - deltaColumn := (column - w.prevColumn) << 1 - deltaLine := (line - w.prevLine) << 1 - - if file != w.prevFile { - deltaLine |= 1 - } - if deltaLine != 0 { - deltaColumn |= 1 - } - - w.int64(deltaColumn) - if deltaColumn&1 != 0 { - w.int64(deltaLine) - if deltaLine&1 != 0 { - w.string(file) - } - } - - w.prevFile = file - w.prevLine = line - w.prevColumn = column -} - -func (w *exportWriter) posV0(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - - // When file is the same as the last position (common case), - // we can save a few bytes by delta encoding just the line - // number. - // - // Note: Because data objects may be read out of order (or not - // at all), we can only apply delta encoding within a single - // object. This is handled implicitly by tracking prevFile and - // prevLine as fields of exportWriter. - - if file == w.prevFile { - delta := line - w.prevLine - w.int64(delta) - if delta == deltaNewFile { - w.int64(-1) - } - } else { - w.int64(deltaNewFile) - w.int64(line) // line >= 0 - w.string(file) - w.prevFile = file - } - w.prevLine = line -} - -func (w *exportWriter) pkg(pkg *types.Package) { - // Ensure any referenced packages are declared in the main index. - w.p.allPkgs[pkg] = true - - w.string(w.exportPath(pkg)) -} - -func (w *exportWriter) qualifiedType(obj *types.TypeName) { - name := w.p.exportName(obj) - - // Ensure any referenced declarations are written out too. - w.p.pushDecl(obj) - w.string(name) - w.pkg(obj.Pkg()) -} - -// TODO(rfindley): what does 'pkg' even mean here? It would be better to pass -// it in explicitly into signatures and structs that may use it for -// constructing fields. -func (w *exportWriter) typ(t types.Type, pkg *types.Package) { - w.data.uint64(w.p.typOff(t, pkg)) -} - -func (p *iexporter) newWriter() *exportWriter { - return &exportWriter{p: p} -} - -func (w *exportWriter) flush() uint64 { - off := uint64(w.p.data0.Len()) - io.Copy(&w.p.data0, &w.data) - return off -} - -func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { - off, ok := p.typIndex[t] - if !ok { - w := p.newWriter() - w.doTyp(t, pkg) - off = predeclReserved + w.flush() - p.typIndex[t] = off - } - return off -} - -func (w *exportWriter) startType(k itag) { - w.data.uint64(uint64(k)) -} - -func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { - if trace { - w.p.trace("exporting type %s (%T)", t, t) - w.p.indent++ - defer func() { - w.p.indent-- - w.p.trace("=> %s", t) - }() - } - switch t := t.(type) { - case *types.Alias: - if targs := aliases.TypeArgs(t); targs.Len() > 0 { - w.startType(instanceType) - w.pos(t.Obj().Pos()) - w.typeList(targs, pkg) - w.typ(aliases.Origin(t), pkg) - return - } - w.startType(aliasType) - w.qualifiedType(t.Obj()) - - case *types.Named: - if targs := t.TypeArgs(); targs.Len() > 0 { - w.startType(instanceType) - // TODO(rfindley): investigate if this position is correct, and if it - // matters. - w.pos(t.Obj().Pos()) - w.typeList(targs, pkg) - w.typ(t.Origin(), pkg) - return - } - w.startType(definedType) - w.qualifiedType(t.Obj()) - - case *types.TypeParam: - w.startType(typeParamType) - w.qualifiedType(t.Obj()) - - case *types.Pointer: - w.startType(pointerType) - w.typ(t.Elem(), pkg) - - case *types.Slice: - w.startType(sliceType) - w.typ(t.Elem(), pkg) - - case *types.Array: - w.startType(arrayType) - w.uint64(uint64(t.Len())) - w.typ(t.Elem(), pkg) - - case *types.Chan: - w.startType(chanType) - // 1 RecvOnly; 2 SendOnly; 3 SendRecv - var dir uint64 - switch t.Dir() { - case types.RecvOnly: - dir = 1 - case types.SendOnly: - dir = 2 - case types.SendRecv: - dir = 3 - } - w.uint64(dir) - w.typ(t.Elem(), pkg) - - case *types.Map: - w.startType(mapType) - w.typ(t.Key(), pkg) - w.typ(t.Elem(), pkg) - - case *types.Signature: - w.startType(signatureType) - w.pkg(pkg) - w.signature(t) - - case *types.Struct: - w.startType(structType) - n := t.NumFields() - // Even for struct{} we must emit some qualifying package, because that's - // what the compiler does, and thus that's what the importer expects. - fieldPkg := pkg - if n > 0 { - fieldPkg = t.Field(0).Pkg() - } - if fieldPkg == nil { - // TODO(rfindley): improve this very hacky logic. - // - // The importer expects a package to be set for all struct types, even - // those with no fields. A better encoding might be to set NumFields - // before pkg. setPkg panics with a nil package, which may be possible - // to reach with invalid packages (and perhaps valid packages, too?), so - // (arbitrarily) set the localpkg if available. - // - // Alternatively, we may be able to simply guarantee that pkg != nil, by - // reconsidering the encoding of constant values. - if w.p.shallow { - fieldPkg = w.p.localpkg - } else { - panic(internalErrorf("no package to set for empty struct")) - } - } - w.pkg(fieldPkg) - w.uint64(uint64(n)) - - for i := 0; i < n; i++ { - f := t.Field(i) - if w.p.shallow { - w.objectPath(f) - } - w.pos(f.Pos()) - w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg - w.typ(f.Type(), fieldPkg) - w.bool(f.Anonymous()) - w.string(t.Tag(i)) // note (or tag) - } - - case *types.Interface: - w.startType(interfaceType) - w.pkg(pkg) - - n := t.NumEmbeddeds() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - ft := t.EmbeddedType(i) - tPkg := pkg - if named, _ := types.Unalias(ft).(*types.Named); named != nil { - w.pos(named.Obj().Pos()) - } else { - w.pos(token.NoPos) - } - w.typ(ft, tPkg) - } - - // See comment for struct fields. In shallow mode we change the encoding - // for interface methods that are promoted from other packages. - - n = t.NumExplicitMethods() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - m := t.ExplicitMethod(i) - if w.p.shallow { - w.objectPath(m) - } - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - w.signature(sig) - } - - case *types.Union: - w.startType(unionType) - nt := t.Len() - w.uint64(uint64(nt)) - for i := 0; i < nt; i++ { - term := t.Term(i) - w.bool(term.Tilde()) - w.typ(term.Type(), pkg) - } - - default: - panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) - } -} - -// objectPath writes the package and objectPath to use to look up obj in a -// different package, when encoding in "shallow" mode. -// -// When doing a shallow import, the importer creates only the local package, -// and requests package symbols for dependencies from the client. -// However, certain types defined in the local package may hold objects defined -// (perhaps deeply) within another package. -// -// For example, consider the following: -// -// package a -// func F() chan * map[string] struct { X int } -// -// package b -// import "a" -// var B = a.F() -// -// In this example, the type of b.B holds fields defined in package a. -// In order to have the correct canonical objects for the field defined in the -// type of B, they are encoded as objectPaths and later looked up in the -// importer. The same problem applies to interface methods. -func (w *exportWriter) objectPath(obj types.Object) { - if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { - // obj.Pkg() may be nil for the builtin error.Error. - // In this case, or if obj is declared in the local package, no need to - // encode. - w.string("") - return - } - objectPath, err := w.p.objectpathEncoder().For(obj) - if err != nil { - // Fall back to the empty string, which will cause the importer to create a - // new object, which matches earlier behavior. Creating a new object is - // sufficient for many purposes (such as type checking), but causes certain - // references algorithms to fail (golang/go#60819). However, we didn't - // notice this problem during months of gopls@v0.12.0 testing. - // - // TODO(golang/go#61674): this workaround is insufficient, as in the case - // where the field forwarded from an instantiated type that may not appear - // in the export data of the original package: - // - // // package a - // type A[P any] struct{ F P } - // - // // package b - // type B a.A[int] - // - // We need to update references algorithms not to depend on this - // de-duplication, at which point we may want to simply remove the - // workaround here. - w.string("") - return - } - w.string(string(objectPath)) - w.pkg(obj.Pkg()) -} - -func (w *exportWriter) signature(sig *types.Signature) { - w.paramList(sig.Params()) - w.paramList(sig.Results()) - if sig.Params().Len() > 0 { - w.bool(sig.Variadic()) - } -} - -func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { - w.uint64(uint64(ts.Len())) - for i := 0; i < ts.Len(); i++ { - w.typ(ts.At(i), pkg) - } -} - -func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { - ll := uint64(list.Len()) - w.uint64(ll) - for i := 0; i < list.Len(); i++ { - tparam := list.At(i) - // Set the type parameter exportName before exporting its type. - exportName := tparamExportName(prefix, tparam) - w.p.tparamNames[tparam.Obj()] = exportName - w.typ(list.At(i), pkg) - } -} - -const blankMarker = "$" - -// tparamExportName returns the 'exported' name of a type parameter, which -// differs from its actual object name: it is prefixed with a qualifier, and -// blank type parameter names are disambiguated by their index in the type -// parameter list. -func tparamExportName(prefix string, tparam *types.TypeParam) string { - assert(prefix != "") - name := tparam.Obj().Name() - if name == "_" { - name = blankMarker + strconv.Itoa(tparam.Index()) - } - return prefix + "." + name -} - -// tparamName returns the real name of a type parameter, after stripping its -// qualifying prefix and reverting blank-name encoding. See tparamExportName -// for details. -func tparamName(exportName string) string { - // Remove the "path" from the type param name that makes it unique. - ix := strings.LastIndex(exportName, ".") - if ix < 0 { - errorf("malformed type parameter export name %s: missing prefix", exportName) - } - name := exportName[ix+1:] - if strings.HasPrefix(name, blankMarker) { - return "_" - } - return name -} - -func (w *exportWriter) paramList(tup *types.Tuple) { - n := tup.Len() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - w.param(tup.At(i)) - } -} - -func (w *exportWriter) param(obj types.Object) { - w.pos(obj.Pos()) - w.localIdent(obj) - w.typ(obj.Type(), obj.Pkg()) -} - -func (w *exportWriter) value(typ types.Type, v constant.Value) { - w.typ(typ, nil) - if w.p.version >= iexportVersionGo1_18 { - w.int64(int64(v.Kind())) - } - - if v.Kind() == constant.Unknown { - // golang/go#60605: treat unknown constant values as if they have invalid type - // - // This loses some fidelity over the package type-checked from source, but that - // is acceptable. - // - // TODO(rfindley): we should switch on the recorded constant kind rather - // than the constant type - return - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - w.bool(constant.BoolVal(v)) - case types.IsInteger: - var i big.Int - if i64, exact := constant.Int64Val(v); exact { - i.SetInt64(i64) - } else if ui64, exact := constant.Uint64Val(v); exact { - i.SetUint64(ui64) - } else { - i.SetString(v.ExactString(), 10) - } - w.mpint(&i, typ) - case types.IsFloat: - f := constantToFloat(v) - w.mpfloat(f, typ) - case types.IsComplex: - w.mpfloat(constantToFloat(constant.Real(v)), typ) - w.mpfloat(constantToFloat(constant.Imag(v)), typ) - case types.IsString: - w.string(constant.StringVal(v)) - default: - if b.Kind() == types.Invalid { - // package contains type errors - break - } - panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying())) - } -} - -// constantToFloat converts a constant.Value with kind constant.Float to a -// big.Float. -func constantToFloat(x constant.Value) *big.Float { - x = constant.ToFloat(x) - // Use the same floating-point precision (512) as cmd/compile - // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). - const mpprec = 512 - var f big.Float - f.SetPrec(mpprec) - if v, exact := constant.Float64Val(x); exact { - // float64 - f.SetFloat64(v) - } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { - // TODO(gri): add big.Rat accessor to constant.Value. - n := valueToRat(num) - d := valueToRat(denom) - f.SetRat(n.Quo(n, d)) - } else { - // Value too large to represent as a fraction => inaccessible. - // TODO(gri): add big.Float accessor to constant.Value. - _, ok := f.SetString(x.ExactString()) - assert(ok) - } - return &f -} - -func valueToRat(x constant.Value) *big.Rat { - // Convert little-endian to big-endian. - // I can't believe this is necessary. - bytes := constant.Bytes(x) - for i := 0; i < len(bytes)/2; i++ { - bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] - } - return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) -} - -// mpint exports a multi-precision integer. -// -// For unsigned types, small values are written out as a single -// byte. Larger values are written out as a length-prefixed big-endian -// byte string, where the length prefix is encoded as its complement. -// For example, bytes 0, 1, and 2 directly represent the integer -// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, -// 2-, and 3-byte big-endian string follow. -// -// Encoding for signed types use the same general approach as for -// unsigned types, except small values use zig-zag encoding and the -// bottom bit of length prefix byte for large values is reserved as a -// sign bit. -// -// The exact boundary between small and large encodings varies -// according to the maximum number of bytes needed to encode a value -// of type typ. As a special case, 8-bit types are always encoded as a -// single byte. -// -// TODO(mdempsky): Is this level of complexity really worthwhile? -func (w *exportWriter) mpint(x *big.Int, typ types.Type) { - basic, ok := typ.Underlying().(*types.Basic) - if !ok { - panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) - } - - signed, maxBytes := intSize(basic) - - negative := x.Sign() < 0 - if !signed && negative { - panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) - } - - b := x.Bytes() - if len(b) > 0 && b[0] == 0 { - panic(internalErrorf("leading zeros")) - } - if uint(len(b)) > maxBytes { - panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) - } - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - // Check if x can use small value encoding. - if len(b) <= 1 { - var ux uint - if len(b) == 1 { - ux = uint(b[0]) - } - if signed { - ux <<= 1 - if negative { - ux-- - } - } - if ux < maxSmall { - w.data.WriteByte(byte(ux)) - return - } - } - - n := 256 - uint(len(b)) - if signed { - n = 256 - 2*uint(len(b)) - if negative { - n |= 1 - } - } - if n < maxSmall || n >= 256 { - panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) - } - - w.data.WriteByte(byte(n)) - w.data.Write(b) -} - -// mpfloat exports a multi-precision floating point number. -// -// The number's value is decomposed into mantissa × 2**exponent, where -// mantissa is an integer. The value is written out as mantissa (as a -// multi-precision integer) and then the exponent, except exponent is -// omitted if mantissa is zero. -func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { - if f.IsInf() { - panic("infinite constant") - } - - // Break into f = mant × 2**exp, with 0.5 <= mant < 1. - var mant big.Float - exp := int64(f.MantExp(&mant)) - - // Scale so that mant is an integer. - prec := mant.MinPrec() - mant.SetMantExp(&mant, int(prec)) - exp -= int64(prec) - - manti, acc := mant.Int(nil) - if acc != big.Exact { - panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) - } - w.mpint(manti, typ) - if manti.Sign() != 0 { - w.int64(exp) - } -} - -func (w *exportWriter) bool(b bool) bool { - var x uint64 - if b { - x = 1 - } - w.uint64(x) - return b -} - -func (w *exportWriter) int64(x int64) { w.data.int64(x) } -func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } -func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } - -func (w *exportWriter) localIdent(obj types.Object) { - // Anonymous parameters. - if obj == nil { - w.string("") - return - } - - name := obj.Name() - if name == "_" { - w.string("_") - return - } - - w.string(name) -} - -type intWriter struct { - bytes.Buffer -} - -func (w *intWriter) int64(x int64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutVarint(buf[:], x) - w.Write(buf[:n]) -} - -func (w *intWriter) uint64(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - w.Write(buf[:n]) -} - -func assert(cond bool) { - if !cond { - panic("internal error: assertion failed") - } -} - -// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. - -// objQueue is a FIFO queue of types.Object. The zero value of objQueue is -// a ready-to-use empty queue. -type objQueue struct { - ring []types.Object - head, tail int -} - -// empty returns true if q contains no Nodes. -func (q *objQueue) empty() bool { - return q.head == q.tail -} - -// pushTail appends n to the tail of the queue. -func (q *objQueue) pushTail(obj types.Object) { - if len(q.ring) == 0 { - q.ring = make([]types.Object, 16) - } else if q.head+len(q.ring) == q.tail { - // Grow the ring. - nring := make([]types.Object, len(q.ring)*2) - // Copy the old elements. - part := q.ring[q.head%len(q.ring):] - if q.tail-q.head <= len(part) { - part = part[:q.tail-q.head] - copy(nring, part) - } else { - pos := copy(nring, part) - copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) - } - q.ring, q.head, q.tail = nring, 0, q.tail-q.head - } - - q.ring[q.tail%len(q.ring)] = obj - q.tail++ -} - -// popHead pops a node from the head of the queue. It panics if q is empty. -func (q *objQueue) popHead() types.Object { - if q.empty() { - panic("dequeue empty") - } - obj := q.ring[q.head%len(q.ring)] - q.head++ - return obj -} - -// internalError represents an error generated inside this package. -type internalError string - -func (e internalError) Error() string { return "gcimporter: " + string(e) } - -// TODO(adonovan): make this call panic, so that it's symmetric with errorf. -// Otherwise it's easy to forget to do anything with the error. -// -// TODO(adonovan): also, consider switching the names "errorf" and -// "internalErrorf" as the former is used for bugs, whose cause is -// internal inconsistency, whereas the latter is used for ordinary -// situations like bad input, whose cause is external. -func internalErrorf(format string, args ...interface{}) error { - return internalError(fmt.Sprintf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go deleted file mode 100644 index 1294392..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go +++ /dev/null @@ -1,1119 +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. - -// Indexed package import. -// See iexport.go for the export data format. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "sort" - "strings" - - "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/aliases" - "golang.org/x/tools/internal/typesinternal" -) - -type intReader struct { - *bytes.Reader - path string -} - -func (r *intReader) int64() int64 { - i, err := binary.ReadVarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -func (r *intReader) uint64() uint64 { - i, err := binary.ReadUvarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -// Keep this in sync with constants in iexport.go. -const ( - iexportVersionGo1_11 = 0 - iexportVersionPosCol = 1 - iexportVersionGo1_18 = 2 - iexportVersionGenerics = 2 - iexportVersion = iexportVersionGenerics - - iexportVersionCurrent = 2 -) - -type ident struct { - pkg *types.Package - name string -} - -const predeclReserved = 32 - -type itag uint64 - -const ( - // Types - definedType itag = iota - pointerType - sliceType - arrayType - chanType - mapType - signatureType - structType - interfaceType - typeParamType - instanceType - unionType - aliasType -) - -// Object tags -const ( - varTag = 'V' - funcTag = 'F' - genericFuncTag = 'G' - constTag = 'C' - aliasTag = 'A' - genericAliasTag = 'B' - typeParamTag = 'P' - typeTag = 'T' - genericTypeTag = 'U' -) - -// IImportData imports a package from the serialized package data -// and returns 0 and a reference to the package. -// If the export data version is not recognized or the format is otherwise -// compromised, an error is returned. -func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) { - pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil) - if err != nil { - return 0, nil, err - } - return 0, pkgs[0], nil -} - -// IImportBundle imports a set of packages from the serialized package bundle. -func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { - return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil) -} - -// A GetPackagesFunc function obtains the non-nil symbols for a set of -// packages, creating and recursively importing them as needed. An -// implementation should store each package symbol is in the Pkg -// field of the items array. -// -// Any error causes importing to fail. This can be used to quickly read -// the import manifest of an export data file without fully decoding it. -type GetPackagesFunc = func(items []GetPackagesItem) error - -// A GetPackagesItem is a request from the importer for the package -// symbol of the specified name and path. -type GetPackagesItem struct { - Name, Path string - Pkg *types.Package // to be filled in by GetPackagesFunc call - - // private importer state - pathOffset uint64 - nameIndex map[string]uint64 -} - -// GetPackagesFromMap returns a GetPackagesFunc that retrieves -// packages from the given map of package path to package. -// -// The returned function may mutate m: each requested package that is not -// found is created with types.NewPackage and inserted into m. -func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { - return func(items []GetPackagesItem) error { - for i, item := range items { - pkg, ok := m[item.Path] - if !ok { - pkg = types.NewPackage(item.Path, item.Name) - m[item.Path] = pkg - } - items[i].Pkg = pkg - } - return nil - } -} - -func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { - const currentVersion = iexportVersionCurrent - version := int64(-1) - if !debug { - defer func() { - if e := recover(); e != nil { - if bundle { - err = fmt.Errorf("%v", e) - } else if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) - } - } - }() - } - - r := &intReader{bytes.NewReader(data), path} - - if bundle { - if v := r.uint64(); v != bundleVersion { - errorf("unknown bundle format version %d", v) - } - } - - version = int64(r.uint64()) - switch version { - case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: - default: - if version > iexportVersionGo1_18 { - errorf("unstable iexport format version %d, just rebuild compiler and std library", version) - } else { - errorf("unknown iexport format version %d", version) - } - } - - sLen := int64(r.uint64()) - var fLen int64 - var fileOffset []uint64 - if shallow { - // Shallow mode uses a different position encoding. - fLen = int64(r.uint64()) - fileOffset = make([]uint64, r.uint64()) - for i := range fileOffset { - fileOffset[i] = r.uint64() - } - } - dLen := int64(r.uint64()) - - whence, _ := r.Seek(0, io.SeekCurrent) - stringData := data[whence : whence+sLen] - fileData := data[whence+sLen : whence+sLen+fLen] - declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] - r.Seek(sLen+fLen+dLen, io.SeekCurrent) - - p := iimporter{ - version: int(version), - ipath: path, - aliases: aliases.Enabled(), - shallow: shallow, - reportf: reportf, - - stringData: stringData, - stringCache: make(map[uint64]string), - fileOffset: fileOffset, - fileData: fileData, - fileCache: make([]*token.File, len(fileOffset)), - pkgCache: make(map[uint64]*types.Package), - - declData: declData, - pkgIndex: make(map[*types.Package]map[string]uint64), - typCache: make(map[uint64]types.Type), - // Separate map for typeparams, keyed by their package and unique - // name. - tparamIndex: make(map[ident]types.Type), - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - } - defer p.fake.setLines() // set lines for files in fset - - for i, pt := range predeclared() { - p.typCache[uint64(i)] = pt - } - - // Gather the relevant packages from the manifest. - items := make([]GetPackagesItem, r.uint64()) - uniquePkgPaths := make(map[string]bool) - for i := range items { - pkgPathOff := r.uint64() - pkgPath := p.stringAt(pkgPathOff) - pkgName := p.stringAt(r.uint64()) - _ = r.uint64() // package height; unused by go/types - - if pkgPath == "" { - pkgPath = path - } - items[i].Name = pkgName - items[i].Path = pkgPath - items[i].pathOffset = pkgPathOff - - // Read index for package. - nameIndex := make(map[string]uint64) - nSyms := r.uint64() - // In shallow mode, only the current package (i=0) has an index. - assert(!(shallow && i > 0 && nSyms != 0)) - for ; nSyms > 0; nSyms-- { - name := p.stringAt(r.uint64()) - nameIndex[name] = r.uint64() - } - - items[i].nameIndex = nameIndex - - uniquePkgPaths[pkgPath] = true - } - // Debugging #63822; hypothesis: there are duplicate PkgPaths. - if len(uniquePkgPaths) != len(items) { - reportf("found duplicate PkgPaths while reading export data manifest: %v", items) - } - - // Request packages all at once from the client, - // enabling a parallel implementation. - if err := getPackages(items); err != nil { - return nil, err // don't wrap this error - } - - // Check the results and complete the index. - pkgList := make([]*types.Package, len(items)) - for i, item := range items { - pkg := item.Pkg - if pkg == nil { - errorf("internal error: getPackages returned nil package for %q", item.Path) - } else if pkg.Path() != item.Path { - errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) - } else if pkg.Name() != item.Name { - errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) - } - p.pkgCache[item.pathOffset] = pkg - p.pkgIndex[pkg] = item.nameIndex - pkgList[i] = pkg - } - - if bundle { - pkgs = make([]*types.Package, r.uint64()) - for i := range pkgs { - pkg := p.pkgAt(r.uint64()) - imps := make([]*types.Package, r.uint64()) - for j := range imps { - imps[j] = p.pkgAt(r.uint64()) - } - pkg.SetImports(imps) - pkgs[i] = pkg - } - } else { - if len(pkgList) == 0 { - errorf("no packages found for %s", path) - panic("unreachable") - } - pkgs = pkgList[:1] - - // record all referenced packages as imports - list := append(([]*types.Package)(nil), pkgList[1:]...) - sort.Sort(byPath(list)) - pkgs[0].SetImports(list) - } - - for _, pkg := range pkgs { - if pkg.Complete() { - continue - } - - names := make([]string, 0, len(p.pkgIndex[pkg])) - for name := range p.pkgIndex[pkg] { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - p.doDecl(pkg, name) - } - - // package was imported completely and without errors - pkg.MarkComplete() - } - - // SetConstraint can't be called if the constraint type is not yet complete. - // When type params are created in the typeParamTag case of (*importReader).obj(), - // the associated constraint type may not be complete due to recursion. - // Therefore, we defer calling SetConstraint there, and call it here instead - // after all types are complete. - for _, d := range p.later { - d.t.SetConstraint(d.constraint) - } - - for _, typ := range p.interfaceList { - typ.Complete() - } - - // Workaround for golang/go#61561. See the doc for instanceList for details. - for _, typ := range p.instanceList { - if iface, _ := typ.Underlying().(*types.Interface); iface != nil { - iface.Complete() - } - } - - return pkgs, nil -} - -type setConstraintArgs struct { - t *types.TypeParam - constraint types.Type -} - -type iimporter struct { - version int - ipath string - - aliases bool - shallow bool - reportf ReportFunc // if non-nil, used to report bugs - - stringData []byte - stringCache map[uint64]string - fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i - fileData []byte - fileCache []*token.File // memoized decoding of file encoded as i - pkgCache map[uint64]*types.Package - - declData []byte - pkgIndex map[*types.Package]map[string]uint64 - typCache map[uint64]types.Type - tparamIndex map[ident]types.Type - - fake fakeFileSet - interfaceList []*types.Interface - - // Workaround for the go/types bug golang/go#61561: instances produced during - // instantiation may contain incomplete interfaces. Here we only complete the - // underlying type of the instance, which is the most common case but doesn't - // handle parameterized interface literals defined deeper in the type. - instanceList []types.Type // instances for later completion (see golang/go#61561) - - // Arguments for calls to SetConstraint that are deferred due to recursive types - later []setConstraintArgs - - indent int // for tracing support -} - -func (p *iimporter) trace(format string, args ...interface{}) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -func (p *iimporter) doDecl(pkg *types.Package, name string) { - if debug { - p.trace("import decl %s", name) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", name) - }() - } - // See if we've already imported this declaration. - if obj := pkg.Scope().Lookup(name); obj != nil { - return - } - - off, ok := p.pkgIndex[pkg][name] - if !ok { - // In deep mode, the index should be complete. In shallow - // mode, we should have already recursively loaded necessary - // dependencies so the above Lookup succeeds. - errorf("%v.%v not in index", pkg, name) - } - - r := &importReader{p: p, currPkg: pkg} - r.declReader.Reset(p.declData[off:]) - - r.obj(name) -} - -func (p *iimporter) stringAt(off uint64) string { - if s, ok := p.stringCache[off]; ok { - return s - } - - slen, n := binary.Uvarint(p.stringData[off:]) - if n <= 0 { - errorf("varint failed") - } - spos := off + uint64(n) - s := string(p.stringData[spos : spos+slen]) - p.stringCache[off] = s - return s -} - -func (p *iimporter) fileAt(index uint64) *token.File { - file := p.fileCache[index] - if file == nil { - off := p.fileOffset[index] - file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) - p.fileCache[index] = file - } - return file -} - -func (p *iimporter) decodeFile(rd intReader) *token.File { - filename := p.stringAt(rd.uint64()) - size := int(rd.uint64()) - file := p.fake.fset.AddFile(filename, -1, size) - - // SetLines requires a nondecreasing sequence. - // Because it is common for clients to derive the interval - // [start, start+len(name)] from a start position, and we - // want to ensure that the end offset is on the same line, - // we fill in the gaps of the sparse encoding with values - // that strictly increase by the largest possible amount. - // This allows us to avoid having to record the actual end - // offset of each needed line. - - lines := make([]int, int(rd.uint64())) - var index, offset int - for i, n := 0, int(rd.uint64()); i < n; i++ { - index += int(rd.uint64()) - offset += int(rd.uint64()) - lines[index] = offset - - // Ensure monotonicity between points. - for j := index - 1; j > 0 && lines[j] == 0; j-- { - lines[j] = lines[j+1] - 1 - } - } - - // Ensure monotonicity after last point. - for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { - size-- - lines[j] = size - } - - if !file.SetLines(lines) { - errorf("SetLines failed: %d", lines) // can't happen - } - return file -} - -func (p *iimporter) pkgAt(off uint64) *types.Package { - if pkg, ok := p.pkgCache[off]; ok { - return pkg - } - path := p.stringAt(off) - errorf("missing package %q in %q", path, p.ipath) - return nil -} - -func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && canReuse(base, t) { - return t - } - - if off < predeclReserved { - errorf("predeclared type missing from cache: %v", off) - } - - r := &importReader{p: p} - r.declReader.Reset(p.declData[off-predeclReserved:]) - t := r.doType(base) - - if canReuse(base, t) { - p.typCache[off] = t - } - return t -} - -// canReuse reports whether the type rhs on the RHS of the declaration for def -// may be re-used. -// -// Specifically, if def is non-nil and rhs is an interface type with methods, it -// may not be re-used because we have a convention of setting the receiver type -// for interface methods to def. -func canReuse(def *types.Named, rhs types.Type) bool { - if def == nil { - return true - } - iface, _ := types.Unalias(rhs).(*types.Interface) - if iface == nil { - return true - } - // Don't use iface.Empty() here as iface may not be complete. - return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 -} - -type importReader struct { - p *iimporter - declReader bytes.Reader - currPkg *types.Package - prevFile string - prevLine int64 - prevColumn int64 -} - -// markBlack is redefined in iimport_go123.go, to work around golang/go#69912. -// -// If TypeNames are not marked black (in the sense of go/types cycle -// detection), they may be mutated when dot-imported. Fix this by punching a -// hole through the type, when compiling with Go 1.23. (The bug has been fixed -// for 1.24, but the fix was not worth back-porting). -var markBlack = func(name *types.TypeName) {} - -func (r *importReader) obj(name string) { - tag := r.byte() - pos := r.pos() - - switch tag { - case aliasTag, genericAliasTag: - var tparams []*types.TypeParam - if tag == genericAliasTag { - tparams = r.tparamList() - } - typ := r.typ() - obj := aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ, tparams) - markBlack(obj) // workaround for golang/go#69912 - r.declare(obj) - - case constTag: - typ, val := r.value() - - r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) - - case funcTag, genericFuncTag: - var tparams []*types.TypeParam - if tag == genericFuncTag { - tparams = r.tparamList() - } - sig := r.signature(nil, nil, tparams) - r.declare(types.NewFunc(pos, r.currPkg, name, sig)) - - case typeTag, genericTypeTag: - // Types can be recursive. We need to setup a stub - // declaration before recursing. - obj := types.NewTypeName(pos, r.currPkg, name, nil) - named := types.NewNamed(obj, nil, nil) - - markBlack(obj) // workaround for golang/go#69912 - - // Declare obj before calling r.tparamList, so the new type name is recognized - // if used in the constraint of one of its own typeparams (see #48280). - r.declare(obj) - if tag == genericTypeTag { - tparams := r.tparamList() - named.SetTypeParams(tparams) - } - - underlying := r.p.typAt(r.uint64(), named).Underlying() - named.SetUnderlying(underlying) - - if !isInterface(underlying) { - for n := r.uint64(); n > 0; n-- { - mpos := r.pos() - mname := r.ident() - recv := r.param() - - // If the receiver has any targs, set those as the - // rparams of the method (since those are the - // typeparams being used in the method sig/body). - _, recvNamed := typesinternal.ReceiverNamed(recv) - targs := recvNamed.TypeArgs() - var rparams []*types.TypeParam - if targs.Len() > 0 { - rparams = make([]*types.TypeParam, targs.Len()) - for i := range rparams { - rparams[i] = types.Unalias(targs.At(i)).(*types.TypeParam) - } - } - msig := r.signature(recv, rparams, nil) - - named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) - } - } - - case typeParamTag: - // We need to "declare" a typeparam in order to have a name that - // can be referenced recursively (if needed) in the type param's - // bound. - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - name0 := tparamName(name) - tn := types.NewTypeName(pos, r.currPkg, name0, nil) - t := types.NewTypeParam(tn, nil) - - // To handle recursive references to the typeparam within its - // bound, save the partial type in tparamIndex before reading the bounds. - id := ident{r.currPkg, name} - r.p.tparamIndex[id] = t - var implicit bool - if r.p.version >= iexportVersionGo1_18 { - implicit = r.bool() - } - constraint := r.typ() - if implicit { - iface, _ := types.Unalias(constraint).(*types.Interface) - if iface == nil { - errorf("non-interface constraint marked implicit") - } - iface.MarkImplicit() - } - // The constraint type may not be complete, if we - // are in the middle of a type recursion involving type - // constraints. So, we defer SetConstraint until we have - // completely set up all types in ImportData. - r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) - - case varTag: - typ := r.typ() - - v := types.NewVar(pos, r.currPkg, name, typ) - typesinternal.SetVarKind(v, typesinternal.PackageVar) - r.declare(v) - - default: - errorf("unexpected tag: %v", tag) - } -} - -func (r *importReader) declare(obj types.Object) { - obj.Pkg().Scope().Insert(obj) -} - -func (r *importReader) value() (typ types.Type, val constant.Value) { - typ = r.typ() - if r.p.version >= iexportVersionGo1_18 { - // TODO: add support for using the kind. - _ = constant.Kind(r.int64()) - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - val = constant.MakeBool(r.bool()) - - case types.IsString: - val = constant.MakeString(r.string()) - - case types.IsInteger: - var x big.Int - r.mpint(&x, b) - val = constant.Make(&x) - - case types.IsFloat: - val = r.mpfloat(b) - - case types.IsComplex: - re := r.mpfloat(b) - im := r.mpfloat(b) - val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - - default: - if b.Kind() == types.Invalid { - val = constant.MakeUnknown() - return - } - errorf("unexpected type %v", typ) // panics - panic("unreachable") - } - - return -} - -func intSize(b *types.Basic) (signed bool, maxBytes uint) { - if (b.Info() & types.IsUntyped) != 0 { - return true, 64 - } - - switch b.Kind() { - case types.Float32, types.Complex64: - return true, 3 - case types.Float64, types.Complex128: - return true, 7 - } - - signed = (b.Info() & types.IsUnsigned) == 0 - switch b.Kind() { - case types.Int8, types.Uint8: - maxBytes = 1 - case types.Int16, types.Uint16: - maxBytes = 2 - case types.Int32, types.Uint32: - maxBytes = 4 - default: - maxBytes = 8 - } - - return -} - -func (r *importReader) mpint(x *big.Int, typ *types.Basic) { - signed, maxBytes := intSize(typ) - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - n, _ := r.declReader.ReadByte() - if uint(n) < maxSmall { - v := int64(n) - if signed { - v >>= 1 - if n&1 != 0 { - v = ^v - } - } - x.SetInt64(v) - return - } - - v := -n - if signed { - v = -(n &^ 1) >> 1 - } - if v < 1 || uint(v) > maxBytes { - errorf("weird decoding: %v, %v => %v", n, signed, v) - } - b := make([]byte, v) - io.ReadFull(&r.declReader, b) - x.SetBytes(b) - if signed && n&1 != 0 { - x.Neg(x) - } -} - -func (r *importReader) mpfloat(typ *types.Basic) constant.Value { - var mant big.Int - r.mpint(&mant, typ) - var f big.Float - f.SetInt(&mant) - if f.Sign() != 0 { - f.SetMantExp(&f, int(r.int64())) - } - return constant.Make(&f) -} - -func (r *importReader) ident() string { - return r.string() -} - -func (r *importReader) qualifiedIdent() (*types.Package, string) { - name := r.string() - pkg := r.pkg() - return pkg, name -} - -func (r *importReader) pos() token.Pos { - if r.p.shallow { - // precise offsets are encoded only in shallow mode - return r.posv2() - } - if r.p.version >= iexportVersionPosCol { - r.posv1() - } else { - r.posv0() - } - - if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { - return token.NoPos - } - return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) -} - -func (r *importReader) posv0() { - delta := r.int64() - if delta != deltaNewFile { - r.prevLine += delta - } else if l := r.int64(); l == -1 { - r.prevLine += deltaNewFile - } else { - r.prevFile = r.string() - r.prevLine = l - } -} - -func (r *importReader) posv1() { - delta := r.int64() - r.prevColumn += delta >> 1 - if delta&1 != 0 { - delta = r.int64() - r.prevLine += delta >> 1 - if delta&1 != 0 { - r.prevFile = r.string() - } - } -} - -func (r *importReader) posv2() token.Pos { - file := r.uint64() - if file == 0 { - return token.NoPos - } - tf := r.p.fileAt(file - 1) - return tf.Pos(int(r.uint64())) -} - -func (r *importReader) typ() types.Type { - return r.p.typAt(r.uint64(), nil) -} - -func isInterface(t types.Type) bool { - _, ok := types.Unalias(t).(*types.Interface) - return ok -} - -func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } -func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } - -func (r *importReader) doType(base *types.Named) (res types.Type) { - k := r.kind() - if debug { - r.p.trace("importing type %d (base: %v)", k, base) - r.p.indent++ - defer func() { - r.p.indent-- - r.p.trace("=> %s", res) - }() - } - switch k { - default: - errorf("unexpected kind tag in %q: %v", r.p.ipath, k) - return nil - - case aliasType, definedType: - pkg, name := r.qualifiedIdent() - r.p.doDecl(pkg, name) - return pkg.Scope().Lookup(name).(*types.TypeName).Type() - case pointerType: - return types.NewPointer(r.typ()) - case sliceType: - return types.NewSlice(r.typ()) - case arrayType: - n := r.uint64() - return types.NewArray(r.typ(), int64(n)) - case chanType: - dir := chanDir(int(r.uint64())) - return types.NewChan(dir, r.typ()) - case mapType: - return types.NewMap(r.typ(), r.typ()) - case signatureType: - r.currPkg = r.pkg() - return r.signature(nil, nil, nil) - - case structType: - r.currPkg = r.pkg() - - fields := make([]*types.Var, r.uint64()) - tags := make([]string, len(fields)) - for i := range fields { - var field *types.Var - if r.p.shallow { - field, _ = r.objectPathObject().(*types.Var) - } - - fpos := r.pos() - fname := r.ident() - ftyp := r.typ() - emb := r.bool() - tag := r.string() - - // Either this is not a shallow import, the field is local, or the - // encoded objectPath failed to produce an object (a bug). - // - // Even in this last, buggy case, fall back on creating a new field. As - // discussed in iexport.go, this is not correct, but mostly works and is - // preferable to failing (for now at least). - if field == nil { - field = types.NewField(fpos, r.currPkg, fname, ftyp, emb) - } - - fields[i] = field - tags[i] = tag - } - return types.NewStruct(fields, tags) - - case interfaceType: - r.currPkg = r.pkg() - - embeddeds := make([]types.Type, r.uint64()) - for i := range embeddeds { - _ = r.pos() - embeddeds[i] = r.typ() - } - - methods := make([]*types.Func, r.uint64()) - for i := range methods { - var method *types.Func - if r.p.shallow { - method, _ = r.objectPathObject().(*types.Func) - } - - mpos := r.pos() - mname := r.ident() - - // TODO(mdempsky): Matches bimport.go, but I - // don't agree with this. - var recv *types.Var - if base != nil { - recv = types.NewVar(token.NoPos, r.currPkg, "", base) - } - msig := r.signature(recv, nil, nil) - - if method == nil { - method = types.NewFunc(mpos, r.currPkg, mname, msig) - } - methods[i] = method - } - - typ := types.NewInterfaceType(methods, embeddeds) - r.p.interfaceList = append(r.p.interfaceList, typ) - return typ - - case typeParamType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - pkg, name := r.qualifiedIdent() - id := ident{pkg, name} - if t, ok := r.p.tparamIndex[id]; ok { - // We're already in the process of importing this typeparam. - return t - } - // Otherwise, import the definition of the typeparam now. - r.p.doDecl(pkg, name) - return r.p.tparamIndex[id] - - case instanceType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - // pos does not matter for instances: they are positioned on the original - // type. - _ = r.pos() - len := r.uint64() - targs := make([]types.Type, len) - for i := range targs { - targs[i] = r.typ() - } - baseType := r.typ() - // The imported instantiated type doesn't include any methods, so - // we must always use the methods of the base (orig) type. - // TODO provide a non-nil *Environment - t, _ := types.Instantiate(nil, baseType, targs, false) - - // Workaround for golang/go#61561. See the doc for instanceList for details. - r.p.instanceList = append(r.p.instanceList, t) - return t - - case unionType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - terms := make([]*types.Term, r.uint64()) - for i := range terms { - terms[i] = types.NewTerm(r.bool(), r.typ()) - } - return types.NewUnion(terms) - } -} - -func (r *importReader) kind() itag { - return itag(r.uint64()) -} - -// objectPathObject is the inverse of exportWriter.objectPath. -// -// In shallow mode, certain fields and methods may need to be looked up in an -// imported package. See the doc for exportWriter.objectPath for a full -// explanation. -func (r *importReader) objectPathObject() types.Object { - objPath := objectpath.Path(r.string()) - if objPath == "" { - return nil - } - pkg := r.pkg() - obj, err := objectpath.Object(pkg, objPath) - if err != nil { - if r.p.reportf != nil { - r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) - } - } - return obj -} - -func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { - params := r.paramList() - results := r.paramList() - variadic := params.Len() > 0 && r.bool() - return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) -} - -func (r *importReader) tparamList() []*types.TypeParam { - n := r.uint64() - if n == 0 { - return nil - } - xs := make([]*types.TypeParam, n) - for i := range xs { - // Note: the standard library importer is tolerant of nil types here, - // though would panic in SetTypeParams. - xs[i] = types.Unalias(r.typ()).(*types.TypeParam) - } - return xs -} - -func (r *importReader) paramList() *types.Tuple { - xs := make([]*types.Var, r.uint64()) - for i := range xs { - xs[i] = r.param() - } - return types.NewTuple(xs...) -} - -func (r *importReader) param() *types.Var { - pos := r.pos() - name := r.ident() - typ := r.typ() - return types.NewParam(pos, r.currPkg, name, typ) -} - -func (r *importReader) bool() bool { - return r.uint64() != 0 -} - -func (r *importReader) int64() int64 { - n, err := binary.ReadVarint(&r.declReader) - if err != nil { - errorf("readVarint: %v", err) - } - return n -} - -func (r *importReader) uint64() uint64 { - n, err := binary.ReadUvarint(&r.declReader) - if err != nil { - errorf("readUvarint: %v", err) - } - return n -} - -func (r *importReader) byte() byte { - x, err := r.declReader.ReadByte() - if err != nil { - errorf("declReader.ReadByte: %v", err) - } - return x -} - -type byPath []*types.Package - -func (a byPath) Len() int { return len(a) } -func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go deleted file mode 100644 index 7586bfa..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 The Go 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.22 && !go1.24 - -package gcimporter - -import ( - "go/token" - "go/types" - "unsafe" -) - -// TODO(rfindley): delete this workaround once go1.24 is assured. - -func init() { - // Update markBlack so that it correctly sets the color - // of imported TypeNames. - // - // See the doc comment for markBlack for details. - - type color uint32 - const ( - white color = iota - black - grey - ) - type object struct { - _ *types.Scope - _ token.Pos - _ *types.Package - _ string - _ types.Type - _ uint32 - color_ color - _ token.Pos - } - type typeName struct { - object - } - - // If the size of types.TypeName changes, this will fail to compile. - const delta = int64(unsafe.Sizeof(typeName{})) - int64(unsafe.Sizeof(types.TypeName{})) - var _ [-delta * delta]int - - markBlack = func(obj *types.TypeName) { - type uP = unsafe.Pointer - var ptr *typeName - *(*uP)(uP(&ptr)) = uP(obj) - ptr.color_ = black - } -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go b/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go deleted file mode 100644 index 907c855..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2024 The Go 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 gcimporter - -import ( - "go/types" - "sync" -) - -// predecl is a cache for the predeclared types in types.Universe. -// -// Cache a distinct result based on the runtime value of any. -// The pointer value of the any type varies based on GODEBUG settings. -var predeclMu sync.Mutex -var predecl map[types.Type][]types.Type - -func predeclared() []types.Type { - anyt := types.Universe.Lookup("any").Type() - - predeclMu.Lock() - defer predeclMu.Unlock() - - if pre, ok := predecl[anyt]; ok { - return pre - } - - if predecl == nil { - predecl = make(map[types.Type][]types.Type) - } - - decls := []types.Type{ // basic types - types.Typ[types.Bool], - types.Typ[types.Int], - types.Typ[types.Int8], - types.Typ[types.Int16], - types.Typ[types.Int32], - types.Typ[types.Int64], - types.Typ[types.Uint], - types.Typ[types.Uint8], - types.Typ[types.Uint16], - types.Typ[types.Uint32], - types.Typ[types.Uint64], - types.Typ[types.Uintptr], - types.Typ[types.Float32], - types.Typ[types.Float64], - types.Typ[types.Complex64], - types.Typ[types.Complex128], - types.Typ[types.String], - - // basic type aliases - types.Universe.Lookup("byte").Type(), - types.Universe.Lookup("rune").Type(), - - // error - types.Universe.Lookup("error").Type(), - - // untyped types - types.Typ[types.UntypedBool], - types.Typ[types.UntypedInt], - types.Typ[types.UntypedRune], - types.Typ[types.UntypedFloat], - types.Typ[types.UntypedComplex], - types.Typ[types.UntypedString], - types.Typ[types.UntypedNil], - - // package unsafe - types.Typ[types.UnsafePointer], - - // invalid type - types.Typ[types.Invalid], // only appears in packages with errors - - // used internally by gc; never used by this package or in .a files - anyType{}, - - // comparable - types.Universe.Lookup("comparable").Type(), - - // any - anyt, - } - - predecl[anyt] = decls - return decls -} - -type anyType struct{} - -func (t anyType) Underlying() types.Type { return t } -func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support.go b/vendor/golang.org/x/tools/internal/gcimporter/support.go deleted file mode 100644 index 4af810d..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/support.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 The Go 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 gcimporter - -import ( - "bufio" - "io" - "strconv" - "strings" -) - -// Copy of $GOROOT/src/cmd/internal/archive.ReadHeader. -func readArchiveHeader(b *bufio.Reader, name string) int { - // architecture-independent object file output - const HeaderSize = 60 - - var buf [HeaderSize]byte - if _, err := io.ReadFull(b, buf[:]); err != nil { - return -1 - } - aname := strings.Trim(string(buf[0:16]), " ") - if !strings.HasPrefix(aname, name) { - return -1 - } - asize := strings.Trim(string(buf[48:58]), " ") - i, _ := strconv.Atoi(asize) - return i -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go deleted file mode 100644 index 522287d..0000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go +++ /dev/null @@ -1,761 +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. - -// Derived from go/internal/gcimporter/ureader.go - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sort" - - "golang.org/x/tools/internal/aliases" - "golang.org/x/tools/internal/pkgbits" - "golang.org/x/tools/internal/typesinternal" -) - -// A pkgReader holds the shared state for reading a unified IR package -// description. -type pkgReader struct { - pkgbits.PkgDecoder - - fake fakeFileSet - - ctxt *types.Context - imports map[string]*types.Package // previously imported packages, indexed by path - aliases bool // create types.Alias nodes - - // lazily initialized arrays corresponding to the unified IR - // PosBase, Pkg, and Type sections, respectively. - posBases []string // position bases (i.e., file names) - pkgs []*types.Package - typs []types.Type - - // laterFns holds functions that need to be invoked at the end of - // import reading. - laterFns []func() - // laterFors is used in case of 'type A B' to ensure that B is processed before A. - laterFors map[types.Type]int - - // ifaces holds a list of constructed Interfaces, which need to have - // Complete called after importing is done. - ifaces []*types.Interface -} - -// later adds a function to be invoked at the end of import reading. -func (pr *pkgReader) later(fn func()) { - pr.laterFns = append(pr.laterFns, fn) -} - -// See cmd/compile/internal/noder.derivedInfo. -type derivedInfo struct { - idx pkgbits.Index -} - -// See cmd/compile/internal/noder.typeInfo. -type typeInfo struct { - idx pkgbits.Index - derived bool -} - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - if !debug { - defer func() { - if x := recover(); x != nil { - err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) - } - }() - } - - s := string(data) - input := pkgbits.NewPkgDecoder(path, s) - pkg = readUnifiedPackage(fset, nil, imports, input) - return -} - -// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. -func (pr *pkgReader) laterFor(t types.Type, fn func()) { - if pr.laterFors == nil { - pr.laterFors = make(map[types.Type]int) - } - pr.laterFors[t] = len(pr.laterFns) - pr.laterFns = append(pr.laterFns, fn) -} - -// readUnifiedPackage reads a package description from the given -// unified IR export data decoder. -func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { - pr := pkgReader{ - PkgDecoder: input, - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - - ctxt: ctxt, - imports: imports, - aliases: aliases.Enabled(), - - posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), - pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), - typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), - } - defer pr.fake.setLines() - - r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) - pkg := r.pkg() - if r.Version().Has(pkgbits.HasInit) { - r.Bool() - } - - for i, n := 0, r.Len(); i < n; i++ { - // As if r.obj(), but avoiding the Scope.Lookup call, - // to avoid eager loading of imports. - r.Sync(pkgbits.SyncObject) - if r.Version().Has(pkgbits.DerivedFuncInstance) { - assert(!r.Bool()) - } - r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - assert(r.Len() == 0) - } - - r.Sync(pkgbits.SyncEOF) - - for _, fn := range pr.laterFns { - fn() - } - - for _, iface := range pr.ifaces { - iface.Complete() - } - - // Imports() of pkg are all of the transitive packages that were loaded. - var imps []*types.Package - for _, imp := range pr.pkgs { - if imp != nil && imp != pkg { - imps = append(imps, imp) - } - } - sort.Sort(byPath(imps)) - pkg.SetImports(imps) - - pkg.MarkComplete() - return pkg -} - -// A reader holds the state for reading a single unified IR element -// within a package. -type reader struct { - pkgbits.Decoder - - p *pkgReader - - dict *readerDict -} - -// A readerDict holds the state for type parameters that parameterize -// the current unified IR element. -type readerDict struct { - // bounds is a slice of typeInfos corresponding to the underlying - // bounds of the element's type parameters. - bounds []typeInfo - - // tparams is a slice of the constructed TypeParams for the element. - tparams []*types.TypeParam - - // derived is a slice of types derived from tparams, which may be - // instantiated while reading the current element. - derived []derivedInfo - derivedTypes []types.Type // lazily instantiated from derived -} - -func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.NewDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.TempDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) retireReader(r *reader) { - pr.RetireDecoder(&r.Decoder) -} - -// @@@ Positions - -func (r *reader) pos() token.Pos { - r.Sync(pkgbits.SyncPos) - if !r.Bool() { - return token.NoPos - } - - // TODO(mdempsky): Delta encoding. - posBase := r.posBase() - line := r.Uint() - col := r.Uint() - return r.p.fake.pos(posBase, int(line), int(col)) -} - -func (r *reader) posBase() string { - return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) -} - -func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { - if b := pr.posBases[idx]; b != "" { - return b - } - - var filename string - { - r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) - - // Within types2, position bases have a lot more details (e.g., - // keeping track of where //line directives appeared exactly). - // - // For go/types, we just track the file name. - - filename = r.String() - - if r.Bool() { // file base - // Was: "b = token.NewTrimmedFileBase(filename, true)" - } else { // line base - pos := r.pos() - line := r.Uint() - col := r.Uint() - - // Was: "b = token.NewLineBase(pos, filename, true, line, col)" - _, _, _ = pos, line, col - } - pr.retireReader(r) - } - b := filename - pr.posBases[idx] = b - return b -} - -// @@@ Packages - -func (r *reader) pkg() *types.Package { - r.Sync(pkgbits.SyncPkg) - return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) -} - -func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { - // TODO(mdempsky): Consider using some non-nil pointer to indicate - // the universe scope, so we don't need to keep re-reading it. - if pkg := pr.pkgs[idx]; pkg != nil { - return pkg - } - - pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() - pr.pkgs[idx] = pkg - return pkg -} - -func (r *reader) doPkg() *types.Package { - path := r.String() - switch path { - // cmd/compile emits path="main" for main packages because - // that's the linker symbol prefix it used; but we need - // the package's path as it would be reported by go list, - // hence "main" below. - // See test at go/packages.TestMainPackagePathInModeTypes. - case "", "main": - path = r.p.PkgPath() - case "builtin": - return nil // universe - case "unsafe": - return types.Unsafe - } - - if pkg := r.p.imports[path]; pkg != nil { - return pkg - } - - name := r.String() - - pkg := types.NewPackage(path, name) - r.p.imports[path] = pkg - - return pkg -} - -// @@@ Types - -func (r *reader) typ() types.Type { - return r.p.typIdx(r.typInfo(), r.dict) -} - -func (r *reader) typInfo() typeInfo { - r.Sync(pkgbits.SyncType) - if r.Bool() { - return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} - } - return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} -} - -func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { - idx := info.idx - var where *types.Type - if info.derived { - where = &dict.derivedTypes[idx] - idx = dict.derived[idx].idx - } else { - where = &pr.typs[idx] - } - - if typ := *where; typ != nil { - return typ - } - - var typ types.Type - { - r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) - r.dict = dict - - typ = r.doTyp() - assert(typ != nil) - pr.retireReader(r) - } - // See comment in pkgReader.typIdx explaining how this happens. - if prev := *where; prev != nil { - return prev - } - - *where = typ - return typ -} - -func (r *reader) doTyp() (res types.Type) { - switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { - default: - errorf("unhandled type tag: %v", tag) - panic("unreachable") - - case pkgbits.TypeBasic: - return types.Typ[r.Len()] - - case pkgbits.TypeNamed: - obj, targs := r.obj() - name := obj.(*types.TypeName) - if len(targs) != 0 { - t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) - return t - } - return name.Type() - - case pkgbits.TypeTypeParam: - return r.dict.tparams[r.Len()] - - case pkgbits.TypeArray: - len := int64(r.Uint64()) - return types.NewArray(r.typ(), len) - case pkgbits.TypeChan: - dir := types.ChanDir(r.Len()) - return types.NewChan(dir, r.typ()) - case pkgbits.TypeMap: - return types.NewMap(r.typ(), r.typ()) - case pkgbits.TypePointer: - return types.NewPointer(r.typ()) - case pkgbits.TypeSignature: - return r.signature(nil, nil, nil) - case pkgbits.TypeSlice: - return types.NewSlice(r.typ()) - case pkgbits.TypeStruct: - return r.structType() - case pkgbits.TypeInterface: - return r.interfaceType() - case pkgbits.TypeUnion: - return r.unionType() - } -} - -func (r *reader) structType() *types.Struct { - fields := make([]*types.Var, r.Len()) - var tags []string - for i := range fields { - pos := r.pos() - pkg, name := r.selector() - ftyp := r.typ() - tag := r.String() - embedded := r.Bool() - - fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) - if tag != "" { - for len(tags) < i { - tags = append(tags, "") - } - tags = append(tags, tag) - } - } - return types.NewStruct(fields, tags) -} - -func (r *reader) unionType() *types.Union { - terms := make([]*types.Term, r.Len()) - for i := range terms { - terms[i] = types.NewTerm(r.Bool(), r.typ()) - } - return types.NewUnion(terms) -} - -func (r *reader) interfaceType() *types.Interface { - methods := make([]*types.Func, r.Len()) - embeddeds := make([]types.Type, r.Len()) - implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() - - for i := range methods { - pos := r.pos() - pkg, name := r.selector() - mtyp := r.signature(nil, nil, nil) - methods[i] = types.NewFunc(pos, pkg, name, mtyp) - } - - for i := range embeddeds { - embeddeds[i] = r.typ() - } - - iface := types.NewInterfaceType(methods, embeddeds) - if implicit { - iface.MarkImplicit() - } - - // We need to call iface.Complete(), but if there are any embedded - // defined types, then we may not have set their underlying - // interface type yet. So we need to defer calling Complete until - // after we've called SetUnderlying everywhere. - // - // TODO(mdempsky): After CL 424876 lands, it should be safe to call - // iface.Complete() immediately. - r.p.ifaces = append(r.p.ifaces, iface) - - return iface -} - -func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { - r.Sync(pkgbits.SyncSignature) - - params := r.params() - results := r.params() - variadic := r.Bool() - - return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) -} - -func (r *reader) params() *types.Tuple { - r.Sync(pkgbits.SyncParams) - - params := make([]*types.Var, r.Len()) - for i := range params { - params[i] = r.param() - } - - return types.NewTuple(params...) -} - -func (r *reader) param() *types.Var { - r.Sync(pkgbits.SyncParam) - - pos := r.pos() - pkg, name := r.localIdent() - typ := r.typ() - - return types.NewParam(pos, pkg, name, typ) -} - -// @@@ Objects - -func (r *reader) obj() (types.Object, []types.Type) { - r.Sync(pkgbits.SyncObject) - - if r.Version().Has(pkgbits.DerivedFuncInstance) { - assert(!r.Bool()) - } - - pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - obj := pkgScope(pkg).Lookup(name) - - targs := make([]types.Type, r.Len()) - for i := range targs { - targs[i] = r.typ() - } - - return obj, targs -} - -func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { - - var objPkg *types.Package - var objName string - var tag pkgbits.CodeObj - { - rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) - - objPkg, objName = rname.qualifiedIdent() - assert(objName != "") - - tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) - pr.retireReader(rname) - } - - if tag == pkgbits.ObjStub { - assert(objPkg == nil || objPkg == types.Unsafe) - return objPkg, objName - } - - // Ignore local types promoted to global scope (#55110). - if _, suffix := splitVargenSuffix(objName); suffix != "" { - return objPkg, objName - } - - if objPkg.Scope().Lookup(objName) == nil { - dict := pr.objDictIdx(idx) - - r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) - r.dict = dict - - declare := func(obj types.Object) { - objPkg.Scope().Insert(obj) - } - - switch tag { - default: - panic("weird") - - case pkgbits.ObjAlias: - pos := r.pos() - var tparams []*types.TypeParam - if r.Version().Has(pkgbits.AliasTypeParamNames) { - tparams = r.typeParamNames() - } - typ := r.typ() - declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ, tparams)) - - case pkgbits.ObjConst: - pos := r.pos() - typ := r.typ() - val := r.Value() - declare(types.NewConst(pos, objPkg, objName, typ, val)) - - case pkgbits.ObjFunc: - pos := r.pos() - tparams := r.typeParamNames() - sig := r.signature(nil, nil, tparams) - declare(types.NewFunc(pos, objPkg, objName, sig)) - - case pkgbits.ObjType: - pos := r.pos() - - obj := types.NewTypeName(pos, objPkg, objName, nil) - named := types.NewNamed(obj, nil, nil) - declare(obj) - - named.SetTypeParams(r.typeParamNames()) - - setUnderlying := func(underlying types.Type) { - // If the underlying type is an interface, we need to - // duplicate its methods so we can replace the receiver - // parameter's type (#49906). - if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { - methods := make([]*types.Func, iface.NumExplicitMethods()) - for i := range methods { - fn := iface.ExplicitMethod(i) - sig := fn.Type().(*types.Signature) - - recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) - typesinternal.SetVarKind(recv, typesinternal.RecvVar) - methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic())) - } - - embeds := make([]types.Type, iface.NumEmbeddeds()) - for i := range embeds { - embeds[i] = iface.EmbeddedType(i) - } - - newIface := types.NewInterfaceType(methods, embeds) - r.p.ifaces = append(r.p.ifaces, newIface) - underlying = newIface - } - - named.SetUnderlying(underlying) - } - - // Since go.dev/cl/455279, we can assume rhs.Underlying() will - // always be non-nil. However, to temporarily support users of - // older snapshot releases, we continue to fallback to the old - // behavior for now. - // - // TODO(mdempsky): Remove fallback code and simplify after - // allowing time for snapshot users to upgrade. - rhs := r.typ() - if underlying := rhs.Underlying(); underlying != nil { - setUnderlying(underlying) - } else { - pk := r.p - pk.laterFor(named, func() { - // First be sure that the rhs is initialized, if it needs to be initialized. - delete(pk.laterFors, named) // prevent cycles - if i, ok := pk.laterFors[rhs]; ok { - f := pk.laterFns[i] - pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op - f() // initialize RHS - } - setUnderlying(rhs.Underlying()) - }) - } - - for i, n := 0, r.Len(); i < n; i++ { - named.AddMethod(r.method()) - } - - case pkgbits.ObjVar: - pos := r.pos() - typ := r.typ() - v := types.NewVar(pos, objPkg, objName, typ) - typesinternal.SetVarKind(v, typesinternal.PackageVar) - declare(v) - } - } - - return objPkg, objName -} - -func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { - - var dict readerDict - - { - r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) - if implicits := r.Len(); implicits != 0 { - errorf("unexpected object with %v implicit type parameter(s)", implicits) - } - - dict.bounds = make([]typeInfo, r.Len()) - for i := range dict.bounds { - dict.bounds[i] = r.typInfo() - } - - dict.derived = make([]derivedInfo, r.Len()) - dict.derivedTypes = make([]types.Type, len(dict.derived)) - for i := range dict.derived { - dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)} - if r.Version().Has(pkgbits.DerivedInfoNeeded) { - assert(!r.Bool()) - } - } - - pr.retireReader(r) - } - // function references follow, but reader doesn't need those - - return &dict -} - -func (r *reader) typeParamNames() []*types.TypeParam { - r.Sync(pkgbits.SyncTypeParamNames) - - // Note: This code assumes it only processes objects without - // implement type parameters. This is currently fine, because - // reader is only used to read in exported declarations, which are - // always package scoped. - - if len(r.dict.bounds) == 0 { - return nil - } - - // Careful: Type parameter lists may have cycles. To allow for this, - // we construct the type parameter list in two passes: first we - // create all the TypeNames and TypeParams, then we construct and - // set the bound type. - - r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) - for i := range r.dict.bounds { - pos := r.pos() - pkg, name := r.localIdent() - - tname := types.NewTypeName(pos, pkg, name, nil) - r.dict.tparams[i] = types.NewTypeParam(tname, nil) - } - - typs := make([]types.Type, len(r.dict.bounds)) - for i, bound := range r.dict.bounds { - typs[i] = r.p.typIdx(bound, r.dict) - } - - // TODO(mdempsky): This is subtle, elaborate further. - // - // We have to save tparams outside of the closure, because - // typeParamNames() can be called multiple times with the same - // dictionary instance. - // - // Also, this needs to happen later to make sure SetUnderlying has - // been called. - // - // TODO(mdempsky): Is it safe to have a single "later" slice or do - // we need to have multiple passes? See comments on CL 386002 and - // go.dev/issue/52104. - tparams := r.dict.tparams - r.p.later(func() { - for i, typ := range typs { - tparams[i].SetConstraint(typ) - } - }) - - return r.dict.tparams -} - -func (r *reader) method() *types.Func { - r.Sync(pkgbits.SyncMethod) - pos := r.pos() - pkg, name := r.selector() - - rparams := r.typeParamNames() - sig := r.signature(r.param(), rparams, nil) - - _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. - return types.NewFunc(pos, pkg, name, sig) -} - -func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } -func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } -func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } - -func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { - r.Sync(marker) - return r.pkg(), r.String() -} - -// pkgScope returns pkg.Scope(). -// If pkg is nil, it returns types.Universe instead. -// -// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. -func pkgScope(pkg *types.Package) *types.Scope { - if pkg != nil { - return pkg.Scope() - } - return types.Universe -} - -// See cmd/compile/internal/types.SplitVargenSuffix. -func splitVargenSuffix(name string) (base, suffix string) { - i := len(name) - for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { - i-- - } - const dot = "·" - if i >= len(dot) && name[i-len(dot):i] == dot { - i -= len(dot) - return name[:i], name[i:] - } - return name, "" -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go deleted file mode 100644 index 7ea9013..0000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ /dev/null @@ -1,567 +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 gocommand is a helper for calling the go command. -package gocommand - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// A Runner will run go command invocations and serialize -// them if it sees a concurrency error. -type Runner struct { - // once guards the runner initialization. - once sync.Once - - // inFlight tracks available workers. - inFlight chan struct{} - - // serialized guards the ability to run a go command serially, - // to avoid deadlocks when claiming workers. - serialized chan struct{} -} - -const maxInFlight = 10 - -func (runner *Runner) initialize() { - runner.once.Do(func() { - runner.inFlight = make(chan struct{}, maxInFlight) - runner.serialized = make(chan struct{}, 1) - }) -} - -// 1.13: go: updates to go.mod needed, but contents have changed -// 1.14: go: updating go.mod: existing contents have changed since last read -var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) - -// event keys for go command invocations -var ( - verb = keys.NewString("verb", "go command verb") - directory = keys.NewString("directory", "") -) - -func invLabels(inv Invocation) []label.Label { - return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)} -} - -// Run is a convenience wrapper around RunRaw. -// It returns only stdout and a "friendly" error. -func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...) - defer done() - - stdout, _, friendly, _ := runner.RunRaw(ctx, inv) - return stdout, friendly -} - -// RunPiped runs the invocation serially, always waiting for any concurrent -// invocations to complete first. -func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { - ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...) - defer done() - - _, err := runner.runPiped(ctx, inv, stdout, stderr) - return err -} - -// RunRaw runs the invocation, serializing requests only if they fight over -// go.mod changes. -// Postcondition: both error results have same nilness. -func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) - defer done() - // Make sure the runner is always initialized. - runner.initialize() - - // First, try to run the go command concurrently. - stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) - - // If we encounter a load concurrency error, we need to retry serially. - if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { - event.Error(ctx, "Load concurrency error, will retry serially", err) - - // Run serially by calling runPiped. - stdout.Reset() - stderr.Reset() - friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) - } - - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - // Wait for 1 worker to become available. - select { - case <-ctx.Done(): - return nil, nil, ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - defer func() { <-runner.inFlight }() - } - - stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} - friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { - // Make sure the runner is always initialized. - runner.initialize() - - // Acquire the serialization lock. This avoids deadlocks between two - // runPiped commands. - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.serialized <- struct{}{}: - defer func() { <-runner.serialized }() - } - - // Wait for all in-progress go commands to return before proceeding, - // to avoid load concurrency errors. - for i := 0; i < maxInFlight; i++ { - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - // Make sure we always "return" any workers we took. - defer func() { <-runner.inFlight }() - } - } - - return inv.runWithFriendlyError(ctx, stdout, stderr) -} - -// An Invocation represents a call to the go command. -type Invocation struct { - Verb string - Args []string - BuildFlags []string - - // If ModFlag is set, the go command is invoked with -mod=ModFlag. - // TODO(rfindley): remove, in favor of Args. - ModFlag string - - // If ModFile is set, the go command is invoked with -modfile=ModFile. - // TODO(rfindley): remove, in favor of Args. - ModFile string - - // Overlay is the name of the JSON overlay file that describes - // unsaved editor buffers; see [WriteOverlays]. - // If set, the go command is invoked with -overlay=Overlay. - // TODO(rfindley): remove, in favor of Args. - Overlay string - - // If CleanEnv is set, the invocation will run only with the environment - // in Env, not starting with os.Environ. - CleanEnv bool - Env []string - WorkingDir string - Logf func(format string, args ...any) -} - -// Postcondition: both error results have same nilness. -func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { - rawError = i.run(ctx, stdout, stderr) - if rawError != nil { - friendlyError = rawError - // Check for 'go' executable not being found. - if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - friendlyError = fmt.Errorf("go command required, not found: %v", ee) - } - if ctx.Err() != nil { - friendlyError = ctx.Err() - } - friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) - } - return -} - -// logf logs if i.Logf is non-nil. -func (i *Invocation) logf(format string, args ...any) { - if i.Logf != nil { - i.Logf(format, args...) - } -} - -func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { - goArgs := []string{i.Verb} - - appendModFile := func() { - if i.ModFile != "" { - goArgs = append(goArgs, "-modfile="+i.ModFile) - } - } - appendModFlag := func() { - if i.ModFlag != "" { - goArgs = append(goArgs, "-mod="+i.ModFlag) - } - } - appendOverlayFlag := func() { - if i.Overlay != "" { - goArgs = append(goArgs, "-overlay="+i.Overlay) - } - } - - switch i.Verb { - case "env", "version": - goArgs = append(goArgs, i.Args...) - case "mod": - // mod needs the sub-verb before flags. - goArgs = append(goArgs, i.Args[0]) - appendModFile() - goArgs = append(goArgs, i.Args[1:]...) - case "get": - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - goArgs = append(goArgs, i.Args...) - - default: // notably list and build. - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - appendModFlag() - appendOverlayFlag() - goArgs = append(goArgs, i.Args...) - } - cmd := exec.Command("go", goArgs...) - cmd.Stdout = stdout - cmd.Stderr = stderr - - // https://go.dev/issue/59541: don't wait forever copying stderr - // after the command has exited. - // After CL 484741 we copy stdout manually, so we we'll stop reading that as - // soon as ctx is done. However, we also don't want to wait around forever - // for stderr. Give a much-longer-than-reasonable delay and then assume that - // something has wedged in the kernel or runtime. - cmd.WaitDelay = 30 * time.Second - - // The cwd gets resolved to the real path. On Darwin, where - // /tmp is a symlink, this breaks anything that expects the - // working directory to keep the original path, including the - // go command when dealing with modules. - // - // os.Getwd has a special feature where if the cwd and the PWD - // are the same node then it trusts the PWD, so by setting it - // in the env for the child process we fix up all the paths - // returned by the go command. - if !i.CleanEnv { - cmd.Env = os.Environ() - } - cmd.Env = append(cmd.Env, i.Env...) - if i.WorkingDir != "" { - cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) - cmd.Dir = i.WorkingDir - } - - debugStr := cmdDebugStr(cmd) - i.logf("starting %v", debugStr) - start := time.Now() - defer func() { - i.logf("%s for %v", time.Since(start), debugStr) - }() - - return runCmdContext(ctx, cmd) -} - -// DebugHangingGoCommands may be set by tests to enable additional -// instrumentation (including panics) for debugging hanging Go commands. -// -// See golang/go#54461 for details. -var DebugHangingGoCommands = false - -// runCmdContext is like exec.CommandContext except it sends os.Interrupt -// before os.Kill. -func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { - // If cmd.Stdout is not an *os.File, the exec package will create a pipe and - // copy it to the Writer in a goroutine until the process has finished and - // either the pipe reaches EOF or command's WaitDelay expires. - // - // However, the output from 'go list' can be quite large, and we don't want to - // keep reading (and allocating buffers) if we've already decided we don't - // care about the output. We don't want to wait for the process to finish, and - // we don't wait to wait for the WaitDelay to expire either. - // - // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace - // it with a pipe (which is an *os.File), which we can close in order to stop - // copying output as soon as we realize we don't care about it. - var stdoutW *os.File - if cmd.Stdout != nil { - if _, ok := cmd.Stdout.(*os.File); !ok { - var stdoutR *os.File - stdoutR, stdoutW, err = os.Pipe() - if err != nil { - return err - } - prevStdout := cmd.Stdout - cmd.Stdout = stdoutW - - stdoutErr := make(chan error, 1) - go func() { - _, err := io.Copy(prevStdout, stdoutR) - if err != nil { - err = fmt.Errorf("copying stdout: %w", err) - } - stdoutErr <- err - }() - defer func() { - // We started a goroutine to copy a stdout pipe. - // Wait for it to finish, or terminate it if need be. - var err2 error - select { - case err2 = <-stdoutErr: - stdoutR.Close() - case <-ctx.Done(): - stdoutR.Close() - // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close - // should cause the Read call in io.Copy to unblock and return - // immediately, but we still need to receive from stdoutErr to confirm - // that it has happened. - <-stdoutErr - err2 = ctx.Err() - } - if err == nil { - err = err2 - } - }() - - // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the - // same writer, and have a type that can be compared with ==, at most - // one goroutine at a time will call Write.” - // - // Since we're starting a goroutine that writes to cmd.Stdout, we must - // also update cmd.Stderr so that it still holds. - func() { - defer func() { recover() }() - if cmd.Stderr == prevStdout { - cmd.Stderr = cmd.Stdout - } - }() - } - } - - startTime := time.Now() - err = cmd.Start() - if stdoutW != nil { - // The child process has inherited the pipe file, - // so close the copy held in this process. - stdoutW.Close() - stdoutW = nil - } - if err != nil { - return err - } - - resChan := make(chan error, 1) - go func() { - resChan <- cmd.Wait() - }() - - // If we're interested in debugging hanging Go commands, stop waiting after a - // minute and panic with interesting information. - debug := DebugHangingGoCommands - if debug { - timer := time.NewTimer(1 * time.Minute) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - // HandleHangingGoCommand terminates this process. - // Pass off resChan in case we can collect the command error. - handleHangingGoCommand(startTime, cmd, resChan) - case <-ctx.Done(): - } - } else { - select { - case err := <-resChan: - return err - case <-ctx.Done(): - } - } - - // Cancelled. Interrupt and see if it ends voluntarily. - if err := cmd.Process.Signal(os.Interrupt); err == nil { - // (We used to wait only 1s but this proved - // fragile on loaded builder machines.) - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - } - } - - // Didn't shut down in response to interrupt. Kill it hard. - if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug { - log.Printf("error killing the Go command: %v", err) - } - - return <-resChan -} - -// handleHangingGoCommand outputs debugging information to help diagnose the -// cause of a hanging Go command, and then exits with log.Fatalf. -func handleHangingGoCommand(start time.Time, cmd *exec.Cmd, resChan chan error) { - switch runtime.GOOS { - case "linux", "darwin", "freebsd", "netbsd", "openbsd": - fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND - - The gopls test runner has detected a hanging go command. In order to debug - this, the output of ps and lsof/fstat is printed below. - - See golang/go#54461 for more details.`) - - fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") - fmt.Fprintln(os.Stderr, "-------------------------") - psCmd := exec.Command("ps", "axo", "ppid,pid,command") - psCmd.Stdout = os.Stderr - psCmd.Stderr = os.Stderr - if err := psCmd.Run(); err != nil { - log.Printf("Handling hanging Go command: running ps: %v", err) - } - - listFiles := "lsof" - if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { - listFiles = "fstat" - } - - fmt.Fprintln(os.Stderr, "\n"+listFiles+":") - fmt.Fprintln(os.Stderr, "-----") - listFilesCmd := exec.Command(listFiles) - listFilesCmd.Stdout = os.Stderr - listFilesCmd.Stderr = os.Stderr - if err := listFilesCmd.Run(); err != nil { - log.Printf("Handling hanging Go command: running %s: %v", listFiles, err) - } - // Try to extract information about the slow go process by issuing a SIGQUIT. - if err := cmd.Process.Signal(sigStuckProcess); err == nil { - select { - case err := <-resChan: - stderr := "not a bytes.Buffer" - if buf, _ := cmd.Stderr.(*bytes.Buffer); buf != nil { - stderr = buf.String() - } - log.Printf("Quit hanging go command:\n\terr:%v\n\tstderr:\n%v\n\n", err, stderr) - case <-time.After(5 * time.Second): - } - } else { - log.Printf("Sending signal %d to hanging go command: %v", sigStuckProcess, err) - } - } - log.Fatalf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid) -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - if len(split) == 2 { - k, v := split[0], split[1] - env[k] = v - } - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} - -// WriteOverlays writes each value in the overlay (see the Overlay -// field of go/packages.Config) to a temporary file and returns the name -// of a JSON file describing the mapping that is suitable for the "go -// list -overlay" flag. -// -// On success, the caller must call the cleanup function exactly once -// when the files are no longer needed. -func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) { - // Do nothing if there are no overlays in the config. - if len(overlay) == 0 { - return "", func() {}, nil - } - - dir, err := os.MkdirTemp("", "gocommand-*") - if err != nil { - return "", nil, err - } - - // The caller must clean up this directory, - // unless this function returns an error. - // (The cleanup operand of each return - // statement below is ignored.) - defer func() { - cleanup = func() { - os.RemoveAll(dir) - } - if err != nil { - cleanup() - cleanup = nil - } - }() - - // Write each map entry to a temporary file. - overlays := make(map[string]string) - for k, v := range overlay { - // Use a unique basename for each file (001-foo.go), - // to avoid creating nested directories. - base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k)) - filename := filepath.Join(dir, base) - err := os.WriteFile(filename, v, 0666) - if err != nil { - return "", nil, err - } - overlays[k] = filename - } - - // Write the JSON overlay file that maps logical file names to temp files. - // - // OverlayJSON is the format overlay files are expected to be in. - // The Replace map maps from overlaid paths to replacement paths: - // the Go command will forward all reads trying to open - // each overlaid path to its replacement path, or consider the overlaid - // path not to exist if the replacement path is empty. - // - // From golang/go#39958. - type OverlayJSON struct { - Replace map[string]string `json:"replace,omitempty"` - } - b, err := json.Marshal(OverlayJSON{Replace: overlays}) - if err != nil { - return "", nil, err - } - filename = filepath.Join(dir, "overlay.json") - if err := os.WriteFile(filename, b, 0666); err != nil { - return "", nil, err - } - - return filename, nil, nil -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go deleted file mode 100644 index 469c648..0000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2025 The Go 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 !unix - -package gocommand - -import "os" - -// sigStuckProcess is the signal to send to kill a hanging subprocess. -// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill. -var sigStuckProcess = os.Kill diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go deleted file mode 100644 index 169d37c..0000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2025 The Go 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 unix - -package gocommand - -import "syscall" - -// Sigstuckprocess is the signal to send to kill a hanging subprocess. -// Send SIGQUIT to get a stack trace. -var sigStuckProcess = syscall.SIGQUIT diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go deleted file mode 100644 index e38d1fb..0000000 --- a/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ /dev/null @@ -1,163 +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 gocommand - -import ( - "bytes" - "context" - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "golang.org/x/mod/semver" -) - -// ModuleJSON holds information about a module. -type ModuleJSON struct { - Path string // module path - Version string // module version - Versions []string // available module versions (with -versions) - Replace *ModuleJSON // replaced by this module - Time *time.Time // time version was created - Update *ModuleJSON // available update, if any (with -u) - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module -} - -var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) - -// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands -// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, -// of which only Verb and Args are modified to run the appropriate Go command. -// Inspired by setDefaultBuildMod in modload/init.go -func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { - mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) - if err != nil { - return false, nil, err - } - - // We check the GOFLAGS to see if there is anything overridden or not. - inv.Verb = "env" - inv.Args = []string{"GOFLAGS"} - stdout, err := r.Run(ctx, inv) - if err != nil { - return false, nil, err - } - goflags := string(bytes.TrimSpace(stdout.Bytes())) - matches := modFlagRegexp.FindStringSubmatch(goflags) - var modFlag string - if len(matches) != 0 { - modFlag = matches[1] - } - // Don't override an explicit '-mod=' argument. - if modFlag == "vendor" { - return true, mainMod, nil - } else if modFlag != "" { - return false, nil, nil - } - if mainMod == nil || !go114 { - return false, nil, nil - } - // Check 1.14's automatic vendor mode. - if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { - if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { - // The Go version is at least 1.14, and a vendor directory exists. - // Set -mod=vendor by default. - return true, mainMod, nil - } - } - return false, nil, nil -} - -// getMainModuleAnd114 gets one of the main modules' information and whether the -// go command in use is 1.14+. This is the information needed to figure out -// if vendoring should be enabled. -func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { - const format = `{{.Path}} -{{.Dir}} -{{.GoMod}} -{{.GoVersion}} -{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} -` - inv.Verb = "list" - inv.Args = []string{"-m", "-f", format} - stdout, err := r.Run(ctx, inv) - if err != nil { - return nil, false, err - } - - lines := strings.Split(stdout.String(), "\n") - if len(lines) < 5 { - return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) - } - mod := &ModuleJSON{ - Path: lines[0], - Dir: lines[1], - GoMod: lines[2], - GoVersion: lines[3], - Main: true, - } - return mod, lines[4] == "go1.14", nil -} - -// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands -// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, -// of which only Verb and Args are modified to run the appropriate Go command. -// Inspired by setDefaultBuildMod in modload/init.go -func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) { - inv.Verb = "env" - inv.Args = []string{"GOWORK"} - stdout, err := r.Run(ctx, inv) - if err != nil { - return false, nil, err - } - goWork := string(bytes.TrimSpace(stdout.Bytes())) - if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() { - mainMods, err := getWorkspaceMainModules(ctx, inv, r) - if err != nil { - return false, nil, err - } - return true, mainMods, nil - } - return false, nil, nil -} - -// getWorkspaceMainModules gets the main modules' information. -// This is the information needed to figure out if vendoring should be enabled. -func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) { - const format = `{{.Path}} -{{.Dir}} -{{.GoMod}} -{{.GoVersion}} -` - inv.Verb = "list" - inv.Args = []string{"-m", "-f", format} - stdout, err := r.Run(ctx, inv) - if err != nil { - return nil, err - } - - lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n") - if len(lines) < 4 { - return nil, fmt.Errorf("unexpected stdout: %q", stdout.String()) - } - mods := make([]*ModuleJSON, 0, len(lines)/4) - for i := 0; i < len(lines); i += 4 { - mods = append(mods, &ModuleJSON{ - Path: lines[i], - Dir: lines[i+1], - GoMod: lines[i+2], - GoVersion: lines[i+3], - Main: true, - }) - } - return mods, nil -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go deleted file mode 100644 index 446c584..0000000 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ /dev/null @@ -1,71 +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 gocommand - -import ( - "context" - "fmt" - "regexp" - "strings" -) - -// GoVersion reports the minor version number of the highest release -// tag built into the go command on the PATH. -// -// Note that this may be higher than the version of the go tool used -// to build this application, and thus the versions of the standard -// go/{scanner,parser,ast,types} packages that are linked into it. -// In that case, callers should either downgrade to the version of -// go used to build the application, or report an error that the -// application is too old to use the go command on the PATH. -func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { - inv.Verb = "list" - inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} - inv.BuildFlags = nil // This is not a build command. - inv.ModFlag = "" - inv.ModFile = "" - inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") - - stdoutBytes, err := r.Run(ctx, inv) - if err != nil { - return 0, err - } - stdout := stdoutBytes.String() - if len(stdout) < 3 { - return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) - } - // Split up "[go1.1 go1.15]" and return highest go1.X value. - tags := strings.Fields(stdout[1 : len(stdout)-2]) - for i := len(tags) - 1; i >= 0; i-- { - var version int - if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil { - continue - } - return version, nil - } - return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) -} - -// GoVersionOutput returns the complete output of the go version command. -func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { - inv.Verb = "version" - goVersion, err := r.Run(ctx, inv) - if err != nil { - return "", err - } - return goVersion.String(), nil -} - -// ParseGoVersionOutput extracts the Go version string -// from the output of the "go version" command. -// Given an unrecognized form, it returns an empty string. -func ParseGoVersionOutput(data string) string { - re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) - m := re.FindStringSubmatch(data) - if len(m) != 2 { - return "" // unrecognized version - } - return m[1] -} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go deleted file mode 100644 index 7846059..0000000 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ /dev/null @@ -1,20 +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 packagesinternal exposes internal-only fields from go/packages. -package packagesinternal - -var GetDepsErrors = func(p any) []*PackageError { return nil } - -type PackageError struct { - ImportStack []string // shortest path from package named on command line to this one - Pos string // position of error (if present, file:line:col) - Err string // the error itself -} - -var TypecheckCgo int -var DepsErrors int // must be set as a LoadMode to call GetDepsErrors - -var SetModFlag = func(config any, value string) {} -var SetModFile = func(config interface{}, value string) {} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go deleted file mode 100644 index f0cabde..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/codes.go +++ /dev/null @@ -1,77 +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 pkgbits - -// A Code is an enum value that can be encoded into bitstreams. -// -// Code types are preferable for enum types, because they allow -// Decoder to detect desyncs. -type Code interface { - // Marker returns the SyncMarker for the Code's dynamic type. - Marker() SyncMarker - - // Value returns the Code's ordinal value. - Value() int -} - -// A CodeVal distinguishes among go/constant.Value encodings. -type CodeVal int - -func (c CodeVal) Marker() SyncMarker { return SyncVal } -func (c CodeVal) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ValBool CodeVal = iota - ValString - ValInt64 - ValBigInt - ValBigRat - ValBigFloat -) - -// A CodeType distinguishes among go/types.Type encodings. -type CodeType int - -func (c CodeType) Marker() SyncMarker { return SyncType } -func (c CodeType) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - TypeBasic CodeType = iota - TypeNamed - TypePointer - TypeSlice - TypeArray - TypeChan - TypeMap - TypeSignature - TypeStruct - TypeInterface - TypeUnion - TypeTypeParam -) - -// A CodeObj distinguishes among go/types.Object encodings. -type CodeObj int - -func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } -func (c CodeObj) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ObjAlias CodeObj = iota - ObjConst - ObjType - ObjFunc - ObjVar - ObjStub -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go deleted file mode 100644 index f6cb37c..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go +++ /dev/null @@ -1,519 +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 pkgbits - -import ( - "encoding/binary" - "errors" - "fmt" - "go/constant" - "go/token" - "io" - "math/big" - "os" - "runtime" - "strings" -) - -// A PkgDecoder provides methods for decoding a package's Unified IR -// export data. -type PkgDecoder struct { - // version is the file format version. - version Version - - // sync indicates whether the file uses sync markers. - sync bool - - // pkgPath is the package path for the package to be decoded. - // - // TODO(mdempsky): Remove; unneeded since CL 391014. - pkgPath string - - // elemData is the full data payload of the encoded package. - // Elements are densely and contiguously packed together. - // - // The last 8 bytes of elemData are the package fingerprint. - elemData string - - // elemEnds stores the byte-offset end positions of element - // bitstreams within elemData. - // - // For example, element I's bitstream data starts at elemEnds[I-1] - // (or 0, if I==0) and ends at elemEnds[I]. - // - // Note: elemEnds is indexed by absolute indices, not - // section-relative indices. - elemEnds []uint32 - - // elemEndsEnds stores the index-offset end positions of relocation - // sections within elemEnds. - // - // For example, section K's end positions start at elemEndsEnds[K-1] - // (or 0, if K==0) and end at elemEndsEnds[K]. - elemEndsEnds [numRelocs]uint32 - - scratchRelocEnt []RelocEnt -} - -// PkgPath returns the package path for the package -// -// TODO(mdempsky): Remove; unneeded since CL 391014. -func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } - -// SyncMarkers reports whether pr uses sync markers. -func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } - -// NewPkgDecoder returns a PkgDecoder initialized to read the Unified -// IR export data from input. pkgPath is the package path for the -// compilation unit that produced the export data. -func NewPkgDecoder(pkgPath, input string) PkgDecoder { - pr := PkgDecoder{ - pkgPath: pkgPath, - } - - // TODO(mdempsky): Implement direct indexing of input string to - // avoid copying the position information. - - r := strings.NewReader(input) - - var ver uint32 - assert(binary.Read(r, binary.LittleEndian, &ver) == nil) - pr.version = Version(ver) - - if pr.version >= numVersions { - panic(fmt.Errorf("cannot decode %q, export data version %d is greater than maximum supported version %d", pkgPath, pr.version, numVersions-1)) - } - - if pr.version.Has(Flags) { - var flags uint32 - assert(binary.Read(r, binary.LittleEndian, &flags) == nil) - pr.sync = flags&flagSyncMarkers != 0 - } - - assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) - - pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) - assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) - - pos, err := r.Seek(0, io.SeekCurrent) - assert(err == nil) - - pr.elemData = input[pos:] - - const fingerprintSize = 8 - assert(len(pr.elemData)-fingerprintSize == int(pr.elemEnds[len(pr.elemEnds)-1])) - - return pr -} - -// NumElems returns the number of elements in section k. -func (pr *PkgDecoder) NumElems(k RelocKind) int { - count := int(pr.elemEndsEnds[k]) - if k > 0 { - count -= int(pr.elemEndsEnds[k-1]) - } - return count -} - -// TotalElems returns the total number of elements across all sections. -func (pr *PkgDecoder) TotalElems() int { - return len(pr.elemEnds) -} - -// Fingerprint returns the package fingerprint. -func (pr *PkgDecoder) Fingerprint() [8]byte { - var fp [8]byte - copy(fp[:], pr.elemData[len(pr.elemData)-8:]) - return fp -} - -// AbsIdx returns the absolute index for the given (section, index) -// pair. -func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { - absIdx := int(idx) - if k > 0 { - absIdx += int(pr.elemEndsEnds[k-1]) - } - if absIdx >= int(pr.elemEndsEnds[k]) { - panicf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) - } - return absIdx -} - -// DataIdx returns the raw element bitstream for the given (section, -// index) pair. -func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { - absIdx := pr.AbsIdx(k, idx) - - var start uint32 - if absIdx > 0 { - start = pr.elemEnds[absIdx-1] - } - end := pr.elemEnds[absIdx] - - return pr.elemData[start:end] -} - -// StringIdx returns the string value for the given string index. -func (pr *PkgDecoder) StringIdx(idx Index) string { - return pr.DataIdx(RelocString, idx) -} - -// NewDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.NewDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -// TempDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -// If possible the Decoder should be RetireDecoder'd when it is no longer -// needed, this will avoid heap allocations. -func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.TempDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -func (pr *PkgDecoder) RetireDecoder(d *Decoder) { - pr.scratchRelocEnt = d.Relocs - d.Relocs = nil -} - -// NewDecoderRaw returns a Decoder for the given (section, index) pair. -// -// Most callers should use NewDecoder instead. -func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - r.Data.Reset(pr.DataIdx(k, idx)) - r.Sync(SyncRelocs) - r.Relocs = make([]RelocEnt, r.Len()) - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - r.Data.Reset(pr.DataIdx(k, idx)) - r.Sync(SyncRelocs) - l := r.Len() - if cap(pr.scratchRelocEnt) >= l { - r.Relocs = pr.scratchRelocEnt[:l] - pr.scratchRelocEnt = nil - } else { - r.Relocs = make([]RelocEnt, l) - } - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -// A Decoder provides methods for decoding an individual element's -// bitstream data. -type Decoder struct { - common *PkgDecoder - - Relocs []RelocEnt - Data strings.Reader - - k RelocKind - Idx Index -} - -func (r *Decoder) checkErr(err error) { - if err != nil { - panicf("unexpected decoding error: %w", err) - } -} - -func (r *Decoder) rawUvarint() uint64 { - x, err := readUvarint(&r.Data) - r.checkErr(err) - return x -} - -// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint. -// This avoids the interface conversion and thus has better escape properties, -// which flows up the stack. -func readUvarint(r *strings.Reader) (uint64, error) { - var x uint64 - var s uint - for i := 0; i < binary.MaxVarintLen64; i++ { - b, err := r.ReadByte() - if err != nil { - if i > 0 && err == io.EOF { - err = io.ErrUnexpectedEOF - } - return x, err - } - if b < 0x80 { - if i == binary.MaxVarintLen64-1 && b > 1 { - return x, overflow - } - return x | uint64(b)<> 1) - if ux&1 != 0 { - x = ^x - } - return x -} - -func (r *Decoder) rawReloc(k RelocKind, idx int) Index { - e := r.Relocs[idx] - assert(e.Kind == k) - return e.Idx -} - -// Sync decodes a sync marker from the element bitstream and asserts -// that it matches the expected marker. -// -// If r.common.sync is false, then Sync is a no-op. -func (r *Decoder) Sync(mWant SyncMarker) { - if !r.common.sync { - return - } - - pos, _ := r.Data.Seek(0, io.SeekCurrent) - mHave := SyncMarker(r.rawUvarint()) - writerPCs := make([]int, r.rawUvarint()) - for i := range writerPCs { - writerPCs[i] = int(r.rawUvarint()) - } - - if mHave == mWant { - return - } - - // There's some tension here between printing: - // - // (1) full file paths that tools can recognize (e.g., so emacs - // hyperlinks the "file:line" text for easy navigation), or - // - // (2) short file paths that are easier for humans to read (e.g., by - // omitting redundant or irrelevant details, so it's easier to - // focus on the useful bits that remain). - // - // The current formatting favors the former, as it seems more - // helpful in practice. But perhaps the formatting could be improved - // to better address both concerns. For example, use relative file - // paths if they would be shorter, or rewrite file paths to contain - // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how - // to reliably expand that again. - - fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) - - fmt.Printf("\nfound %v, written at:\n", mHave) - if len(writerPCs) == 0 { - fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) - } - for _, pc := range writerPCs { - fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) - } - - fmt.Printf("\nexpected %v, reading at:\n", mWant) - var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? - n := runtime.Callers(2, readerPCs[:]) - for _, pc := range fmtFrames(readerPCs[:n]...) { - fmt.Printf("\t%s\n", pc) - } - - // We already printed a stack trace for the reader, so now we can - // simply exit. Printing a second one with panic or base.Fatalf - // would just be noise. - os.Exit(1) -} - -// Bool decodes and returns a bool value from the element bitstream. -func (r *Decoder) Bool() bool { - r.Sync(SyncBool) - x, err := r.Data.ReadByte() - r.checkErr(err) - assert(x < 2) - return x != 0 -} - -// Int64 decodes and returns an int64 value from the element bitstream. -func (r *Decoder) Int64() int64 { - r.Sync(SyncInt64) - return r.rawVarint() -} - -// Uint64 decodes and returns a uint64 value from the element bitstream. -func (r *Decoder) Uint64() uint64 { - r.Sync(SyncUint64) - return r.rawUvarint() -} - -// Len decodes and returns a non-negative int value from the element bitstream. -func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } - -// Int decodes and returns an int value from the element bitstream. -func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } - -// Uint decodes and returns a uint value from the element bitstream. -func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } - -// Code decodes a Code value from the element bitstream and returns -// its ordinal value. It's the caller's responsibility to convert the -// result to an appropriate Code type. -// -// TODO(mdempsky): Ideally this method would have signature "Code[T -// Code] T" instead, but we don't allow generic methods and the -// compiler can't depend on generics yet anyway. -func (r *Decoder) Code(mark SyncMarker) int { - r.Sync(mark) - return r.Len() -} - -// Reloc decodes a relocation of expected section k from the element -// bitstream and returns an index to the referenced element. -func (r *Decoder) Reloc(k RelocKind) Index { - r.Sync(SyncUseReloc) - return r.rawReloc(k, r.Len()) -} - -// String decodes and returns a string value from the element -// bitstream. -func (r *Decoder) String() string { - r.Sync(SyncString) - return r.common.StringIdx(r.Reloc(RelocString)) -} - -// Strings decodes and returns a variable-length slice of strings from -// the element bitstream. -func (r *Decoder) Strings() []string { - res := make([]string, r.Len()) - for i := range res { - res[i] = r.String() - } - return res -} - -// Value decodes and returns a constant.Value from the element -// bitstream. -func (r *Decoder) Value() constant.Value { - r.Sync(SyncValue) - isComplex := r.Bool() - val := r.scalar() - if isComplex { - val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) - } - return val -} - -func (r *Decoder) scalar() constant.Value { - switch tag := CodeVal(r.Code(SyncVal)); tag { - default: - panic(fmt.Errorf("unexpected scalar tag: %v", tag)) - - case ValBool: - return constant.MakeBool(r.Bool()) - case ValString: - return constant.MakeString(r.String()) - case ValInt64: - return constant.MakeInt64(r.Int64()) - case ValBigInt: - return constant.Make(r.bigInt()) - case ValBigRat: - num := r.bigInt() - denom := r.bigInt() - return constant.Make(new(big.Rat).SetFrac(num, denom)) - case ValBigFloat: - return constant.Make(r.bigFloat()) - } -} - -func (r *Decoder) bigInt() *big.Int { - v := new(big.Int).SetBytes([]byte(r.String())) - if r.Bool() { - v.Neg(v) - } - return v -} - -func (r *Decoder) bigFloat() *big.Float { - v := new(big.Float).SetPrec(512) - assert(v.UnmarshalText([]byte(r.String())) == nil) - return v -} - -// @@@ Helpers - -// TODO(mdempsky): These should probably be removed. I think they're a -// smell that the export data format is not yet quite right. - -// PeekPkgPath returns the package path for the specified package -// index. -func (pr *PkgDecoder) PeekPkgPath(idx Index) string { - var path string - { - r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef) - path = r.String() - pr.RetireDecoder(&r) - } - if path == "" { - path = pr.pkgPath - } - return path -} - -// PeekObj returns the package path, object name, and CodeObj for the -// specified object index. -func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { - var ridx Index - var name string - var rcode int - { - r := pr.TempDecoder(RelocName, idx, SyncObject1) - r.Sync(SyncSym) - r.Sync(SyncPkg) - ridx = r.Reloc(RelocPkg) - name = r.String() - rcode = r.Code(SyncCodeObj) - pr.RetireDecoder(&r) - } - - path := pr.PeekPkgPath(ridx) - assert(name != "") - - tag := CodeObj(rcode) - - return path, name, tag -} - -// Version reports the version of the bitstream. -func (w *Decoder) Version() Version { return w.common.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go deleted file mode 100644 index c8a2796..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2022 The Go 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 pkgbits implements low-level coding abstractions for -// Unified IR's export data format. -// -// At a low-level, a package is a collection of bitstream elements. -// Each element has a "kind" and a dense, non-negative index. -// Elements can be randomly accessed given their kind and index. -// -// Individual elements are sequences of variable-length values (e.g., -// integers, booleans, strings, go/constant values, cross-references -// to other elements). Package pkgbits provides APIs for encoding and -// decoding these low-level values, but the details of mapping -// higher-level Go constructs into elements is left to higher-level -// abstractions. -// -// Elements may cross-reference each other with "relocations." For -// example, an element representing a pointer type has a relocation -// referring to the element type. -// -// Go constructs may be composed as a constellation of multiple -// elements. For example, a declared function may have one element to -// describe the object (e.g., its name, type, position), and a -// separate element to describe its function body. This allows readers -// some flexibility in efficiently seeking or re-reading data (e.g., -// inlining requires re-reading the function body for each inlined -// call, without needing to re-read the object-level details). -// -// This is a copy of internal/pkgbits in the Go implementation. -package pkgbits diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go deleted file mode 100644 index c17a123..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go +++ /dev/null @@ -1,392 +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 pkgbits - -import ( - "bytes" - "crypto/md5" - "encoding/binary" - "go/constant" - "io" - "math/big" - "runtime" - "strings" -) - -// A PkgEncoder provides methods for encoding a package's Unified IR -// export data. -type PkgEncoder struct { - // version of the bitstream. - version Version - - // elems holds the bitstream for previously encoded elements. - elems [numRelocs][]string - - // stringsIdx maps previously encoded strings to their index within - // the RelocString section, to allow deduplication. That is, - // elems[RelocString][stringsIdx[s]] == s (if present). - stringsIdx map[string]Index - - // syncFrames is the number of frames to write at each sync - // marker. A negative value means sync markers are omitted. - syncFrames int -} - -// SyncMarkers reports whether pw uses sync markers. -func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } - -// NewPkgEncoder returns an initialized PkgEncoder. -// -// syncFrames is the number of caller frames that should be serialized -// at Sync points. Serializing additional frames results in larger -// export data files, but can help diagnosing desync errors in -// higher-level Unified IR reader/writer code. If syncFrames is -// negative, then sync markers are omitted entirely. -func NewPkgEncoder(version Version, syncFrames int) PkgEncoder { - return PkgEncoder{ - version: version, - stringsIdx: make(map[string]Index), - syncFrames: syncFrames, - } -} - -// DumpTo writes the package's encoded data to out0 and returns the -// package fingerprint. -func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { - h := md5.New() - out := io.MultiWriter(out0, h) - - writeUint32 := func(x uint32) { - assert(binary.Write(out, binary.LittleEndian, x) == nil) - } - - writeUint32(uint32(pw.version)) - - if pw.version.Has(Flags) { - var flags uint32 - if pw.SyncMarkers() { - flags |= flagSyncMarkers - } - writeUint32(flags) - } - - // Write elemEndsEnds. - var sum uint32 - for _, elems := range &pw.elems { - sum += uint32(len(elems)) - writeUint32(sum) - } - - // Write elemEnds. - sum = 0 - for _, elems := range &pw.elems { - for _, elem := range elems { - sum += uint32(len(elem)) - writeUint32(sum) - } - } - - // Write elemData. - for _, elems := range &pw.elems { - for _, elem := range elems { - _, err := io.WriteString(out, elem) - assert(err == nil) - } - } - - // Write fingerprint. - copy(fingerprint[:], h.Sum(nil)) - _, err := out0.Write(fingerprint[:]) - assert(err == nil) - - return -} - -// StringIdx adds a string value to the strings section, if not -// already present, and returns its index. -func (pw *PkgEncoder) StringIdx(s string) Index { - if idx, ok := pw.stringsIdx[s]; ok { - assert(pw.elems[RelocString][idx] == s) - return idx - } - - idx := Index(len(pw.elems[RelocString])) - pw.elems[RelocString] = append(pw.elems[RelocString], s) - pw.stringsIdx[s] = idx - return idx -} - -// NewEncoder returns an Encoder for a new element within the given -// section, and encodes the given SyncMarker as the start of the -// element bitstream. -func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { - e := pw.NewEncoderRaw(k) - e.Sync(marker) - return e -} - -// NewEncoderRaw returns an Encoder for a new element within the given -// section. -// -// Most callers should use NewEncoder instead. -func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { - idx := Index(len(pw.elems[k])) - pw.elems[k] = append(pw.elems[k], "") // placeholder - - return Encoder{ - p: pw, - k: k, - Idx: idx, - } -} - -// An Encoder provides methods for encoding an individual element's -// bitstream data. -type Encoder struct { - p *PkgEncoder - - Relocs []RelocEnt - RelocMap map[RelocEnt]uint32 - Data bytes.Buffer // accumulated element bitstream data - - encodingRelocHeader bool - - k RelocKind - Idx Index // index within relocation section -} - -// Flush finalizes the element's bitstream and returns its Index. -func (w *Encoder) Flush() Index { - var sb strings.Builder - - // Backup the data so we write the relocations at the front. - var tmp bytes.Buffer - io.Copy(&tmp, &w.Data) - - // TODO(mdempsky): Consider writing these out separately so they're - // easier to strip, along with function bodies, so that we can prune - // down to just the data that's relevant to go/types. - if w.encodingRelocHeader { - panic("encodingRelocHeader already true; recursive flush?") - } - w.encodingRelocHeader = true - w.Sync(SyncRelocs) - w.Len(len(w.Relocs)) - for _, rEnt := range w.Relocs { - w.Sync(SyncReloc) - w.Len(int(rEnt.Kind)) - w.Len(int(rEnt.Idx)) - } - - io.Copy(&sb, &w.Data) - io.Copy(&sb, &tmp) - w.p.elems[w.k][w.Idx] = sb.String() - - return w.Idx -} - -func (w *Encoder) checkErr(err error) { - if err != nil { - panicf("unexpected encoding error: %v", err) - } -} - -func (w *Encoder) rawUvarint(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - _, err := w.Data.Write(buf[:n]) - w.checkErr(err) -} - -func (w *Encoder) rawVarint(x int64) { - // Zig-zag encode. - ux := uint64(x) << 1 - if x < 0 { - ux = ^ux - } - - w.rawUvarint(ux) -} - -func (w *Encoder) rawReloc(r RelocKind, idx Index) int { - e := RelocEnt{r, idx} - if w.RelocMap != nil { - if i, ok := w.RelocMap[e]; ok { - return int(i) - } - } else { - w.RelocMap = make(map[RelocEnt]uint32) - } - - i := len(w.Relocs) - w.RelocMap[e] = uint32(i) - w.Relocs = append(w.Relocs, e) - return i -} - -func (w *Encoder) Sync(m SyncMarker) { - if !w.p.SyncMarkers() { - return - } - - // Writing out stack frame string references requires working - // relocations, but writing out the relocations themselves involves - // sync markers. To prevent infinite recursion, we simply trim the - // stack frame for sync markers within the relocation header. - var frames []string - if !w.encodingRelocHeader && w.p.syncFrames > 0 { - pcs := make([]uintptr, w.p.syncFrames) - n := runtime.Callers(2, pcs) - frames = fmtFrames(pcs[:n]...) - } - - // TODO(mdempsky): Save space by writing out stack frames as a - // linked list so we can share common stack frames. - w.rawUvarint(uint64(m)) - w.rawUvarint(uint64(len(frames))) - for _, frame := range frames { - w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) - } -} - -// Bool encodes and writes a bool value into the element bitstream, -// and then returns the bool value. -// -// For simple, 2-alternative encodings, the idiomatic way to call Bool -// is something like: -// -// if w.Bool(x != 0) { -// // alternative #1 -// } else { -// // alternative #2 -// } -// -// For multi-alternative encodings, use Code instead. -func (w *Encoder) Bool(b bool) bool { - w.Sync(SyncBool) - var x byte - if b { - x = 1 - } - err := w.Data.WriteByte(x) - w.checkErr(err) - return b -} - -// Int64 encodes and writes an int64 value into the element bitstream. -func (w *Encoder) Int64(x int64) { - w.Sync(SyncInt64) - w.rawVarint(x) -} - -// Uint64 encodes and writes a uint64 value into the element bitstream. -func (w *Encoder) Uint64(x uint64) { - w.Sync(SyncUint64) - w.rawUvarint(x) -} - -// Len encodes and writes a non-negative int value into the element bitstream. -func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } - -// Int encodes and writes an int value into the element bitstream. -func (w *Encoder) Int(x int) { w.Int64(int64(x)) } - -// Uint encodes and writes a uint value into the element bitstream. -func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } - -// Reloc encodes and writes a relocation for the given (section, -// index) pair into the element bitstream. -// -// Note: Only the index is formally written into the element -// bitstream, so bitstream decoders must know from context which -// section an encoded relocation refers to. -func (w *Encoder) Reloc(r RelocKind, idx Index) { - w.Sync(SyncUseReloc) - w.Len(w.rawReloc(r, idx)) -} - -// Code encodes and writes a Code value into the element bitstream. -func (w *Encoder) Code(c Code) { - w.Sync(c.Marker()) - w.Len(c.Value()) -} - -// String encodes and writes a string value into the element -// bitstream. -// -// Internally, strings are deduplicated by adding them to the strings -// section (if not already present), and then writing a relocation -// into the element bitstream. -func (w *Encoder) String(s string) { - w.StringRef(w.p.StringIdx(s)) -} - -// StringRef writes a reference to the given index, which must be a -// previously encoded string value. -func (w *Encoder) StringRef(idx Index) { - w.Sync(SyncString) - w.Reloc(RelocString, idx) -} - -// Strings encodes and writes a variable-length slice of strings into -// the element bitstream. -func (w *Encoder) Strings(ss []string) { - w.Len(len(ss)) - for _, s := range ss { - w.String(s) - } -} - -// Value encodes and writes a constant.Value into the element -// bitstream. -func (w *Encoder) Value(val constant.Value) { - w.Sync(SyncValue) - if w.Bool(val.Kind() == constant.Complex) { - w.scalar(constant.Real(val)) - w.scalar(constant.Imag(val)) - } else { - w.scalar(val) - } -} - -func (w *Encoder) scalar(val constant.Value) { - switch v := constant.Val(val).(type) { - default: - panicf("unhandled %v (%v)", val, val.Kind()) - case bool: - w.Code(ValBool) - w.Bool(v) - case string: - w.Code(ValString) - w.String(v) - case int64: - w.Code(ValInt64) - w.Int64(v) - case *big.Int: - w.Code(ValBigInt) - w.bigInt(v) - case *big.Rat: - w.Code(ValBigRat) - w.bigInt(v.Num()) - w.bigInt(v.Denom()) - case *big.Float: - w.Code(ValBigFloat) - w.bigFloat(v) - } -} - -func (w *Encoder) bigInt(v *big.Int) { - b := v.Bytes() - w.String(string(b)) // TODO: More efficient encoding. - w.Bool(v.Sign() < 0) -} - -func (w *Encoder) bigFloat(v *big.Float) { - b := v.Append(nil, 'p', -1) - w.String(string(b)) // TODO: More efficient encoding. -} - -// Version reports the version of the bitstream. -func (w *Encoder) Version() Version { return w.p.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go deleted file mode 100644 index 6542227..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/flags.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2022 The Go 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 pkgbits - -const ( - flagSyncMarkers = 1 << iota // file format contains sync markers -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go deleted file mode 100644 index fcdfb97..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go +++ /dev/null @@ -1,42 +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 pkgbits - -// A RelocKind indicates a particular section within a unified IR export. -type RelocKind int32 - -// An Index represents a bitstream element index within a particular -// section. -type Index int32 - -// A relocEnt (relocation entry) is an entry in an element's local -// reference table. -// -// TODO(mdempsky): Rename this too. -type RelocEnt struct { - Kind RelocKind - Idx Index -} - -// Reserved indices within the meta relocation section. -const ( - PublicRootIdx Index = 0 - PrivateRootIdx Index = 1 -) - -const ( - RelocString RelocKind = iota - RelocMeta - RelocPosBase - RelocPkg - RelocName - RelocType - RelocObj - RelocObjExt - RelocObjDict - RelocBody - - numRelocs = iota -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go deleted file mode 100644 index 50534a2..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/support.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 The Go 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 pkgbits - -import "fmt" - -func assert(b bool) { - if !b { - panic("assertion failed") - } -} - -func panicf(format string, args ...any) { - panic(fmt.Errorf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go deleted file mode 100644 index 1520b73..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/sync.go +++ /dev/null @@ -1,136 +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 pkgbits - -import ( - "fmt" - "runtime" - "strings" -) - -// fmtFrames formats a backtrace for reporting reader/writer desyncs. -func fmtFrames(pcs ...uintptr) []string { - res := make([]string, 0, len(pcs)) - walkFrames(pcs, func(file string, line int, name string, offset uintptr) { - // Trim package from function name. It's just redundant noise. - name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") - - res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) - }) - return res -} - -type frameVisitor func(file string, line int, name string, offset uintptr) - -// walkFrames calls visit for each call frame represented by pcs. -// -// pcs should be a slice of PCs, as returned by runtime.Callers. -func walkFrames(pcs []uintptr, visit frameVisitor) { - if len(pcs) == 0 { - return - } - - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) - if !more { - return - } - } -} - -// SyncMarker is an enum type that represents markers that may be -// written to export data to ensure the reader and writer stay -// synchronized. -type SyncMarker int - -//go:generate stringer -type=SyncMarker -trimprefix=Sync - -const ( - _ SyncMarker = iota - - // Public markers (known to go/types importers). - - // Low-level coding markers. - SyncEOF - SyncBool - SyncInt64 - SyncUint64 - SyncString - SyncValue - SyncVal - SyncRelocs - SyncReloc - SyncUseReloc - - // Higher-level object and type markers. - SyncPublic - SyncPos - SyncPosBase - SyncObject - SyncObject1 - SyncPkg - SyncPkgDef - SyncMethod - SyncType - SyncTypeIdx - SyncTypeParamNames - SyncSignature - SyncParams - SyncParam - SyncCodeObj - SyncSym - SyncLocalIdent - SyncSelector - - // Private markers (only known to cmd/compile). - SyncPrivate - - SyncFuncExt - SyncVarExt - SyncTypeExt - SyncPragma - - SyncExprList - SyncExprs - SyncExpr - SyncExprType - SyncAssign - SyncOp - SyncFuncLit - SyncCompLit - - SyncDecl - SyncFuncBody - SyncOpenScope - SyncCloseScope - SyncCloseAnotherScope - SyncDeclNames - SyncDeclName - - SyncStmts - SyncBlockStmt - SyncIfStmt - SyncForStmt - SyncSwitchStmt - SyncRangeStmt - SyncCaseClause - SyncCommClause - SyncSelectStmt - SyncDecls - SyncLabeledStmt - SyncUseObjLocal - SyncAddLocal - SyncLinkname - SyncStmt1 - SyncStmtsEnd - SyncLabel - SyncOptLabel - - SyncMultiExpr - SyncRType - SyncConvRTTI -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go deleted file mode 100644 index 582ad56..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go +++ /dev/null @@ -1,92 +0,0 @@ -// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. - -package pkgbits - -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[SyncEOF-1] - _ = x[SyncBool-2] - _ = x[SyncInt64-3] - _ = x[SyncUint64-4] - _ = x[SyncString-5] - _ = x[SyncValue-6] - _ = x[SyncVal-7] - _ = x[SyncRelocs-8] - _ = x[SyncReloc-9] - _ = x[SyncUseReloc-10] - _ = x[SyncPublic-11] - _ = x[SyncPos-12] - _ = x[SyncPosBase-13] - _ = x[SyncObject-14] - _ = x[SyncObject1-15] - _ = x[SyncPkg-16] - _ = x[SyncPkgDef-17] - _ = x[SyncMethod-18] - _ = x[SyncType-19] - _ = x[SyncTypeIdx-20] - _ = x[SyncTypeParamNames-21] - _ = x[SyncSignature-22] - _ = x[SyncParams-23] - _ = x[SyncParam-24] - _ = x[SyncCodeObj-25] - _ = x[SyncSym-26] - _ = x[SyncLocalIdent-27] - _ = x[SyncSelector-28] - _ = x[SyncPrivate-29] - _ = x[SyncFuncExt-30] - _ = x[SyncVarExt-31] - _ = x[SyncTypeExt-32] - _ = x[SyncPragma-33] - _ = x[SyncExprList-34] - _ = x[SyncExprs-35] - _ = x[SyncExpr-36] - _ = x[SyncExprType-37] - _ = x[SyncAssign-38] - _ = x[SyncOp-39] - _ = x[SyncFuncLit-40] - _ = x[SyncCompLit-41] - _ = x[SyncDecl-42] - _ = x[SyncFuncBody-43] - _ = x[SyncOpenScope-44] - _ = x[SyncCloseScope-45] - _ = x[SyncCloseAnotherScope-46] - _ = x[SyncDeclNames-47] - _ = x[SyncDeclName-48] - _ = x[SyncStmts-49] - _ = x[SyncBlockStmt-50] - _ = x[SyncIfStmt-51] - _ = x[SyncForStmt-52] - _ = x[SyncSwitchStmt-53] - _ = x[SyncRangeStmt-54] - _ = x[SyncCaseClause-55] - _ = x[SyncCommClause-56] - _ = x[SyncSelectStmt-57] - _ = x[SyncDecls-58] - _ = x[SyncLabeledStmt-59] - _ = x[SyncUseObjLocal-60] - _ = x[SyncAddLocal-61] - _ = x[SyncLinkname-62] - _ = x[SyncStmt1-63] - _ = x[SyncStmtsEnd-64] - _ = x[SyncLabel-65] - _ = x[SyncOptLabel-66] - _ = x[SyncMultiExpr-67] - _ = x[SyncRType-68] - _ = x[SyncConvRTTI-69] -} - -const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI" - -var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458, 467, 472, 480} - -func (i SyncMarker) String() string { - i -= 1 - if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { - return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go deleted file mode 100644 index 53af9df..0000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/version.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2024 The Go 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 pkgbits - -// Version indicates a version of a unified IR bitstream. -// Each Version indicates the addition, removal, or change of -// new data in the bitstream. -// -// These are serialized to disk and the interpretation remains fixed. -type Version uint32 - -const ( - // V0: initial prototype. - // - // All data that is not assigned a Field is in version V0 - // and has not been deprecated. - V0 Version = iota - - // V1: adds the Flags uint32 word - V1 - - // V2: removes unused legacy fields and supports type parameters for aliases. - // - remove the legacy "has init" bool from the public root - // - remove obj's "derived func instance" bool - // - add a TypeParamNames field to ObjAlias - // - remove derived info "needed" bool - V2 - - numVersions = iota -) - -// Field denotes a unit of data in the serialized unified IR bitstream. -// It is conceptually a like field in a structure. -// -// We only really need Fields when the data may or may not be present -// in a stream based on the Version of the bitstream. -// -// Unlike much of pkgbits, Fields are not serialized and -// can change values as needed. -type Field int - -const ( - // Flags in a uint32 in the header of a bitstream - // that is used to indicate whether optional features are enabled. - Flags Field = iota - - // Deprecated: HasInit was a bool indicating whether a package - // has any init functions. - HasInit - - // Deprecated: DerivedFuncInstance was a bool indicating - // whether an object was a function instance. - DerivedFuncInstance - - // ObjAlias has a list of TypeParamNames. - AliasTypeParamNames - - // Deprecated: DerivedInfoNeeded was a bool indicating - // whether a type was a derived type. - DerivedInfoNeeded - - numFields = iota -) - -// introduced is the version a field was added. -var introduced = [numFields]Version{ - Flags: V1, - AliasTypeParamNames: V2, -} - -// removed is the version a field was removed in or 0 for fields -// that have not yet been deprecated. -// (So removed[f]-1 is the last version it is included in.) -var removed = [numFields]Version{ - HasInit: V2, - DerivedFuncInstance: V2, - DerivedInfoNeeded: V2, -} - -// Has reports whether field f is present in a bitstream at version v. -func (v Version) Has(f Field) bool { - return introduced[f] <= v && (v < removed[f] || removed[f] == V0) -} diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go deleted file mode 100644 index 9f0b871..0000000 --- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go +++ /dev/null @@ -1,17650 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate.go. DO NOT EDIT. - -package stdlib - -var PackageSymbols = map[string][]Symbol{ - "archive/tar": { - {"(*Header).FileInfo", Method, 1}, - {"(*Reader).Next", Method, 0}, - {"(*Reader).Read", Method, 0}, - {"(*Writer).AddFS", Method, 22}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).Flush", Method, 0}, - {"(*Writer).Write", Method, 0}, - {"(*Writer).WriteHeader", Method, 0}, - {"(Format).String", Method, 10}, - {"ErrFieldTooLong", Var, 0}, - {"ErrHeader", Var, 0}, - {"ErrInsecurePath", Var, 20}, - {"ErrWriteAfterClose", Var, 0}, - {"ErrWriteTooLong", Var, 0}, - {"FileInfoHeader", Func, 1}, - {"FileInfoNames", Type, 23}, - {"Format", Type, 10}, - {"FormatGNU", Const, 10}, - {"FormatPAX", Const, 10}, - {"FormatUSTAR", Const, 10}, - {"FormatUnknown", Const, 10}, - {"Header", Type, 0}, - {"Header.AccessTime", Field, 0}, - {"Header.ChangeTime", Field, 0}, - {"Header.Devmajor", Field, 0}, - {"Header.Devminor", Field, 0}, - {"Header.Format", Field, 10}, - {"Header.Gid", Field, 0}, - {"Header.Gname", Field, 0}, - {"Header.Linkname", Field, 0}, - {"Header.ModTime", Field, 0}, - {"Header.Mode", Field, 0}, - {"Header.Name", Field, 0}, - {"Header.PAXRecords", Field, 10}, - {"Header.Size", Field, 0}, - {"Header.Typeflag", Field, 0}, - {"Header.Uid", Field, 0}, - {"Header.Uname", Field, 0}, - {"Header.Xattrs", Field, 3}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"Reader", Type, 0}, - {"TypeBlock", Const, 0}, - {"TypeChar", Const, 0}, - {"TypeCont", Const, 0}, - {"TypeDir", Const, 0}, - {"TypeFifo", Const, 0}, - {"TypeGNULongLink", Const, 1}, - {"TypeGNULongName", Const, 1}, - {"TypeGNUSparse", Const, 3}, - {"TypeLink", Const, 0}, - {"TypeReg", Const, 0}, - {"TypeRegA", Const, 0}, - {"TypeSymlink", Const, 0}, - {"TypeXGlobalHeader", Const, 0}, - {"TypeXHeader", Const, 0}, - {"Writer", Type, 0}, - }, - "archive/zip": { - {"(*File).DataOffset", Method, 2}, - {"(*File).FileInfo", Method, 0}, - {"(*File).ModTime", Method, 0}, - {"(*File).Mode", Method, 0}, - {"(*File).Open", Method, 0}, - {"(*File).OpenRaw", Method, 17}, - {"(*File).SetModTime", Method, 0}, - {"(*File).SetMode", Method, 0}, - {"(*FileHeader).FileInfo", Method, 0}, - {"(*FileHeader).ModTime", Method, 0}, - {"(*FileHeader).Mode", Method, 0}, - {"(*FileHeader).SetModTime", Method, 0}, - {"(*FileHeader).SetMode", Method, 0}, - {"(*ReadCloser).Close", Method, 0}, - {"(*ReadCloser).Open", Method, 16}, - {"(*ReadCloser).RegisterDecompressor", Method, 6}, - {"(*Reader).Open", Method, 16}, - {"(*Reader).RegisterDecompressor", Method, 6}, - {"(*Writer).AddFS", Method, 22}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).Copy", Method, 17}, - {"(*Writer).Create", Method, 0}, - {"(*Writer).CreateHeader", Method, 0}, - {"(*Writer).CreateRaw", Method, 17}, - {"(*Writer).Flush", Method, 4}, - {"(*Writer).RegisterCompressor", Method, 6}, - {"(*Writer).SetComment", Method, 10}, - {"(*Writer).SetOffset", Method, 5}, - {"Compressor", Type, 2}, - {"Decompressor", Type, 2}, - {"Deflate", Const, 0}, - {"ErrAlgorithm", Var, 0}, - {"ErrChecksum", Var, 0}, - {"ErrFormat", Var, 0}, - {"ErrInsecurePath", Var, 20}, - {"File", Type, 0}, - {"File.FileHeader", Field, 0}, - {"FileHeader", Type, 0}, - {"FileHeader.CRC32", Field, 0}, - {"FileHeader.Comment", Field, 0}, - {"FileHeader.CompressedSize", Field, 0}, - {"FileHeader.CompressedSize64", Field, 1}, - {"FileHeader.CreatorVersion", Field, 0}, - {"FileHeader.ExternalAttrs", Field, 0}, - {"FileHeader.Extra", Field, 0}, - {"FileHeader.Flags", Field, 0}, - {"FileHeader.Method", Field, 0}, - {"FileHeader.Modified", Field, 10}, - {"FileHeader.ModifiedDate", Field, 0}, - {"FileHeader.ModifiedTime", Field, 0}, - {"FileHeader.Name", Field, 0}, - {"FileHeader.NonUTF8", Field, 10}, - {"FileHeader.ReaderVersion", Field, 0}, - {"FileHeader.UncompressedSize", Field, 0}, - {"FileHeader.UncompressedSize64", Field, 1}, - {"FileInfoHeader", Func, 0}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"OpenReader", Func, 0}, - {"ReadCloser", Type, 0}, - {"ReadCloser.Reader", Field, 0}, - {"Reader", Type, 0}, - {"Reader.Comment", Field, 0}, - {"Reader.File", Field, 0}, - {"RegisterCompressor", Func, 2}, - {"RegisterDecompressor", Func, 2}, - {"Store", Const, 0}, - {"Writer", Type, 0}, - }, - "bufio": { - {"(*Reader).Buffered", Method, 0}, - {"(*Reader).Discard", Method, 5}, - {"(*Reader).Peek", Method, 0}, - {"(*Reader).Read", Method, 0}, - {"(*Reader).ReadByte", Method, 0}, - {"(*Reader).ReadBytes", Method, 0}, - {"(*Reader).ReadLine", Method, 0}, - {"(*Reader).ReadRune", Method, 0}, - {"(*Reader).ReadSlice", Method, 0}, - {"(*Reader).ReadString", Method, 0}, - {"(*Reader).Reset", Method, 2}, - {"(*Reader).Size", Method, 10}, - {"(*Reader).UnreadByte", Method, 0}, - {"(*Reader).UnreadRune", Method, 0}, - {"(*Reader).WriteTo", Method, 1}, - {"(*Scanner).Buffer", Method, 6}, - {"(*Scanner).Bytes", Method, 1}, - {"(*Scanner).Err", Method, 1}, - {"(*Scanner).Scan", Method, 1}, - {"(*Scanner).Split", Method, 1}, - {"(*Scanner).Text", Method, 1}, - {"(*Writer).Available", Method, 0}, - {"(*Writer).AvailableBuffer", Method, 18}, - {"(*Writer).Buffered", Method, 0}, - {"(*Writer).Flush", Method, 0}, - {"(*Writer).ReadFrom", Method, 1}, - {"(*Writer).Reset", Method, 2}, - {"(*Writer).Size", Method, 10}, - {"(*Writer).Write", Method, 0}, - {"(*Writer).WriteByte", Method, 0}, - {"(*Writer).WriteRune", Method, 0}, - {"(*Writer).WriteString", Method, 0}, - {"(ReadWriter).Available", Method, 0}, - {"(ReadWriter).AvailableBuffer", Method, 18}, - {"(ReadWriter).Discard", Method, 5}, - {"(ReadWriter).Flush", Method, 0}, - {"(ReadWriter).Peek", Method, 0}, - {"(ReadWriter).Read", Method, 0}, - {"(ReadWriter).ReadByte", Method, 0}, - {"(ReadWriter).ReadBytes", Method, 0}, - {"(ReadWriter).ReadFrom", Method, 1}, - {"(ReadWriter).ReadLine", Method, 0}, - {"(ReadWriter).ReadRune", Method, 0}, - {"(ReadWriter).ReadSlice", Method, 0}, - {"(ReadWriter).ReadString", Method, 0}, - {"(ReadWriter).UnreadByte", Method, 0}, - {"(ReadWriter).UnreadRune", Method, 0}, - {"(ReadWriter).Write", Method, 0}, - {"(ReadWriter).WriteByte", Method, 0}, - {"(ReadWriter).WriteRune", Method, 0}, - {"(ReadWriter).WriteString", Method, 0}, - {"(ReadWriter).WriteTo", Method, 1}, - {"ErrAdvanceTooFar", Var, 1}, - {"ErrBadReadCount", Var, 15}, - {"ErrBufferFull", Var, 0}, - {"ErrFinalToken", Var, 6}, - {"ErrInvalidUnreadByte", Var, 0}, - {"ErrInvalidUnreadRune", Var, 0}, - {"ErrNegativeAdvance", Var, 1}, - {"ErrNegativeCount", Var, 0}, - {"ErrTooLong", Var, 1}, - {"MaxScanTokenSize", Const, 1}, - {"NewReadWriter", Func, 0}, - {"NewReader", Func, 0}, - {"NewReaderSize", Func, 0}, - {"NewScanner", Func, 1}, - {"NewWriter", Func, 0}, - {"NewWriterSize", Func, 0}, - {"ReadWriter", Type, 0}, - {"ReadWriter.Reader", Field, 0}, - {"ReadWriter.Writer", Field, 0}, - {"Reader", Type, 0}, - {"ScanBytes", Func, 1}, - {"ScanLines", Func, 1}, - {"ScanRunes", Func, 1}, - {"ScanWords", Func, 1}, - {"Scanner", Type, 1}, - {"SplitFunc", Type, 1}, - {"Writer", Type, 0}, - }, - "bytes": { - {"(*Buffer).Available", Method, 21}, - {"(*Buffer).AvailableBuffer", Method, 21}, - {"(*Buffer).Bytes", Method, 0}, - {"(*Buffer).Cap", Method, 5}, - {"(*Buffer).Grow", Method, 1}, - {"(*Buffer).Len", Method, 0}, - {"(*Buffer).Next", Method, 0}, - {"(*Buffer).Read", Method, 0}, - {"(*Buffer).ReadByte", Method, 0}, - {"(*Buffer).ReadBytes", Method, 0}, - {"(*Buffer).ReadFrom", Method, 0}, - {"(*Buffer).ReadRune", Method, 0}, - {"(*Buffer).ReadString", Method, 0}, - {"(*Buffer).Reset", Method, 0}, - {"(*Buffer).String", Method, 0}, - {"(*Buffer).Truncate", Method, 0}, - {"(*Buffer).UnreadByte", Method, 0}, - {"(*Buffer).UnreadRune", Method, 0}, - {"(*Buffer).Write", Method, 0}, - {"(*Buffer).WriteByte", Method, 0}, - {"(*Buffer).WriteRune", Method, 0}, - {"(*Buffer).WriteString", Method, 0}, - {"(*Buffer).WriteTo", Method, 0}, - {"(*Reader).Len", Method, 0}, - {"(*Reader).Read", Method, 0}, - {"(*Reader).ReadAt", Method, 0}, - {"(*Reader).ReadByte", Method, 0}, - {"(*Reader).ReadRune", Method, 0}, - {"(*Reader).Reset", Method, 7}, - {"(*Reader).Seek", Method, 0}, - {"(*Reader).Size", Method, 5}, - {"(*Reader).UnreadByte", Method, 0}, - {"(*Reader).UnreadRune", Method, 0}, - {"(*Reader).WriteTo", Method, 1}, - {"Buffer", Type, 0}, - {"Clone", Func, 20}, - {"Compare", Func, 0}, - {"Contains", Func, 0}, - {"ContainsAny", Func, 7}, - {"ContainsFunc", Func, 21}, - {"ContainsRune", Func, 7}, - {"Count", Func, 0}, - {"Cut", Func, 18}, - {"CutPrefix", Func, 20}, - {"CutSuffix", Func, 20}, - {"Equal", Func, 0}, - {"EqualFold", Func, 0}, - {"ErrTooLarge", Var, 0}, - {"Fields", Func, 0}, - {"FieldsFunc", Func, 0}, - {"FieldsFuncSeq", Func, 24}, - {"FieldsSeq", Func, 24}, - {"HasPrefix", Func, 0}, - {"HasSuffix", Func, 0}, - {"Index", Func, 0}, - {"IndexAny", Func, 0}, - {"IndexByte", Func, 0}, - {"IndexFunc", Func, 0}, - {"IndexRune", Func, 0}, - {"Join", Func, 0}, - {"LastIndex", Func, 0}, - {"LastIndexAny", Func, 0}, - {"LastIndexByte", Func, 5}, - {"LastIndexFunc", Func, 0}, - {"Lines", Func, 24}, - {"Map", Func, 0}, - {"MinRead", Const, 0}, - {"NewBuffer", Func, 0}, - {"NewBufferString", Func, 0}, - {"NewReader", Func, 0}, - {"Reader", Type, 0}, - {"Repeat", Func, 0}, - {"Replace", Func, 0}, - {"ReplaceAll", Func, 12}, - {"Runes", Func, 0}, - {"Split", Func, 0}, - {"SplitAfter", Func, 0}, - {"SplitAfterN", Func, 0}, - {"SplitAfterSeq", Func, 24}, - {"SplitN", Func, 0}, - {"SplitSeq", Func, 24}, - {"Title", Func, 0}, - {"ToLower", Func, 0}, - {"ToLowerSpecial", Func, 0}, - {"ToTitle", Func, 0}, - {"ToTitleSpecial", Func, 0}, - {"ToUpper", Func, 0}, - {"ToUpperSpecial", Func, 0}, - {"ToValidUTF8", Func, 13}, - {"Trim", Func, 0}, - {"TrimFunc", Func, 0}, - {"TrimLeft", Func, 0}, - {"TrimLeftFunc", Func, 0}, - {"TrimPrefix", Func, 1}, - {"TrimRight", Func, 0}, - {"TrimRightFunc", Func, 0}, - {"TrimSpace", Func, 0}, - {"TrimSuffix", Func, 1}, - }, - "cmp": { - {"Compare", Func, 21}, - {"Less", Func, 21}, - {"Or", Func, 22}, - {"Ordered", Type, 21}, - }, - "compress/bzip2": { - {"(StructuralError).Error", Method, 0}, - {"NewReader", Func, 0}, - {"StructuralError", Type, 0}, - }, - "compress/flate": { - {"(*ReadError).Error", Method, 0}, - {"(*WriteError).Error", Method, 0}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).Flush", Method, 0}, - {"(*Writer).Reset", Method, 2}, - {"(*Writer).Write", Method, 0}, - {"(CorruptInputError).Error", Method, 0}, - {"(InternalError).Error", Method, 0}, - {"BestCompression", Const, 0}, - {"BestSpeed", Const, 0}, - {"CorruptInputError", Type, 0}, - {"DefaultCompression", Const, 0}, - {"HuffmanOnly", Const, 7}, - {"InternalError", Type, 0}, - {"NewReader", Func, 0}, - {"NewReaderDict", Func, 0}, - {"NewWriter", Func, 0}, - {"NewWriterDict", Func, 0}, - {"NoCompression", Const, 0}, - {"ReadError", Type, 0}, - {"ReadError.Err", Field, 0}, - {"ReadError.Offset", Field, 0}, - {"Reader", Type, 0}, - {"Resetter", Type, 4}, - {"WriteError", Type, 0}, - {"WriteError.Err", Field, 0}, - {"WriteError.Offset", Field, 0}, - {"Writer", Type, 0}, - }, - "compress/gzip": { - {"(*Reader).Close", Method, 0}, - {"(*Reader).Multistream", Method, 4}, - {"(*Reader).Read", Method, 0}, - {"(*Reader).Reset", Method, 3}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).Flush", Method, 1}, - {"(*Writer).Reset", Method, 2}, - {"(*Writer).Write", Method, 0}, - {"BestCompression", Const, 0}, - {"BestSpeed", Const, 0}, - {"DefaultCompression", Const, 0}, - {"ErrChecksum", Var, 0}, - {"ErrHeader", Var, 0}, - {"Header", Type, 0}, - {"Header.Comment", Field, 0}, - {"Header.Extra", Field, 0}, - {"Header.ModTime", Field, 0}, - {"Header.Name", Field, 0}, - {"Header.OS", Field, 0}, - {"HuffmanOnly", Const, 8}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"NewWriterLevel", Func, 0}, - {"NoCompression", Const, 0}, - {"Reader", Type, 0}, - {"Reader.Header", Field, 0}, - {"Writer", Type, 0}, - {"Writer.Header", Field, 0}, - }, - "compress/lzw": { - {"(*Reader).Close", Method, 17}, - {"(*Reader).Read", Method, 17}, - {"(*Reader).Reset", Method, 17}, - {"(*Writer).Close", Method, 17}, - {"(*Writer).Reset", Method, 17}, - {"(*Writer).Write", Method, 17}, - {"LSB", Const, 0}, - {"MSB", Const, 0}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"Order", Type, 0}, - {"Reader", Type, 17}, - {"Writer", Type, 17}, - }, - "compress/zlib": { - {"(*Writer).Close", Method, 0}, - {"(*Writer).Flush", Method, 0}, - {"(*Writer).Reset", Method, 2}, - {"(*Writer).Write", Method, 0}, - {"BestCompression", Const, 0}, - {"BestSpeed", Const, 0}, - {"DefaultCompression", Const, 0}, - {"ErrChecksum", Var, 0}, - {"ErrDictionary", Var, 0}, - {"ErrHeader", Var, 0}, - {"HuffmanOnly", Const, 8}, - {"NewReader", Func, 0}, - {"NewReaderDict", Func, 0}, - {"NewWriter", Func, 0}, - {"NewWriterLevel", Func, 0}, - {"NewWriterLevelDict", Func, 0}, - {"NoCompression", Const, 0}, - {"Resetter", Type, 4}, - {"Writer", Type, 0}, - }, - "container/heap": { - {"Fix", Func, 2}, - {"Init", Func, 0}, - {"Interface", Type, 0}, - {"Pop", Func, 0}, - {"Push", Func, 0}, - {"Remove", Func, 0}, - }, - "container/list": { - {"(*Element).Next", Method, 0}, - {"(*Element).Prev", Method, 0}, - {"(*List).Back", Method, 0}, - {"(*List).Front", Method, 0}, - {"(*List).Init", Method, 0}, - {"(*List).InsertAfter", Method, 0}, - {"(*List).InsertBefore", Method, 0}, - {"(*List).Len", Method, 0}, - {"(*List).MoveAfter", Method, 2}, - {"(*List).MoveBefore", Method, 2}, - {"(*List).MoveToBack", Method, 0}, - {"(*List).MoveToFront", Method, 0}, - {"(*List).PushBack", Method, 0}, - {"(*List).PushBackList", Method, 0}, - {"(*List).PushFront", Method, 0}, - {"(*List).PushFrontList", Method, 0}, - {"(*List).Remove", Method, 0}, - {"Element", Type, 0}, - {"Element.Value", Field, 0}, - {"List", Type, 0}, - {"New", Func, 0}, - }, - "container/ring": { - {"(*Ring).Do", Method, 0}, - {"(*Ring).Len", Method, 0}, - {"(*Ring).Link", Method, 0}, - {"(*Ring).Move", Method, 0}, - {"(*Ring).Next", Method, 0}, - {"(*Ring).Prev", Method, 0}, - {"(*Ring).Unlink", Method, 0}, - {"New", Func, 0}, - {"Ring", Type, 0}, - {"Ring.Value", Field, 0}, - }, - "context": { - {"AfterFunc", Func, 21}, - {"Background", Func, 7}, - {"CancelCauseFunc", Type, 20}, - {"CancelFunc", Type, 7}, - {"Canceled", Var, 7}, - {"Cause", Func, 20}, - {"Context", Type, 7}, - {"DeadlineExceeded", Var, 7}, - {"TODO", Func, 7}, - {"WithCancel", Func, 7}, - {"WithCancelCause", Func, 20}, - {"WithDeadline", Func, 7}, - {"WithDeadlineCause", Func, 21}, - {"WithTimeout", Func, 7}, - {"WithTimeoutCause", Func, 21}, - {"WithValue", Func, 7}, - {"WithoutCancel", Func, 21}, - }, - "crypto": { - {"(Hash).Available", Method, 0}, - {"(Hash).HashFunc", Method, 4}, - {"(Hash).New", Method, 0}, - {"(Hash).Size", Method, 0}, - {"(Hash).String", Method, 15}, - {"BLAKE2b_256", Const, 9}, - {"BLAKE2b_384", Const, 9}, - {"BLAKE2b_512", Const, 9}, - {"BLAKE2s_256", Const, 9}, - {"Decrypter", Type, 5}, - {"DecrypterOpts", Type, 5}, - {"Hash", Type, 0}, - {"MD4", Const, 0}, - {"MD5", Const, 0}, - {"MD5SHA1", Const, 0}, - {"PrivateKey", Type, 0}, - {"PublicKey", Type, 2}, - {"RIPEMD160", Const, 0}, - {"RegisterHash", Func, 0}, - {"SHA1", Const, 0}, - {"SHA224", Const, 0}, - {"SHA256", Const, 0}, - {"SHA384", Const, 0}, - {"SHA3_224", Const, 4}, - {"SHA3_256", Const, 4}, - {"SHA3_384", Const, 4}, - {"SHA3_512", Const, 4}, - {"SHA512", Const, 0}, - {"SHA512_224", Const, 5}, - {"SHA512_256", Const, 5}, - {"Signer", Type, 4}, - {"SignerOpts", Type, 4}, - }, - "crypto/aes": { - {"(KeySizeError).Error", Method, 0}, - {"BlockSize", Const, 0}, - {"KeySizeError", Type, 0}, - {"NewCipher", Func, 0}, - }, - "crypto/cipher": { - {"(StreamReader).Read", Method, 0}, - {"(StreamWriter).Close", Method, 0}, - {"(StreamWriter).Write", Method, 0}, - {"AEAD", Type, 2}, - {"Block", Type, 0}, - {"BlockMode", Type, 0}, - {"NewCBCDecrypter", Func, 0}, - {"NewCBCEncrypter", Func, 0}, - {"NewCFBDecrypter", Func, 0}, - {"NewCFBEncrypter", Func, 0}, - {"NewCTR", Func, 0}, - {"NewGCM", Func, 2}, - {"NewGCMWithNonceSize", Func, 5}, - {"NewGCMWithRandomNonce", Func, 24}, - {"NewGCMWithTagSize", Func, 11}, - {"NewOFB", Func, 0}, - {"Stream", Type, 0}, - {"StreamReader", Type, 0}, - {"StreamReader.R", Field, 0}, - {"StreamReader.S", Field, 0}, - {"StreamWriter", Type, 0}, - {"StreamWriter.Err", Field, 0}, - {"StreamWriter.S", Field, 0}, - {"StreamWriter.W", Field, 0}, - }, - "crypto/des": { - {"(KeySizeError).Error", Method, 0}, - {"BlockSize", Const, 0}, - {"KeySizeError", Type, 0}, - {"NewCipher", Func, 0}, - {"NewTripleDESCipher", Func, 0}, - }, - "crypto/dsa": { - {"ErrInvalidPublicKey", Var, 0}, - {"GenerateKey", Func, 0}, - {"GenerateParameters", Func, 0}, - {"L1024N160", Const, 0}, - {"L2048N224", Const, 0}, - {"L2048N256", Const, 0}, - {"L3072N256", Const, 0}, - {"ParameterSizes", Type, 0}, - {"Parameters", Type, 0}, - {"Parameters.G", Field, 0}, - {"Parameters.P", Field, 0}, - {"Parameters.Q", Field, 0}, - {"PrivateKey", Type, 0}, - {"PrivateKey.PublicKey", Field, 0}, - {"PrivateKey.X", Field, 0}, - {"PublicKey", Type, 0}, - {"PublicKey.Parameters", Field, 0}, - {"PublicKey.Y", Field, 0}, - {"Sign", Func, 0}, - {"Verify", Func, 0}, - }, - "crypto/ecdh": { - {"(*PrivateKey).Bytes", Method, 20}, - {"(*PrivateKey).Curve", Method, 20}, - {"(*PrivateKey).ECDH", Method, 20}, - {"(*PrivateKey).Equal", Method, 20}, - {"(*PrivateKey).Public", Method, 20}, - {"(*PrivateKey).PublicKey", Method, 20}, - {"(*PublicKey).Bytes", Method, 20}, - {"(*PublicKey).Curve", Method, 20}, - {"(*PublicKey).Equal", Method, 20}, - {"Curve", Type, 20}, - {"P256", Func, 20}, - {"P384", Func, 20}, - {"P521", Func, 20}, - {"PrivateKey", Type, 20}, - {"PublicKey", Type, 20}, - {"X25519", Func, 20}, - }, - "crypto/ecdsa": { - {"(*PrivateKey).ECDH", Method, 20}, - {"(*PrivateKey).Equal", Method, 15}, - {"(*PrivateKey).Public", Method, 4}, - {"(*PrivateKey).Sign", Method, 4}, - {"(*PublicKey).ECDH", Method, 20}, - {"(*PublicKey).Equal", Method, 15}, - {"(PrivateKey).Add", Method, 0}, - {"(PrivateKey).Double", Method, 0}, - {"(PrivateKey).IsOnCurve", Method, 0}, - {"(PrivateKey).Params", Method, 0}, - {"(PrivateKey).ScalarBaseMult", Method, 0}, - {"(PrivateKey).ScalarMult", Method, 0}, - {"(PublicKey).Add", Method, 0}, - {"(PublicKey).Double", Method, 0}, - {"(PublicKey).IsOnCurve", Method, 0}, - {"(PublicKey).Params", Method, 0}, - {"(PublicKey).ScalarBaseMult", Method, 0}, - {"(PublicKey).ScalarMult", Method, 0}, - {"GenerateKey", Func, 0}, - {"PrivateKey", Type, 0}, - {"PrivateKey.D", Field, 0}, - {"PrivateKey.PublicKey", Field, 0}, - {"PublicKey", Type, 0}, - {"PublicKey.Curve", Field, 0}, - {"PublicKey.X", Field, 0}, - {"PublicKey.Y", Field, 0}, - {"Sign", Func, 0}, - {"SignASN1", Func, 15}, - {"Verify", Func, 0}, - {"VerifyASN1", Func, 15}, - }, - "crypto/ed25519": { - {"(*Options).HashFunc", Method, 20}, - {"(PrivateKey).Equal", Method, 15}, - {"(PrivateKey).Public", Method, 13}, - {"(PrivateKey).Seed", Method, 13}, - {"(PrivateKey).Sign", Method, 13}, - {"(PublicKey).Equal", Method, 15}, - {"GenerateKey", Func, 13}, - {"NewKeyFromSeed", Func, 13}, - {"Options", Type, 20}, - {"Options.Context", Field, 20}, - {"Options.Hash", Field, 20}, - {"PrivateKey", Type, 13}, - {"PrivateKeySize", Const, 13}, - {"PublicKey", Type, 13}, - {"PublicKeySize", Const, 13}, - {"SeedSize", Const, 13}, - {"Sign", Func, 13}, - {"SignatureSize", Const, 13}, - {"Verify", Func, 13}, - {"VerifyWithOptions", Func, 20}, - }, - "crypto/elliptic": { - {"(*CurveParams).Add", Method, 0}, - {"(*CurveParams).Double", Method, 0}, - {"(*CurveParams).IsOnCurve", Method, 0}, - {"(*CurveParams).Params", Method, 0}, - {"(*CurveParams).ScalarBaseMult", Method, 0}, - {"(*CurveParams).ScalarMult", Method, 0}, - {"Curve", Type, 0}, - {"CurveParams", Type, 0}, - {"CurveParams.B", Field, 0}, - {"CurveParams.BitSize", Field, 0}, - {"CurveParams.Gx", Field, 0}, - {"CurveParams.Gy", Field, 0}, - {"CurveParams.N", Field, 0}, - {"CurveParams.Name", Field, 5}, - {"CurveParams.P", Field, 0}, - {"GenerateKey", Func, 0}, - {"Marshal", Func, 0}, - {"MarshalCompressed", Func, 15}, - {"P224", Func, 0}, - {"P256", Func, 0}, - {"P384", Func, 0}, - {"P521", Func, 0}, - {"Unmarshal", Func, 0}, - {"UnmarshalCompressed", Func, 15}, - }, - "crypto/fips140": { - {"Enabled", Func, 24}, - }, - "crypto/hkdf": { - {"Expand", Func, 24}, - {"Extract", Func, 24}, - {"Key", Func, 24}, - }, - "crypto/hmac": { - {"Equal", Func, 1}, - {"New", Func, 0}, - }, - "crypto/md5": { - {"BlockSize", Const, 0}, - {"New", Func, 0}, - {"Size", Const, 0}, - {"Sum", Func, 2}, - }, - "crypto/mlkem": { - {"(*DecapsulationKey1024).Bytes", Method, 24}, - {"(*DecapsulationKey1024).Decapsulate", Method, 24}, - {"(*DecapsulationKey1024).EncapsulationKey", Method, 24}, - {"(*DecapsulationKey768).Bytes", Method, 24}, - {"(*DecapsulationKey768).Decapsulate", Method, 24}, - {"(*DecapsulationKey768).EncapsulationKey", Method, 24}, - {"(*EncapsulationKey1024).Bytes", Method, 24}, - {"(*EncapsulationKey1024).Encapsulate", Method, 24}, - {"(*EncapsulationKey768).Bytes", Method, 24}, - {"(*EncapsulationKey768).Encapsulate", Method, 24}, - {"CiphertextSize1024", Const, 24}, - {"CiphertextSize768", Const, 24}, - {"DecapsulationKey1024", Type, 24}, - {"DecapsulationKey768", Type, 24}, - {"EncapsulationKey1024", Type, 24}, - {"EncapsulationKey768", Type, 24}, - {"EncapsulationKeySize1024", Const, 24}, - {"EncapsulationKeySize768", Const, 24}, - {"GenerateKey1024", Func, 24}, - {"GenerateKey768", Func, 24}, - {"NewDecapsulationKey1024", Func, 24}, - {"NewDecapsulationKey768", Func, 24}, - {"NewEncapsulationKey1024", Func, 24}, - {"NewEncapsulationKey768", Func, 24}, - {"SeedSize", Const, 24}, - {"SharedKeySize", Const, 24}, - }, - "crypto/pbkdf2": { - {"Key", Func, 24}, - }, - "crypto/rand": { - {"Int", Func, 0}, - {"Prime", Func, 0}, - {"Read", Func, 0}, - {"Reader", Var, 0}, - {"Text", Func, 24}, - }, - "crypto/rc4": { - {"(*Cipher).Reset", Method, 0}, - {"(*Cipher).XORKeyStream", Method, 0}, - {"(KeySizeError).Error", Method, 0}, - {"Cipher", Type, 0}, - {"KeySizeError", Type, 0}, - {"NewCipher", Func, 0}, - }, - "crypto/rsa": { - {"(*PSSOptions).HashFunc", Method, 4}, - {"(*PrivateKey).Decrypt", Method, 5}, - {"(*PrivateKey).Equal", Method, 15}, - {"(*PrivateKey).Precompute", Method, 0}, - {"(*PrivateKey).Public", Method, 4}, - {"(*PrivateKey).Sign", Method, 4}, - {"(*PrivateKey).Size", Method, 11}, - {"(*PrivateKey).Validate", Method, 0}, - {"(*PublicKey).Equal", Method, 15}, - {"(*PublicKey).Size", Method, 11}, - {"CRTValue", Type, 0}, - {"CRTValue.Coeff", Field, 0}, - {"CRTValue.Exp", Field, 0}, - {"CRTValue.R", Field, 0}, - {"DecryptOAEP", Func, 0}, - {"DecryptPKCS1v15", Func, 0}, - {"DecryptPKCS1v15SessionKey", Func, 0}, - {"EncryptOAEP", Func, 0}, - {"EncryptPKCS1v15", Func, 0}, - {"ErrDecryption", Var, 0}, - {"ErrMessageTooLong", Var, 0}, - {"ErrVerification", Var, 0}, - {"GenerateKey", Func, 0}, - {"GenerateMultiPrimeKey", Func, 0}, - {"OAEPOptions", Type, 5}, - {"OAEPOptions.Hash", Field, 5}, - {"OAEPOptions.Label", Field, 5}, - {"OAEPOptions.MGFHash", Field, 20}, - {"PKCS1v15DecryptOptions", Type, 5}, - {"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5}, - {"PSSOptions", Type, 2}, - {"PSSOptions.Hash", Field, 4}, - {"PSSOptions.SaltLength", Field, 2}, - {"PSSSaltLengthAuto", Const, 2}, - {"PSSSaltLengthEqualsHash", Const, 2}, - {"PrecomputedValues", Type, 0}, - {"PrecomputedValues.CRTValues", Field, 0}, - {"PrecomputedValues.Dp", Field, 0}, - {"PrecomputedValues.Dq", Field, 0}, - {"PrecomputedValues.Qinv", Field, 0}, - {"PrivateKey", Type, 0}, - {"PrivateKey.D", Field, 0}, - {"PrivateKey.Precomputed", Field, 0}, - {"PrivateKey.Primes", Field, 0}, - {"PrivateKey.PublicKey", Field, 0}, - {"PublicKey", Type, 0}, - {"PublicKey.E", Field, 0}, - {"PublicKey.N", Field, 0}, - {"SignPKCS1v15", Func, 0}, - {"SignPSS", Func, 2}, - {"VerifyPKCS1v15", Func, 0}, - {"VerifyPSS", Func, 2}, - }, - "crypto/sha1": { - {"BlockSize", Const, 0}, - {"New", Func, 0}, - {"Size", Const, 0}, - {"Sum", Func, 2}, - }, - "crypto/sha256": { - {"BlockSize", Const, 0}, - {"New", Func, 0}, - {"New224", Func, 0}, - {"Size", Const, 0}, - {"Size224", Const, 0}, - {"Sum224", Func, 2}, - {"Sum256", Func, 2}, - }, - "crypto/sha3": { - {"(*SHA3).AppendBinary", Method, 24}, - {"(*SHA3).BlockSize", Method, 24}, - {"(*SHA3).MarshalBinary", Method, 24}, - {"(*SHA3).Reset", Method, 24}, - {"(*SHA3).Size", Method, 24}, - {"(*SHA3).Sum", Method, 24}, - {"(*SHA3).UnmarshalBinary", Method, 24}, - {"(*SHA3).Write", Method, 24}, - {"(*SHAKE).AppendBinary", Method, 24}, - {"(*SHAKE).BlockSize", Method, 24}, - {"(*SHAKE).MarshalBinary", Method, 24}, - {"(*SHAKE).Read", Method, 24}, - {"(*SHAKE).Reset", Method, 24}, - {"(*SHAKE).UnmarshalBinary", Method, 24}, - {"(*SHAKE).Write", Method, 24}, - {"New224", Func, 24}, - {"New256", Func, 24}, - {"New384", Func, 24}, - {"New512", Func, 24}, - {"NewCSHAKE128", Func, 24}, - {"NewCSHAKE256", Func, 24}, - {"NewSHAKE128", Func, 24}, - {"NewSHAKE256", Func, 24}, - {"SHA3", Type, 24}, - {"SHAKE", Type, 24}, - {"Sum224", Func, 24}, - {"Sum256", Func, 24}, - {"Sum384", Func, 24}, - {"Sum512", Func, 24}, - {"SumSHAKE128", Func, 24}, - {"SumSHAKE256", Func, 24}, - }, - "crypto/sha512": { - {"BlockSize", Const, 0}, - {"New", Func, 0}, - {"New384", Func, 0}, - {"New512_224", Func, 5}, - {"New512_256", Func, 5}, - {"Size", Const, 0}, - {"Size224", Const, 5}, - {"Size256", Const, 5}, - {"Size384", Const, 0}, - {"Sum384", Func, 2}, - {"Sum512", Func, 2}, - {"Sum512_224", Func, 5}, - {"Sum512_256", Func, 5}, - }, - "crypto/subtle": { - {"ConstantTimeByteEq", Func, 0}, - {"ConstantTimeCompare", Func, 0}, - {"ConstantTimeCopy", Func, 0}, - {"ConstantTimeEq", Func, 0}, - {"ConstantTimeLessOrEq", Func, 2}, - {"ConstantTimeSelect", Func, 0}, - {"WithDataIndependentTiming", Func, 24}, - {"XORBytes", Func, 20}, - }, - "crypto/tls": { - {"(*CertificateRequestInfo).Context", Method, 17}, - {"(*CertificateRequestInfo).SupportsCertificate", Method, 14}, - {"(*CertificateVerificationError).Error", Method, 20}, - {"(*CertificateVerificationError).Unwrap", Method, 20}, - {"(*ClientHelloInfo).Context", Method, 17}, - {"(*ClientHelloInfo).SupportsCertificate", Method, 14}, - {"(*ClientSessionState).ResumptionState", Method, 21}, - {"(*Config).BuildNameToCertificate", Method, 0}, - {"(*Config).Clone", Method, 8}, - {"(*Config).DecryptTicket", Method, 21}, - {"(*Config).EncryptTicket", Method, 21}, - {"(*Config).SetSessionTicketKeys", Method, 5}, - {"(*Conn).Close", Method, 0}, - {"(*Conn).CloseWrite", Method, 8}, - {"(*Conn).ConnectionState", Method, 0}, - {"(*Conn).Handshake", Method, 0}, - {"(*Conn).HandshakeContext", Method, 17}, - {"(*Conn).LocalAddr", Method, 0}, - {"(*Conn).NetConn", Method, 18}, - {"(*Conn).OCSPResponse", Method, 0}, - {"(*Conn).Read", Method, 0}, - {"(*Conn).RemoteAddr", Method, 0}, - {"(*Conn).SetDeadline", Method, 0}, - {"(*Conn).SetReadDeadline", Method, 0}, - {"(*Conn).SetWriteDeadline", Method, 0}, - {"(*Conn).VerifyHostname", Method, 0}, - {"(*Conn).Write", Method, 0}, - {"(*ConnectionState).ExportKeyingMaterial", Method, 11}, - {"(*Dialer).Dial", Method, 15}, - {"(*Dialer).DialContext", Method, 15}, - {"(*ECHRejectionError).Error", Method, 23}, - {"(*QUICConn).Close", Method, 21}, - {"(*QUICConn).ConnectionState", Method, 21}, - {"(*QUICConn).HandleData", Method, 21}, - {"(*QUICConn).NextEvent", Method, 21}, - {"(*QUICConn).SendSessionTicket", Method, 21}, - {"(*QUICConn).SetTransportParameters", Method, 21}, - {"(*QUICConn).Start", Method, 21}, - {"(*QUICConn).StoreSession", Method, 23}, - {"(*SessionState).Bytes", Method, 21}, - {"(AlertError).Error", Method, 21}, - {"(ClientAuthType).String", Method, 15}, - {"(CurveID).String", Method, 15}, - {"(QUICEncryptionLevel).String", Method, 21}, - {"(RecordHeaderError).Error", Method, 6}, - {"(SignatureScheme).String", Method, 15}, - {"AlertError", Type, 21}, - {"Certificate", Type, 0}, - {"Certificate.Certificate", Field, 0}, - {"Certificate.Leaf", Field, 0}, - {"Certificate.OCSPStaple", Field, 0}, - {"Certificate.PrivateKey", Field, 0}, - {"Certificate.SignedCertificateTimestamps", Field, 5}, - {"Certificate.SupportedSignatureAlgorithms", Field, 14}, - {"CertificateRequestInfo", Type, 8}, - {"CertificateRequestInfo.AcceptableCAs", Field, 8}, - {"CertificateRequestInfo.SignatureSchemes", Field, 8}, - {"CertificateRequestInfo.Version", Field, 14}, - {"CertificateVerificationError", Type, 20}, - {"CertificateVerificationError.Err", Field, 20}, - {"CertificateVerificationError.UnverifiedCertificates", Field, 20}, - {"CipherSuite", Type, 14}, - {"CipherSuite.ID", Field, 14}, - {"CipherSuite.Insecure", Field, 14}, - {"CipherSuite.Name", Field, 14}, - {"CipherSuite.SupportedVersions", Field, 14}, - {"CipherSuiteName", Func, 14}, - {"CipherSuites", Func, 14}, - {"Client", Func, 0}, - {"ClientAuthType", Type, 0}, - {"ClientHelloInfo", Type, 4}, - {"ClientHelloInfo.CipherSuites", Field, 4}, - {"ClientHelloInfo.Conn", Field, 8}, - {"ClientHelloInfo.Extensions", Field, 24}, - {"ClientHelloInfo.ServerName", Field, 4}, - {"ClientHelloInfo.SignatureSchemes", Field, 8}, - {"ClientHelloInfo.SupportedCurves", Field, 4}, - {"ClientHelloInfo.SupportedPoints", Field, 4}, - {"ClientHelloInfo.SupportedProtos", Field, 8}, - {"ClientHelloInfo.SupportedVersions", Field, 8}, - {"ClientSessionCache", Type, 3}, - {"ClientSessionState", Type, 3}, - {"Config", Type, 0}, - {"Config.Certificates", Field, 0}, - {"Config.CipherSuites", Field, 0}, - {"Config.ClientAuth", Field, 0}, - {"Config.ClientCAs", Field, 0}, - {"Config.ClientSessionCache", Field, 3}, - {"Config.CurvePreferences", Field, 3}, - {"Config.DynamicRecordSizingDisabled", Field, 7}, - {"Config.EncryptedClientHelloConfigList", Field, 23}, - {"Config.EncryptedClientHelloKeys", Field, 24}, - {"Config.EncryptedClientHelloRejectionVerify", Field, 23}, - {"Config.GetCertificate", Field, 4}, - {"Config.GetClientCertificate", Field, 8}, - {"Config.GetConfigForClient", Field, 8}, - {"Config.InsecureSkipVerify", Field, 0}, - {"Config.KeyLogWriter", Field, 8}, - {"Config.MaxVersion", Field, 2}, - {"Config.MinVersion", Field, 2}, - {"Config.NameToCertificate", Field, 0}, - {"Config.NextProtos", Field, 0}, - {"Config.PreferServerCipherSuites", Field, 1}, - {"Config.Rand", Field, 0}, - {"Config.Renegotiation", Field, 7}, - {"Config.RootCAs", Field, 0}, - {"Config.ServerName", Field, 0}, - {"Config.SessionTicketKey", Field, 1}, - {"Config.SessionTicketsDisabled", Field, 1}, - {"Config.Time", Field, 0}, - {"Config.UnwrapSession", Field, 21}, - {"Config.VerifyConnection", Field, 15}, - {"Config.VerifyPeerCertificate", Field, 8}, - {"Config.WrapSession", Field, 21}, - {"Conn", Type, 0}, - {"ConnectionState", Type, 0}, - {"ConnectionState.CipherSuite", Field, 0}, - {"ConnectionState.DidResume", Field, 1}, - {"ConnectionState.ECHAccepted", Field, 23}, - {"ConnectionState.HandshakeComplete", Field, 0}, - {"ConnectionState.NegotiatedProtocol", Field, 0}, - {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0}, - {"ConnectionState.OCSPResponse", Field, 5}, - {"ConnectionState.PeerCertificates", Field, 0}, - {"ConnectionState.ServerName", Field, 0}, - {"ConnectionState.SignedCertificateTimestamps", Field, 5}, - {"ConnectionState.TLSUnique", Field, 4}, - {"ConnectionState.VerifiedChains", Field, 0}, - {"ConnectionState.Version", Field, 3}, - {"CurveID", Type, 3}, - {"CurveP256", Const, 3}, - {"CurveP384", Const, 3}, - {"CurveP521", Const, 3}, - {"Dial", Func, 0}, - {"DialWithDialer", Func, 3}, - {"Dialer", Type, 15}, - {"Dialer.Config", Field, 15}, - {"Dialer.NetDialer", Field, 15}, - {"ECDSAWithP256AndSHA256", Const, 8}, - {"ECDSAWithP384AndSHA384", Const, 8}, - {"ECDSAWithP521AndSHA512", Const, 8}, - {"ECDSAWithSHA1", Const, 10}, - {"ECHRejectionError", Type, 23}, - {"ECHRejectionError.RetryConfigList", Field, 23}, - {"Ed25519", Const, 13}, - {"EncryptedClientHelloKey", Type, 24}, - {"EncryptedClientHelloKey.Config", Field, 24}, - {"EncryptedClientHelloKey.PrivateKey", Field, 24}, - {"EncryptedClientHelloKey.SendAsRetry", Field, 24}, - {"InsecureCipherSuites", Func, 14}, - {"Listen", Func, 0}, - {"LoadX509KeyPair", Func, 0}, - {"NewLRUClientSessionCache", Func, 3}, - {"NewListener", Func, 0}, - {"NewResumptionState", Func, 21}, - {"NoClientCert", Const, 0}, - {"PKCS1WithSHA1", Const, 8}, - {"PKCS1WithSHA256", Const, 8}, - {"PKCS1WithSHA384", Const, 8}, - {"PKCS1WithSHA512", Const, 8}, - {"PSSWithSHA256", Const, 8}, - {"PSSWithSHA384", Const, 8}, - {"PSSWithSHA512", Const, 8}, - {"ParseSessionState", Func, 21}, - {"QUICClient", Func, 21}, - {"QUICConfig", Type, 21}, - {"QUICConfig.EnableSessionEvents", Field, 23}, - {"QUICConfig.TLSConfig", Field, 21}, - {"QUICConn", Type, 21}, - {"QUICEncryptionLevel", Type, 21}, - {"QUICEncryptionLevelApplication", Const, 21}, - {"QUICEncryptionLevelEarly", Const, 21}, - {"QUICEncryptionLevelHandshake", Const, 21}, - {"QUICEncryptionLevelInitial", Const, 21}, - {"QUICEvent", Type, 21}, - {"QUICEvent.Data", Field, 21}, - {"QUICEvent.Kind", Field, 21}, - {"QUICEvent.Level", Field, 21}, - {"QUICEvent.SessionState", Field, 23}, - {"QUICEvent.Suite", Field, 21}, - {"QUICEventKind", Type, 21}, - {"QUICHandshakeDone", Const, 21}, - {"QUICNoEvent", Const, 21}, - {"QUICRejectedEarlyData", Const, 21}, - {"QUICResumeSession", Const, 23}, - {"QUICServer", Func, 21}, - {"QUICSessionTicketOptions", Type, 21}, - {"QUICSessionTicketOptions.EarlyData", Field, 21}, - {"QUICSessionTicketOptions.Extra", Field, 23}, - {"QUICSetReadSecret", Const, 21}, - {"QUICSetWriteSecret", Const, 21}, - {"QUICStoreSession", Const, 23}, - {"QUICTransportParameters", Const, 21}, - {"QUICTransportParametersRequired", Const, 21}, - {"QUICWriteData", Const, 21}, - {"RecordHeaderError", Type, 6}, - {"RecordHeaderError.Conn", Field, 12}, - {"RecordHeaderError.Msg", Field, 6}, - {"RecordHeaderError.RecordHeader", Field, 6}, - {"RenegotiateFreelyAsClient", Const, 7}, - {"RenegotiateNever", Const, 7}, - {"RenegotiateOnceAsClient", Const, 7}, - {"RenegotiationSupport", Type, 7}, - {"RequestClientCert", Const, 0}, - {"RequireAndVerifyClientCert", Const, 0}, - {"RequireAnyClientCert", Const, 0}, - {"Server", Func, 0}, - {"SessionState", Type, 21}, - {"SessionState.EarlyData", Field, 21}, - {"SessionState.Extra", Field, 21}, - {"SignatureScheme", Type, 8}, - {"TLS_AES_128_GCM_SHA256", Const, 12}, - {"TLS_AES_256_GCM_SHA384", Const, 12}, - {"TLS_CHACHA20_POLY1305_SHA256", Const, 12}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2}, - {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2}, - {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5}, - {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8}, - {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, - {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2}, - {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, - {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0}, - {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, - {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2}, - {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1}, - {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5}, - {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8}, - {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14}, - {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0}, - {"TLS_FALLBACK_SCSV", Const, 4}, - {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0}, - {"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0}, - {"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8}, - {"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6}, - {"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1}, - {"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6}, - {"TLS_RSA_WITH_RC4_128_SHA", Const, 0}, - {"VerifyClientCertIfGiven", Const, 0}, - {"VersionName", Func, 21}, - {"VersionSSL30", Const, 2}, - {"VersionTLS10", Const, 2}, - {"VersionTLS11", Const, 2}, - {"VersionTLS12", Const, 2}, - {"VersionTLS13", Const, 12}, - {"X25519", Const, 8}, - {"X25519MLKEM768", Const, 24}, - {"X509KeyPair", Func, 0}, - }, - "crypto/x509": { - {"(*CertPool).AddCert", Method, 0}, - {"(*CertPool).AddCertWithConstraint", Method, 22}, - {"(*CertPool).AppendCertsFromPEM", Method, 0}, - {"(*CertPool).Clone", Method, 19}, - {"(*CertPool).Equal", Method, 19}, - {"(*CertPool).Subjects", Method, 0}, - {"(*Certificate).CheckCRLSignature", Method, 0}, - {"(*Certificate).CheckSignature", Method, 0}, - {"(*Certificate).CheckSignatureFrom", Method, 0}, - {"(*Certificate).CreateCRL", Method, 0}, - {"(*Certificate).Equal", Method, 0}, - {"(*Certificate).Verify", Method, 0}, - {"(*Certificate).VerifyHostname", Method, 0}, - {"(*CertificateRequest).CheckSignature", Method, 5}, - {"(*OID).UnmarshalBinary", Method, 23}, - {"(*OID).UnmarshalText", Method, 23}, - {"(*RevocationList).CheckSignatureFrom", Method, 19}, - {"(CertificateInvalidError).Error", Method, 0}, - {"(ConstraintViolationError).Error", Method, 0}, - {"(HostnameError).Error", Method, 0}, - {"(InsecureAlgorithmError).Error", Method, 6}, - {"(OID).AppendBinary", Method, 24}, - {"(OID).AppendText", Method, 24}, - {"(OID).Equal", Method, 22}, - {"(OID).EqualASN1OID", Method, 22}, - {"(OID).MarshalBinary", Method, 23}, - {"(OID).MarshalText", Method, 23}, - {"(OID).String", Method, 22}, - {"(PublicKeyAlgorithm).String", Method, 10}, - {"(SignatureAlgorithm).String", Method, 6}, - {"(SystemRootsError).Error", Method, 1}, - {"(SystemRootsError).Unwrap", Method, 16}, - {"(UnhandledCriticalExtension).Error", Method, 0}, - {"(UnknownAuthorityError).Error", Method, 0}, - {"CANotAuthorizedForExtKeyUsage", Const, 10}, - {"CANotAuthorizedForThisName", Const, 0}, - {"CertPool", Type, 0}, - {"Certificate", Type, 0}, - {"Certificate.AuthorityKeyId", Field, 0}, - {"Certificate.BasicConstraintsValid", Field, 0}, - {"Certificate.CRLDistributionPoints", Field, 2}, - {"Certificate.DNSNames", Field, 0}, - {"Certificate.EmailAddresses", Field, 0}, - {"Certificate.ExcludedDNSDomains", Field, 9}, - {"Certificate.ExcludedEmailAddresses", Field, 10}, - {"Certificate.ExcludedIPRanges", Field, 10}, - {"Certificate.ExcludedURIDomains", Field, 10}, - {"Certificate.ExtKeyUsage", Field, 0}, - {"Certificate.Extensions", Field, 2}, - {"Certificate.ExtraExtensions", Field, 2}, - {"Certificate.IPAddresses", Field, 1}, - {"Certificate.InhibitAnyPolicy", Field, 24}, - {"Certificate.InhibitAnyPolicyZero", Field, 24}, - {"Certificate.InhibitPolicyMapping", Field, 24}, - {"Certificate.InhibitPolicyMappingZero", Field, 24}, - {"Certificate.IsCA", Field, 0}, - {"Certificate.Issuer", Field, 0}, - {"Certificate.IssuingCertificateURL", Field, 2}, - {"Certificate.KeyUsage", Field, 0}, - {"Certificate.MaxPathLen", Field, 0}, - {"Certificate.MaxPathLenZero", Field, 4}, - {"Certificate.NotAfter", Field, 0}, - {"Certificate.NotBefore", Field, 0}, - {"Certificate.OCSPServer", Field, 2}, - {"Certificate.PermittedDNSDomains", Field, 0}, - {"Certificate.PermittedDNSDomainsCritical", Field, 0}, - {"Certificate.PermittedEmailAddresses", Field, 10}, - {"Certificate.PermittedIPRanges", Field, 10}, - {"Certificate.PermittedURIDomains", Field, 10}, - {"Certificate.Policies", Field, 22}, - {"Certificate.PolicyIdentifiers", Field, 0}, - {"Certificate.PolicyMappings", Field, 24}, - {"Certificate.PublicKey", Field, 0}, - {"Certificate.PublicKeyAlgorithm", Field, 0}, - {"Certificate.Raw", Field, 0}, - {"Certificate.RawIssuer", Field, 0}, - {"Certificate.RawSubject", Field, 0}, - {"Certificate.RawSubjectPublicKeyInfo", Field, 0}, - {"Certificate.RawTBSCertificate", Field, 0}, - {"Certificate.RequireExplicitPolicy", Field, 24}, - {"Certificate.RequireExplicitPolicyZero", Field, 24}, - {"Certificate.SerialNumber", Field, 0}, - {"Certificate.Signature", Field, 0}, - {"Certificate.SignatureAlgorithm", Field, 0}, - {"Certificate.Subject", Field, 0}, - {"Certificate.SubjectKeyId", Field, 0}, - {"Certificate.URIs", Field, 10}, - {"Certificate.UnhandledCriticalExtensions", Field, 5}, - {"Certificate.UnknownExtKeyUsage", Field, 0}, - {"Certificate.Version", Field, 0}, - {"CertificateInvalidError", Type, 0}, - {"CertificateInvalidError.Cert", Field, 0}, - {"CertificateInvalidError.Detail", Field, 10}, - {"CertificateInvalidError.Reason", Field, 0}, - {"CertificateRequest", Type, 3}, - {"CertificateRequest.Attributes", Field, 3}, - {"CertificateRequest.DNSNames", Field, 3}, - {"CertificateRequest.EmailAddresses", Field, 3}, - {"CertificateRequest.Extensions", Field, 3}, - {"CertificateRequest.ExtraExtensions", Field, 3}, - {"CertificateRequest.IPAddresses", Field, 3}, - {"CertificateRequest.PublicKey", Field, 3}, - {"CertificateRequest.PublicKeyAlgorithm", Field, 3}, - {"CertificateRequest.Raw", Field, 3}, - {"CertificateRequest.RawSubject", Field, 3}, - {"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3}, - {"CertificateRequest.RawTBSCertificateRequest", Field, 3}, - {"CertificateRequest.Signature", Field, 3}, - {"CertificateRequest.SignatureAlgorithm", Field, 3}, - {"CertificateRequest.Subject", Field, 3}, - {"CertificateRequest.URIs", Field, 10}, - {"CertificateRequest.Version", Field, 3}, - {"ConstraintViolationError", Type, 0}, - {"CreateCertificate", Func, 0}, - {"CreateCertificateRequest", Func, 3}, - {"CreateRevocationList", Func, 15}, - {"DSA", Const, 0}, - {"DSAWithSHA1", Const, 0}, - {"DSAWithSHA256", Const, 0}, - {"DecryptPEMBlock", Func, 1}, - {"ECDSA", Const, 1}, - {"ECDSAWithSHA1", Const, 1}, - {"ECDSAWithSHA256", Const, 1}, - {"ECDSAWithSHA384", Const, 1}, - {"ECDSAWithSHA512", Const, 1}, - {"Ed25519", Const, 13}, - {"EncryptPEMBlock", Func, 1}, - {"ErrUnsupportedAlgorithm", Var, 0}, - {"Expired", Const, 0}, - {"ExtKeyUsage", Type, 0}, - {"ExtKeyUsageAny", Const, 0}, - {"ExtKeyUsageClientAuth", Const, 0}, - {"ExtKeyUsageCodeSigning", Const, 0}, - {"ExtKeyUsageEmailProtection", Const, 0}, - {"ExtKeyUsageIPSECEndSystem", Const, 1}, - {"ExtKeyUsageIPSECTunnel", Const, 1}, - {"ExtKeyUsageIPSECUser", Const, 1}, - {"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10}, - {"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10}, - {"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1}, - {"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1}, - {"ExtKeyUsageOCSPSigning", Const, 0}, - {"ExtKeyUsageServerAuth", Const, 0}, - {"ExtKeyUsageTimeStamping", Const, 0}, - {"HostnameError", Type, 0}, - {"HostnameError.Certificate", Field, 0}, - {"HostnameError.Host", Field, 0}, - {"IncompatibleUsage", Const, 1}, - {"IncorrectPasswordError", Var, 1}, - {"InsecureAlgorithmError", Type, 6}, - {"InvalidReason", Type, 0}, - {"IsEncryptedPEMBlock", Func, 1}, - {"KeyUsage", Type, 0}, - {"KeyUsageCRLSign", Const, 0}, - {"KeyUsageCertSign", Const, 0}, - {"KeyUsageContentCommitment", Const, 0}, - {"KeyUsageDataEncipherment", Const, 0}, - {"KeyUsageDecipherOnly", Const, 0}, - {"KeyUsageDigitalSignature", Const, 0}, - {"KeyUsageEncipherOnly", Const, 0}, - {"KeyUsageKeyAgreement", Const, 0}, - {"KeyUsageKeyEncipherment", Const, 0}, - {"MD2WithRSA", Const, 0}, - {"MD5WithRSA", Const, 0}, - {"MarshalECPrivateKey", Func, 2}, - {"MarshalPKCS1PrivateKey", Func, 0}, - {"MarshalPKCS1PublicKey", Func, 10}, - {"MarshalPKCS8PrivateKey", Func, 10}, - {"MarshalPKIXPublicKey", Func, 0}, - {"NameConstraintsWithoutSANs", Const, 10}, - {"NameMismatch", Const, 8}, - {"NewCertPool", Func, 0}, - {"NoValidChains", Const, 24}, - {"NotAuthorizedToSign", Const, 0}, - {"OID", Type, 22}, - {"OIDFromInts", Func, 22}, - {"PEMCipher", Type, 1}, - {"PEMCipher3DES", Const, 1}, - {"PEMCipherAES128", Const, 1}, - {"PEMCipherAES192", Const, 1}, - {"PEMCipherAES256", Const, 1}, - {"PEMCipherDES", Const, 1}, - {"ParseCRL", Func, 0}, - {"ParseCertificate", Func, 0}, - {"ParseCertificateRequest", Func, 3}, - {"ParseCertificates", Func, 0}, - {"ParseDERCRL", Func, 0}, - {"ParseECPrivateKey", Func, 1}, - {"ParseOID", Func, 23}, - {"ParsePKCS1PrivateKey", Func, 0}, - {"ParsePKCS1PublicKey", Func, 10}, - {"ParsePKCS8PrivateKey", Func, 0}, - {"ParsePKIXPublicKey", Func, 0}, - {"ParseRevocationList", Func, 19}, - {"PolicyMapping", Type, 24}, - {"PolicyMapping.IssuerDomainPolicy", Field, 24}, - {"PolicyMapping.SubjectDomainPolicy", Field, 24}, - {"PublicKeyAlgorithm", Type, 0}, - {"PureEd25519", Const, 13}, - {"RSA", Const, 0}, - {"RevocationList", Type, 15}, - {"RevocationList.AuthorityKeyId", Field, 19}, - {"RevocationList.Extensions", Field, 19}, - {"RevocationList.ExtraExtensions", Field, 15}, - {"RevocationList.Issuer", Field, 19}, - {"RevocationList.NextUpdate", Field, 15}, - {"RevocationList.Number", Field, 15}, - {"RevocationList.Raw", Field, 19}, - {"RevocationList.RawIssuer", Field, 19}, - {"RevocationList.RawTBSRevocationList", Field, 19}, - {"RevocationList.RevokedCertificateEntries", Field, 21}, - {"RevocationList.RevokedCertificates", Field, 15}, - {"RevocationList.Signature", Field, 19}, - {"RevocationList.SignatureAlgorithm", Field, 15}, - {"RevocationList.ThisUpdate", Field, 15}, - {"RevocationListEntry", Type, 21}, - {"RevocationListEntry.Extensions", Field, 21}, - {"RevocationListEntry.ExtraExtensions", Field, 21}, - {"RevocationListEntry.Raw", Field, 21}, - {"RevocationListEntry.ReasonCode", Field, 21}, - {"RevocationListEntry.RevocationTime", Field, 21}, - {"RevocationListEntry.SerialNumber", Field, 21}, - {"SHA1WithRSA", Const, 0}, - {"SHA256WithRSA", Const, 0}, - {"SHA256WithRSAPSS", Const, 8}, - {"SHA384WithRSA", Const, 0}, - {"SHA384WithRSAPSS", Const, 8}, - {"SHA512WithRSA", Const, 0}, - {"SHA512WithRSAPSS", Const, 8}, - {"SetFallbackRoots", Func, 20}, - {"SignatureAlgorithm", Type, 0}, - {"SystemCertPool", Func, 7}, - {"SystemRootsError", Type, 1}, - {"SystemRootsError.Err", Field, 7}, - {"TooManyConstraints", Const, 10}, - {"TooManyIntermediates", Const, 0}, - {"UnconstrainedName", Const, 10}, - {"UnhandledCriticalExtension", Type, 0}, - {"UnknownAuthorityError", Type, 0}, - {"UnknownAuthorityError.Cert", Field, 8}, - {"UnknownPublicKeyAlgorithm", Const, 0}, - {"UnknownSignatureAlgorithm", Const, 0}, - {"VerifyOptions", Type, 0}, - {"VerifyOptions.CertificatePolicies", Field, 24}, - {"VerifyOptions.CurrentTime", Field, 0}, - {"VerifyOptions.DNSName", Field, 0}, - {"VerifyOptions.Intermediates", Field, 0}, - {"VerifyOptions.KeyUsages", Field, 1}, - {"VerifyOptions.MaxConstraintComparisions", Field, 10}, - {"VerifyOptions.Roots", Field, 0}, - }, - "crypto/x509/pkix": { - {"(*CertificateList).HasExpired", Method, 0}, - {"(*Name).FillFromRDNSequence", Method, 0}, - {"(Name).String", Method, 10}, - {"(Name).ToRDNSequence", Method, 0}, - {"(RDNSequence).String", Method, 10}, - {"AlgorithmIdentifier", Type, 0}, - {"AlgorithmIdentifier.Algorithm", Field, 0}, - {"AlgorithmIdentifier.Parameters", Field, 0}, - {"AttributeTypeAndValue", Type, 0}, - {"AttributeTypeAndValue.Type", Field, 0}, - {"AttributeTypeAndValue.Value", Field, 0}, - {"AttributeTypeAndValueSET", Type, 3}, - {"AttributeTypeAndValueSET.Type", Field, 3}, - {"AttributeTypeAndValueSET.Value", Field, 3}, - {"CertificateList", Type, 0}, - {"CertificateList.SignatureAlgorithm", Field, 0}, - {"CertificateList.SignatureValue", Field, 0}, - {"CertificateList.TBSCertList", Field, 0}, - {"Extension", Type, 0}, - {"Extension.Critical", Field, 0}, - {"Extension.Id", Field, 0}, - {"Extension.Value", Field, 0}, - {"Name", Type, 0}, - {"Name.CommonName", Field, 0}, - {"Name.Country", Field, 0}, - {"Name.ExtraNames", Field, 5}, - {"Name.Locality", Field, 0}, - {"Name.Names", Field, 0}, - {"Name.Organization", Field, 0}, - {"Name.OrganizationalUnit", Field, 0}, - {"Name.PostalCode", Field, 0}, - {"Name.Province", Field, 0}, - {"Name.SerialNumber", Field, 0}, - {"Name.StreetAddress", Field, 0}, - {"RDNSequence", Type, 0}, - {"RelativeDistinguishedNameSET", Type, 0}, - {"RevokedCertificate", Type, 0}, - {"RevokedCertificate.Extensions", Field, 0}, - {"RevokedCertificate.RevocationTime", Field, 0}, - {"RevokedCertificate.SerialNumber", Field, 0}, - {"TBSCertificateList", Type, 0}, - {"TBSCertificateList.Extensions", Field, 0}, - {"TBSCertificateList.Issuer", Field, 0}, - {"TBSCertificateList.NextUpdate", Field, 0}, - {"TBSCertificateList.Raw", Field, 0}, - {"TBSCertificateList.RevokedCertificates", Field, 0}, - {"TBSCertificateList.Signature", Field, 0}, - {"TBSCertificateList.ThisUpdate", Field, 0}, - {"TBSCertificateList.Version", Field, 0}, - }, - "database/sql": { - {"(*ColumnType).DatabaseTypeName", Method, 8}, - {"(*ColumnType).DecimalSize", Method, 8}, - {"(*ColumnType).Length", Method, 8}, - {"(*ColumnType).Name", Method, 8}, - {"(*ColumnType).Nullable", Method, 8}, - {"(*ColumnType).ScanType", Method, 8}, - {"(*Conn).BeginTx", Method, 9}, - {"(*Conn).Close", Method, 9}, - {"(*Conn).ExecContext", Method, 9}, - {"(*Conn).PingContext", Method, 9}, - {"(*Conn).PrepareContext", Method, 9}, - {"(*Conn).QueryContext", Method, 9}, - {"(*Conn).QueryRowContext", Method, 9}, - {"(*Conn).Raw", Method, 13}, - {"(*DB).Begin", Method, 0}, - {"(*DB).BeginTx", Method, 8}, - {"(*DB).Close", Method, 0}, - {"(*DB).Conn", Method, 9}, - {"(*DB).Driver", Method, 0}, - {"(*DB).Exec", Method, 0}, - {"(*DB).ExecContext", Method, 8}, - {"(*DB).Ping", Method, 1}, - {"(*DB).PingContext", Method, 8}, - {"(*DB).Prepare", Method, 0}, - {"(*DB).PrepareContext", Method, 8}, - {"(*DB).Query", Method, 0}, - {"(*DB).QueryContext", Method, 8}, - {"(*DB).QueryRow", Method, 0}, - {"(*DB).QueryRowContext", Method, 8}, - {"(*DB).SetConnMaxIdleTime", Method, 15}, - {"(*DB).SetConnMaxLifetime", Method, 6}, - {"(*DB).SetMaxIdleConns", Method, 1}, - {"(*DB).SetMaxOpenConns", Method, 2}, - {"(*DB).Stats", Method, 5}, - {"(*Null).Scan", Method, 22}, - {"(*NullBool).Scan", Method, 0}, - {"(*NullByte).Scan", Method, 17}, - {"(*NullFloat64).Scan", Method, 0}, - {"(*NullInt16).Scan", Method, 17}, - {"(*NullInt32).Scan", Method, 13}, - {"(*NullInt64).Scan", Method, 0}, - {"(*NullString).Scan", Method, 0}, - {"(*NullTime).Scan", Method, 13}, - {"(*Row).Err", Method, 15}, - {"(*Row).Scan", Method, 0}, - {"(*Rows).Close", Method, 0}, - {"(*Rows).ColumnTypes", Method, 8}, - {"(*Rows).Columns", Method, 0}, - {"(*Rows).Err", Method, 0}, - {"(*Rows).Next", Method, 0}, - {"(*Rows).NextResultSet", Method, 8}, - {"(*Rows).Scan", Method, 0}, - {"(*Stmt).Close", Method, 0}, - {"(*Stmt).Exec", Method, 0}, - {"(*Stmt).ExecContext", Method, 8}, - {"(*Stmt).Query", Method, 0}, - {"(*Stmt).QueryContext", Method, 8}, - {"(*Stmt).QueryRow", Method, 0}, - {"(*Stmt).QueryRowContext", Method, 8}, - {"(*Tx).Commit", Method, 0}, - {"(*Tx).Exec", Method, 0}, - {"(*Tx).ExecContext", Method, 8}, - {"(*Tx).Prepare", Method, 0}, - {"(*Tx).PrepareContext", Method, 8}, - {"(*Tx).Query", Method, 0}, - {"(*Tx).QueryContext", Method, 8}, - {"(*Tx).QueryRow", Method, 0}, - {"(*Tx).QueryRowContext", Method, 8}, - {"(*Tx).Rollback", Method, 0}, - {"(*Tx).Stmt", Method, 0}, - {"(*Tx).StmtContext", Method, 8}, - {"(IsolationLevel).String", Method, 11}, - {"(Null).Value", Method, 22}, - {"(NullBool).Value", Method, 0}, - {"(NullByte).Value", Method, 17}, - {"(NullFloat64).Value", Method, 0}, - {"(NullInt16).Value", Method, 17}, - {"(NullInt32).Value", Method, 13}, - {"(NullInt64).Value", Method, 0}, - {"(NullString).Value", Method, 0}, - {"(NullTime).Value", Method, 13}, - {"ColumnType", Type, 8}, - {"Conn", Type, 9}, - {"DB", Type, 0}, - {"DBStats", Type, 5}, - {"DBStats.Idle", Field, 11}, - {"DBStats.InUse", Field, 11}, - {"DBStats.MaxIdleClosed", Field, 11}, - {"DBStats.MaxIdleTimeClosed", Field, 15}, - {"DBStats.MaxLifetimeClosed", Field, 11}, - {"DBStats.MaxOpenConnections", Field, 11}, - {"DBStats.OpenConnections", Field, 5}, - {"DBStats.WaitCount", Field, 11}, - {"DBStats.WaitDuration", Field, 11}, - {"Drivers", Func, 4}, - {"ErrConnDone", Var, 9}, - {"ErrNoRows", Var, 0}, - {"ErrTxDone", Var, 0}, - {"IsolationLevel", Type, 8}, - {"LevelDefault", Const, 8}, - {"LevelLinearizable", Const, 8}, - {"LevelReadCommitted", Const, 8}, - {"LevelReadUncommitted", Const, 8}, - {"LevelRepeatableRead", Const, 8}, - {"LevelSerializable", Const, 8}, - {"LevelSnapshot", Const, 8}, - {"LevelWriteCommitted", Const, 8}, - {"Named", Func, 8}, - {"NamedArg", Type, 8}, - {"NamedArg.Name", Field, 8}, - {"NamedArg.Value", Field, 8}, - {"Null", Type, 22}, - {"Null.V", Field, 22}, - {"Null.Valid", Field, 22}, - {"NullBool", Type, 0}, - {"NullBool.Bool", Field, 0}, - {"NullBool.Valid", Field, 0}, - {"NullByte", Type, 17}, - {"NullByte.Byte", Field, 17}, - {"NullByte.Valid", Field, 17}, - {"NullFloat64", Type, 0}, - {"NullFloat64.Float64", Field, 0}, - {"NullFloat64.Valid", Field, 0}, - {"NullInt16", Type, 17}, - {"NullInt16.Int16", Field, 17}, - {"NullInt16.Valid", Field, 17}, - {"NullInt32", Type, 13}, - {"NullInt32.Int32", Field, 13}, - {"NullInt32.Valid", Field, 13}, - {"NullInt64", Type, 0}, - {"NullInt64.Int64", Field, 0}, - {"NullInt64.Valid", Field, 0}, - {"NullString", Type, 0}, - {"NullString.String", Field, 0}, - {"NullString.Valid", Field, 0}, - {"NullTime", Type, 13}, - {"NullTime.Time", Field, 13}, - {"NullTime.Valid", Field, 13}, - {"Open", Func, 0}, - {"OpenDB", Func, 10}, - {"Out", Type, 9}, - {"Out.Dest", Field, 9}, - {"Out.In", Field, 9}, - {"RawBytes", Type, 0}, - {"Register", Func, 0}, - {"Result", Type, 0}, - {"Row", Type, 0}, - {"Rows", Type, 0}, - {"Scanner", Type, 0}, - {"Stmt", Type, 0}, - {"Tx", Type, 0}, - {"TxOptions", Type, 8}, - {"TxOptions.Isolation", Field, 8}, - {"TxOptions.ReadOnly", Field, 8}, - }, - "database/sql/driver": { - {"(NotNull).ConvertValue", Method, 0}, - {"(Null).ConvertValue", Method, 0}, - {"(RowsAffected).LastInsertId", Method, 0}, - {"(RowsAffected).RowsAffected", Method, 0}, - {"Bool", Var, 0}, - {"ColumnConverter", Type, 0}, - {"Conn", Type, 0}, - {"ConnBeginTx", Type, 8}, - {"ConnPrepareContext", Type, 8}, - {"Connector", Type, 10}, - {"DefaultParameterConverter", Var, 0}, - {"Driver", Type, 0}, - {"DriverContext", Type, 10}, - {"ErrBadConn", Var, 0}, - {"ErrRemoveArgument", Var, 9}, - {"ErrSkip", Var, 0}, - {"Execer", Type, 0}, - {"ExecerContext", Type, 8}, - {"Int32", Var, 0}, - {"IsScanValue", Func, 0}, - {"IsValue", Func, 0}, - {"IsolationLevel", Type, 8}, - {"NamedValue", Type, 8}, - {"NamedValue.Name", Field, 8}, - {"NamedValue.Ordinal", Field, 8}, - {"NamedValue.Value", Field, 8}, - {"NamedValueChecker", Type, 9}, - {"NotNull", Type, 0}, - {"NotNull.Converter", Field, 0}, - {"Null", Type, 0}, - {"Null.Converter", Field, 0}, - {"Pinger", Type, 8}, - {"Queryer", Type, 1}, - {"QueryerContext", Type, 8}, - {"Result", Type, 0}, - {"ResultNoRows", Var, 0}, - {"Rows", Type, 0}, - {"RowsAffected", Type, 0}, - {"RowsColumnTypeDatabaseTypeName", Type, 8}, - {"RowsColumnTypeLength", Type, 8}, - {"RowsColumnTypeNullable", Type, 8}, - {"RowsColumnTypePrecisionScale", Type, 8}, - {"RowsColumnTypeScanType", Type, 8}, - {"RowsNextResultSet", Type, 8}, - {"SessionResetter", Type, 10}, - {"Stmt", Type, 0}, - {"StmtExecContext", Type, 8}, - {"StmtQueryContext", Type, 8}, - {"String", Var, 0}, - {"Tx", Type, 0}, - {"TxOptions", Type, 8}, - {"TxOptions.Isolation", Field, 8}, - {"TxOptions.ReadOnly", Field, 8}, - {"Validator", Type, 15}, - {"Value", Type, 0}, - {"ValueConverter", Type, 0}, - {"Valuer", Type, 0}, - }, - "debug/buildinfo": { - {"BuildInfo", Type, 18}, - {"Read", Func, 18}, - {"ReadFile", Func, 18}, - }, - "debug/dwarf": { - {"(*AddrType).Basic", Method, 0}, - {"(*AddrType).Common", Method, 0}, - {"(*AddrType).Size", Method, 0}, - {"(*AddrType).String", Method, 0}, - {"(*ArrayType).Common", Method, 0}, - {"(*ArrayType).Size", Method, 0}, - {"(*ArrayType).String", Method, 0}, - {"(*BasicType).Basic", Method, 0}, - {"(*BasicType).Common", Method, 0}, - {"(*BasicType).Size", Method, 0}, - {"(*BasicType).String", Method, 0}, - {"(*BoolType).Basic", Method, 0}, - {"(*BoolType).Common", Method, 0}, - {"(*BoolType).Size", Method, 0}, - {"(*BoolType).String", Method, 0}, - {"(*CharType).Basic", Method, 0}, - {"(*CharType).Common", Method, 0}, - {"(*CharType).Size", Method, 0}, - {"(*CharType).String", Method, 0}, - {"(*CommonType).Common", Method, 0}, - {"(*CommonType).Size", Method, 0}, - {"(*ComplexType).Basic", Method, 0}, - {"(*ComplexType).Common", Method, 0}, - {"(*ComplexType).Size", Method, 0}, - {"(*ComplexType).String", Method, 0}, - {"(*Data).AddSection", Method, 14}, - {"(*Data).AddTypes", Method, 3}, - {"(*Data).LineReader", Method, 5}, - {"(*Data).Ranges", Method, 7}, - {"(*Data).Reader", Method, 0}, - {"(*Data).Type", Method, 0}, - {"(*DotDotDotType).Common", Method, 0}, - {"(*DotDotDotType).Size", Method, 0}, - {"(*DotDotDotType).String", Method, 0}, - {"(*Entry).AttrField", Method, 5}, - {"(*Entry).Val", Method, 0}, - {"(*EnumType).Common", Method, 0}, - {"(*EnumType).Size", Method, 0}, - {"(*EnumType).String", Method, 0}, - {"(*FloatType).Basic", Method, 0}, - {"(*FloatType).Common", Method, 0}, - {"(*FloatType).Size", Method, 0}, - {"(*FloatType).String", Method, 0}, - {"(*FuncType).Common", Method, 0}, - {"(*FuncType).Size", Method, 0}, - {"(*FuncType).String", Method, 0}, - {"(*IntType).Basic", Method, 0}, - {"(*IntType).Common", Method, 0}, - {"(*IntType).Size", Method, 0}, - {"(*IntType).String", Method, 0}, - {"(*LineReader).Files", Method, 14}, - {"(*LineReader).Next", Method, 5}, - {"(*LineReader).Reset", Method, 5}, - {"(*LineReader).Seek", Method, 5}, - {"(*LineReader).SeekPC", Method, 5}, - {"(*LineReader).Tell", Method, 5}, - {"(*PtrType).Common", Method, 0}, - {"(*PtrType).Size", Method, 0}, - {"(*PtrType).String", Method, 0}, - {"(*QualType).Common", Method, 0}, - {"(*QualType).Size", Method, 0}, - {"(*QualType).String", Method, 0}, - {"(*Reader).AddressSize", Method, 5}, - {"(*Reader).ByteOrder", Method, 14}, - {"(*Reader).Next", Method, 0}, - {"(*Reader).Seek", Method, 0}, - {"(*Reader).SeekPC", Method, 7}, - {"(*Reader).SkipChildren", Method, 0}, - {"(*StructType).Common", Method, 0}, - {"(*StructType).Defn", Method, 0}, - {"(*StructType).Size", Method, 0}, - {"(*StructType).String", Method, 0}, - {"(*TypedefType).Common", Method, 0}, - {"(*TypedefType).Size", Method, 0}, - {"(*TypedefType).String", Method, 0}, - {"(*UcharType).Basic", Method, 0}, - {"(*UcharType).Common", Method, 0}, - {"(*UcharType).Size", Method, 0}, - {"(*UcharType).String", Method, 0}, - {"(*UintType).Basic", Method, 0}, - {"(*UintType).Common", Method, 0}, - {"(*UintType).Size", Method, 0}, - {"(*UintType).String", Method, 0}, - {"(*UnspecifiedType).Basic", Method, 4}, - {"(*UnspecifiedType).Common", Method, 4}, - {"(*UnspecifiedType).Size", Method, 4}, - {"(*UnspecifiedType).String", Method, 4}, - {"(*UnsupportedType).Common", Method, 13}, - {"(*UnsupportedType).Size", Method, 13}, - {"(*UnsupportedType).String", Method, 13}, - {"(*VoidType).Common", Method, 0}, - {"(*VoidType).Size", Method, 0}, - {"(*VoidType).String", Method, 0}, - {"(Attr).GoString", Method, 0}, - {"(Attr).String", Method, 0}, - {"(Class).GoString", Method, 5}, - {"(Class).String", Method, 5}, - {"(DecodeError).Error", Method, 0}, - {"(Tag).GoString", Method, 0}, - {"(Tag).String", Method, 0}, - {"AddrType", Type, 0}, - {"AddrType.BasicType", Field, 0}, - {"ArrayType", Type, 0}, - {"ArrayType.CommonType", Field, 0}, - {"ArrayType.Count", Field, 0}, - {"ArrayType.StrideBitSize", Field, 0}, - {"ArrayType.Type", Field, 0}, - {"Attr", Type, 0}, - {"AttrAbstractOrigin", Const, 0}, - {"AttrAccessibility", Const, 0}, - {"AttrAddrBase", Const, 14}, - {"AttrAddrClass", Const, 0}, - {"AttrAlignment", Const, 14}, - {"AttrAllocated", Const, 0}, - {"AttrArtificial", Const, 0}, - {"AttrAssociated", Const, 0}, - {"AttrBaseTypes", Const, 0}, - {"AttrBinaryScale", Const, 14}, - {"AttrBitOffset", Const, 0}, - {"AttrBitSize", Const, 0}, - {"AttrByteSize", Const, 0}, - {"AttrCallAllCalls", Const, 14}, - {"AttrCallAllSourceCalls", Const, 14}, - {"AttrCallAllTailCalls", Const, 14}, - {"AttrCallColumn", Const, 0}, - {"AttrCallDataLocation", Const, 14}, - {"AttrCallDataValue", Const, 14}, - {"AttrCallFile", Const, 0}, - {"AttrCallLine", Const, 0}, - {"AttrCallOrigin", Const, 14}, - {"AttrCallPC", Const, 14}, - {"AttrCallParameter", Const, 14}, - {"AttrCallReturnPC", Const, 14}, - {"AttrCallTailCall", Const, 14}, - {"AttrCallTarget", Const, 14}, - {"AttrCallTargetClobbered", Const, 14}, - {"AttrCallValue", Const, 14}, - {"AttrCalling", Const, 0}, - {"AttrCommonRef", Const, 0}, - {"AttrCompDir", Const, 0}, - {"AttrConstExpr", Const, 14}, - {"AttrConstValue", Const, 0}, - {"AttrContainingType", Const, 0}, - {"AttrCount", Const, 0}, - {"AttrDataBitOffset", Const, 14}, - {"AttrDataLocation", Const, 0}, - {"AttrDataMemberLoc", Const, 0}, - {"AttrDecimalScale", Const, 14}, - {"AttrDecimalSign", Const, 14}, - {"AttrDeclColumn", Const, 0}, - {"AttrDeclFile", Const, 0}, - {"AttrDeclLine", Const, 0}, - {"AttrDeclaration", Const, 0}, - {"AttrDefaultValue", Const, 0}, - {"AttrDefaulted", Const, 14}, - {"AttrDeleted", Const, 14}, - {"AttrDescription", Const, 0}, - {"AttrDigitCount", Const, 14}, - {"AttrDiscr", Const, 0}, - {"AttrDiscrList", Const, 0}, - {"AttrDiscrValue", Const, 0}, - {"AttrDwoName", Const, 14}, - {"AttrElemental", Const, 14}, - {"AttrEncoding", Const, 0}, - {"AttrEndianity", Const, 14}, - {"AttrEntrypc", Const, 0}, - {"AttrEnumClass", Const, 14}, - {"AttrExplicit", Const, 14}, - {"AttrExportSymbols", Const, 14}, - {"AttrExtension", Const, 0}, - {"AttrExternal", Const, 0}, - {"AttrFrameBase", Const, 0}, - {"AttrFriend", Const, 0}, - {"AttrHighpc", Const, 0}, - {"AttrIdentifierCase", Const, 0}, - {"AttrImport", Const, 0}, - {"AttrInline", Const, 0}, - {"AttrIsOptional", Const, 0}, - {"AttrLanguage", Const, 0}, - {"AttrLinkageName", Const, 14}, - {"AttrLocation", Const, 0}, - {"AttrLoclistsBase", Const, 14}, - {"AttrLowerBound", Const, 0}, - {"AttrLowpc", Const, 0}, - {"AttrMacroInfo", Const, 0}, - {"AttrMacros", Const, 14}, - {"AttrMainSubprogram", Const, 14}, - {"AttrMutable", Const, 14}, - {"AttrName", Const, 0}, - {"AttrNamelistItem", Const, 0}, - {"AttrNoreturn", Const, 14}, - {"AttrObjectPointer", Const, 14}, - {"AttrOrdering", Const, 0}, - {"AttrPictureString", Const, 14}, - {"AttrPriority", Const, 0}, - {"AttrProducer", Const, 0}, - {"AttrPrototyped", Const, 0}, - {"AttrPure", Const, 14}, - {"AttrRanges", Const, 0}, - {"AttrRank", Const, 14}, - {"AttrRecursive", Const, 14}, - {"AttrReference", Const, 14}, - {"AttrReturnAddr", Const, 0}, - {"AttrRnglistsBase", Const, 14}, - {"AttrRvalueReference", Const, 14}, - {"AttrSegment", Const, 0}, - {"AttrSibling", Const, 0}, - {"AttrSignature", Const, 14}, - {"AttrSmall", Const, 14}, - {"AttrSpecification", Const, 0}, - {"AttrStartScope", Const, 0}, - {"AttrStaticLink", Const, 0}, - {"AttrStmtList", Const, 0}, - {"AttrStrOffsetsBase", Const, 14}, - {"AttrStride", Const, 0}, - {"AttrStrideSize", Const, 0}, - {"AttrStringLength", Const, 0}, - {"AttrStringLengthBitSize", Const, 14}, - {"AttrStringLengthByteSize", Const, 14}, - {"AttrThreadsScaled", Const, 14}, - {"AttrTrampoline", Const, 0}, - {"AttrType", Const, 0}, - {"AttrUpperBound", Const, 0}, - {"AttrUseLocation", Const, 0}, - {"AttrUseUTF8", Const, 0}, - {"AttrVarParam", Const, 0}, - {"AttrVirtuality", Const, 0}, - {"AttrVisibility", Const, 0}, - {"AttrVtableElemLoc", Const, 0}, - {"BasicType", Type, 0}, - {"BasicType.BitOffset", Field, 0}, - {"BasicType.BitSize", Field, 0}, - {"BasicType.CommonType", Field, 0}, - {"BasicType.DataBitOffset", Field, 18}, - {"BoolType", Type, 0}, - {"BoolType.BasicType", Field, 0}, - {"CharType", Type, 0}, - {"CharType.BasicType", Field, 0}, - {"Class", Type, 5}, - {"ClassAddrPtr", Const, 14}, - {"ClassAddress", Const, 5}, - {"ClassBlock", Const, 5}, - {"ClassConstant", Const, 5}, - {"ClassExprLoc", Const, 5}, - {"ClassFlag", Const, 5}, - {"ClassLinePtr", Const, 5}, - {"ClassLocList", Const, 14}, - {"ClassLocListPtr", Const, 5}, - {"ClassMacPtr", Const, 5}, - {"ClassRangeListPtr", Const, 5}, - {"ClassReference", Const, 5}, - {"ClassReferenceAlt", Const, 5}, - {"ClassReferenceSig", Const, 5}, - {"ClassRngList", Const, 14}, - {"ClassRngListsPtr", Const, 14}, - {"ClassStrOffsetsPtr", Const, 14}, - {"ClassString", Const, 5}, - {"ClassStringAlt", Const, 5}, - {"ClassUnknown", Const, 6}, - {"CommonType", Type, 0}, - {"CommonType.ByteSize", Field, 0}, - {"CommonType.Name", Field, 0}, - {"ComplexType", Type, 0}, - {"ComplexType.BasicType", Field, 0}, - {"Data", Type, 0}, - {"DecodeError", Type, 0}, - {"DecodeError.Err", Field, 0}, - {"DecodeError.Name", Field, 0}, - {"DecodeError.Offset", Field, 0}, - {"DotDotDotType", Type, 0}, - {"DotDotDotType.CommonType", Field, 0}, - {"Entry", Type, 0}, - {"Entry.Children", Field, 0}, - {"Entry.Field", Field, 0}, - {"Entry.Offset", Field, 0}, - {"Entry.Tag", Field, 0}, - {"EnumType", Type, 0}, - {"EnumType.CommonType", Field, 0}, - {"EnumType.EnumName", Field, 0}, - {"EnumType.Val", Field, 0}, - {"EnumValue", Type, 0}, - {"EnumValue.Name", Field, 0}, - {"EnumValue.Val", Field, 0}, - {"ErrUnknownPC", Var, 5}, - {"Field", Type, 0}, - {"Field.Attr", Field, 0}, - {"Field.Class", Field, 5}, - {"Field.Val", Field, 0}, - {"FloatType", Type, 0}, - {"FloatType.BasicType", Field, 0}, - {"FuncType", Type, 0}, - {"FuncType.CommonType", Field, 0}, - {"FuncType.ParamType", Field, 0}, - {"FuncType.ReturnType", Field, 0}, - {"IntType", Type, 0}, - {"IntType.BasicType", Field, 0}, - {"LineEntry", Type, 5}, - {"LineEntry.Address", Field, 5}, - {"LineEntry.BasicBlock", Field, 5}, - {"LineEntry.Column", Field, 5}, - {"LineEntry.Discriminator", Field, 5}, - {"LineEntry.EndSequence", Field, 5}, - {"LineEntry.EpilogueBegin", Field, 5}, - {"LineEntry.File", Field, 5}, - {"LineEntry.ISA", Field, 5}, - {"LineEntry.IsStmt", Field, 5}, - {"LineEntry.Line", Field, 5}, - {"LineEntry.OpIndex", Field, 5}, - {"LineEntry.PrologueEnd", Field, 5}, - {"LineFile", Type, 5}, - {"LineFile.Length", Field, 5}, - {"LineFile.Mtime", Field, 5}, - {"LineFile.Name", Field, 5}, - {"LineReader", Type, 5}, - {"LineReaderPos", Type, 5}, - {"New", Func, 0}, - {"Offset", Type, 0}, - {"PtrType", Type, 0}, - {"PtrType.CommonType", Field, 0}, - {"PtrType.Type", Field, 0}, - {"QualType", Type, 0}, - {"QualType.CommonType", Field, 0}, - {"QualType.Qual", Field, 0}, - {"QualType.Type", Field, 0}, - {"Reader", Type, 0}, - {"StructField", Type, 0}, - {"StructField.BitOffset", Field, 0}, - {"StructField.BitSize", Field, 0}, - {"StructField.ByteOffset", Field, 0}, - {"StructField.ByteSize", Field, 0}, - {"StructField.DataBitOffset", Field, 18}, - {"StructField.Name", Field, 0}, - {"StructField.Type", Field, 0}, - {"StructType", Type, 0}, - {"StructType.CommonType", Field, 0}, - {"StructType.Field", Field, 0}, - {"StructType.Incomplete", Field, 0}, - {"StructType.Kind", Field, 0}, - {"StructType.StructName", Field, 0}, - {"Tag", Type, 0}, - {"TagAccessDeclaration", Const, 0}, - {"TagArrayType", Const, 0}, - {"TagAtomicType", Const, 14}, - {"TagBaseType", Const, 0}, - {"TagCallSite", Const, 14}, - {"TagCallSiteParameter", Const, 14}, - {"TagCatchDwarfBlock", Const, 0}, - {"TagClassType", Const, 0}, - {"TagCoarrayType", Const, 14}, - {"TagCommonDwarfBlock", Const, 0}, - {"TagCommonInclusion", Const, 0}, - {"TagCompileUnit", Const, 0}, - {"TagCondition", Const, 3}, - {"TagConstType", Const, 0}, - {"TagConstant", Const, 0}, - {"TagDwarfProcedure", Const, 0}, - {"TagDynamicType", Const, 14}, - {"TagEntryPoint", Const, 0}, - {"TagEnumerationType", Const, 0}, - {"TagEnumerator", Const, 0}, - {"TagFileType", Const, 0}, - {"TagFormalParameter", Const, 0}, - {"TagFriend", Const, 0}, - {"TagGenericSubrange", Const, 14}, - {"TagImmutableType", Const, 14}, - {"TagImportedDeclaration", Const, 0}, - {"TagImportedModule", Const, 0}, - {"TagImportedUnit", Const, 0}, - {"TagInheritance", Const, 0}, - {"TagInlinedSubroutine", Const, 0}, - {"TagInterfaceType", Const, 0}, - {"TagLabel", Const, 0}, - {"TagLexDwarfBlock", Const, 0}, - {"TagMember", Const, 0}, - {"TagModule", Const, 0}, - {"TagMutableType", Const, 0}, - {"TagNamelist", Const, 0}, - {"TagNamelistItem", Const, 0}, - {"TagNamespace", Const, 0}, - {"TagPackedType", Const, 0}, - {"TagPartialUnit", Const, 0}, - {"TagPointerType", Const, 0}, - {"TagPtrToMemberType", Const, 0}, - {"TagReferenceType", Const, 0}, - {"TagRestrictType", Const, 0}, - {"TagRvalueReferenceType", Const, 3}, - {"TagSetType", Const, 0}, - {"TagSharedType", Const, 3}, - {"TagSkeletonUnit", Const, 14}, - {"TagStringType", Const, 0}, - {"TagStructType", Const, 0}, - {"TagSubprogram", Const, 0}, - {"TagSubrangeType", Const, 0}, - {"TagSubroutineType", Const, 0}, - {"TagTemplateAlias", Const, 3}, - {"TagTemplateTypeParameter", Const, 0}, - {"TagTemplateValueParameter", Const, 0}, - {"TagThrownType", Const, 0}, - {"TagTryDwarfBlock", Const, 0}, - {"TagTypeUnit", Const, 3}, - {"TagTypedef", Const, 0}, - {"TagUnionType", Const, 0}, - {"TagUnspecifiedParameters", Const, 0}, - {"TagUnspecifiedType", Const, 0}, - {"TagVariable", Const, 0}, - {"TagVariant", Const, 0}, - {"TagVariantPart", Const, 0}, - {"TagVolatileType", Const, 0}, - {"TagWithStmt", Const, 0}, - {"Type", Type, 0}, - {"TypedefType", Type, 0}, - {"TypedefType.CommonType", Field, 0}, - {"TypedefType.Type", Field, 0}, - {"UcharType", Type, 0}, - {"UcharType.BasicType", Field, 0}, - {"UintType", Type, 0}, - {"UintType.BasicType", Field, 0}, - {"UnspecifiedType", Type, 4}, - {"UnspecifiedType.BasicType", Field, 4}, - {"UnsupportedType", Type, 13}, - {"UnsupportedType.CommonType", Field, 13}, - {"UnsupportedType.Tag", Field, 13}, - {"VoidType", Type, 0}, - {"VoidType.CommonType", Field, 0}, - }, - "debug/elf": { - {"(*File).Close", Method, 0}, - {"(*File).DWARF", Method, 0}, - {"(*File).DynString", Method, 1}, - {"(*File).DynValue", Method, 21}, - {"(*File).DynamicSymbols", Method, 4}, - {"(*File).DynamicVersionNeeds", Method, 24}, - {"(*File).DynamicVersions", Method, 24}, - {"(*File).ImportedLibraries", Method, 0}, - {"(*File).ImportedSymbols", Method, 0}, - {"(*File).Section", Method, 0}, - {"(*File).SectionByType", Method, 0}, - {"(*File).Symbols", Method, 0}, - {"(*FormatError).Error", Method, 0}, - {"(*Prog).Open", Method, 0}, - {"(*Section).Data", Method, 0}, - {"(*Section).Open", Method, 0}, - {"(Class).GoString", Method, 0}, - {"(Class).String", Method, 0}, - {"(CompressionType).GoString", Method, 6}, - {"(CompressionType).String", Method, 6}, - {"(Data).GoString", Method, 0}, - {"(Data).String", Method, 0}, - {"(DynFlag).GoString", Method, 0}, - {"(DynFlag).String", Method, 0}, - {"(DynFlag1).GoString", Method, 21}, - {"(DynFlag1).String", Method, 21}, - {"(DynTag).GoString", Method, 0}, - {"(DynTag).String", Method, 0}, - {"(Machine).GoString", Method, 0}, - {"(Machine).String", Method, 0}, - {"(NType).GoString", Method, 0}, - {"(NType).String", Method, 0}, - {"(OSABI).GoString", Method, 0}, - {"(OSABI).String", Method, 0}, - {"(Prog).ReadAt", Method, 0}, - {"(ProgFlag).GoString", Method, 0}, - {"(ProgFlag).String", Method, 0}, - {"(ProgType).GoString", Method, 0}, - {"(ProgType).String", Method, 0}, - {"(R_386).GoString", Method, 0}, - {"(R_386).String", Method, 0}, - {"(R_390).GoString", Method, 7}, - {"(R_390).String", Method, 7}, - {"(R_AARCH64).GoString", Method, 4}, - {"(R_AARCH64).String", Method, 4}, - {"(R_ALPHA).GoString", Method, 0}, - {"(R_ALPHA).String", Method, 0}, - {"(R_ARM).GoString", Method, 0}, - {"(R_ARM).String", Method, 0}, - {"(R_LARCH).GoString", Method, 19}, - {"(R_LARCH).String", Method, 19}, - {"(R_MIPS).GoString", Method, 6}, - {"(R_MIPS).String", Method, 6}, - {"(R_PPC).GoString", Method, 0}, - {"(R_PPC).String", Method, 0}, - {"(R_PPC64).GoString", Method, 5}, - {"(R_PPC64).String", Method, 5}, - {"(R_RISCV).GoString", Method, 11}, - {"(R_RISCV).String", Method, 11}, - {"(R_SPARC).GoString", Method, 0}, - {"(R_SPARC).String", Method, 0}, - {"(R_X86_64).GoString", Method, 0}, - {"(R_X86_64).String", Method, 0}, - {"(Section).ReadAt", Method, 0}, - {"(SectionFlag).GoString", Method, 0}, - {"(SectionFlag).String", Method, 0}, - {"(SectionIndex).GoString", Method, 0}, - {"(SectionIndex).String", Method, 0}, - {"(SectionType).GoString", Method, 0}, - {"(SectionType).String", Method, 0}, - {"(SymBind).GoString", Method, 0}, - {"(SymBind).String", Method, 0}, - {"(SymType).GoString", Method, 0}, - {"(SymType).String", Method, 0}, - {"(SymVis).GoString", Method, 0}, - {"(SymVis).String", Method, 0}, - {"(Type).GoString", Method, 0}, - {"(Type).String", Method, 0}, - {"(Version).GoString", Method, 0}, - {"(Version).String", Method, 0}, - {"ARM_MAGIC_TRAMP_NUMBER", Const, 0}, - {"COMPRESS_HIOS", Const, 6}, - {"COMPRESS_HIPROC", Const, 6}, - {"COMPRESS_LOOS", Const, 6}, - {"COMPRESS_LOPROC", Const, 6}, - {"COMPRESS_ZLIB", Const, 6}, - {"COMPRESS_ZSTD", Const, 21}, - {"Chdr32", Type, 6}, - {"Chdr32.Addralign", Field, 6}, - {"Chdr32.Size", Field, 6}, - {"Chdr32.Type", Field, 6}, - {"Chdr64", Type, 6}, - {"Chdr64.Addralign", Field, 6}, - {"Chdr64.Size", Field, 6}, - {"Chdr64.Type", Field, 6}, - {"Class", Type, 0}, - {"CompressionType", Type, 6}, - {"DF_1_CONFALT", Const, 21}, - {"DF_1_DIRECT", Const, 21}, - {"DF_1_DISPRELDNE", Const, 21}, - {"DF_1_DISPRELPND", Const, 21}, - {"DF_1_EDITED", Const, 21}, - {"DF_1_ENDFILTEE", Const, 21}, - {"DF_1_GLOBAL", Const, 21}, - {"DF_1_GLOBAUDIT", Const, 21}, - {"DF_1_GROUP", Const, 21}, - {"DF_1_IGNMULDEF", Const, 21}, - {"DF_1_INITFIRST", Const, 21}, - {"DF_1_INTERPOSE", Const, 21}, - {"DF_1_KMOD", Const, 21}, - {"DF_1_LOADFLTR", Const, 21}, - {"DF_1_NOCOMMON", Const, 21}, - {"DF_1_NODEFLIB", Const, 21}, - {"DF_1_NODELETE", Const, 21}, - {"DF_1_NODIRECT", Const, 21}, - {"DF_1_NODUMP", Const, 21}, - {"DF_1_NOHDR", Const, 21}, - {"DF_1_NOKSYMS", Const, 21}, - {"DF_1_NOOPEN", Const, 21}, - {"DF_1_NORELOC", Const, 21}, - {"DF_1_NOW", Const, 21}, - {"DF_1_ORIGIN", Const, 21}, - {"DF_1_PIE", Const, 21}, - {"DF_1_SINGLETON", Const, 21}, - {"DF_1_STUB", Const, 21}, - {"DF_1_SYMINTPOSE", Const, 21}, - {"DF_1_TRANS", Const, 21}, - {"DF_1_WEAKFILTER", Const, 21}, - {"DF_BIND_NOW", Const, 0}, - {"DF_ORIGIN", Const, 0}, - {"DF_STATIC_TLS", Const, 0}, - {"DF_SYMBOLIC", Const, 0}, - {"DF_TEXTREL", Const, 0}, - {"DT_ADDRRNGHI", Const, 16}, - {"DT_ADDRRNGLO", Const, 16}, - {"DT_AUDIT", Const, 16}, - {"DT_AUXILIARY", Const, 16}, - {"DT_BIND_NOW", Const, 0}, - {"DT_CHECKSUM", Const, 16}, - {"DT_CONFIG", Const, 16}, - {"DT_DEBUG", Const, 0}, - {"DT_DEPAUDIT", Const, 16}, - {"DT_ENCODING", Const, 0}, - {"DT_FEATURE", Const, 16}, - {"DT_FILTER", Const, 16}, - {"DT_FINI", Const, 0}, - {"DT_FINI_ARRAY", Const, 0}, - {"DT_FINI_ARRAYSZ", Const, 0}, - {"DT_FLAGS", Const, 0}, - {"DT_FLAGS_1", Const, 16}, - {"DT_GNU_CONFLICT", Const, 16}, - {"DT_GNU_CONFLICTSZ", Const, 16}, - {"DT_GNU_HASH", Const, 16}, - {"DT_GNU_LIBLIST", Const, 16}, - {"DT_GNU_LIBLISTSZ", Const, 16}, - {"DT_GNU_PRELINKED", Const, 16}, - {"DT_HASH", Const, 0}, - {"DT_HIOS", Const, 0}, - {"DT_HIPROC", Const, 0}, - {"DT_INIT", Const, 0}, - {"DT_INIT_ARRAY", Const, 0}, - {"DT_INIT_ARRAYSZ", Const, 0}, - {"DT_JMPREL", Const, 0}, - {"DT_LOOS", Const, 0}, - {"DT_LOPROC", Const, 0}, - {"DT_MIPS_AUX_DYNAMIC", Const, 16}, - {"DT_MIPS_BASE_ADDRESS", Const, 16}, - {"DT_MIPS_COMPACT_SIZE", Const, 16}, - {"DT_MIPS_CONFLICT", Const, 16}, - {"DT_MIPS_CONFLICTNO", Const, 16}, - {"DT_MIPS_CXX_FLAGS", Const, 16}, - {"DT_MIPS_DELTA_CLASS", Const, 16}, - {"DT_MIPS_DELTA_CLASSSYM", Const, 16}, - {"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16}, - {"DT_MIPS_DELTA_CLASS_NO", Const, 16}, - {"DT_MIPS_DELTA_INSTANCE", Const, 16}, - {"DT_MIPS_DELTA_INSTANCE_NO", Const, 16}, - {"DT_MIPS_DELTA_RELOC", Const, 16}, - {"DT_MIPS_DELTA_RELOC_NO", Const, 16}, - {"DT_MIPS_DELTA_SYM", Const, 16}, - {"DT_MIPS_DELTA_SYM_NO", Const, 16}, - {"DT_MIPS_DYNSTR_ALIGN", Const, 16}, - {"DT_MIPS_FLAGS", Const, 16}, - {"DT_MIPS_GOTSYM", Const, 16}, - {"DT_MIPS_GP_VALUE", Const, 16}, - {"DT_MIPS_HIDDEN_GOTIDX", Const, 16}, - {"DT_MIPS_HIPAGENO", Const, 16}, - {"DT_MIPS_ICHECKSUM", Const, 16}, - {"DT_MIPS_INTERFACE", Const, 16}, - {"DT_MIPS_INTERFACE_SIZE", Const, 16}, - {"DT_MIPS_IVERSION", Const, 16}, - {"DT_MIPS_LIBLIST", Const, 16}, - {"DT_MIPS_LIBLISTNO", Const, 16}, - {"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16}, - {"DT_MIPS_LOCAL_GOTIDX", Const, 16}, - {"DT_MIPS_LOCAL_GOTNO", Const, 16}, - {"DT_MIPS_MSYM", Const, 16}, - {"DT_MIPS_OPTIONS", Const, 16}, - {"DT_MIPS_PERF_SUFFIX", Const, 16}, - {"DT_MIPS_PIXIE_INIT", Const, 16}, - {"DT_MIPS_PLTGOT", Const, 16}, - {"DT_MIPS_PROTECTED_GOTIDX", Const, 16}, - {"DT_MIPS_RLD_MAP", Const, 16}, - {"DT_MIPS_RLD_MAP_REL", Const, 16}, - {"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16}, - {"DT_MIPS_RLD_VERSION", Const, 16}, - {"DT_MIPS_RWPLT", Const, 16}, - {"DT_MIPS_SYMBOL_LIB", Const, 16}, - {"DT_MIPS_SYMTABNO", Const, 16}, - {"DT_MIPS_TIME_STAMP", Const, 16}, - {"DT_MIPS_UNREFEXTNO", Const, 16}, - {"DT_MOVEENT", Const, 16}, - {"DT_MOVESZ", Const, 16}, - {"DT_MOVETAB", Const, 16}, - {"DT_NEEDED", Const, 0}, - {"DT_NULL", Const, 0}, - {"DT_PLTGOT", Const, 0}, - {"DT_PLTPAD", Const, 16}, - {"DT_PLTPADSZ", Const, 16}, - {"DT_PLTREL", Const, 0}, - {"DT_PLTRELSZ", Const, 0}, - {"DT_POSFLAG_1", Const, 16}, - {"DT_PPC64_GLINK", Const, 16}, - {"DT_PPC64_OPD", Const, 16}, - {"DT_PPC64_OPDSZ", Const, 16}, - {"DT_PPC64_OPT", Const, 16}, - {"DT_PPC_GOT", Const, 16}, - {"DT_PPC_OPT", Const, 16}, - {"DT_PREINIT_ARRAY", Const, 0}, - {"DT_PREINIT_ARRAYSZ", Const, 0}, - {"DT_REL", Const, 0}, - {"DT_RELA", Const, 0}, - {"DT_RELACOUNT", Const, 16}, - {"DT_RELAENT", Const, 0}, - {"DT_RELASZ", Const, 0}, - {"DT_RELCOUNT", Const, 16}, - {"DT_RELENT", Const, 0}, - {"DT_RELSZ", Const, 0}, - {"DT_RPATH", Const, 0}, - {"DT_RUNPATH", Const, 0}, - {"DT_SONAME", Const, 0}, - {"DT_SPARC_REGISTER", Const, 16}, - {"DT_STRSZ", Const, 0}, - {"DT_STRTAB", Const, 0}, - {"DT_SYMBOLIC", Const, 0}, - {"DT_SYMENT", Const, 0}, - {"DT_SYMINENT", Const, 16}, - {"DT_SYMINFO", Const, 16}, - {"DT_SYMINSZ", Const, 16}, - {"DT_SYMTAB", Const, 0}, - {"DT_SYMTAB_SHNDX", Const, 16}, - {"DT_TEXTREL", Const, 0}, - {"DT_TLSDESC_GOT", Const, 16}, - {"DT_TLSDESC_PLT", Const, 16}, - {"DT_USED", Const, 16}, - {"DT_VALRNGHI", Const, 16}, - {"DT_VALRNGLO", Const, 16}, - {"DT_VERDEF", Const, 16}, - {"DT_VERDEFNUM", Const, 16}, - {"DT_VERNEED", Const, 0}, - {"DT_VERNEEDNUM", Const, 0}, - {"DT_VERSYM", Const, 0}, - {"Data", Type, 0}, - {"Dyn32", Type, 0}, - {"Dyn32.Tag", Field, 0}, - {"Dyn32.Val", Field, 0}, - {"Dyn64", Type, 0}, - {"Dyn64.Tag", Field, 0}, - {"Dyn64.Val", Field, 0}, - {"DynFlag", Type, 0}, - {"DynFlag1", Type, 21}, - {"DynTag", Type, 0}, - {"DynamicVersion", Type, 24}, - {"DynamicVersion.Deps", Field, 24}, - {"DynamicVersion.Flags", Field, 24}, - {"DynamicVersion.Index", Field, 24}, - {"DynamicVersion.Name", Field, 24}, - {"DynamicVersionDep", Type, 24}, - {"DynamicVersionDep.Dep", Field, 24}, - {"DynamicVersionDep.Flags", Field, 24}, - {"DynamicVersionDep.Index", Field, 24}, - {"DynamicVersionFlag", Type, 24}, - {"DynamicVersionNeed", Type, 24}, - {"DynamicVersionNeed.Name", Field, 24}, - {"DynamicVersionNeed.Needs", Field, 24}, - {"EI_ABIVERSION", Const, 0}, - {"EI_CLASS", Const, 0}, - {"EI_DATA", Const, 0}, - {"EI_NIDENT", Const, 0}, - {"EI_OSABI", Const, 0}, - {"EI_PAD", Const, 0}, - {"EI_VERSION", Const, 0}, - {"ELFCLASS32", Const, 0}, - {"ELFCLASS64", Const, 0}, - {"ELFCLASSNONE", Const, 0}, - {"ELFDATA2LSB", Const, 0}, - {"ELFDATA2MSB", Const, 0}, - {"ELFDATANONE", Const, 0}, - {"ELFMAG", Const, 0}, - {"ELFOSABI_86OPEN", Const, 0}, - {"ELFOSABI_AIX", Const, 0}, - {"ELFOSABI_ARM", Const, 0}, - {"ELFOSABI_AROS", Const, 11}, - {"ELFOSABI_CLOUDABI", Const, 11}, - {"ELFOSABI_FENIXOS", Const, 11}, - {"ELFOSABI_FREEBSD", Const, 0}, - {"ELFOSABI_HPUX", Const, 0}, - {"ELFOSABI_HURD", Const, 0}, - {"ELFOSABI_IRIX", Const, 0}, - {"ELFOSABI_LINUX", Const, 0}, - {"ELFOSABI_MODESTO", Const, 0}, - {"ELFOSABI_NETBSD", Const, 0}, - {"ELFOSABI_NONE", Const, 0}, - {"ELFOSABI_NSK", Const, 0}, - {"ELFOSABI_OPENBSD", Const, 0}, - {"ELFOSABI_OPENVMS", Const, 0}, - {"ELFOSABI_SOLARIS", Const, 0}, - {"ELFOSABI_STANDALONE", Const, 0}, - {"ELFOSABI_TRU64", Const, 0}, - {"EM_386", Const, 0}, - {"EM_486", Const, 0}, - {"EM_56800EX", Const, 11}, - {"EM_68HC05", Const, 11}, - {"EM_68HC08", Const, 11}, - {"EM_68HC11", Const, 11}, - {"EM_68HC12", Const, 0}, - {"EM_68HC16", Const, 11}, - {"EM_68K", Const, 0}, - {"EM_78KOR", Const, 11}, - {"EM_8051", Const, 11}, - {"EM_860", Const, 0}, - {"EM_88K", Const, 0}, - {"EM_960", Const, 0}, - {"EM_AARCH64", Const, 4}, - {"EM_ALPHA", Const, 0}, - {"EM_ALPHA_STD", Const, 0}, - {"EM_ALTERA_NIOS2", Const, 11}, - {"EM_AMDGPU", Const, 11}, - {"EM_ARC", Const, 0}, - {"EM_ARCA", Const, 11}, - {"EM_ARC_COMPACT", Const, 11}, - {"EM_ARC_COMPACT2", Const, 11}, - {"EM_ARM", Const, 0}, - {"EM_AVR", Const, 11}, - {"EM_AVR32", Const, 11}, - {"EM_BA1", Const, 11}, - {"EM_BA2", Const, 11}, - {"EM_BLACKFIN", Const, 11}, - {"EM_BPF", Const, 11}, - {"EM_C166", Const, 11}, - {"EM_CDP", Const, 11}, - {"EM_CE", Const, 11}, - {"EM_CLOUDSHIELD", Const, 11}, - {"EM_COGE", Const, 11}, - {"EM_COLDFIRE", Const, 0}, - {"EM_COOL", Const, 11}, - {"EM_COREA_1ST", Const, 11}, - {"EM_COREA_2ND", Const, 11}, - {"EM_CR", Const, 11}, - {"EM_CR16", Const, 11}, - {"EM_CRAYNV2", Const, 11}, - {"EM_CRIS", Const, 11}, - {"EM_CRX", Const, 11}, - {"EM_CSR_KALIMBA", Const, 11}, - {"EM_CUDA", Const, 11}, - {"EM_CYPRESS_M8C", Const, 11}, - {"EM_D10V", Const, 11}, - {"EM_D30V", Const, 11}, - {"EM_DSP24", Const, 11}, - {"EM_DSPIC30F", Const, 11}, - {"EM_DXP", Const, 11}, - {"EM_ECOG1", Const, 11}, - {"EM_ECOG16", Const, 11}, - {"EM_ECOG1X", Const, 11}, - {"EM_ECOG2", Const, 11}, - {"EM_ETPU", Const, 11}, - {"EM_EXCESS", Const, 11}, - {"EM_F2MC16", Const, 11}, - {"EM_FIREPATH", Const, 11}, - {"EM_FR20", Const, 0}, - {"EM_FR30", Const, 11}, - {"EM_FT32", Const, 11}, - {"EM_FX66", Const, 11}, - {"EM_H8S", Const, 0}, - {"EM_H8_300", Const, 0}, - {"EM_H8_300H", Const, 0}, - {"EM_H8_500", Const, 0}, - {"EM_HUANY", Const, 11}, - {"EM_IA_64", Const, 0}, - {"EM_INTEL205", Const, 11}, - {"EM_INTEL206", Const, 11}, - {"EM_INTEL207", Const, 11}, - {"EM_INTEL208", Const, 11}, - {"EM_INTEL209", Const, 11}, - {"EM_IP2K", Const, 11}, - {"EM_JAVELIN", Const, 11}, - {"EM_K10M", Const, 11}, - {"EM_KM32", Const, 11}, - {"EM_KMX16", Const, 11}, - {"EM_KMX32", Const, 11}, - {"EM_KMX8", Const, 11}, - {"EM_KVARC", Const, 11}, - {"EM_L10M", Const, 11}, - {"EM_LANAI", Const, 11}, - {"EM_LATTICEMICO32", Const, 11}, - {"EM_LOONGARCH", Const, 19}, - {"EM_M16C", Const, 11}, - {"EM_M32", Const, 0}, - {"EM_M32C", Const, 11}, - {"EM_M32R", Const, 11}, - {"EM_MANIK", Const, 11}, - {"EM_MAX", Const, 11}, - {"EM_MAXQ30", Const, 11}, - {"EM_MCHP_PIC", Const, 11}, - {"EM_MCST_ELBRUS", Const, 11}, - {"EM_ME16", Const, 0}, - {"EM_METAG", Const, 11}, - {"EM_MICROBLAZE", Const, 11}, - {"EM_MIPS", Const, 0}, - {"EM_MIPS_RS3_LE", Const, 0}, - {"EM_MIPS_RS4_BE", Const, 0}, - {"EM_MIPS_X", Const, 0}, - {"EM_MMA", Const, 0}, - {"EM_MMDSP_PLUS", Const, 11}, - {"EM_MMIX", Const, 11}, - {"EM_MN10200", Const, 11}, - {"EM_MN10300", Const, 11}, - {"EM_MOXIE", Const, 11}, - {"EM_MSP430", Const, 11}, - {"EM_NCPU", Const, 0}, - {"EM_NDR1", Const, 0}, - {"EM_NDS32", Const, 11}, - {"EM_NONE", Const, 0}, - {"EM_NORC", Const, 11}, - {"EM_NS32K", Const, 11}, - {"EM_OPEN8", Const, 11}, - {"EM_OPENRISC", Const, 11}, - {"EM_PARISC", Const, 0}, - {"EM_PCP", Const, 0}, - {"EM_PDP10", Const, 11}, - {"EM_PDP11", Const, 11}, - {"EM_PDSP", Const, 11}, - {"EM_PJ", Const, 11}, - {"EM_PPC", Const, 0}, - {"EM_PPC64", Const, 0}, - {"EM_PRISM", Const, 11}, - {"EM_QDSP6", Const, 11}, - {"EM_R32C", Const, 11}, - {"EM_RCE", Const, 0}, - {"EM_RH32", Const, 0}, - {"EM_RISCV", Const, 11}, - {"EM_RL78", Const, 11}, - {"EM_RS08", Const, 11}, - {"EM_RX", Const, 11}, - {"EM_S370", Const, 0}, - {"EM_S390", Const, 0}, - {"EM_SCORE7", Const, 11}, - {"EM_SEP", Const, 11}, - {"EM_SE_C17", Const, 11}, - {"EM_SE_C33", Const, 11}, - {"EM_SH", Const, 0}, - {"EM_SHARC", Const, 11}, - {"EM_SLE9X", Const, 11}, - {"EM_SNP1K", Const, 11}, - {"EM_SPARC", Const, 0}, - {"EM_SPARC32PLUS", Const, 0}, - {"EM_SPARCV9", Const, 0}, - {"EM_ST100", Const, 0}, - {"EM_ST19", Const, 11}, - {"EM_ST200", Const, 11}, - {"EM_ST7", Const, 11}, - {"EM_ST9PLUS", Const, 11}, - {"EM_STARCORE", Const, 0}, - {"EM_STM8", Const, 11}, - {"EM_STXP7X", Const, 11}, - {"EM_SVX", Const, 11}, - {"EM_TILE64", Const, 11}, - {"EM_TILEGX", Const, 11}, - {"EM_TILEPRO", Const, 11}, - {"EM_TINYJ", Const, 0}, - {"EM_TI_ARP32", Const, 11}, - {"EM_TI_C2000", Const, 11}, - {"EM_TI_C5500", Const, 11}, - {"EM_TI_C6000", Const, 11}, - {"EM_TI_PRU", Const, 11}, - {"EM_TMM_GPP", Const, 11}, - {"EM_TPC", Const, 11}, - {"EM_TRICORE", Const, 0}, - {"EM_TRIMEDIA", Const, 11}, - {"EM_TSK3000", Const, 11}, - {"EM_UNICORE", Const, 11}, - {"EM_V800", Const, 0}, - {"EM_V850", Const, 11}, - {"EM_VAX", Const, 11}, - {"EM_VIDEOCORE", Const, 11}, - {"EM_VIDEOCORE3", Const, 11}, - {"EM_VIDEOCORE5", Const, 11}, - {"EM_VISIUM", Const, 11}, - {"EM_VPP500", Const, 0}, - {"EM_X86_64", Const, 0}, - {"EM_XCORE", Const, 11}, - {"EM_XGATE", Const, 11}, - {"EM_XIMO16", Const, 11}, - {"EM_XTENSA", Const, 11}, - {"EM_Z80", Const, 11}, - {"EM_ZSP", Const, 11}, - {"ET_CORE", Const, 0}, - {"ET_DYN", Const, 0}, - {"ET_EXEC", Const, 0}, - {"ET_HIOS", Const, 0}, - {"ET_HIPROC", Const, 0}, - {"ET_LOOS", Const, 0}, - {"ET_LOPROC", Const, 0}, - {"ET_NONE", Const, 0}, - {"ET_REL", Const, 0}, - {"EV_CURRENT", Const, 0}, - {"EV_NONE", Const, 0}, - {"ErrNoSymbols", Var, 4}, - {"File", Type, 0}, - {"File.FileHeader", Field, 0}, - {"File.Progs", Field, 0}, - {"File.Sections", Field, 0}, - {"FileHeader", Type, 0}, - {"FileHeader.ABIVersion", Field, 0}, - {"FileHeader.ByteOrder", Field, 0}, - {"FileHeader.Class", Field, 0}, - {"FileHeader.Data", Field, 0}, - {"FileHeader.Entry", Field, 1}, - {"FileHeader.Machine", Field, 0}, - {"FileHeader.OSABI", Field, 0}, - {"FileHeader.Type", Field, 0}, - {"FileHeader.Version", Field, 0}, - {"FormatError", Type, 0}, - {"Header32", Type, 0}, - {"Header32.Ehsize", Field, 0}, - {"Header32.Entry", Field, 0}, - {"Header32.Flags", Field, 0}, - {"Header32.Ident", Field, 0}, - {"Header32.Machine", Field, 0}, - {"Header32.Phentsize", Field, 0}, - {"Header32.Phnum", Field, 0}, - {"Header32.Phoff", Field, 0}, - {"Header32.Shentsize", Field, 0}, - {"Header32.Shnum", Field, 0}, - {"Header32.Shoff", Field, 0}, - {"Header32.Shstrndx", Field, 0}, - {"Header32.Type", Field, 0}, - {"Header32.Version", Field, 0}, - {"Header64", Type, 0}, - {"Header64.Ehsize", Field, 0}, - {"Header64.Entry", Field, 0}, - {"Header64.Flags", Field, 0}, - {"Header64.Ident", Field, 0}, - {"Header64.Machine", Field, 0}, - {"Header64.Phentsize", Field, 0}, - {"Header64.Phnum", Field, 0}, - {"Header64.Phoff", Field, 0}, - {"Header64.Shentsize", Field, 0}, - {"Header64.Shnum", Field, 0}, - {"Header64.Shoff", Field, 0}, - {"Header64.Shstrndx", Field, 0}, - {"Header64.Type", Field, 0}, - {"Header64.Version", Field, 0}, - {"ImportedSymbol", Type, 0}, - {"ImportedSymbol.Library", Field, 0}, - {"ImportedSymbol.Name", Field, 0}, - {"ImportedSymbol.Version", Field, 0}, - {"Machine", Type, 0}, - {"NT_FPREGSET", Const, 0}, - {"NT_PRPSINFO", Const, 0}, - {"NT_PRSTATUS", Const, 0}, - {"NType", Type, 0}, - {"NewFile", Func, 0}, - {"OSABI", Type, 0}, - {"Open", Func, 0}, - {"PF_MASKOS", Const, 0}, - {"PF_MASKPROC", Const, 0}, - {"PF_R", Const, 0}, - {"PF_W", Const, 0}, - {"PF_X", Const, 0}, - {"PT_AARCH64_ARCHEXT", Const, 16}, - {"PT_AARCH64_UNWIND", Const, 16}, - {"PT_ARM_ARCHEXT", Const, 16}, - {"PT_ARM_EXIDX", Const, 16}, - {"PT_DYNAMIC", Const, 0}, - {"PT_GNU_EH_FRAME", Const, 16}, - {"PT_GNU_MBIND_HI", Const, 16}, - {"PT_GNU_MBIND_LO", Const, 16}, - {"PT_GNU_PROPERTY", Const, 16}, - {"PT_GNU_RELRO", Const, 16}, - {"PT_GNU_STACK", Const, 16}, - {"PT_HIOS", Const, 0}, - {"PT_HIPROC", Const, 0}, - {"PT_INTERP", Const, 0}, - {"PT_LOAD", Const, 0}, - {"PT_LOOS", Const, 0}, - {"PT_LOPROC", Const, 0}, - {"PT_MIPS_ABIFLAGS", Const, 16}, - {"PT_MIPS_OPTIONS", Const, 16}, - {"PT_MIPS_REGINFO", Const, 16}, - {"PT_MIPS_RTPROC", Const, 16}, - {"PT_NOTE", Const, 0}, - {"PT_NULL", Const, 0}, - {"PT_OPENBSD_BOOTDATA", Const, 16}, - {"PT_OPENBSD_NOBTCFI", Const, 23}, - {"PT_OPENBSD_RANDOMIZE", Const, 16}, - {"PT_OPENBSD_WXNEEDED", Const, 16}, - {"PT_PAX_FLAGS", Const, 16}, - {"PT_PHDR", Const, 0}, - {"PT_S390_PGSTE", Const, 16}, - {"PT_SHLIB", Const, 0}, - {"PT_SUNWSTACK", Const, 16}, - {"PT_SUNW_EH_FRAME", Const, 16}, - {"PT_TLS", Const, 0}, - {"Prog", Type, 0}, - {"Prog.ProgHeader", Field, 0}, - {"Prog.ReaderAt", Field, 0}, - {"Prog32", Type, 0}, - {"Prog32.Align", Field, 0}, - {"Prog32.Filesz", Field, 0}, - {"Prog32.Flags", Field, 0}, - {"Prog32.Memsz", Field, 0}, - {"Prog32.Off", Field, 0}, - {"Prog32.Paddr", Field, 0}, - {"Prog32.Type", Field, 0}, - {"Prog32.Vaddr", Field, 0}, - {"Prog64", Type, 0}, - {"Prog64.Align", Field, 0}, - {"Prog64.Filesz", Field, 0}, - {"Prog64.Flags", Field, 0}, - {"Prog64.Memsz", Field, 0}, - {"Prog64.Off", Field, 0}, - {"Prog64.Paddr", Field, 0}, - {"Prog64.Type", Field, 0}, - {"Prog64.Vaddr", Field, 0}, - {"ProgFlag", Type, 0}, - {"ProgHeader", Type, 0}, - {"ProgHeader.Align", Field, 0}, - {"ProgHeader.Filesz", Field, 0}, - {"ProgHeader.Flags", Field, 0}, - {"ProgHeader.Memsz", Field, 0}, - {"ProgHeader.Off", Field, 0}, - {"ProgHeader.Paddr", Field, 0}, - {"ProgHeader.Type", Field, 0}, - {"ProgHeader.Vaddr", Field, 0}, - {"ProgType", Type, 0}, - {"R_386", Type, 0}, - {"R_386_16", Const, 10}, - {"R_386_32", Const, 0}, - {"R_386_32PLT", Const, 10}, - {"R_386_8", Const, 10}, - {"R_386_COPY", Const, 0}, - {"R_386_GLOB_DAT", Const, 0}, - {"R_386_GOT32", Const, 0}, - {"R_386_GOT32X", Const, 10}, - {"R_386_GOTOFF", Const, 0}, - {"R_386_GOTPC", Const, 0}, - {"R_386_IRELATIVE", Const, 10}, - {"R_386_JMP_SLOT", Const, 0}, - {"R_386_NONE", Const, 0}, - {"R_386_PC16", Const, 10}, - {"R_386_PC32", Const, 0}, - {"R_386_PC8", Const, 10}, - {"R_386_PLT32", Const, 0}, - {"R_386_RELATIVE", Const, 0}, - {"R_386_SIZE32", Const, 10}, - {"R_386_TLS_DESC", Const, 10}, - {"R_386_TLS_DESC_CALL", Const, 10}, - {"R_386_TLS_DTPMOD32", Const, 0}, - {"R_386_TLS_DTPOFF32", Const, 0}, - {"R_386_TLS_GD", Const, 0}, - {"R_386_TLS_GD_32", Const, 0}, - {"R_386_TLS_GD_CALL", Const, 0}, - {"R_386_TLS_GD_POP", Const, 0}, - {"R_386_TLS_GD_PUSH", Const, 0}, - {"R_386_TLS_GOTDESC", Const, 10}, - {"R_386_TLS_GOTIE", Const, 0}, - {"R_386_TLS_IE", Const, 0}, - {"R_386_TLS_IE_32", Const, 0}, - {"R_386_TLS_LDM", Const, 0}, - {"R_386_TLS_LDM_32", Const, 0}, - {"R_386_TLS_LDM_CALL", Const, 0}, - {"R_386_TLS_LDM_POP", Const, 0}, - {"R_386_TLS_LDM_PUSH", Const, 0}, - {"R_386_TLS_LDO_32", Const, 0}, - {"R_386_TLS_LE", Const, 0}, - {"R_386_TLS_LE_32", Const, 0}, - {"R_386_TLS_TPOFF", Const, 0}, - {"R_386_TLS_TPOFF32", Const, 0}, - {"R_390", Type, 7}, - {"R_390_12", Const, 7}, - {"R_390_16", Const, 7}, - {"R_390_20", Const, 7}, - {"R_390_32", Const, 7}, - {"R_390_64", Const, 7}, - {"R_390_8", Const, 7}, - {"R_390_COPY", Const, 7}, - {"R_390_GLOB_DAT", Const, 7}, - {"R_390_GOT12", Const, 7}, - {"R_390_GOT16", Const, 7}, - {"R_390_GOT20", Const, 7}, - {"R_390_GOT32", Const, 7}, - {"R_390_GOT64", Const, 7}, - {"R_390_GOTENT", Const, 7}, - {"R_390_GOTOFF", Const, 7}, - {"R_390_GOTOFF16", Const, 7}, - {"R_390_GOTOFF64", Const, 7}, - {"R_390_GOTPC", Const, 7}, - {"R_390_GOTPCDBL", Const, 7}, - {"R_390_GOTPLT12", Const, 7}, - {"R_390_GOTPLT16", Const, 7}, - {"R_390_GOTPLT20", Const, 7}, - {"R_390_GOTPLT32", Const, 7}, - {"R_390_GOTPLT64", Const, 7}, - {"R_390_GOTPLTENT", Const, 7}, - {"R_390_GOTPLTOFF16", Const, 7}, - {"R_390_GOTPLTOFF32", Const, 7}, - {"R_390_GOTPLTOFF64", Const, 7}, - {"R_390_JMP_SLOT", Const, 7}, - {"R_390_NONE", Const, 7}, - {"R_390_PC16", Const, 7}, - {"R_390_PC16DBL", Const, 7}, - {"R_390_PC32", Const, 7}, - {"R_390_PC32DBL", Const, 7}, - {"R_390_PC64", Const, 7}, - {"R_390_PLT16DBL", Const, 7}, - {"R_390_PLT32", Const, 7}, - {"R_390_PLT32DBL", Const, 7}, - {"R_390_PLT64", Const, 7}, - {"R_390_RELATIVE", Const, 7}, - {"R_390_TLS_DTPMOD", Const, 7}, - {"R_390_TLS_DTPOFF", Const, 7}, - {"R_390_TLS_GD32", Const, 7}, - {"R_390_TLS_GD64", Const, 7}, - {"R_390_TLS_GDCALL", Const, 7}, - {"R_390_TLS_GOTIE12", Const, 7}, - {"R_390_TLS_GOTIE20", Const, 7}, - {"R_390_TLS_GOTIE32", Const, 7}, - {"R_390_TLS_GOTIE64", Const, 7}, - {"R_390_TLS_IE32", Const, 7}, - {"R_390_TLS_IE64", Const, 7}, - {"R_390_TLS_IEENT", Const, 7}, - {"R_390_TLS_LDCALL", Const, 7}, - {"R_390_TLS_LDM32", Const, 7}, - {"R_390_TLS_LDM64", Const, 7}, - {"R_390_TLS_LDO32", Const, 7}, - {"R_390_TLS_LDO64", Const, 7}, - {"R_390_TLS_LE32", Const, 7}, - {"R_390_TLS_LE64", Const, 7}, - {"R_390_TLS_LOAD", Const, 7}, - {"R_390_TLS_TPOFF", Const, 7}, - {"R_AARCH64", Type, 4}, - {"R_AARCH64_ABS16", Const, 4}, - {"R_AARCH64_ABS32", Const, 4}, - {"R_AARCH64_ABS64", Const, 4}, - {"R_AARCH64_ADD_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_ADR_GOT_PAGE", Const, 4}, - {"R_AARCH64_ADR_PREL_LO21", Const, 4}, - {"R_AARCH64_ADR_PREL_PG_HI21", Const, 4}, - {"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4}, - {"R_AARCH64_CALL26", Const, 4}, - {"R_AARCH64_CONDBR19", Const, 4}, - {"R_AARCH64_COPY", Const, 4}, - {"R_AARCH64_GLOB_DAT", Const, 4}, - {"R_AARCH64_GOT_LD_PREL19", Const, 4}, - {"R_AARCH64_IRELATIVE", Const, 4}, - {"R_AARCH64_JUMP26", Const, 4}, - {"R_AARCH64_JUMP_SLOT", Const, 4}, - {"R_AARCH64_LD64_GOTOFF_LO15", Const, 10}, - {"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10}, - {"R_AARCH64_LD64_GOT_LO12_NC", Const, 4}, - {"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_LD_PREL_LO19", Const, 4}, - {"R_AARCH64_MOVW_SABS_G0", Const, 4}, - {"R_AARCH64_MOVW_SABS_G1", Const, 4}, - {"R_AARCH64_MOVW_SABS_G2", Const, 4}, - {"R_AARCH64_MOVW_UABS_G0", Const, 4}, - {"R_AARCH64_MOVW_UABS_G0_NC", Const, 4}, - {"R_AARCH64_MOVW_UABS_G1", Const, 4}, - {"R_AARCH64_MOVW_UABS_G1_NC", Const, 4}, - {"R_AARCH64_MOVW_UABS_G2", Const, 4}, - {"R_AARCH64_MOVW_UABS_G2_NC", Const, 4}, - {"R_AARCH64_MOVW_UABS_G3", Const, 4}, - {"R_AARCH64_NONE", Const, 4}, - {"R_AARCH64_NULL", Const, 4}, - {"R_AARCH64_P32_ABS16", Const, 4}, - {"R_AARCH64_P32_ABS32", Const, 4}, - {"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4}, - {"R_AARCH64_P32_ADR_PREL_LO21", Const, 4}, - {"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4}, - {"R_AARCH64_P32_CALL26", Const, 4}, - {"R_AARCH64_P32_CONDBR19", Const, 4}, - {"R_AARCH64_P32_COPY", Const, 4}, - {"R_AARCH64_P32_GLOB_DAT", Const, 4}, - {"R_AARCH64_P32_GOT_LD_PREL19", Const, 4}, - {"R_AARCH64_P32_IRELATIVE", Const, 4}, - {"R_AARCH64_P32_JUMP26", Const, 4}, - {"R_AARCH64_P32_JUMP_SLOT", Const, 4}, - {"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4}, - {"R_AARCH64_P32_LD_PREL_LO19", Const, 4}, - {"R_AARCH64_P32_MOVW_SABS_G0", Const, 4}, - {"R_AARCH64_P32_MOVW_UABS_G0", Const, 4}, - {"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4}, - {"R_AARCH64_P32_MOVW_UABS_G1", Const, 4}, - {"R_AARCH64_P32_PREL16", Const, 4}, - {"R_AARCH64_P32_PREL32", Const, 4}, - {"R_AARCH64_P32_RELATIVE", Const, 4}, - {"R_AARCH64_P32_TLSDESC", Const, 4}, - {"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4}, - {"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4}, - {"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4}, - {"R_AARCH64_P32_TLSDESC_CALL", Const, 4}, - {"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4}, - {"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4}, - {"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4}, - {"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4}, - {"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, - {"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4}, - {"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4}, - {"R_AARCH64_P32_TLS_DTPMOD", Const, 4}, - {"R_AARCH64_P32_TLS_DTPREL", Const, 4}, - {"R_AARCH64_P32_TLS_TPREL", Const, 4}, - {"R_AARCH64_P32_TSTBR14", Const, 4}, - {"R_AARCH64_PREL16", Const, 4}, - {"R_AARCH64_PREL32", Const, 4}, - {"R_AARCH64_PREL64", Const, 4}, - {"R_AARCH64_RELATIVE", Const, 4}, - {"R_AARCH64_TLSDESC", Const, 4}, - {"R_AARCH64_TLSDESC_ADD", Const, 4}, - {"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4}, - {"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4}, - {"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4}, - {"R_AARCH64_TLSDESC_CALL", Const, 4}, - {"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4}, - {"R_AARCH64_TLSDESC_LDR", Const, 4}, - {"R_AARCH64_TLSDESC_LD_PREL19", Const, 4}, - {"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4}, - {"R_AARCH64_TLSDESC_OFF_G1", Const, 4}, - {"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4}, - {"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4}, - {"R_AARCH64_TLSGD_ADR_PREL21", Const, 10}, - {"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10}, - {"R_AARCH64_TLSGD_MOVW_G1", Const, 10}, - {"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4}, - {"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4}, - {"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4}, - {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4}, - {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4}, - {"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10}, - {"R_AARCH64_TLSLD_ADR_PREL21", Const, 10}, - {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10}, - {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10}, - {"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4}, - {"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4}, - {"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4}, - {"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10}, - {"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4}, - {"R_AARCH64_TLS_DTPMOD64", Const, 4}, - {"R_AARCH64_TLS_DTPREL64", Const, 4}, - {"R_AARCH64_TLS_TPREL64", Const, 4}, - {"R_AARCH64_TSTBR14", Const, 4}, - {"R_ALPHA", Type, 0}, - {"R_ALPHA_BRADDR", Const, 0}, - {"R_ALPHA_COPY", Const, 0}, - {"R_ALPHA_GLOB_DAT", Const, 0}, - {"R_ALPHA_GPDISP", Const, 0}, - {"R_ALPHA_GPREL32", Const, 0}, - {"R_ALPHA_GPRELHIGH", Const, 0}, - {"R_ALPHA_GPRELLOW", Const, 0}, - {"R_ALPHA_GPVALUE", Const, 0}, - {"R_ALPHA_HINT", Const, 0}, - {"R_ALPHA_IMMED_BR_HI32", Const, 0}, - {"R_ALPHA_IMMED_GP_16", Const, 0}, - {"R_ALPHA_IMMED_GP_HI32", Const, 0}, - {"R_ALPHA_IMMED_LO32", Const, 0}, - {"R_ALPHA_IMMED_SCN_HI32", Const, 0}, - {"R_ALPHA_JMP_SLOT", Const, 0}, - {"R_ALPHA_LITERAL", Const, 0}, - {"R_ALPHA_LITUSE", Const, 0}, - {"R_ALPHA_NONE", Const, 0}, - {"R_ALPHA_OP_PRSHIFT", Const, 0}, - {"R_ALPHA_OP_PSUB", Const, 0}, - {"R_ALPHA_OP_PUSH", Const, 0}, - {"R_ALPHA_OP_STORE", Const, 0}, - {"R_ALPHA_REFLONG", Const, 0}, - {"R_ALPHA_REFQUAD", Const, 0}, - {"R_ALPHA_RELATIVE", Const, 0}, - {"R_ALPHA_SREL16", Const, 0}, - {"R_ALPHA_SREL32", Const, 0}, - {"R_ALPHA_SREL64", Const, 0}, - {"R_ARM", Type, 0}, - {"R_ARM_ABS12", Const, 0}, - {"R_ARM_ABS16", Const, 0}, - {"R_ARM_ABS32", Const, 0}, - {"R_ARM_ABS32_NOI", Const, 10}, - {"R_ARM_ABS8", Const, 0}, - {"R_ARM_ALU_PCREL_15_8", Const, 10}, - {"R_ARM_ALU_PCREL_23_15", Const, 10}, - {"R_ARM_ALU_PCREL_7_0", Const, 10}, - {"R_ARM_ALU_PC_G0", Const, 10}, - {"R_ARM_ALU_PC_G0_NC", Const, 10}, - {"R_ARM_ALU_PC_G1", Const, 10}, - {"R_ARM_ALU_PC_G1_NC", Const, 10}, - {"R_ARM_ALU_PC_G2", Const, 10}, - {"R_ARM_ALU_SBREL_19_12_NC", Const, 10}, - {"R_ARM_ALU_SBREL_27_20_CK", Const, 10}, - {"R_ARM_ALU_SB_G0", Const, 10}, - {"R_ARM_ALU_SB_G0_NC", Const, 10}, - {"R_ARM_ALU_SB_G1", Const, 10}, - {"R_ARM_ALU_SB_G1_NC", Const, 10}, - {"R_ARM_ALU_SB_G2", Const, 10}, - {"R_ARM_AMP_VCALL9", Const, 0}, - {"R_ARM_BASE_ABS", Const, 10}, - {"R_ARM_CALL", Const, 10}, - {"R_ARM_COPY", Const, 0}, - {"R_ARM_GLOB_DAT", Const, 0}, - {"R_ARM_GNU_VTENTRY", Const, 0}, - {"R_ARM_GNU_VTINHERIT", Const, 0}, - {"R_ARM_GOT32", Const, 0}, - {"R_ARM_GOTOFF", Const, 0}, - {"R_ARM_GOTOFF12", Const, 10}, - {"R_ARM_GOTPC", Const, 0}, - {"R_ARM_GOTRELAX", Const, 10}, - {"R_ARM_GOT_ABS", Const, 10}, - {"R_ARM_GOT_BREL12", Const, 10}, - {"R_ARM_GOT_PREL", Const, 10}, - {"R_ARM_IRELATIVE", Const, 10}, - {"R_ARM_JUMP24", Const, 10}, - {"R_ARM_JUMP_SLOT", Const, 0}, - {"R_ARM_LDC_PC_G0", Const, 10}, - {"R_ARM_LDC_PC_G1", Const, 10}, - {"R_ARM_LDC_PC_G2", Const, 10}, - {"R_ARM_LDC_SB_G0", Const, 10}, - {"R_ARM_LDC_SB_G1", Const, 10}, - {"R_ARM_LDC_SB_G2", Const, 10}, - {"R_ARM_LDRS_PC_G0", Const, 10}, - {"R_ARM_LDRS_PC_G1", Const, 10}, - {"R_ARM_LDRS_PC_G2", Const, 10}, - {"R_ARM_LDRS_SB_G0", Const, 10}, - {"R_ARM_LDRS_SB_G1", Const, 10}, - {"R_ARM_LDRS_SB_G2", Const, 10}, - {"R_ARM_LDR_PC_G1", Const, 10}, - {"R_ARM_LDR_PC_G2", Const, 10}, - {"R_ARM_LDR_SBREL_11_10_NC", Const, 10}, - {"R_ARM_LDR_SB_G0", Const, 10}, - {"R_ARM_LDR_SB_G1", Const, 10}, - {"R_ARM_LDR_SB_G2", Const, 10}, - {"R_ARM_ME_TOO", Const, 10}, - {"R_ARM_MOVT_ABS", Const, 10}, - {"R_ARM_MOVT_BREL", Const, 10}, - {"R_ARM_MOVT_PREL", Const, 10}, - {"R_ARM_MOVW_ABS_NC", Const, 10}, - {"R_ARM_MOVW_BREL", Const, 10}, - {"R_ARM_MOVW_BREL_NC", Const, 10}, - {"R_ARM_MOVW_PREL_NC", Const, 10}, - {"R_ARM_NONE", Const, 0}, - {"R_ARM_PC13", Const, 0}, - {"R_ARM_PC24", Const, 0}, - {"R_ARM_PLT32", Const, 0}, - {"R_ARM_PLT32_ABS", Const, 10}, - {"R_ARM_PREL31", Const, 10}, - {"R_ARM_PRIVATE_0", Const, 10}, - {"R_ARM_PRIVATE_1", Const, 10}, - {"R_ARM_PRIVATE_10", Const, 10}, - {"R_ARM_PRIVATE_11", Const, 10}, - {"R_ARM_PRIVATE_12", Const, 10}, - {"R_ARM_PRIVATE_13", Const, 10}, - {"R_ARM_PRIVATE_14", Const, 10}, - {"R_ARM_PRIVATE_15", Const, 10}, - {"R_ARM_PRIVATE_2", Const, 10}, - {"R_ARM_PRIVATE_3", Const, 10}, - {"R_ARM_PRIVATE_4", Const, 10}, - {"R_ARM_PRIVATE_5", Const, 10}, - {"R_ARM_PRIVATE_6", Const, 10}, - {"R_ARM_PRIVATE_7", Const, 10}, - {"R_ARM_PRIVATE_8", Const, 10}, - {"R_ARM_PRIVATE_9", Const, 10}, - {"R_ARM_RABS32", Const, 0}, - {"R_ARM_RBASE", Const, 0}, - {"R_ARM_REL32", Const, 0}, - {"R_ARM_REL32_NOI", Const, 10}, - {"R_ARM_RELATIVE", Const, 0}, - {"R_ARM_RPC24", Const, 0}, - {"R_ARM_RREL32", Const, 0}, - {"R_ARM_RSBREL32", Const, 0}, - {"R_ARM_RXPC25", Const, 10}, - {"R_ARM_SBREL31", Const, 10}, - {"R_ARM_SBREL32", Const, 0}, - {"R_ARM_SWI24", Const, 0}, - {"R_ARM_TARGET1", Const, 10}, - {"R_ARM_TARGET2", Const, 10}, - {"R_ARM_THM_ABS5", Const, 0}, - {"R_ARM_THM_ALU_ABS_G0_NC", Const, 10}, - {"R_ARM_THM_ALU_ABS_G1_NC", Const, 10}, - {"R_ARM_THM_ALU_ABS_G2_NC", Const, 10}, - {"R_ARM_THM_ALU_ABS_G3", Const, 10}, - {"R_ARM_THM_ALU_PREL_11_0", Const, 10}, - {"R_ARM_THM_GOT_BREL12", Const, 10}, - {"R_ARM_THM_JUMP11", Const, 10}, - {"R_ARM_THM_JUMP19", Const, 10}, - {"R_ARM_THM_JUMP24", Const, 10}, - {"R_ARM_THM_JUMP6", Const, 10}, - {"R_ARM_THM_JUMP8", Const, 10}, - {"R_ARM_THM_MOVT_ABS", Const, 10}, - {"R_ARM_THM_MOVT_BREL", Const, 10}, - {"R_ARM_THM_MOVT_PREL", Const, 10}, - {"R_ARM_THM_MOVW_ABS_NC", Const, 10}, - {"R_ARM_THM_MOVW_BREL", Const, 10}, - {"R_ARM_THM_MOVW_BREL_NC", Const, 10}, - {"R_ARM_THM_MOVW_PREL_NC", Const, 10}, - {"R_ARM_THM_PC12", Const, 10}, - {"R_ARM_THM_PC22", Const, 0}, - {"R_ARM_THM_PC8", Const, 0}, - {"R_ARM_THM_RPC22", Const, 0}, - {"R_ARM_THM_SWI8", Const, 0}, - {"R_ARM_THM_TLS_CALL", Const, 10}, - {"R_ARM_THM_TLS_DESCSEQ16", Const, 10}, - {"R_ARM_THM_TLS_DESCSEQ32", Const, 10}, - {"R_ARM_THM_XPC22", Const, 0}, - {"R_ARM_TLS_CALL", Const, 10}, - {"R_ARM_TLS_DESCSEQ", Const, 10}, - {"R_ARM_TLS_DTPMOD32", Const, 10}, - {"R_ARM_TLS_DTPOFF32", Const, 10}, - {"R_ARM_TLS_GD32", Const, 10}, - {"R_ARM_TLS_GOTDESC", Const, 10}, - {"R_ARM_TLS_IE12GP", Const, 10}, - {"R_ARM_TLS_IE32", Const, 10}, - {"R_ARM_TLS_LDM32", Const, 10}, - {"R_ARM_TLS_LDO12", Const, 10}, - {"R_ARM_TLS_LDO32", Const, 10}, - {"R_ARM_TLS_LE12", Const, 10}, - {"R_ARM_TLS_LE32", Const, 10}, - {"R_ARM_TLS_TPOFF32", Const, 10}, - {"R_ARM_V4BX", Const, 10}, - {"R_ARM_XPC25", Const, 0}, - {"R_INFO", Func, 0}, - {"R_INFO32", Func, 0}, - {"R_LARCH", Type, 19}, - {"R_LARCH_32", Const, 19}, - {"R_LARCH_32_PCREL", Const, 20}, - {"R_LARCH_64", Const, 19}, - {"R_LARCH_64_PCREL", Const, 22}, - {"R_LARCH_ABS64_HI12", Const, 20}, - {"R_LARCH_ABS64_LO20", Const, 20}, - {"R_LARCH_ABS_HI20", Const, 20}, - {"R_LARCH_ABS_LO12", Const, 20}, - {"R_LARCH_ADD16", Const, 19}, - {"R_LARCH_ADD24", Const, 19}, - {"R_LARCH_ADD32", Const, 19}, - {"R_LARCH_ADD6", Const, 22}, - {"R_LARCH_ADD64", Const, 19}, - {"R_LARCH_ADD8", Const, 19}, - {"R_LARCH_ADD_ULEB128", Const, 22}, - {"R_LARCH_ALIGN", Const, 22}, - {"R_LARCH_B16", Const, 20}, - {"R_LARCH_B21", Const, 20}, - {"R_LARCH_B26", Const, 20}, - {"R_LARCH_CFA", Const, 22}, - {"R_LARCH_COPY", Const, 19}, - {"R_LARCH_DELETE", Const, 22}, - {"R_LARCH_GNU_VTENTRY", Const, 20}, - {"R_LARCH_GNU_VTINHERIT", Const, 20}, - {"R_LARCH_GOT64_HI12", Const, 20}, - {"R_LARCH_GOT64_LO20", Const, 20}, - {"R_LARCH_GOT64_PC_HI12", Const, 20}, - {"R_LARCH_GOT64_PC_LO20", Const, 20}, - {"R_LARCH_GOT_HI20", Const, 20}, - {"R_LARCH_GOT_LO12", Const, 20}, - {"R_LARCH_GOT_PC_HI20", Const, 20}, - {"R_LARCH_GOT_PC_LO12", Const, 20}, - {"R_LARCH_IRELATIVE", Const, 19}, - {"R_LARCH_JUMP_SLOT", Const, 19}, - {"R_LARCH_MARK_LA", Const, 19}, - {"R_LARCH_MARK_PCREL", Const, 19}, - {"R_LARCH_NONE", Const, 19}, - {"R_LARCH_PCALA64_HI12", Const, 20}, - {"R_LARCH_PCALA64_LO20", Const, 20}, - {"R_LARCH_PCALA_HI20", Const, 20}, - {"R_LARCH_PCALA_LO12", Const, 20}, - {"R_LARCH_PCREL20_S2", Const, 22}, - {"R_LARCH_RELATIVE", Const, 19}, - {"R_LARCH_RELAX", Const, 20}, - {"R_LARCH_SOP_ADD", Const, 19}, - {"R_LARCH_SOP_AND", Const, 19}, - {"R_LARCH_SOP_ASSERT", Const, 19}, - {"R_LARCH_SOP_IF_ELSE", Const, 19}, - {"R_LARCH_SOP_NOT", Const, 19}, - {"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19}, - {"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19}, - {"R_LARCH_SOP_POP_32_S_10_12", Const, 19}, - {"R_LARCH_SOP_POP_32_S_10_16", Const, 19}, - {"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19}, - {"R_LARCH_SOP_POP_32_S_10_5", Const, 19}, - {"R_LARCH_SOP_POP_32_S_5_20", Const, 19}, - {"R_LARCH_SOP_POP_32_U", Const, 19}, - {"R_LARCH_SOP_POP_32_U_10_12", Const, 19}, - {"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19}, - {"R_LARCH_SOP_PUSH_DUP", Const, 19}, - {"R_LARCH_SOP_PUSH_GPREL", Const, 19}, - {"R_LARCH_SOP_PUSH_PCREL", Const, 19}, - {"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19}, - {"R_LARCH_SOP_PUSH_TLS_GD", Const, 19}, - {"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19}, - {"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19}, - {"R_LARCH_SOP_SL", Const, 19}, - {"R_LARCH_SOP_SR", Const, 19}, - {"R_LARCH_SOP_SUB", Const, 19}, - {"R_LARCH_SUB16", Const, 19}, - {"R_LARCH_SUB24", Const, 19}, - {"R_LARCH_SUB32", Const, 19}, - {"R_LARCH_SUB6", Const, 22}, - {"R_LARCH_SUB64", Const, 19}, - {"R_LARCH_SUB8", Const, 19}, - {"R_LARCH_SUB_ULEB128", Const, 22}, - {"R_LARCH_TLS_DTPMOD32", Const, 19}, - {"R_LARCH_TLS_DTPMOD64", Const, 19}, - {"R_LARCH_TLS_DTPREL32", Const, 19}, - {"R_LARCH_TLS_DTPREL64", Const, 19}, - {"R_LARCH_TLS_GD_HI20", Const, 20}, - {"R_LARCH_TLS_GD_PC_HI20", Const, 20}, - {"R_LARCH_TLS_IE64_HI12", Const, 20}, - {"R_LARCH_TLS_IE64_LO20", Const, 20}, - {"R_LARCH_TLS_IE64_PC_HI12", Const, 20}, - {"R_LARCH_TLS_IE64_PC_LO20", Const, 20}, - {"R_LARCH_TLS_IE_HI20", Const, 20}, - {"R_LARCH_TLS_IE_LO12", Const, 20}, - {"R_LARCH_TLS_IE_PC_HI20", Const, 20}, - {"R_LARCH_TLS_IE_PC_LO12", Const, 20}, - {"R_LARCH_TLS_LD_HI20", Const, 20}, - {"R_LARCH_TLS_LD_PC_HI20", Const, 20}, - {"R_LARCH_TLS_LE64_HI12", Const, 20}, - {"R_LARCH_TLS_LE64_LO20", Const, 20}, - {"R_LARCH_TLS_LE_HI20", Const, 20}, - {"R_LARCH_TLS_LE_LO12", Const, 20}, - {"R_LARCH_TLS_TPREL32", Const, 19}, - {"R_LARCH_TLS_TPREL64", Const, 19}, - {"R_MIPS", Type, 6}, - {"R_MIPS_16", Const, 6}, - {"R_MIPS_26", Const, 6}, - {"R_MIPS_32", Const, 6}, - {"R_MIPS_64", Const, 6}, - {"R_MIPS_ADD_IMMEDIATE", Const, 6}, - {"R_MIPS_CALL16", Const, 6}, - {"R_MIPS_CALL_HI16", Const, 6}, - {"R_MIPS_CALL_LO16", Const, 6}, - {"R_MIPS_DELETE", Const, 6}, - {"R_MIPS_GOT16", Const, 6}, - {"R_MIPS_GOT_DISP", Const, 6}, - {"R_MIPS_GOT_HI16", Const, 6}, - {"R_MIPS_GOT_LO16", Const, 6}, - {"R_MIPS_GOT_OFST", Const, 6}, - {"R_MIPS_GOT_PAGE", Const, 6}, - {"R_MIPS_GPREL16", Const, 6}, - {"R_MIPS_GPREL32", Const, 6}, - {"R_MIPS_HI16", Const, 6}, - {"R_MIPS_HIGHER", Const, 6}, - {"R_MIPS_HIGHEST", Const, 6}, - {"R_MIPS_INSERT_A", Const, 6}, - {"R_MIPS_INSERT_B", Const, 6}, - {"R_MIPS_JALR", Const, 6}, - {"R_MIPS_LITERAL", Const, 6}, - {"R_MIPS_LO16", Const, 6}, - {"R_MIPS_NONE", Const, 6}, - {"R_MIPS_PC16", Const, 6}, - {"R_MIPS_PC32", Const, 22}, - {"R_MIPS_PJUMP", Const, 6}, - {"R_MIPS_REL16", Const, 6}, - {"R_MIPS_REL32", Const, 6}, - {"R_MIPS_RELGOT", Const, 6}, - {"R_MIPS_SCN_DISP", Const, 6}, - {"R_MIPS_SHIFT5", Const, 6}, - {"R_MIPS_SHIFT6", Const, 6}, - {"R_MIPS_SUB", Const, 6}, - {"R_MIPS_TLS_DTPMOD32", Const, 6}, - {"R_MIPS_TLS_DTPMOD64", Const, 6}, - {"R_MIPS_TLS_DTPREL32", Const, 6}, - {"R_MIPS_TLS_DTPREL64", Const, 6}, - {"R_MIPS_TLS_DTPREL_HI16", Const, 6}, - {"R_MIPS_TLS_DTPREL_LO16", Const, 6}, - {"R_MIPS_TLS_GD", Const, 6}, - {"R_MIPS_TLS_GOTTPREL", Const, 6}, - {"R_MIPS_TLS_LDM", Const, 6}, - {"R_MIPS_TLS_TPREL32", Const, 6}, - {"R_MIPS_TLS_TPREL64", Const, 6}, - {"R_MIPS_TLS_TPREL_HI16", Const, 6}, - {"R_MIPS_TLS_TPREL_LO16", Const, 6}, - {"R_PPC", Type, 0}, - {"R_PPC64", Type, 5}, - {"R_PPC64_ADDR14", Const, 5}, - {"R_PPC64_ADDR14_BRNTAKEN", Const, 5}, - {"R_PPC64_ADDR14_BRTAKEN", Const, 5}, - {"R_PPC64_ADDR16", Const, 5}, - {"R_PPC64_ADDR16_DS", Const, 5}, - {"R_PPC64_ADDR16_HA", Const, 5}, - {"R_PPC64_ADDR16_HI", Const, 5}, - {"R_PPC64_ADDR16_HIGH", Const, 10}, - {"R_PPC64_ADDR16_HIGHA", Const, 10}, - {"R_PPC64_ADDR16_HIGHER", Const, 5}, - {"R_PPC64_ADDR16_HIGHER34", Const, 20}, - {"R_PPC64_ADDR16_HIGHERA", Const, 5}, - {"R_PPC64_ADDR16_HIGHERA34", Const, 20}, - {"R_PPC64_ADDR16_HIGHEST", Const, 5}, - {"R_PPC64_ADDR16_HIGHEST34", Const, 20}, - {"R_PPC64_ADDR16_HIGHESTA", Const, 5}, - {"R_PPC64_ADDR16_HIGHESTA34", Const, 20}, - {"R_PPC64_ADDR16_LO", Const, 5}, - {"R_PPC64_ADDR16_LO_DS", Const, 5}, - {"R_PPC64_ADDR24", Const, 5}, - {"R_PPC64_ADDR32", Const, 5}, - {"R_PPC64_ADDR64", Const, 5}, - {"R_PPC64_ADDR64_LOCAL", Const, 10}, - {"R_PPC64_COPY", Const, 20}, - {"R_PPC64_D28", Const, 20}, - {"R_PPC64_D34", Const, 20}, - {"R_PPC64_D34_HA30", Const, 20}, - {"R_PPC64_D34_HI30", Const, 20}, - {"R_PPC64_D34_LO", Const, 20}, - {"R_PPC64_DTPMOD64", Const, 5}, - {"R_PPC64_DTPREL16", Const, 5}, - {"R_PPC64_DTPREL16_DS", Const, 5}, - {"R_PPC64_DTPREL16_HA", Const, 5}, - {"R_PPC64_DTPREL16_HI", Const, 5}, - {"R_PPC64_DTPREL16_HIGH", Const, 10}, - {"R_PPC64_DTPREL16_HIGHA", Const, 10}, - {"R_PPC64_DTPREL16_HIGHER", Const, 5}, - {"R_PPC64_DTPREL16_HIGHERA", Const, 5}, - {"R_PPC64_DTPREL16_HIGHEST", Const, 5}, - {"R_PPC64_DTPREL16_HIGHESTA", Const, 5}, - {"R_PPC64_DTPREL16_LO", Const, 5}, - {"R_PPC64_DTPREL16_LO_DS", Const, 5}, - {"R_PPC64_DTPREL34", Const, 20}, - {"R_PPC64_DTPREL64", Const, 5}, - {"R_PPC64_ENTRY", Const, 10}, - {"R_PPC64_GLOB_DAT", Const, 20}, - {"R_PPC64_GNU_VTENTRY", Const, 20}, - {"R_PPC64_GNU_VTINHERIT", Const, 20}, - {"R_PPC64_GOT16", Const, 5}, - {"R_PPC64_GOT16_DS", Const, 5}, - {"R_PPC64_GOT16_HA", Const, 5}, - {"R_PPC64_GOT16_HI", Const, 5}, - {"R_PPC64_GOT16_LO", Const, 5}, - {"R_PPC64_GOT16_LO_DS", Const, 5}, - {"R_PPC64_GOT_DTPREL16_DS", Const, 5}, - {"R_PPC64_GOT_DTPREL16_HA", Const, 5}, - {"R_PPC64_GOT_DTPREL16_HI", Const, 5}, - {"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5}, - {"R_PPC64_GOT_DTPREL_PCREL34", Const, 20}, - {"R_PPC64_GOT_PCREL34", Const, 20}, - {"R_PPC64_GOT_TLSGD16", Const, 5}, - {"R_PPC64_GOT_TLSGD16_HA", Const, 5}, - {"R_PPC64_GOT_TLSGD16_HI", Const, 5}, - {"R_PPC64_GOT_TLSGD16_LO", Const, 5}, - {"R_PPC64_GOT_TLSGD_PCREL34", Const, 20}, - {"R_PPC64_GOT_TLSLD16", Const, 5}, - {"R_PPC64_GOT_TLSLD16_HA", Const, 5}, - {"R_PPC64_GOT_TLSLD16_HI", Const, 5}, - {"R_PPC64_GOT_TLSLD16_LO", Const, 5}, - {"R_PPC64_GOT_TLSLD_PCREL34", Const, 20}, - {"R_PPC64_GOT_TPREL16_DS", Const, 5}, - {"R_PPC64_GOT_TPREL16_HA", Const, 5}, - {"R_PPC64_GOT_TPREL16_HI", Const, 5}, - {"R_PPC64_GOT_TPREL16_LO_DS", Const, 5}, - {"R_PPC64_GOT_TPREL_PCREL34", Const, 20}, - {"R_PPC64_IRELATIVE", Const, 10}, - {"R_PPC64_JMP_IREL", Const, 10}, - {"R_PPC64_JMP_SLOT", Const, 5}, - {"R_PPC64_NONE", Const, 5}, - {"R_PPC64_PCREL28", Const, 20}, - {"R_PPC64_PCREL34", Const, 20}, - {"R_PPC64_PCREL_OPT", Const, 20}, - {"R_PPC64_PLT16_HA", Const, 20}, - {"R_PPC64_PLT16_HI", Const, 20}, - {"R_PPC64_PLT16_LO", Const, 20}, - {"R_PPC64_PLT16_LO_DS", Const, 10}, - {"R_PPC64_PLT32", Const, 20}, - {"R_PPC64_PLT64", Const, 20}, - {"R_PPC64_PLTCALL", Const, 20}, - {"R_PPC64_PLTCALL_NOTOC", Const, 20}, - {"R_PPC64_PLTGOT16", Const, 10}, - {"R_PPC64_PLTGOT16_DS", Const, 10}, - {"R_PPC64_PLTGOT16_HA", Const, 10}, - {"R_PPC64_PLTGOT16_HI", Const, 10}, - {"R_PPC64_PLTGOT16_LO", Const, 10}, - {"R_PPC64_PLTGOT_LO_DS", Const, 10}, - {"R_PPC64_PLTREL32", Const, 20}, - {"R_PPC64_PLTREL64", Const, 20}, - {"R_PPC64_PLTSEQ", Const, 20}, - {"R_PPC64_PLTSEQ_NOTOC", Const, 20}, - {"R_PPC64_PLT_PCREL34", Const, 20}, - {"R_PPC64_PLT_PCREL34_NOTOC", Const, 20}, - {"R_PPC64_REL14", Const, 5}, - {"R_PPC64_REL14_BRNTAKEN", Const, 5}, - {"R_PPC64_REL14_BRTAKEN", Const, 5}, - {"R_PPC64_REL16", Const, 5}, - {"R_PPC64_REL16DX_HA", Const, 10}, - {"R_PPC64_REL16_HA", Const, 5}, - {"R_PPC64_REL16_HI", Const, 5}, - {"R_PPC64_REL16_HIGH", Const, 20}, - {"R_PPC64_REL16_HIGHA", Const, 20}, - {"R_PPC64_REL16_HIGHER", Const, 20}, - {"R_PPC64_REL16_HIGHER34", Const, 20}, - {"R_PPC64_REL16_HIGHERA", Const, 20}, - {"R_PPC64_REL16_HIGHERA34", Const, 20}, - {"R_PPC64_REL16_HIGHEST", Const, 20}, - {"R_PPC64_REL16_HIGHEST34", Const, 20}, - {"R_PPC64_REL16_HIGHESTA", Const, 20}, - {"R_PPC64_REL16_HIGHESTA34", Const, 20}, - {"R_PPC64_REL16_LO", Const, 5}, - {"R_PPC64_REL24", Const, 5}, - {"R_PPC64_REL24_NOTOC", Const, 10}, - {"R_PPC64_REL24_P9NOTOC", Const, 21}, - {"R_PPC64_REL30", Const, 20}, - {"R_PPC64_REL32", Const, 5}, - {"R_PPC64_REL64", Const, 5}, - {"R_PPC64_RELATIVE", Const, 18}, - {"R_PPC64_SECTOFF", Const, 20}, - {"R_PPC64_SECTOFF_DS", Const, 10}, - {"R_PPC64_SECTOFF_HA", Const, 20}, - {"R_PPC64_SECTOFF_HI", Const, 20}, - {"R_PPC64_SECTOFF_LO", Const, 20}, - {"R_PPC64_SECTOFF_LO_DS", Const, 10}, - {"R_PPC64_TLS", Const, 5}, - {"R_PPC64_TLSGD", Const, 5}, - {"R_PPC64_TLSLD", Const, 5}, - {"R_PPC64_TOC", Const, 5}, - {"R_PPC64_TOC16", Const, 5}, - {"R_PPC64_TOC16_DS", Const, 5}, - {"R_PPC64_TOC16_HA", Const, 5}, - {"R_PPC64_TOC16_HI", Const, 5}, - {"R_PPC64_TOC16_LO", Const, 5}, - {"R_PPC64_TOC16_LO_DS", Const, 5}, - {"R_PPC64_TOCSAVE", Const, 10}, - {"R_PPC64_TPREL16", Const, 5}, - {"R_PPC64_TPREL16_DS", Const, 5}, - {"R_PPC64_TPREL16_HA", Const, 5}, - {"R_PPC64_TPREL16_HI", Const, 5}, - {"R_PPC64_TPREL16_HIGH", Const, 10}, - {"R_PPC64_TPREL16_HIGHA", Const, 10}, - {"R_PPC64_TPREL16_HIGHER", Const, 5}, - {"R_PPC64_TPREL16_HIGHERA", Const, 5}, - {"R_PPC64_TPREL16_HIGHEST", Const, 5}, - {"R_PPC64_TPREL16_HIGHESTA", Const, 5}, - {"R_PPC64_TPREL16_LO", Const, 5}, - {"R_PPC64_TPREL16_LO_DS", Const, 5}, - {"R_PPC64_TPREL34", Const, 20}, - {"R_PPC64_TPREL64", Const, 5}, - {"R_PPC64_UADDR16", Const, 20}, - {"R_PPC64_UADDR32", Const, 20}, - {"R_PPC64_UADDR64", Const, 20}, - {"R_PPC_ADDR14", Const, 0}, - {"R_PPC_ADDR14_BRNTAKEN", Const, 0}, - {"R_PPC_ADDR14_BRTAKEN", Const, 0}, - {"R_PPC_ADDR16", Const, 0}, - {"R_PPC_ADDR16_HA", Const, 0}, - {"R_PPC_ADDR16_HI", Const, 0}, - {"R_PPC_ADDR16_LO", Const, 0}, - {"R_PPC_ADDR24", Const, 0}, - {"R_PPC_ADDR32", Const, 0}, - {"R_PPC_COPY", Const, 0}, - {"R_PPC_DTPMOD32", Const, 0}, - {"R_PPC_DTPREL16", Const, 0}, - {"R_PPC_DTPREL16_HA", Const, 0}, - {"R_PPC_DTPREL16_HI", Const, 0}, - {"R_PPC_DTPREL16_LO", Const, 0}, - {"R_PPC_DTPREL32", Const, 0}, - {"R_PPC_EMB_BIT_FLD", Const, 0}, - {"R_PPC_EMB_MRKREF", Const, 0}, - {"R_PPC_EMB_NADDR16", Const, 0}, - {"R_PPC_EMB_NADDR16_HA", Const, 0}, - {"R_PPC_EMB_NADDR16_HI", Const, 0}, - {"R_PPC_EMB_NADDR16_LO", Const, 0}, - {"R_PPC_EMB_NADDR32", Const, 0}, - {"R_PPC_EMB_RELSDA", Const, 0}, - {"R_PPC_EMB_RELSEC16", Const, 0}, - {"R_PPC_EMB_RELST_HA", Const, 0}, - {"R_PPC_EMB_RELST_HI", Const, 0}, - {"R_PPC_EMB_RELST_LO", Const, 0}, - {"R_PPC_EMB_SDA21", Const, 0}, - {"R_PPC_EMB_SDA2I16", Const, 0}, - {"R_PPC_EMB_SDA2REL", Const, 0}, - {"R_PPC_EMB_SDAI16", Const, 0}, - {"R_PPC_GLOB_DAT", Const, 0}, - {"R_PPC_GOT16", Const, 0}, - {"R_PPC_GOT16_HA", Const, 0}, - {"R_PPC_GOT16_HI", Const, 0}, - {"R_PPC_GOT16_LO", Const, 0}, - {"R_PPC_GOT_TLSGD16", Const, 0}, - {"R_PPC_GOT_TLSGD16_HA", Const, 0}, - {"R_PPC_GOT_TLSGD16_HI", Const, 0}, - {"R_PPC_GOT_TLSGD16_LO", Const, 0}, - {"R_PPC_GOT_TLSLD16", Const, 0}, - {"R_PPC_GOT_TLSLD16_HA", Const, 0}, - {"R_PPC_GOT_TLSLD16_HI", Const, 0}, - {"R_PPC_GOT_TLSLD16_LO", Const, 0}, - {"R_PPC_GOT_TPREL16", Const, 0}, - {"R_PPC_GOT_TPREL16_HA", Const, 0}, - {"R_PPC_GOT_TPREL16_HI", Const, 0}, - {"R_PPC_GOT_TPREL16_LO", Const, 0}, - {"R_PPC_JMP_SLOT", Const, 0}, - {"R_PPC_LOCAL24PC", Const, 0}, - {"R_PPC_NONE", Const, 0}, - {"R_PPC_PLT16_HA", Const, 0}, - {"R_PPC_PLT16_HI", Const, 0}, - {"R_PPC_PLT16_LO", Const, 0}, - {"R_PPC_PLT32", Const, 0}, - {"R_PPC_PLTREL24", Const, 0}, - {"R_PPC_PLTREL32", Const, 0}, - {"R_PPC_REL14", Const, 0}, - {"R_PPC_REL14_BRNTAKEN", Const, 0}, - {"R_PPC_REL14_BRTAKEN", Const, 0}, - {"R_PPC_REL24", Const, 0}, - {"R_PPC_REL32", Const, 0}, - {"R_PPC_RELATIVE", Const, 0}, - {"R_PPC_SDAREL16", Const, 0}, - {"R_PPC_SECTOFF", Const, 0}, - {"R_PPC_SECTOFF_HA", Const, 0}, - {"R_PPC_SECTOFF_HI", Const, 0}, - {"R_PPC_SECTOFF_LO", Const, 0}, - {"R_PPC_TLS", Const, 0}, - {"R_PPC_TPREL16", Const, 0}, - {"R_PPC_TPREL16_HA", Const, 0}, - {"R_PPC_TPREL16_HI", Const, 0}, - {"R_PPC_TPREL16_LO", Const, 0}, - {"R_PPC_TPREL32", Const, 0}, - {"R_PPC_UADDR16", Const, 0}, - {"R_PPC_UADDR32", Const, 0}, - {"R_RISCV", Type, 11}, - {"R_RISCV_32", Const, 11}, - {"R_RISCV_32_PCREL", Const, 12}, - {"R_RISCV_64", Const, 11}, - {"R_RISCV_ADD16", Const, 11}, - {"R_RISCV_ADD32", Const, 11}, - {"R_RISCV_ADD64", Const, 11}, - {"R_RISCV_ADD8", Const, 11}, - {"R_RISCV_ALIGN", Const, 11}, - {"R_RISCV_BRANCH", Const, 11}, - {"R_RISCV_CALL", Const, 11}, - {"R_RISCV_CALL_PLT", Const, 11}, - {"R_RISCV_COPY", Const, 11}, - {"R_RISCV_GNU_VTENTRY", Const, 11}, - {"R_RISCV_GNU_VTINHERIT", Const, 11}, - {"R_RISCV_GOT_HI20", Const, 11}, - {"R_RISCV_GPREL_I", Const, 11}, - {"R_RISCV_GPREL_S", Const, 11}, - {"R_RISCV_HI20", Const, 11}, - {"R_RISCV_JAL", Const, 11}, - {"R_RISCV_JUMP_SLOT", Const, 11}, - {"R_RISCV_LO12_I", Const, 11}, - {"R_RISCV_LO12_S", Const, 11}, - {"R_RISCV_NONE", Const, 11}, - {"R_RISCV_PCREL_HI20", Const, 11}, - {"R_RISCV_PCREL_LO12_I", Const, 11}, - {"R_RISCV_PCREL_LO12_S", Const, 11}, - {"R_RISCV_RELATIVE", Const, 11}, - {"R_RISCV_RELAX", Const, 11}, - {"R_RISCV_RVC_BRANCH", Const, 11}, - {"R_RISCV_RVC_JUMP", Const, 11}, - {"R_RISCV_RVC_LUI", Const, 11}, - {"R_RISCV_SET16", Const, 11}, - {"R_RISCV_SET32", Const, 11}, - {"R_RISCV_SET6", Const, 11}, - {"R_RISCV_SET8", Const, 11}, - {"R_RISCV_SUB16", Const, 11}, - {"R_RISCV_SUB32", Const, 11}, - {"R_RISCV_SUB6", Const, 11}, - {"R_RISCV_SUB64", Const, 11}, - {"R_RISCV_SUB8", Const, 11}, - {"R_RISCV_TLS_DTPMOD32", Const, 11}, - {"R_RISCV_TLS_DTPMOD64", Const, 11}, - {"R_RISCV_TLS_DTPREL32", Const, 11}, - {"R_RISCV_TLS_DTPREL64", Const, 11}, - {"R_RISCV_TLS_GD_HI20", Const, 11}, - {"R_RISCV_TLS_GOT_HI20", Const, 11}, - {"R_RISCV_TLS_TPREL32", Const, 11}, - {"R_RISCV_TLS_TPREL64", Const, 11}, - {"R_RISCV_TPREL_ADD", Const, 11}, - {"R_RISCV_TPREL_HI20", Const, 11}, - {"R_RISCV_TPREL_I", Const, 11}, - {"R_RISCV_TPREL_LO12_I", Const, 11}, - {"R_RISCV_TPREL_LO12_S", Const, 11}, - {"R_RISCV_TPREL_S", Const, 11}, - {"R_SPARC", Type, 0}, - {"R_SPARC_10", Const, 0}, - {"R_SPARC_11", Const, 0}, - {"R_SPARC_13", Const, 0}, - {"R_SPARC_16", Const, 0}, - {"R_SPARC_22", Const, 0}, - {"R_SPARC_32", Const, 0}, - {"R_SPARC_5", Const, 0}, - {"R_SPARC_6", Const, 0}, - {"R_SPARC_64", Const, 0}, - {"R_SPARC_7", Const, 0}, - {"R_SPARC_8", Const, 0}, - {"R_SPARC_COPY", Const, 0}, - {"R_SPARC_DISP16", Const, 0}, - {"R_SPARC_DISP32", Const, 0}, - {"R_SPARC_DISP64", Const, 0}, - {"R_SPARC_DISP8", Const, 0}, - {"R_SPARC_GLOB_DAT", Const, 0}, - {"R_SPARC_GLOB_JMP", Const, 0}, - {"R_SPARC_GOT10", Const, 0}, - {"R_SPARC_GOT13", Const, 0}, - {"R_SPARC_GOT22", Const, 0}, - {"R_SPARC_H44", Const, 0}, - {"R_SPARC_HH22", Const, 0}, - {"R_SPARC_HI22", Const, 0}, - {"R_SPARC_HIPLT22", Const, 0}, - {"R_SPARC_HIX22", Const, 0}, - {"R_SPARC_HM10", Const, 0}, - {"R_SPARC_JMP_SLOT", Const, 0}, - {"R_SPARC_L44", Const, 0}, - {"R_SPARC_LM22", Const, 0}, - {"R_SPARC_LO10", Const, 0}, - {"R_SPARC_LOPLT10", Const, 0}, - {"R_SPARC_LOX10", Const, 0}, - {"R_SPARC_M44", Const, 0}, - {"R_SPARC_NONE", Const, 0}, - {"R_SPARC_OLO10", Const, 0}, - {"R_SPARC_PC10", Const, 0}, - {"R_SPARC_PC22", Const, 0}, - {"R_SPARC_PCPLT10", Const, 0}, - {"R_SPARC_PCPLT22", Const, 0}, - {"R_SPARC_PCPLT32", Const, 0}, - {"R_SPARC_PC_HH22", Const, 0}, - {"R_SPARC_PC_HM10", Const, 0}, - {"R_SPARC_PC_LM22", Const, 0}, - {"R_SPARC_PLT32", Const, 0}, - {"R_SPARC_PLT64", Const, 0}, - {"R_SPARC_REGISTER", Const, 0}, - {"R_SPARC_RELATIVE", Const, 0}, - {"R_SPARC_UA16", Const, 0}, - {"R_SPARC_UA32", Const, 0}, - {"R_SPARC_UA64", Const, 0}, - {"R_SPARC_WDISP16", Const, 0}, - {"R_SPARC_WDISP19", Const, 0}, - {"R_SPARC_WDISP22", Const, 0}, - {"R_SPARC_WDISP30", Const, 0}, - {"R_SPARC_WPLT30", Const, 0}, - {"R_SYM32", Func, 0}, - {"R_SYM64", Func, 0}, - {"R_TYPE32", Func, 0}, - {"R_TYPE64", Func, 0}, - {"R_X86_64", Type, 0}, - {"R_X86_64_16", Const, 0}, - {"R_X86_64_32", Const, 0}, - {"R_X86_64_32S", Const, 0}, - {"R_X86_64_64", Const, 0}, - {"R_X86_64_8", Const, 0}, - {"R_X86_64_COPY", Const, 0}, - {"R_X86_64_DTPMOD64", Const, 0}, - {"R_X86_64_DTPOFF32", Const, 0}, - {"R_X86_64_DTPOFF64", Const, 0}, - {"R_X86_64_GLOB_DAT", Const, 0}, - {"R_X86_64_GOT32", Const, 0}, - {"R_X86_64_GOT64", Const, 10}, - {"R_X86_64_GOTOFF64", Const, 10}, - {"R_X86_64_GOTPC32", Const, 10}, - {"R_X86_64_GOTPC32_TLSDESC", Const, 10}, - {"R_X86_64_GOTPC64", Const, 10}, - {"R_X86_64_GOTPCREL", Const, 0}, - {"R_X86_64_GOTPCREL64", Const, 10}, - {"R_X86_64_GOTPCRELX", Const, 10}, - {"R_X86_64_GOTPLT64", Const, 10}, - {"R_X86_64_GOTTPOFF", Const, 0}, - {"R_X86_64_IRELATIVE", Const, 10}, - {"R_X86_64_JMP_SLOT", Const, 0}, - {"R_X86_64_NONE", Const, 0}, - {"R_X86_64_PC16", Const, 0}, - {"R_X86_64_PC32", Const, 0}, - {"R_X86_64_PC32_BND", Const, 10}, - {"R_X86_64_PC64", Const, 10}, - {"R_X86_64_PC8", Const, 0}, - {"R_X86_64_PLT32", Const, 0}, - {"R_X86_64_PLT32_BND", Const, 10}, - {"R_X86_64_PLTOFF64", Const, 10}, - {"R_X86_64_RELATIVE", Const, 0}, - {"R_X86_64_RELATIVE64", Const, 10}, - {"R_X86_64_REX_GOTPCRELX", Const, 10}, - {"R_X86_64_SIZE32", Const, 10}, - {"R_X86_64_SIZE64", Const, 10}, - {"R_X86_64_TLSDESC", Const, 10}, - {"R_X86_64_TLSDESC_CALL", Const, 10}, - {"R_X86_64_TLSGD", Const, 0}, - {"R_X86_64_TLSLD", Const, 0}, - {"R_X86_64_TPOFF32", Const, 0}, - {"R_X86_64_TPOFF64", Const, 0}, - {"Rel32", Type, 0}, - {"Rel32.Info", Field, 0}, - {"Rel32.Off", Field, 0}, - {"Rel64", Type, 0}, - {"Rel64.Info", Field, 0}, - {"Rel64.Off", Field, 0}, - {"Rela32", Type, 0}, - {"Rela32.Addend", Field, 0}, - {"Rela32.Info", Field, 0}, - {"Rela32.Off", Field, 0}, - {"Rela64", Type, 0}, - {"Rela64.Addend", Field, 0}, - {"Rela64.Info", Field, 0}, - {"Rela64.Off", Field, 0}, - {"SHF_ALLOC", Const, 0}, - {"SHF_COMPRESSED", Const, 6}, - {"SHF_EXECINSTR", Const, 0}, - {"SHF_GROUP", Const, 0}, - {"SHF_INFO_LINK", Const, 0}, - {"SHF_LINK_ORDER", Const, 0}, - {"SHF_MASKOS", Const, 0}, - {"SHF_MASKPROC", Const, 0}, - {"SHF_MERGE", Const, 0}, - {"SHF_OS_NONCONFORMING", Const, 0}, - {"SHF_STRINGS", Const, 0}, - {"SHF_TLS", Const, 0}, - {"SHF_WRITE", Const, 0}, - {"SHN_ABS", Const, 0}, - {"SHN_COMMON", Const, 0}, - {"SHN_HIOS", Const, 0}, - {"SHN_HIPROC", Const, 0}, - {"SHN_HIRESERVE", Const, 0}, - {"SHN_LOOS", Const, 0}, - {"SHN_LOPROC", Const, 0}, - {"SHN_LORESERVE", Const, 0}, - {"SHN_UNDEF", Const, 0}, - {"SHN_XINDEX", Const, 0}, - {"SHT_DYNAMIC", Const, 0}, - {"SHT_DYNSYM", Const, 0}, - {"SHT_FINI_ARRAY", Const, 0}, - {"SHT_GNU_ATTRIBUTES", Const, 0}, - {"SHT_GNU_HASH", Const, 0}, - {"SHT_GNU_LIBLIST", Const, 0}, - {"SHT_GNU_VERDEF", Const, 0}, - {"SHT_GNU_VERNEED", Const, 0}, - {"SHT_GNU_VERSYM", Const, 0}, - {"SHT_GROUP", Const, 0}, - {"SHT_HASH", Const, 0}, - {"SHT_HIOS", Const, 0}, - {"SHT_HIPROC", Const, 0}, - {"SHT_HIUSER", Const, 0}, - {"SHT_INIT_ARRAY", Const, 0}, - {"SHT_LOOS", Const, 0}, - {"SHT_LOPROC", Const, 0}, - {"SHT_LOUSER", Const, 0}, - {"SHT_MIPS_ABIFLAGS", Const, 17}, - {"SHT_NOBITS", Const, 0}, - {"SHT_NOTE", Const, 0}, - {"SHT_NULL", Const, 0}, - {"SHT_PREINIT_ARRAY", Const, 0}, - {"SHT_PROGBITS", Const, 0}, - {"SHT_REL", Const, 0}, - {"SHT_RELA", Const, 0}, - {"SHT_SHLIB", Const, 0}, - {"SHT_STRTAB", Const, 0}, - {"SHT_SYMTAB", Const, 0}, - {"SHT_SYMTAB_SHNDX", Const, 0}, - {"STB_GLOBAL", Const, 0}, - {"STB_HIOS", Const, 0}, - {"STB_HIPROC", Const, 0}, - {"STB_LOCAL", Const, 0}, - {"STB_LOOS", Const, 0}, - {"STB_LOPROC", Const, 0}, - {"STB_WEAK", Const, 0}, - {"STT_COMMON", Const, 0}, - {"STT_FILE", Const, 0}, - {"STT_FUNC", Const, 0}, - {"STT_GNU_IFUNC", Const, 23}, - {"STT_HIOS", Const, 0}, - {"STT_HIPROC", Const, 0}, - {"STT_LOOS", Const, 0}, - {"STT_LOPROC", Const, 0}, - {"STT_NOTYPE", Const, 0}, - {"STT_OBJECT", Const, 0}, - {"STT_RELC", Const, 23}, - {"STT_SECTION", Const, 0}, - {"STT_SRELC", Const, 23}, - {"STT_TLS", Const, 0}, - {"STV_DEFAULT", Const, 0}, - {"STV_HIDDEN", Const, 0}, - {"STV_INTERNAL", Const, 0}, - {"STV_PROTECTED", Const, 0}, - {"ST_BIND", Func, 0}, - {"ST_INFO", Func, 0}, - {"ST_TYPE", Func, 0}, - {"ST_VISIBILITY", Func, 0}, - {"Section", Type, 0}, - {"Section.ReaderAt", Field, 0}, - {"Section.SectionHeader", Field, 0}, - {"Section32", Type, 0}, - {"Section32.Addr", Field, 0}, - {"Section32.Addralign", Field, 0}, - {"Section32.Entsize", Field, 0}, - {"Section32.Flags", Field, 0}, - {"Section32.Info", Field, 0}, - {"Section32.Link", Field, 0}, - {"Section32.Name", Field, 0}, - {"Section32.Off", Field, 0}, - {"Section32.Size", Field, 0}, - {"Section32.Type", Field, 0}, - {"Section64", Type, 0}, - {"Section64.Addr", Field, 0}, - {"Section64.Addralign", Field, 0}, - {"Section64.Entsize", Field, 0}, - {"Section64.Flags", Field, 0}, - {"Section64.Info", Field, 0}, - {"Section64.Link", Field, 0}, - {"Section64.Name", Field, 0}, - {"Section64.Off", Field, 0}, - {"Section64.Size", Field, 0}, - {"Section64.Type", Field, 0}, - {"SectionFlag", Type, 0}, - {"SectionHeader", Type, 0}, - {"SectionHeader.Addr", Field, 0}, - {"SectionHeader.Addralign", Field, 0}, - {"SectionHeader.Entsize", Field, 0}, - {"SectionHeader.FileSize", Field, 6}, - {"SectionHeader.Flags", Field, 0}, - {"SectionHeader.Info", Field, 0}, - {"SectionHeader.Link", Field, 0}, - {"SectionHeader.Name", Field, 0}, - {"SectionHeader.Offset", Field, 0}, - {"SectionHeader.Size", Field, 0}, - {"SectionHeader.Type", Field, 0}, - {"SectionIndex", Type, 0}, - {"SectionType", Type, 0}, - {"Sym32", Type, 0}, - {"Sym32.Info", Field, 0}, - {"Sym32.Name", Field, 0}, - {"Sym32.Other", Field, 0}, - {"Sym32.Shndx", Field, 0}, - {"Sym32.Size", Field, 0}, - {"Sym32.Value", Field, 0}, - {"Sym32Size", Const, 0}, - {"Sym64", Type, 0}, - {"Sym64.Info", Field, 0}, - {"Sym64.Name", Field, 0}, - {"Sym64.Other", Field, 0}, - {"Sym64.Shndx", Field, 0}, - {"Sym64.Size", Field, 0}, - {"Sym64.Value", Field, 0}, - {"Sym64Size", Const, 0}, - {"SymBind", Type, 0}, - {"SymType", Type, 0}, - {"SymVis", Type, 0}, - {"Symbol", Type, 0}, - {"Symbol.Info", Field, 0}, - {"Symbol.Library", Field, 13}, - {"Symbol.Name", Field, 0}, - {"Symbol.Other", Field, 0}, - {"Symbol.Section", Field, 0}, - {"Symbol.Size", Field, 0}, - {"Symbol.Value", Field, 0}, - {"Symbol.Version", Field, 13}, - {"Symbol.VersionIndex", Field, 24}, - {"Symbol.VersionScope", Field, 24}, - {"SymbolVersionScope", Type, 24}, - {"Type", Type, 0}, - {"VER_FLG_BASE", Const, 24}, - {"VER_FLG_INFO", Const, 24}, - {"VER_FLG_WEAK", Const, 24}, - {"Version", Type, 0}, - {"VersionScopeGlobal", Const, 24}, - {"VersionScopeHidden", Const, 24}, - {"VersionScopeLocal", Const, 24}, - {"VersionScopeNone", Const, 24}, - {"VersionScopeSpecific", Const, 24}, - }, - "debug/gosym": { - {"(*DecodingError).Error", Method, 0}, - {"(*LineTable).LineToPC", Method, 0}, - {"(*LineTable).PCToLine", Method, 0}, - {"(*Sym).BaseName", Method, 0}, - {"(*Sym).PackageName", Method, 0}, - {"(*Sym).ReceiverName", Method, 0}, - {"(*Sym).Static", Method, 0}, - {"(*Table).LineToPC", Method, 0}, - {"(*Table).LookupFunc", Method, 0}, - {"(*Table).LookupSym", Method, 0}, - {"(*Table).PCToFunc", Method, 0}, - {"(*Table).PCToLine", Method, 0}, - {"(*Table).SymByAddr", Method, 0}, - {"(*UnknownLineError).Error", Method, 0}, - {"(Func).BaseName", Method, 0}, - {"(Func).PackageName", Method, 0}, - {"(Func).ReceiverName", Method, 0}, - {"(Func).Static", Method, 0}, - {"(UnknownFileError).Error", Method, 0}, - {"DecodingError", Type, 0}, - {"Func", Type, 0}, - {"Func.End", Field, 0}, - {"Func.Entry", Field, 0}, - {"Func.FrameSize", Field, 0}, - {"Func.LineTable", Field, 0}, - {"Func.Locals", Field, 0}, - {"Func.Obj", Field, 0}, - {"Func.Params", Field, 0}, - {"Func.Sym", Field, 0}, - {"LineTable", Type, 0}, - {"LineTable.Data", Field, 0}, - {"LineTable.Line", Field, 0}, - {"LineTable.PC", Field, 0}, - {"NewLineTable", Func, 0}, - {"NewTable", Func, 0}, - {"Obj", Type, 0}, - {"Obj.Funcs", Field, 0}, - {"Obj.Paths", Field, 0}, - {"Sym", Type, 0}, - {"Sym.Func", Field, 0}, - {"Sym.GoType", Field, 0}, - {"Sym.Name", Field, 0}, - {"Sym.Type", Field, 0}, - {"Sym.Value", Field, 0}, - {"Table", Type, 0}, - {"Table.Files", Field, 0}, - {"Table.Funcs", Field, 0}, - {"Table.Objs", Field, 0}, - {"Table.Syms", Field, 0}, - {"UnknownFileError", Type, 0}, - {"UnknownLineError", Type, 0}, - {"UnknownLineError.File", Field, 0}, - {"UnknownLineError.Line", Field, 0}, - }, - "debug/macho": { - {"(*FatFile).Close", Method, 3}, - {"(*File).Close", Method, 0}, - {"(*File).DWARF", Method, 0}, - {"(*File).ImportedLibraries", Method, 0}, - {"(*File).ImportedSymbols", Method, 0}, - {"(*File).Section", Method, 0}, - {"(*File).Segment", Method, 0}, - {"(*FormatError).Error", Method, 0}, - {"(*Section).Data", Method, 0}, - {"(*Section).Open", Method, 0}, - {"(*Segment).Data", Method, 0}, - {"(*Segment).Open", Method, 0}, - {"(Cpu).GoString", Method, 0}, - {"(Cpu).String", Method, 0}, - {"(Dylib).Raw", Method, 0}, - {"(Dysymtab).Raw", Method, 0}, - {"(FatArch).Close", Method, 3}, - {"(FatArch).DWARF", Method, 3}, - {"(FatArch).ImportedLibraries", Method, 3}, - {"(FatArch).ImportedSymbols", Method, 3}, - {"(FatArch).Section", Method, 3}, - {"(FatArch).Segment", Method, 3}, - {"(LoadBytes).Raw", Method, 0}, - {"(LoadCmd).GoString", Method, 0}, - {"(LoadCmd).String", Method, 0}, - {"(RelocTypeARM).GoString", Method, 10}, - {"(RelocTypeARM).String", Method, 10}, - {"(RelocTypeARM64).GoString", Method, 10}, - {"(RelocTypeARM64).String", Method, 10}, - {"(RelocTypeGeneric).GoString", Method, 10}, - {"(RelocTypeGeneric).String", Method, 10}, - {"(RelocTypeX86_64).GoString", Method, 10}, - {"(RelocTypeX86_64).String", Method, 10}, - {"(Rpath).Raw", Method, 10}, - {"(Section).ReadAt", Method, 0}, - {"(Segment).Raw", Method, 0}, - {"(Segment).ReadAt", Method, 0}, - {"(Symtab).Raw", Method, 0}, - {"(Type).GoString", Method, 10}, - {"(Type).String", Method, 10}, - {"ARM64_RELOC_ADDEND", Const, 10}, - {"ARM64_RELOC_BRANCH26", Const, 10}, - {"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10}, - {"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10}, - {"ARM64_RELOC_PAGE21", Const, 10}, - {"ARM64_RELOC_PAGEOFF12", Const, 10}, - {"ARM64_RELOC_POINTER_TO_GOT", Const, 10}, - {"ARM64_RELOC_SUBTRACTOR", Const, 10}, - {"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10}, - {"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10}, - {"ARM64_RELOC_UNSIGNED", Const, 10}, - {"ARM_RELOC_BR24", Const, 10}, - {"ARM_RELOC_HALF", Const, 10}, - {"ARM_RELOC_HALF_SECTDIFF", Const, 10}, - {"ARM_RELOC_LOCAL_SECTDIFF", Const, 10}, - {"ARM_RELOC_PAIR", Const, 10}, - {"ARM_RELOC_PB_LA_PTR", Const, 10}, - {"ARM_RELOC_SECTDIFF", Const, 10}, - {"ARM_RELOC_VANILLA", Const, 10}, - {"ARM_THUMB_32BIT_BRANCH", Const, 10}, - {"ARM_THUMB_RELOC_BR22", Const, 10}, - {"Cpu", Type, 0}, - {"Cpu386", Const, 0}, - {"CpuAmd64", Const, 0}, - {"CpuArm", Const, 3}, - {"CpuArm64", Const, 11}, - {"CpuPpc", Const, 3}, - {"CpuPpc64", Const, 3}, - {"Dylib", Type, 0}, - {"Dylib.CompatVersion", Field, 0}, - {"Dylib.CurrentVersion", Field, 0}, - {"Dylib.LoadBytes", Field, 0}, - {"Dylib.Name", Field, 0}, - {"Dylib.Time", Field, 0}, - {"DylibCmd", Type, 0}, - {"DylibCmd.Cmd", Field, 0}, - {"DylibCmd.CompatVersion", Field, 0}, - {"DylibCmd.CurrentVersion", Field, 0}, - {"DylibCmd.Len", Field, 0}, - {"DylibCmd.Name", Field, 0}, - {"DylibCmd.Time", Field, 0}, - {"Dysymtab", Type, 0}, - {"Dysymtab.DysymtabCmd", Field, 0}, - {"Dysymtab.IndirectSyms", Field, 0}, - {"Dysymtab.LoadBytes", Field, 0}, - {"DysymtabCmd", Type, 0}, - {"DysymtabCmd.Cmd", Field, 0}, - {"DysymtabCmd.Extrefsymoff", Field, 0}, - {"DysymtabCmd.Extreloff", Field, 0}, - {"DysymtabCmd.Iextdefsym", Field, 0}, - {"DysymtabCmd.Ilocalsym", Field, 0}, - {"DysymtabCmd.Indirectsymoff", Field, 0}, - {"DysymtabCmd.Iundefsym", Field, 0}, - {"DysymtabCmd.Len", Field, 0}, - {"DysymtabCmd.Locreloff", Field, 0}, - {"DysymtabCmd.Modtaboff", Field, 0}, - {"DysymtabCmd.Nextdefsym", Field, 0}, - {"DysymtabCmd.Nextrefsyms", Field, 0}, - {"DysymtabCmd.Nextrel", Field, 0}, - {"DysymtabCmd.Nindirectsyms", Field, 0}, - {"DysymtabCmd.Nlocalsym", Field, 0}, - {"DysymtabCmd.Nlocrel", Field, 0}, - {"DysymtabCmd.Nmodtab", Field, 0}, - {"DysymtabCmd.Ntoc", Field, 0}, - {"DysymtabCmd.Nundefsym", Field, 0}, - {"DysymtabCmd.Tocoffset", Field, 0}, - {"ErrNotFat", Var, 3}, - {"FatArch", Type, 3}, - {"FatArch.FatArchHeader", Field, 3}, - {"FatArch.File", Field, 3}, - {"FatArchHeader", Type, 3}, - {"FatArchHeader.Align", Field, 3}, - {"FatArchHeader.Cpu", Field, 3}, - {"FatArchHeader.Offset", Field, 3}, - {"FatArchHeader.Size", Field, 3}, - {"FatArchHeader.SubCpu", Field, 3}, - {"FatFile", Type, 3}, - {"FatFile.Arches", Field, 3}, - {"FatFile.Magic", Field, 3}, - {"File", Type, 0}, - {"File.ByteOrder", Field, 0}, - {"File.Dysymtab", Field, 0}, - {"File.FileHeader", Field, 0}, - {"File.Loads", Field, 0}, - {"File.Sections", Field, 0}, - {"File.Symtab", Field, 0}, - {"FileHeader", Type, 0}, - {"FileHeader.Cmdsz", Field, 0}, - {"FileHeader.Cpu", Field, 0}, - {"FileHeader.Flags", Field, 0}, - {"FileHeader.Magic", Field, 0}, - {"FileHeader.Ncmd", Field, 0}, - {"FileHeader.SubCpu", Field, 0}, - {"FileHeader.Type", Field, 0}, - {"FlagAllModsBound", Const, 10}, - {"FlagAllowStackExecution", Const, 10}, - {"FlagAppExtensionSafe", Const, 10}, - {"FlagBindAtLoad", Const, 10}, - {"FlagBindsToWeak", Const, 10}, - {"FlagCanonical", Const, 10}, - {"FlagDeadStrippableDylib", Const, 10}, - {"FlagDyldLink", Const, 10}, - {"FlagForceFlat", Const, 10}, - {"FlagHasTLVDescriptors", Const, 10}, - {"FlagIncrLink", Const, 10}, - {"FlagLazyInit", Const, 10}, - {"FlagNoFixPrebinding", Const, 10}, - {"FlagNoHeapExecution", Const, 10}, - {"FlagNoMultiDefs", Const, 10}, - {"FlagNoReexportedDylibs", Const, 10}, - {"FlagNoUndefs", Const, 10}, - {"FlagPIE", Const, 10}, - {"FlagPrebindable", Const, 10}, - {"FlagPrebound", Const, 10}, - {"FlagRootSafe", Const, 10}, - {"FlagSetuidSafe", Const, 10}, - {"FlagSplitSegs", Const, 10}, - {"FlagSubsectionsViaSymbols", Const, 10}, - {"FlagTwoLevel", Const, 10}, - {"FlagWeakDefines", Const, 10}, - {"FormatError", Type, 0}, - {"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10}, - {"GENERIC_RELOC_PAIR", Const, 10}, - {"GENERIC_RELOC_PB_LA_PTR", Const, 10}, - {"GENERIC_RELOC_SECTDIFF", Const, 10}, - {"GENERIC_RELOC_TLV", Const, 10}, - {"GENERIC_RELOC_VANILLA", Const, 10}, - {"Load", Type, 0}, - {"LoadBytes", Type, 0}, - {"LoadCmd", Type, 0}, - {"LoadCmdDylib", Const, 0}, - {"LoadCmdDylinker", Const, 0}, - {"LoadCmdDysymtab", Const, 0}, - {"LoadCmdRpath", Const, 10}, - {"LoadCmdSegment", Const, 0}, - {"LoadCmdSegment64", Const, 0}, - {"LoadCmdSymtab", Const, 0}, - {"LoadCmdThread", Const, 0}, - {"LoadCmdUnixThread", Const, 0}, - {"Magic32", Const, 0}, - {"Magic64", Const, 0}, - {"MagicFat", Const, 3}, - {"NewFatFile", Func, 3}, - {"NewFile", Func, 0}, - {"Nlist32", Type, 0}, - {"Nlist32.Desc", Field, 0}, - {"Nlist32.Name", Field, 0}, - {"Nlist32.Sect", Field, 0}, - {"Nlist32.Type", Field, 0}, - {"Nlist32.Value", Field, 0}, - {"Nlist64", Type, 0}, - {"Nlist64.Desc", Field, 0}, - {"Nlist64.Name", Field, 0}, - {"Nlist64.Sect", Field, 0}, - {"Nlist64.Type", Field, 0}, - {"Nlist64.Value", Field, 0}, - {"Open", Func, 0}, - {"OpenFat", Func, 3}, - {"Regs386", Type, 0}, - {"Regs386.AX", Field, 0}, - {"Regs386.BP", Field, 0}, - {"Regs386.BX", Field, 0}, - {"Regs386.CS", Field, 0}, - {"Regs386.CX", Field, 0}, - {"Regs386.DI", Field, 0}, - {"Regs386.DS", Field, 0}, - {"Regs386.DX", Field, 0}, - {"Regs386.ES", Field, 0}, - {"Regs386.FLAGS", Field, 0}, - {"Regs386.FS", Field, 0}, - {"Regs386.GS", Field, 0}, - {"Regs386.IP", Field, 0}, - {"Regs386.SI", Field, 0}, - {"Regs386.SP", Field, 0}, - {"Regs386.SS", Field, 0}, - {"RegsAMD64", Type, 0}, - {"RegsAMD64.AX", Field, 0}, - {"RegsAMD64.BP", Field, 0}, - {"RegsAMD64.BX", Field, 0}, - {"RegsAMD64.CS", Field, 0}, - {"RegsAMD64.CX", Field, 0}, - {"RegsAMD64.DI", Field, 0}, - {"RegsAMD64.DX", Field, 0}, - {"RegsAMD64.FLAGS", Field, 0}, - {"RegsAMD64.FS", Field, 0}, - {"RegsAMD64.GS", Field, 0}, - {"RegsAMD64.IP", Field, 0}, - {"RegsAMD64.R10", Field, 0}, - {"RegsAMD64.R11", Field, 0}, - {"RegsAMD64.R12", Field, 0}, - {"RegsAMD64.R13", Field, 0}, - {"RegsAMD64.R14", Field, 0}, - {"RegsAMD64.R15", Field, 0}, - {"RegsAMD64.R8", Field, 0}, - {"RegsAMD64.R9", Field, 0}, - {"RegsAMD64.SI", Field, 0}, - {"RegsAMD64.SP", Field, 0}, - {"Reloc", Type, 10}, - {"Reloc.Addr", Field, 10}, - {"Reloc.Extern", Field, 10}, - {"Reloc.Len", Field, 10}, - {"Reloc.Pcrel", Field, 10}, - {"Reloc.Scattered", Field, 10}, - {"Reloc.Type", Field, 10}, - {"Reloc.Value", Field, 10}, - {"RelocTypeARM", Type, 10}, - {"RelocTypeARM64", Type, 10}, - {"RelocTypeGeneric", Type, 10}, - {"RelocTypeX86_64", Type, 10}, - {"Rpath", Type, 10}, - {"Rpath.LoadBytes", Field, 10}, - {"Rpath.Path", Field, 10}, - {"RpathCmd", Type, 10}, - {"RpathCmd.Cmd", Field, 10}, - {"RpathCmd.Len", Field, 10}, - {"RpathCmd.Path", Field, 10}, - {"Section", Type, 0}, - {"Section.ReaderAt", Field, 0}, - {"Section.Relocs", Field, 10}, - {"Section.SectionHeader", Field, 0}, - {"Section32", Type, 0}, - {"Section32.Addr", Field, 0}, - {"Section32.Align", Field, 0}, - {"Section32.Flags", Field, 0}, - {"Section32.Name", Field, 0}, - {"Section32.Nreloc", Field, 0}, - {"Section32.Offset", Field, 0}, - {"Section32.Reloff", Field, 0}, - {"Section32.Reserve1", Field, 0}, - {"Section32.Reserve2", Field, 0}, - {"Section32.Seg", Field, 0}, - {"Section32.Size", Field, 0}, - {"Section64", Type, 0}, - {"Section64.Addr", Field, 0}, - {"Section64.Align", Field, 0}, - {"Section64.Flags", Field, 0}, - {"Section64.Name", Field, 0}, - {"Section64.Nreloc", Field, 0}, - {"Section64.Offset", Field, 0}, - {"Section64.Reloff", Field, 0}, - {"Section64.Reserve1", Field, 0}, - {"Section64.Reserve2", Field, 0}, - {"Section64.Reserve3", Field, 0}, - {"Section64.Seg", Field, 0}, - {"Section64.Size", Field, 0}, - {"SectionHeader", Type, 0}, - {"SectionHeader.Addr", Field, 0}, - {"SectionHeader.Align", Field, 0}, - {"SectionHeader.Flags", Field, 0}, - {"SectionHeader.Name", Field, 0}, - {"SectionHeader.Nreloc", Field, 0}, - {"SectionHeader.Offset", Field, 0}, - {"SectionHeader.Reloff", Field, 0}, - {"SectionHeader.Seg", Field, 0}, - {"SectionHeader.Size", Field, 0}, - {"Segment", Type, 0}, - {"Segment.LoadBytes", Field, 0}, - {"Segment.ReaderAt", Field, 0}, - {"Segment.SegmentHeader", Field, 0}, - {"Segment32", Type, 0}, - {"Segment32.Addr", Field, 0}, - {"Segment32.Cmd", Field, 0}, - {"Segment32.Filesz", Field, 0}, - {"Segment32.Flag", Field, 0}, - {"Segment32.Len", Field, 0}, - {"Segment32.Maxprot", Field, 0}, - {"Segment32.Memsz", Field, 0}, - {"Segment32.Name", Field, 0}, - {"Segment32.Nsect", Field, 0}, - {"Segment32.Offset", Field, 0}, - {"Segment32.Prot", Field, 0}, - {"Segment64", Type, 0}, - {"Segment64.Addr", Field, 0}, - {"Segment64.Cmd", Field, 0}, - {"Segment64.Filesz", Field, 0}, - {"Segment64.Flag", Field, 0}, - {"Segment64.Len", Field, 0}, - {"Segment64.Maxprot", Field, 0}, - {"Segment64.Memsz", Field, 0}, - {"Segment64.Name", Field, 0}, - {"Segment64.Nsect", Field, 0}, - {"Segment64.Offset", Field, 0}, - {"Segment64.Prot", Field, 0}, - {"SegmentHeader", Type, 0}, - {"SegmentHeader.Addr", Field, 0}, - {"SegmentHeader.Cmd", Field, 0}, - {"SegmentHeader.Filesz", Field, 0}, - {"SegmentHeader.Flag", Field, 0}, - {"SegmentHeader.Len", Field, 0}, - {"SegmentHeader.Maxprot", Field, 0}, - {"SegmentHeader.Memsz", Field, 0}, - {"SegmentHeader.Name", Field, 0}, - {"SegmentHeader.Nsect", Field, 0}, - {"SegmentHeader.Offset", Field, 0}, - {"SegmentHeader.Prot", Field, 0}, - {"Symbol", Type, 0}, - {"Symbol.Desc", Field, 0}, - {"Symbol.Name", Field, 0}, - {"Symbol.Sect", Field, 0}, - {"Symbol.Type", Field, 0}, - {"Symbol.Value", Field, 0}, - {"Symtab", Type, 0}, - {"Symtab.LoadBytes", Field, 0}, - {"Symtab.Syms", Field, 0}, - {"Symtab.SymtabCmd", Field, 0}, - {"SymtabCmd", Type, 0}, - {"SymtabCmd.Cmd", Field, 0}, - {"SymtabCmd.Len", Field, 0}, - {"SymtabCmd.Nsyms", Field, 0}, - {"SymtabCmd.Stroff", Field, 0}, - {"SymtabCmd.Strsize", Field, 0}, - {"SymtabCmd.Symoff", Field, 0}, - {"Thread", Type, 0}, - {"Thread.Cmd", Field, 0}, - {"Thread.Data", Field, 0}, - {"Thread.Len", Field, 0}, - {"Thread.Type", Field, 0}, - {"Type", Type, 0}, - {"TypeBundle", Const, 3}, - {"TypeDylib", Const, 3}, - {"TypeExec", Const, 0}, - {"TypeObj", Const, 0}, - {"X86_64_RELOC_BRANCH", Const, 10}, - {"X86_64_RELOC_GOT", Const, 10}, - {"X86_64_RELOC_GOT_LOAD", Const, 10}, - {"X86_64_RELOC_SIGNED", Const, 10}, - {"X86_64_RELOC_SIGNED_1", Const, 10}, - {"X86_64_RELOC_SIGNED_2", Const, 10}, - {"X86_64_RELOC_SIGNED_4", Const, 10}, - {"X86_64_RELOC_SUBTRACTOR", Const, 10}, - {"X86_64_RELOC_TLV", Const, 10}, - {"X86_64_RELOC_UNSIGNED", Const, 10}, - }, - "debug/pe": { - {"(*COFFSymbol).FullName", Method, 8}, - {"(*File).COFFSymbolReadSectionDefAux", Method, 19}, - {"(*File).Close", Method, 0}, - {"(*File).DWARF", Method, 0}, - {"(*File).ImportedLibraries", Method, 0}, - {"(*File).ImportedSymbols", Method, 0}, - {"(*File).Section", Method, 0}, - {"(*FormatError).Error", Method, 0}, - {"(*Section).Data", Method, 0}, - {"(*Section).Open", Method, 0}, - {"(Section).ReadAt", Method, 0}, - {"(StringTable).String", Method, 8}, - {"COFFSymbol", Type, 1}, - {"COFFSymbol.Name", Field, 1}, - {"COFFSymbol.NumberOfAuxSymbols", Field, 1}, - {"COFFSymbol.SectionNumber", Field, 1}, - {"COFFSymbol.StorageClass", Field, 1}, - {"COFFSymbol.Type", Field, 1}, - {"COFFSymbol.Value", Field, 1}, - {"COFFSymbolAuxFormat5", Type, 19}, - {"COFFSymbolAuxFormat5.Checksum", Field, 19}, - {"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19}, - {"COFFSymbolAuxFormat5.NumRelocs", Field, 19}, - {"COFFSymbolAuxFormat5.SecNum", Field, 19}, - {"COFFSymbolAuxFormat5.Selection", Field, 19}, - {"COFFSymbolAuxFormat5.Size", Field, 19}, - {"COFFSymbolSize", Const, 1}, - {"DataDirectory", Type, 3}, - {"DataDirectory.Size", Field, 3}, - {"DataDirectory.VirtualAddress", Field, 3}, - {"File", Type, 0}, - {"File.COFFSymbols", Field, 8}, - {"File.FileHeader", Field, 0}, - {"File.OptionalHeader", Field, 3}, - {"File.Sections", Field, 0}, - {"File.StringTable", Field, 8}, - {"File.Symbols", Field, 1}, - {"FileHeader", Type, 0}, - {"FileHeader.Characteristics", Field, 0}, - {"FileHeader.Machine", Field, 0}, - {"FileHeader.NumberOfSections", Field, 0}, - {"FileHeader.NumberOfSymbols", Field, 0}, - {"FileHeader.PointerToSymbolTable", Field, 0}, - {"FileHeader.SizeOfOptionalHeader", Field, 0}, - {"FileHeader.TimeDateStamp", Field, 0}, - {"FormatError", Type, 0}, - {"IMAGE_COMDAT_SELECT_ANY", Const, 19}, - {"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19}, - {"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19}, - {"IMAGE_COMDAT_SELECT_LARGEST", Const, 19}, - {"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19}, - {"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19}, - {"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11}, - {"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11}, - {"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15}, - {"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15}, - {"IMAGE_FILE_32BIT_MACHINE", Const, 15}, - {"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15}, - {"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15}, - {"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15}, - {"IMAGE_FILE_DEBUG_STRIPPED", Const, 15}, - {"IMAGE_FILE_DLL", Const, 15}, - {"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15}, - {"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15}, - {"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15}, - {"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15}, - {"IMAGE_FILE_MACHINE_AM33", Const, 0}, - {"IMAGE_FILE_MACHINE_AMD64", Const, 0}, - {"IMAGE_FILE_MACHINE_ARM", Const, 0}, - {"IMAGE_FILE_MACHINE_ARM64", Const, 11}, - {"IMAGE_FILE_MACHINE_ARMNT", Const, 12}, - {"IMAGE_FILE_MACHINE_EBC", Const, 0}, - {"IMAGE_FILE_MACHINE_I386", Const, 0}, - {"IMAGE_FILE_MACHINE_IA64", Const, 0}, - {"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19}, - {"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19}, - {"IMAGE_FILE_MACHINE_M32R", Const, 0}, - {"IMAGE_FILE_MACHINE_MIPS16", Const, 0}, - {"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0}, - {"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0}, - {"IMAGE_FILE_MACHINE_POWERPC", Const, 0}, - {"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0}, - {"IMAGE_FILE_MACHINE_R4000", Const, 0}, - {"IMAGE_FILE_MACHINE_RISCV128", Const, 20}, - {"IMAGE_FILE_MACHINE_RISCV32", Const, 20}, - {"IMAGE_FILE_MACHINE_RISCV64", Const, 20}, - {"IMAGE_FILE_MACHINE_SH3", Const, 0}, - {"IMAGE_FILE_MACHINE_SH3DSP", Const, 0}, - {"IMAGE_FILE_MACHINE_SH4", Const, 0}, - {"IMAGE_FILE_MACHINE_SH5", Const, 0}, - {"IMAGE_FILE_MACHINE_THUMB", Const, 0}, - {"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0}, - {"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0}, - {"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15}, - {"IMAGE_FILE_RELOCS_STRIPPED", Const, 15}, - {"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15}, - {"IMAGE_FILE_SYSTEM", Const, 15}, - {"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15}, - {"IMAGE_SCN_CNT_CODE", Const, 19}, - {"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19}, - {"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19}, - {"IMAGE_SCN_LNK_COMDAT", Const, 19}, - {"IMAGE_SCN_MEM_DISCARDABLE", Const, 19}, - {"IMAGE_SCN_MEM_EXECUTE", Const, 19}, - {"IMAGE_SCN_MEM_READ", Const, 19}, - {"IMAGE_SCN_MEM_WRITE", Const, 19}, - {"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15}, - {"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15}, - {"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15}, - {"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15}, - {"IMAGE_SUBSYSTEM_NATIVE", Const, 15}, - {"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15}, - {"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15}, - {"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15}, - {"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15}, - {"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15}, - {"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15}, - {"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15}, - {"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15}, - {"IMAGE_SUBSYSTEM_XBOX", Const, 15}, - {"ImportDirectory", Type, 0}, - {"ImportDirectory.FirstThunk", Field, 0}, - {"ImportDirectory.ForwarderChain", Field, 0}, - {"ImportDirectory.Name", Field, 0}, - {"ImportDirectory.OriginalFirstThunk", Field, 0}, - {"ImportDirectory.TimeDateStamp", Field, 0}, - {"NewFile", Func, 0}, - {"Open", Func, 0}, - {"OptionalHeader32", Type, 3}, - {"OptionalHeader32.AddressOfEntryPoint", Field, 3}, - {"OptionalHeader32.BaseOfCode", Field, 3}, - {"OptionalHeader32.BaseOfData", Field, 3}, - {"OptionalHeader32.CheckSum", Field, 3}, - {"OptionalHeader32.DataDirectory", Field, 3}, - {"OptionalHeader32.DllCharacteristics", Field, 3}, - {"OptionalHeader32.FileAlignment", Field, 3}, - {"OptionalHeader32.ImageBase", Field, 3}, - {"OptionalHeader32.LoaderFlags", Field, 3}, - {"OptionalHeader32.Magic", Field, 3}, - {"OptionalHeader32.MajorImageVersion", Field, 3}, - {"OptionalHeader32.MajorLinkerVersion", Field, 3}, - {"OptionalHeader32.MajorOperatingSystemVersion", Field, 3}, - {"OptionalHeader32.MajorSubsystemVersion", Field, 3}, - {"OptionalHeader32.MinorImageVersion", Field, 3}, - {"OptionalHeader32.MinorLinkerVersion", Field, 3}, - {"OptionalHeader32.MinorOperatingSystemVersion", Field, 3}, - {"OptionalHeader32.MinorSubsystemVersion", Field, 3}, - {"OptionalHeader32.NumberOfRvaAndSizes", Field, 3}, - {"OptionalHeader32.SectionAlignment", Field, 3}, - {"OptionalHeader32.SizeOfCode", Field, 3}, - {"OptionalHeader32.SizeOfHeaders", Field, 3}, - {"OptionalHeader32.SizeOfHeapCommit", Field, 3}, - {"OptionalHeader32.SizeOfHeapReserve", Field, 3}, - {"OptionalHeader32.SizeOfImage", Field, 3}, - {"OptionalHeader32.SizeOfInitializedData", Field, 3}, - {"OptionalHeader32.SizeOfStackCommit", Field, 3}, - {"OptionalHeader32.SizeOfStackReserve", Field, 3}, - {"OptionalHeader32.SizeOfUninitializedData", Field, 3}, - {"OptionalHeader32.Subsystem", Field, 3}, - {"OptionalHeader32.Win32VersionValue", Field, 3}, - {"OptionalHeader64", Type, 3}, - {"OptionalHeader64.AddressOfEntryPoint", Field, 3}, - {"OptionalHeader64.BaseOfCode", Field, 3}, - {"OptionalHeader64.CheckSum", Field, 3}, - {"OptionalHeader64.DataDirectory", Field, 3}, - {"OptionalHeader64.DllCharacteristics", Field, 3}, - {"OptionalHeader64.FileAlignment", Field, 3}, - {"OptionalHeader64.ImageBase", Field, 3}, - {"OptionalHeader64.LoaderFlags", Field, 3}, - {"OptionalHeader64.Magic", Field, 3}, - {"OptionalHeader64.MajorImageVersion", Field, 3}, - {"OptionalHeader64.MajorLinkerVersion", Field, 3}, - {"OptionalHeader64.MajorOperatingSystemVersion", Field, 3}, - {"OptionalHeader64.MajorSubsystemVersion", Field, 3}, - {"OptionalHeader64.MinorImageVersion", Field, 3}, - {"OptionalHeader64.MinorLinkerVersion", Field, 3}, - {"OptionalHeader64.MinorOperatingSystemVersion", Field, 3}, - {"OptionalHeader64.MinorSubsystemVersion", Field, 3}, - {"OptionalHeader64.NumberOfRvaAndSizes", Field, 3}, - {"OptionalHeader64.SectionAlignment", Field, 3}, - {"OptionalHeader64.SizeOfCode", Field, 3}, - {"OptionalHeader64.SizeOfHeaders", Field, 3}, - {"OptionalHeader64.SizeOfHeapCommit", Field, 3}, - {"OptionalHeader64.SizeOfHeapReserve", Field, 3}, - {"OptionalHeader64.SizeOfImage", Field, 3}, - {"OptionalHeader64.SizeOfInitializedData", Field, 3}, - {"OptionalHeader64.SizeOfStackCommit", Field, 3}, - {"OptionalHeader64.SizeOfStackReserve", Field, 3}, - {"OptionalHeader64.SizeOfUninitializedData", Field, 3}, - {"OptionalHeader64.Subsystem", Field, 3}, - {"OptionalHeader64.Win32VersionValue", Field, 3}, - {"Reloc", Type, 8}, - {"Reloc.SymbolTableIndex", Field, 8}, - {"Reloc.Type", Field, 8}, - {"Reloc.VirtualAddress", Field, 8}, - {"Section", Type, 0}, - {"Section.ReaderAt", Field, 0}, - {"Section.Relocs", Field, 8}, - {"Section.SectionHeader", Field, 0}, - {"SectionHeader", Type, 0}, - {"SectionHeader.Characteristics", Field, 0}, - {"SectionHeader.Name", Field, 0}, - {"SectionHeader.NumberOfLineNumbers", Field, 0}, - {"SectionHeader.NumberOfRelocations", Field, 0}, - {"SectionHeader.Offset", Field, 0}, - {"SectionHeader.PointerToLineNumbers", Field, 0}, - {"SectionHeader.PointerToRelocations", Field, 0}, - {"SectionHeader.Size", Field, 0}, - {"SectionHeader.VirtualAddress", Field, 0}, - {"SectionHeader.VirtualSize", Field, 0}, - {"SectionHeader32", Type, 0}, - {"SectionHeader32.Characteristics", Field, 0}, - {"SectionHeader32.Name", Field, 0}, - {"SectionHeader32.NumberOfLineNumbers", Field, 0}, - {"SectionHeader32.NumberOfRelocations", Field, 0}, - {"SectionHeader32.PointerToLineNumbers", Field, 0}, - {"SectionHeader32.PointerToRawData", Field, 0}, - {"SectionHeader32.PointerToRelocations", Field, 0}, - {"SectionHeader32.SizeOfRawData", Field, 0}, - {"SectionHeader32.VirtualAddress", Field, 0}, - {"SectionHeader32.VirtualSize", Field, 0}, - {"StringTable", Type, 8}, - {"Symbol", Type, 1}, - {"Symbol.Name", Field, 1}, - {"Symbol.SectionNumber", Field, 1}, - {"Symbol.StorageClass", Field, 1}, - {"Symbol.Type", Field, 1}, - {"Symbol.Value", Field, 1}, - }, - "debug/plan9obj": { - {"(*File).Close", Method, 3}, - {"(*File).Section", Method, 3}, - {"(*File).Symbols", Method, 3}, - {"(*Section).Data", Method, 3}, - {"(*Section).Open", Method, 3}, - {"(Section).ReadAt", Method, 3}, - {"ErrNoSymbols", Var, 18}, - {"File", Type, 3}, - {"File.FileHeader", Field, 3}, - {"File.Sections", Field, 3}, - {"FileHeader", Type, 3}, - {"FileHeader.Bss", Field, 3}, - {"FileHeader.Entry", Field, 3}, - {"FileHeader.HdrSize", Field, 4}, - {"FileHeader.LoadAddress", Field, 4}, - {"FileHeader.Magic", Field, 3}, - {"FileHeader.PtrSize", Field, 3}, - {"Magic386", Const, 3}, - {"Magic64", Const, 3}, - {"MagicAMD64", Const, 3}, - {"MagicARM", Const, 3}, - {"NewFile", Func, 3}, - {"Open", Func, 3}, - {"Section", Type, 3}, - {"Section.ReaderAt", Field, 3}, - {"Section.SectionHeader", Field, 3}, - {"SectionHeader", Type, 3}, - {"SectionHeader.Name", Field, 3}, - {"SectionHeader.Offset", Field, 3}, - {"SectionHeader.Size", Field, 3}, - {"Sym", Type, 3}, - {"Sym.Name", Field, 3}, - {"Sym.Type", Field, 3}, - {"Sym.Value", Field, 3}, - }, - "embed": { - {"(FS).Open", Method, 16}, - {"(FS).ReadDir", Method, 16}, - {"(FS).ReadFile", Method, 16}, - {"FS", Type, 16}, - }, - "encoding": { - {"BinaryAppender", Type, 24}, - {"BinaryMarshaler", Type, 2}, - {"BinaryUnmarshaler", Type, 2}, - {"TextAppender", Type, 24}, - {"TextMarshaler", Type, 2}, - {"TextUnmarshaler", Type, 2}, - }, - "encoding/ascii85": { - {"(CorruptInputError).Error", Method, 0}, - {"CorruptInputError", Type, 0}, - {"Decode", Func, 0}, - {"Encode", Func, 0}, - {"MaxEncodedLen", Func, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - }, - "encoding/asn1": { - {"(BitString).At", Method, 0}, - {"(BitString).RightAlign", Method, 0}, - {"(ObjectIdentifier).Equal", Method, 0}, - {"(ObjectIdentifier).String", Method, 3}, - {"(StructuralError).Error", Method, 0}, - {"(SyntaxError).Error", Method, 0}, - {"BitString", Type, 0}, - {"BitString.BitLength", Field, 0}, - {"BitString.Bytes", Field, 0}, - {"ClassApplication", Const, 6}, - {"ClassContextSpecific", Const, 6}, - {"ClassPrivate", Const, 6}, - {"ClassUniversal", Const, 6}, - {"Enumerated", Type, 0}, - {"Flag", Type, 0}, - {"Marshal", Func, 0}, - {"MarshalWithParams", Func, 10}, - {"NullBytes", Var, 9}, - {"NullRawValue", Var, 9}, - {"ObjectIdentifier", Type, 0}, - {"RawContent", Type, 0}, - {"RawValue", Type, 0}, - {"RawValue.Bytes", Field, 0}, - {"RawValue.Class", Field, 0}, - {"RawValue.FullBytes", Field, 0}, - {"RawValue.IsCompound", Field, 0}, - {"RawValue.Tag", Field, 0}, - {"StructuralError", Type, 0}, - {"StructuralError.Msg", Field, 0}, - {"SyntaxError", Type, 0}, - {"SyntaxError.Msg", Field, 0}, - {"TagBMPString", Const, 14}, - {"TagBitString", Const, 6}, - {"TagBoolean", Const, 6}, - {"TagEnum", Const, 6}, - {"TagGeneralString", Const, 6}, - {"TagGeneralizedTime", Const, 6}, - {"TagIA5String", Const, 6}, - {"TagInteger", Const, 6}, - {"TagNull", Const, 9}, - {"TagNumericString", Const, 10}, - {"TagOID", Const, 6}, - {"TagOctetString", Const, 6}, - {"TagPrintableString", Const, 6}, - {"TagSequence", Const, 6}, - {"TagSet", Const, 6}, - {"TagT61String", Const, 6}, - {"TagUTCTime", Const, 6}, - {"TagUTF8String", Const, 6}, - {"Unmarshal", Func, 0}, - {"UnmarshalWithParams", Func, 0}, - }, - "encoding/base32": { - {"(*Encoding).AppendDecode", Method, 22}, - {"(*Encoding).AppendEncode", Method, 22}, - {"(*Encoding).Decode", Method, 0}, - {"(*Encoding).DecodeString", Method, 0}, - {"(*Encoding).DecodedLen", Method, 0}, - {"(*Encoding).Encode", Method, 0}, - {"(*Encoding).EncodeToString", Method, 0}, - {"(*Encoding).EncodedLen", Method, 0}, - {"(CorruptInputError).Error", Method, 0}, - {"(Encoding).WithPadding", Method, 9}, - {"CorruptInputError", Type, 0}, - {"Encoding", Type, 0}, - {"HexEncoding", Var, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - {"NewEncoding", Func, 0}, - {"NoPadding", Const, 9}, - {"StdEncoding", Var, 0}, - {"StdPadding", Const, 9}, - }, - "encoding/base64": { - {"(*Encoding).AppendDecode", Method, 22}, - {"(*Encoding).AppendEncode", Method, 22}, - {"(*Encoding).Decode", Method, 0}, - {"(*Encoding).DecodeString", Method, 0}, - {"(*Encoding).DecodedLen", Method, 0}, - {"(*Encoding).Encode", Method, 0}, - {"(*Encoding).EncodeToString", Method, 0}, - {"(*Encoding).EncodedLen", Method, 0}, - {"(CorruptInputError).Error", Method, 0}, - {"(Encoding).Strict", Method, 8}, - {"(Encoding).WithPadding", Method, 5}, - {"CorruptInputError", Type, 0}, - {"Encoding", Type, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - {"NewEncoding", Func, 0}, - {"NoPadding", Const, 5}, - {"RawStdEncoding", Var, 5}, - {"RawURLEncoding", Var, 5}, - {"StdEncoding", Var, 0}, - {"StdPadding", Const, 5}, - {"URLEncoding", Var, 0}, - }, - "encoding/binary": { - {"Append", Func, 23}, - {"AppendByteOrder", Type, 19}, - {"AppendUvarint", Func, 19}, - {"AppendVarint", Func, 19}, - {"BigEndian", Var, 0}, - {"ByteOrder", Type, 0}, - {"Decode", Func, 23}, - {"Encode", Func, 23}, - {"LittleEndian", Var, 0}, - {"MaxVarintLen16", Const, 0}, - {"MaxVarintLen32", Const, 0}, - {"MaxVarintLen64", Const, 0}, - {"NativeEndian", Var, 21}, - {"PutUvarint", Func, 0}, - {"PutVarint", Func, 0}, - {"Read", Func, 0}, - {"ReadUvarint", Func, 0}, - {"ReadVarint", Func, 0}, - {"Size", Func, 0}, - {"Uvarint", Func, 0}, - {"Varint", Func, 0}, - {"Write", Func, 0}, - }, - "encoding/csv": { - {"(*ParseError).Error", Method, 0}, - {"(*ParseError).Unwrap", Method, 13}, - {"(*Reader).FieldPos", Method, 17}, - {"(*Reader).InputOffset", Method, 19}, - {"(*Reader).Read", Method, 0}, - {"(*Reader).ReadAll", Method, 0}, - {"(*Writer).Error", Method, 1}, - {"(*Writer).Flush", Method, 0}, - {"(*Writer).Write", Method, 0}, - {"(*Writer).WriteAll", Method, 0}, - {"ErrBareQuote", Var, 0}, - {"ErrFieldCount", Var, 0}, - {"ErrQuote", Var, 0}, - {"ErrTrailingComma", Var, 0}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"ParseError", Type, 0}, - {"ParseError.Column", Field, 0}, - {"ParseError.Err", Field, 0}, - {"ParseError.Line", Field, 0}, - {"ParseError.StartLine", Field, 10}, - {"Reader", Type, 0}, - {"Reader.Comma", Field, 0}, - {"Reader.Comment", Field, 0}, - {"Reader.FieldsPerRecord", Field, 0}, - {"Reader.LazyQuotes", Field, 0}, - {"Reader.ReuseRecord", Field, 9}, - {"Reader.TrailingComma", Field, 0}, - {"Reader.TrimLeadingSpace", Field, 0}, - {"Writer", Type, 0}, - {"Writer.Comma", Field, 0}, - {"Writer.UseCRLF", Field, 0}, - }, - "encoding/gob": { - {"(*Decoder).Decode", Method, 0}, - {"(*Decoder).DecodeValue", Method, 0}, - {"(*Encoder).Encode", Method, 0}, - {"(*Encoder).EncodeValue", Method, 0}, - {"CommonType", Type, 0}, - {"CommonType.Id", Field, 0}, - {"CommonType.Name", Field, 0}, - {"Decoder", Type, 0}, - {"Encoder", Type, 0}, - {"GobDecoder", Type, 0}, - {"GobEncoder", Type, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - {"Register", Func, 0}, - {"RegisterName", Func, 0}, - }, - "encoding/hex": { - {"(InvalidByteError).Error", Method, 0}, - {"AppendDecode", Func, 22}, - {"AppendEncode", Func, 22}, - {"Decode", Func, 0}, - {"DecodeString", Func, 0}, - {"DecodedLen", Func, 0}, - {"Dump", Func, 0}, - {"Dumper", Func, 0}, - {"Encode", Func, 0}, - {"EncodeToString", Func, 0}, - {"EncodedLen", Func, 0}, - {"ErrLength", Var, 0}, - {"InvalidByteError", Type, 0}, - {"NewDecoder", Func, 10}, - {"NewEncoder", Func, 10}, - }, - "encoding/json": { - {"(*Decoder).Buffered", Method, 1}, - {"(*Decoder).Decode", Method, 0}, - {"(*Decoder).DisallowUnknownFields", Method, 10}, - {"(*Decoder).InputOffset", Method, 14}, - {"(*Decoder).More", Method, 5}, - {"(*Decoder).Token", Method, 5}, - {"(*Decoder).UseNumber", Method, 1}, - {"(*Encoder).Encode", Method, 0}, - {"(*Encoder).SetEscapeHTML", Method, 7}, - {"(*Encoder).SetIndent", Method, 7}, - {"(*InvalidUTF8Error).Error", Method, 0}, - {"(*InvalidUnmarshalError).Error", Method, 0}, - {"(*MarshalerError).Error", Method, 0}, - {"(*MarshalerError).Unwrap", Method, 13}, - {"(*RawMessage).MarshalJSON", Method, 0}, - {"(*RawMessage).UnmarshalJSON", Method, 0}, - {"(*SyntaxError).Error", Method, 0}, - {"(*UnmarshalFieldError).Error", Method, 0}, - {"(*UnmarshalTypeError).Error", Method, 0}, - {"(*UnsupportedTypeError).Error", Method, 0}, - {"(*UnsupportedValueError).Error", Method, 0}, - {"(Delim).String", Method, 5}, - {"(Number).Float64", Method, 1}, - {"(Number).Int64", Method, 1}, - {"(Number).String", Method, 1}, - {"(RawMessage).MarshalJSON", Method, 8}, - {"Compact", Func, 0}, - {"Decoder", Type, 0}, - {"Delim", Type, 5}, - {"Encoder", Type, 0}, - {"HTMLEscape", Func, 0}, - {"Indent", Func, 0}, - {"InvalidUTF8Error", Type, 0}, - {"InvalidUTF8Error.S", Field, 0}, - {"InvalidUnmarshalError", Type, 0}, - {"InvalidUnmarshalError.Type", Field, 0}, - {"Marshal", Func, 0}, - {"MarshalIndent", Func, 0}, - {"Marshaler", Type, 0}, - {"MarshalerError", Type, 0}, - {"MarshalerError.Err", Field, 0}, - {"MarshalerError.Type", Field, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - {"Number", Type, 1}, - {"RawMessage", Type, 0}, - {"SyntaxError", Type, 0}, - {"SyntaxError.Offset", Field, 0}, - {"Token", Type, 5}, - {"Unmarshal", Func, 0}, - {"UnmarshalFieldError", Type, 0}, - {"UnmarshalFieldError.Field", Field, 0}, - {"UnmarshalFieldError.Key", Field, 0}, - {"UnmarshalFieldError.Type", Field, 0}, - {"UnmarshalTypeError", Type, 0}, - {"UnmarshalTypeError.Field", Field, 8}, - {"UnmarshalTypeError.Offset", Field, 5}, - {"UnmarshalTypeError.Struct", Field, 8}, - {"UnmarshalTypeError.Type", Field, 0}, - {"UnmarshalTypeError.Value", Field, 0}, - {"Unmarshaler", Type, 0}, - {"UnsupportedTypeError", Type, 0}, - {"UnsupportedTypeError.Type", Field, 0}, - {"UnsupportedValueError", Type, 0}, - {"UnsupportedValueError.Str", Field, 0}, - {"UnsupportedValueError.Value", Field, 0}, - {"Valid", Func, 9}, - }, - "encoding/pem": { - {"Block", Type, 0}, - {"Block.Bytes", Field, 0}, - {"Block.Headers", Field, 0}, - {"Block.Type", Field, 0}, - {"Decode", Func, 0}, - {"Encode", Func, 0}, - {"EncodeToMemory", Func, 0}, - }, - "encoding/xml": { - {"(*Decoder).Decode", Method, 0}, - {"(*Decoder).DecodeElement", Method, 0}, - {"(*Decoder).InputOffset", Method, 4}, - {"(*Decoder).InputPos", Method, 19}, - {"(*Decoder).RawToken", Method, 0}, - {"(*Decoder).Skip", Method, 0}, - {"(*Decoder).Token", Method, 0}, - {"(*Encoder).Close", Method, 20}, - {"(*Encoder).Encode", Method, 0}, - {"(*Encoder).EncodeElement", Method, 2}, - {"(*Encoder).EncodeToken", Method, 2}, - {"(*Encoder).Flush", Method, 2}, - {"(*Encoder).Indent", Method, 1}, - {"(*SyntaxError).Error", Method, 0}, - {"(*TagPathError).Error", Method, 0}, - {"(*UnsupportedTypeError).Error", Method, 0}, - {"(CharData).Copy", Method, 0}, - {"(Comment).Copy", Method, 0}, - {"(Directive).Copy", Method, 0}, - {"(ProcInst).Copy", Method, 0}, - {"(StartElement).Copy", Method, 0}, - {"(StartElement).End", Method, 2}, - {"(UnmarshalError).Error", Method, 0}, - {"Attr", Type, 0}, - {"Attr.Name", Field, 0}, - {"Attr.Value", Field, 0}, - {"CharData", Type, 0}, - {"Comment", Type, 0}, - {"CopyToken", Func, 0}, - {"Decoder", Type, 0}, - {"Decoder.AutoClose", Field, 0}, - {"Decoder.CharsetReader", Field, 0}, - {"Decoder.DefaultSpace", Field, 1}, - {"Decoder.Entity", Field, 0}, - {"Decoder.Strict", Field, 0}, - {"Directive", Type, 0}, - {"Encoder", Type, 0}, - {"EndElement", Type, 0}, - {"EndElement.Name", Field, 0}, - {"Escape", Func, 0}, - {"EscapeText", Func, 1}, - {"HTMLAutoClose", Var, 0}, - {"HTMLEntity", Var, 0}, - {"Header", Const, 0}, - {"Marshal", Func, 0}, - {"MarshalIndent", Func, 0}, - {"Marshaler", Type, 2}, - {"MarshalerAttr", Type, 2}, - {"Name", Type, 0}, - {"Name.Local", Field, 0}, - {"Name.Space", Field, 0}, - {"NewDecoder", Func, 0}, - {"NewEncoder", Func, 0}, - {"NewTokenDecoder", Func, 10}, - {"ProcInst", Type, 0}, - {"ProcInst.Inst", Field, 0}, - {"ProcInst.Target", Field, 0}, - {"StartElement", Type, 0}, - {"StartElement.Attr", Field, 0}, - {"StartElement.Name", Field, 0}, - {"SyntaxError", Type, 0}, - {"SyntaxError.Line", Field, 0}, - {"SyntaxError.Msg", Field, 0}, - {"TagPathError", Type, 0}, - {"TagPathError.Field1", Field, 0}, - {"TagPathError.Field2", Field, 0}, - {"TagPathError.Struct", Field, 0}, - {"TagPathError.Tag1", Field, 0}, - {"TagPathError.Tag2", Field, 0}, - {"Token", Type, 0}, - {"TokenReader", Type, 10}, - {"Unmarshal", Func, 0}, - {"UnmarshalError", Type, 0}, - {"Unmarshaler", Type, 2}, - {"UnmarshalerAttr", Type, 2}, - {"UnsupportedTypeError", Type, 0}, - {"UnsupportedTypeError.Type", Field, 0}, - }, - "errors": { - {"As", Func, 13}, - {"ErrUnsupported", Var, 21}, - {"Is", Func, 13}, - {"Join", Func, 20}, - {"New", Func, 0}, - {"Unwrap", Func, 13}, - }, - "expvar": { - {"(*Float).Add", Method, 0}, - {"(*Float).Set", Method, 0}, - {"(*Float).String", Method, 0}, - {"(*Float).Value", Method, 8}, - {"(*Int).Add", Method, 0}, - {"(*Int).Set", Method, 0}, - {"(*Int).String", Method, 0}, - {"(*Int).Value", Method, 8}, - {"(*Map).Add", Method, 0}, - {"(*Map).AddFloat", Method, 0}, - {"(*Map).Delete", Method, 12}, - {"(*Map).Do", Method, 0}, - {"(*Map).Get", Method, 0}, - {"(*Map).Init", Method, 0}, - {"(*Map).Set", Method, 0}, - {"(*Map).String", Method, 0}, - {"(*String).Set", Method, 0}, - {"(*String).String", Method, 0}, - {"(*String).Value", Method, 8}, - {"(Func).String", Method, 0}, - {"(Func).Value", Method, 8}, - {"Do", Func, 0}, - {"Float", Type, 0}, - {"Func", Type, 0}, - {"Get", Func, 0}, - {"Handler", Func, 8}, - {"Int", Type, 0}, - {"KeyValue", Type, 0}, - {"KeyValue.Key", Field, 0}, - {"KeyValue.Value", Field, 0}, - {"Map", Type, 0}, - {"NewFloat", Func, 0}, - {"NewInt", Func, 0}, - {"NewMap", Func, 0}, - {"NewString", Func, 0}, - {"Publish", Func, 0}, - {"String", Type, 0}, - {"Var", Type, 0}, - }, - "flag": { - {"(*FlagSet).Arg", Method, 0}, - {"(*FlagSet).Args", Method, 0}, - {"(*FlagSet).Bool", Method, 0}, - {"(*FlagSet).BoolFunc", Method, 21}, - {"(*FlagSet).BoolVar", Method, 0}, - {"(*FlagSet).Duration", Method, 0}, - {"(*FlagSet).DurationVar", Method, 0}, - {"(*FlagSet).ErrorHandling", Method, 10}, - {"(*FlagSet).Float64", Method, 0}, - {"(*FlagSet).Float64Var", Method, 0}, - {"(*FlagSet).Func", Method, 16}, - {"(*FlagSet).Init", Method, 0}, - {"(*FlagSet).Int", Method, 0}, - {"(*FlagSet).Int64", Method, 0}, - {"(*FlagSet).Int64Var", Method, 0}, - {"(*FlagSet).IntVar", Method, 0}, - {"(*FlagSet).Lookup", Method, 0}, - {"(*FlagSet).NArg", Method, 0}, - {"(*FlagSet).NFlag", Method, 0}, - {"(*FlagSet).Name", Method, 10}, - {"(*FlagSet).Output", Method, 10}, - {"(*FlagSet).Parse", Method, 0}, - {"(*FlagSet).Parsed", Method, 0}, - {"(*FlagSet).PrintDefaults", Method, 0}, - {"(*FlagSet).Set", Method, 0}, - {"(*FlagSet).SetOutput", Method, 0}, - {"(*FlagSet).String", Method, 0}, - {"(*FlagSet).StringVar", Method, 0}, - {"(*FlagSet).TextVar", Method, 19}, - {"(*FlagSet).Uint", Method, 0}, - {"(*FlagSet).Uint64", Method, 0}, - {"(*FlagSet).Uint64Var", Method, 0}, - {"(*FlagSet).UintVar", Method, 0}, - {"(*FlagSet).Var", Method, 0}, - {"(*FlagSet).Visit", Method, 0}, - {"(*FlagSet).VisitAll", Method, 0}, - {"Arg", Func, 0}, - {"Args", Func, 0}, - {"Bool", Func, 0}, - {"BoolFunc", Func, 21}, - {"BoolVar", Func, 0}, - {"CommandLine", Var, 2}, - {"ContinueOnError", Const, 0}, - {"Duration", Func, 0}, - {"DurationVar", Func, 0}, - {"ErrHelp", Var, 0}, - {"ErrorHandling", Type, 0}, - {"ExitOnError", Const, 0}, - {"Flag", Type, 0}, - {"Flag.DefValue", Field, 0}, - {"Flag.Name", Field, 0}, - {"Flag.Usage", Field, 0}, - {"Flag.Value", Field, 0}, - {"FlagSet", Type, 0}, - {"FlagSet.Usage", Field, 0}, - {"Float64", Func, 0}, - {"Float64Var", Func, 0}, - {"Func", Func, 16}, - {"Getter", Type, 2}, - {"Int", Func, 0}, - {"Int64", Func, 0}, - {"Int64Var", Func, 0}, - {"IntVar", Func, 0}, - {"Lookup", Func, 0}, - {"NArg", Func, 0}, - {"NFlag", Func, 0}, - {"NewFlagSet", Func, 0}, - {"PanicOnError", Const, 0}, - {"Parse", Func, 0}, - {"Parsed", Func, 0}, - {"PrintDefaults", Func, 0}, - {"Set", Func, 0}, - {"String", Func, 0}, - {"StringVar", Func, 0}, - {"TextVar", Func, 19}, - {"Uint", Func, 0}, - {"Uint64", Func, 0}, - {"Uint64Var", Func, 0}, - {"UintVar", Func, 0}, - {"UnquoteUsage", Func, 5}, - {"Usage", Var, 0}, - {"Value", Type, 0}, - {"Var", Func, 0}, - {"Visit", Func, 0}, - {"VisitAll", Func, 0}, - }, - "fmt": { - {"Append", Func, 19}, - {"Appendf", Func, 19}, - {"Appendln", Func, 19}, - {"Errorf", Func, 0}, - {"FormatString", Func, 20}, - {"Formatter", Type, 0}, - {"Fprint", Func, 0}, - {"Fprintf", Func, 0}, - {"Fprintln", Func, 0}, - {"Fscan", Func, 0}, - {"Fscanf", Func, 0}, - {"Fscanln", Func, 0}, - {"GoStringer", Type, 0}, - {"Print", Func, 0}, - {"Printf", Func, 0}, - {"Println", Func, 0}, - {"Scan", Func, 0}, - {"ScanState", Type, 0}, - {"Scanf", Func, 0}, - {"Scanln", Func, 0}, - {"Scanner", Type, 0}, - {"Sprint", Func, 0}, - {"Sprintf", Func, 0}, - {"Sprintln", Func, 0}, - {"Sscan", Func, 0}, - {"Sscanf", Func, 0}, - {"Sscanln", Func, 0}, - {"State", Type, 0}, - {"Stringer", Type, 0}, - }, - "go/ast": { - {"(*ArrayType).End", Method, 0}, - {"(*ArrayType).Pos", Method, 0}, - {"(*AssignStmt).End", Method, 0}, - {"(*AssignStmt).Pos", Method, 0}, - {"(*BadDecl).End", Method, 0}, - {"(*BadDecl).Pos", Method, 0}, - {"(*BadExpr).End", Method, 0}, - {"(*BadExpr).Pos", Method, 0}, - {"(*BadStmt).End", Method, 0}, - {"(*BadStmt).Pos", Method, 0}, - {"(*BasicLit).End", Method, 0}, - {"(*BasicLit).Pos", Method, 0}, - {"(*BinaryExpr).End", Method, 0}, - {"(*BinaryExpr).Pos", Method, 0}, - {"(*BlockStmt).End", Method, 0}, - {"(*BlockStmt).Pos", Method, 0}, - {"(*BranchStmt).End", Method, 0}, - {"(*BranchStmt).Pos", Method, 0}, - {"(*CallExpr).End", Method, 0}, - {"(*CallExpr).Pos", Method, 0}, - {"(*CaseClause).End", Method, 0}, - {"(*CaseClause).Pos", Method, 0}, - {"(*ChanType).End", Method, 0}, - {"(*ChanType).Pos", Method, 0}, - {"(*CommClause).End", Method, 0}, - {"(*CommClause).Pos", Method, 0}, - {"(*Comment).End", Method, 0}, - {"(*Comment).Pos", Method, 0}, - {"(*CommentGroup).End", Method, 0}, - {"(*CommentGroup).Pos", Method, 0}, - {"(*CommentGroup).Text", Method, 0}, - {"(*CompositeLit).End", Method, 0}, - {"(*CompositeLit).Pos", Method, 0}, - {"(*DeclStmt).End", Method, 0}, - {"(*DeclStmt).Pos", Method, 0}, - {"(*DeferStmt).End", Method, 0}, - {"(*DeferStmt).Pos", Method, 0}, - {"(*Ellipsis).End", Method, 0}, - {"(*Ellipsis).Pos", Method, 0}, - {"(*EmptyStmt).End", Method, 0}, - {"(*EmptyStmt).Pos", Method, 0}, - {"(*ExprStmt).End", Method, 0}, - {"(*ExprStmt).Pos", Method, 0}, - {"(*Field).End", Method, 0}, - {"(*Field).Pos", Method, 0}, - {"(*FieldList).End", Method, 0}, - {"(*FieldList).NumFields", Method, 0}, - {"(*FieldList).Pos", Method, 0}, - {"(*File).End", Method, 0}, - {"(*File).Pos", Method, 0}, - {"(*ForStmt).End", Method, 0}, - {"(*ForStmt).Pos", Method, 0}, - {"(*FuncDecl).End", Method, 0}, - {"(*FuncDecl).Pos", Method, 0}, - {"(*FuncLit).End", Method, 0}, - {"(*FuncLit).Pos", Method, 0}, - {"(*FuncType).End", Method, 0}, - {"(*FuncType).Pos", Method, 0}, - {"(*GenDecl).End", Method, 0}, - {"(*GenDecl).Pos", Method, 0}, - {"(*GoStmt).End", Method, 0}, - {"(*GoStmt).Pos", Method, 0}, - {"(*Ident).End", Method, 0}, - {"(*Ident).IsExported", Method, 0}, - {"(*Ident).Pos", Method, 0}, - {"(*Ident).String", Method, 0}, - {"(*IfStmt).End", Method, 0}, - {"(*IfStmt).Pos", Method, 0}, - {"(*ImportSpec).End", Method, 0}, - {"(*ImportSpec).Pos", Method, 0}, - {"(*IncDecStmt).End", Method, 0}, - {"(*IncDecStmt).Pos", Method, 0}, - {"(*IndexExpr).End", Method, 0}, - {"(*IndexExpr).Pos", Method, 0}, - {"(*IndexListExpr).End", Method, 18}, - {"(*IndexListExpr).Pos", Method, 18}, - {"(*InterfaceType).End", Method, 0}, - {"(*InterfaceType).Pos", Method, 0}, - {"(*KeyValueExpr).End", Method, 0}, - {"(*KeyValueExpr).Pos", Method, 0}, - {"(*LabeledStmt).End", Method, 0}, - {"(*LabeledStmt).Pos", Method, 0}, - {"(*MapType).End", Method, 0}, - {"(*MapType).Pos", Method, 0}, - {"(*Object).Pos", Method, 0}, - {"(*Package).End", Method, 0}, - {"(*Package).Pos", Method, 0}, - {"(*ParenExpr).End", Method, 0}, - {"(*ParenExpr).Pos", Method, 0}, - {"(*RangeStmt).End", Method, 0}, - {"(*RangeStmt).Pos", Method, 0}, - {"(*ReturnStmt).End", Method, 0}, - {"(*ReturnStmt).Pos", Method, 0}, - {"(*Scope).Insert", Method, 0}, - {"(*Scope).Lookup", Method, 0}, - {"(*Scope).String", Method, 0}, - {"(*SelectStmt).End", Method, 0}, - {"(*SelectStmt).Pos", Method, 0}, - {"(*SelectorExpr).End", Method, 0}, - {"(*SelectorExpr).Pos", Method, 0}, - {"(*SendStmt).End", Method, 0}, - {"(*SendStmt).Pos", Method, 0}, - {"(*SliceExpr).End", Method, 0}, - {"(*SliceExpr).Pos", Method, 0}, - {"(*StarExpr).End", Method, 0}, - {"(*StarExpr).Pos", Method, 0}, - {"(*StructType).End", Method, 0}, - {"(*StructType).Pos", Method, 0}, - {"(*SwitchStmt).End", Method, 0}, - {"(*SwitchStmt).Pos", Method, 0}, - {"(*TypeAssertExpr).End", Method, 0}, - {"(*TypeAssertExpr).Pos", Method, 0}, - {"(*TypeSpec).End", Method, 0}, - {"(*TypeSpec).Pos", Method, 0}, - {"(*TypeSwitchStmt).End", Method, 0}, - {"(*TypeSwitchStmt).Pos", Method, 0}, - {"(*UnaryExpr).End", Method, 0}, - {"(*UnaryExpr).Pos", Method, 0}, - {"(*ValueSpec).End", Method, 0}, - {"(*ValueSpec).Pos", Method, 0}, - {"(CommentMap).Comments", Method, 1}, - {"(CommentMap).Filter", Method, 1}, - {"(CommentMap).String", Method, 1}, - {"(CommentMap).Update", Method, 1}, - {"(ObjKind).String", Method, 0}, - {"ArrayType", Type, 0}, - {"ArrayType.Elt", Field, 0}, - {"ArrayType.Lbrack", Field, 0}, - {"ArrayType.Len", Field, 0}, - {"AssignStmt", Type, 0}, - {"AssignStmt.Lhs", Field, 0}, - {"AssignStmt.Rhs", Field, 0}, - {"AssignStmt.Tok", Field, 0}, - {"AssignStmt.TokPos", Field, 0}, - {"Bad", Const, 0}, - {"BadDecl", Type, 0}, - {"BadDecl.From", Field, 0}, - {"BadDecl.To", Field, 0}, - {"BadExpr", Type, 0}, - {"BadExpr.From", Field, 0}, - {"BadExpr.To", Field, 0}, - {"BadStmt", Type, 0}, - {"BadStmt.From", Field, 0}, - {"BadStmt.To", Field, 0}, - {"BasicLit", Type, 0}, - {"BasicLit.Kind", Field, 0}, - {"BasicLit.Value", Field, 0}, - {"BasicLit.ValuePos", Field, 0}, - {"BinaryExpr", Type, 0}, - {"BinaryExpr.Op", Field, 0}, - {"BinaryExpr.OpPos", Field, 0}, - {"BinaryExpr.X", Field, 0}, - {"BinaryExpr.Y", Field, 0}, - {"BlockStmt", Type, 0}, - {"BlockStmt.Lbrace", Field, 0}, - {"BlockStmt.List", Field, 0}, - {"BlockStmt.Rbrace", Field, 0}, - {"BranchStmt", Type, 0}, - {"BranchStmt.Label", Field, 0}, - {"BranchStmt.Tok", Field, 0}, - {"BranchStmt.TokPos", Field, 0}, - {"CallExpr", Type, 0}, - {"CallExpr.Args", Field, 0}, - {"CallExpr.Ellipsis", Field, 0}, - {"CallExpr.Fun", Field, 0}, - {"CallExpr.Lparen", Field, 0}, - {"CallExpr.Rparen", Field, 0}, - {"CaseClause", Type, 0}, - {"CaseClause.Body", Field, 0}, - {"CaseClause.Case", Field, 0}, - {"CaseClause.Colon", Field, 0}, - {"CaseClause.List", Field, 0}, - {"ChanDir", Type, 0}, - {"ChanType", Type, 0}, - {"ChanType.Arrow", Field, 1}, - {"ChanType.Begin", Field, 0}, - {"ChanType.Dir", Field, 0}, - {"ChanType.Value", Field, 0}, - {"CommClause", Type, 0}, - {"CommClause.Body", Field, 0}, - {"CommClause.Case", Field, 0}, - {"CommClause.Colon", Field, 0}, - {"CommClause.Comm", Field, 0}, - {"Comment", Type, 0}, - {"Comment.Slash", Field, 0}, - {"Comment.Text", Field, 0}, - {"CommentGroup", Type, 0}, - {"CommentGroup.List", Field, 0}, - {"CommentMap", Type, 1}, - {"CompositeLit", Type, 0}, - {"CompositeLit.Elts", Field, 0}, - {"CompositeLit.Incomplete", Field, 11}, - {"CompositeLit.Lbrace", Field, 0}, - {"CompositeLit.Rbrace", Field, 0}, - {"CompositeLit.Type", Field, 0}, - {"Con", Const, 0}, - {"Decl", Type, 0}, - {"DeclStmt", Type, 0}, - {"DeclStmt.Decl", Field, 0}, - {"DeferStmt", Type, 0}, - {"DeferStmt.Call", Field, 0}, - {"DeferStmt.Defer", Field, 0}, - {"Ellipsis", Type, 0}, - {"Ellipsis.Ellipsis", Field, 0}, - {"Ellipsis.Elt", Field, 0}, - {"EmptyStmt", Type, 0}, - {"EmptyStmt.Implicit", Field, 5}, - {"EmptyStmt.Semicolon", Field, 0}, - {"Expr", Type, 0}, - {"ExprStmt", Type, 0}, - {"ExprStmt.X", Field, 0}, - {"Field", Type, 0}, - {"Field.Comment", Field, 0}, - {"Field.Doc", Field, 0}, - {"Field.Names", Field, 0}, - {"Field.Tag", Field, 0}, - {"Field.Type", Field, 0}, - {"FieldFilter", Type, 0}, - {"FieldList", Type, 0}, - {"FieldList.Closing", Field, 0}, - {"FieldList.List", Field, 0}, - {"FieldList.Opening", Field, 0}, - {"File", Type, 0}, - {"File.Comments", Field, 0}, - {"File.Decls", Field, 0}, - {"File.Doc", Field, 0}, - {"File.FileEnd", Field, 20}, - {"File.FileStart", Field, 20}, - {"File.GoVersion", Field, 21}, - {"File.Imports", Field, 0}, - {"File.Name", Field, 0}, - {"File.Package", Field, 0}, - {"File.Scope", Field, 0}, - {"File.Unresolved", Field, 0}, - {"FileExports", Func, 0}, - {"Filter", Type, 0}, - {"FilterDecl", Func, 0}, - {"FilterFile", Func, 0}, - {"FilterFuncDuplicates", Const, 0}, - {"FilterImportDuplicates", Const, 0}, - {"FilterPackage", Func, 0}, - {"FilterUnassociatedComments", Const, 0}, - {"ForStmt", Type, 0}, - {"ForStmt.Body", Field, 0}, - {"ForStmt.Cond", Field, 0}, - {"ForStmt.For", Field, 0}, - {"ForStmt.Init", Field, 0}, - {"ForStmt.Post", Field, 0}, - {"Fprint", Func, 0}, - {"Fun", Const, 0}, - {"FuncDecl", Type, 0}, - {"FuncDecl.Body", Field, 0}, - {"FuncDecl.Doc", Field, 0}, - {"FuncDecl.Name", Field, 0}, - {"FuncDecl.Recv", Field, 0}, - {"FuncDecl.Type", Field, 0}, - {"FuncLit", Type, 0}, - {"FuncLit.Body", Field, 0}, - {"FuncLit.Type", Field, 0}, - {"FuncType", Type, 0}, - {"FuncType.Func", Field, 0}, - {"FuncType.Params", Field, 0}, - {"FuncType.Results", Field, 0}, - {"FuncType.TypeParams", Field, 18}, - {"GenDecl", Type, 0}, - {"GenDecl.Doc", Field, 0}, - {"GenDecl.Lparen", Field, 0}, - {"GenDecl.Rparen", Field, 0}, - {"GenDecl.Specs", Field, 0}, - {"GenDecl.Tok", Field, 0}, - {"GenDecl.TokPos", Field, 0}, - {"GoStmt", Type, 0}, - {"GoStmt.Call", Field, 0}, - {"GoStmt.Go", Field, 0}, - {"Ident", Type, 0}, - {"Ident.Name", Field, 0}, - {"Ident.NamePos", Field, 0}, - {"Ident.Obj", Field, 0}, - {"IfStmt", Type, 0}, - {"IfStmt.Body", Field, 0}, - {"IfStmt.Cond", Field, 0}, - {"IfStmt.Else", Field, 0}, - {"IfStmt.If", Field, 0}, - {"IfStmt.Init", Field, 0}, - {"ImportSpec", Type, 0}, - {"ImportSpec.Comment", Field, 0}, - {"ImportSpec.Doc", Field, 0}, - {"ImportSpec.EndPos", Field, 0}, - {"ImportSpec.Name", Field, 0}, - {"ImportSpec.Path", Field, 0}, - {"Importer", Type, 0}, - {"IncDecStmt", Type, 0}, - {"IncDecStmt.Tok", Field, 0}, - {"IncDecStmt.TokPos", Field, 0}, - {"IncDecStmt.X", Field, 0}, - {"IndexExpr", Type, 0}, - {"IndexExpr.Index", Field, 0}, - {"IndexExpr.Lbrack", Field, 0}, - {"IndexExpr.Rbrack", Field, 0}, - {"IndexExpr.X", Field, 0}, - {"IndexListExpr", Type, 18}, - {"IndexListExpr.Indices", Field, 18}, - {"IndexListExpr.Lbrack", Field, 18}, - {"IndexListExpr.Rbrack", Field, 18}, - {"IndexListExpr.X", Field, 18}, - {"Inspect", Func, 0}, - {"InterfaceType", Type, 0}, - {"InterfaceType.Incomplete", Field, 0}, - {"InterfaceType.Interface", Field, 0}, - {"InterfaceType.Methods", Field, 0}, - {"IsExported", Func, 0}, - {"IsGenerated", Func, 21}, - {"KeyValueExpr", Type, 0}, - {"KeyValueExpr.Colon", Field, 0}, - {"KeyValueExpr.Key", Field, 0}, - {"KeyValueExpr.Value", Field, 0}, - {"LabeledStmt", Type, 0}, - {"LabeledStmt.Colon", Field, 0}, - {"LabeledStmt.Label", Field, 0}, - {"LabeledStmt.Stmt", Field, 0}, - {"Lbl", Const, 0}, - {"MapType", Type, 0}, - {"MapType.Key", Field, 0}, - {"MapType.Map", Field, 0}, - {"MapType.Value", Field, 0}, - {"MergeMode", Type, 0}, - {"MergePackageFiles", Func, 0}, - {"NewCommentMap", Func, 1}, - {"NewIdent", Func, 0}, - {"NewObj", Func, 0}, - {"NewPackage", Func, 0}, - {"NewScope", Func, 0}, - {"Node", Type, 0}, - {"NotNilFilter", Func, 0}, - {"ObjKind", Type, 0}, - {"Object", Type, 0}, - {"Object.Data", Field, 0}, - {"Object.Decl", Field, 0}, - {"Object.Kind", Field, 0}, - {"Object.Name", Field, 0}, - {"Object.Type", Field, 0}, - {"Package", Type, 0}, - {"Package.Files", Field, 0}, - {"Package.Imports", Field, 0}, - {"Package.Name", Field, 0}, - {"Package.Scope", Field, 0}, - {"PackageExports", Func, 0}, - {"ParenExpr", Type, 0}, - {"ParenExpr.Lparen", Field, 0}, - {"ParenExpr.Rparen", Field, 0}, - {"ParenExpr.X", Field, 0}, - {"Pkg", Const, 0}, - {"Preorder", Func, 23}, - {"Print", Func, 0}, - {"RECV", Const, 0}, - {"RangeStmt", Type, 0}, - {"RangeStmt.Body", Field, 0}, - {"RangeStmt.For", Field, 0}, - {"RangeStmt.Key", Field, 0}, - {"RangeStmt.Range", Field, 20}, - {"RangeStmt.Tok", Field, 0}, - {"RangeStmt.TokPos", Field, 0}, - {"RangeStmt.Value", Field, 0}, - {"RangeStmt.X", Field, 0}, - {"ReturnStmt", Type, 0}, - {"ReturnStmt.Results", Field, 0}, - {"ReturnStmt.Return", Field, 0}, - {"SEND", Const, 0}, - {"Scope", Type, 0}, - {"Scope.Objects", Field, 0}, - {"Scope.Outer", Field, 0}, - {"SelectStmt", Type, 0}, - {"SelectStmt.Body", Field, 0}, - {"SelectStmt.Select", Field, 0}, - {"SelectorExpr", Type, 0}, - {"SelectorExpr.Sel", Field, 0}, - {"SelectorExpr.X", Field, 0}, - {"SendStmt", Type, 0}, - {"SendStmt.Arrow", Field, 0}, - {"SendStmt.Chan", Field, 0}, - {"SendStmt.Value", Field, 0}, - {"SliceExpr", Type, 0}, - {"SliceExpr.High", Field, 0}, - {"SliceExpr.Lbrack", Field, 0}, - {"SliceExpr.Low", Field, 0}, - {"SliceExpr.Max", Field, 2}, - {"SliceExpr.Rbrack", Field, 0}, - {"SliceExpr.Slice3", Field, 2}, - {"SliceExpr.X", Field, 0}, - {"SortImports", Func, 0}, - {"Spec", Type, 0}, - {"StarExpr", Type, 0}, - {"StarExpr.Star", Field, 0}, - {"StarExpr.X", Field, 0}, - {"Stmt", Type, 0}, - {"StructType", Type, 0}, - {"StructType.Fields", Field, 0}, - {"StructType.Incomplete", Field, 0}, - {"StructType.Struct", Field, 0}, - {"SwitchStmt", Type, 0}, - {"SwitchStmt.Body", Field, 0}, - {"SwitchStmt.Init", Field, 0}, - {"SwitchStmt.Switch", Field, 0}, - {"SwitchStmt.Tag", Field, 0}, - {"Typ", Const, 0}, - {"TypeAssertExpr", Type, 0}, - {"TypeAssertExpr.Lparen", Field, 2}, - {"TypeAssertExpr.Rparen", Field, 2}, - {"TypeAssertExpr.Type", Field, 0}, - {"TypeAssertExpr.X", Field, 0}, - {"TypeSpec", Type, 0}, - {"TypeSpec.Assign", Field, 9}, - {"TypeSpec.Comment", Field, 0}, - {"TypeSpec.Doc", Field, 0}, - {"TypeSpec.Name", Field, 0}, - {"TypeSpec.Type", Field, 0}, - {"TypeSpec.TypeParams", Field, 18}, - {"TypeSwitchStmt", Type, 0}, - {"TypeSwitchStmt.Assign", Field, 0}, - {"TypeSwitchStmt.Body", Field, 0}, - {"TypeSwitchStmt.Init", Field, 0}, - {"TypeSwitchStmt.Switch", Field, 0}, - {"UnaryExpr", Type, 0}, - {"UnaryExpr.Op", Field, 0}, - {"UnaryExpr.OpPos", Field, 0}, - {"UnaryExpr.X", Field, 0}, - {"Unparen", Func, 22}, - {"ValueSpec", Type, 0}, - {"ValueSpec.Comment", Field, 0}, - {"ValueSpec.Doc", Field, 0}, - {"ValueSpec.Names", Field, 0}, - {"ValueSpec.Type", Field, 0}, - {"ValueSpec.Values", Field, 0}, - {"Var", Const, 0}, - {"Visitor", Type, 0}, - {"Walk", Func, 0}, - }, - "go/build": { - {"(*Context).Import", Method, 0}, - {"(*Context).ImportDir", Method, 0}, - {"(*Context).MatchFile", Method, 2}, - {"(*Context).SrcDirs", Method, 0}, - {"(*MultiplePackageError).Error", Method, 4}, - {"(*NoGoError).Error", Method, 0}, - {"(*Package).IsCommand", Method, 0}, - {"AllowBinary", Const, 0}, - {"ArchChar", Func, 0}, - {"Context", Type, 0}, - {"Context.BuildTags", Field, 0}, - {"Context.CgoEnabled", Field, 0}, - {"Context.Compiler", Field, 0}, - {"Context.Dir", Field, 14}, - {"Context.GOARCH", Field, 0}, - {"Context.GOOS", Field, 0}, - {"Context.GOPATH", Field, 0}, - {"Context.GOROOT", Field, 0}, - {"Context.HasSubdir", Field, 0}, - {"Context.InstallSuffix", Field, 1}, - {"Context.IsAbsPath", Field, 0}, - {"Context.IsDir", Field, 0}, - {"Context.JoinPath", Field, 0}, - {"Context.OpenFile", Field, 0}, - {"Context.ReadDir", Field, 0}, - {"Context.ReleaseTags", Field, 1}, - {"Context.SplitPathList", Field, 0}, - {"Context.ToolTags", Field, 17}, - {"Context.UseAllFiles", Field, 0}, - {"Default", Var, 0}, - {"Directive", Type, 21}, - {"Directive.Pos", Field, 21}, - {"Directive.Text", Field, 21}, - {"FindOnly", Const, 0}, - {"IgnoreVendor", Const, 6}, - {"Import", Func, 0}, - {"ImportComment", Const, 4}, - {"ImportDir", Func, 0}, - {"ImportMode", Type, 0}, - {"IsLocalImport", Func, 0}, - {"MultiplePackageError", Type, 4}, - {"MultiplePackageError.Dir", Field, 4}, - {"MultiplePackageError.Files", Field, 4}, - {"MultiplePackageError.Packages", Field, 4}, - {"NoGoError", Type, 0}, - {"NoGoError.Dir", Field, 0}, - {"Package", Type, 0}, - {"Package.AllTags", Field, 2}, - {"Package.BinDir", Field, 0}, - {"Package.BinaryOnly", Field, 7}, - {"Package.CFiles", Field, 0}, - {"Package.CXXFiles", Field, 2}, - {"Package.CgoCFLAGS", Field, 0}, - {"Package.CgoCPPFLAGS", Field, 2}, - {"Package.CgoCXXFLAGS", Field, 2}, - {"Package.CgoFFLAGS", Field, 7}, - {"Package.CgoFiles", Field, 0}, - {"Package.CgoLDFLAGS", Field, 0}, - {"Package.CgoPkgConfig", Field, 0}, - {"Package.ConflictDir", Field, 2}, - {"Package.Dir", Field, 0}, - {"Package.Directives", Field, 21}, - {"Package.Doc", Field, 0}, - {"Package.EmbedPatternPos", Field, 16}, - {"Package.EmbedPatterns", Field, 16}, - {"Package.FFiles", Field, 7}, - {"Package.GoFiles", Field, 0}, - {"Package.Goroot", Field, 0}, - {"Package.HFiles", Field, 0}, - {"Package.IgnoredGoFiles", Field, 1}, - {"Package.IgnoredOtherFiles", Field, 16}, - {"Package.ImportComment", Field, 4}, - {"Package.ImportPath", Field, 0}, - {"Package.ImportPos", Field, 0}, - {"Package.Imports", Field, 0}, - {"Package.InvalidGoFiles", Field, 6}, - {"Package.MFiles", Field, 3}, - {"Package.Name", Field, 0}, - {"Package.PkgObj", Field, 0}, - {"Package.PkgRoot", Field, 0}, - {"Package.PkgTargetRoot", Field, 5}, - {"Package.Root", Field, 0}, - {"Package.SFiles", Field, 0}, - {"Package.SrcRoot", Field, 0}, - {"Package.SwigCXXFiles", Field, 1}, - {"Package.SwigFiles", Field, 1}, - {"Package.SysoFiles", Field, 0}, - {"Package.TestDirectives", Field, 21}, - {"Package.TestEmbedPatternPos", Field, 16}, - {"Package.TestEmbedPatterns", Field, 16}, - {"Package.TestGoFiles", Field, 0}, - {"Package.TestImportPos", Field, 0}, - {"Package.TestImports", Field, 0}, - {"Package.XTestDirectives", Field, 21}, - {"Package.XTestEmbedPatternPos", Field, 16}, - {"Package.XTestEmbedPatterns", Field, 16}, - {"Package.XTestGoFiles", Field, 0}, - {"Package.XTestImportPos", Field, 0}, - {"Package.XTestImports", Field, 0}, - {"ToolDir", Var, 0}, - }, - "go/build/constraint": { - {"(*AndExpr).Eval", Method, 16}, - {"(*AndExpr).String", Method, 16}, - {"(*NotExpr).Eval", Method, 16}, - {"(*NotExpr).String", Method, 16}, - {"(*OrExpr).Eval", Method, 16}, - {"(*OrExpr).String", Method, 16}, - {"(*SyntaxError).Error", Method, 16}, - {"(*TagExpr).Eval", Method, 16}, - {"(*TagExpr).String", Method, 16}, - {"AndExpr", Type, 16}, - {"AndExpr.X", Field, 16}, - {"AndExpr.Y", Field, 16}, - {"Expr", Type, 16}, - {"GoVersion", Func, 21}, - {"IsGoBuild", Func, 16}, - {"IsPlusBuild", Func, 16}, - {"NotExpr", Type, 16}, - {"NotExpr.X", Field, 16}, - {"OrExpr", Type, 16}, - {"OrExpr.X", Field, 16}, - {"OrExpr.Y", Field, 16}, - {"Parse", Func, 16}, - {"PlusBuildLines", Func, 16}, - {"SyntaxError", Type, 16}, - {"SyntaxError.Err", Field, 16}, - {"SyntaxError.Offset", Field, 16}, - {"TagExpr", Type, 16}, - {"TagExpr.Tag", Field, 16}, - }, - "go/constant": { - {"(Kind).String", Method, 18}, - {"BinaryOp", Func, 5}, - {"BitLen", Func, 5}, - {"Bool", Const, 5}, - {"BoolVal", Func, 5}, - {"Bytes", Func, 5}, - {"Compare", Func, 5}, - {"Complex", Const, 5}, - {"Denom", Func, 5}, - {"Float", Const, 5}, - {"Float32Val", Func, 5}, - {"Float64Val", Func, 5}, - {"Imag", Func, 5}, - {"Int", Const, 5}, - {"Int64Val", Func, 5}, - {"Kind", Type, 5}, - {"Make", Func, 13}, - {"MakeBool", Func, 5}, - {"MakeFloat64", Func, 5}, - {"MakeFromBytes", Func, 5}, - {"MakeFromLiteral", Func, 5}, - {"MakeImag", Func, 5}, - {"MakeInt64", Func, 5}, - {"MakeString", Func, 5}, - {"MakeUint64", Func, 5}, - {"MakeUnknown", Func, 5}, - {"Num", Func, 5}, - {"Real", Func, 5}, - {"Shift", Func, 5}, - {"Sign", Func, 5}, - {"String", Const, 5}, - {"StringVal", Func, 5}, - {"ToComplex", Func, 6}, - {"ToFloat", Func, 6}, - {"ToInt", Func, 6}, - {"Uint64Val", Func, 5}, - {"UnaryOp", Func, 5}, - {"Unknown", Const, 5}, - {"Val", Func, 13}, - {"Value", Type, 5}, - }, - "go/doc": { - {"(*Package).Filter", Method, 0}, - {"(*Package).HTML", Method, 19}, - {"(*Package).Markdown", Method, 19}, - {"(*Package).Parser", Method, 19}, - {"(*Package).Printer", Method, 19}, - {"(*Package).Synopsis", Method, 19}, - {"(*Package).Text", Method, 19}, - {"AllDecls", Const, 0}, - {"AllMethods", Const, 0}, - {"Example", Type, 0}, - {"Example.Code", Field, 0}, - {"Example.Comments", Field, 0}, - {"Example.Doc", Field, 0}, - {"Example.EmptyOutput", Field, 1}, - {"Example.Name", Field, 0}, - {"Example.Order", Field, 1}, - {"Example.Output", Field, 0}, - {"Example.Play", Field, 1}, - {"Example.Suffix", Field, 14}, - {"Example.Unordered", Field, 7}, - {"Examples", Func, 0}, - {"Filter", Type, 0}, - {"Func", Type, 0}, - {"Func.Decl", Field, 0}, - {"Func.Doc", Field, 0}, - {"Func.Examples", Field, 14}, - {"Func.Level", Field, 0}, - {"Func.Name", Field, 0}, - {"Func.Orig", Field, 0}, - {"Func.Recv", Field, 0}, - {"IllegalPrefixes", Var, 1}, - {"IsPredeclared", Func, 8}, - {"Mode", Type, 0}, - {"New", Func, 0}, - {"NewFromFiles", Func, 14}, - {"Note", Type, 1}, - {"Note.Body", Field, 1}, - {"Note.End", Field, 1}, - {"Note.Pos", Field, 1}, - {"Note.UID", Field, 1}, - {"Package", Type, 0}, - {"Package.Bugs", Field, 0}, - {"Package.Consts", Field, 0}, - {"Package.Doc", Field, 0}, - {"Package.Examples", Field, 14}, - {"Package.Filenames", Field, 0}, - {"Package.Funcs", Field, 0}, - {"Package.ImportPath", Field, 0}, - {"Package.Imports", Field, 0}, - {"Package.Name", Field, 0}, - {"Package.Notes", Field, 1}, - {"Package.Types", Field, 0}, - {"Package.Vars", Field, 0}, - {"PreserveAST", Const, 12}, - {"Synopsis", Func, 0}, - {"ToHTML", Func, 0}, - {"ToText", Func, 0}, - {"Type", Type, 0}, - {"Type.Consts", Field, 0}, - {"Type.Decl", Field, 0}, - {"Type.Doc", Field, 0}, - {"Type.Examples", Field, 14}, - {"Type.Funcs", Field, 0}, - {"Type.Methods", Field, 0}, - {"Type.Name", Field, 0}, - {"Type.Vars", Field, 0}, - {"Value", Type, 0}, - {"Value.Decl", Field, 0}, - {"Value.Doc", Field, 0}, - {"Value.Names", Field, 0}, - }, - "go/doc/comment": { - {"(*DocLink).DefaultURL", Method, 19}, - {"(*Heading).DefaultID", Method, 19}, - {"(*List).BlankBefore", Method, 19}, - {"(*List).BlankBetween", Method, 19}, - {"(*Parser).Parse", Method, 19}, - {"(*Printer).Comment", Method, 19}, - {"(*Printer).HTML", Method, 19}, - {"(*Printer).Markdown", Method, 19}, - {"(*Printer).Text", Method, 19}, - {"Block", Type, 19}, - {"Code", Type, 19}, - {"Code.Text", Field, 19}, - {"DefaultLookupPackage", Func, 19}, - {"Doc", Type, 19}, - {"Doc.Content", Field, 19}, - {"Doc.Links", Field, 19}, - {"DocLink", Type, 19}, - {"DocLink.ImportPath", Field, 19}, - {"DocLink.Name", Field, 19}, - {"DocLink.Recv", Field, 19}, - {"DocLink.Text", Field, 19}, - {"Heading", Type, 19}, - {"Heading.Text", Field, 19}, - {"Italic", Type, 19}, - {"Link", Type, 19}, - {"Link.Auto", Field, 19}, - {"Link.Text", Field, 19}, - {"Link.URL", Field, 19}, - {"LinkDef", Type, 19}, - {"LinkDef.Text", Field, 19}, - {"LinkDef.URL", Field, 19}, - {"LinkDef.Used", Field, 19}, - {"List", Type, 19}, - {"List.ForceBlankBefore", Field, 19}, - {"List.ForceBlankBetween", Field, 19}, - {"List.Items", Field, 19}, - {"ListItem", Type, 19}, - {"ListItem.Content", Field, 19}, - {"ListItem.Number", Field, 19}, - {"Paragraph", Type, 19}, - {"Paragraph.Text", Field, 19}, - {"Parser", Type, 19}, - {"Parser.LookupPackage", Field, 19}, - {"Parser.LookupSym", Field, 19}, - {"Parser.Words", Field, 19}, - {"Plain", Type, 19}, - {"Printer", Type, 19}, - {"Printer.DocLinkBaseURL", Field, 19}, - {"Printer.DocLinkURL", Field, 19}, - {"Printer.HeadingID", Field, 19}, - {"Printer.HeadingLevel", Field, 19}, - {"Printer.TextCodePrefix", Field, 19}, - {"Printer.TextPrefix", Field, 19}, - {"Printer.TextWidth", Field, 19}, - {"Text", Type, 19}, - }, - "go/format": { - {"Node", Func, 1}, - {"Source", Func, 1}, - }, - "go/importer": { - {"Default", Func, 5}, - {"For", Func, 5}, - {"ForCompiler", Func, 12}, - {"Lookup", Type, 5}, - }, - "go/parser": { - {"AllErrors", Const, 1}, - {"DeclarationErrors", Const, 0}, - {"ImportsOnly", Const, 0}, - {"Mode", Type, 0}, - {"PackageClauseOnly", Const, 0}, - {"ParseComments", Const, 0}, - {"ParseDir", Func, 0}, - {"ParseExpr", Func, 0}, - {"ParseExprFrom", Func, 5}, - {"ParseFile", Func, 0}, - {"SkipObjectResolution", Const, 17}, - {"SpuriousErrors", Const, 0}, - {"Trace", Const, 0}, - }, - "go/printer": { - {"(*Config).Fprint", Method, 0}, - {"CommentedNode", Type, 0}, - {"CommentedNode.Comments", Field, 0}, - {"CommentedNode.Node", Field, 0}, - {"Config", Type, 0}, - {"Config.Indent", Field, 1}, - {"Config.Mode", Field, 0}, - {"Config.Tabwidth", Field, 0}, - {"Fprint", Func, 0}, - {"Mode", Type, 0}, - {"RawFormat", Const, 0}, - {"SourcePos", Const, 0}, - {"TabIndent", Const, 0}, - {"UseSpaces", Const, 0}, - }, - "go/scanner": { - {"(*ErrorList).Add", Method, 0}, - {"(*ErrorList).RemoveMultiples", Method, 0}, - {"(*ErrorList).Reset", Method, 0}, - {"(*Scanner).Init", Method, 0}, - {"(*Scanner).Scan", Method, 0}, - {"(Error).Error", Method, 0}, - {"(ErrorList).Err", Method, 0}, - {"(ErrorList).Error", Method, 0}, - {"(ErrorList).Len", Method, 0}, - {"(ErrorList).Less", Method, 0}, - {"(ErrorList).Sort", Method, 0}, - {"(ErrorList).Swap", Method, 0}, - {"Error", Type, 0}, - {"Error.Msg", Field, 0}, - {"Error.Pos", Field, 0}, - {"ErrorHandler", Type, 0}, - {"ErrorList", Type, 0}, - {"Mode", Type, 0}, - {"PrintError", Func, 0}, - {"ScanComments", Const, 0}, - {"Scanner", Type, 0}, - {"Scanner.ErrorCount", Field, 0}, - }, - "go/token": { - {"(*File).AddLine", Method, 0}, - {"(*File).AddLineColumnInfo", Method, 11}, - {"(*File).AddLineInfo", Method, 0}, - {"(*File).Base", Method, 0}, - {"(*File).Line", Method, 0}, - {"(*File).LineCount", Method, 0}, - {"(*File).LineStart", Method, 12}, - {"(*File).Lines", Method, 21}, - {"(*File).MergeLine", Method, 2}, - {"(*File).Name", Method, 0}, - {"(*File).Offset", Method, 0}, - {"(*File).Pos", Method, 0}, - {"(*File).Position", Method, 0}, - {"(*File).PositionFor", Method, 4}, - {"(*File).SetLines", Method, 0}, - {"(*File).SetLinesForContent", Method, 0}, - {"(*File).Size", Method, 0}, - {"(*FileSet).AddFile", Method, 0}, - {"(*FileSet).Base", Method, 0}, - {"(*FileSet).File", Method, 0}, - {"(*FileSet).Iterate", Method, 0}, - {"(*FileSet).Position", Method, 0}, - {"(*FileSet).PositionFor", Method, 4}, - {"(*FileSet).Read", Method, 0}, - {"(*FileSet).RemoveFile", Method, 20}, - {"(*FileSet).Write", Method, 0}, - {"(*Position).IsValid", Method, 0}, - {"(Pos).IsValid", Method, 0}, - {"(Position).String", Method, 0}, - {"(Token).IsKeyword", Method, 0}, - {"(Token).IsLiteral", Method, 0}, - {"(Token).IsOperator", Method, 0}, - {"(Token).Precedence", Method, 0}, - {"(Token).String", Method, 0}, - {"ADD", Const, 0}, - {"ADD_ASSIGN", Const, 0}, - {"AND", Const, 0}, - {"AND_ASSIGN", Const, 0}, - {"AND_NOT", Const, 0}, - {"AND_NOT_ASSIGN", Const, 0}, - {"ARROW", Const, 0}, - {"ASSIGN", Const, 0}, - {"BREAK", Const, 0}, - {"CASE", Const, 0}, - {"CHAN", Const, 0}, - {"CHAR", Const, 0}, - {"COLON", Const, 0}, - {"COMMA", Const, 0}, - {"COMMENT", Const, 0}, - {"CONST", Const, 0}, - {"CONTINUE", Const, 0}, - {"DEC", Const, 0}, - {"DEFAULT", Const, 0}, - {"DEFER", Const, 0}, - {"DEFINE", Const, 0}, - {"ELLIPSIS", Const, 0}, - {"ELSE", Const, 0}, - {"EOF", Const, 0}, - {"EQL", Const, 0}, - {"FALLTHROUGH", Const, 0}, - {"FLOAT", Const, 0}, - {"FOR", Const, 0}, - {"FUNC", Const, 0}, - {"File", Type, 0}, - {"FileSet", Type, 0}, - {"GEQ", Const, 0}, - {"GO", Const, 0}, - {"GOTO", Const, 0}, - {"GTR", Const, 0}, - {"HighestPrec", Const, 0}, - {"IDENT", Const, 0}, - {"IF", Const, 0}, - {"ILLEGAL", Const, 0}, - {"IMAG", Const, 0}, - {"IMPORT", Const, 0}, - {"INC", Const, 0}, - {"INT", Const, 0}, - {"INTERFACE", Const, 0}, - {"IsExported", Func, 13}, - {"IsIdentifier", Func, 13}, - {"IsKeyword", Func, 13}, - {"LAND", Const, 0}, - {"LBRACE", Const, 0}, - {"LBRACK", Const, 0}, - {"LEQ", Const, 0}, - {"LOR", Const, 0}, - {"LPAREN", Const, 0}, - {"LSS", Const, 0}, - {"Lookup", Func, 0}, - {"LowestPrec", Const, 0}, - {"MAP", Const, 0}, - {"MUL", Const, 0}, - {"MUL_ASSIGN", Const, 0}, - {"NEQ", Const, 0}, - {"NOT", Const, 0}, - {"NewFileSet", Func, 0}, - {"NoPos", Const, 0}, - {"OR", Const, 0}, - {"OR_ASSIGN", Const, 0}, - {"PACKAGE", Const, 0}, - {"PERIOD", Const, 0}, - {"Pos", Type, 0}, - {"Position", Type, 0}, - {"Position.Column", Field, 0}, - {"Position.Filename", Field, 0}, - {"Position.Line", Field, 0}, - {"Position.Offset", Field, 0}, - {"QUO", Const, 0}, - {"QUO_ASSIGN", Const, 0}, - {"RANGE", Const, 0}, - {"RBRACE", Const, 0}, - {"RBRACK", Const, 0}, - {"REM", Const, 0}, - {"REM_ASSIGN", Const, 0}, - {"RETURN", Const, 0}, - {"RPAREN", Const, 0}, - {"SELECT", Const, 0}, - {"SEMICOLON", Const, 0}, - {"SHL", Const, 0}, - {"SHL_ASSIGN", Const, 0}, - {"SHR", Const, 0}, - {"SHR_ASSIGN", Const, 0}, - {"STRING", Const, 0}, - {"STRUCT", Const, 0}, - {"SUB", Const, 0}, - {"SUB_ASSIGN", Const, 0}, - {"SWITCH", Const, 0}, - {"TILDE", Const, 18}, - {"TYPE", Const, 0}, - {"Token", Type, 0}, - {"UnaryPrec", Const, 0}, - {"VAR", Const, 0}, - {"XOR", Const, 0}, - {"XOR_ASSIGN", Const, 0}, - }, - "go/types": { - {"(*Alias).Obj", Method, 22}, - {"(*Alias).Origin", Method, 23}, - {"(*Alias).Rhs", Method, 23}, - {"(*Alias).SetTypeParams", Method, 23}, - {"(*Alias).String", Method, 22}, - {"(*Alias).TypeArgs", Method, 23}, - {"(*Alias).TypeParams", Method, 23}, - {"(*Alias).Underlying", Method, 22}, - {"(*ArgumentError).Error", Method, 18}, - {"(*ArgumentError).Unwrap", Method, 18}, - {"(*Array).Elem", Method, 5}, - {"(*Array).Len", Method, 5}, - {"(*Array).String", Method, 5}, - {"(*Array).Underlying", Method, 5}, - {"(*Basic).Info", Method, 5}, - {"(*Basic).Kind", Method, 5}, - {"(*Basic).Name", Method, 5}, - {"(*Basic).String", Method, 5}, - {"(*Basic).Underlying", Method, 5}, - {"(*Builtin).Exported", Method, 5}, - {"(*Builtin).Id", Method, 5}, - {"(*Builtin).Name", Method, 5}, - {"(*Builtin).Parent", Method, 5}, - {"(*Builtin).Pkg", Method, 5}, - {"(*Builtin).Pos", Method, 5}, - {"(*Builtin).String", Method, 5}, - {"(*Builtin).Type", Method, 5}, - {"(*Chan).Dir", Method, 5}, - {"(*Chan).Elem", Method, 5}, - {"(*Chan).String", Method, 5}, - {"(*Chan).Underlying", Method, 5}, - {"(*Checker).Files", Method, 5}, - {"(*Config).Check", Method, 5}, - {"(*Const).Exported", Method, 5}, - {"(*Const).Id", Method, 5}, - {"(*Const).Name", Method, 5}, - {"(*Const).Parent", Method, 5}, - {"(*Const).Pkg", Method, 5}, - {"(*Const).Pos", Method, 5}, - {"(*Const).String", Method, 5}, - {"(*Const).Type", Method, 5}, - {"(*Const).Val", Method, 5}, - {"(*Func).Exported", Method, 5}, - {"(*Func).FullName", Method, 5}, - {"(*Func).Id", Method, 5}, - {"(*Func).Name", Method, 5}, - {"(*Func).Origin", Method, 19}, - {"(*Func).Parent", Method, 5}, - {"(*Func).Pkg", Method, 5}, - {"(*Func).Pos", Method, 5}, - {"(*Func).Scope", Method, 5}, - {"(*Func).Signature", Method, 23}, - {"(*Func).String", Method, 5}, - {"(*Func).Type", Method, 5}, - {"(*Info).ObjectOf", Method, 5}, - {"(*Info).PkgNameOf", Method, 22}, - {"(*Info).TypeOf", Method, 5}, - {"(*Initializer).String", Method, 5}, - {"(*Interface).Complete", Method, 5}, - {"(*Interface).Embedded", Method, 5}, - {"(*Interface).EmbeddedType", Method, 11}, - {"(*Interface).EmbeddedTypes", Method, 24}, - {"(*Interface).Empty", Method, 5}, - {"(*Interface).ExplicitMethod", Method, 5}, - {"(*Interface).ExplicitMethods", Method, 24}, - {"(*Interface).IsComparable", Method, 18}, - {"(*Interface).IsImplicit", Method, 18}, - {"(*Interface).IsMethodSet", Method, 18}, - {"(*Interface).MarkImplicit", Method, 18}, - {"(*Interface).Method", Method, 5}, - {"(*Interface).Methods", Method, 24}, - {"(*Interface).NumEmbeddeds", Method, 5}, - {"(*Interface).NumExplicitMethods", Method, 5}, - {"(*Interface).NumMethods", Method, 5}, - {"(*Interface).String", Method, 5}, - {"(*Interface).Underlying", Method, 5}, - {"(*Label).Exported", Method, 5}, - {"(*Label).Id", Method, 5}, - {"(*Label).Name", Method, 5}, - {"(*Label).Parent", Method, 5}, - {"(*Label).Pkg", Method, 5}, - {"(*Label).Pos", Method, 5}, - {"(*Label).String", Method, 5}, - {"(*Label).Type", Method, 5}, - {"(*Map).Elem", Method, 5}, - {"(*Map).Key", Method, 5}, - {"(*Map).String", Method, 5}, - {"(*Map).Underlying", Method, 5}, - {"(*MethodSet).At", Method, 5}, - {"(*MethodSet).Len", Method, 5}, - {"(*MethodSet).Lookup", Method, 5}, - {"(*MethodSet).Methods", Method, 24}, - {"(*MethodSet).String", Method, 5}, - {"(*Named).AddMethod", Method, 5}, - {"(*Named).Method", Method, 5}, - {"(*Named).Methods", Method, 24}, - {"(*Named).NumMethods", Method, 5}, - {"(*Named).Obj", Method, 5}, - {"(*Named).Origin", Method, 18}, - {"(*Named).SetTypeParams", Method, 18}, - {"(*Named).SetUnderlying", Method, 5}, - {"(*Named).String", Method, 5}, - {"(*Named).TypeArgs", Method, 18}, - {"(*Named).TypeParams", Method, 18}, - {"(*Named).Underlying", Method, 5}, - {"(*Nil).Exported", Method, 5}, - {"(*Nil).Id", Method, 5}, - {"(*Nil).Name", Method, 5}, - {"(*Nil).Parent", Method, 5}, - {"(*Nil).Pkg", Method, 5}, - {"(*Nil).Pos", Method, 5}, - {"(*Nil).String", Method, 5}, - {"(*Nil).Type", Method, 5}, - {"(*Package).Complete", Method, 5}, - {"(*Package).GoVersion", Method, 21}, - {"(*Package).Imports", Method, 5}, - {"(*Package).MarkComplete", Method, 5}, - {"(*Package).Name", Method, 5}, - {"(*Package).Path", Method, 5}, - {"(*Package).Scope", Method, 5}, - {"(*Package).SetImports", Method, 5}, - {"(*Package).SetName", Method, 6}, - {"(*Package).String", Method, 5}, - {"(*PkgName).Exported", Method, 5}, - {"(*PkgName).Id", Method, 5}, - {"(*PkgName).Imported", Method, 5}, - {"(*PkgName).Name", Method, 5}, - {"(*PkgName).Parent", Method, 5}, - {"(*PkgName).Pkg", Method, 5}, - {"(*PkgName).Pos", Method, 5}, - {"(*PkgName).String", Method, 5}, - {"(*PkgName).Type", Method, 5}, - {"(*Pointer).Elem", Method, 5}, - {"(*Pointer).String", Method, 5}, - {"(*Pointer).Underlying", Method, 5}, - {"(*Scope).Child", Method, 5}, - {"(*Scope).Children", Method, 24}, - {"(*Scope).Contains", Method, 5}, - {"(*Scope).End", Method, 5}, - {"(*Scope).Innermost", Method, 5}, - {"(*Scope).Insert", Method, 5}, - {"(*Scope).Len", Method, 5}, - {"(*Scope).Lookup", Method, 5}, - {"(*Scope).LookupParent", Method, 5}, - {"(*Scope).Names", Method, 5}, - {"(*Scope).NumChildren", Method, 5}, - {"(*Scope).Parent", Method, 5}, - {"(*Scope).Pos", Method, 5}, - {"(*Scope).String", Method, 5}, - {"(*Scope).WriteTo", Method, 5}, - {"(*Selection).Index", Method, 5}, - {"(*Selection).Indirect", Method, 5}, - {"(*Selection).Kind", Method, 5}, - {"(*Selection).Obj", Method, 5}, - {"(*Selection).Recv", Method, 5}, - {"(*Selection).String", Method, 5}, - {"(*Selection).Type", Method, 5}, - {"(*Signature).Params", Method, 5}, - {"(*Signature).Recv", Method, 5}, - {"(*Signature).RecvTypeParams", Method, 18}, - {"(*Signature).Results", Method, 5}, - {"(*Signature).String", Method, 5}, - {"(*Signature).TypeParams", Method, 18}, - {"(*Signature).Underlying", Method, 5}, - {"(*Signature).Variadic", Method, 5}, - {"(*Slice).Elem", Method, 5}, - {"(*Slice).String", Method, 5}, - {"(*Slice).Underlying", Method, 5}, - {"(*StdSizes).Alignof", Method, 5}, - {"(*StdSizes).Offsetsof", Method, 5}, - {"(*StdSizes).Sizeof", Method, 5}, - {"(*Struct).Field", Method, 5}, - {"(*Struct).Fields", Method, 24}, - {"(*Struct).NumFields", Method, 5}, - {"(*Struct).String", Method, 5}, - {"(*Struct).Tag", Method, 5}, - {"(*Struct).Underlying", Method, 5}, - {"(*Term).String", Method, 18}, - {"(*Term).Tilde", Method, 18}, - {"(*Term).Type", Method, 18}, - {"(*Tuple).At", Method, 5}, - {"(*Tuple).Len", Method, 5}, - {"(*Tuple).String", Method, 5}, - {"(*Tuple).Underlying", Method, 5}, - {"(*Tuple).Variables", Method, 24}, - {"(*TypeList).At", Method, 18}, - {"(*TypeList).Len", Method, 18}, - {"(*TypeList).Types", Method, 24}, - {"(*TypeName).Exported", Method, 5}, - {"(*TypeName).Id", Method, 5}, - {"(*TypeName).IsAlias", Method, 9}, - {"(*TypeName).Name", Method, 5}, - {"(*TypeName).Parent", Method, 5}, - {"(*TypeName).Pkg", Method, 5}, - {"(*TypeName).Pos", Method, 5}, - {"(*TypeName).String", Method, 5}, - {"(*TypeName).Type", Method, 5}, - {"(*TypeParam).Constraint", Method, 18}, - {"(*TypeParam).Index", Method, 18}, - {"(*TypeParam).Obj", Method, 18}, - {"(*TypeParam).SetConstraint", Method, 18}, - {"(*TypeParam).String", Method, 18}, - {"(*TypeParam).Underlying", Method, 18}, - {"(*TypeParamList).At", Method, 18}, - {"(*TypeParamList).Len", Method, 18}, - {"(*TypeParamList).TypeParams", Method, 24}, - {"(*Union).Len", Method, 18}, - {"(*Union).String", Method, 18}, - {"(*Union).Term", Method, 18}, - {"(*Union).Terms", Method, 24}, - {"(*Union).Underlying", Method, 18}, - {"(*Var).Anonymous", Method, 5}, - {"(*Var).Embedded", Method, 11}, - {"(*Var).Exported", Method, 5}, - {"(*Var).Id", Method, 5}, - {"(*Var).IsField", Method, 5}, - {"(*Var).Name", Method, 5}, - {"(*Var).Origin", Method, 19}, - {"(*Var).Parent", Method, 5}, - {"(*Var).Pkg", Method, 5}, - {"(*Var).Pos", Method, 5}, - {"(*Var).String", Method, 5}, - {"(*Var).Type", Method, 5}, - {"(Checker).ObjectOf", Method, 5}, - {"(Checker).PkgNameOf", Method, 22}, - {"(Checker).TypeOf", Method, 5}, - {"(Error).Error", Method, 5}, - {"(TypeAndValue).Addressable", Method, 5}, - {"(TypeAndValue).Assignable", Method, 5}, - {"(TypeAndValue).HasOk", Method, 5}, - {"(TypeAndValue).IsBuiltin", Method, 5}, - {"(TypeAndValue).IsNil", Method, 5}, - {"(TypeAndValue).IsType", Method, 5}, - {"(TypeAndValue).IsValue", Method, 5}, - {"(TypeAndValue).IsVoid", Method, 5}, - {"Alias", Type, 22}, - {"ArgumentError", Type, 18}, - {"ArgumentError.Err", Field, 18}, - {"ArgumentError.Index", Field, 18}, - {"Array", Type, 5}, - {"AssertableTo", Func, 5}, - {"AssignableTo", Func, 5}, - {"Basic", Type, 5}, - {"BasicInfo", Type, 5}, - {"BasicKind", Type, 5}, - {"Bool", Const, 5}, - {"Builtin", Type, 5}, - {"Byte", Const, 5}, - {"Chan", Type, 5}, - {"ChanDir", Type, 5}, - {"CheckExpr", Func, 13}, - {"Checker", Type, 5}, - {"Checker.Info", Field, 5}, - {"Comparable", Func, 5}, - {"Complex128", Const, 5}, - {"Complex64", Const, 5}, - {"Config", Type, 5}, - {"Config.Context", Field, 18}, - {"Config.DisableUnusedImportCheck", Field, 5}, - {"Config.Error", Field, 5}, - {"Config.FakeImportC", Field, 5}, - {"Config.GoVersion", Field, 18}, - {"Config.IgnoreFuncBodies", Field, 5}, - {"Config.Importer", Field, 5}, - {"Config.Sizes", Field, 5}, - {"Const", Type, 5}, - {"Context", Type, 18}, - {"ConvertibleTo", Func, 5}, - {"DefPredeclaredTestFuncs", Func, 5}, - {"Default", Func, 8}, - {"Error", Type, 5}, - {"Error.Fset", Field, 5}, - {"Error.Msg", Field, 5}, - {"Error.Pos", Field, 5}, - {"Error.Soft", Field, 5}, - {"Eval", Func, 5}, - {"ExprString", Func, 5}, - {"FieldVal", Const, 5}, - {"Float32", Const, 5}, - {"Float64", Const, 5}, - {"Func", Type, 5}, - {"Id", Func, 5}, - {"Identical", Func, 5}, - {"IdenticalIgnoreTags", Func, 8}, - {"Implements", Func, 5}, - {"ImportMode", Type, 6}, - {"Importer", Type, 5}, - {"ImporterFrom", Type, 6}, - {"Info", Type, 5}, - {"Info.Defs", Field, 5}, - {"Info.FileVersions", Field, 22}, - {"Info.Implicits", Field, 5}, - {"Info.InitOrder", Field, 5}, - {"Info.Instances", Field, 18}, - {"Info.Scopes", Field, 5}, - {"Info.Selections", Field, 5}, - {"Info.Types", Field, 5}, - {"Info.Uses", Field, 5}, - {"Initializer", Type, 5}, - {"Initializer.Lhs", Field, 5}, - {"Initializer.Rhs", Field, 5}, - {"Instance", Type, 18}, - {"Instance.Type", Field, 18}, - {"Instance.TypeArgs", Field, 18}, - {"Instantiate", Func, 18}, - {"Int", Const, 5}, - {"Int16", Const, 5}, - {"Int32", Const, 5}, - {"Int64", Const, 5}, - {"Int8", Const, 5}, - {"Interface", Type, 5}, - {"Invalid", Const, 5}, - {"IsBoolean", Const, 5}, - {"IsComplex", Const, 5}, - {"IsConstType", Const, 5}, - {"IsFloat", Const, 5}, - {"IsInteger", Const, 5}, - {"IsInterface", Func, 5}, - {"IsNumeric", Const, 5}, - {"IsOrdered", Const, 5}, - {"IsString", Const, 5}, - {"IsUnsigned", Const, 5}, - {"IsUntyped", Const, 5}, - {"Label", Type, 5}, - {"LookupFieldOrMethod", Func, 5}, - {"Map", Type, 5}, - {"MethodExpr", Const, 5}, - {"MethodSet", Type, 5}, - {"MethodVal", Const, 5}, - {"MissingMethod", Func, 5}, - {"Named", Type, 5}, - {"NewAlias", Func, 22}, - {"NewArray", Func, 5}, - {"NewChan", Func, 5}, - {"NewChecker", Func, 5}, - {"NewConst", Func, 5}, - {"NewContext", Func, 18}, - {"NewField", Func, 5}, - {"NewFunc", Func, 5}, - {"NewInterface", Func, 5}, - {"NewInterfaceType", Func, 11}, - {"NewLabel", Func, 5}, - {"NewMap", Func, 5}, - {"NewMethodSet", Func, 5}, - {"NewNamed", Func, 5}, - {"NewPackage", Func, 5}, - {"NewParam", Func, 5}, - {"NewPkgName", Func, 5}, - {"NewPointer", Func, 5}, - {"NewScope", Func, 5}, - {"NewSignature", Func, 5}, - {"NewSignatureType", Func, 18}, - {"NewSlice", Func, 5}, - {"NewStruct", Func, 5}, - {"NewTerm", Func, 18}, - {"NewTuple", Func, 5}, - {"NewTypeName", Func, 5}, - {"NewTypeParam", Func, 18}, - {"NewUnion", Func, 18}, - {"NewVar", Func, 5}, - {"Nil", Type, 5}, - {"Object", Type, 5}, - {"ObjectString", Func, 5}, - {"Package", Type, 5}, - {"PkgName", Type, 5}, - {"Pointer", Type, 5}, - {"Qualifier", Type, 5}, - {"RecvOnly", Const, 5}, - {"RelativeTo", Func, 5}, - {"Rune", Const, 5}, - {"Satisfies", Func, 20}, - {"Scope", Type, 5}, - {"Selection", Type, 5}, - {"SelectionKind", Type, 5}, - {"SelectionString", Func, 5}, - {"SendOnly", Const, 5}, - {"SendRecv", Const, 5}, - {"Signature", Type, 5}, - {"Sizes", Type, 5}, - {"SizesFor", Func, 9}, - {"Slice", Type, 5}, - {"StdSizes", Type, 5}, - {"StdSizes.MaxAlign", Field, 5}, - {"StdSizes.WordSize", Field, 5}, - {"String", Const, 5}, - {"Struct", Type, 5}, - {"Term", Type, 18}, - {"Tuple", Type, 5}, - {"Typ", Var, 5}, - {"Type", Type, 5}, - {"TypeAndValue", Type, 5}, - {"TypeAndValue.Type", Field, 5}, - {"TypeAndValue.Value", Field, 5}, - {"TypeList", Type, 18}, - {"TypeName", Type, 5}, - {"TypeParam", Type, 18}, - {"TypeParamList", Type, 18}, - {"TypeString", Func, 5}, - {"Uint", Const, 5}, - {"Uint16", Const, 5}, - {"Uint32", Const, 5}, - {"Uint64", Const, 5}, - {"Uint8", Const, 5}, - {"Uintptr", Const, 5}, - {"Unalias", Func, 22}, - {"Union", Type, 18}, - {"Universe", Var, 5}, - {"Unsafe", Var, 5}, - {"UnsafePointer", Const, 5}, - {"UntypedBool", Const, 5}, - {"UntypedComplex", Const, 5}, - {"UntypedFloat", Const, 5}, - {"UntypedInt", Const, 5}, - {"UntypedNil", Const, 5}, - {"UntypedRune", Const, 5}, - {"UntypedString", Const, 5}, - {"Var", Type, 5}, - {"WriteExpr", Func, 5}, - {"WriteSignature", Func, 5}, - {"WriteType", Func, 5}, - }, - "go/version": { - {"Compare", Func, 22}, - {"IsValid", Func, 22}, - {"Lang", Func, 22}, - }, - "hash": { - {"Hash", Type, 0}, - {"Hash32", Type, 0}, - {"Hash64", Type, 0}, - }, - "hash/adler32": { - {"Checksum", Func, 0}, - {"New", Func, 0}, - {"Size", Const, 0}, - }, - "hash/crc32": { - {"Castagnoli", Const, 0}, - {"Checksum", Func, 0}, - {"ChecksumIEEE", Func, 0}, - {"IEEE", Const, 0}, - {"IEEETable", Var, 0}, - {"Koopman", Const, 0}, - {"MakeTable", Func, 0}, - {"New", Func, 0}, - {"NewIEEE", Func, 0}, - {"Size", Const, 0}, - {"Table", Type, 0}, - {"Update", Func, 0}, - }, - "hash/crc64": { - {"Checksum", Func, 0}, - {"ECMA", Const, 0}, - {"ISO", Const, 0}, - {"MakeTable", Func, 0}, - {"New", Func, 0}, - {"Size", Const, 0}, - {"Table", Type, 0}, - {"Update", Func, 0}, - }, - "hash/fnv": { - {"New128", Func, 9}, - {"New128a", Func, 9}, - {"New32", Func, 0}, - {"New32a", Func, 0}, - {"New64", Func, 0}, - {"New64a", Func, 0}, - }, - "hash/maphash": { - {"(*Hash).BlockSize", Method, 14}, - {"(*Hash).Reset", Method, 14}, - {"(*Hash).Seed", Method, 14}, - {"(*Hash).SetSeed", Method, 14}, - {"(*Hash).Size", Method, 14}, - {"(*Hash).Sum", Method, 14}, - {"(*Hash).Sum64", Method, 14}, - {"(*Hash).Write", Method, 14}, - {"(*Hash).WriteByte", Method, 14}, - {"(*Hash).WriteString", Method, 14}, - {"Bytes", Func, 19}, - {"Comparable", Func, 24}, - {"Hash", Type, 14}, - {"MakeSeed", Func, 14}, - {"Seed", Type, 14}, - {"String", Func, 19}, - {"WriteComparable", Func, 24}, - }, - "html": { - {"EscapeString", Func, 0}, - {"UnescapeString", Func, 0}, - }, - "html/template": { - {"(*Error).Error", Method, 0}, - {"(*Template).AddParseTree", Method, 0}, - {"(*Template).Clone", Method, 0}, - {"(*Template).DefinedTemplates", Method, 6}, - {"(*Template).Delims", Method, 0}, - {"(*Template).Execute", Method, 0}, - {"(*Template).ExecuteTemplate", Method, 0}, - {"(*Template).Funcs", Method, 0}, - {"(*Template).Lookup", Method, 0}, - {"(*Template).Name", Method, 0}, - {"(*Template).New", Method, 0}, - {"(*Template).Option", Method, 5}, - {"(*Template).Parse", Method, 0}, - {"(*Template).ParseFS", Method, 16}, - {"(*Template).ParseFiles", Method, 0}, - {"(*Template).ParseGlob", Method, 0}, - {"(*Template).Templates", Method, 0}, - {"CSS", Type, 0}, - {"ErrAmbigContext", Const, 0}, - {"ErrBadHTML", Const, 0}, - {"ErrBranchEnd", Const, 0}, - {"ErrEndContext", Const, 0}, - {"ErrJSTemplate", Const, 21}, - {"ErrNoSuchTemplate", Const, 0}, - {"ErrOutputContext", Const, 0}, - {"ErrPartialCharset", Const, 0}, - {"ErrPartialEscape", Const, 0}, - {"ErrPredefinedEscaper", Const, 9}, - {"ErrRangeLoopReentry", Const, 0}, - {"ErrSlashAmbig", Const, 0}, - {"Error", Type, 0}, - {"Error.Description", Field, 0}, - {"Error.ErrorCode", Field, 0}, - {"Error.Line", Field, 0}, - {"Error.Name", Field, 0}, - {"Error.Node", Field, 4}, - {"ErrorCode", Type, 0}, - {"FuncMap", Type, 0}, - {"HTML", Type, 0}, - {"HTMLAttr", Type, 0}, - {"HTMLEscape", Func, 0}, - {"HTMLEscapeString", Func, 0}, - {"HTMLEscaper", Func, 0}, - {"IsTrue", Func, 6}, - {"JS", Type, 0}, - {"JSEscape", Func, 0}, - {"JSEscapeString", Func, 0}, - {"JSEscaper", Func, 0}, - {"JSStr", Type, 0}, - {"Must", Func, 0}, - {"New", Func, 0}, - {"OK", Const, 0}, - {"ParseFS", Func, 16}, - {"ParseFiles", Func, 0}, - {"ParseGlob", Func, 0}, - {"Srcset", Type, 10}, - {"Template", Type, 0}, - {"Template.Tree", Field, 2}, - {"URL", Type, 0}, - {"URLQueryEscaper", Func, 0}, - }, - "image": { - {"(*Alpha).AlphaAt", Method, 4}, - {"(*Alpha).At", Method, 0}, - {"(*Alpha).Bounds", Method, 0}, - {"(*Alpha).ColorModel", Method, 0}, - {"(*Alpha).Opaque", Method, 0}, - {"(*Alpha).PixOffset", Method, 0}, - {"(*Alpha).RGBA64At", Method, 17}, - {"(*Alpha).Set", Method, 0}, - {"(*Alpha).SetAlpha", Method, 0}, - {"(*Alpha).SetRGBA64", Method, 17}, - {"(*Alpha).SubImage", Method, 0}, - {"(*Alpha16).Alpha16At", Method, 4}, - {"(*Alpha16).At", Method, 0}, - {"(*Alpha16).Bounds", Method, 0}, - {"(*Alpha16).ColorModel", Method, 0}, - {"(*Alpha16).Opaque", Method, 0}, - {"(*Alpha16).PixOffset", Method, 0}, - {"(*Alpha16).RGBA64At", Method, 17}, - {"(*Alpha16).Set", Method, 0}, - {"(*Alpha16).SetAlpha16", Method, 0}, - {"(*Alpha16).SetRGBA64", Method, 17}, - {"(*Alpha16).SubImage", Method, 0}, - {"(*CMYK).At", Method, 5}, - {"(*CMYK).Bounds", Method, 5}, - {"(*CMYK).CMYKAt", Method, 5}, - {"(*CMYK).ColorModel", Method, 5}, - {"(*CMYK).Opaque", Method, 5}, - {"(*CMYK).PixOffset", Method, 5}, - {"(*CMYK).RGBA64At", Method, 17}, - {"(*CMYK).Set", Method, 5}, - {"(*CMYK).SetCMYK", Method, 5}, - {"(*CMYK).SetRGBA64", Method, 17}, - {"(*CMYK).SubImage", Method, 5}, - {"(*Gray).At", Method, 0}, - {"(*Gray).Bounds", Method, 0}, - {"(*Gray).ColorModel", Method, 0}, - {"(*Gray).GrayAt", Method, 4}, - {"(*Gray).Opaque", Method, 0}, - {"(*Gray).PixOffset", Method, 0}, - {"(*Gray).RGBA64At", Method, 17}, - {"(*Gray).Set", Method, 0}, - {"(*Gray).SetGray", Method, 0}, - {"(*Gray).SetRGBA64", Method, 17}, - {"(*Gray).SubImage", Method, 0}, - {"(*Gray16).At", Method, 0}, - {"(*Gray16).Bounds", Method, 0}, - {"(*Gray16).ColorModel", Method, 0}, - {"(*Gray16).Gray16At", Method, 4}, - {"(*Gray16).Opaque", Method, 0}, - {"(*Gray16).PixOffset", Method, 0}, - {"(*Gray16).RGBA64At", Method, 17}, - {"(*Gray16).Set", Method, 0}, - {"(*Gray16).SetGray16", Method, 0}, - {"(*Gray16).SetRGBA64", Method, 17}, - {"(*Gray16).SubImage", Method, 0}, - {"(*NRGBA).At", Method, 0}, - {"(*NRGBA).Bounds", Method, 0}, - {"(*NRGBA).ColorModel", Method, 0}, - {"(*NRGBA).NRGBAAt", Method, 4}, - {"(*NRGBA).Opaque", Method, 0}, - {"(*NRGBA).PixOffset", Method, 0}, - {"(*NRGBA).RGBA64At", Method, 17}, - {"(*NRGBA).Set", Method, 0}, - {"(*NRGBA).SetNRGBA", Method, 0}, - {"(*NRGBA).SetRGBA64", Method, 17}, - {"(*NRGBA).SubImage", Method, 0}, - {"(*NRGBA64).At", Method, 0}, - {"(*NRGBA64).Bounds", Method, 0}, - {"(*NRGBA64).ColorModel", Method, 0}, - {"(*NRGBA64).NRGBA64At", Method, 4}, - {"(*NRGBA64).Opaque", Method, 0}, - {"(*NRGBA64).PixOffset", Method, 0}, - {"(*NRGBA64).RGBA64At", Method, 17}, - {"(*NRGBA64).Set", Method, 0}, - {"(*NRGBA64).SetNRGBA64", Method, 0}, - {"(*NRGBA64).SetRGBA64", Method, 17}, - {"(*NRGBA64).SubImage", Method, 0}, - {"(*NYCbCrA).AOffset", Method, 6}, - {"(*NYCbCrA).At", Method, 6}, - {"(*NYCbCrA).Bounds", Method, 6}, - {"(*NYCbCrA).COffset", Method, 6}, - {"(*NYCbCrA).ColorModel", Method, 6}, - {"(*NYCbCrA).NYCbCrAAt", Method, 6}, - {"(*NYCbCrA).Opaque", Method, 6}, - {"(*NYCbCrA).RGBA64At", Method, 17}, - {"(*NYCbCrA).SubImage", Method, 6}, - {"(*NYCbCrA).YCbCrAt", Method, 6}, - {"(*NYCbCrA).YOffset", Method, 6}, - {"(*Paletted).At", Method, 0}, - {"(*Paletted).Bounds", Method, 0}, - {"(*Paletted).ColorIndexAt", Method, 0}, - {"(*Paletted).ColorModel", Method, 0}, - {"(*Paletted).Opaque", Method, 0}, - {"(*Paletted).PixOffset", Method, 0}, - {"(*Paletted).RGBA64At", Method, 17}, - {"(*Paletted).Set", Method, 0}, - {"(*Paletted).SetColorIndex", Method, 0}, - {"(*Paletted).SetRGBA64", Method, 17}, - {"(*Paletted).SubImage", Method, 0}, - {"(*RGBA).At", Method, 0}, - {"(*RGBA).Bounds", Method, 0}, - {"(*RGBA).ColorModel", Method, 0}, - {"(*RGBA).Opaque", Method, 0}, - {"(*RGBA).PixOffset", Method, 0}, - {"(*RGBA).RGBA64At", Method, 17}, - {"(*RGBA).RGBAAt", Method, 4}, - {"(*RGBA).Set", Method, 0}, - {"(*RGBA).SetRGBA", Method, 0}, - {"(*RGBA).SetRGBA64", Method, 17}, - {"(*RGBA).SubImage", Method, 0}, - {"(*RGBA64).At", Method, 0}, - {"(*RGBA64).Bounds", Method, 0}, - {"(*RGBA64).ColorModel", Method, 0}, - {"(*RGBA64).Opaque", Method, 0}, - {"(*RGBA64).PixOffset", Method, 0}, - {"(*RGBA64).RGBA64At", Method, 4}, - {"(*RGBA64).Set", Method, 0}, - {"(*RGBA64).SetRGBA64", Method, 0}, - {"(*RGBA64).SubImage", Method, 0}, - {"(*Uniform).At", Method, 0}, - {"(*Uniform).Bounds", Method, 0}, - {"(*Uniform).ColorModel", Method, 0}, - {"(*Uniform).Convert", Method, 0}, - {"(*Uniform).Opaque", Method, 0}, - {"(*Uniform).RGBA", Method, 0}, - {"(*Uniform).RGBA64At", Method, 17}, - {"(*YCbCr).At", Method, 0}, - {"(*YCbCr).Bounds", Method, 0}, - {"(*YCbCr).COffset", Method, 0}, - {"(*YCbCr).ColorModel", Method, 0}, - {"(*YCbCr).Opaque", Method, 0}, - {"(*YCbCr).RGBA64At", Method, 17}, - {"(*YCbCr).SubImage", Method, 0}, - {"(*YCbCr).YCbCrAt", Method, 4}, - {"(*YCbCr).YOffset", Method, 0}, - {"(Point).Add", Method, 0}, - {"(Point).Div", Method, 0}, - {"(Point).Eq", Method, 0}, - {"(Point).In", Method, 0}, - {"(Point).Mod", Method, 0}, - {"(Point).Mul", Method, 0}, - {"(Point).String", Method, 0}, - {"(Point).Sub", Method, 0}, - {"(Rectangle).Add", Method, 0}, - {"(Rectangle).At", Method, 5}, - {"(Rectangle).Bounds", Method, 5}, - {"(Rectangle).Canon", Method, 0}, - {"(Rectangle).ColorModel", Method, 5}, - {"(Rectangle).Dx", Method, 0}, - {"(Rectangle).Dy", Method, 0}, - {"(Rectangle).Empty", Method, 0}, - {"(Rectangle).Eq", Method, 0}, - {"(Rectangle).In", Method, 0}, - {"(Rectangle).Inset", Method, 0}, - {"(Rectangle).Intersect", Method, 0}, - {"(Rectangle).Overlaps", Method, 0}, - {"(Rectangle).RGBA64At", Method, 17}, - {"(Rectangle).Size", Method, 0}, - {"(Rectangle).String", Method, 0}, - {"(Rectangle).Sub", Method, 0}, - {"(Rectangle).Union", Method, 0}, - {"(YCbCrSubsampleRatio).String", Method, 0}, - {"Alpha", Type, 0}, - {"Alpha.Pix", Field, 0}, - {"Alpha.Rect", Field, 0}, - {"Alpha.Stride", Field, 0}, - {"Alpha16", Type, 0}, - {"Alpha16.Pix", Field, 0}, - {"Alpha16.Rect", Field, 0}, - {"Alpha16.Stride", Field, 0}, - {"Black", Var, 0}, - {"CMYK", Type, 5}, - {"CMYK.Pix", Field, 5}, - {"CMYK.Rect", Field, 5}, - {"CMYK.Stride", Field, 5}, - {"Config", Type, 0}, - {"Config.ColorModel", Field, 0}, - {"Config.Height", Field, 0}, - {"Config.Width", Field, 0}, - {"Decode", Func, 0}, - {"DecodeConfig", Func, 0}, - {"ErrFormat", Var, 0}, - {"Gray", Type, 0}, - {"Gray.Pix", Field, 0}, - {"Gray.Rect", Field, 0}, - {"Gray.Stride", Field, 0}, - {"Gray16", Type, 0}, - {"Gray16.Pix", Field, 0}, - {"Gray16.Rect", Field, 0}, - {"Gray16.Stride", Field, 0}, - {"Image", Type, 0}, - {"NRGBA", Type, 0}, - {"NRGBA.Pix", Field, 0}, - {"NRGBA.Rect", Field, 0}, - {"NRGBA.Stride", Field, 0}, - {"NRGBA64", Type, 0}, - {"NRGBA64.Pix", Field, 0}, - {"NRGBA64.Rect", Field, 0}, - {"NRGBA64.Stride", Field, 0}, - {"NYCbCrA", Type, 6}, - {"NYCbCrA.A", Field, 6}, - {"NYCbCrA.AStride", Field, 6}, - {"NYCbCrA.YCbCr", Field, 6}, - {"NewAlpha", Func, 0}, - {"NewAlpha16", Func, 0}, - {"NewCMYK", Func, 5}, - {"NewGray", Func, 0}, - {"NewGray16", Func, 0}, - {"NewNRGBA", Func, 0}, - {"NewNRGBA64", Func, 0}, - {"NewNYCbCrA", Func, 6}, - {"NewPaletted", Func, 0}, - {"NewRGBA", Func, 0}, - {"NewRGBA64", Func, 0}, - {"NewUniform", Func, 0}, - {"NewYCbCr", Func, 0}, - {"Opaque", Var, 0}, - {"Paletted", Type, 0}, - {"Paletted.Palette", Field, 0}, - {"Paletted.Pix", Field, 0}, - {"Paletted.Rect", Field, 0}, - {"Paletted.Stride", Field, 0}, - {"PalettedImage", Type, 0}, - {"Point", Type, 0}, - {"Point.X", Field, 0}, - {"Point.Y", Field, 0}, - {"Pt", Func, 0}, - {"RGBA", Type, 0}, - {"RGBA.Pix", Field, 0}, - {"RGBA.Rect", Field, 0}, - {"RGBA.Stride", Field, 0}, - {"RGBA64", Type, 0}, - {"RGBA64.Pix", Field, 0}, - {"RGBA64.Rect", Field, 0}, - {"RGBA64.Stride", Field, 0}, - {"RGBA64Image", Type, 17}, - {"Rect", Func, 0}, - {"Rectangle", Type, 0}, - {"Rectangle.Max", Field, 0}, - {"Rectangle.Min", Field, 0}, - {"RegisterFormat", Func, 0}, - {"Transparent", Var, 0}, - {"Uniform", Type, 0}, - {"Uniform.C", Field, 0}, - {"White", Var, 0}, - {"YCbCr", Type, 0}, - {"YCbCr.CStride", Field, 0}, - {"YCbCr.Cb", Field, 0}, - {"YCbCr.Cr", Field, 0}, - {"YCbCr.Rect", Field, 0}, - {"YCbCr.SubsampleRatio", Field, 0}, - {"YCbCr.Y", Field, 0}, - {"YCbCr.YStride", Field, 0}, - {"YCbCrSubsampleRatio", Type, 0}, - {"YCbCrSubsampleRatio410", Const, 5}, - {"YCbCrSubsampleRatio411", Const, 5}, - {"YCbCrSubsampleRatio420", Const, 0}, - {"YCbCrSubsampleRatio422", Const, 0}, - {"YCbCrSubsampleRatio440", Const, 1}, - {"YCbCrSubsampleRatio444", Const, 0}, - {"ZP", Var, 0}, - {"ZR", Var, 0}, - }, - "image/color": { - {"(Alpha).RGBA", Method, 0}, - {"(Alpha16).RGBA", Method, 0}, - {"(CMYK).RGBA", Method, 5}, - {"(Gray).RGBA", Method, 0}, - {"(Gray16).RGBA", Method, 0}, - {"(NRGBA).RGBA", Method, 0}, - {"(NRGBA64).RGBA", Method, 0}, - {"(NYCbCrA).RGBA", Method, 6}, - {"(Palette).Convert", Method, 0}, - {"(Palette).Index", Method, 0}, - {"(RGBA).RGBA", Method, 0}, - {"(RGBA64).RGBA", Method, 0}, - {"(YCbCr).RGBA", Method, 0}, - {"Alpha", Type, 0}, - {"Alpha.A", Field, 0}, - {"Alpha16", Type, 0}, - {"Alpha16.A", Field, 0}, - {"Alpha16Model", Var, 0}, - {"AlphaModel", Var, 0}, - {"Black", Var, 0}, - {"CMYK", Type, 5}, - {"CMYK.C", Field, 5}, - {"CMYK.K", Field, 5}, - {"CMYK.M", Field, 5}, - {"CMYK.Y", Field, 5}, - {"CMYKModel", Var, 5}, - {"CMYKToRGB", Func, 5}, - {"Color", Type, 0}, - {"Gray", Type, 0}, - {"Gray.Y", Field, 0}, - {"Gray16", Type, 0}, - {"Gray16.Y", Field, 0}, - {"Gray16Model", Var, 0}, - {"GrayModel", Var, 0}, - {"Model", Type, 0}, - {"ModelFunc", Func, 0}, - {"NRGBA", Type, 0}, - {"NRGBA.A", Field, 0}, - {"NRGBA.B", Field, 0}, - {"NRGBA.G", Field, 0}, - {"NRGBA.R", Field, 0}, - {"NRGBA64", Type, 0}, - {"NRGBA64.A", Field, 0}, - {"NRGBA64.B", Field, 0}, - {"NRGBA64.G", Field, 0}, - {"NRGBA64.R", Field, 0}, - {"NRGBA64Model", Var, 0}, - {"NRGBAModel", Var, 0}, - {"NYCbCrA", Type, 6}, - {"NYCbCrA.A", Field, 6}, - {"NYCbCrA.YCbCr", Field, 6}, - {"NYCbCrAModel", Var, 6}, - {"Opaque", Var, 0}, - {"Palette", Type, 0}, - {"RGBA", Type, 0}, - {"RGBA.A", Field, 0}, - {"RGBA.B", Field, 0}, - {"RGBA.G", Field, 0}, - {"RGBA.R", Field, 0}, - {"RGBA64", Type, 0}, - {"RGBA64.A", Field, 0}, - {"RGBA64.B", Field, 0}, - {"RGBA64.G", Field, 0}, - {"RGBA64.R", Field, 0}, - {"RGBA64Model", Var, 0}, - {"RGBAModel", Var, 0}, - {"RGBToCMYK", Func, 5}, - {"RGBToYCbCr", Func, 0}, - {"Transparent", Var, 0}, - {"White", Var, 0}, - {"YCbCr", Type, 0}, - {"YCbCr.Cb", Field, 0}, - {"YCbCr.Cr", Field, 0}, - {"YCbCr.Y", Field, 0}, - {"YCbCrModel", Var, 0}, - {"YCbCrToRGB", Func, 0}, - }, - "image/color/palette": { - {"Plan9", Var, 2}, - {"WebSafe", Var, 2}, - }, - "image/draw": { - {"(Op).Draw", Method, 2}, - {"Draw", Func, 0}, - {"DrawMask", Func, 0}, - {"Drawer", Type, 2}, - {"FloydSteinberg", Var, 2}, - {"Image", Type, 0}, - {"Op", Type, 0}, - {"Over", Const, 0}, - {"Quantizer", Type, 2}, - {"RGBA64Image", Type, 17}, - {"Src", Const, 0}, - }, - "image/gif": { - {"Decode", Func, 0}, - {"DecodeAll", Func, 0}, - {"DecodeConfig", Func, 0}, - {"DisposalBackground", Const, 5}, - {"DisposalNone", Const, 5}, - {"DisposalPrevious", Const, 5}, - {"Encode", Func, 2}, - {"EncodeAll", Func, 2}, - {"GIF", Type, 0}, - {"GIF.BackgroundIndex", Field, 5}, - {"GIF.Config", Field, 5}, - {"GIF.Delay", Field, 0}, - {"GIF.Disposal", Field, 5}, - {"GIF.Image", Field, 0}, - {"GIF.LoopCount", Field, 0}, - {"Options", Type, 2}, - {"Options.Drawer", Field, 2}, - {"Options.NumColors", Field, 2}, - {"Options.Quantizer", Field, 2}, - }, - "image/jpeg": { - {"(FormatError).Error", Method, 0}, - {"(UnsupportedError).Error", Method, 0}, - {"Decode", Func, 0}, - {"DecodeConfig", Func, 0}, - {"DefaultQuality", Const, 0}, - {"Encode", Func, 0}, - {"FormatError", Type, 0}, - {"Options", Type, 0}, - {"Options.Quality", Field, 0}, - {"Reader", Type, 0}, - {"UnsupportedError", Type, 0}, - }, - "image/png": { - {"(*Encoder).Encode", Method, 4}, - {"(FormatError).Error", Method, 0}, - {"(UnsupportedError).Error", Method, 0}, - {"BestCompression", Const, 4}, - {"BestSpeed", Const, 4}, - {"CompressionLevel", Type, 4}, - {"Decode", Func, 0}, - {"DecodeConfig", Func, 0}, - {"DefaultCompression", Const, 4}, - {"Encode", Func, 0}, - {"Encoder", Type, 4}, - {"Encoder.BufferPool", Field, 9}, - {"Encoder.CompressionLevel", Field, 4}, - {"EncoderBuffer", Type, 9}, - {"EncoderBufferPool", Type, 9}, - {"FormatError", Type, 0}, - {"NoCompression", Const, 4}, - {"UnsupportedError", Type, 0}, - }, - "index/suffixarray": { - {"(*Index).Bytes", Method, 0}, - {"(*Index).FindAllIndex", Method, 0}, - {"(*Index).Lookup", Method, 0}, - {"(*Index).Read", Method, 0}, - {"(*Index).Write", Method, 0}, - {"Index", Type, 0}, - {"New", Func, 0}, - }, - "io": { - {"(*LimitedReader).Read", Method, 0}, - {"(*OffsetWriter).Seek", Method, 20}, - {"(*OffsetWriter).Write", Method, 20}, - {"(*OffsetWriter).WriteAt", Method, 20}, - {"(*PipeReader).Close", Method, 0}, - {"(*PipeReader).CloseWithError", Method, 0}, - {"(*PipeReader).Read", Method, 0}, - {"(*PipeWriter).Close", Method, 0}, - {"(*PipeWriter).CloseWithError", Method, 0}, - {"(*PipeWriter).Write", Method, 0}, - {"(*SectionReader).Outer", Method, 22}, - {"(*SectionReader).Read", Method, 0}, - {"(*SectionReader).ReadAt", Method, 0}, - {"(*SectionReader).Seek", Method, 0}, - {"(*SectionReader).Size", Method, 0}, - {"ByteReader", Type, 0}, - {"ByteScanner", Type, 0}, - {"ByteWriter", Type, 1}, - {"Closer", Type, 0}, - {"Copy", Func, 0}, - {"CopyBuffer", Func, 5}, - {"CopyN", Func, 0}, - {"Discard", Var, 16}, - {"EOF", Var, 0}, - {"ErrClosedPipe", Var, 0}, - {"ErrNoProgress", Var, 1}, - {"ErrShortBuffer", Var, 0}, - {"ErrShortWrite", Var, 0}, - {"ErrUnexpectedEOF", Var, 0}, - {"LimitReader", Func, 0}, - {"LimitedReader", Type, 0}, - {"LimitedReader.N", Field, 0}, - {"LimitedReader.R", Field, 0}, - {"MultiReader", Func, 0}, - {"MultiWriter", Func, 0}, - {"NewOffsetWriter", Func, 20}, - {"NewSectionReader", Func, 0}, - {"NopCloser", Func, 16}, - {"OffsetWriter", Type, 20}, - {"Pipe", Func, 0}, - {"PipeReader", Type, 0}, - {"PipeWriter", Type, 0}, - {"ReadAll", Func, 16}, - {"ReadAtLeast", Func, 0}, - {"ReadCloser", Type, 0}, - {"ReadFull", Func, 0}, - {"ReadSeekCloser", Type, 16}, - {"ReadSeeker", Type, 0}, - {"ReadWriteCloser", Type, 0}, - {"ReadWriteSeeker", Type, 0}, - {"ReadWriter", Type, 0}, - {"Reader", Type, 0}, - {"ReaderAt", Type, 0}, - {"ReaderFrom", Type, 0}, - {"RuneReader", Type, 0}, - {"RuneScanner", Type, 0}, - {"SectionReader", Type, 0}, - {"SeekCurrent", Const, 7}, - {"SeekEnd", Const, 7}, - {"SeekStart", Const, 7}, - {"Seeker", Type, 0}, - {"StringWriter", Type, 12}, - {"TeeReader", Func, 0}, - {"WriteCloser", Type, 0}, - {"WriteSeeker", Type, 0}, - {"WriteString", Func, 0}, - {"Writer", Type, 0}, - {"WriterAt", Type, 0}, - {"WriterTo", Type, 0}, - }, - "io/fs": { - {"(*PathError).Error", Method, 16}, - {"(*PathError).Timeout", Method, 16}, - {"(*PathError).Unwrap", Method, 16}, - {"(FileMode).IsDir", Method, 16}, - {"(FileMode).IsRegular", Method, 16}, - {"(FileMode).Perm", Method, 16}, - {"(FileMode).String", Method, 16}, - {"(FileMode).Type", Method, 16}, - {"DirEntry", Type, 16}, - {"ErrClosed", Var, 16}, - {"ErrExist", Var, 16}, - {"ErrInvalid", Var, 16}, - {"ErrNotExist", Var, 16}, - {"ErrPermission", Var, 16}, - {"FS", Type, 16}, - {"File", Type, 16}, - {"FileInfo", Type, 16}, - {"FileInfoToDirEntry", Func, 17}, - {"FileMode", Type, 16}, - {"FormatDirEntry", Func, 21}, - {"FormatFileInfo", Func, 21}, - {"Glob", Func, 16}, - {"GlobFS", Type, 16}, - {"ModeAppend", Const, 16}, - {"ModeCharDevice", Const, 16}, - {"ModeDevice", Const, 16}, - {"ModeDir", Const, 16}, - {"ModeExclusive", Const, 16}, - {"ModeIrregular", Const, 16}, - {"ModeNamedPipe", Const, 16}, - {"ModePerm", Const, 16}, - {"ModeSetgid", Const, 16}, - {"ModeSetuid", Const, 16}, - {"ModeSocket", Const, 16}, - {"ModeSticky", Const, 16}, - {"ModeSymlink", Const, 16}, - {"ModeTemporary", Const, 16}, - {"ModeType", Const, 16}, - {"PathError", Type, 16}, - {"PathError.Err", Field, 16}, - {"PathError.Op", Field, 16}, - {"PathError.Path", Field, 16}, - {"ReadDir", Func, 16}, - {"ReadDirFS", Type, 16}, - {"ReadDirFile", Type, 16}, - {"ReadFile", Func, 16}, - {"ReadFileFS", Type, 16}, - {"SkipAll", Var, 20}, - {"SkipDir", Var, 16}, - {"Stat", Func, 16}, - {"StatFS", Type, 16}, - {"Sub", Func, 16}, - {"SubFS", Type, 16}, - {"ValidPath", Func, 16}, - {"WalkDir", Func, 16}, - {"WalkDirFunc", Type, 16}, - }, - "io/ioutil": { - {"Discard", Var, 0}, - {"NopCloser", Func, 0}, - {"ReadAll", Func, 0}, - {"ReadDir", Func, 0}, - {"ReadFile", Func, 0}, - {"TempDir", Func, 0}, - {"TempFile", Func, 0}, - {"WriteFile", Func, 0}, - }, - "iter": { - {"Pull", Func, 23}, - {"Pull2", Func, 23}, - {"Seq", Type, 23}, - {"Seq2", Type, 23}, - }, - "log": { - {"(*Logger).Fatal", Method, 0}, - {"(*Logger).Fatalf", Method, 0}, - {"(*Logger).Fatalln", Method, 0}, - {"(*Logger).Flags", Method, 0}, - {"(*Logger).Output", Method, 0}, - {"(*Logger).Panic", Method, 0}, - {"(*Logger).Panicf", Method, 0}, - {"(*Logger).Panicln", Method, 0}, - {"(*Logger).Prefix", Method, 0}, - {"(*Logger).Print", Method, 0}, - {"(*Logger).Printf", Method, 0}, - {"(*Logger).Println", Method, 0}, - {"(*Logger).SetFlags", Method, 0}, - {"(*Logger).SetOutput", Method, 5}, - {"(*Logger).SetPrefix", Method, 0}, - {"(*Logger).Writer", Method, 12}, - {"Default", Func, 16}, - {"Fatal", Func, 0}, - {"Fatalf", Func, 0}, - {"Fatalln", Func, 0}, - {"Flags", Func, 0}, - {"LUTC", Const, 5}, - {"Ldate", Const, 0}, - {"Llongfile", Const, 0}, - {"Lmicroseconds", Const, 0}, - {"Lmsgprefix", Const, 14}, - {"Logger", Type, 0}, - {"Lshortfile", Const, 0}, - {"LstdFlags", Const, 0}, - {"Ltime", Const, 0}, - {"New", Func, 0}, - {"Output", Func, 5}, - {"Panic", Func, 0}, - {"Panicf", Func, 0}, - {"Panicln", Func, 0}, - {"Prefix", Func, 0}, - {"Print", Func, 0}, - {"Printf", Func, 0}, - {"Println", Func, 0}, - {"SetFlags", Func, 0}, - {"SetOutput", Func, 0}, - {"SetPrefix", Func, 0}, - {"Writer", Func, 13}, - }, - "log/slog": { - {"(*JSONHandler).Enabled", Method, 21}, - {"(*JSONHandler).Handle", Method, 21}, - {"(*JSONHandler).WithAttrs", Method, 21}, - {"(*JSONHandler).WithGroup", Method, 21}, - {"(*Level).UnmarshalJSON", Method, 21}, - {"(*Level).UnmarshalText", Method, 21}, - {"(*LevelVar).AppendText", Method, 24}, - {"(*LevelVar).Level", Method, 21}, - {"(*LevelVar).MarshalText", Method, 21}, - {"(*LevelVar).Set", Method, 21}, - {"(*LevelVar).String", Method, 21}, - {"(*LevelVar).UnmarshalText", Method, 21}, - {"(*Logger).Debug", Method, 21}, - {"(*Logger).DebugContext", Method, 21}, - {"(*Logger).Enabled", Method, 21}, - {"(*Logger).Error", Method, 21}, - {"(*Logger).ErrorContext", Method, 21}, - {"(*Logger).Handler", Method, 21}, - {"(*Logger).Info", Method, 21}, - {"(*Logger).InfoContext", Method, 21}, - {"(*Logger).Log", Method, 21}, - {"(*Logger).LogAttrs", Method, 21}, - {"(*Logger).Warn", Method, 21}, - {"(*Logger).WarnContext", Method, 21}, - {"(*Logger).With", Method, 21}, - {"(*Logger).WithGroup", Method, 21}, - {"(*Record).Add", Method, 21}, - {"(*Record).AddAttrs", Method, 21}, - {"(*TextHandler).Enabled", Method, 21}, - {"(*TextHandler).Handle", Method, 21}, - {"(*TextHandler).WithAttrs", Method, 21}, - {"(*TextHandler).WithGroup", Method, 21}, - {"(Attr).Equal", Method, 21}, - {"(Attr).String", Method, 21}, - {"(Kind).String", Method, 21}, - {"(Level).AppendText", Method, 24}, - {"(Level).Level", Method, 21}, - {"(Level).MarshalJSON", Method, 21}, - {"(Level).MarshalText", Method, 21}, - {"(Level).String", Method, 21}, - {"(Record).Attrs", Method, 21}, - {"(Record).Clone", Method, 21}, - {"(Record).NumAttrs", Method, 21}, - {"(Value).Any", Method, 21}, - {"(Value).Bool", Method, 21}, - {"(Value).Duration", Method, 21}, - {"(Value).Equal", Method, 21}, - {"(Value).Float64", Method, 21}, - {"(Value).Group", Method, 21}, - {"(Value).Int64", Method, 21}, - {"(Value).Kind", Method, 21}, - {"(Value).LogValuer", Method, 21}, - {"(Value).Resolve", Method, 21}, - {"(Value).String", Method, 21}, - {"(Value).Time", Method, 21}, - {"(Value).Uint64", Method, 21}, - {"Any", Func, 21}, - {"AnyValue", Func, 21}, - {"Attr", Type, 21}, - {"Attr.Key", Field, 21}, - {"Attr.Value", Field, 21}, - {"Bool", Func, 21}, - {"BoolValue", Func, 21}, - {"Debug", Func, 21}, - {"DebugContext", Func, 21}, - {"Default", Func, 21}, - {"DiscardHandler", Var, 24}, - {"Duration", Func, 21}, - {"DurationValue", Func, 21}, - {"Error", Func, 21}, - {"ErrorContext", Func, 21}, - {"Float64", Func, 21}, - {"Float64Value", Func, 21}, - {"Group", Func, 21}, - {"GroupValue", Func, 21}, - {"Handler", Type, 21}, - {"HandlerOptions", Type, 21}, - {"HandlerOptions.AddSource", Field, 21}, - {"HandlerOptions.Level", Field, 21}, - {"HandlerOptions.ReplaceAttr", Field, 21}, - {"Info", Func, 21}, - {"InfoContext", Func, 21}, - {"Int", Func, 21}, - {"Int64", Func, 21}, - {"Int64Value", Func, 21}, - {"IntValue", Func, 21}, - {"JSONHandler", Type, 21}, - {"Kind", Type, 21}, - {"KindAny", Const, 21}, - {"KindBool", Const, 21}, - {"KindDuration", Const, 21}, - {"KindFloat64", Const, 21}, - {"KindGroup", Const, 21}, - {"KindInt64", Const, 21}, - {"KindLogValuer", Const, 21}, - {"KindString", Const, 21}, - {"KindTime", Const, 21}, - {"KindUint64", Const, 21}, - {"Level", Type, 21}, - {"LevelDebug", Const, 21}, - {"LevelError", Const, 21}, - {"LevelInfo", Const, 21}, - {"LevelKey", Const, 21}, - {"LevelVar", Type, 21}, - {"LevelWarn", Const, 21}, - {"Leveler", Type, 21}, - {"Log", Func, 21}, - {"LogAttrs", Func, 21}, - {"LogValuer", Type, 21}, - {"Logger", Type, 21}, - {"MessageKey", Const, 21}, - {"New", Func, 21}, - {"NewJSONHandler", Func, 21}, - {"NewLogLogger", Func, 21}, - {"NewRecord", Func, 21}, - {"NewTextHandler", Func, 21}, - {"Record", Type, 21}, - {"Record.Level", Field, 21}, - {"Record.Message", Field, 21}, - {"Record.PC", Field, 21}, - {"Record.Time", Field, 21}, - {"SetDefault", Func, 21}, - {"SetLogLoggerLevel", Func, 22}, - {"Source", Type, 21}, - {"Source.File", Field, 21}, - {"Source.Function", Field, 21}, - {"Source.Line", Field, 21}, - {"SourceKey", Const, 21}, - {"String", Func, 21}, - {"StringValue", Func, 21}, - {"TextHandler", Type, 21}, - {"Time", Func, 21}, - {"TimeKey", Const, 21}, - {"TimeValue", Func, 21}, - {"Uint64", Func, 21}, - {"Uint64Value", Func, 21}, - {"Value", Type, 21}, - {"Warn", Func, 21}, - {"WarnContext", Func, 21}, - {"With", Func, 21}, - }, - "log/syslog": { - {"(*Writer).Alert", Method, 0}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).Crit", Method, 0}, - {"(*Writer).Debug", Method, 0}, - {"(*Writer).Emerg", Method, 0}, - {"(*Writer).Err", Method, 0}, - {"(*Writer).Info", Method, 0}, - {"(*Writer).Notice", Method, 0}, - {"(*Writer).Warning", Method, 0}, - {"(*Writer).Write", Method, 0}, - {"Dial", Func, 0}, - {"LOG_ALERT", Const, 0}, - {"LOG_AUTH", Const, 1}, - {"LOG_AUTHPRIV", Const, 1}, - {"LOG_CRIT", Const, 0}, - {"LOG_CRON", Const, 1}, - {"LOG_DAEMON", Const, 1}, - {"LOG_DEBUG", Const, 0}, - {"LOG_EMERG", Const, 0}, - {"LOG_ERR", Const, 0}, - {"LOG_FTP", Const, 1}, - {"LOG_INFO", Const, 0}, - {"LOG_KERN", Const, 1}, - {"LOG_LOCAL0", Const, 1}, - {"LOG_LOCAL1", Const, 1}, - {"LOG_LOCAL2", Const, 1}, - {"LOG_LOCAL3", Const, 1}, - {"LOG_LOCAL4", Const, 1}, - {"LOG_LOCAL5", Const, 1}, - {"LOG_LOCAL6", Const, 1}, - {"LOG_LOCAL7", Const, 1}, - {"LOG_LPR", Const, 1}, - {"LOG_MAIL", Const, 1}, - {"LOG_NEWS", Const, 1}, - {"LOG_NOTICE", Const, 0}, - {"LOG_SYSLOG", Const, 1}, - {"LOG_USER", Const, 1}, - {"LOG_UUCP", Const, 1}, - {"LOG_WARNING", Const, 0}, - {"New", Func, 0}, - {"NewLogger", Func, 0}, - {"Priority", Type, 0}, - {"Writer", Type, 0}, - }, - "maps": { - {"All", Func, 23}, - {"Clone", Func, 21}, - {"Collect", Func, 23}, - {"Copy", Func, 21}, - {"DeleteFunc", Func, 21}, - {"Equal", Func, 21}, - {"EqualFunc", Func, 21}, - {"Insert", Func, 23}, - {"Keys", Func, 23}, - {"Values", Func, 23}, - }, - "math": { - {"Abs", Func, 0}, - {"Acos", Func, 0}, - {"Acosh", Func, 0}, - {"Asin", Func, 0}, - {"Asinh", Func, 0}, - {"Atan", Func, 0}, - {"Atan2", Func, 0}, - {"Atanh", Func, 0}, - {"Cbrt", Func, 0}, - {"Ceil", Func, 0}, - {"Copysign", Func, 0}, - {"Cos", Func, 0}, - {"Cosh", Func, 0}, - {"Dim", Func, 0}, - {"E", Const, 0}, - {"Erf", Func, 0}, - {"Erfc", Func, 0}, - {"Erfcinv", Func, 10}, - {"Erfinv", Func, 10}, - {"Exp", Func, 0}, - {"Exp2", Func, 0}, - {"Expm1", Func, 0}, - {"FMA", Func, 14}, - {"Float32bits", Func, 0}, - {"Float32frombits", Func, 0}, - {"Float64bits", Func, 0}, - {"Float64frombits", Func, 0}, - {"Floor", Func, 0}, - {"Frexp", Func, 0}, - {"Gamma", Func, 0}, - {"Hypot", Func, 0}, - {"Ilogb", Func, 0}, - {"Inf", Func, 0}, - {"IsInf", Func, 0}, - {"IsNaN", Func, 0}, - {"J0", Func, 0}, - {"J1", Func, 0}, - {"Jn", Func, 0}, - {"Ldexp", Func, 0}, - {"Lgamma", Func, 0}, - {"Ln10", Const, 0}, - {"Ln2", Const, 0}, - {"Log", Func, 0}, - {"Log10", Func, 0}, - {"Log10E", Const, 0}, - {"Log1p", Func, 0}, - {"Log2", Func, 0}, - {"Log2E", Const, 0}, - {"Logb", Func, 0}, - {"Max", Func, 0}, - {"MaxFloat32", Const, 0}, - {"MaxFloat64", Const, 0}, - {"MaxInt", Const, 17}, - {"MaxInt16", Const, 0}, - {"MaxInt32", Const, 0}, - {"MaxInt64", Const, 0}, - {"MaxInt8", Const, 0}, - {"MaxUint", Const, 17}, - {"MaxUint16", Const, 0}, - {"MaxUint32", Const, 0}, - {"MaxUint64", Const, 0}, - {"MaxUint8", Const, 0}, - {"Min", Func, 0}, - {"MinInt", Const, 17}, - {"MinInt16", Const, 0}, - {"MinInt32", Const, 0}, - {"MinInt64", Const, 0}, - {"MinInt8", Const, 0}, - {"Mod", Func, 0}, - {"Modf", Func, 0}, - {"NaN", Func, 0}, - {"Nextafter", Func, 0}, - {"Nextafter32", Func, 4}, - {"Phi", Const, 0}, - {"Pi", Const, 0}, - {"Pow", Func, 0}, - {"Pow10", Func, 0}, - {"Remainder", Func, 0}, - {"Round", Func, 10}, - {"RoundToEven", Func, 10}, - {"Signbit", Func, 0}, - {"Sin", Func, 0}, - {"Sincos", Func, 0}, - {"Sinh", Func, 0}, - {"SmallestNonzeroFloat32", Const, 0}, - {"SmallestNonzeroFloat64", Const, 0}, - {"Sqrt", Func, 0}, - {"Sqrt2", Const, 0}, - {"SqrtE", Const, 0}, - {"SqrtPhi", Const, 0}, - {"SqrtPi", Const, 0}, - {"Tan", Func, 0}, - {"Tanh", Func, 0}, - {"Trunc", Func, 0}, - {"Y0", Func, 0}, - {"Y1", Func, 0}, - {"Yn", Func, 0}, - }, - "math/big": { - {"(*Float).Abs", Method, 5}, - {"(*Float).Acc", Method, 5}, - {"(*Float).Add", Method, 5}, - {"(*Float).Append", Method, 5}, - {"(*Float).AppendText", Method, 24}, - {"(*Float).Cmp", Method, 5}, - {"(*Float).Copy", Method, 5}, - {"(*Float).Float32", Method, 5}, - {"(*Float).Float64", Method, 5}, - {"(*Float).Format", Method, 5}, - {"(*Float).GobDecode", Method, 7}, - {"(*Float).GobEncode", Method, 7}, - {"(*Float).Int", Method, 5}, - {"(*Float).Int64", Method, 5}, - {"(*Float).IsInf", Method, 5}, - {"(*Float).IsInt", Method, 5}, - {"(*Float).MantExp", Method, 5}, - {"(*Float).MarshalText", Method, 6}, - {"(*Float).MinPrec", Method, 5}, - {"(*Float).Mode", Method, 5}, - {"(*Float).Mul", Method, 5}, - {"(*Float).Neg", Method, 5}, - {"(*Float).Parse", Method, 5}, - {"(*Float).Prec", Method, 5}, - {"(*Float).Quo", Method, 5}, - {"(*Float).Rat", Method, 5}, - {"(*Float).Scan", Method, 8}, - {"(*Float).Set", Method, 5}, - {"(*Float).SetFloat64", Method, 5}, - {"(*Float).SetInf", Method, 5}, - {"(*Float).SetInt", Method, 5}, - {"(*Float).SetInt64", Method, 5}, - {"(*Float).SetMantExp", Method, 5}, - {"(*Float).SetMode", Method, 5}, - {"(*Float).SetPrec", Method, 5}, - {"(*Float).SetRat", Method, 5}, - {"(*Float).SetString", Method, 5}, - {"(*Float).SetUint64", Method, 5}, - {"(*Float).Sign", Method, 5}, - {"(*Float).Signbit", Method, 5}, - {"(*Float).Sqrt", Method, 10}, - {"(*Float).String", Method, 5}, - {"(*Float).Sub", Method, 5}, - {"(*Float).Text", Method, 5}, - {"(*Float).Uint64", Method, 5}, - {"(*Float).UnmarshalText", Method, 6}, - {"(*Int).Abs", Method, 0}, - {"(*Int).Add", Method, 0}, - {"(*Int).And", Method, 0}, - {"(*Int).AndNot", Method, 0}, - {"(*Int).Append", Method, 6}, - {"(*Int).AppendText", Method, 24}, - {"(*Int).Binomial", Method, 0}, - {"(*Int).Bit", Method, 0}, - {"(*Int).BitLen", Method, 0}, - {"(*Int).Bits", Method, 0}, - {"(*Int).Bytes", Method, 0}, - {"(*Int).Cmp", Method, 0}, - {"(*Int).CmpAbs", Method, 10}, - {"(*Int).Div", Method, 0}, - {"(*Int).DivMod", Method, 0}, - {"(*Int).Exp", Method, 0}, - {"(*Int).FillBytes", Method, 15}, - {"(*Int).Float64", Method, 21}, - {"(*Int).Format", Method, 0}, - {"(*Int).GCD", Method, 0}, - {"(*Int).GobDecode", Method, 0}, - {"(*Int).GobEncode", Method, 0}, - {"(*Int).Int64", Method, 0}, - {"(*Int).IsInt64", Method, 9}, - {"(*Int).IsUint64", Method, 9}, - {"(*Int).Lsh", Method, 0}, - {"(*Int).MarshalJSON", Method, 1}, - {"(*Int).MarshalText", Method, 3}, - {"(*Int).Mod", Method, 0}, - {"(*Int).ModInverse", Method, 0}, - {"(*Int).ModSqrt", Method, 5}, - {"(*Int).Mul", Method, 0}, - {"(*Int).MulRange", Method, 0}, - {"(*Int).Neg", Method, 0}, - {"(*Int).Not", Method, 0}, - {"(*Int).Or", Method, 0}, - {"(*Int).ProbablyPrime", Method, 0}, - {"(*Int).Quo", Method, 0}, - {"(*Int).QuoRem", Method, 0}, - {"(*Int).Rand", Method, 0}, - {"(*Int).Rem", Method, 0}, - {"(*Int).Rsh", Method, 0}, - {"(*Int).Scan", Method, 0}, - {"(*Int).Set", Method, 0}, - {"(*Int).SetBit", Method, 0}, - {"(*Int).SetBits", Method, 0}, - {"(*Int).SetBytes", Method, 0}, - {"(*Int).SetInt64", Method, 0}, - {"(*Int).SetString", Method, 0}, - {"(*Int).SetUint64", Method, 1}, - {"(*Int).Sign", Method, 0}, - {"(*Int).Sqrt", Method, 8}, - {"(*Int).String", Method, 0}, - {"(*Int).Sub", Method, 0}, - {"(*Int).Text", Method, 6}, - {"(*Int).TrailingZeroBits", Method, 13}, - {"(*Int).Uint64", Method, 1}, - {"(*Int).UnmarshalJSON", Method, 1}, - {"(*Int).UnmarshalText", Method, 3}, - {"(*Int).Xor", Method, 0}, - {"(*Rat).Abs", Method, 0}, - {"(*Rat).Add", Method, 0}, - {"(*Rat).AppendText", Method, 24}, - {"(*Rat).Cmp", Method, 0}, - {"(*Rat).Denom", Method, 0}, - {"(*Rat).Float32", Method, 4}, - {"(*Rat).Float64", Method, 1}, - {"(*Rat).FloatPrec", Method, 22}, - {"(*Rat).FloatString", Method, 0}, - {"(*Rat).GobDecode", Method, 0}, - {"(*Rat).GobEncode", Method, 0}, - {"(*Rat).Inv", Method, 0}, - {"(*Rat).IsInt", Method, 0}, - {"(*Rat).MarshalText", Method, 3}, - {"(*Rat).Mul", Method, 0}, - {"(*Rat).Neg", Method, 0}, - {"(*Rat).Num", Method, 0}, - {"(*Rat).Quo", Method, 0}, - {"(*Rat).RatString", Method, 0}, - {"(*Rat).Scan", Method, 0}, - {"(*Rat).Set", Method, 0}, - {"(*Rat).SetFloat64", Method, 1}, - {"(*Rat).SetFrac", Method, 0}, - {"(*Rat).SetFrac64", Method, 0}, - {"(*Rat).SetInt", Method, 0}, - {"(*Rat).SetInt64", Method, 0}, - {"(*Rat).SetString", Method, 0}, - {"(*Rat).SetUint64", Method, 13}, - {"(*Rat).Sign", Method, 0}, - {"(*Rat).String", Method, 0}, - {"(*Rat).Sub", Method, 0}, - {"(*Rat).UnmarshalText", Method, 3}, - {"(Accuracy).String", Method, 5}, - {"(ErrNaN).Error", Method, 5}, - {"(RoundingMode).String", Method, 5}, - {"Above", Const, 5}, - {"Accuracy", Type, 5}, - {"AwayFromZero", Const, 5}, - {"Below", Const, 5}, - {"ErrNaN", Type, 5}, - {"Exact", Const, 5}, - {"Float", Type, 5}, - {"Int", Type, 0}, - {"Jacobi", Func, 5}, - {"MaxBase", Const, 0}, - {"MaxExp", Const, 5}, - {"MaxPrec", Const, 5}, - {"MinExp", Const, 5}, - {"NewFloat", Func, 5}, - {"NewInt", Func, 0}, - {"NewRat", Func, 0}, - {"ParseFloat", Func, 5}, - {"Rat", Type, 0}, - {"RoundingMode", Type, 5}, - {"ToNearestAway", Const, 5}, - {"ToNearestEven", Const, 5}, - {"ToNegativeInf", Const, 5}, - {"ToPositiveInf", Const, 5}, - {"ToZero", Const, 5}, - {"Word", Type, 0}, - }, - "math/bits": { - {"Add", Func, 12}, - {"Add32", Func, 12}, - {"Add64", Func, 12}, - {"Div", Func, 12}, - {"Div32", Func, 12}, - {"Div64", Func, 12}, - {"LeadingZeros", Func, 9}, - {"LeadingZeros16", Func, 9}, - {"LeadingZeros32", Func, 9}, - {"LeadingZeros64", Func, 9}, - {"LeadingZeros8", Func, 9}, - {"Len", Func, 9}, - {"Len16", Func, 9}, - {"Len32", Func, 9}, - {"Len64", Func, 9}, - {"Len8", Func, 9}, - {"Mul", Func, 12}, - {"Mul32", Func, 12}, - {"Mul64", Func, 12}, - {"OnesCount", Func, 9}, - {"OnesCount16", Func, 9}, - {"OnesCount32", Func, 9}, - {"OnesCount64", Func, 9}, - {"OnesCount8", Func, 9}, - {"Rem", Func, 14}, - {"Rem32", Func, 14}, - {"Rem64", Func, 14}, - {"Reverse", Func, 9}, - {"Reverse16", Func, 9}, - {"Reverse32", Func, 9}, - {"Reverse64", Func, 9}, - {"Reverse8", Func, 9}, - {"ReverseBytes", Func, 9}, - {"ReverseBytes16", Func, 9}, - {"ReverseBytes32", Func, 9}, - {"ReverseBytes64", Func, 9}, - {"RotateLeft", Func, 9}, - {"RotateLeft16", Func, 9}, - {"RotateLeft32", Func, 9}, - {"RotateLeft64", Func, 9}, - {"RotateLeft8", Func, 9}, - {"Sub", Func, 12}, - {"Sub32", Func, 12}, - {"Sub64", Func, 12}, - {"TrailingZeros", Func, 9}, - {"TrailingZeros16", Func, 9}, - {"TrailingZeros32", Func, 9}, - {"TrailingZeros64", Func, 9}, - {"TrailingZeros8", Func, 9}, - {"UintSize", Const, 9}, - }, - "math/cmplx": { - {"Abs", Func, 0}, - {"Acos", Func, 0}, - {"Acosh", Func, 0}, - {"Asin", Func, 0}, - {"Asinh", Func, 0}, - {"Atan", Func, 0}, - {"Atanh", Func, 0}, - {"Conj", Func, 0}, - {"Cos", Func, 0}, - {"Cosh", Func, 0}, - {"Cot", Func, 0}, - {"Exp", Func, 0}, - {"Inf", Func, 0}, - {"IsInf", Func, 0}, - {"IsNaN", Func, 0}, - {"Log", Func, 0}, - {"Log10", Func, 0}, - {"NaN", Func, 0}, - {"Phase", Func, 0}, - {"Polar", Func, 0}, - {"Pow", Func, 0}, - {"Rect", Func, 0}, - {"Sin", Func, 0}, - {"Sinh", Func, 0}, - {"Sqrt", Func, 0}, - {"Tan", Func, 0}, - {"Tanh", Func, 0}, - }, - "math/rand": { - {"(*Rand).ExpFloat64", Method, 0}, - {"(*Rand).Float32", Method, 0}, - {"(*Rand).Float64", Method, 0}, - {"(*Rand).Int", Method, 0}, - {"(*Rand).Int31", Method, 0}, - {"(*Rand).Int31n", Method, 0}, - {"(*Rand).Int63", Method, 0}, - {"(*Rand).Int63n", Method, 0}, - {"(*Rand).Intn", Method, 0}, - {"(*Rand).NormFloat64", Method, 0}, - {"(*Rand).Perm", Method, 0}, - {"(*Rand).Read", Method, 6}, - {"(*Rand).Seed", Method, 0}, - {"(*Rand).Shuffle", Method, 10}, - {"(*Rand).Uint32", Method, 0}, - {"(*Rand).Uint64", Method, 8}, - {"(*Zipf).Uint64", Method, 0}, - {"ExpFloat64", Func, 0}, - {"Float32", Func, 0}, - {"Float64", Func, 0}, - {"Int", Func, 0}, - {"Int31", Func, 0}, - {"Int31n", Func, 0}, - {"Int63", Func, 0}, - {"Int63n", Func, 0}, - {"Intn", Func, 0}, - {"New", Func, 0}, - {"NewSource", Func, 0}, - {"NewZipf", Func, 0}, - {"NormFloat64", Func, 0}, - {"Perm", Func, 0}, - {"Rand", Type, 0}, - {"Read", Func, 6}, - {"Seed", Func, 0}, - {"Shuffle", Func, 10}, - {"Source", Type, 0}, - {"Source64", Type, 8}, - {"Uint32", Func, 0}, - {"Uint64", Func, 8}, - {"Zipf", Type, 0}, - }, - "math/rand/v2": { - {"(*ChaCha8).AppendBinary", Method, 24}, - {"(*ChaCha8).MarshalBinary", Method, 22}, - {"(*ChaCha8).Read", Method, 23}, - {"(*ChaCha8).Seed", Method, 22}, - {"(*ChaCha8).Uint64", Method, 22}, - {"(*ChaCha8).UnmarshalBinary", Method, 22}, - {"(*PCG).AppendBinary", Method, 24}, - {"(*PCG).MarshalBinary", Method, 22}, - {"(*PCG).Seed", Method, 22}, - {"(*PCG).Uint64", Method, 22}, - {"(*PCG).UnmarshalBinary", Method, 22}, - {"(*Rand).ExpFloat64", Method, 22}, - {"(*Rand).Float32", Method, 22}, - {"(*Rand).Float64", Method, 22}, - {"(*Rand).Int", Method, 22}, - {"(*Rand).Int32", Method, 22}, - {"(*Rand).Int32N", Method, 22}, - {"(*Rand).Int64", Method, 22}, - {"(*Rand).Int64N", Method, 22}, - {"(*Rand).IntN", Method, 22}, - {"(*Rand).NormFloat64", Method, 22}, - {"(*Rand).Perm", Method, 22}, - {"(*Rand).Shuffle", Method, 22}, - {"(*Rand).Uint", Method, 23}, - {"(*Rand).Uint32", Method, 22}, - {"(*Rand).Uint32N", Method, 22}, - {"(*Rand).Uint64", Method, 22}, - {"(*Rand).Uint64N", Method, 22}, - {"(*Rand).UintN", Method, 22}, - {"(*Zipf).Uint64", Method, 22}, - {"ChaCha8", Type, 22}, - {"ExpFloat64", Func, 22}, - {"Float32", Func, 22}, - {"Float64", Func, 22}, - {"Int", Func, 22}, - {"Int32", Func, 22}, - {"Int32N", Func, 22}, - {"Int64", Func, 22}, - {"Int64N", Func, 22}, - {"IntN", Func, 22}, - {"N", Func, 22}, - {"New", Func, 22}, - {"NewChaCha8", Func, 22}, - {"NewPCG", Func, 22}, - {"NewZipf", Func, 22}, - {"NormFloat64", Func, 22}, - {"PCG", Type, 22}, - {"Perm", Func, 22}, - {"Rand", Type, 22}, - {"Shuffle", Func, 22}, - {"Source", Type, 22}, - {"Uint", Func, 23}, - {"Uint32", Func, 22}, - {"Uint32N", Func, 22}, - {"Uint64", Func, 22}, - {"Uint64N", Func, 22}, - {"UintN", Func, 22}, - {"Zipf", Type, 22}, - }, - "mime": { - {"(*WordDecoder).Decode", Method, 5}, - {"(*WordDecoder).DecodeHeader", Method, 5}, - {"(WordEncoder).Encode", Method, 5}, - {"AddExtensionType", Func, 0}, - {"BEncoding", Const, 5}, - {"ErrInvalidMediaParameter", Var, 9}, - {"ExtensionsByType", Func, 5}, - {"FormatMediaType", Func, 0}, - {"ParseMediaType", Func, 0}, - {"QEncoding", Const, 5}, - {"TypeByExtension", Func, 0}, - {"WordDecoder", Type, 5}, - {"WordDecoder.CharsetReader", Field, 5}, - {"WordEncoder", Type, 5}, - }, - "mime/multipart": { - {"(*FileHeader).Open", Method, 0}, - {"(*Form).RemoveAll", Method, 0}, - {"(*Part).Close", Method, 0}, - {"(*Part).FileName", Method, 0}, - {"(*Part).FormName", Method, 0}, - {"(*Part).Read", Method, 0}, - {"(*Reader).NextPart", Method, 0}, - {"(*Reader).NextRawPart", Method, 14}, - {"(*Reader).ReadForm", Method, 0}, - {"(*Writer).Boundary", Method, 0}, - {"(*Writer).Close", Method, 0}, - {"(*Writer).CreateFormField", Method, 0}, - {"(*Writer).CreateFormFile", Method, 0}, - {"(*Writer).CreatePart", Method, 0}, - {"(*Writer).FormDataContentType", Method, 0}, - {"(*Writer).SetBoundary", Method, 1}, - {"(*Writer).WriteField", Method, 0}, - {"ErrMessageTooLarge", Var, 9}, - {"File", Type, 0}, - {"FileHeader", Type, 0}, - {"FileHeader.Filename", Field, 0}, - {"FileHeader.Header", Field, 0}, - {"FileHeader.Size", Field, 9}, - {"Form", Type, 0}, - {"Form.File", Field, 0}, - {"Form.Value", Field, 0}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"Part", Type, 0}, - {"Part.Header", Field, 0}, - {"Reader", Type, 0}, - {"Writer", Type, 0}, - }, - "mime/quotedprintable": { - {"(*Reader).Read", Method, 5}, - {"(*Writer).Close", Method, 5}, - {"(*Writer).Write", Method, 5}, - {"NewReader", Func, 5}, - {"NewWriter", Func, 5}, - {"Reader", Type, 5}, - {"Writer", Type, 5}, - {"Writer.Binary", Field, 5}, - }, - "net": { - {"(*AddrError).Error", Method, 0}, - {"(*AddrError).Temporary", Method, 0}, - {"(*AddrError).Timeout", Method, 0}, - {"(*Buffers).Read", Method, 8}, - {"(*Buffers).WriteTo", Method, 8}, - {"(*DNSConfigError).Error", Method, 0}, - {"(*DNSConfigError).Temporary", Method, 0}, - {"(*DNSConfigError).Timeout", Method, 0}, - {"(*DNSConfigError).Unwrap", Method, 13}, - {"(*DNSError).Error", Method, 0}, - {"(*DNSError).Temporary", Method, 0}, - {"(*DNSError).Timeout", Method, 0}, - {"(*DNSError).Unwrap", Method, 23}, - {"(*Dialer).Dial", Method, 1}, - {"(*Dialer).DialContext", Method, 7}, - {"(*Dialer).MultipathTCP", Method, 21}, - {"(*Dialer).SetMultipathTCP", Method, 21}, - {"(*IP).UnmarshalText", Method, 2}, - {"(*IPAddr).Network", Method, 0}, - {"(*IPAddr).String", Method, 0}, - {"(*IPConn).Close", Method, 0}, - {"(*IPConn).File", Method, 0}, - {"(*IPConn).LocalAddr", Method, 0}, - {"(*IPConn).Read", Method, 0}, - {"(*IPConn).ReadFrom", Method, 0}, - {"(*IPConn).ReadFromIP", Method, 0}, - {"(*IPConn).ReadMsgIP", Method, 1}, - {"(*IPConn).RemoteAddr", Method, 0}, - {"(*IPConn).SetDeadline", Method, 0}, - {"(*IPConn).SetReadBuffer", Method, 0}, - {"(*IPConn).SetReadDeadline", Method, 0}, - {"(*IPConn).SetWriteBuffer", Method, 0}, - {"(*IPConn).SetWriteDeadline", Method, 0}, - {"(*IPConn).SyscallConn", Method, 9}, - {"(*IPConn).Write", Method, 0}, - {"(*IPConn).WriteMsgIP", Method, 1}, - {"(*IPConn).WriteTo", Method, 0}, - {"(*IPConn).WriteToIP", Method, 0}, - {"(*IPNet).Contains", Method, 0}, - {"(*IPNet).Network", Method, 0}, - {"(*IPNet).String", Method, 0}, - {"(*Interface).Addrs", Method, 0}, - {"(*Interface).MulticastAddrs", Method, 0}, - {"(*ListenConfig).Listen", Method, 11}, - {"(*ListenConfig).ListenPacket", Method, 11}, - {"(*ListenConfig).MultipathTCP", Method, 21}, - {"(*ListenConfig).SetMultipathTCP", Method, 21}, - {"(*OpError).Error", Method, 0}, - {"(*OpError).Temporary", Method, 0}, - {"(*OpError).Timeout", Method, 0}, - {"(*OpError).Unwrap", Method, 13}, - {"(*ParseError).Error", Method, 0}, - {"(*ParseError).Temporary", Method, 17}, - {"(*ParseError).Timeout", Method, 17}, - {"(*Resolver).LookupAddr", Method, 8}, - {"(*Resolver).LookupCNAME", Method, 8}, - {"(*Resolver).LookupHost", Method, 8}, - {"(*Resolver).LookupIP", Method, 15}, - {"(*Resolver).LookupIPAddr", Method, 8}, - {"(*Resolver).LookupMX", Method, 8}, - {"(*Resolver).LookupNS", Method, 8}, - {"(*Resolver).LookupNetIP", Method, 18}, - {"(*Resolver).LookupPort", Method, 8}, - {"(*Resolver).LookupSRV", Method, 8}, - {"(*Resolver).LookupTXT", Method, 8}, - {"(*TCPAddr).AddrPort", Method, 18}, - {"(*TCPAddr).Network", Method, 0}, - {"(*TCPAddr).String", Method, 0}, - {"(*TCPConn).Close", Method, 0}, - {"(*TCPConn).CloseRead", Method, 0}, - {"(*TCPConn).CloseWrite", Method, 0}, - {"(*TCPConn).File", Method, 0}, - {"(*TCPConn).LocalAddr", Method, 0}, - {"(*TCPConn).MultipathTCP", Method, 21}, - {"(*TCPConn).Read", Method, 0}, - {"(*TCPConn).ReadFrom", Method, 0}, - {"(*TCPConn).RemoteAddr", Method, 0}, - {"(*TCPConn).SetDeadline", Method, 0}, - {"(*TCPConn).SetKeepAlive", Method, 0}, - {"(*TCPConn).SetKeepAliveConfig", Method, 23}, - {"(*TCPConn).SetKeepAlivePeriod", Method, 2}, - {"(*TCPConn).SetLinger", Method, 0}, - {"(*TCPConn).SetNoDelay", Method, 0}, - {"(*TCPConn).SetReadBuffer", Method, 0}, - {"(*TCPConn).SetReadDeadline", Method, 0}, - {"(*TCPConn).SetWriteBuffer", Method, 0}, - {"(*TCPConn).SetWriteDeadline", Method, 0}, - {"(*TCPConn).SyscallConn", Method, 9}, - {"(*TCPConn).Write", Method, 0}, - {"(*TCPConn).WriteTo", Method, 22}, - {"(*TCPListener).Accept", Method, 0}, - {"(*TCPListener).AcceptTCP", Method, 0}, - {"(*TCPListener).Addr", Method, 0}, - {"(*TCPListener).Close", Method, 0}, - {"(*TCPListener).File", Method, 0}, - {"(*TCPListener).SetDeadline", Method, 0}, - {"(*TCPListener).SyscallConn", Method, 10}, - {"(*UDPAddr).AddrPort", Method, 18}, - {"(*UDPAddr).Network", Method, 0}, - {"(*UDPAddr).String", Method, 0}, - {"(*UDPConn).Close", Method, 0}, - {"(*UDPConn).File", Method, 0}, - {"(*UDPConn).LocalAddr", Method, 0}, - {"(*UDPConn).Read", Method, 0}, - {"(*UDPConn).ReadFrom", Method, 0}, - {"(*UDPConn).ReadFromUDP", Method, 0}, - {"(*UDPConn).ReadFromUDPAddrPort", Method, 18}, - {"(*UDPConn).ReadMsgUDP", Method, 1}, - {"(*UDPConn).ReadMsgUDPAddrPort", Method, 18}, - {"(*UDPConn).RemoteAddr", Method, 0}, - {"(*UDPConn).SetDeadline", Method, 0}, - {"(*UDPConn).SetReadBuffer", Method, 0}, - {"(*UDPConn).SetReadDeadline", Method, 0}, - {"(*UDPConn).SetWriteBuffer", Method, 0}, - {"(*UDPConn).SetWriteDeadline", Method, 0}, - {"(*UDPConn).SyscallConn", Method, 9}, - {"(*UDPConn).Write", Method, 0}, - {"(*UDPConn).WriteMsgUDP", Method, 1}, - {"(*UDPConn).WriteMsgUDPAddrPort", Method, 18}, - {"(*UDPConn).WriteTo", Method, 0}, - {"(*UDPConn).WriteToUDP", Method, 0}, - {"(*UDPConn).WriteToUDPAddrPort", Method, 18}, - {"(*UnixAddr).Network", Method, 0}, - {"(*UnixAddr).String", Method, 0}, - {"(*UnixConn).Close", Method, 0}, - {"(*UnixConn).CloseRead", Method, 1}, - {"(*UnixConn).CloseWrite", Method, 1}, - {"(*UnixConn).File", Method, 0}, - {"(*UnixConn).LocalAddr", Method, 0}, - {"(*UnixConn).Read", Method, 0}, - {"(*UnixConn).ReadFrom", Method, 0}, - {"(*UnixConn).ReadFromUnix", Method, 0}, - {"(*UnixConn).ReadMsgUnix", Method, 0}, - {"(*UnixConn).RemoteAddr", Method, 0}, - {"(*UnixConn).SetDeadline", Method, 0}, - {"(*UnixConn).SetReadBuffer", Method, 0}, - {"(*UnixConn).SetReadDeadline", Method, 0}, - {"(*UnixConn).SetWriteBuffer", Method, 0}, - {"(*UnixConn).SetWriteDeadline", Method, 0}, - {"(*UnixConn).SyscallConn", Method, 9}, - {"(*UnixConn).Write", Method, 0}, - {"(*UnixConn).WriteMsgUnix", Method, 0}, - {"(*UnixConn).WriteTo", Method, 0}, - {"(*UnixConn).WriteToUnix", Method, 0}, - {"(*UnixListener).Accept", Method, 0}, - {"(*UnixListener).AcceptUnix", Method, 0}, - {"(*UnixListener).Addr", Method, 0}, - {"(*UnixListener).Close", Method, 0}, - {"(*UnixListener).File", Method, 0}, - {"(*UnixListener).SetDeadline", Method, 0}, - {"(*UnixListener).SetUnlinkOnClose", Method, 8}, - {"(*UnixListener).SyscallConn", Method, 10}, - {"(Flags).String", Method, 0}, - {"(HardwareAddr).String", Method, 0}, - {"(IP).AppendText", Method, 24}, - {"(IP).DefaultMask", Method, 0}, - {"(IP).Equal", Method, 0}, - {"(IP).IsGlobalUnicast", Method, 0}, - {"(IP).IsInterfaceLocalMulticast", Method, 0}, - {"(IP).IsLinkLocalMulticast", Method, 0}, - {"(IP).IsLinkLocalUnicast", Method, 0}, - {"(IP).IsLoopback", Method, 0}, - {"(IP).IsMulticast", Method, 0}, - {"(IP).IsPrivate", Method, 17}, - {"(IP).IsUnspecified", Method, 0}, - {"(IP).MarshalText", Method, 2}, - {"(IP).Mask", Method, 0}, - {"(IP).String", Method, 0}, - {"(IP).To16", Method, 0}, - {"(IP).To4", Method, 0}, - {"(IPMask).Size", Method, 0}, - {"(IPMask).String", Method, 0}, - {"(InvalidAddrError).Error", Method, 0}, - {"(InvalidAddrError).Temporary", Method, 0}, - {"(InvalidAddrError).Timeout", Method, 0}, - {"(UnknownNetworkError).Error", Method, 0}, - {"(UnknownNetworkError).Temporary", Method, 0}, - {"(UnknownNetworkError).Timeout", Method, 0}, - {"Addr", Type, 0}, - {"AddrError", Type, 0}, - {"AddrError.Addr", Field, 0}, - {"AddrError.Err", Field, 0}, - {"Buffers", Type, 8}, - {"CIDRMask", Func, 0}, - {"Conn", Type, 0}, - {"DNSConfigError", Type, 0}, - {"DNSConfigError.Err", Field, 0}, - {"DNSError", Type, 0}, - {"DNSError.Err", Field, 0}, - {"DNSError.IsNotFound", Field, 13}, - {"DNSError.IsTemporary", Field, 6}, - {"DNSError.IsTimeout", Field, 0}, - {"DNSError.Name", Field, 0}, - {"DNSError.Server", Field, 0}, - {"DNSError.UnwrapErr", Field, 23}, - {"DefaultResolver", Var, 8}, - {"Dial", Func, 0}, - {"DialIP", Func, 0}, - {"DialTCP", Func, 0}, - {"DialTimeout", Func, 0}, - {"DialUDP", Func, 0}, - {"DialUnix", Func, 0}, - {"Dialer", Type, 1}, - {"Dialer.Cancel", Field, 6}, - {"Dialer.Control", Field, 11}, - {"Dialer.ControlContext", Field, 20}, - {"Dialer.Deadline", Field, 1}, - {"Dialer.DualStack", Field, 2}, - {"Dialer.FallbackDelay", Field, 5}, - {"Dialer.KeepAlive", Field, 3}, - {"Dialer.KeepAliveConfig", Field, 23}, - {"Dialer.LocalAddr", Field, 1}, - {"Dialer.Resolver", Field, 8}, - {"Dialer.Timeout", Field, 1}, - {"ErrClosed", Var, 16}, - {"ErrWriteToConnected", Var, 0}, - {"Error", Type, 0}, - {"FileConn", Func, 0}, - {"FileListener", Func, 0}, - {"FilePacketConn", Func, 0}, - {"FlagBroadcast", Const, 0}, - {"FlagLoopback", Const, 0}, - {"FlagMulticast", Const, 0}, - {"FlagPointToPoint", Const, 0}, - {"FlagRunning", Const, 20}, - {"FlagUp", Const, 0}, - {"Flags", Type, 0}, - {"HardwareAddr", Type, 0}, - {"IP", Type, 0}, - {"IPAddr", Type, 0}, - {"IPAddr.IP", Field, 0}, - {"IPAddr.Zone", Field, 1}, - {"IPConn", Type, 0}, - {"IPMask", Type, 0}, - {"IPNet", Type, 0}, - {"IPNet.IP", Field, 0}, - {"IPNet.Mask", Field, 0}, - {"IPv4", Func, 0}, - {"IPv4Mask", Func, 0}, - {"IPv4allrouter", Var, 0}, - {"IPv4allsys", Var, 0}, - {"IPv4bcast", Var, 0}, - {"IPv4len", Const, 0}, - {"IPv4zero", Var, 0}, - {"IPv6interfacelocalallnodes", Var, 0}, - {"IPv6len", Const, 0}, - {"IPv6linklocalallnodes", Var, 0}, - {"IPv6linklocalallrouters", Var, 0}, - {"IPv6loopback", Var, 0}, - {"IPv6unspecified", Var, 0}, - {"IPv6zero", Var, 0}, - {"Interface", Type, 0}, - {"Interface.Flags", Field, 0}, - {"Interface.HardwareAddr", Field, 0}, - {"Interface.Index", Field, 0}, - {"Interface.MTU", Field, 0}, - {"Interface.Name", Field, 0}, - {"InterfaceAddrs", Func, 0}, - {"InterfaceByIndex", Func, 0}, - {"InterfaceByName", Func, 0}, - {"Interfaces", Func, 0}, - {"InvalidAddrError", Type, 0}, - {"JoinHostPort", Func, 0}, - {"KeepAliveConfig", Type, 23}, - {"KeepAliveConfig.Count", Field, 23}, - {"KeepAliveConfig.Enable", Field, 23}, - {"KeepAliveConfig.Idle", Field, 23}, - {"KeepAliveConfig.Interval", Field, 23}, - {"Listen", Func, 0}, - {"ListenConfig", Type, 11}, - {"ListenConfig.Control", Field, 11}, - {"ListenConfig.KeepAlive", Field, 13}, - {"ListenConfig.KeepAliveConfig", Field, 23}, - {"ListenIP", Func, 0}, - {"ListenMulticastUDP", Func, 0}, - {"ListenPacket", Func, 0}, - {"ListenTCP", Func, 0}, - {"ListenUDP", Func, 0}, - {"ListenUnix", Func, 0}, - {"ListenUnixgram", Func, 0}, - {"Listener", Type, 0}, - {"LookupAddr", Func, 0}, - {"LookupCNAME", Func, 0}, - {"LookupHost", Func, 0}, - {"LookupIP", Func, 0}, - {"LookupMX", Func, 0}, - {"LookupNS", Func, 1}, - {"LookupPort", Func, 0}, - {"LookupSRV", Func, 0}, - {"LookupTXT", Func, 0}, - {"MX", Type, 0}, - {"MX.Host", Field, 0}, - {"MX.Pref", Field, 0}, - {"NS", Type, 1}, - {"NS.Host", Field, 1}, - {"OpError", Type, 0}, - {"OpError.Addr", Field, 0}, - {"OpError.Err", Field, 0}, - {"OpError.Net", Field, 0}, - {"OpError.Op", Field, 0}, - {"OpError.Source", Field, 5}, - {"PacketConn", Type, 0}, - {"ParseCIDR", Func, 0}, - {"ParseError", Type, 0}, - {"ParseError.Text", Field, 0}, - {"ParseError.Type", Field, 0}, - {"ParseIP", Func, 0}, - {"ParseMAC", Func, 0}, - {"Pipe", Func, 0}, - {"ResolveIPAddr", Func, 0}, - {"ResolveTCPAddr", Func, 0}, - {"ResolveUDPAddr", Func, 0}, - {"ResolveUnixAddr", Func, 0}, - {"Resolver", Type, 8}, - {"Resolver.Dial", Field, 9}, - {"Resolver.PreferGo", Field, 8}, - {"Resolver.StrictErrors", Field, 9}, - {"SRV", Type, 0}, - {"SRV.Port", Field, 0}, - {"SRV.Priority", Field, 0}, - {"SRV.Target", Field, 0}, - {"SRV.Weight", Field, 0}, - {"SplitHostPort", Func, 0}, - {"TCPAddr", Type, 0}, - {"TCPAddr.IP", Field, 0}, - {"TCPAddr.Port", Field, 0}, - {"TCPAddr.Zone", Field, 1}, - {"TCPAddrFromAddrPort", Func, 18}, - {"TCPConn", Type, 0}, - {"TCPListener", Type, 0}, - {"UDPAddr", Type, 0}, - {"UDPAddr.IP", Field, 0}, - {"UDPAddr.Port", Field, 0}, - {"UDPAddr.Zone", Field, 1}, - {"UDPAddrFromAddrPort", Func, 18}, - {"UDPConn", Type, 0}, - {"UnixAddr", Type, 0}, - {"UnixAddr.Name", Field, 0}, - {"UnixAddr.Net", Field, 0}, - {"UnixConn", Type, 0}, - {"UnixListener", Type, 0}, - {"UnknownNetworkError", Type, 0}, - }, - "net/http": { - {"(*Client).CloseIdleConnections", Method, 12}, - {"(*Client).Do", Method, 0}, - {"(*Client).Get", Method, 0}, - {"(*Client).Head", Method, 0}, - {"(*Client).Post", Method, 0}, - {"(*Client).PostForm", Method, 0}, - {"(*Cookie).String", Method, 0}, - {"(*Cookie).Valid", Method, 18}, - {"(*MaxBytesError).Error", Method, 19}, - {"(*ProtocolError).Error", Method, 0}, - {"(*ProtocolError).Is", Method, 21}, - {"(*Protocols).SetHTTP1", Method, 24}, - {"(*Protocols).SetHTTP2", Method, 24}, - {"(*Protocols).SetUnencryptedHTTP2", Method, 24}, - {"(*Request).AddCookie", Method, 0}, - {"(*Request).BasicAuth", Method, 4}, - {"(*Request).Clone", Method, 13}, - {"(*Request).Context", Method, 7}, - {"(*Request).Cookie", Method, 0}, - {"(*Request).Cookies", Method, 0}, - {"(*Request).CookiesNamed", Method, 23}, - {"(*Request).FormFile", Method, 0}, - {"(*Request).FormValue", Method, 0}, - {"(*Request).MultipartReader", Method, 0}, - {"(*Request).ParseForm", Method, 0}, - {"(*Request).ParseMultipartForm", Method, 0}, - {"(*Request).PathValue", Method, 22}, - {"(*Request).PostFormValue", Method, 1}, - {"(*Request).ProtoAtLeast", Method, 0}, - {"(*Request).Referer", Method, 0}, - {"(*Request).SetBasicAuth", Method, 0}, - {"(*Request).SetPathValue", Method, 22}, - {"(*Request).UserAgent", Method, 0}, - {"(*Request).WithContext", Method, 7}, - {"(*Request).Write", Method, 0}, - {"(*Request).WriteProxy", Method, 0}, - {"(*Response).Cookies", Method, 0}, - {"(*Response).Location", Method, 0}, - {"(*Response).ProtoAtLeast", Method, 0}, - {"(*Response).Write", Method, 0}, - {"(*ResponseController).EnableFullDuplex", Method, 21}, - {"(*ResponseController).Flush", Method, 20}, - {"(*ResponseController).Hijack", Method, 20}, - {"(*ResponseController).SetReadDeadline", Method, 20}, - {"(*ResponseController).SetWriteDeadline", Method, 20}, - {"(*ServeMux).Handle", Method, 0}, - {"(*ServeMux).HandleFunc", Method, 0}, - {"(*ServeMux).Handler", Method, 1}, - {"(*ServeMux).ServeHTTP", Method, 0}, - {"(*Server).Close", Method, 8}, - {"(*Server).ListenAndServe", Method, 0}, - {"(*Server).ListenAndServeTLS", Method, 0}, - {"(*Server).RegisterOnShutdown", Method, 9}, - {"(*Server).Serve", Method, 0}, - {"(*Server).ServeTLS", Method, 9}, - {"(*Server).SetKeepAlivesEnabled", Method, 3}, - {"(*Server).Shutdown", Method, 8}, - {"(*Transport).CancelRequest", Method, 1}, - {"(*Transport).Clone", Method, 13}, - {"(*Transport).CloseIdleConnections", Method, 0}, - {"(*Transport).RegisterProtocol", Method, 0}, - {"(*Transport).RoundTrip", Method, 0}, - {"(ConnState).String", Method, 3}, - {"(Dir).Open", Method, 0}, - {"(HandlerFunc).ServeHTTP", Method, 0}, - {"(Header).Add", Method, 0}, - {"(Header).Clone", Method, 13}, - {"(Header).Del", Method, 0}, - {"(Header).Get", Method, 0}, - {"(Header).Set", Method, 0}, - {"(Header).Values", Method, 14}, - {"(Header).Write", Method, 0}, - {"(Header).WriteSubset", Method, 0}, - {"(Protocols).HTTP1", Method, 24}, - {"(Protocols).HTTP2", Method, 24}, - {"(Protocols).String", Method, 24}, - {"(Protocols).UnencryptedHTTP2", Method, 24}, - {"AllowQuerySemicolons", Func, 17}, - {"CanonicalHeaderKey", Func, 0}, - {"Client", Type, 0}, - {"Client.CheckRedirect", Field, 0}, - {"Client.Jar", Field, 0}, - {"Client.Timeout", Field, 3}, - {"Client.Transport", Field, 0}, - {"CloseNotifier", Type, 1}, - {"ConnState", Type, 3}, - {"Cookie", Type, 0}, - {"Cookie.Domain", Field, 0}, - {"Cookie.Expires", Field, 0}, - {"Cookie.HttpOnly", Field, 0}, - {"Cookie.MaxAge", Field, 0}, - {"Cookie.Name", Field, 0}, - {"Cookie.Partitioned", Field, 23}, - {"Cookie.Path", Field, 0}, - {"Cookie.Quoted", Field, 23}, - {"Cookie.Raw", Field, 0}, - {"Cookie.RawExpires", Field, 0}, - {"Cookie.SameSite", Field, 11}, - {"Cookie.Secure", Field, 0}, - {"Cookie.Unparsed", Field, 0}, - {"Cookie.Value", Field, 0}, - {"CookieJar", Type, 0}, - {"DefaultClient", Var, 0}, - {"DefaultMaxHeaderBytes", Const, 0}, - {"DefaultMaxIdleConnsPerHost", Const, 0}, - {"DefaultServeMux", Var, 0}, - {"DefaultTransport", Var, 0}, - {"DetectContentType", Func, 0}, - {"Dir", Type, 0}, - {"ErrAbortHandler", Var, 8}, - {"ErrBodyNotAllowed", Var, 0}, - {"ErrBodyReadAfterClose", Var, 0}, - {"ErrContentLength", Var, 0}, - {"ErrHandlerTimeout", Var, 0}, - {"ErrHeaderTooLong", Var, 0}, - {"ErrHijacked", Var, 0}, - {"ErrLineTooLong", Var, 0}, - {"ErrMissingBoundary", Var, 0}, - {"ErrMissingContentLength", Var, 0}, - {"ErrMissingFile", Var, 0}, - {"ErrNoCookie", Var, 0}, - {"ErrNoLocation", Var, 0}, - {"ErrNotMultipart", Var, 0}, - {"ErrNotSupported", Var, 0}, - {"ErrSchemeMismatch", Var, 21}, - {"ErrServerClosed", Var, 8}, - {"ErrShortBody", Var, 0}, - {"ErrSkipAltProtocol", Var, 6}, - {"ErrUnexpectedTrailer", Var, 0}, - {"ErrUseLastResponse", Var, 7}, - {"ErrWriteAfterFlush", Var, 0}, - {"Error", Func, 0}, - {"FS", Func, 16}, - {"File", Type, 0}, - {"FileServer", Func, 0}, - {"FileServerFS", Func, 22}, - {"FileSystem", Type, 0}, - {"Flusher", Type, 0}, - {"Get", Func, 0}, - {"HTTP2Config", Type, 24}, - {"HTTP2Config.CountError", Field, 24}, - {"HTTP2Config.MaxConcurrentStreams", Field, 24}, - {"HTTP2Config.MaxDecoderHeaderTableSize", Field, 24}, - {"HTTP2Config.MaxEncoderHeaderTableSize", Field, 24}, - {"HTTP2Config.MaxReadFrameSize", Field, 24}, - {"HTTP2Config.MaxReceiveBufferPerConnection", Field, 24}, - {"HTTP2Config.MaxReceiveBufferPerStream", Field, 24}, - {"HTTP2Config.PermitProhibitedCipherSuites", Field, 24}, - {"HTTP2Config.PingTimeout", Field, 24}, - {"HTTP2Config.SendPingTimeout", Field, 24}, - {"HTTP2Config.WriteByteTimeout", Field, 24}, - {"Handle", Func, 0}, - {"HandleFunc", Func, 0}, - {"Handler", Type, 0}, - {"HandlerFunc", Type, 0}, - {"Head", Func, 0}, - {"Header", Type, 0}, - {"Hijacker", Type, 0}, - {"ListenAndServe", Func, 0}, - {"ListenAndServeTLS", Func, 0}, - {"LocalAddrContextKey", Var, 7}, - {"MaxBytesError", Type, 19}, - {"MaxBytesError.Limit", Field, 19}, - {"MaxBytesHandler", Func, 18}, - {"MaxBytesReader", Func, 0}, - {"MethodConnect", Const, 6}, - {"MethodDelete", Const, 6}, - {"MethodGet", Const, 6}, - {"MethodHead", Const, 6}, - {"MethodOptions", Const, 6}, - {"MethodPatch", Const, 6}, - {"MethodPost", Const, 6}, - {"MethodPut", Const, 6}, - {"MethodTrace", Const, 6}, - {"NewFileTransport", Func, 0}, - {"NewFileTransportFS", Func, 22}, - {"NewRequest", Func, 0}, - {"NewRequestWithContext", Func, 13}, - {"NewResponseController", Func, 20}, - {"NewServeMux", Func, 0}, - {"NoBody", Var, 8}, - {"NotFound", Func, 0}, - {"NotFoundHandler", Func, 0}, - {"ParseCookie", Func, 23}, - {"ParseHTTPVersion", Func, 0}, - {"ParseSetCookie", Func, 23}, - {"ParseTime", Func, 1}, - {"Post", Func, 0}, - {"PostForm", Func, 0}, - {"ProtocolError", Type, 0}, - {"ProtocolError.ErrorString", Field, 0}, - {"Protocols", Type, 24}, - {"ProxyFromEnvironment", Func, 0}, - {"ProxyURL", Func, 0}, - {"PushOptions", Type, 8}, - {"PushOptions.Header", Field, 8}, - {"PushOptions.Method", Field, 8}, - {"Pusher", Type, 8}, - {"ReadRequest", Func, 0}, - {"ReadResponse", Func, 0}, - {"Redirect", Func, 0}, - {"RedirectHandler", Func, 0}, - {"Request", Type, 0}, - {"Request.Body", Field, 0}, - {"Request.Cancel", Field, 5}, - {"Request.Close", Field, 0}, - {"Request.ContentLength", Field, 0}, - {"Request.Form", Field, 0}, - {"Request.GetBody", Field, 8}, - {"Request.Header", Field, 0}, - {"Request.Host", Field, 0}, - {"Request.Method", Field, 0}, - {"Request.MultipartForm", Field, 0}, - {"Request.Pattern", Field, 23}, - {"Request.PostForm", Field, 1}, - {"Request.Proto", Field, 0}, - {"Request.ProtoMajor", Field, 0}, - {"Request.ProtoMinor", Field, 0}, - {"Request.RemoteAddr", Field, 0}, - {"Request.RequestURI", Field, 0}, - {"Request.Response", Field, 7}, - {"Request.TLS", Field, 0}, - {"Request.Trailer", Field, 0}, - {"Request.TransferEncoding", Field, 0}, - {"Request.URL", Field, 0}, - {"Response", Type, 0}, - {"Response.Body", Field, 0}, - {"Response.Close", Field, 0}, - {"Response.ContentLength", Field, 0}, - {"Response.Header", Field, 0}, - {"Response.Proto", Field, 0}, - {"Response.ProtoMajor", Field, 0}, - {"Response.ProtoMinor", Field, 0}, - {"Response.Request", Field, 0}, - {"Response.Status", Field, 0}, - {"Response.StatusCode", Field, 0}, - {"Response.TLS", Field, 3}, - {"Response.Trailer", Field, 0}, - {"Response.TransferEncoding", Field, 0}, - {"Response.Uncompressed", Field, 7}, - {"ResponseController", Type, 20}, - {"ResponseWriter", Type, 0}, - {"RoundTripper", Type, 0}, - {"SameSite", Type, 11}, - {"SameSiteDefaultMode", Const, 11}, - {"SameSiteLaxMode", Const, 11}, - {"SameSiteNoneMode", Const, 13}, - {"SameSiteStrictMode", Const, 11}, - {"Serve", Func, 0}, - {"ServeContent", Func, 0}, - {"ServeFile", Func, 0}, - {"ServeFileFS", Func, 22}, - {"ServeMux", Type, 0}, - {"ServeTLS", Func, 9}, - {"Server", Type, 0}, - {"Server.Addr", Field, 0}, - {"Server.BaseContext", Field, 13}, - {"Server.ConnContext", Field, 13}, - {"Server.ConnState", Field, 3}, - {"Server.DisableGeneralOptionsHandler", Field, 20}, - {"Server.ErrorLog", Field, 3}, - {"Server.HTTP2", Field, 24}, - {"Server.Handler", Field, 0}, - {"Server.IdleTimeout", Field, 8}, - {"Server.MaxHeaderBytes", Field, 0}, - {"Server.Protocols", Field, 24}, - {"Server.ReadHeaderTimeout", Field, 8}, - {"Server.ReadTimeout", Field, 0}, - {"Server.TLSConfig", Field, 0}, - {"Server.TLSNextProto", Field, 1}, - {"Server.WriteTimeout", Field, 0}, - {"ServerContextKey", Var, 7}, - {"SetCookie", Func, 0}, - {"StateActive", Const, 3}, - {"StateClosed", Const, 3}, - {"StateHijacked", Const, 3}, - {"StateIdle", Const, 3}, - {"StateNew", Const, 3}, - {"StatusAccepted", Const, 0}, - {"StatusAlreadyReported", Const, 7}, - {"StatusBadGateway", Const, 0}, - {"StatusBadRequest", Const, 0}, - {"StatusConflict", Const, 0}, - {"StatusContinue", Const, 0}, - {"StatusCreated", Const, 0}, - {"StatusEarlyHints", Const, 13}, - {"StatusExpectationFailed", Const, 0}, - {"StatusFailedDependency", Const, 7}, - {"StatusForbidden", Const, 0}, - {"StatusFound", Const, 0}, - {"StatusGatewayTimeout", Const, 0}, - {"StatusGone", Const, 0}, - {"StatusHTTPVersionNotSupported", Const, 0}, - {"StatusIMUsed", Const, 7}, - {"StatusInsufficientStorage", Const, 7}, - {"StatusInternalServerError", Const, 0}, - {"StatusLengthRequired", Const, 0}, - {"StatusLocked", Const, 7}, - {"StatusLoopDetected", Const, 7}, - {"StatusMethodNotAllowed", Const, 0}, - {"StatusMisdirectedRequest", Const, 11}, - {"StatusMovedPermanently", Const, 0}, - {"StatusMultiStatus", Const, 7}, - {"StatusMultipleChoices", Const, 0}, - {"StatusNetworkAuthenticationRequired", Const, 6}, - {"StatusNoContent", Const, 0}, - {"StatusNonAuthoritativeInfo", Const, 0}, - {"StatusNotAcceptable", Const, 0}, - {"StatusNotExtended", Const, 7}, - {"StatusNotFound", Const, 0}, - {"StatusNotImplemented", Const, 0}, - {"StatusNotModified", Const, 0}, - {"StatusOK", Const, 0}, - {"StatusPartialContent", Const, 0}, - {"StatusPaymentRequired", Const, 0}, - {"StatusPermanentRedirect", Const, 7}, - {"StatusPreconditionFailed", Const, 0}, - {"StatusPreconditionRequired", Const, 6}, - {"StatusProcessing", Const, 7}, - {"StatusProxyAuthRequired", Const, 0}, - {"StatusRequestEntityTooLarge", Const, 0}, - {"StatusRequestHeaderFieldsTooLarge", Const, 6}, - {"StatusRequestTimeout", Const, 0}, - {"StatusRequestURITooLong", Const, 0}, - {"StatusRequestedRangeNotSatisfiable", Const, 0}, - {"StatusResetContent", Const, 0}, - {"StatusSeeOther", Const, 0}, - {"StatusServiceUnavailable", Const, 0}, - {"StatusSwitchingProtocols", Const, 0}, - {"StatusTeapot", Const, 0}, - {"StatusTemporaryRedirect", Const, 0}, - {"StatusText", Func, 0}, - {"StatusTooEarly", Const, 12}, - {"StatusTooManyRequests", Const, 6}, - {"StatusUnauthorized", Const, 0}, - {"StatusUnavailableForLegalReasons", Const, 6}, - {"StatusUnprocessableEntity", Const, 7}, - {"StatusUnsupportedMediaType", Const, 0}, - {"StatusUpgradeRequired", Const, 7}, - {"StatusUseProxy", Const, 0}, - {"StatusVariantAlsoNegotiates", Const, 7}, - {"StripPrefix", Func, 0}, - {"TimeFormat", Const, 0}, - {"TimeoutHandler", Func, 0}, - {"TrailerPrefix", Const, 8}, - {"Transport", Type, 0}, - {"Transport.Dial", Field, 0}, - {"Transport.DialContext", Field, 7}, - {"Transport.DialTLS", Field, 4}, - {"Transport.DialTLSContext", Field, 14}, - {"Transport.DisableCompression", Field, 0}, - {"Transport.DisableKeepAlives", Field, 0}, - {"Transport.ExpectContinueTimeout", Field, 6}, - {"Transport.ForceAttemptHTTP2", Field, 13}, - {"Transport.GetProxyConnectHeader", Field, 16}, - {"Transport.HTTP2", Field, 24}, - {"Transport.IdleConnTimeout", Field, 7}, - {"Transport.MaxConnsPerHost", Field, 11}, - {"Transport.MaxIdleConns", Field, 7}, - {"Transport.MaxIdleConnsPerHost", Field, 0}, - {"Transport.MaxResponseHeaderBytes", Field, 7}, - {"Transport.OnProxyConnectResponse", Field, 20}, - {"Transport.Protocols", Field, 24}, - {"Transport.Proxy", Field, 0}, - {"Transport.ProxyConnectHeader", Field, 8}, - {"Transport.ReadBufferSize", Field, 13}, - {"Transport.ResponseHeaderTimeout", Field, 1}, - {"Transport.TLSClientConfig", Field, 0}, - {"Transport.TLSHandshakeTimeout", Field, 3}, - {"Transport.TLSNextProto", Field, 6}, - {"Transport.WriteBufferSize", Field, 13}, - }, - "net/http/cgi": { - {"(*Handler).ServeHTTP", Method, 0}, - {"Handler", Type, 0}, - {"Handler.Args", Field, 0}, - {"Handler.Dir", Field, 0}, - {"Handler.Env", Field, 0}, - {"Handler.InheritEnv", Field, 0}, - {"Handler.Logger", Field, 0}, - {"Handler.Path", Field, 0}, - {"Handler.PathLocationHandler", Field, 0}, - {"Handler.Root", Field, 0}, - {"Handler.Stderr", Field, 7}, - {"Request", Func, 0}, - {"RequestFromMap", Func, 0}, - {"Serve", Func, 0}, - }, - "net/http/cookiejar": { - {"(*Jar).Cookies", Method, 1}, - {"(*Jar).SetCookies", Method, 1}, - {"Jar", Type, 1}, - {"New", Func, 1}, - {"Options", Type, 1}, - {"Options.PublicSuffixList", Field, 1}, - {"PublicSuffixList", Type, 1}, - }, - "net/http/fcgi": { - {"ErrConnClosed", Var, 5}, - {"ErrRequestAborted", Var, 5}, - {"ProcessEnv", Func, 9}, - {"Serve", Func, 0}, - }, - "net/http/httptest": { - {"(*ResponseRecorder).Flush", Method, 0}, - {"(*ResponseRecorder).Header", Method, 0}, - {"(*ResponseRecorder).Result", Method, 7}, - {"(*ResponseRecorder).Write", Method, 0}, - {"(*ResponseRecorder).WriteHeader", Method, 0}, - {"(*ResponseRecorder).WriteString", Method, 6}, - {"(*Server).Certificate", Method, 9}, - {"(*Server).Client", Method, 9}, - {"(*Server).Close", Method, 0}, - {"(*Server).CloseClientConnections", Method, 0}, - {"(*Server).Start", Method, 0}, - {"(*Server).StartTLS", Method, 0}, - {"DefaultRemoteAddr", Const, 0}, - {"NewRecorder", Func, 0}, - {"NewRequest", Func, 7}, - {"NewRequestWithContext", Func, 23}, - {"NewServer", Func, 0}, - {"NewTLSServer", Func, 0}, - {"NewUnstartedServer", Func, 0}, - {"ResponseRecorder", Type, 0}, - {"ResponseRecorder.Body", Field, 0}, - {"ResponseRecorder.Code", Field, 0}, - {"ResponseRecorder.Flushed", Field, 0}, - {"ResponseRecorder.HeaderMap", Field, 0}, - {"Server", Type, 0}, - {"Server.Config", Field, 0}, - {"Server.EnableHTTP2", Field, 14}, - {"Server.Listener", Field, 0}, - {"Server.TLS", Field, 0}, - {"Server.URL", Field, 0}, - }, - "net/http/httptrace": { - {"ClientTrace", Type, 7}, - {"ClientTrace.ConnectDone", Field, 7}, - {"ClientTrace.ConnectStart", Field, 7}, - {"ClientTrace.DNSDone", Field, 7}, - {"ClientTrace.DNSStart", Field, 7}, - {"ClientTrace.GetConn", Field, 7}, - {"ClientTrace.Got100Continue", Field, 7}, - {"ClientTrace.Got1xxResponse", Field, 11}, - {"ClientTrace.GotConn", Field, 7}, - {"ClientTrace.GotFirstResponseByte", Field, 7}, - {"ClientTrace.PutIdleConn", Field, 7}, - {"ClientTrace.TLSHandshakeDone", Field, 8}, - {"ClientTrace.TLSHandshakeStart", Field, 8}, - {"ClientTrace.Wait100Continue", Field, 7}, - {"ClientTrace.WroteHeaderField", Field, 11}, - {"ClientTrace.WroteHeaders", Field, 7}, - {"ClientTrace.WroteRequest", Field, 7}, - {"ContextClientTrace", Func, 7}, - {"DNSDoneInfo", Type, 7}, - {"DNSDoneInfo.Addrs", Field, 7}, - {"DNSDoneInfo.Coalesced", Field, 7}, - {"DNSDoneInfo.Err", Field, 7}, - {"DNSStartInfo", Type, 7}, - {"DNSStartInfo.Host", Field, 7}, - {"GotConnInfo", Type, 7}, - {"GotConnInfo.Conn", Field, 7}, - {"GotConnInfo.IdleTime", Field, 7}, - {"GotConnInfo.Reused", Field, 7}, - {"GotConnInfo.WasIdle", Field, 7}, - {"WithClientTrace", Func, 7}, - {"WroteRequestInfo", Type, 7}, - {"WroteRequestInfo.Err", Field, 7}, - }, - "net/http/httputil": { - {"(*ClientConn).Close", Method, 0}, - {"(*ClientConn).Do", Method, 0}, - {"(*ClientConn).Hijack", Method, 0}, - {"(*ClientConn).Pending", Method, 0}, - {"(*ClientConn).Read", Method, 0}, - {"(*ClientConn).Write", Method, 0}, - {"(*ProxyRequest).SetURL", Method, 20}, - {"(*ProxyRequest).SetXForwarded", Method, 20}, - {"(*ReverseProxy).ServeHTTP", Method, 0}, - {"(*ServerConn).Close", Method, 0}, - {"(*ServerConn).Hijack", Method, 0}, - {"(*ServerConn).Pending", Method, 0}, - {"(*ServerConn).Read", Method, 0}, - {"(*ServerConn).Write", Method, 0}, - {"BufferPool", Type, 6}, - {"ClientConn", Type, 0}, - {"DumpRequest", Func, 0}, - {"DumpRequestOut", Func, 0}, - {"DumpResponse", Func, 0}, - {"ErrClosed", Var, 0}, - {"ErrLineTooLong", Var, 0}, - {"ErrPersistEOF", Var, 0}, - {"ErrPipeline", Var, 0}, - {"NewChunkedReader", Func, 0}, - {"NewChunkedWriter", Func, 0}, - {"NewClientConn", Func, 0}, - {"NewProxyClientConn", Func, 0}, - {"NewServerConn", Func, 0}, - {"NewSingleHostReverseProxy", Func, 0}, - {"ProxyRequest", Type, 20}, - {"ProxyRequest.In", Field, 20}, - {"ProxyRequest.Out", Field, 20}, - {"ReverseProxy", Type, 0}, - {"ReverseProxy.BufferPool", Field, 6}, - {"ReverseProxy.Director", Field, 0}, - {"ReverseProxy.ErrorHandler", Field, 11}, - {"ReverseProxy.ErrorLog", Field, 4}, - {"ReverseProxy.FlushInterval", Field, 0}, - {"ReverseProxy.ModifyResponse", Field, 8}, - {"ReverseProxy.Rewrite", Field, 20}, - {"ReverseProxy.Transport", Field, 0}, - {"ServerConn", Type, 0}, - }, - "net/http/pprof": { - {"Cmdline", Func, 0}, - {"Handler", Func, 0}, - {"Index", Func, 0}, - {"Profile", Func, 0}, - {"Symbol", Func, 0}, - {"Trace", Func, 5}, - }, - "net/mail": { - {"(*Address).String", Method, 0}, - {"(*AddressParser).Parse", Method, 5}, - {"(*AddressParser).ParseList", Method, 5}, - {"(Header).AddressList", Method, 0}, - {"(Header).Date", Method, 0}, - {"(Header).Get", Method, 0}, - {"Address", Type, 0}, - {"Address.Address", Field, 0}, - {"Address.Name", Field, 0}, - {"AddressParser", Type, 5}, - {"AddressParser.WordDecoder", Field, 5}, - {"ErrHeaderNotPresent", Var, 0}, - {"Header", Type, 0}, - {"Message", Type, 0}, - {"Message.Body", Field, 0}, - {"Message.Header", Field, 0}, - {"ParseAddress", Func, 1}, - {"ParseAddressList", Func, 1}, - {"ParseDate", Func, 8}, - {"ReadMessage", Func, 0}, - }, - "net/netip": { - {"(*Addr).UnmarshalBinary", Method, 18}, - {"(*Addr).UnmarshalText", Method, 18}, - {"(*AddrPort).UnmarshalBinary", Method, 18}, - {"(*AddrPort).UnmarshalText", Method, 18}, - {"(*Prefix).UnmarshalBinary", Method, 18}, - {"(*Prefix).UnmarshalText", Method, 18}, - {"(Addr).AppendBinary", Method, 24}, - {"(Addr).AppendText", Method, 24}, - {"(Addr).AppendTo", Method, 18}, - {"(Addr).As16", Method, 18}, - {"(Addr).As4", Method, 18}, - {"(Addr).AsSlice", Method, 18}, - {"(Addr).BitLen", Method, 18}, - {"(Addr).Compare", Method, 18}, - {"(Addr).Is4", Method, 18}, - {"(Addr).Is4In6", Method, 18}, - {"(Addr).Is6", Method, 18}, - {"(Addr).IsGlobalUnicast", Method, 18}, - {"(Addr).IsInterfaceLocalMulticast", Method, 18}, - {"(Addr).IsLinkLocalMulticast", Method, 18}, - {"(Addr).IsLinkLocalUnicast", Method, 18}, - {"(Addr).IsLoopback", Method, 18}, - {"(Addr).IsMulticast", Method, 18}, - {"(Addr).IsPrivate", Method, 18}, - {"(Addr).IsUnspecified", Method, 18}, - {"(Addr).IsValid", Method, 18}, - {"(Addr).Less", Method, 18}, - {"(Addr).MarshalBinary", Method, 18}, - {"(Addr).MarshalText", Method, 18}, - {"(Addr).Next", Method, 18}, - {"(Addr).Prefix", Method, 18}, - {"(Addr).Prev", Method, 18}, - {"(Addr).String", Method, 18}, - {"(Addr).StringExpanded", Method, 18}, - {"(Addr).Unmap", Method, 18}, - {"(Addr).WithZone", Method, 18}, - {"(Addr).Zone", Method, 18}, - {"(AddrPort).Addr", Method, 18}, - {"(AddrPort).AppendBinary", Method, 24}, - {"(AddrPort).AppendText", Method, 24}, - {"(AddrPort).AppendTo", Method, 18}, - {"(AddrPort).Compare", Method, 22}, - {"(AddrPort).IsValid", Method, 18}, - {"(AddrPort).MarshalBinary", Method, 18}, - {"(AddrPort).MarshalText", Method, 18}, - {"(AddrPort).Port", Method, 18}, - {"(AddrPort).String", Method, 18}, - {"(Prefix).Addr", Method, 18}, - {"(Prefix).AppendBinary", Method, 24}, - {"(Prefix).AppendText", Method, 24}, - {"(Prefix).AppendTo", Method, 18}, - {"(Prefix).Bits", Method, 18}, - {"(Prefix).Contains", Method, 18}, - {"(Prefix).IsSingleIP", Method, 18}, - {"(Prefix).IsValid", Method, 18}, - {"(Prefix).MarshalBinary", Method, 18}, - {"(Prefix).MarshalText", Method, 18}, - {"(Prefix).Masked", Method, 18}, - {"(Prefix).Overlaps", Method, 18}, - {"(Prefix).String", Method, 18}, - {"Addr", Type, 18}, - {"AddrFrom16", Func, 18}, - {"AddrFrom4", Func, 18}, - {"AddrFromSlice", Func, 18}, - {"AddrPort", Type, 18}, - {"AddrPortFrom", Func, 18}, - {"IPv4Unspecified", Func, 18}, - {"IPv6LinkLocalAllNodes", Func, 18}, - {"IPv6LinkLocalAllRouters", Func, 20}, - {"IPv6Loopback", Func, 20}, - {"IPv6Unspecified", Func, 18}, - {"MustParseAddr", Func, 18}, - {"MustParseAddrPort", Func, 18}, - {"MustParsePrefix", Func, 18}, - {"ParseAddr", Func, 18}, - {"ParseAddrPort", Func, 18}, - {"ParsePrefix", Func, 18}, - {"Prefix", Type, 18}, - {"PrefixFrom", Func, 18}, - }, - "net/rpc": { - {"(*Client).Call", Method, 0}, - {"(*Client).Close", Method, 0}, - {"(*Client).Go", Method, 0}, - {"(*Server).Accept", Method, 0}, - {"(*Server).HandleHTTP", Method, 0}, - {"(*Server).Register", Method, 0}, - {"(*Server).RegisterName", Method, 0}, - {"(*Server).ServeCodec", Method, 0}, - {"(*Server).ServeConn", Method, 0}, - {"(*Server).ServeHTTP", Method, 0}, - {"(*Server).ServeRequest", Method, 0}, - {"(ServerError).Error", Method, 0}, - {"Accept", Func, 0}, - {"Call", Type, 0}, - {"Call.Args", Field, 0}, - {"Call.Done", Field, 0}, - {"Call.Error", Field, 0}, - {"Call.Reply", Field, 0}, - {"Call.ServiceMethod", Field, 0}, - {"Client", Type, 0}, - {"ClientCodec", Type, 0}, - {"DefaultDebugPath", Const, 0}, - {"DefaultRPCPath", Const, 0}, - {"DefaultServer", Var, 0}, - {"Dial", Func, 0}, - {"DialHTTP", Func, 0}, - {"DialHTTPPath", Func, 0}, - {"ErrShutdown", Var, 0}, - {"HandleHTTP", Func, 0}, - {"NewClient", Func, 0}, - {"NewClientWithCodec", Func, 0}, - {"NewServer", Func, 0}, - {"Register", Func, 0}, - {"RegisterName", Func, 0}, - {"Request", Type, 0}, - {"Request.Seq", Field, 0}, - {"Request.ServiceMethod", Field, 0}, - {"Response", Type, 0}, - {"Response.Error", Field, 0}, - {"Response.Seq", Field, 0}, - {"Response.ServiceMethod", Field, 0}, - {"ServeCodec", Func, 0}, - {"ServeConn", Func, 0}, - {"ServeRequest", Func, 0}, - {"Server", Type, 0}, - {"ServerCodec", Type, 0}, - {"ServerError", Type, 0}, - }, - "net/rpc/jsonrpc": { - {"Dial", Func, 0}, - {"NewClient", Func, 0}, - {"NewClientCodec", Func, 0}, - {"NewServerCodec", Func, 0}, - {"ServeConn", Func, 0}, - }, - "net/smtp": { - {"(*Client).Auth", Method, 0}, - {"(*Client).Close", Method, 2}, - {"(*Client).Data", Method, 0}, - {"(*Client).Extension", Method, 0}, - {"(*Client).Hello", Method, 1}, - {"(*Client).Mail", Method, 0}, - {"(*Client).Noop", Method, 10}, - {"(*Client).Quit", Method, 0}, - {"(*Client).Rcpt", Method, 0}, - {"(*Client).Reset", Method, 0}, - {"(*Client).StartTLS", Method, 0}, - {"(*Client).TLSConnectionState", Method, 5}, - {"(*Client).Verify", Method, 0}, - {"Auth", Type, 0}, - {"CRAMMD5Auth", Func, 0}, - {"Client", Type, 0}, - {"Client.Text", Field, 0}, - {"Dial", Func, 0}, - {"NewClient", Func, 0}, - {"PlainAuth", Func, 0}, - {"SendMail", Func, 0}, - {"ServerInfo", Type, 0}, - {"ServerInfo.Auth", Field, 0}, - {"ServerInfo.Name", Field, 0}, - {"ServerInfo.TLS", Field, 0}, - }, - "net/textproto": { - {"(*Conn).Close", Method, 0}, - {"(*Conn).Cmd", Method, 0}, - {"(*Conn).DotReader", Method, 0}, - {"(*Conn).DotWriter", Method, 0}, - {"(*Conn).EndRequest", Method, 0}, - {"(*Conn).EndResponse", Method, 0}, - {"(*Conn).Next", Method, 0}, - {"(*Conn).PrintfLine", Method, 0}, - {"(*Conn).ReadCodeLine", Method, 0}, - {"(*Conn).ReadContinuedLine", Method, 0}, - {"(*Conn).ReadContinuedLineBytes", Method, 0}, - {"(*Conn).ReadDotBytes", Method, 0}, - {"(*Conn).ReadDotLines", Method, 0}, - {"(*Conn).ReadLine", Method, 0}, - {"(*Conn).ReadLineBytes", Method, 0}, - {"(*Conn).ReadMIMEHeader", Method, 0}, - {"(*Conn).ReadResponse", Method, 0}, - {"(*Conn).StartRequest", Method, 0}, - {"(*Conn).StartResponse", Method, 0}, - {"(*Error).Error", Method, 0}, - {"(*Pipeline).EndRequest", Method, 0}, - {"(*Pipeline).EndResponse", Method, 0}, - {"(*Pipeline).Next", Method, 0}, - {"(*Pipeline).StartRequest", Method, 0}, - {"(*Pipeline).StartResponse", Method, 0}, - {"(*Reader).DotReader", Method, 0}, - {"(*Reader).ReadCodeLine", Method, 0}, - {"(*Reader).ReadContinuedLine", Method, 0}, - {"(*Reader).ReadContinuedLineBytes", Method, 0}, - {"(*Reader).ReadDotBytes", Method, 0}, - {"(*Reader).ReadDotLines", Method, 0}, - {"(*Reader).ReadLine", Method, 0}, - {"(*Reader).ReadLineBytes", Method, 0}, - {"(*Reader).ReadMIMEHeader", Method, 0}, - {"(*Reader).ReadResponse", Method, 0}, - {"(*Writer).DotWriter", Method, 0}, - {"(*Writer).PrintfLine", Method, 0}, - {"(MIMEHeader).Add", Method, 0}, - {"(MIMEHeader).Del", Method, 0}, - {"(MIMEHeader).Get", Method, 0}, - {"(MIMEHeader).Set", Method, 0}, - {"(MIMEHeader).Values", Method, 14}, - {"(ProtocolError).Error", Method, 0}, - {"CanonicalMIMEHeaderKey", Func, 0}, - {"Conn", Type, 0}, - {"Conn.Pipeline", Field, 0}, - {"Conn.Reader", Field, 0}, - {"Conn.Writer", Field, 0}, - {"Dial", Func, 0}, - {"Error", Type, 0}, - {"Error.Code", Field, 0}, - {"Error.Msg", Field, 0}, - {"MIMEHeader", Type, 0}, - {"NewConn", Func, 0}, - {"NewReader", Func, 0}, - {"NewWriter", Func, 0}, - {"Pipeline", Type, 0}, - {"ProtocolError", Type, 0}, - {"Reader", Type, 0}, - {"Reader.R", Field, 0}, - {"TrimBytes", Func, 1}, - {"TrimString", Func, 1}, - {"Writer", Type, 0}, - {"Writer.W", Field, 0}, - }, - "net/url": { - {"(*Error).Error", Method, 0}, - {"(*Error).Temporary", Method, 6}, - {"(*Error).Timeout", Method, 6}, - {"(*Error).Unwrap", Method, 13}, - {"(*URL).AppendBinary", Method, 24}, - {"(*URL).EscapedFragment", Method, 15}, - {"(*URL).EscapedPath", Method, 5}, - {"(*URL).Hostname", Method, 8}, - {"(*URL).IsAbs", Method, 0}, - {"(*URL).JoinPath", Method, 19}, - {"(*URL).MarshalBinary", Method, 8}, - {"(*URL).Parse", Method, 0}, - {"(*URL).Port", Method, 8}, - {"(*URL).Query", Method, 0}, - {"(*URL).Redacted", Method, 15}, - {"(*URL).RequestURI", Method, 0}, - {"(*URL).ResolveReference", Method, 0}, - {"(*URL).String", Method, 0}, - {"(*URL).UnmarshalBinary", Method, 8}, - {"(*Userinfo).Password", Method, 0}, - {"(*Userinfo).String", Method, 0}, - {"(*Userinfo).Username", Method, 0}, - {"(EscapeError).Error", Method, 0}, - {"(InvalidHostError).Error", Method, 6}, - {"(Values).Add", Method, 0}, - {"(Values).Del", Method, 0}, - {"(Values).Encode", Method, 0}, - {"(Values).Get", Method, 0}, - {"(Values).Has", Method, 17}, - {"(Values).Set", Method, 0}, - {"Error", Type, 0}, - {"Error.Err", Field, 0}, - {"Error.Op", Field, 0}, - {"Error.URL", Field, 0}, - {"EscapeError", Type, 0}, - {"InvalidHostError", Type, 6}, - {"JoinPath", Func, 19}, - {"Parse", Func, 0}, - {"ParseQuery", Func, 0}, - {"ParseRequestURI", Func, 0}, - {"PathEscape", Func, 8}, - {"PathUnescape", Func, 8}, - {"QueryEscape", Func, 0}, - {"QueryUnescape", Func, 0}, - {"URL", Type, 0}, - {"URL.ForceQuery", Field, 7}, - {"URL.Fragment", Field, 0}, - {"URL.Host", Field, 0}, - {"URL.OmitHost", Field, 19}, - {"URL.Opaque", Field, 0}, - {"URL.Path", Field, 0}, - {"URL.RawFragment", Field, 15}, - {"URL.RawPath", Field, 5}, - {"URL.RawQuery", Field, 0}, - {"URL.Scheme", Field, 0}, - {"URL.User", Field, 0}, - {"User", Func, 0}, - {"UserPassword", Func, 0}, - {"Userinfo", Type, 0}, - {"Values", Type, 0}, - }, - "os": { - {"(*File).Chdir", Method, 0}, - {"(*File).Chmod", Method, 0}, - {"(*File).Chown", Method, 0}, - {"(*File).Close", Method, 0}, - {"(*File).Fd", Method, 0}, - {"(*File).Name", Method, 0}, - {"(*File).Read", Method, 0}, - {"(*File).ReadAt", Method, 0}, - {"(*File).ReadDir", Method, 16}, - {"(*File).ReadFrom", Method, 15}, - {"(*File).Readdir", Method, 0}, - {"(*File).Readdirnames", Method, 0}, - {"(*File).Seek", Method, 0}, - {"(*File).SetDeadline", Method, 10}, - {"(*File).SetReadDeadline", Method, 10}, - {"(*File).SetWriteDeadline", Method, 10}, - {"(*File).Stat", Method, 0}, - {"(*File).Sync", Method, 0}, - {"(*File).SyscallConn", Method, 12}, - {"(*File).Truncate", Method, 0}, - {"(*File).Write", Method, 0}, - {"(*File).WriteAt", Method, 0}, - {"(*File).WriteString", Method, 0}, - {"(*File).WriteTo", Method, 22}, - {"(*LinkError).Error", Method, 0}, - {"(*LinkError).Unwrap", Method, 13}, - {"(*PathError).Error", Method, 0}, - {"(*PathError).Timeout", Method, 10}, - {"(*PathError).Unwrap", Method, 13}, - {"(*Process).Kill", Method, 0}, - {"(*Process).Release", Method, 0}, - {"(*Process).Signal", Method, 0}, - {"(*Process).Wait", Method, 0}, - {"(*ProcessState).ExitCode", Method, 12}, - {"(*ProcessState).Exited", Method, 0}, - {"(*ProcessState).Pid", Method, 0}, - {"(*ProcessState).String", Method, 0}, - {"(*ProcessState).Success", Method, 0}, - {"(*ProcessState).Sys", Method, 0}, - {"(*ProcessState).SysUsage", Method, 0}, - {"(*ProcessState).SystemTime", Method, 0}, - {"(*ProcessState).UserTime", Method, 0}, - {"(*Root).Close", Method, 24}, - {"(*Root).Create", Method, 24}, - {"(*Root).FS", Method, 24}, - {"(*Root).Lstat", Method, 24}, - {"(*Root).Mkdir", Method, 24}, - {"(*Root).Name", Method, 24}, - {"(*Root).Open", Method, 24}, - {"(*Root).OpenFile", Method, 24}, - {"(*Root).OpenRoot", Method, 24}, - {"(*Root).Remove", Method, 24}, - {"(*Root).Stat", Method, 24}, - {"(*SyscallError).Error", Method, 0}, - {"(*SyscallError).Timeout", Method, 10}, - {"(*SyscallError).Unwrap", Method, 13}, - {"(FileMode).IsDir", Method, 0}, - {"(FileMode).IsRegular", Method, 1}, - {"(FileMode).Perm", Method, 0}, - {"(FileMode).String", Method, 0}, - {"Args", Var, 0}, - {"Chdir", Func, 0}, - {"Chmod", Func, 0}, - {"Chown", Func, 0}, - {"Chtimes", Func, 0}, - {"Clearenv", Func, 0}, - {"CopyFS", Func, 23}, - {"Create", Func, 0}, - {"CreateTemp", Func, 16}, - {"DevNull", Const, 0}, - {"DirEntry", Type, 16}, - {"DirFS", Func, 16}, - {"Environ", Func, 0}, - {"ErrClosed", Var, 8}, - {"ErrDeadlineExceeded", Var, 15}, - {"ErrExist", Var, 0}, - {"ErrInvalid", Var, 0}, - {"ErrNoDeadline", Var, 10}, - {"ErrNotExist", Var, 0}, - {"ErrPermission", Var, 0}, - {"ErrProcessDone", Var, 16}, - {"Executable", Func, 8}, - {"Exit", Func, 0}, - {"Expand", Func, 0}, - {"ExpandEnv", Func, 0}, - {"File", Type, 0}, - {"FileInfo", Type, 0}, - {"FileMode", Type, 0}, - {"FindProcess", Func, 0}, - {"Getegid", Func, 0}, - {"Getenv", Func, 0}, - {"Geteuid", Func, 0}, - {"Getgid", Func, 0}, - {"Getgroups", Func, 0}, - {"Getpagesize", Func, 0}, - {"Getpid", Func, 0}, - {"Getppid", Func, 0}, - {"Getuid", Func, 0}, - {"Getwd", Func, 0}, - {"Hostname", Func, 0}, - {"Interrupt", Var, 0}, - {"IsExist", Func, 0}, - {"IsNotExist", Func, 0}, - {"IsPathSeparator", Func, 0}, - {"IsPermission", Func, 0}, - {"IsTimeout", Func, 10}, - {"Kill", Var, 0}, - {"Lchown", Func, 0}, - {"Link", Func, 0}, - {"LinkError", Type, 0}, - {"LinkError.Err", Field, 0}, - {"LinkError.New", Field, 0}, - {"LinkError.Old", Field, 0}, - {"LinkError.Op", Field, 0}, - {"LookupEnv", Func, 5}, - {"Lstat", Func, 0}, - {"Mkdir", Func, 0}, - {"MkdirAll", Func, 0}, - {"MkdirTemp", Func, 16}, - {"ModeAppend", Const, 0}, - {"ModeCharDevice", Const, 0}, - {"ModeDevice", Const, 0}, - {"ModeDir", Const, 0}, - {"ModeExclusive", Const, 0}, - {"ModeIrregular", Const, 11}, - {"ModeNamedPipe", Const, 0}, - {"ModePerm", Const, 0}, - {"ModeSetgid", Const, 0}, - {"ModeSetuid", Const, 0}, - {"ModeSocket", Const, 0}, - {"ModeSticky", Const, 0}, - {"ModeSymlink", Const, 0}, - {"ModeTemporary", Const, 0}, - {"ModeType", Const, 0}, - {"NewFile", Func, 0}, - {"NewSyscallError", Func, 0}, - {"O_APPEND", Const, 0}, - {"O_CREATE", Const, 0}, - {"O_EXCL", Const, 0}, - {"O_RDONLY", Const, 0}, - {"O_RDWR", Const, 0}, - {"O_SYNC", Const, 0}, - {"O_TRUNC", Const, 0}, - {"O_WRONLY", Const, 0}, - {"Open", Func, 0}, - {"OpenFile", Func, 0}, - {"OpenInRoot", Func, 24}, - {"OpenRoot", Func, 24}, - {"PathError", Type, 0}, - {"PathError.Err", Field, 0}, - {"PathError.Op", Field, 0}, - {"PathError.Path", Field, 0}, - {"PathListSeparator", Const, 0}, - {"PathSeparator", Const, 0}, - {"Pipe", Func, 0}, - {"ProcAttr", Type, 0}, - {"ProcAttr.Dir", Field, 0}, - {"ProcAttr.Env", Field, 0}, - {"ProcAttr.Files", Field, 0}, - {"ProcAttr.Sys", Field, 0}, - {"Process", Type, 0}, - {"Process.Pid", Field, 0}, - {"ProcessState", Type, 0}, - {"ReadDir", Func, 16}, - {"ReadFile", Func, 16}, - {"Readlink", Func, 0}, - {"Remove", Func, 0}, - {"RemoveAll", Func, 0}, - {"Rename", Func, 0}, - {"Root", Type, 24}, - {"SEEK_CUR", Const, 0}, - {"SEEK_END", Const, 0}, - {"SEEK_SET", Const, 0}, - {"SameFile", Func, 0}, - {"Setenv", Func, 0}, - {"Signal", Type, 0}, - {"StartProcess", Func, 0}, - {"Stat", Func, 0}, - {"Stderr", Var, 0}, - {"Stdin", Var, 0}, - {"Stdout", Var, 0}, - {"Symlink", Func, 0}, - {"SyscallError", Type, 0}, - {"SyscallError.Err", Field, 0}, - {"SyscallError.Syscall", Field, 0}, - {"TempDir", Func, 0}, - {"Truncate", Func, 0}, - {"Unsetenv", Func, 4}, - {"UserCacheDir", Func, 11}, - {"UserConfigDir", Func, 13}, - {"UserHomeDir", Func, 12}, - {"WriteFile", Func, 16}, - }, - "os/exec": { - {"(*Cmd).CombinedOutput", Method, 0}, - {"(*Cmd).Environ", Method, 19}, - {"(*Cmd).Output", Method, 0}, - {"(*Cmd).Run", Method, 0}, - {"(*Cmd).Start", Method, 0}, - {"(*Cmd).StderrPipe", Method, 0}, - {"(*Cmd).StdinPipe", Method, 0}, - {"(*Cmd).StdoutPipe", Method, 0}, - {"(*Cmd).String", Method, 13}, - {"(*Cmd).Wait", Method, 0}, - {"(*Error).Error", Method, 0}, - {"(*Error).Unwrap", Method, 13}, - {"(*ExitError).Error", Method, 0}, - {"(ExitError).ExitCode", Method, 12}, - {"(ExitError).Exited", Method, 0}, - {"(ExitError).Pid", Method, 0}, - {"(ExitError).String", Method, 0}, - {"(ExitError).Success", Method, 0}, - {"(ExitError).Sys", Method, 0}, - {"(ExitError).SysUsage", Method, 0}, - {"(ExitError).SystemTime", Method, 0}, - {"(ExitError).UserTime", Method, 0}, - {"Cmd", Type, 0}, - {"Cmd.Args", Field, 0}, - {"Cmd.Cancel", Field, 20}, - {"Cmd.Dir", Field, 0}, - {"Cmd.Env", Field, 0}, - {"Cmd.Err", Field, 19}, - {"Cmd.ExtraFiles", Field, 0}, - {"Cmd.Path", Field, 0}, - {"Cmd.Process", Field, 0}, - {"Cmd.ProcessState", Field, 0}, - {"Cmd.Stderr", Field, 0}, - {"Cmd.Stdin", Field, 0}, - {"Cmd.Stdout", Field, 0}, - {"Cmd.SysProcAttr", Field, 0}, - {"Cmd.WaitDelay", Field, 20}, - {"Command", Func, 0}, - {"CommandContext", Func, 7}, - {"ErrDot", Var, 19}, - {"ErrNotFound", Var, 0}, - {"ErrWaitDelay", Var, 20}, - {"Error", Type, 0}, - {"Error.Err", Field, 0}, - {"Error.Name", Field, 0}, - {"ExitError", Type, 0}, - {"ExitError.ProcessState", Field, 0}, - {"ExitError.Stderr", Field, 6}, - {"LookPath", Func, 0}, - }, - "os/signal": { - {"Ignore", Func, 5}, - {"Ignored", Func, 11}, - {"Notify", Func, 0}, - {"NotifyContext", Func, 16}, - {"Reset", Func, 5}, - {"Stop", Func, 1}, - }, - "os/user": { - {"(*User).GroupIds", Method, 7}, - {"(UnknownGroupError).Error", Method, 7}, - {"(UnknownGroupIdError).Error", Method, 7}, - {"(UnknownUserError).Error", Method, 0}, - {"(UnknownUserIdError).Error", Method, 0}, - {"Current", Func, 0}, - {"Group", Type, 7}, - {"Group.Gid", Field, 7}, - {"Group.Name", Field, 7}, - {"Lookup", Func, 0}, - {"LookupGroup", Func, 7}, - {"LookupGroupId", Func, 7}, - {"LookupId", Func, 0}, - {"UnknownGroupError", Type, 7}, - {"UnknownGroupIdError", Type, 7}, - {"UnknownUserError", Type, 0}, - {"UnknownUserIdError", Type, 0}, - {"User", Type, 0}, - {"User.Gid", Field, 0}, - {"User.HomeDir", Field, 0}, - {"User.Name", Field, 0}, - {"User.Uid", Field, 0}, - {"User.Username", Field, 0}, - }, - "path": { - {"Base", Func, 0}, - {"Clean", Func, 0}, - {"Dir", Func, 0}, - {"ErrBadPattern", Var, 0}, - {"Ext", Func, 0}, - {"IsAbs", Func, 0}, - {"Join", Func, 0}, - {"Match", Func, 0}, - {"Split", Func, 0}, - }, - "path/filepath": { - {"Abs", Func, 0}, - {"Base", Func, 0}, - {"Clean", Func, 0}, - {"Dir", Func, 0}, - {"ErrBadPattern", Var, 0}, - {"EvalSymlinks", Func, 0}, - {"Ext", Func, 0}, - {"FromSlash", Func, 0}, - {"Glob", Func, 0}, - {"HasPrefix", Func, 0}, - {"IsAbs", Func, 0}, - {"IsLocal", Func, 20}, - {"Join", Func, 0}, - {"ListSeparator", Const, 0}, - {"Localize", Func, 23}, - {"Match", Func, 0}, - {"Rel", Func, 0}, - {"Separator", Const, 0}, - {"SkipAll", Var, 20}, - {"SkipDir", Var, 0}, - {"Split", Func, 0}, - {"SplitList", Func, 0}, - {"ToSlash", Func, 0}, - {"VolumeName", Func, 0}, - {"Walk", Func, 0}, - {"WalkDir", Func, 16}, - {"WalkFunc", Type, 0}, - }, - "plugin": { - {"(*Plugin).Lookup", Method, 8}, - {"Open", Func, 8}, - {"Plugin", Type, 8}, - {"Symbol", Type, 8}, - }, - "reflect": { - {"(*MapIter).Key", Method, 12}, - {"(*MapIter).Next", Method, 12}, - {"(*MapIter).Reset", Method, 18}, - {"(*MapIter).Value", Method, 12}, - {"(*ValueError).Error", Method, 0}, - {"(ChanDir).String", Method, 0}, - {"(Kind).String", Method, 0}, - {"(Method).IsExported", Method, 17}, - {"(StructField).IsExported", Method, 17}, - {"(StructTag).Get", Method, 0}, - {"(StructTag).Lookup", Method, 7}, - {"(Value).Addr", Method, 0}, - {"(Value).Bool", Method, 0}, - {"(Value).Bytes", Method, 0}, - {"(Value).Call", Method, 0}, - {"(Value).CallSlice", Method, 0}, - {"(Value).CanAddr", Method, 0}, - {"(Value).CanComplex", Method, 18}, - {"(Value).CanConvert", Method, 17}, - {"(Value).CanFloat", Method, 18}, - {"(Value).CanInt", Method, 18}, - {"(Value).CanInterface", Method, 0}, - {"(Value).CanSet", Method, 0}, - {"(Value).CanUint", Method, 18}, - {"(Value).Cap", Method, 0}, - {"(Value).Clear", Method, 21}, - {"(Value).Close", Method, 0}, - {"(Value).Comparable", Method, 20}, - {"(Value).Complex", Method, 0}, - {"(Value).Convert", Method, 1}, - {"(Value).Elem", Method, 0}, - {"(Value).Equal", Method, 20}, - {"(Value).Field", Method, 0}, - {"(Value).FieldByIndex", Method, 0}, - {"(Value).FieldByIndexErr", Method, 18}, - {"(Value).FieldByName", Method, 0}, - {"(Value).FieldByNameFunc", Method, 0}, - {"(Value).Float", Method, 0}, - {"(Value).Grow", Method, 20}, - {"(Value).Index", Method, 0}, - {"(Value).Int", Method, 0}, - {"(Value).Interface", Method, 0}, - {"(Value).InterfaceData", Method, 0}, - {"(Value).IsNil", Method, 0}, - {"(Value).IsValid", Method, 0}, - {"(Value).IsZero", Method, 13}, - {"(Value).Kind", Method, 0}, - {"(Value).Len", Method, 0}, - {"(Value).MapIndex", Method, 0}, - {"(Value).MapKeys", Method, 0}, - {"(Value).MapRange", Method, 12}, - {"(Value).Method", Method, 0}, - {"(Value).MethodByName", Method, 0}, - {"(Value).NumField", Method, 0}, - {"(Value).NumMethod", Method, 0}, - {"(Value).OverflowComplex", Method, 0}, - {"(Value).OverflowFloat", Method, 0}, - {"(Value).OverflowInt", Method, 0}, - {"(Value).OverflowUint", Method, 0}, - {"(Value).Pointer", Method, 0}, - {"(Value).Recv", Method, 0}, - {"(Value).Send", Method, 0}, - {"(Value).Seq", Method, 23}, - {"(Value).Seq2", Method, 23}, - {"(Value).Set", Method, 0}, - {"(Value).SetBool", Method, 0}, - {"(Value).SetBytes", Method, 0}, - {"(Value).SetCap", Method, 2}, - {"(Value).SetComplex", Method, 0}, - {"(Value).SetFloat", Method, 0}, - {"(Value).SetInt", Method, 0}, - {"(Value).SetIterKey", Method, 18}, - {"(Value).SetIterValue", Method, 18}, - {"(Value).SetLen", Method, 0}, - {"(Value).SetMapIndex", Method, 0}, - {"(Value).SetPointer", Method, 0}, - {"(Value).SetString", Method, 0}, - {"(Value).SetUint", Method, 0}, - {"(Value).SetZero", Method, 20}, - {"(Value).Slice", Method, 0}, - {"(Value).Slice3", Method, 2}, - {"(Value).String", Method, 0}, - {"(Value).TryRecv", Method, 0}, - {"(Value).TrySend", Method, 0}, - {"(Value).Type", Method, 0}, - {"(Value).Uint", Method, 0}, - {"(Value).UnsafeAddr", Method, 0}, - {"(Value).UnsafePointer", Method, 18}, - {"Append", Func, 0}, - {"AppendSlice", Func, 0}, - {"Array", Const, 0}, - {"ArrayOf", Func, 5}, - {"Bool", Const, 0}, - {"BothDir", Const, 0}, - {"Chan", Const, 0}, - {"ChanDir", Type, 0}, - {"ChanOf", Func, 1}, - {"Complex128", Const, 0}, - {"Complex64", Const, 0}, - {"Copy", Func, 0}, - {"DeepEqual", Func, 0}, - {"Float32", Const, 0}, - {"Float64", Const, 0}, - {"Func", Const, 0}, - {"FuncOf", Func, 5}, - {"Indirect", Func, 0}, - {"Int", Const, 0}, - {"Int16", Const, 0}, - {"Int32", Const, 0}, - {"Int64", Const, 0}, - {"Int8", Const, 0}, - {"Interface", Const, 0}, - {"Invalid", Const, 0}, - {"Kind", Type, 0}, - {"MakeChan", Func, 0}, - {"MakeFunc", Func, 1}, - {"MakeMap", Func, 0}, - {"MakeMapWithSize", Func, 9}, - {"MakeSlice", Func, 0}, - {"Map", Const, 0}, - {"MapIter", Type, 12}, - {"MapOf", Func, 1}, - {"Method", Type, 0}, - {"Method.Func", Field, 0}, - {"Method.Index", Field, 0}, - {"Method.Name", Field, 0}, - {"Method.PkgPath", Field, 0}, - {"Method.Type", Field, 0}, - {"New", Func, 0}, - {"NewAt", Func, 0}, - {"Pointer", Const, 18}, - {"PointerTo", Func, 18}, - {"Ptr", Const, 0}, - {"PtrTo", Func, 0}, - {"RecvDir", Const, 0}, - {"Select", Func, 1}, - {"SelectCase", Type, 1}, - {"SelectCase.Chan", Field, 1}, - {"SelectCase.Dir", Field, 1}, - {"SelectCase.Send", Field, 1}, - {"SelectDefault", Const, 1}, - {"SelectDir", Type, 1}, - {"SelectRecv", Const, 1}, - {"SelectSend", Const, 1}, - {"SendDir", Const, 0}, - {"Slice", Const, 0}, - {"SliceAt", Func, 23}, - {"SliceHeader", Type, 0}, - {"SliceHeader.Cap", Field, 0}, - {"SliceHeader.Data", Field, 0}, - {"SliceHeader.Len", Field, 0}, - {"SliceOf", Func, 1}, - {"String", Const, 0}, - {"StringHeader", Type, 0}, - {"StringHeader.Data", Field, 0}, - {"StringHeader.Len", Field, 0}, - {"Struct", Const, 0}, - {"StructField", Type, 0}, - {"StructField.Anonymous", Field, 0}, - {"StructField.Index", Field, 0}, - {"StructField.Name", Field, 0}, - {"StructField.Offset", Field, 0}, - {"StructField.PkgPath", Field, 0}, - {"StructField.Tag", Field, 0}, - {"StructField.Type", Field, 0}, - {"StructOf", Func, 7}, - {"StructTag", Type, 0}, - {"Swapper", Func, 8}, - {"Type", Type, 0}, - {"TypeFor", Func, 22}, - {"TypeOf", Func, 0}, - {"Uint", Const, 0}, - {"Uint16", Const, 0}, - {"Uint32", Const, 0}, - {"Uint64", Const, 0}, - {"Uint8", Const, 0}, - {"Uintptr", Const, 0}, - {"UnsafePointer", Const, 0}, - {"Value", Type, 0}, - {"ValueError", Type, 0}, - {"ValueError.Kind", Field, 0}, - {"ValueError.Method", Field, 0}, - {"ValueOf", Func, 0}, - {"VisibleFields", Func, 17}, - {"Zero", Func, 0}, - }, - "regexp": { - {"(*Regexp).AppendText", Method, 24}, - {"(*Regexp).Copy", Method, 6}, - {"(*Regexp).Expand", Method, 0}, - {"(*Regexp).ExpandString", Method, 0}, - {"(*Regexp).Find", Method, 0}, - {"(*Regexp).FindAll", Method, 0}, - {"(*Regexp).FindAllIndex", Method, 0}, - {"(*Regexp).FindAllString", Method, 0}, - {"(*Regexp).FindAllStringIndex", Method, 0}, - {"(*Regexp).FindAllStringSubmatch", Method, 0}, - {"(*Regexp).FindAllStringSubmatchIndex", Method, 0}, - {"(*Regexp).FindAllSubmatch", Method, 0}, - {"(*Regexp).FindAllSubmatchIndex", Method, 0}, - {"(*Regexp).FindIndex", Method, 0}, - {"(*Regexp).FindReaderIndex", Method, 0}, - {"(*Regexp).FindReaderSubmatchIndex", Method, 0}, - {"(*Regexp).FindString", Method, 0}, - {"(*Regexp).FindStringIndex", Method, 0}, - {"(*Regexp).FindStringSubmatch", Method, 0}, - {"(*Regexp).FindStringSubmatchIndex", Method, 0}, - {"(*Regexp).FindSubmatch", Method, 0}, - {"(*Regexp).FindSubmatchIndex", Method, 0}, - {"(*Regexp).LiteralPrefix", Method, 0}, - {"(*Regexp).Longest", Method, 1}, - {"(*Regexp).MarshalText", Method, 21}, - {"(*Regexp).Match", Method, 0}, - {"(*Regexp).MatchReader", Method, 0}, - {"(*Regexp).MatchString", Method, 0}, - {"(*Regexp).NumSubexp", Method, 0}, - {"(*Regexp).ReplaceAll", Method, 0}, - {"(*Regexp).ReplaceAllFunc", Method, 0}, - {"(*Regexp).ReplaceAllLiteral", Method, 0}, - {"(*Regexp).ReplaceAllLiteralString", Method, 0}, - {"(*Regexp).ReplaceAllString", Method, 0}, - {"(*Regexp).ReplaceAllStringFunc", Method, 0}, - {"(*Regexp).Split", Method, 1}, - {"(*Regexp).String", Method, 0}, - {"(*Regexp).SubexpIndex", Method, 15}, - {"(*Regexp).SubexpNames", Method, 0}, - {"(*Regexp).UnmarshalText", Method, 21}, - {"Compile", Func, 0}, - {"CompilePOSIX", Func, 0}, - {"Match", Func, 0}, - {"MatchReader", Func, 0}, - {"MatchString", Func, 0}, - {"MustCompile", Func, 0}, - {"MustCompilePOSIX", Func, 0}, - {"QuoteMeta", Func, 0}, - {"Regexp", Type, 0}, - }, - "regexp/syntax": { - {"(*Error).Error", Method, 0}, - {"(*Inst).MatchEmptyWidth", Method, 0}, - {"(*Inst).MatchRune", Method, 0}, - {"(*Inst).MatchRunePos", Method, 3}, - {"(*Inst).String", Method, 0}, - {"(*Prog).Prefix", Method, 0}, - {"(*Prog).StartCond", Method, 0}, - {"(*Prog).String", Method, 0}, - {"(*Regexp).CapNames", Method, 0}, - {"(*Regexp).Equal", Method, 0}, - {"(*Regexp).MaxCap", Method, 0}, - {"(*Regexp).Simplify", Method, 0}, - {"(*Regexp).String", Method, 0}, - {"(ErrorCode).String", Method, 0}, - {"(InstOp).String", Method, 3}, - {"(Op).String", Method, 11}, - {"ClassNL", Const, 0}, - {"Compile", Func, 0}, - {"DotNL", Const, 0}, - {"EmptyBeginLine", Const, 0}, - {"EmptyBeginText", Const, 0}, - {"EmptyEndLine", Const, 0}, - {"EmptyEndText", Const, 0}, - {"EmptyNoWordBoundary", Const, 0}, - {"EmptyOp", Type, 0}, - {"EmptyOpContext", Func, 0}, - {"EmptyWordBoundary", Const, 0}, - {"ErrInternalError", Const, 0}, - {"ErrInvalidCharClass", Const, 0}, - {"ErrInvalidCharRange", Const, 0}, - {"ErrInvalidEscape", Const, 0}, - {"ErrInvalidNamedCapture", Const, 0}, - {"ErrInvalidPerlOp", Const, 0}, - {"ErrInvalidRepeatOp", Const, 0}, - {"ErrInvalidRepeatSize", Const, 0}, - {"ErrInvalidUTF8", Const, 0}, - {"ErrLarge", Const, 20}, - {"ErrMissingBracket", Const, 0}, - {"ErrMissingParen", Const, 0}, - {"ErrMissingRepeatArgument", Const, 0}, - {"ErrNestingDepth", Const, 19}, - {"ErrTrailingBackslash", Const, 0}, - {"ErrUnexpectedParen", Const, 1}, - {"Error", Type, 0}, - {"Error.Code", Field, 0}, - {"Error.Expr", Field, 0}, - {"ErrorCode", Type, 0}, - {"Flags", Type, 0}, - {"FoldCase", Const, 0}, - {"Inst", Type, 0}, - {"Inst.Arg", Field, 0}, - {"Inst.Op", Field, 0}, - {"Inst.Out", Field, 0}, - {"Inst.Rune", Field, 0}, - {"InstAlt", Const, 0}, - {"InstAltMatch", Const, 0}, - {"InstCapture", Const, 0}, - {"InstEmptyWidth", Const, 0}, - {"InstFail", Const, 0}, - {"InstMatch", Const, 0}, - {"InstNop", Const, 0}, - {"InstOp", Type, 0}, - {"InstRune", Const, 0}, - {"InstRune1", Const, 0}, - {"InstRuneAny", Const, 0}, - {"InstRuneAnyNotNL", Const, 0}, - {"IsWordChar", Func, 0}, - {"Literal", Const, 0}, - {"MatchNL", Const, 0}, - {"NonGreedy", Const, 0}, - {"OneLine", Const, 0}, - {"Op", Type, 0}, - {"OpAlternate", Const, 0}, - {"OpAnyChar", Const, 0}, - {"OpAnyCharNotNL", Const, 0}, - {"OpBeginLine", Const, 0}, - {"OpBeginText", Const, 0}, - {"OpCapture", Const, 0}, - {"OpCharClass", Const, 0}, - {"OpConcat", Const, 0}, - {"OpEmptyMatch", Const, 0}, - {"OpEndLine", Const, 0}, - {"OpEndText", Const, 0}, - {"OpLiteral", Const, 0}, - {"OpNoMatch", Const, 0}, - {"OpNoWordBoundary", Const, 0}, - {"OpPlus", Const, 0}, - {"OpQuest", Const, 0}, - {"OpRepeat", Const, 0}, - {"OpStar", Const, 0}, - {"OpWordBoundary", Const, 0}, - {"POSIX", Const, 0}, - {"Parse", Func, 0}, - {"Perl", Const, 0}, - {"PerlX", Const, 0}, - {"Prog", Type, 0}, - {"Prog.Inst", Field, 0}, - {"Prog.NumCap", Field, 0}, - {"Prog.Start", Field, 0}, - {"Regexp", Type, 0}, - {"Regexp.Cap", Field, 0}, - {"Regexp.Flags", Field, 0}, - {"Regexp.Max", Field, 0}, - {"Regexp.Min", Field, 0}, - {"Regexp.Name", Field, 0}, - {"Regexp.Op", Field, 0}, - {"Regexp.Rune", Field, 0}, - {"Regexp.Rune0", Field, 0}, - {"Regexp.Sub", Field, 0}, - {"Regexp.Sub0", Field, 0}, - {"Simple", Const, 0}, - {"UnicodeGroups", Const, 0}, - {"WasDollar", Const, 0}, - }, - "runtime": { - {"(*BlockProfileRecord).Stack", Method, 1}, - {"(*Frames).Next", Method, 7}, - {"(*Func).Entry", Method, 0}, - {"(*Func).FileLine", Method, 0}, - {"(*Func).Name", Method, 0}, - {"(*MemProfileRecord).InUseBytes", Method, 0}, - {"(*MemProfileRecord).InUseObjects", Method, 0}, - {"(*MemProfileRecord).Stack", Method, 0}, - {"(*PanicNilError).Error", Method, 21}, - {"(*PanicNilError).RuntimeError", Method, 21}, - {"(*Pinner).Pin", Method, 21}, - {"(*Pinner).Unpin", Method, 21}, - {"(*StackRecord).Stack", Method, 0}, - {"(*TypeAssertionError).Error", Method, 0}, - {"(*TypeAssertionError).RuntimeError", Method, 0}, - {"(Cleanup).Stop", Method, 24}, - {"AddCleanup", Func, 24}, - {"BlockProfile", Func, 1}, - {"BlockProfileRecord", Type, 1}, - {"BlockProfileRecord.Count", Field, 1}, - {"BlockProfileRecord.Cycles", Field, 1}, - {"BlockProfileRecord.StackRecord", Field, 1}, - {"Breakpoint", Func, 0}, - {"CPUProfile", Func, 0}, - {"Caller", Func, 0}, - {"Callers", Func, 0}, - {"CallersFrames", Func, 7}, - {"Cleanup", Type, 24}, - {"Compiler", Const, 0}, - {"Error", Type, 0}, - {"Frame", Type, 7}, - {"Frame.Entry", Field, 7}, - {"Frame.File", Field, 7}, - {"Frame.Func", Field, 7}, - {"Frame.Function", Field, 7}, - {"Frame.Line", Field, 7}, - {"Frame.PC", Field, 7}, - {"Frames", Type, 7}, - {"Func", Type, 0}, - {"FuncForPC", Func, 0}, - {"GC", Func, 0}, - {"GOARCH", Const, 0}, - {"GOMAXPROCS", Func, 0}, - {"GOOS", Const, 0}, - {"GOROOT", Func, 0}, - {"Goexit", Func, 0}, - {"GoroutineProfile", Func, 0}, - {"Gosched", Func, 0}, - {"KeepAlive", Func, 7}, - {"LockOSThread", Func, 0}, - {"MemProfile", Func, 0}, - {"MemProfileRate", Var, 0}, - {"MemProfileRecord", Type, 0}, - {"MemProfileRecord.AllocBytes", Field, 0}, - {"MemProfileRecord.AllocObjects", Field, 0}, - {"MemProfileRecord.FreeBytes", Field, 0}, - {"MemProfileRecord.FreeObjects", Field, 0}, - {"MemProfileRecord.Stack0", Field, 0}, - {"MemStats", Type, 0}, - {"MemStats.Alloc", Field, 0}, - {"MemStats.BuckHashSys", Field, 0}, - {"MemStats.BySize", Field, 0}, - {"MemStats.DebugGC", Field, 0}, - {"MemStats.EnableGC", Field, 0}, - {"MemStats.Frees", Field, 0}, - {"MemStats.GCCPUFraction", Field, 5}, - {"MemStats.GCSys", Field, 2}, - {"MemStats.HeapAlloc", Field, 0}, - {"MemStats.HeapIdle", Field, 0}, - {"MemStats.HeapInuse", Field, 0}, - {"MemStats.HeapObjects", Field, 0}, - {"MemStats.HeapReleased", Field, 0}, - {"MemStats.HeapSys", Field, 0}, - {"MemStats.LastGC", Field, 0}, - {"MemStats.Lookups", Field, 0}, - {"MemStats.MCacheInuse", Field, 0}, - {"MemStats.MCacheSys", Field, 0}, - {"MemStats.MSpanInuse", Field, 0}, - {"MemStats.MSpanSys", Field, 0}, - {"MemStats.Mallocs", Field, 0}, - {"MemStats.NextGC", Field, 0}, - {"MemStats.NumForcedGC", Field, 8}, - {"MemStats.NumGC", Field, 0}, - {"MemStats.OtherSys", Field, 2}, - {"MemStats.PauseEnd", Field, 4}, - {"MemStats.PauseNs", Field, 0}, - {"MemStats.PauseTotalNs", Field, 0}, - {"MemStats.StackInuse", Field, 0}, - {"MemStats.StackSys", Field, 0}, - {"MemStats.Sys", Field, 0}, - {"MemStats.TotalAlloc", Field, 0}, - {"MutexProfile", Func, 8}, - {"NumCPU", Func, 0}, - {"NumCgoCall", Func, 0}, - {"NumGoroutine", Func, 0}, - {"PanicNilError", Type, 21}, - {"Pinner", Type, 21}, - {"ReadMemStats", Func, 0}, - {"ReadTrace", Func, 5}, - {"SetBlockProfileRate", Func, 1}, - {"SetCPUProfileRate", Func, 0}, - {"SetCgoTraceback", Func, 7}, - {"SetFinalizer", Func, 0}, - {"SetMutexProfileFraction", Func, 8}, - {"Stack", Func, 0}, - {"StackRecord", Type, 0}, - {"StackRecord.Stack0", Field, 0}, - {"StartTrace", Func, 5}, - {"StopTrace", Func, 5}, - {"ThreadCreateProfile", Func, 0}, - {"TypeAssertionError", Type, 0}, - {"UnlockOSThread", Func, 0}, - {"Version", Func, 0}, - }, - "runtime/cgo": { - {"(Handle).Delete", Method, 17}, - {"(Handle).Value", Method, 17}, - {"Handle", Type, 17}, - {"Incomplete", Type, 20}, - {"NewHandle", Func, 17}, - }, - "runtime/coverage": { - {"ClearCounters", Func, 20}, - {"WriteCounters", Func, 20}, - {"WriteCountersDir", Func, 20}, - {"WriteMeta", Func, 20}, - {"WriteMetaDir", Func, 20}, - }, - "runtime/debug": { - {"(*BuildInfo).String", Method, 18}, - {"BuildInfo", Type, 12}, - {"BuildInfo.Deps", Field, 12}, - {"BuildInfo.GoVersion", Field, 18}, - {"BuildInfo.Main", Field, 12}, - {"BuildInfo.Path", Field, 12}, - {"BuildInfo.Settings", Field, 18}, - {"BuildSetting", Type, 18}, - {"BuildSetting.Key", Field, 18}, - {"BuildSetting.Value", Field, 18}, - {"CrashOptions", Type, 23}, - {"FreeOSMemory", Func, 1}, - {"GCStats", Type, 1}, - {"GCStats.LastGC", Field, 1}, - {"GCStats.NumGC", Field, 1}, - {"GCStats.Pause", Field, 1}, - {"GCStats.PauseEnd", Field, 4}, - {"GCStats.PauseQuantiles", Field, 1}, - {"GCStats.PauseTotal", Field, 1}, - {"Module", Type, 12}, - {"Module.Path", Field, 12}, - {"Module.Replace", Field, 12}, - {"Module.Sum", Field, 12}, - {"Module.Version", Field, 12}, - {"ParseBuildInfo", Func, 18}, - {"PrintStack", Func, 0}, - {"ReadBuildInfo", Func, 12}, - {"ReadGCStats", Func, 1}, - {"SetCrashOutput", Func, 23}, - {"SetGCPercent", Func, 1}, - {"SetMaxStack", Func, 2}, - {"SetMaxThreads", Func, 2}, - {"SetMemoryLimit", Func, 19}, - {"SetPanicOnFault", Func, 3}, - {"SetTraceback", Func, 6}, - {"Stack", Func, 0}, - {"WriteHeapDump", Func, 3}, - }, - "runtime/metrics": { - {"(Value).Float64", Method, 16}, - {"(Value).Float64Histogram", Method, 16}, - {"(Value).Kind", Method, 16}, - {"(Value).Uint64", Method, 16}, - {"All", Func, 16}, - {"Description", Type, 16}, - {"Description.Cumulative", Field, 16}, - {"Description.Description", Field, 16}, - {"Description.Kind", Field, 16}, - {"Description.Name", Field, 16}, - {"Float64Histogram", Type, 16}, - {"Float64Histogram.Buckets", Field, 16}, - {"Float64Histogram.Counts", Field, 16}, - {"KindBad", Const, 16}, - {"KindFloat64", Const, 16}, - {"KindFloat64Histogram", Const, 16}, - {"KindUint64", Const, 16}, - {"Read", Func, 16}, - {"Sample", Type, 16}, - {"Sample.Name", Field, 16}, - {"Sample.Value", Field, 16}, - {"Value", Type, 16}, - {"ValueKind", Type, 16}, - }, - "runtime/pprof": { - {"(*Profile).Add", Method, 0}, - {"(*Profile).Count", Method, 0}, - {"(*Profile).Name", Method, 0}, - {"(*Profile).Remove", Method, 0}, - {"(*Profile).WriteTo", Method, 0}, - {"Do", Func, 9}, - {"ForLabels", Func, 9}, - {"Label", Func, 9}, - {"LabelSet", Type, 9}, - {"Labels", Func, 9}, - {"Lookup", Func, 0}, - {"NewProfile", Func, 0}, - {"Profile", Type, 0}, - {"Profiles", Func, 0}, - {"SetGoroutineLabels", Func, 9}, - {"StartCPUProfile", Func, 0}, - {"StopCPUProfile", Func, 0}, - {"WithLabels", Func, 9}, - {"WriteHeapProfile", Func, 0}, - }, - "runtime/trace": { - {"(*Region).End", Method, 11}, - {"(*Task).End", Method, 11}, - {"IsEnabled", Func, 11}, - {"Log", Func, 11}, - {"Logf", Func, 11}, - {"NewTask", Func, 11}, - {"Region", Type, 11}, - {"Start", Func, 5}, - {"StartRegion", Func, 11}, - {"Stop", Func, 5}, - {"Task", Type, 11}, - {"WithRegion", Func, 11}, - }, - "slices": { - {"All", Func, 23}, - {"AppendSeq", Func, 23}, - {"Backward", Func, 23}, - {"BinarySearch", Func, 21}, - {"BinarySearchFunc", Func, 21}, - {"Chunk", Func, 23}, - {"Clip", Func, 21}, - {"Clone", Func, 21}, - {"Collect", Func, 23}, - {"Compact", Func, 21}, - {"CompactFunc", Func, 21}, - {"Compare", Func, 21}, - {"CompareFunc", Func, 21}, - {"Concat", Func, 22}, - {"Contains", Func, 21}, - {"ContainsFunc", Func, 21}, - {"Delete", Func, 21}, - {"DeleteFunc", Func, 21}, - {"Equal", Func, 21}, - {"EqualFunc", Func, 21}, - {"Grow", Func, 21}, - {"Index", Func, 21}, - {"IndexFunc", Func, 21}, - {"Insert", Func, 21}, - {"IsSorted", Func, 21}, - {"IsSortedFunc", Func, 21}, - {"Max", Func, 21}, - {"MaxFunc", Func, 21}, - {"Min", Func, 21}, - {"MinFunc", Func, 21}, - {"Repeat", Func, 23}, - {"Replace", Func, 21}, - {"Reverse", Func, 21}, - {"Sort", Func, 21}, - {"SortFunc", Func, 21}, - {"SortStableFunc", Func, 21}, - {"Sorted", Func, 23}, - {"SortedFunc", Func, 23}, - {"SortedStableFunc", Func, 23}, - {"Values", Func, 23}, - }, - "sort": { - {"(Float64Slice).Len", Method, 0}, - {"(Float64Slice).Less", Method, 0}, - {"(Float64Slice).Search", Method, 0}, - {"(Float64Slice).Sort", Method, 0}, - {"(Float64Slice).Swap", Method, 0}, - {"(IntSlice).Len", Method, 0}, - {"(IntSlice).Less", Method, 0}, - {"(IntSlice).Search", Method, 0}, - {"(IntSlice).Sort", Method, 0}, - {"(IntSlice).Swap", Method, 0}, - {"(StringSlice).Len", Method, 0}, - {"(StringSlice).Less", Method, 0}, - {"(StringSlice).Search", Method, 0}, - {"(StringSlice).Sort", Method, 0}, - {"(StringSlice).Swap", Method, 0}, - {"Find", Func, 19}, - {"Float64Slice", Type, 0}, - {"Float64s", Func, 0}, - {"Float64sAreSorted", Func, 0}, - {"IntSlice", Type, 0}, - {"Interface", Type, 0}, - {"Ints", Func, 0}, - {"IntsAreSorted", Func, 0}, - {"IsSorted", Func, 0}, - {"Reverse", Func, 1}, - {"Search", Func, 0}, - {"SearchFloat64s", Func, 0}, - {"SearchInts", Func, 0}, - {"SearchStrings", Func, 0}, - {"Slice", Func, 8}, - {"SliceIsSorted", Func, 8}, - {"SliceStable", Func, 8}, - {"Sort", Func, 0}, - {"Stable", Func, 2}, - {"StringSlice", Type, 0}, - {"Strings", Func, 0}, - {"StringsAreSorted", Func, 0}, - }, - "strconv": { - {"(*NumError).Error", Method, 0}, - {"(*NumError).Unwrap", Method, 14}, - {"AppendBool", Func, 0}, - {"AppendFloat", Func, 0}, - {"AppendInt", Func, 0}, - {"AppendQuote", Func, 0}, - {"AppendQuoteRune", Func, 0}, - {"AppendQuoteRuneToASCII", Func, 0}, - {"AppendQuoteRuneToGraphic", Func, 6}, - {"AppendQuoteToASCII", Func, 0}, - {"AppendQuoteToGraphic", Func, 6}, - {"AppendUint", Func, 0}, - {"Atoi", Func, 0}, - {"CanBackquote", Func, 0}, - {"ErrRange", Var, 0}, - {"ErrSyntax", Var, 0}, - {"FormatBool", Func, 0}, - {"FormatComplex", Func, 15}, - {"FormatFloat", Func, 0}, - {"FormatInt", Func, 0}, - {"FormatUint", Func, 0}, - {"IntSize", Const, 0}, - {"IsGraphic", Func, 6}, - {"IsPrint", Func, 0}, - {"Itoa", Func, 0}, - {"NumError", Type, 0}, - {"NumError.Err", Field, 0}, - {"NumError.Func", Field, 0}, - {"NumError.Num", Field, 0}, - {"ParseBool", Func, 0}, - {"ParseComplex", Func, 15}, - {"ParseFloat", Func, 0}, - {"ParseInt", Func, 0}, - {"ParseUint", Func, 0}, - {"Quote", Func, 0}, - {"QuoteRune", Func, 0}, - {"QuoteRuneToASCII", Func, 0}, - {"QuoteRuneToGraphic", Func, 6}, - {"QuoteToASCII", Func, 0}, - {"QuoteToGraphic", Func, 6}, - {"QuotedPrefix", Func, 17}, - {"Unquote", Func, 0}, - {"UnquoteChar", Func, 0}, - }, - "strings": { - {"(*Builder).Cap", Method, 12}, - {"(*Builder).Grow", Method, 10}, - {"(*Builder).Len", Method, 10}, - {"(*Builder).Reset", Method, 10}, - {"(*Builder).String", Method, 10}, - {"(*Builder).Write", Method, 10}, - {"(*Builder).WriteByte", Method, 10}, - {"(*Builder).WriteRune", Method, 10}, - {"(*Builder).WriteString", Method, 10}, - {"(*Reader).Len", Method, 0}, - {"(*Reader).Read", Method, 0}, - {"(*Reader).ReadAt", Method, 0}, - {"(*Reader).ReadByte", Method, 0}, - {"(*Reader).ReadRune", Method, 0}, - {"(*Reader).Reset", Method, 7}, - {"(*Reader).Seek", Method, 0}, - {"(*Reader).Size", Method, 5}, - {"(*Reader).UnreadByte", Method, 0}, - {"(*Reader).UnreadRune", Method, 0}, - {"(*Reader).WriteTo", Method, 1}, - {"(*Replacer).Replace", Method, 0}, - {"(*Replacer).WriteString", Method, 0}, - {"Builder", Type, 10}, - {"Clone", Func, 18}, - {"Compare", Func, 5}, - {"Contains", Func, 0}, - {"ContainsAny", Func, 0}, - {"ContainsFunc", Func, 21}, - {"ContainsRune", Func, 0}, - {"Count", Func, 0}, - {"Cut", Func, 18}, - {"CutPrefix", Func, 20}, - {"CutSuffix", Func, 20}, - {"EqualFold", Func, 0}, - {"Fields", Func, 0}, - {"FieldsFunc", Func, 0}, - {"FieldsFuncSeq", Func, 24}, - {"FieldsSeq", Func, 24}, - {"HasPrefix", Func, 0}, - {"HasSuffix", Func, 0}, - {"Index", Func, 0}, - {"IndexAny", Func, 0}, - {"IndexByte", Func, 2}, - {"IndexFunc", Func, 0}, - {"IndexRune", Func, 0}, - {"Join", Func, 0}, - {"LastIndex", Func, 0}, - {"LastIndexAny", Func, 0}, - {"LastIndexByte", Func, 5}, - {"LastIndexFunc", Func, 0}, - {"Lines", Func, 24}, - {"Map", Func, 0}, - {"NewReader", Func, 0}, - {"NewReplacer", Func, 0}, - {"Reader", Type, 0}, - {"Repeat", Func, 0}, - {"Replace", Func, 0}, - {"ReplaceAll", Func, 12}, - {"Replacer", Type, 0}, - {"Split", Func, 0}, - {"SplitAfter", Func, 0}, - {"SplitAfterN", Func, 0}, - {"SplitAfterSeq", Func, 24}, - {"SplitN", Func, 0}, - {"SplitSeq", Func, 24}, - {"Title", Func, 0}, - {"ToLower", Func, 0}, - {"ToLowerSpecial", Func, 0}, - {"ToTitle", Func, 0}, - {"ToTitleSpecial", Func, 0}, - {"ToUpper", Func, 0}, - {"ToUpperSpecial", Func, 0}, - {"ToValidUTF8", Func, 13}, - {"Trim", Func, 0}, - {"TrimFunc", Func, 0}, - {"TrimLeft", Func, 0}, - {"TrimLeftFunc", Func, 0}, - {"TrimPrefix", Func, 1}, - {"TrimRight", Func, 0}, - {"TrimRightFunc", Func, 0}, - {"TrimSpace", Func, 0}, - {"TrimSuffix", Func, 1}, - }, - "structs": { - {"HostLayout", Type, 23}, - }, - "sync": { - {"(*Cond).Broadcast", Method, 0}, - {"(*Cond).Signal", Method, 0}, - {"(*Cond).Wait", Method, 0}, - {"(*Map).Clear", Method, 23}, - {"(*Map).CompareAndDelete", Method, 20}, - {"(*Map).CompareAndSwap", Method, 20}, - {"(*Map).Delete", Method, 9}, - {"(*Map).Load", Method, 9}, - {"(*Map).LoadAndDelete", Method, 15}, - {"(*Map).LoadOrStore", Method, 9}, - {"(*Map).Range", Method, 9}, - {"(*Map).Store", Method, 9}, - {"(*Map).Swap", Method, 20}, - {"(*Mutex).Lock", Method, 0}, - {"(*Mutex).TryLock", Method, 18}, - {"(*Mutex).Unlock", Method, 0}, - {"(*Once).Do", Method, 0}, - {"(*Pool).Get", Method, 3}, - {"(*Pool).Put", Method, 3}, - {"(*RWMutex).Lock", Method, 0}, - {"(*RWMutex).RLock", Method, 0}, - {"(*RWMutex).RLocker", Method, 0}, - {"(*RWMutex).RUnlock", Method, 0}, - {"(*RWMutex).TryLock", Method, 18}, - {"(*RWMutex).TryRLock", Method, 18}, - {"(*RWMutex).Unlock", Method, 0}, - {"(*WaitGroup).Add", Method, 0}, - {"(*WaitGroup).Done", Method, 0}, - {"(*WaitGroup).Wait", Method, 0}, - {"Cond", Type, 0}, - {"Cond.L", Field, 0}, - {"Locker", Type, 0}, - {"Map", Type, 9}, - {"Mutex", Type, 0}, - {"NewCond", Func, 0}, - {"Once", Type, 0}, - {"OnceFunc", Func, 21}, - {"OnceValue", Func, 21}, - {"OnceValues", Func, 21}, - {"Pool", Type, 3}, - {"Pool.New", Field, 3}, - {"RWMutex", Type, 0}, - {"WaitGroup", Type, 0}, - }, - "sync/atomic": { - {"(*Bool).CompareAndSwap", Method, 19}, - {"(*Bool).Load", Method, 19}, - {"(*Bool).Store", Method, 19}, - {"(*Bool).Swap", Method, 19}, - {"(*Int32).Add", Method, 19}, - {"(*Int32).And", Method, 23}, - {"(*Int32).CompareAndSwap", Method, 19}, - {"(*Int32).Load", Method, 19}, - {"(*Int32).Or", Method, 23}, - {"(*Int32).Store", Method, 19}, - {"(*Int32).Swap", Method, 19}, - {"(*Int64).Add", Method, 19}, - {"(*Int64).And", Method, 23}, - {"(*Int64).CompareAndSwap", Method, 19}, - {"(*Int64).Load", Method, 19}, - {"(*Int64).Or", Method, 23}, - {"(*Int64).Store", Method, 19}, - {"(*Int64).Swap", Method, 19}, - {"(*Pointer).CompareAndSwap", Method, 19}, - {"(*Pointer).Load", Method, 19}, - {"(*Pointer).Store", Method, 19}, - {"(*Pointer).Swap", Method, 19}, - {"(*Uint32).Add", Method, 19}, - {"(*Uint32).And", Method, 23}, - {"(*Uint32).CompareAndSwap", Method, 19}, - {"(*Uint32).Load", Method, 19}, - {"(*Uint32).Or", Method, 23}, - {"(*Uint32).Store", Method, 19}, - {"(*Uint32).Swap", Method, 19}, - {"(*Uint64).Add", Method, 19}, - {"(*Uint64).And", Method, 23}, - {"(*Uint64).CompareAndSwap", Method, 19}, - {"(*Uint64).Load", Method, 19}, - {"(*Uint64).Or", Method, 23}, - {"(*Uint64).Store", Method, 19}, - {"(*Uint64).Swap", Method, 19}, - {"(*Uintptr).Add", Method, 19}, - {"(*Uintptr).And", Method, 23}, - {"(*Uintptr).CompareAndSwap", Method, 19}, - {"(*Uintptr).Load", Method, 19}, - {"(*Uintptr).Or", Method, 23}, - {"(*Uintptr).Store", Method, 19}, - {"(*Uintptr).Swap", Method, 19}, - {"(*Value).CompareAndSwap", Method, 17}, - {"(*Value).Load", Method, 4}, - {"(*Value).Store", Method, 4}, - {"(*Value).Swap", Method, 17}, - {"AddInt32", Func, 0}, - {"AddInt64", Func, 0}, - {"AddUint32", Func, 0}, - {"AddUint64", Func, 0}, - {"AddUintptr", Func, 0}, - {"AndInt32", Func, 23}, - {"AndInt64", Func, 23}, - {"AndUint32", Func, 23}, - {"AndUint64", Func, 23}, - {"AndUintptr", Func, 23}, - {"Bool", Type, 19}, - {"CompareAndSwapInt32", Func, 0}, - {"CompareAndSwapInt64", Func, 0}, - {"CompareAndSwapPointer", Func, 0}, - {"CompareAndSwapUint32", Func, 0}, - {"CompareAndSwapUint64", Func, 0}, - {"CompareAndSwapUintptr", Func, 0}, - {"Int32", Type, 19}, - {"Int64", Type, 19}, - {"LoadInt32", Func, 0}, - {"LoadInt64", Func, 0}, - {"LoadPointer", Func, 0}, - {"LoadUint32", Func, 0}, - {"LoadUint64", Func, 0}, - {"LoadUintptr", Func, 0}, - {"OrInt32", Func, 23}, - {"OrInt64", Func, 23}, - {"OrUint32", Func, 23}, - {"OrUint64", Func, 23}, - {"OrUintptr", Func, 23}, - {"Pointer", Type, 19}, - {"StoreInt32", Func, 0}, - {"StoreInt64", Func, 0}, - {"StorePointer", Func, 0}, - {"StoreUint32", Func, 0}, - {"StoreUint64", Func, 0}, - {"StoreUintptr", Func, 0}, - {"SwapInt32", Func, 2}, - {"SwapInt64", Func, 2}, - {"SwapPointer", Func, 2}, - {"SwapUint32", Func, 2}, - {"SwapUint64", Func, 2}, - {"SwapUintptr", Func, 2}, - {"Uint32", Type, 19}, - {"Uint64", Type, 19}, - {"Uintptr", Type, 19}, - {"Value", Type, 4}, - }, - "syscall": { - {"(*Cmsghdr).SetLen", Method, 0}, - {"(*DLL).FindProc", Method, 0}, - {"(*DLL).MustFindProc", Method, 0}, - {"(*DLL).Release", Method, 0}, - {"(*DLLError).Error", Method, 0}, - {"(*DLLError).Unwrap", Method, 16}, - {"(*Filetime).Nanoseconds", Method, 0}, - {"(*Iovec).SetLen", Method, 0}, - {"(*LazyDLL).Handle", Method, 0}, - {"(*LazyDLL).Load", Method, 0}, - {"(*LazyDLL).NewProc", Method, 0}, - {"(*LazyProc).Addr", Method, 0}, - {"(*LazyProc).Call", Method, 0}, - {"(*LazyProc).Find", Method, 0}, - {"(*Msghdr).SetControllen", Method, 0}, - {"(*Proc).Addr", Method, 0}, - {"(*Proc).Call", Method, 0}, - {"(*PtraceRegs).PC", Method, 0}, - {"(*PtraceRegs).SetPC", Method, 0}, - {"(*RawSockaddrAny).Sockaddr", Method, 0}, - {"(*SID).Copy", Method, 0}, - {"(*SID).Len", Method, 0}, - {"(*SID).LookupAccount", Method, 0}, - {"(*SID).String", Method, 0}, - {"(*Timespec).Nano", Method, 0}, - {"(*Timespec).Unix", Method, 0}, - {"(*Timeval).Nano", Method, 0}, - {"(*Timeval).Nanoseconds", Method, 0}, - {"(*Timeval).Unix", Method, 0}, - {"(Errno).Error", Method, 0}, - {"(Errno).Is", Method, 13}, - {"(Errno).Temporary", Method, 0}, - {"(Errno).Timeout", Method, 0}, - {"(Signal).Signal", Method, 0}, - {"(Signal).String", Method, 0}, - {"(Token).Close", Method, 0}, - {"(Token).GetTokenPrimaryGroup", Method, 0}, - {"(Token).GetTokenUser", Method, 0}, - {"(Token).GetUserProfileDirectory", Method, 0}, - {"(WaitStatus).Continued", Method, 0}, - {"(WaitStatus).CoreDump", Method, 0}, - {"(WaitStatus).ExitStatus", Method, 0}, - {"(WaitStatus).Exited", Method, 0}, - {"(WaitStatus).Signal", Method, 0}, - {"(WaitStatus).Signaled", Method, 0}, - {"(WaitStatus).StopSignal", Method, 0}, - {"(WaitStatus).Stopped", Method, 0}, - {"(WaitStatus).TrapCause", Method, 0}, - {"AF_ALG", Const, 0}, - {"AF_APPLETALK", Const, 0}, - {"AF_ARP", Const, 0}, - {"AF_ASH", Const, 0}, - {"AF_ATM", Const, 0}, - {"AF_ATMPVC", Const, 0}, - {"AF_ATMSVC", Const, 0}, - {"AF_AX25", Const, 0}, - {"AF_BLUETOOTH", Const, 0}, - {"AF_BRIDGE", Const, 0}, - {"AF_CAIF", Const, 0}, - {"AF_CAN", Const, 0}, - {"AF_CCITT", Const, 0}, - {"AF_CHAOS", Const, 0}, - {"AF_CNT", Const, 0}, - {"AF_COIP", Const, 0}, - {"AF_DATAKIT", Const, 0}, - {"AF_DECnet", Const, 0}, - {"AF_DLI", Const, 0}, - {"AF_E164", Const, 0}, - {"AF_ECMA", Const, 0}, - {"AF_ECONET", Const, 0}, - {"AF_ENCAP", Const, 1}, - {"AF_FILE", Const, 0}, - {"AF_HYLINK", Const, 0}, - {"AF_IEEE80211", Const, 0}, - {"AF_IEEE802154", Const, 0}, - {"AF_IMPLINK", Const, 0}, - {"AF_INET", Const, 0}, - {"AF_INET6", Const, 0}, - {"AF_INET6_SDP", Const, 3}, - {"AF_INET_SDP", Const, 3}, - {"AF_IPX", Const, 0}, - {"AF_IRDA", Const, 0}, - {"AF_ISDN", Const, 0}, - {"AF_ISO", Const, 0}, - {"AF_IUCV", Const, 0}, - {"AF_KEY", Const, 0}, - {"AF_LAT", Const, 0}, - {"AF_LINK", Const, 0}, - {"AF_LLC", Const, 0}, - {"AF_LOCAL", Const, 0}, - {"AF_MAX", Const, 0}, - {"AF_MPLS", Const, 1}, - {"AF_NATM", Const, 0}, - {"AF_NDRV", Const, 0}, - {"AF_NETBEUI", Const, 0}, - {"AF_NETBIOS", Const, 0}, - {"AF_NETGRAPH", Const, 0}, - {"AF_NETLINK", Const, 0}, - {"AF_NETROM", Const, 0}, - {"AF_NS", Const, 0}, - {"AF_OROUTE", Const, 1}, - {"AF_OSI", Const, 0}, - {"AF_PACKET", Const, 0}, - {"AF_PHONET", Const, 0}, - {"AF_PPP", Const, 0}, - {"AF_PPPOX", Const, 0}, - {"AF_PUP", Const, 0}, - {"AF_RDS", Const, 0}, - {"AF_RESERVED_36", Const, 0}, - {"AF_ROSE", Const, 0}, - {"AF_ROUTE", Const, 0}, - {"AF_RXRPC", Const, 0}, - {"AF_SCLUSTER", Const, 0}, - {"AF_SECURITY", Const, 0}, - {"AF_SIP", Const, 0}, - {"AF_SLOW", Const, 0}, - {"AF_SNA", Const, 0}, - {"AF_SYSTEM", Const, 0}, - {"AF_TIPC", Const, 0}, - {"AF_UNIX", Const, 0}, - {"AF_UNSPEC", Const, 0}, - {"AF_UTUN", Const, 16}, - {"AF_VENDOR00", Const, 0}, - {"AF_VENDOR01", Const, 0}, - {"AF_VENDOR02", Const, 0}, - {"AF_VENDOR03", Const, 0}, - {"AF_VENDOR04", Const, 0}, - {"AF_VENDOR05", Const, 0}, - {"AF_VENDOR06", Const, 0}, - {"AF_VENDOR07", Const, 0}, - {"AF_VENDOR08", Const, 0}, - {"AF_VENDOR09", Const, 0}, - {"AF_VENDOR10", Const, 0}, - {"AF_VENDOR11", Const, 0}, - {"AF_VENDOR12", Const, 0}, - {"AF_VENDOR13", Const, 0}, - {"AF_VENDOR14", Const, 0}, - {"AF_VENDOR15", Const, 0}, - {"AF_VENDOR16", Const, 0}, - {"AF_VENDOR17", Const, 0}, - {"AF_VENDOR18", Const, 0}, - {"AF_VENDOR19", Const, 0}, - {"AF_VENDOR20", Const, 0}, - {"AF_VENDOR21", Const, 0}, - {"AF_VENDOR22", Const, 0}, - {"AF_VENDOR23", Const, 0}, - {"AF_VENDOR24", Const, 0}, - {"AF_VENDOR25", Const, 0}, - {"AF_VENDOR26", Const, 0}, - {"AF_VENDOR27", Const, 0}, - {"AF_VENDOR28", Const, 0}, - {"AF_VENDOR29", Const, 0}, - {"AF_VENDOR30", Const, 0}, - {"AF_VENDOR31", Const, 0}, - {"AF_VENDOR32", Const, 0}, - {"AF_VENDOR33", Const, 0}, - {"AF_VENDOR34", Const, 0}, - {"AF_VENDOR35", Const, 0}, - {"AF_VENDOR36", Const, 0}, - {"AF_VENDOR37", Const, 0}, - {"AF_VENDOR38", Const, 0}, - {"AF_VENDOR39", Const, 0}, - {"AF_VENDOR40", Const, 0}, - {"AF_VENDOR41", Const, 0}, - {"AF_VENDOR42", Const, 0}, - {"AF_VENDOR43", Const, 0}, - {"AF_VENDOR44", Const, 0}, - {"AF_VENDOR45", Const, 0}, - {"AF_VENDOR46", Const, 0}, - {"AF_VENDOR47", Const, 0}, - {"AF_WANPIPE", Const, 0}, - {"AF_X25", Const, 0}, - {"AI_CANONNAME", Const, 1}, - {"AI_NUMERICHOST", Const, 1}, - {"AI_PASSIVE", Const, 1}, - {"APPLICATION_ERROR", Const, 0}, - {"ARPHRD_ADAPT", Const, 0}, - {"ARPHRD_APPLETLK", Const, 0}, - {"ARPHRD_ARCNET", Const, 0}, - {"ARPHRD_ASH", Const, 0}, - {"ARPHRD_ATM", Const, 0}, - {"ARPHRD_AX25", Const, 0}, - {"ARPHRD_BIF", Const, 0}, - {"ARPHRD_CHAOS", Const, 0}, - {"ARPHRD_CISCO", Const, 0}, - {"ARPHRD_CSLIP", Const, 0}, - {"ARPHRD_CSLIP6", Const, 0}, - {"ARPHRD_DDCMP", Const, 0}, - {"ARPHRD_DLCI", Const, 0}, - {"ARPHRD_ECONET", Const, 0}, - {"ARPHRD_EETHER", Const, 0}, - {"ARPHRD_ETHER", Const, 0}, - {"ARPHRD_EUI64", Const, 0}, - {"ARPHRD_FCAL", Const, 0}, - {"ARPHRD_FCFABRIC", Const, 0}, - {"ARPHRD_FCPL", Const, 0}, - {"ARPHRD_FCPP", Const, 0}, - {"ARPHRD_FDDI", Const, 0}, - {"ARPHRD_FRAD", Const, 0}, - {"ARPHRD_FRELAY", Const, 1}, - {"ARPHRD_HDLC", Const, 0}, - {"ARPHRD_HIPPI", Const, 0}, - {"ARPHRD_HWX25", Const, 0}, - {"ARPHRD_IEEE1394", Const, 0}, - {"ARPHRD_IEEE802", Const, 0}, - {"ARPHRD_IEEE80211", Const, 0}, - {"ARPHRD_IEEE80211_PRISM", Const, 0}, - {"ARPHRD_IEEE80211_RADIOTAP", Const, 0}, - {"ARPHRD_IEEE802154", Const, 0}, - {"ARPHRD_IEEE802154_PHY", Const, 0}, - {"ARPHRD_IEEE802_TR", Const, 0}, - {"ARPHRD_INFINIBAND", Const, 0}, - {"ARPHRD_IPDDP", Const, 0}, - {"ARPHRD_IPGRE", Const, 0}, - {"ARPHRD_IRDA", Const, 0}, - {"ARPHRD_LAPB", Const, 0}, - {"ARPHRD_LOCALTLK", Const, 0}, - {"ARPHRD_LOOPBACK", Const, 0}, - {"ARPHRD_METRICOM", Const, 0}, - {"ARPHRD_NETROM", Const, 0}, - {"ARPHRD_NONE", Const, 0}, - {"ARPHRD_PIMREG", Const, 0}, - {"ARPHRD_PPP", Const, 0}, - {"ARPHRD_PRONET", Const, 0}, - {"ARPHRD_RAWHDLC", Const, 0}, - {"ARPHRD_ROSE", Const, 0}, - {"ARPHRD_RSRVD", Const, 0}, - {"ARPHRD_SIT", Const, 0}, - {"ARPHRD_SKIP", Const, 0}, - {"ARPHRD_SLIP", Const, 0}, - {"ARPHRD_SLIP6", Const, 0}, - {"ARPHRD_STRIP", Const, 1}, - {"ARPHRD_TUNNEL", Const, 0}, - {"ARPHRD_TUNNEL6", Const, 0}, - {"ARPHRD_VOID", Const, 0}, - {"ARPHRD_X25", Const, 0}, - {"AUTHTYPE_CLIENT", Const, 0}, - {"AUTHTYPE_SERVER", Const, 0}, - {"Accept", Func, 0}, - {"Accept4", Func, 1}, - {"AcceptEx", Func, 0}, - {"Access", Func, 0}, - {"Acct", Func, 0}, - {"AddrinfoW", Type, 1}, - {"AddrinfoW.Addr", Field, 1}, - {"AddrinfoW.Addrlen", Field, 1}, - {"AddrinfoW.Canonname", Field, 1}, - {"AddrinfoW.Family", Field, 1}, - {"AddrinfoW.Flags", Field, 1}, - {"AddrinfoW.Next", Field, 1}, - {"AddrinfoW.Protocol", Field, 1}, - {"AddrinfoW.Socktype", Field, 1}, - {"Adjtime", Func, 0}, - {"Adjtimex", Func, 0}, - {"AllThreadsSyscall", Func, 16}, - {"AllThreadsSyscall6", Func, 16}, - {"AttachLsf", Func, 0}, - {"B0", Const, 0}, - {"B1000000", Const, 0}, - {"B110", Const, 0}, - {"B115200", Const, 0}, - {"B1152000", Const, 0}, - {"B1200", Const, 0}, - {"B134", Const, 0}, - {"B14400", Const, 1}, - {"B150", Const, 0}, - {"B1500000", Const, 0}, - {"B1800", Const, 0}, - {"B19200", Const, 0}, - {"B200", Const, 0}, - {"B2000000", Const, 0}, - {"B230400", Const, 0}, - {"B2400", Const, 0}, - {"B2500000", Const, 0}, - {"B28800", Const, 1}, - {"B300", Const, 0}, - {"B3000000", Const, 0}, - {"B3500000", Const, 0}, - {"B38400", Const, 0}, - {"B4000000", Const, 0}, - {"B460800", Const, 0}, - {"B4800", Const, 0}, - {"B50", Const, 0}, - {"B500000", Const, 0}, - {"B57600", Const, 0}, - {"B576000", Const, 0}, - {"B600", Const, 0}, - {"B7200", Const, 1}, - {"B75", Const, 0}, - {"B76800", Const, 1}, - {"B921600", Const, 0}, - {"B9600", Const, 0}, - {"BASE_PROTOCOL", Const, 2}, - {"BIOCFEEDBACK", Const, 0}, - {"BIOCFLUSH", Const, 0}, - {"BIOCGBLEN", Const, 0}, - {"BIOCGDIRECTION", Const, 0}, - {"BIOCGDIRFILT", Const, 1}, - {"BIOCGDLT", Const, 0}, - {"BIOCGDLTLIST", Const, 0}, - {"BIOCGETBUFMODE", Const, 0}, - {"BIOCGETIF", Const, 0}, - {"BIOCGETZMAX", Const, 0}, - {"BIOCGFEEDBACK", Const, 1}, - {"BIOCGFILDROP", Const, 1}, - {"BIOCGHDRCMPLT", Const, 0}, - {"BIOCGRSIG", Const, 0}, - {"BIOCGRTIMEOUT", Const, 0}, - {"BIOCGSEESENT", Const, 0}, - {"BIOCGSTATS", Const, 0}, - {"BIOCGSTATSOLD", Const, 1}, - {"BIOCGTSTAMP", Const, 1}, - {"BIOCIMMEDIATE", Const, 0}, - {"BIOCLOCK", Const, 0}, - {"BIOCPROMISC", Const, 0}, - {"BIOCROTZBUF", Const, 0}, - {"BIOCSBLEN", Const, 0}, - {"BIOCSDIRECTION", Const, 0}, - {"BIOCSDIRFILT", Const, 1}, - {"BIOCSDLT", Const, 0}, - {"BIOCSETBUFMODE", Const, 0}, - {"BIOCSETF", Const, 0}, - {"BIOCSETFNR", Const, 0}, - {"BIOCSETIF", Const, 0}, - {"BIOCSETWF", Const, 0}, - {"BIOCSETZBUF", Const, 0}, - {"BIOCSFEEDBACK", Const, 1}, - {"BIOCSFILDROP", Const, 1}, - {"BIOCSHDRCMPLT", Const, 0}, - {"BIOCSRSIG", Const, 0}, - {"BIOCSRTIMEOUT", Const, 0}, - {"BIOCSSEESENT", Const, 0}, - {"BIOCSTCPF", Const, 1}, - {"BIOCSTSTAMP", Const, 1}, - {"BIOCSUDPF", Const, 1}, - {"BIOCVERSION", Const, 0}, - {"BPF_A", Const, 0}, - {"BPF_ABS", Const, 0}, - {"BPF_ADD", Const, 0}, - {"BPF_ALIGNMENT", Const, 0}, - {"BPF_ALIGNMENT32", Const, 1}, - {"BPF_ALU", Const, 0}, - {"BPF_AND", Const, 0}, - {"BPF_B", Const, 0}, - {"BPF_BUFMODE_BUFFER", Const, 0}, - {"BPF_BUFMODE_ZBUF", Const, 0}, - {"BPF_DFLTBUFSIZE", Const, 1}, - {"BPF_DIRECTION_IN", Const, 1}, - {"BPF_DIRECTION_OUT", Const, 1}, - {"BPF_DIV", Const, 0}, - {"BPF_H", Const, 0}, - {"BPF_IMM", Const, 0}, - {"BPF_IND", Const, 0}, - {"BPF_JA", Const, 0}, - {"BPF_JEQ", Const, 0}, - {"BPF_JGE", Const, 0}, - {"BPF_JGT", Const, 0}, - {"BPF_JMP", Const, 0}, - {"BPF_JSET", Const, 0}, - {"BPF_K", Const, 0}, - {"BPF_LD", Const, 0}, - {"BPF_LDX", Const, 0}, - {"BPF_LEN", Const, 0}, - {"BPF_LSH", Const, 0}, - {"BPF_MAJOR_VERSION", Const, 0}, - {"BPF_MAXBUFSIZE", Const, 0}, - {"BPF_MAXINSNS", Const, 0}, - {"BPF_MEM", Const, 0}, - {"BPF_MEMWORDS", Const, 0}, - {"BPF_MINBUFSIZE", Const, 0}, - {"BPF_MINOR_VERSION", Const, 0}, - {"BPF_MISC", Const, 0}, - {"BPF_MSH", Const, 0}, - {"BPF_MUL", Const, 0}, - {"BPF_NEG", Const, 0}, - {"BPF_OR", Const, 0}, - {"BPF_RELEASE", Const, 0}, - {"BPF_RET", Const, 0}, - {"BPF_RSH", Const, 0}, - {"BPF_ST", Const, 0}, - {"BPF_STX", Const, 0}, - {"BPF_SUB", Const, 0}, - {"BPF_TAX", Const, 0}, - {"BPF_TXA", Const, 0}, - {"BPF_T_BINTIME", Const, 1}, - {"BPF_T_BINTIME_FAST", Const, 1}, - {"BPF_T_BINTIME_MONOTONIC", Const, 1}, - {"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1}, - {"BPF_T_FAST", Const, 1}, - {"BPF_T_FLAG_MASK", Const, 1}, - {"BPF_T_FORMAT_MASK", Const, 1}, - {"BPF_T_MICROTIME", Const, 1}, - {"BPF_T_MICROTIME_FAST", Const, 1}, - {"BPF_T_MICROTIME_MONOTONIC", Const, 1}, - {"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1}, - {"BPF_T_MONOTONIC", Const, 1}, - {"BPF_T_MONOTONIC_FAST", Const, 1}, - {"BPF_T_NANOTIME", Const, 1}, - {"BPF_T_NANOTIME_FAST", Const, 1}, - {"BPF_T_NANOTIME_MONOTONIC", Const, 1}, - {"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1}, - {"BPF_T_NONE", Const, 1}, - {"BPF_T_NORMAL", Const, 1}, - {"BPF_W", Const, 0}, - {"BPF_X", Const, 0}, - {"BRKINT", Const, 0}, - {"Bind", Func, 0}, - {"BindToDevice", Func, 0}, - {"BpfBuflen", Func, 0}, - {"BpfDatalink", Func, 0}, - {"BpfHdr", Type, 0}, - {"BpfHdr.Caplen", Field, 0}, - {"BpfHdr.Datalen", Field, 0}, - {"BpfHdr.Hdrlen", Field, 0}, - {"BpfHdr.Pad_cgo_0", Field, 0}, - {"BpfHdr.Tstamp", Field, 0}, - {"BpfHeadercmpl", Func, 0}, - {"BpfInsn", Type, 0}, - {"BpfInsn.Code", Field, 0}, - {"BpfInsn.Jf", Field, 0}, - {"BpfInsn.Jt", Field, 0}, - {"BpfInsn.K", Field, 0}, - {"BpfInterface", Func, 0}, - {"BpfJump", Func, 0}, - {"BpfProgram", Type, 0}, - {"BpfProgram.Insns", Field, 0}, - {"BpfProgram.Len", Field, 0}, - {"BpfProgram.Pad_cgo_0", Field, 0}, - {"BpfStat", Type, 0}, - {"BpfStat.Capt", Field, 2}, - {"BpfStat.Drop", Field, 0}, - {"BpfStat.Padding", Field, 2}, - {"BpfStat.Recv", Field, 0}, - {"BpfStats", Func, 0}, - {"BpfStmt", Func, 0}, - {"BpfTimeout", Func, 0}, - {"BpfTimeval", Type, 2}, - {"BpfTimeval.Sec", Field, 2}, - {"BpfTimeval.Usec", Field, 2}, - {"BpfVersion", Type, 0}, - {"BpfVersion.Major", Field, 0}, - {"BpfVersion.Minor", Field, 0}, - {"BpfZbuf", Type, 0}, - {"BpfZbuf.Bufa", Field, 0}, - {"BpfZbuf.Bufb", Field, 0}, - {"BpfZbuf.Buflen", Field, 0}, - {"BpfZbufHeader", Type, 0}, - {"BpfZbufHeader.Kernel_gen", Field, 0}, - {"BpfZbufHeader.Kernel_len", Field, 0}, - {"BpfZbufHeader.User_gen", Field, 0}, - {"BpfZbufHeader.X_bzh_pad", Field, 0}, - {"ByHandleFileInformation", Type, 0}, - {"ByHandleFileInformation.CreationTime", Field, 0}, - {"ByHandleFileInformation.FileAttributes", Field, 0}, - {"ByHandleFileInformation.FileIndexHigh", Field, 0}, - {"ByHandleFileInformation.FileIndexLow", Field, 0}, - {"ByHandleFileInformation.FileSizeHigh", Field, 0}, - {"ByHandleFileInformation.FileSizeLow", Field, 0}, - {"ByHandleFileInformation.LastAccessTime", Field, 0}, - {"ByHandleFileInformation.LastWriteTime", Field, 0}, - {"ByHandleFileInformation.NumberOfLinks", Field, 0}, - {"ByHandleFileInformation.VolumeSerialNumber", Field, 0}, - {"BytePtrFromString", Func, 1}, - {"ByteSliceFromString", Func, 1}, - {"CCR0_FLUSH", Const, 1}, - {"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0}, - {"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0}, - {"CERT_CHAIN_POLICY_BASE", Const, 0}, - {"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0}, - {"CERT_CHAIN_POLICY_EV", Const, 0}, - {"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0}, - {"CERT_CHAIN_POLICY_NT_AUTH", Const, 0}, - {"CERT_CHAIN_POLICY_SSL", Const, 0}, - {"CERT_E_CN_NO_MATCH", Const, 0}, - {"CERT_E_EXPIRED", Const, 0}, - {"CERT_E_PURPOSE", Const, 0}, - {"CERT_E_ROLE", Const, 0}, - {"CERT_E_UNTRUSTEDROOT", Const, 0}, - {"CERT_STORE_ADD_ALWAYS", Const, 0}, - {"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0}, - {"CERT_STORE_PROV_MEMORY", Const, 0}, - {"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0}, - {"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0}, - {"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0}, - {"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0}, - {"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0}, - {"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0}, - {"CERT_TRUST_INVALID_EXTENSION", Const, 0}, - {"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0}, - {"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0}, - {"CERT_TRUST_IS_CYCLIC", Const, 0}, - {"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0}, - {"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0}, - {"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0}, - {"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0}, - {"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0}, - {"CERT_TRUST_IS_REVOKED", Const, 0}, - {"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0}, - {"CERT_TRUST_NO_ERROR", Const, 0}, - {"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0}, - {"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0}, - {"CFLUSH", Const, 1}, - {"CLOCAL", Const, 0}, - {"CLONE_CHILD_CLEARTID", Const, 2}, - {"CLONE_CHILD_SETTID", Const, 2}, - {"CLONE_CLEAR_SIGHAND", Const, 20}, - {"CLONE_CSIGNAL", Const, 3}, - {"CLONE_DETACHED", Const, 2}, - {"CLONE_FILES", Const, 2}, - {"CLONE_FS", Const, 2}, - {"CLONE_INTO_CGROUP", Const, 20}, - {"CLONE_IO", Const, 2}, - {"CLONE_NEWCGROUP", Const, 20}, - {"CLONE_NEWIPC", Const, 2}, - {"CLONE_NEWNET", Const, 2}, - {"CLONE_NEWNS", Const, 2}, - {"CLONE_NEWPID", Const, 2}, - {"CLONE_NEWTIME", Const, 20}, - {"CLONE_NEWUSER", Const, 2}, - {"CLONE_NEWUTS", Const, 2}, - {"CLONE_PARENT", Const, 2}, - {"CLONE_PARENT_SETTID", Const, 2}, - {"CLONE_PID", Const, 3}, - {"CLONE_PIDFD", Const, 20}, - {"CLONE_PTRACE", Const, 2}, - {"CLONE_SETTLS", Const, 2}, - {"CLONE_SIGHAND", Const, 2}, - {"CLONE_SYSVSEM", Const, 2}, - {"CLONE_THREAD", Const, 2}, - {"CLONE_UNTRACED", Const, 2}, - {"CLONE_VFORK", Const, 2}, - {"CLONE_VM", Const, 2}, - {"CPUID_CFLUSH", Const, 1}, - {"CREAD", Const, 0}, - {"CREATE_ALWAYS", Const, 0}, - {"CREATE_NEW", Const, 0}, - {"CREATE_NEW_PROCESS_GROUP", Const, 1}, - {"CREATE_UNICODE_ENVIRONMENT", Const, 0}, - {"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0}, - {"CRYPT_DELETEKEYSET", Const, 0}, - {"CRYPT_MACHINE_KEYSET", Const, 0}, - {"CRYPT_NEWKEYSET", Const, 0}, - {"CRYPT_SILENT", Const, 0}, - {"CRYPT_VERIFYCONTEXT", Const, 0}, - {"CS5", Const, 0}, - {"CS6", Const, 0}, - {"CS7", Const, 0}, - {"CS8", Const, 0}, - {"CSIZE", Const, 0}, - {"CSTART", Const, 1}, - {"CSTATUS", Const, 1}, - {"CSTOP", Const, 1}, - {"CSTOPB", Const, 0}, - {"CSUSP", Const, 1}, - {"CTL_MAXNAME", Const, 0}, - {"CTL_NET", Const, 0}, - {"CTL_QUERY", Const, 1}, - {"CTRL_BREAK_EVENT", Const, 1}, - {"CTRL_CLOSE_EVENT", Const, 14}, - {"CTRL_C_EVENT", Const, 1}, - {"CTRL_LOGOFF_EVENT", Const, 14}, - {"CTRL_SHUTDOWN_EVENT", Const, 14}, - {"CancelIo", Func, 0}, - {"CancelIoEx", Func, 1}, - {"CertAddCertificateContextToStore", Func, 0}, - {"CertChainContext", Type, 0}, - {"CertChainContext.ChainCount", Field, 0}, - {"CertChainContext.Chains", Field, 0}, - {"CertChainContext.HasRevocationFreshnessTime", Field, 0}, - {"CertChainContext.LowerQualityChainCount", Field, 0}, - {"CertChainContext.LowerQualityChains", Field, 0}, - {"CertChainContext.RevocationFreshnessTime", Field, 0}, - {"CertChainContext.Size", Field, 0}, - {"CertChainContext.TrustStatus", Field, 0}, - {"CertChainElement", Type, 0}, - {"CertChainElement.ApplicationUsage", Field, 0}, - {"CertChainElement.CertContext", Field, 0}, - {"CertChainElement.ExtendedErrorInfo", Field, 0}, - {"CertChainElement.IssuanceUsage", Field, 0}, - {"CertChainElement.RevocationInfo", Field, 0}, - {"CertChainElement.Size", Field, 0}, - {"CertChainElement.TrustStatus", Field, 0}, - {"CertChainPara", Type, 0}, - {"CertChainPara.CacheResync", Field, 0}, - {"CertChainPara.CheckRevocationFreshnessTime", Field, 0}, - {"CertChainPara.RequestedUsage", Field, 0}, - {"CertChainPara.RequstedIssuancePolicy", Field, 0}, - {"CertChainPara.RevocationFreshnessTime", Field, 0}, - {"CertChainPara.Size", Field, 0}, - {"CertChainPara.URLRetrievalTimeout", Field, 0}, - {"CertChainPolicyPara", Type, 0}, - {"CertChainPolicyPara.ExtraPolicyPara", Field, 0}, - {"CertChainPolicyPara.Flags", Field, 0}, - {"CertChainPolicyPara.Size", Field, 0}, - {"CertChainPolicyStatus", Type, 0}, - {"CertChainPolicyStatus.ChainIndex", Field, 0}, - {"CertChainPolicyStatus.ElementIndex", Field, 0}, - {"CertChainPolicyStatus.Error", Field, 0}, - {"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0}, - {"CertChainPolicyStatus.Size", Field, 0}, - {"CertCloseStore", Func, 0}, - {"CertContext", Type, 0}, - {"CertContext.CertInfo", Field, 0}, - {"CertContext.EncodedCert", Field, 0}, - {"CertContext.EncodingType", Field, 0}, - {"CertContext.Length", Field, 0}, - {"CertContext.Store", Field, 0}, - {"CertCreateCertificateContext", Func, 0}, - {"CertEnhKeyUsage", Type, 0}, - {"CertEnhKeyUsage.Length", Field, 0}, - {"CertEnhKeyUsage.UsageIdentifiers", Field, 0}, - {"CertEnumCertificatesInStore", Func, 0}, - {"CertFreeCertificateChain", Func, 0}, - {"CertFreeCertificateContext", Func, 0}, - {"CertGetCertificateChain", Func, 0}, - {"CertInfo", Type, 11}, - {"CertOpenStore", Func, 0}, - {"CertOpenSystemStore", Func, 0}, - {"CertRevocationCrlInfo", Type, 11}, - {"CertRevocationInfo", Type, 0}, - {"CertRevocationInfo.CrlInfo", Field, 0}, - {"CertRevocationInfo.FreshnessTime", Field, 0}, - {"CertRevocationInfo.HasFreshnessTime", Field, 0}, - {"CertRevocationInfo.OidSpecificInfo", Field, 0}, - {"CertRevocationInfo.RevocationOid", Field, 0}, - {"CertRevocationInfo.RevocationResult", Field, 0}, - {"CertRevocationInfo.Size", Field, 0}, - {"CertSimpleChain", Type, 0}, - {"CertSimpleChain.Elements", Field, 0}, - {"CertSimpleChain.HasRevocationFreshnessTime", Field, 0}, - {"CertSimpleChain.NumElements", Field, 0}, - {"CertSimpleChain.RevocationFreshnessTime", Field, 0}, - {"CertSimpleChain.Size", Field, 0}, - {"CertSimpleChain.TrustListInfo", Field, 0}, - {"CertSimpleChain.TrustStatus", Field, 0}, - {"CertTrustListInfo", Type, 11}, - {"CertTrustStatus", Type, 0}, - {"CertTrustStatus.ErrorStatus", Field, 0}, - {"CertTrustStatus.InfoStatus", Field, 0}, - {"CertUsageMatch", Type, 0}, - {"CertUsageMatch.Type", Field, 0}, - {"CertUsageMatch.Usage", Field, 0}, - {"CertVerifyCertificateChainPolicy", Func, 0}, - {"Chdir", Func, 0}, - {"CheckBpfVersion", Func, 0}, - {"Chflags", Func, 0}, - {"Chmod", Func, 0}, - {"Chown", Func, 0}, - {"Chroot", Func, 0}, - {"Clearenv", Func, 0}, - {"Close", Func, 0}, - {"CloseHandle", Func, 0}, - {"CloseOnExec", Func, 0}, - {"Closesocket", Func, 0}, - {"CmsgLen", Func, 0}, - {"CmsgSpace", Func, 0}, - {"Cmsghdr", Type, 0}, - {"Cmsghdr.Len", Field, 0}, - {"Cmsghdr.Level", Field, 0}, - {"Cmsghdr.Type", Field, 0}, - {"Cmsghdr.X__cmsg_data", Field, 0}, - {"CommandLineToArgv", Func, 0}, - {"ComputerName", Func, 0}, - {"Conn", Type, 9}, - {"Connect", Func, 0}, - {"ConnectEx", Func, 1}, - {"ConvertSidToStringSid", Func, 0}, - {"ConvertStringSidToSid", Func, 0}, - {"CopySid", Func, 0}, - {"Creat", Func, 0}, - {"CreateDirectory", Func, 0}, - {"CreateFile", Func, 0}, - {"CreateFileMapping", Func, 0}, - {"CreateHardLink", Func, 4}, - {"CreateIoCompletionPort", Func, 0}, - {"CreatePipe", Func, 0}, - {"CreateProcess", Func, 0}, - {"CreateProcessAsUser", Func, 10}, - {"CreateSymbolicLink", Func, 4}, - {"CreateToolhelp32Snapshot", Func, 4}, - {"Credential", Type, 0}, - {"Credential.Gid", Field, 0}, - {"Credential.Groups", Field, 0}, - {"Credential.NoSetGroups", Field, 9}, - {"Credential.Uid", Field, 0}, - {"CryptAcquireContext", Func, 0}, - {"CryptGenRandom", Func, 0}, - {"CryptReleaseContext", Func, 0}, - {"DIOCBSFLUSH", Const, 1}, - {"DIOCOSFPFLUSH", Const, 1}, - {"DLL", Type, 0}, - {"DLL.Handle", Field, 0}, - {"DLL.Name", Field, 0}, - {"DLLError", Type, 0}, - {"DLLError.Err", Field, 0}, - {"DLLError.Msg", Field, 0}, - {"DLLError.ObjName", Field, 0}, - {"DLT_A429", Const, 0}, - {"DLT_A653_ICM", Const, 0}, - {"DLT_AIRONET_HEADER", Const, 0}, - {"DLT_AOS", Const, 1}, - {"DLT_APPLE_IP_OVER_IEEE1394", Const, 0}, - {"DLT_ARCNET", Const, 0}, - {"DLT_ARCNET_LINUX", Const, 0}, - {"DLT_ATM_CLIP", Const, 0}, - {"DLT_ATM_RFC1483", Const, 0}, - {"DLT_AURORA", Const, 0}, - {"DLT_AX25", Const, 0}, - {"DLT_AX25_KISS", Const, 0}, - {"DLT_BACNET_MS_TP", Const, 0}, - {"DLT_BLUETOOTH_HCI_H4", Const, 0}, - {"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0}, - {"DLT_CAN20B", Const, 0}, - {"DLT_CAN_SOCKETCAN", Const, 1}, - {"DLT_CHAOS", Const, 0}, - {"DLT_CHDLC", Const, 0}, - {"DLT_CISCO_IOS", Const, 0}, - {"DLT_C_HDLC", Const, 0}, - {"DLT_C_HDLC_WITH_DIR", Const, 0}, - {"DLT_DBUS", Const, 1}, - {"DLT_DECT", Const, 1}, - {"DLT_DOCSIS", Const, 0}, - {"DLT_DVB_CI", Const, 1}, - {"DLT_ECONET", Const, 0}, - {"DLT_EN10MB", Const, 0}, - {"DLT_EN3MB", Const, 0}, - {"DLT_ENC", Const, 0}, - {"DLT_ERF", Const, 0}, - {"DLT_ERF_ETH", Const, 0}, - {"DLT_ERF_POS", Const, 0}, - {"DLT_FC_2", Const, 1}, - {"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1}, - {"DLT_FDDI", Const, 0}, - {"DLT_FLEXRAY", Const, 0}, - {"DLT_FRELAY", Const, 0}, - {"DLT_FRELAY_WITH_DIR", Const, 0}, - {"DLT_GCOM_SERIAL", Const, 0}, - {"DLT_GCOM_T1E1", Const, 0}, - {"DLT_GPF_F", Const, 0}, - {"DLT_GPF_T", Const, 0}, - {"DLT_GPRS_LLC", Const, 0}, - {"DLT_GSMTAP_ABIS", Const, 1}, - {"DLT_GSMTAP_UM", Const, 1}, - {"DLT_HDLC", Const, 1}, - {"DLT_HHDLC", Const, 0}, - {"DLT_HIPPI", Const, 1}, - {"DLT_IBM_SN", Const, 0}, - {"DLT_IBM_SP", Const, 0}, - {"DLT_IEEE802", Const, 0}, - {"DLT_IEEE802_11", Const, 0}, - {"DLT_IEEE802_11_RADIO", Const, 0}, - {"DLT_IEEE802_11_RADIO_AVS", Const, 0}, - {"DLT_IEEE802_15_4", Const, 0}, - {"DLT_IEEE802_15_4_LINUX", Const, 0}, - {"DLT_IEEE802_15_4_NOFCS", Const, 1}, - {"DLT_IEEE802_15_4_NONASK_PHY", Const, 0}, - {"DLT_IEEE802_16_MAC_CPS", Const, 0}, - {"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0}, - {"DLT_IPFILTER", Const, 0}, - {"DLT_IPMB", Const, 0}, - {"DLT_IPMB_LINUX", Const, 0}, - {"DLT_IPNET", Const, 1}, - {"DLT_IPOIB", Const, 1}, - {"DLT_IPV4", Const, 1}, - {"DLT_IPV6", Const, 1}, - {"DLT_IP_OVER_FC", Const, 0}, - {"DLT_JUNIPER_ATM1", Const, 0}, - {"DLT_JUNIPER_ATM2", Const, 0}, - {"DLT_JUNIPER_ATM_CEMIC", Const, 1}, - {"DLT_JUNIPER_CHDLC", Const, 0}, - {"DLT_JUNIPER_ES", Const, 0}, - {"DLT_JUNIPER_ETHER", Const, 0}, - {"DLT_JUNIPER_FIBRECHANNEL", Const, 1}, - {"DLT_JUNIPER_FRELAY", Const, 0}, - {"DLT_JUNIPER_GGSN", Const, 0}, - {"DLT_JUNIPER_ISM", Const, 0}, - {"DLT_JUNIPER_MFR", Const, 0}, - {"DLT_JUNIPER_MLFR", Const, 0}, - {"DLT_JUNIPER_MLPPP", Const, 0}, - {"DLT_JUNIPER_MONITOR", Const, 0}, - {"DLT_JUNIPER_PIC_PEER", Const, 0}, - {"DLT_JUNIPER_PPP", Const, 0}, - {"DLT_JUNIPER_PPPOE", Const, 0}, - {"DLT_JUNIPER_PPPOE_ATM", Const, 0}, - {"DLT_JUNIPER_SERVICES", Const, 0}, - {"DLT_JUNIPER_SRX_E2E", Const, 1}, - {"DLT_JUNIPER_ST", Const, 0}, - {"DLT_JUNIPER_VP", Const, 0}, - {"DLT_JUNIPER_VS", Const, 1}, - {"DLT_LAPB_WITH_DIR", Const, 0}, - {"DLT_LAPD", Const, 0}, - {"DLT_LIN", Const, 0}, - {"DLT_LINUX_EVDEV", Const, 1}, - {"DLT_LINUX_IRDA", Const, 0}, - {"DLT_LINUX_LAPD", Const, 0}, - {"DLT_LINUX_PPP_WITHDIRECTION", Const, 0}, - {"DLT_LINUX_SLL", Const, 0}, - {"DLT_LOOP", Const, 0}, - {"DLT_LTALK", Const, 0}, - {"DLT_MATCHING_MAX", Const, 1}, - {"DLT_MATCHING_MIN", Const, 1}, - {"DLT_MFR", Const, 0}, - {"DLT_MOST", Const, 0}, - {"DLT_MPEG_2_TS", Const, 1}, - {"DLT_MPLS", Const, 1}, - {"DLT_MTP2", Const, 0}, - {"DLT_MTP2_WITH_PHDR", Const, 0}, - {"DLT_MTP3", Const, 0}, - {"DLT_MUX27010", Const, 1}, - {"DLT_NETANALYZER", Const, 1}, - {"DLT_NETANALYZER_TRANSPARENT", Const, 1}, - {"DLT_NFC_LLCP", Const, 1}, - {"DLT_NFLOG", Const, 1}, - {"DLT_NG40", Const, 1}, - {"DLT_NULL", Const, 0}, - {"DLT_PCI_EXP", Const, 0}, - {"DLT_PFLOG", Const, 0}, - {"DLT_PFSYNC", Const, 0}, - {"DLT_PPI", Const, 0}, - {"DLT_PPP", Const, 0}, - {"DLT_PPP_BSDOS", Const, 0}, - {"DLT_PPP_ETHER", Const, 0}, - {"DLT_PPP_PPPD", Const, 0}, - {"DLT_PPP_SERIAL", Const, 0}, - {"DLT_PPP_WITH_DIR", Const, 0}, - {"DLT_PPP_WITH_DIRECTION", Const, 0}, - {"DLT_PRISM_HEADER", Const, 0}, - {"DLT_PRONET", Const, 0}, - {"DLT_RAIF1", Const, 0}, - {"DLT_RAW", Const, 0}, - {"DLT_RAWAF_MASK", Const, 1}, - {"DLT_RIO", Const, 0}, - {"DLT_SCCP", Const, 0}, - {"DLT_SITA", Const, 0}, - {"DLT_SLIP", Const, 0}, - {"DLT_SLIP_BSDOS", Const, 0}, - {"DLT_STANAG_5066_D_PDU", Const, 1}, - {"DLT_SUNATM", Const, 0}, - {"DLT_SYMANTEC_FIREWALL", Const, 0}, - {"DLT_TZSP", Const, 0}, - {"DLT_USB", Const, 0}, - {"DLT_USB_LINUX", Const, 0}, - {"DLT_USB_LINUX_MMAPPED", Const, 1}, - {"DLT_USER0", Const, 0}, - {"DLT_USER1", Const, 0}, - {"DLT_USER10", Const, 0}, - {"DLT_USER11", Const, 0}, - {"DLT_USER12", Const, 0}, - {"DLT_USER13", Const, 0}, - {"DLT_USER14", Const, 0}, - {"DLT_USER15", Const, 0}, - {"DLT_USER2", Const, 0}, - {"DLT_USER3", Const, 0}, - {"DLT_USER4", Const, 0}, - {"DLT_USER5", Const, 0}, - {"DLT_USER6", Const, 0}, - {"DLT_USER7", Const, 0}, - {"DLT_USER8", Const, 0}, - {"DLT_USER9", Const, 0}, - {"DLT_WIHART", Const, 1}, - {"DLT_X2E_SERIAL", Const, 0}, - {"DLT_X2E_XORAYA", Const, 0}, - {"DNSMXData", Type, 0}, - {"DNSMXData.NameExchange", Field, 0}, - {"DNSMXData.Pad", Field, 0}, - {"DNSMXData.Preference", Field, 0}, - {"DNSPTRData", Type, 0}, - {"DNSPTRData.Host", Field, 0}, - {"DNSRecord", Type, 0}, - {"DNSRecord.Data", Field, 0}, - {"DNSRecord.Dw", Field, 0}, - {"DNSRecord.Length", Field, 0}, - {"DNSRecord.Name", Field, 0}, - {"DNSRecord.Next", Field, 0}, - {"DNSRecord.Reserved", Field, 0}, - {"DNSRecord.Ttl", Field, 0}, - {"DNSRecord.Type", Field, 0}, - {"DNSSRVData", Type, 0}, - {"DNSSRVData.Pad", Field, 0}, - {"DNSSRVData.Port", Field, 0}, - {"DNSSRVData.Priority", Field, 0}, - {"DNSSRVData.Target", Field, 0}, - {"DNSSRVData.Weight", Field, 0}, - {"DNSTXTData", Type, 0}, - {"DNSTXTData.StringArray", Field, 0}, - {"DNSTXTData.StringCount", Field, 0}, - {"DNS_INFO_NO_RECORDS", Const, 4}, - {"DNS_TYPE_A", Const, 0}, - {"DNS_TYPE_A6", Const, 0}, - {"DNS_TYPE_AAAA", Const, 0}, - {"DNS_TYPE_ADDRS", Const, 0}, - {"DNS_TYPE_AFSDB", Const, 0}, - {"DNS_TYPE_ALL", Const, 0}, - {"DNS_TYPE_ANY", Const, 0}, - {"DNS_TYPE_ATMA", Const, 0}, - {"DNS_TYPE_AXFR", Const, 0}, - {"DNS_TYPE_CERT", Const, 0}, - {"DNS_TYPE_CNAME", Const, 0}, - {"DNS_TYPE_DHCID", Const, 0}, - {"DNS_TYPE_DNAME", Const, 0}, - {"DNS_TYPE_DNSKEY", Const, 0}, - {"DNS_TYPE_DS", Const, 0}, - {"DNS_TYPE_EID", Const, 0}, - {"DNS_TYPE_GID", Const, 0}, - {"DNS_TYPE_GPOS", Const, 0}, - {"DNS_TYPE_HINFO", Const, 0}, - {"DNS_TYPE_ISDN", Const, 0}, - {"DNS_TYPE_IXFR", Const, 0}, - {"DNS_TYPE_KEY", Const, 0}, - {"DNS_TYPE_KX", Const, 0}, - {"DNS_TYPE_LOC", Const, 0}, - {"DNS_TYPE_MAILA", Const, 0}, - {"DNS_TYPE_MAILB", Const, 0}, - {"DNS_TYPE_MB", Const, 0}, - {"DNS_TYPE_MD", Const, 0}, - {"DNS_TYPE_MF", Const, 0}, - {"DNS_TYPE_MG", Const, 0}, - {"DNS_TYPE_MINFO", Const, 0}, - {"DNS_TYPE_MR", Const, 0}, - {"DNS_TYPE_MX", Const, 0}, - {"DNS_TYPE_NAPTR", Const, 0}, - {"DNS_TYPE_NBSTAT", Const, 0}, - {"DNS_TYPE_NIMLOC", Const, 0}, - {"DNS_TYPE_NS", Const, 0}, - {"DNS_TYPE_NSAP", Const, 0}, - {"DNS_TYPE_NSAPPTR", Const, 0}, - {"DNS_TYPE_NSEC", Const, 0}, - {"DNS_TYPE_NULL", Const, 0}, - {"DNS_TYPE_NXT", Const, 0}, - {"DNS_TYPE_OPT", Const, 0}, - {"DNS_TYPE_PTR", Const, 0}, - {"DNS_TYPE_PX", Const, 0}, - {"DNS_TYPE_RP", Const, 0}, - {"DNS_TYPE_RRSIG", Const, 0}, - {"DNS_TYPE_RT", Const, 0}, - {"DNS_TYPE_SIG", Const, 0}, - {"DNS_TYPE_SINK", Const, 0}, - {"DNS_TYPE_SOA", Const, 0}, - {"DNS_TYPE_SRV", Const, 0}, - {"DNS_TYPE_TEXT", Const, 0}, - {"DNS_TYPE_TKEY", Const, 0}, - {"DNS_TYPE_TSIG", Const, 0}, - {"DNS_TYPE_UID", Const, 0}, - {"DNS_TYPE_UINFO", Const, 0}, - {"DNS_TYPE_UNSPEC", Const, 0}, - {"DNS_TYPE_WINS", Const, 0}, - {"DNS_TYPE_WINSR", Const, 0}, - {"DNS_TYPE_WKS", Const, 0}, - {"DNS_TYPE_X25", Const, 0}, - {"DT_BLK", Const, 0}, - {"DT_CHR", Const, 0}, - {"DT_DIR", Const, 0}, - {"DT_FIFO", Const, 0}, - {"DT_LNK", Const, 0}, - {"DT_REG", Const, 0}, - {"DT_SOCK", Const, 0}, - {"DT_UNKNOWN", Const, 0}, - {"DT_WHT", Const, 0}, - {"DUPLICATE_CLOSE_SOURCE", Const, 0}, - {"DUPLICATE_SAME_ACCESS", Const, 0}, - {"DeleteFile", Func, 0}, - {"DetachLsf", Func, 0}, - {"DeviceIoControl", Func, 4}, - {"Dirent", Type, 0}, - {"Dirent.Fileno", Field, 0}, - {"Dirent.Ino", Field, 0}, - {"Dirent.Name", Field, 0}, - {"Dirent.Namlen", Field, 0}, - {"Dirent.Off", Field, 0}, - {"Dirent.Pad0", Field, 12}, - {"Dirent.Pad1", Field, 12}, - {"Dirent.Pad_cgo_0", Field, 0}, - {"Dirent.Reclen", Field, 0}, - {"Dirent.Seekoff", Field, 0}, - {"Dirent.Type", Field, 0}, - {"Dirent.X__d_padding", Field, 3}, - {"DnsNameCompare", Func, 4}, - {"DnsQuery", Func, 0}, - {"DnsRecordListFree", Func, 0}, - {"DnsSectionAdditional", Const, 4}, - {"DnsSectionAnswer", Const, 4}, - {"DnsSectionAuthority", Const, 4}, - {"DnsSectionQuestion", Const, 4}, - {"Dup", Func, 0}, - {"Dup2", Func, 0}, - {"Dup3", Func, 2}, - {"DuplicateHandle", Func, 0}, - {"E2BIG", Const, 0}, - {"EACCES", Const, 0}, - {"EADDRINUSE", Const, 0}, - {"EADDRNOTAVAIL", Const, 0}, - {"EADV", Const, 0}, - {"EAFNOSUPPORT", Const, 0}, - {"EAGAIN", Const, 0}, - {"EALREADY", Const, 0}, - {"EAUTH", Const, 0}, - {"EBADARCH", Const, 0}, - {"EBADE", Const, 0}, - {"EBADEXEC", Const, 0}, - {"EBADF", Const, 0}, - {"EBADFD", Const, 0}, - {"EBADMACHO", Const, 0}, - {"EBADMSG", Const, 0}, - {"EBADR", Const, 0}, - {"EBADRPC", Const, 0}, - {"EBADRQC", Const, 0}, - {"EBADSLT", Const, 0}, - {"EBFONT", Const, 0}, - {"EBUSY", Const, 0}, - {"ECANCELED", Const, 0}, - {"ECAPMODE", Const, 1}, - {"ECHILD", Const, 0}, - {"ECHO", Const, 0}, - {"ECHOCTL", Const, 0}, - {"ECHOE", Const, 0}, - {"ECHOK", Const, 0}, - {"ECHOKE", Const, 0}, - {"ECHONL", Const, 0}, - {"ECHOPRT", Const, 0}, - {"ECHRNG", Const, 0}, - {"ECOMM", Const, 0}, - {"ECONNABORTED", Const, 0}, - {"ECONNREFUSED", Const, 0}, - {"ECONNRESET", Const, 0}, - {"EDEADLK", Const, 0}, - {"EDEADLOCK", Const, 0}, - {"EDESTADDRREQ", Const, 0}, - {"EDEVERR", Const, 0}, - {"EDOM", Const, 0}, - {"EDOOFUS", Const, 0}, - {"EDOTDOT", Const, 0}, - {"EDQUOT", Const, 0}, - {"EEXIST", Const, 0}, - {"EFAULT", Const, 0}, - {"EFBIG", Const, 0}, - {"EFER_LMA", Const, 1}, - {"EFER_LME", Const, 1}, - {"EFER_NXE", Const, 1}, - {"EFER_SCE", Const, 1}, - {"EFTYPE", Const, 0}, - {"EHOSTDOWN", Const, 0}, - {"EHOSTUNREACH", Const, 0}, - {"EHWPOISON", Const, 0}, - {"EIDRM", Const, 0}, - {"EILSEQ", Const, 0}, - {"EINPROGRESS", Const, 0}, - {"EINTR", Const, 0}, - {"EINVAL", Const, 0}, - {"EIO", Const, 0}, - {"EIPSEC", Const, 1}, - {"EISCONN", Const, 0}, - {"EISDIR", Const, 0}, - {"EISNAM", Const, 0}, - {"EKEYEXPIRED", Const, 0}, - {"EKEYREJECTED", Const, 0}, - {"EKEYREVOKED", Const, 0}, - {"EL2HLT", Const, 0}, - {"EL2NSYNC", Const, 0}, - {"EL3HLT", Const, 0}, - {"EL3RST", Const, 0}, - {"ELAST", Const, 0}, - {"ELF_NGREG", Const, 0}, - {"ELF_PRARGSZ", Const, 0}, - {"ELIBACC", Const, 0}, - {"ELIBBAD", Const, 0}, - {"ELIBEXEC", Const, 0}, - {"ELIBMAX", Const, 0}, - {"ELIBSCN", Const, 0}, - {"ELNRNG", Const, 0}, - {"ELOOP", Const, 0}, - {"EMEDIUMTYPE", Const, 0}, - {"EMFILE", Const, 0}, - {"EMLINK", Const, 0}, - {"EMSGSIZE", Const, 0}, - {"EMT_TAGOVF", Const, 1}, - {"EMULTIHOP", Const, 0}, - {"EMUL_ENABLED", Const, 1}, - {"EMUL_LINUX", Const, 1}, - {"EMUL_LINUX32", Const, 1}, - {"EMUL_MAXID", Const, 1}, - {"EMUL_NATIVE", Const, 1}, - {"ENAMETOOLONG", Const, 0}, - {"ENAVAIL", Const, 0}, - {"ENDRUNDISC", Const, 1}, - {"ENEEDAUTH", Const, 0}, - {"ENETDOWN", Const, 0}, - {"ENETRESET", Const, 0}, - {"ENETUNREACH", Const, 0}, - {"ENFILE", Const, 0}, - {"ENOANO", Const, 0}, - {"ENOATTR", Const, 0}, - {"ENOBUFS", Const, 0}, - {"ENOCSI", Const, 0}, - {"ENODATA", Const, 0}, - {"ENODEV", Const, 0}, - {"ENOENT", Const, 0}, - {"ENOEXEC", Const, 0}, - {"ENOKEY", Const, 0}, - {"ENOLCK", Const, 0}, - {"ENOLINK", Const, 0}, - {"ENOMEDIUM", Const, 0}, - {"ENOMEM", Const, 0}, - {"ENOMSG", Const, 0}, - {"ENONET", Const, 0}, - {"ENOPKG", Const, 0}, - {"ENOPOLICY", Const, 0}, - {"ENOPROTOOPT", Const, 0}, - {"ENOSPC", Const, 0}, - {"ENOSR", Const, 0}, - {"ENOSTR", Const, 0}, - {"ENOSYS", Const, 0}, - {"ENOTBLK", Const, 0}, - {"ENOTCAPABLE", Const, 0}, - {"ENOTCONN", Const, 0}, - {"ENOTDIR", Const, 0}, - {"ENOTEMPTY", Const, 0}, - {"ENOTNAM", Const, 0}, - {"ENOTRECOVERABLE", Const, 0}, - {"ENOTSOCK", Const, 0}, - {"ENOTSUP", Const, 0}, - {"ENOTTY", Const, 0}, - {"ENOTUNIQ", Const, 0}, - {"ENXIO", Const, 0}, - {"EN_SW_CTL_INF", Const, 1}, - {"EN_SW_CTL_PREC", Const, 1}, - {"EN_SW_CTL_ROUND", Const, 1}, - {"EN_SW_DATACHAIN", Const, 1}, - {"EN_SW_DENORM", Const, 1}, - {"EN_SW_INVOP", Const, 1}, - {"EN_SW_OVERFLOW", Const, 1}, - {"EN_SW_PRECLOSS", Const, 1}, - {"EN_SW_UNDERFLOW", Const, 1}, - {"EN_SW_ZERODIV", Const, 1}, - {"EOPNOTSUPP", Const, 0}, - {"EOVERFLOW", Const, 0}, - {"EOWNERDEAD", Const, 0}, - {"EPERM", Const, 0}, - {"EPFNOSUPPORT", Const, 0}, - {"EPIPE", Const, 0}, - {"EPOLLERR", Const, 0}, - {"EPOLLET", Const, 0}, - {"EPOLLHUP", Const, 0}, - {"EPOLLIN", Const, 0}, - {"EPOLLMSG", Const, 0}, - {"EPOLLONESHOT", Const, 0}, - {"EPOLLOUT", Const, 0}, - {"EPOLLPRI", Const, 0}, - {"EPOLLRDBAND", Const, 0}, - {"EPOLLRDHUP", Const, 0}, - {"EPOLLRDNORM", Const, 0}, - {"EPOLLWRBAND", Const, 0}, - {"EPOLLWRNORM", Const, 0}, - {"EPOLL_CLOEXEC", Const, 0}, - {"EPOLL_CTL_ADD", Const, 0}, - {"EPOLL_CTL_DEL", Const, 0}, - {"EPOLL_CTL_MOD", Const, 0}, - {"EPOLL_NONBLOCK", Const, 0}, - {"EPROCLIM", Const, 0}, - {"EPROCUNAVAIL", Const, 0}, - {"EPROGMISMATCH", Const, 0}, - {"EPROGUNAVAIL", Const, 0}, - {"EPROTO", Const, 0}, - {"EPROTONOSUPPORT", Const, 0}, - {"EPROTOTYPE", Const, 0}, - {"EPWROFF", Const, 0}, - {"EQFULL", Const, 16}, - {"ERANGE", Const, 0}, - {"EREMCHG", Const, 0}, - {"EREMOTE", Const, 0}, - {"EREMOTEIO", Const, 0}, - {"ERESTART", Const, 0}, - {"ERFKILL", Const, 0}, - {"EROFS", Const, 0}, - {"ERPCMISMATCH", Const, 0}, - {"ERROR_ACCESS_DENIED", Const, 0}, - {"ERROR_ALREADY_EXISTS", Const, 0}, - {"ERROR_BROKEN_PIPE", Const, 0}, - {"ERROR_BUFFER_OVERFLOW", Const, 0}, - {"ERROR_DIR_NOT_EMPTY", Const, 8}, - {"ERROR_ENVVAR_NOT_FOUND", Const, 0}, - {"ERROR_FILE_EXISTS", Const, 0}, - {"ERROR_FILE_NOT_FOUND", Const, 0}, - {"ERROR_HANDLE_EOF", Const, 2}, - {"ERROR_INSUFFICIENT_BUFFER", Const, 0}, - {"ERROR_IO_PENDING", Const, 0}, - {"ERROR_MOD_NOT_FOUND", Const, 0}, - {"ERROR_MORE_DATA", Const, 3}, - {"ERROR_NETNAME_DELETED", Const, 3}, - {"ERROR_NOT_FOUND", Const, 1}, - {"ERROR_NO_MORE_FILES", Const, 0}, - {"ERROR_OPERATION_ABORTED", Const, 0}, - {"ERROR_PATH_NOT_FOUND", Const, 0}, - {"ERROR_PRIVILEGE_NOT_HELD", Const, 4}, - {"ERROR_PROC_NOT_FOUND", Const, 0}, - {"ESHLIBVERS", Const, 0}, - {"ESHUTDOWN", Const, 0}, - {"ESOCKTNOSUPPORT", Const, 0}, - {"ESPIPE", Const, 0}, - {"ESRCH", Const, 0}, - {"ESRMNT", Const, 0}, - {"ESTALE", Const, 0}, - {"ESTRPIPE", Const, 0}, - {"ETHERCAP_JUMBO_MTU", Const, 1}, - {"ETHERCAP_VLAN_HWTAGGING", Const, 1}, - {"ETHERCAP_VLAN_MTU", Const, 1}, - {"ETHERMIN", Const, 1}, - {"ETHERMTU", Const, 1}, - {"ETHERMTU_JUMBO", Const, 1}, - {"ETHERTYPE_8023", Const, 1}, - {"ETHERTYPE_AARP", Const, 1}, - {"ETHERTYPE_ACCTON", Const, 1}, - {"ETHERTYPE_AEONIC", Const, 1}, - {"ETHERTYPE_ALPHA", Const, 1}, - {"ETHERTYPE_AMBER", Const, 1}, - {"ETHERTYPE_AMOEBA", Const, 1}, - {"ETHERTYPE_AOE", Const, 1}, - {"ETHERTYPE_APOLLO", Const, 1}, - {"ETHERTYPE_APOLLODOMAIN", Const, 1}, - {"ETHERTYPE_APPLETALK", Const, 1}, - {"ETHERTYPE_APPLITEK", Const, 1}, - {"ETHERTYPE_ARGONAUT", Const, 1}, - {"ETHERTYPE_ARP", Const, 1}, - {"ETHERTYPE_AT", Const, 1}, - {"ETHERTYPE_ATALK", Const, 1}, - {"ETHERTYPE_ATOMIC", Const, 1}, - {"ETHERTYPE_ATT", Const, 1}, - {"ETHERTYPE_ATTSTANFORD", Const, 1}, - {"ETHERTYPE_AUTOPHON", Const, 1}, - {"ETHERTYPE_AXIS", Const, 1}, - {"ETHERTYPE_BCLOOP", Const, 1}, - {"ETHERTYPE_BOFL", Const, 1}, - {"ETHERTYPE_CABLETRON", Const, 1}, - {"ETHERTYPE_CHAOS", Const, 1}, - {"ETHERTYPE_COMDESIGN", Const, 1}, - {"ETHERTYPE_COMPUGRAPHIC", Const, 1}, - {"ETHERTYPE_COUNTERPOINT", Const, 1}, - {"ETHERTYPE_CRONUS", Const, 1}, - {"ETHERTYPE_CRONUSVLN", Const, 1}, - {"ETHERTYPE_DCA", Const, 1}, - {"ETHERTYPE_DDE", Const, 1}, - {"ETHERTYPE_DEBNI", Const, 1}, - {"ETHERTYPE_DECAM", Const, 1}, - {"ETHERTYPE_DECCUST", Const, 1}, - {"ETHERTYPE_DECDIAG", Const, 1}, - {"ETHERTYPE_DECDNS", Const, 1}, - {"ETHERTYPE_DECDTS", Const, 1}, - {"ETHERTYPE_DECEXPER", Const, 1}, - {"ETHERTYPE_DECLAST", Const, 1}, - {"ETHERTYPE_DECLTM", Const, 1}, - {"ETHERTYPE_DECMUMPS", Const, 1}, - {"ETHERTYPE_DECNETBIOS", Const, 1}, - {"ETHERTYPE_DELTACON", Const, 1}, - {"ETHERTYPE_DIDDLE", Const, 1}, - {"ETHERTYPE_DLOG1", Const, 1}, - {"ETHERTYPE_DLOG2", Const, 1}, - {"ETHERTYPE_DN", Const, 1}, - {"ETHERTYPE_DOGFIGHT", Const, 1}, - {"ETHERTYPE_DSMD", Const, 1}, - {"ETHERTYPE_ECMA", Const, 1}, - {"ETHERTYPE_ENCRYPT", Const, 1}, - {"ETHERTYPE_ES", Const, 1}, - {"ETHERTYPE_EXCELAN", Const, 1}, - {"ETHERTYPE_EXPERDATA", Const, 1}, - {"ETHERTYPE_FLIP", Const, 1}, - {"ETHERTYPE_FLOWCONTROL", Const, 1}, - {"ETHERTYPE_FRARP", Const, 1}, - {"ETHERTYPE_GENDYN", Const, 1}, - {"ETHERTYPE_HAYES", Const, 1}, - {"ETHERTYPE_HIPPI_FP", Const, 1}, - {"ETHERTYPE_HITACHI", Const, 1}, - {"ETHERTYPE_HP", Const, 1}, - {"ETHERTYPE_IEEEPUP", Const, 1}, - {"ETHERTYPE_IEEEPUPAT", Const, 1}, - {"ETHERTYPE_IMLBL", Const, 1}, - {"ETHERTYPE_IMLBLDIAG", Const, 1}, - {"ETHERTYPE_IP", Const, 1}, - {"ETHERTYPE_IPAS", Const, 1}, - {"ETHERTYPE_IPV6", Const, 1}, - {"ETHERTYPE_IPX", Const, 1}, - {"ETHERTYPE_IPXNEW", Const, 1}, - {"ETHERTYPE_KALPANA", Const, 1}, - {"ETHERTYPE_LANBRIDGE", Const, 1}, - {"ETHERTYPE_LANPROBE", Const, 1}, - {"ETHERTYPE_LAT", Const, 1}, - {"ETHERTYPE_LBACK", Const, 1}, - {"ETHERTYPE_LITTLE", Const, 1}, - {"ETHERTYPE_LLDP", Const, 1}, - {"ETHERTYPE_LOGICRAFT", Const, 1}, - {"ETHERTYPE_LOOPBACK", Const, 1}, - {"ETHERTYPE_MATRA", Const, 1}, - {"ETHERTYPE_MAX", Const, 1}, - {"ETHERTYPE_MERIT", Const, 1}, - {"ETHERTYPE_MICP", Const, 1}, - {"ETHERTYPE_MOPDL", Const, 1}, - {"ETHERTYPE_MOPRC", Const, 1}, - {"ETHERTYPE_MOTOROLA", Const, 1}, - {"ETHERTYPE_MPLS", Const, 1}, - {"ETHERTYPE_MPLS_MCAST", Const, 1}, - {"ETHERTYPE_MUMPS", Const, 1}, - {"ETHERTYPE_NBPCC", Const, 1}, - {"ETHERTYPE_NBPCLAIM", Const, 1}, - {"ETHERTYPE_NBPCLREQ", Const, 1}, - {"ETHERTYPE_NBPCLRSP", Const, 1}, - {"ETHERTYPE_NBPCREQ", Const, 1}, - {"ETHERTYPE_NBPCRSP", Const, 1}, - {"ETHERTYPE_NBPDG", Const, 1}, - {"ETHERTYPE_NBPDGB", Const, 1}, - {"ETHERTYPE_NBPDLTE", Const, 1}, - {"ETHERTYPE_NBPRAR", Const, 1}, - {"ETHERTYPE_NBPRAS", Const, 1}, - {"ETHERTYPE_NBPRST", Const, 1}, - {"ETHERTYPE_NBPSCD", Const, 1}, - {"ETHERTYPE_NBPVCD", Const, 1}, - {"ETHERTYPE_NBS", Const, 1}, - {"ETHERTYPE_NCD", Const, 1}, - {"ETHERTYPE_NESTAR", Const, 1}, - {"ETHERTYPE_NETBEUI", Const, 1}, - {"ETHERTYPE_NOVELL", Const, 1}, - {"ETHERTYPE_NS", Const, 1}, - {"ETHERTYPE_NSAT", Const, 1}, - {"ETHERTYPE_NSCOMPAT", Const, 1}, - {"ETHERTYPE_NTRAILER", Const, 1}, - {"ETHERTYPE_OS9", Const, 1}, - {"ETHERTYPE_OS9NET", Const, 1}, - {"ETHERTYPE_PACER", Const, 1}, - {"ETHERTYPE_PAE", Const, 1}, - {"ETHERTYPE_PCS", Const, 1}, - {"ETHERTYPE_PLANNING", Const, 1}, - {"ETHERTYPE_PPP", Const, 1}, - {"ETHERTYPE_PPPOE", Const, 1}, - {"ETHERTYPE_PPPOEDISC", Const, 1}, - {"ETHERTYPE_PRIMENTS", Const, 1}, - {"ETHERTYPE_PUP", Const, 1}, - {"ETHERTYPE_PUPAT", Const, 1}, - {"ETHERTYPE_QINQ", Const, 1}, - {"ETHERTYPE_RACAL", Const, 1}, - {"ETHERTYPE_RATIONAL", Const, 1}, - {"ETHERTYPE_RAWFR", Const, 1}, - {"ETHERTYPE_RCL", Const, 1}, - {"ETHERTYPE_RDP", Const, 1}, - {"ETHERTYPE_RETIX", Const, 1}, - {"ETHERTYPE_REVARP", Const, 1}, - {"ETHERTYPE_SCA", Const, 1}, - {"ETHERTYPE_SECTRA", Const, 1}, - {"ETHERTYPE_SECUREDATA", Const, 1}, - {"ETHERTYPE_SGITW", Const, 1}, - {"ETHERTYPE_SG_BOUNCE", Const, 1}, - {"ETHERTYPE_SG_DIAG", Const, 1}, - {"ETHERTYPE_SG_NETGAMES", Const, 1}, - {"ETHERTYPE_SG_RESV", Const, 1}, - {"ETHERTYPE_SIMNET", Const, 1}, - {"ETHERTYPE_SLOW", Const, 1}, - {"ETHERTYPE_SLOWPROTOCOLS", Const, 1}, - {"ETHERTYPE_SNA", Const, 1}, - {"ETHERTYPE_SNMP", Const, 1}, - {"ETHERTYPE_SONIX", Const, 1}, - {"ETHERTYPE_SPIDER", Const, 1}, - {"ETHERTYPE_SPRITE", Const, 1}, - {"ETHERTYPE_STP", Const, 1}, - {"ETHERTYPE_TALARIS", Const, 1}, - {"ETHERTYPE_TALARISMC", Const, 1}, - {"ETHERTYPE_TCPCOMP", Const, 1}, - {"ETHERTYPE_TCPSM", Const, 1}, - {"ETHERTYPE_TEC", Const, 1}, - {"ETHERTYPE_TIGAN", Const, 1}, - {"ETHERTYPE_TRAIL", Const, 1}, - {"ETHERTYPE_TRANSETHER", Const, 1}, - {"ETHERTYPE_TYMSHARE", Const, 1}, - {"ETHERTYPE_UBBST", Const, 1}, - {"ETHERTYPE_UBDEBUG", Const, 1}, - {"ETHERTYPE_UBDIAGLOOP", Const, 1}, - {"ETHERTYPE_UBDL", Const, 1}, - {"ETHERTYPE_UBNIU", Const, 1}, - {"ETHERTYPE_UBNMC", Const, 1}, - {"ETHERTYPE_VALID", Const, 1}, - {"ETHERTYPE_VARIAN", Const, 1}, - {"ETHERTYPE_VAXELN", Const, 1}, - {"ETHERTYPE_VEECO", Const, 1}, - {"ETHERTYPE_VEXP", Const, 1}, - {"ETHERTYPE_VGLAB", Const, 1}, - {"ETHERTYPE_VINES", Const, 1}, - {"ETHERTYPE_VINESECHO", Const, 1}, - {"ETHERTYPE_VINESLOOP", Const, 1}, - {"ETHERTYPE_VITAL", Const, 1}, - {"ETHERTYPE_VLAN", Const, 1}, - {"ETHERTYPE_VLTLMAN", Const, 1}, - {"ETHERTYPE_VPROD", Const, 1}, - {"ETHERTYPE_VURESERVED", Const, 1}, - {"ETHERTYPE_WATERLOO", Const, 1}, - {"ETHERTYPE_WELLFLEET", Const, 1}, - {"ETHERTYPE_X25", Const, 1}, - {"ETHERTYPE_X75", Const, 1}, - {"ETHERTYPE_XNSSM", Const, 1}, - {"ETHERTYPE_XTP", Const, 1}, - {"ETHER_ADDR_LEN", Const, 1}, - {"ETHER_ALIGN", Const, 1}, - {"ETHER_CRC_LEN", Const, 1}, - {"ETHER_CRC_POLY_BE", Const, 1}, - {"ETHER_CRC_POLY_LE", Const, 1}, - {"ETHER_HDR_LEN", Const, 1}, - {"ETHER_MAX_DIX_LEN", Const, 1}, - {"ETHER_MAX_LEN", Const, 1}, - {"ETHER_MAX_LEN_JUMBO", Const, 1}, - {"ETHER_MIN_LEN", Const, 1}, - {"ETHER_PPPOE_ENCAP_LEN", Const, 1}, - {"ETHER_TYPE_LEN", Const, 1}, - {"ETHER_VLAN_ENCAP_LEN", Const, 1}, - {"ETH_P_1588", Const, 0}, - {"ETH_P_8021Q", Const, 0}, - {"ETH_P_802_2", Const, 0}, - {"ETH_P_802_3", Const, 0}, - {"ETH_P_AARP", Const, 0}, - {"ETH_P_ALL", Const, 0}, - {"ETH_P_AOE", Const, 0}, - {"ETH_P_ARCNET", Const, 0}, - {"ETH_P_ARP", Const, 0}, - {"ETH_P_ATALK", Const, 0}, - {"ETH_P_ATMFATE", Const, 0}, - {"ETH_P_ATMMPOA", Const, 0}, - {"ETH_P_AX25", Const, 0}, - {"ETH_P_BPQ", Const, 0}, - {"ETH_P_CAIF", Const, 0}, - {"ETH_P_CAN", Const, 0}, - {"ETH_P_CONTROL", Const, 0}, - {"ETH_P_CUST", Const, 0}, - {"ETH_P_DDCMP", Const, 0}, - {"ETH_P_DEC", Const, 0}, - {"ETH_P_DIAG", Const, 0}, - {"ETH_P_DNA_DL", Const, 0}, - {"ETH_P_DNA_RC", Const, 0}, - {"ETH_P_DNA_RT", Const, 0}, - {"ETH_P_DSA", Const, 0}, - {"ETH_P_ECONET", Const, 0}, - {"ETH_P_EDSA", Const, 0}, - {"ETH_P_FCOE", Const, 0}, - {"ETH_P_FIP", Const, 0}, - {"ETH_P_HDLC", Const, 0}, - {"ETH_P_IEEE802154", Const, 0}, - {"ETH_P_IEEEPUP", Const, 0}, - {"ETH_P_IEEEPUPAT", Const, 0}, - {"ETH_P_IP", Const, 0}, - {"ETH_P_IPV6", Const, 0}, - {"ETH_P_IPX", Const, 0}, - {"ETH_P_IRDA", Const, 0}, - {"ETH_P_LAT", Const, 0}, - {"ETH_P_LINK_CTL", Const, 0}, - {"ETH_P_LOCALTALK", Const, 0}, - {"ETH_P_LOOP", Const, 0}, - {"ETH_P_MOBITEX", Const, 0}, - {"ETH_P_MPLS_MC", Const, 0}, - {"ETH_P_MPLS_UC", Const, 0}, - {"ETH_P_PAE", Const, 0}, - {"ETH_P_PAUSE", Const, 0}, - {"ETH_P_PHONET", Const, 0}, - {"ETH_P_PPPTALK", Const, 0}, - {"ETH_P_PPP_DISC", Const, 0}, - {"ETH_P_PPP_MP", Const, 0}, - {"ETH_P_PPP_SES", Const, 0}, - {"ETH_P_PUP", Const, 0}, - {"ETH_P_PUPAT", Const, 0}, - {"ETH_P_RARP", Const, 0}, - {"ETH_P_SCA", Const, 0}, - {"ETH_P_SLOW", Const, 0}, - {"ETH_P_SNAP", Const, 0}, - {"ETH_P_TEB", Const, 0}, - {"ETH_P_TIPC", Const, 0}, - {"ETH_P_TRAILER", Const, 0}, - {"ETH_P_TR_802_2", Const, 0}, - {"ETH_P_WAN_PPP", Const, 0}, - {"ETH_P_WCCP", Const, 0}, - {"ETH_P_X25", Const, 0}, - {"ETIME", Const, 0}, - {"ETIMEDOUT", Const, 0}, - {"ETOOMANYREFS", Const, 0}, - {"ETXTBSY", Const, 0}, - {"EUCLEAN", Const, 0}, - {"EUNATCH", Const, 0}, - {"EUSERS", Const, 0}, - {"EVFILT_AIO", Const, 0}, - {"EVFILT_FS", Const, 0}, - {"EVFILT_LIO", Const, 0}, - {"EVFILT_MACHPORT", Const, 0}, - {"EVFILT_PROC", Const, 0}, - {"EVFILT_READ", Const, 0}, - {"EVFILT_SIGNAL", Const, 0}, - {"EVFILT_SYSCOUNT", Const, 0}, - {"EVFILT_THREADMARKER", Const, 0}, - {"EVFILT_TIMER", Const, 0}, - {"EVFILT_USER", Const, 0}, - {"EVFILT_VM", Const, 0}, - {"EVFILT_VNODE", Const, 0}, - {"EVFILT_WRITE", Const, 0}, - {"EV_ADD", Const, 0}, - {"EV_CLEAR", Const, 0}, - {"EV_DELETE", Const, 0}, - {"EV_DISABLE", Const, 0}, - {"EV_DISPATCH", Const, 0}, - {"EV_DROP", Const, 3}, - {"EV_ENABLE", Const, 0}, - {"EV_EOF", Const, 0}, - {"EV_ERROR", Const, 0}, - {"EV_FLAG0", Const, 0}, - {"EV_FLAG1", Const, 0}, - {"EV_ONESHOT", Const, 0}, - {"EV_OOBAND", Const, 0}, - {"EV_POLL", Const, 0}, - {"EV_RECEIPT", Const, 0}, - {"EV_SYSFLAGS", Const, 0}, - {"EWINDOWS", Const, 0}, - {"EWOULDBLOCK", Const, 0}, - {"EXDEV", Const, 0}, - {"EXFULL", Const, 0}, - {"EXTA", Const, 0}, - {"EXTB", Const, 0}, - {"EXTPROC", Const, 0}, - {"Environ", Func, 0}, - {"EpollCreate", Func, 0}, - {"EpollCreate1", Func, 0}, - {"EpollCtl", Func, 0}, - {"EpollEvent", Type, 0}, - {"EpollEvent.Events", Field, 0}, - {"EpollEvent.Fd", Field, 0}, - {"EpollEvent.Pad", Field, 0}, - {"EpollEvent.PadFd", Field, 0}, - {"EpollWait", Func, 0}, - {"Errno", Type, 0}, - {"EscapeArg", Func, 0}, - {"Exchangedata", Func, 0}, - {"Exec", Func, 0}, - {"Exit", Func, 0}, - {"ExitProcess", Func, 0}, - {"FD_CLOEXEC", Const, 0}, - {"FD_SETSIZE", Const, 0}, - {"FILE_ACTION_ADDED", Const, 0}, - {"FILE_ACTION_MODIFIED", Const, 0}, - {"FILE_ACTION_REMOVED", Const, 0}, - {"FILE_ACTION_RENAMED_NEW_NAME", Const, 0}, - {"FILE_ACTION_RENAMED_OLD_NAME", Const, 0}, - {"FILE_APPEND_DATA", Const, 0}, - {"FILE_ATTRIBUTE_ARCHIVE", Const, 0}, - {"FILE_ATTRIBUTE_DIRECTORY", Const, 0}, - {"FILE_ATTRIBUTE_HIDDEN", Const, 0}, - {"FILE_ATTRIBUTE_NORMAL", Const, 0}, - {"FILE_ATTRIBUTE_READONLY", Const, 0}, - {"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4}, - {"FILE_ATTRIBUTE_SYSTEM", Const, 0}, - {"FILE_BEGIN", Const, 0}, - {"FILE_CURRENT", Const, 0}, - {"FILE_END", Const, 0}, - {"FILE_FLAG_BACKUP_SEMANTICS", Const, 0}, - {"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4}, - {"FILE_FLAG_OVERLAPPED", Const, 0}, - {"FILE_LIST_DIRECTORY", Const, 0}, - {"FILE_MAP_COPY", Const, 0}, - {"FILE_MAP_EXECUTE", Const, 0}, - {"FILE_MAP_READ", Const, 0}, - {"FILE_MAP_WRITE", Const, 0}, - {"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0}, - {"FILE_NOTIFY_CHANGE_CREATION", Const, 0}, - {"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0}, - {"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0}, - {"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0}, - {"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0}, - {"FILE_NOTIFY_CHANGE_SIZE", Const, 0}, - {"FILE_SHARE_DELETE", Const, 0}, - {"FILE_SHARE_READ", Const, 0}, - {"FILE_SHARE_WRITE", Const, 0}, - {"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2}, - {"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2}, - {"FILE_TYPE_CHAR", Const, 0}, - {"FILE_TYPE_DISK", Const, 0}, - {"FILE_TYPE_PIPE", Const, 0}, - {"FILE_TYPE_REMOTE", Const, 0}, - {"FILE_TYPE_UNKNOWN", Const, 0}, - {"FILE_WRITE_ATTRIBUTES", Const, 0}, - {"FLUSHO", Const, 0}, - {"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0}, - {"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0}, - {"FORMAT_MESSAGE_FROM_HMODULE", Const, 0}, - {"FORMAT_MESSAGE_FROM_STRING", Const, 0}, - {"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0}, - {"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0}, - {"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0}, - {"FSCTL_GET_REPARSE_POINT", Const, 4}, - {"F_ADDFILESIGS", Const, 0}, - {"F_ADDSIGS", Const, 0}, - {"F_ALLOCATEALL", Const, 0}, - {"F_ALLOCATECONTIG", Const, 0}, - {"F_CANCEL", Const, 0}, - {"F_CHKCLEAN", Const, 0}, - {"F_CLOSEM", Const, 1}, - {"F_DUP2FD", Const, 0}, - {"F_DUP2FD_CLOEXEC", Const, 1}, - {"F_DUPFD", Const, 0}, - {"F_DUPFD_CLOEXEC", Const, 0}, - {"F_EXLCK", Const, 0}, - {"F_FINDSIGS", Const, 16}, - {"F_FLUSH_DATA", Const, 0}, - {"F_FREEZE_FS", Const, 0}, - {"F_FSCTL", Const, 1}, - {"F_FSDIRMASK", Const, 1}, - {"F_FSIN", Const, 1}, - {"F_FSINOUT", Const, 1}, - {"F_FSOUT", Const, 1}, - {"F_FSPRIV", Const, 1}, - {"F_FSVOID", Const, 1}, - {"F_FULLFSYNC", Const, 0}, - {"F_GETCODEDIR", Const, 16}, - {"F_GETFD", Const, 0}, - {"F_GETFL", Const, 0}, - {"F_GETLEASE", Const, 0}, - {"F_GETLK", Const, 0}, - {"F_GETLK64", Const, 0}, - {"F_GETLKPID", Const, 0}, - {"F_GETNOSIGPIPE", Const, 0}, - {"F_GETOWN", Const, 0}, - {"F_GETOWN_EX", Const, 0}, - {"F_GETPATH", Const, 0}, - {"F_GETPATH_MTMINFO", Const, 0}, - {"F_GETPIPE_SZ", Const, 0}, - {"F_GETPROTECTIONCLASS", Const, 0}, - {"F_GETPROTECTIONLEVEL", Const, 16}, - {"F_GETSIG", Const, 0}, - {"F_GLOBAL_NOCACHE", Const, 0}, - {"F_LOCK", Const, 0}, - {"F_LOG2PHYS", Const, 0}, - {"F_LOG2PHYS_EXT", Const, 0}, - {"F_MARKDEPENDENCY", Const, 0}, - {"F_MAXFD", Const, 1}, - {"F_NOCACHE", Const, 0}, - {"F_NODIRECT", Const, 0}, - {"F_NOTIFY", Const, 0}, - {"F_OGETLK", Const, 0}, - {"F_OK", Const, 0}, - {"F_OSETLK", Const, 0}, - {"F_OSETLKW", Const, 0}, - {"F_PARAM_MASK", Const, 1}, - {"F_PARAM_MAX", Const, 1}, - {"F_PATHPKG_CHECK", Const, 0}, - {"F_PEOFPOSMODE", Const, 0}, - {"F_PREALLOCATE", Const, 0}, - {"F_RDADVISE", Const, 0}, - {"F_RDAHEAD", Const, 0}, - {"F_RDLCK", Const, 0}, - {"F_READAHEAD", Const, 0}, - {"F_READBOOTSTRAP", Const, 0}, - {"F_SETBACKINGSTORE", Const, 0}, - {"F_SETFD", Const, 0}, - {"F_SETFL", Const, 0}, - {"F_SETLEASE", Const, 0}, - {"F_SETLK", Const, 0}, - {"F_SETLK64", Const, 0}, - {"F_SETLKW", Const, 0}, - {"F_SETLKW64", Const, 0}, - {"F_SETLKWTIMEOUT", Const, 16}, - {"F_SETLK_REMOTE", Const, 0}, - {"F_SETNOSIGPIPE", Const, 0}, - {"F_SETOWN", Const, 0}, - {"F_SETOWN_EX", Const, 0}, - {"F_SETPIPE_SZ", Const, 0}, - {"F_SETPROTECTIONCLASS", Const, 0}, - {"F_SETSIG", Const, 0}, - {"F_SETSIZE", Const, 0}, - {"F_SHLCK", Const, 0}, - {"F_SINGLE_WRITER", Const, 16}, - {"F_TEST", Const, 0}, - {"F_THAW_FS", Const, 0}, - {"F_TLOCK", Const, 0}, - {"F_TRANSCODEKEY", Const, 16}, - {"F_ULOCK", Const, 0}, - {"F_UNLCK", Const, 0}, - {"F_UNLCKSYS", Const, 0}, - {"F_VOLPOSMODE", Const, 0}, - {"F_WRITEBOOTSTRAP", Const, 0}, - {"F_WRLCK", Const, 0}, - {"Faccessat", Func, 0}, - {"Fallocate", Func, 0}, - {"Fbootstraptransfer_t", Type, 0}, - {"Fbootstraptransfer_t.Buffer", Field, 0}, - {"Fbootstraptransfer_t.Length", Field, 0}, - {"Fbootstraptransfer_t.Offset", Field, 0}, - {"Fchdir", Func, 0}, - {"Fchflags", Func, 0}, - {"Fchmod", Func, 0}, - {"Fchmodat", Func, 0}, - {"Fchown", Func, 0}, - {"Fchownat", Func, 0}, - {"FcntlFlock", Func, 3}, - {"FdSet", Type, 0}, - {"FdSet.Bits", Field, 0}, - {"FdSet.X__fds_bits", Field, 0}, - {"Fdatasync", Func, 0}, - {"FileNotifyInformation", Type, 0}, - {"FileNotifyInformation.Action", Field, 0}, - {"FileNotifyInformation.FileName", Field, 0}, - {"FileNotifyInformation.FileNameLength", Field, 0}, - {"FileNotifyInformation.NextEntryOffset", Field, 0}, - {"Filetime", Type, 0}, - {"Filetime.HighDateTime", Field, 0}, - {"Filetime.LowDateTime", Field, 0}, - {"FindClose", Func, 0}, - {"FindFirstFile", Func, 0}, - {"FindNextFile", Func, 0}, - {"Flock", Func, 0}, - {"Flock_t", Type, 0}, - {"Flock_t.Len", Field, 0}, - {"Flock_t.Pad_cgo_0", Field, 0}, - {"Flock_t.Pad_cgo_1", Field, 3}, - {"Flock_t.Pid", Field, 0}, - {"Flock_t.Start", Field, 0}, - {"Flock_t.Sysid", Field, 0}, - {"Flock_t.Type", Field, 0}, - {"Flock_t.Whence", Field, 0}, - {"FlushBpf", Func, 0}, - {"FlushFileBuffers", Func, 0}, - {"FlushViewOfFile", Func, 0}, - {"ForkExec", Func, 0}, - {"ForkLock", Var, 0}, - {"FormatMessage", Func, 0}, - {"Fpathconf", Func, 0}, - {"FreeAddrInfoW", Func, 1}, - {"FreeEnvironmentStrings", Func, 0}, - {"FreeLibrary", Func, 0}, - {"Fsid", Type, 0}, - {"Fsid.Val", Field, 0}, - {"Fsid.X__fsid_val", Field, 2}, - {"Fsid.X__val", Field, 0}, - {"Fstat", Func, 0}, - {"Fstatat", Func, 12}, - {"Fstatfs", Func, 0}, - {"Fstore_t", Type, 0}, - {"Fstore_t.Bytesalloc", Field, 0}, - {"Fstore_t.Flags", Field, 0}, - {"Fstore_t.Length", Field, 0}, - {"Fstore_t.Offset", Field, 0}, - {"Fstore_t.Posmode", Field, 0}, - {"Fsync", Func, 0}, - {"Ftruncate", Func, 0}, - {"FullPath", Func, 4}, - {"Futimes", Func, 0}, - {"Futimesat", Func, 0}, - {"GENERIC_ALL", Const, 0}, - {"GENERIC_EXECUTE", Const, 0}, - {"GENERIC_READ", Const, 0}, - {"GENERIC_WRITE", Const, 0}, - {"GUID", Type, 1}, - {"GUID.Data1", Field, 1}, - {"GUID.Data2", Field, 1}, - {"GUID.Data3", Field, 1}, - {"GUID.Data4", Field, 1}, - {"GetAcceptExSockaddrs", Func, 0}, - {"GetAdaptersInfo", Func, 0}, - {"GetAddrInfoW", Func, 1}, - {"GetCommandLine", Func, 0}, - {"GetComputerName", Func, 0}, - {"GetConsoleMode", Func, 1}, - {"GetCurrentDirectory", Func, 0}, - {"GetCurrentProcess", Func, 0}, - {"GetEnvironmentStrings", Func, 0}, - {"GetEnvironmentVariable", Func, 0}, - {"GetExitCodeProcess", Func, 0}, - {"GetFileAttributes", Func, 0}, - {"GetFileAttributesEx", Func, 0}, - {"GetFileExInfoStandard", Const, 0}, - {"GetFileExMaxInfoLevel", Const, 0}, - {"GetFileInformationByHandle", Func, 0}, - {"GetFileType", Func, 0}, - {"GetFullPathName", Func, 0}, - {"GetHostByName", Func, 0}, - {"GetIfEntry", Func, 0}, - {"GetLastError", Func, 0}, - {"GetLengthSid", Func, 0}, - {"GetLongPathName", Func, 0}, - {"GetProcAddress", Func, 0}, - {"GetProcessTimes", Func, 0}, - {"GetProtoByName", Func, 0}, - {"GetQueuedCompletionStatus", Func, 0}, - {"GetServByName", Func, 0}, - {"GetShortPathName", Func, 0}, - {"GetStartupInfo", Func, 0}, - {"GetStdHandle", Func, 0}, - {"GetSystemTimeAsFileTime", Func, 0}, - {"GetTempPath", Func, 0}, - {"GetTimeZoneInformation", Func, 0}, - {"GetTokenInformation", Func, 0}, - {"GetUserNameEx", Func, 0}, - {"GetUserProfileDirectory", Func, 0}, - {"GetVersion", Func, 0}, - {"Getcwd", Func, 0}, - {"Getdents", Func, 0}, - {"Getdirentries", Func, 0}, - {"Getdtablesize", Func, 0}, - {"Getegid", Func, 0}, - {"Getenv", Func, 0}, - {"Geteuid", Func, 0}, - {"Getfsstat", Func, 0}, - {"Getgid", Func, 0}, - {"Getgroups", Func, 0}, - {"Getpagesize", Func, 0}, - {"Getpeername", Func, 0}, - {"Getpgid", Func, 0}, - {"Getpgrp", Func, 0}, - {"Getpid", Func, 0}, - {"Getppid", Func, 0}, - {"Getpriority", Func, 0}, - {"Getrlimit", Func, 0}, - {"Getrusage", Func, 0}, - {"Getsid", Func, 0}, - {"Getsockname", Func, 0}, - {"Getsockopt", Func, 1}, - {"GetsockoptByte", Func, 0}, - {"GetsockoptICMPv6Filter", Func, 2}, - {"GetsockoptIPMreq", Func, 0}, - {"GetsockoptIPMreqn", Func, 0}, - {"GetsockoptIPv6MTUInfo", Func, 2}, - {"GetsockoptIPv6Mreq", Func, 0}, - {"GetsockoptInet4Addr", Func, 0}, - {"GetsockoptInt", Func, 0}, - {"GetsockoptUcred", Func, 1}, - {"Gettid", Func, 0}, - {"Gettimeofday", Func, 0}, - {"Getuid", Func, 0}, - {"Getwd", Func, 0}, - {"Getxattr", Func, 1}, - {"HANDLE_FLAG_INHERIT", Const, 0}, - {"HKEY_CLASSES_ROOT", Const, 0}, - {"HKEY_CURRENT_CONFIG", Const, 0}, - {"HKEY_CURRENT_USER", Const, 0}, - {"HKEY_DYN_DATA", Const, 0}, - {"HKEY_LOCAL_MACHINE", Const, 0}, - {"HKEY_PERFORMANCE_DATA", Const, 0}, - {"HKEY_USERS", Const, 0}, - {"HUPCL", Const, 0}, - {"Handle", Type, 0}, - {"Hostent", Type, 0}, - {"Hostent.AddrList", Field, 0}, - {"Hostent.AddrType", Field, 0}, - {"Hostent.Aliases", Field, 0}, - {"Hostent.Length", Field, 0}, - {"Hostent.Name", Field, 0}, - {"ICANON", Const, 0}, - {"ICMP6_FILTER", Const, 2}, - {"ICMPV6_FILTER", Const, 2}, - {"ICMPv6Filter", Type, 2}, - {"ICMPv6Filter.Data", Field, 2}, - {"ICMPv6Filter.Filt", Field, 2}, - {"ICRNL", Const, 0}, - {"IEXTEN", Const, 0}, - {"IFAN_ARRIVAL", Const, 1}, - {"IFAN_DEPARTURE", Const, 1}, - {"IFA_ADDRESS", Const, 0}, - {"IFA_ANYCAST", Const, 0}, - {"IFA_BROADCAST", Const, 0}, - {"IFA_CACHEINFO", Const, 0}, - {"IFA_F_DADFAILED", Const, 0}, - {"IFA_F_DEPRECATED", Const, 0}, - {"IFA_F_HOMEADDRESS", Const, 0}, - {"IFA_F_NODAD", Const, 0}, - {"IFA_F_OPTIMISTIC", Const, 0}, - {"IFA_F_PERMANENT", Const, 0}, - {"IFA_F_SECONDARY", Const, 0}, - {"IFA_F_TEMPORARY", Const, 0}, - {"IFA_F_TENTATIVE", Const, 0}, - {"IFA_LABEL", Const, 0}, - {"IFA_LOCAL", Const, 0}, - {"IFA_MAX", Const, 0}, - {"IFA_MULTICAST", Const, 0}, - {"IFA_ROUTE", Const, 1}, - {"IFA_UNSPEC", Const, 0}, - {"IFF_ALLMULTI", Const, 0}, - {"IFF_ALTPHYS", Const, 0}, - {"IFF_AUTOMEDIA", Const, 0}, - {"IFF_BROADCAST", Const, 0}, - {"IFF_CANTCHANGE", Const, 0}, - {"IFF_CANTCONFIG", Const, 1}, - {"IFF_DEBUG", Const, 0}, - {"IFF_DRV_OACTIVE", Const, 0}, - {"IFF_DRV_RUNNING", Const, 0}, - {"IFF_DYING", Const, 0}, - {"IFF_DYNAMIC", Const, 0}, - {"IFF_LINK0", Const, 0}, - {"IFF_LINK1", Const, 0}, - {"IFF_LINK2", Const, 0}, - {"IFF_LOOPBACK", Const, 0}, - {"IFF_MASTER", Const, 0}, - {"IFF_MONITOR", Const, 0}, - {"IFF_MULTICAST", Const, 0}, - {"IFF_NOARP", Const, 0}, - {"IFF_NOTRAILERS", Const, 0}, - {"IFF_NO_PI", Const, 0}, - {"IFF_OACTIVE", Const, 0}, - {"IFF_ONE_QUEUE", Const, 0}, - {"IFF_POINTOPOINT", Const, 0}, - {"IFF_POINTTOPOINT", Const, 0}, - {"IFF_PORTSEL", Const, 0}, - {"IFF_PPROMISC", Const, 0}, - {"IFF_PROMISC", Const, 0}, - {"IFF_RENAMING", Const, 0}, - {"IFF_RUNNING", Const, 0}, - {"IFF_SIMPLEX", Const, 0}, - {"IFF_SLAVE", Const, 0}, - {"IFF_SMART", Const, 0}, - {"IFF_STATICARP", Const, 0}, - {"IFF_TAP", Const, 0}, - {"IFF_TUN", Const, 0}, - {"IFF_TUN_EXCL", Const, 0}, - {"IFF_UP", Const, 0}, - {"IFF_VNET_HDR", Const, 0}, - {"IFLA_ADDRESS", Const, 0}, - {"IFLA_BROADCAST", Const, 0}, - {"IFLA_COST", Const, 0}, - {"IFLA_IFALIAS", Const, 0}, - {"IFLA_IFNAME", Const, 0}, - {"IFLA_LINK", Const, 0}, - {"IFLA_LINKINFO", Const, 0}, - {"IFLA_LINKMODE", Const, 0}, - {"IFLA_MAP", Const, 0}, - {"IFLA_MASTER", Const, 0}, - {"IFLA_MAX", Const, 0}, - {"IFLA_MTU", Const, 0}, - {"IFLA_NET_NS_PID", Const, 0}, - {"IFLA_OPERSTATE", Const, 0}, - {"IFLA_PRIORITY", Const, 0}, - {"IFLA_PROTINFO", Const, 0}, - {"IFLA_QDISC", Const, 0}, - {"IFLA_STATS", Const, 0}, - {"IFLA_TXQLEN", Const, 0}, - {"IFLA_UNSPEC", Const, 0}, - {"IFLA_WEIGHT", Const, 0}, - {"IFLA_WIRELESS", Const, 0}, - {"IFNAMSIZ", Const, 0}, - {"IFT_1822", Const, 0}, - {"IFT_A12MPPSWITCH", Const, 0}, - {"IFT_AAL2", Const, 0}, - {"IFT_AAL5", Const, 0}, - {"IFT_ADSL", Const, 0}, - {"IFT_AFLANE8023", Const, 0}, - {"IFT_AFLANE8025", Const, 0}, - {"IFT_ARAP", Const, 0}, - {"IFT_ARCNET", Const, 0}, - {"IFT_ARCNETPLUS", Const, 0}, - {"IFT_ASYNC", Const, 0}, - {"IFT_ATM", Const, 0}, - {"IFT_ATMDXI", Const, 0}, - {"IFT_ATMFUNI", Const, 0}, - {"IFT_ATMIMA", Const, 0}, - {"IFT_ATMLOGICAL", Const, 0}, - {"IFT_ATMRADIO", Const, 0}, - {"IFT_ATMSUBINTERFACE", Const, 0}, - {"IFT_ATMVCIENDPT", Const, 0}, - {"IFT_ATMVIRTUAL", Const, 0}, - {"IFT_BGPPOLICYACCOUNTING", Const, 0}, - {"IFT_BLUETOOTH", Const, 1}, - {"IFT_BRIDGE", Const, 0}, - {"IFT_BSC", Const, 0}, - {"IFT_CARP", Const, 0}, - {"IFT_CCTEMUL", Const, 0}, - {"IFT_CELLULAR", Const, 0}, - {"IFT_CEPT", Const, 0}, - {"IFT_CES", Const, 0}, - {"IFT_CHANNEL", Const, 0}, - {"IFT_CNR", Const, 0}, - {"IFT_COFFEE", Const, 0}, - {"IFT_COMPOSITELINK", Const, 0}, - {"IFT_DCN", Const, 0}, - {"IFT_DIGITALPOWERLINE", Const, 0}, - {"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0}, - {"IFT_DLSW", Const, 0}, - {"IFT_DOCSCABLEDOWNSTREAM", Const, 0}, - {"IFT_DOCSCABLEMACLAYER", Const, 0}, - {"IFT_DOCSCABLEUPSTREAM", Const, 0}, - {"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1}, - {"IFT_DS0", Const, 0}, - {"IFT_DS0BUNDLE", Const, 0}, - {"IFT_DS1FDL", Const, 0}, - {"IFT_DS3", Const, 0}, - {"IFT_DTM", Const, 0}, - {"IFT_DUMMY", Const, 1}, - {"IFT_DVBASILN", Const, 0}, - {"IFT_DVBASIOUT", Const, 0}, - {"IFT_DVBRCCDOWNSTREAM", Const, 0}, - {"IFT_DVBRCCMACLAYER", Const, 0}, - {"IFT_DVBRCCUPSTREAM", Const, 0}, - {"IFT_ECONET", Const, 1}, - {"IFT_ENC", Const, 0}, - {"IFT_EON", Const, 0}, - {"IFT_EPLRS", Const, 0}, - {"IFT_ESCON", Const, 0}, - {"IFT_ETHER", Const, 0}, - {"IFT_FAITH", Const, 0}, - {"IFT_FAST", Const, 0}, - {"IFT_FASTETHER", Const, 0}, - {"IFT_FASTETHERFX", Const, 0}, - {"IFT_FDDI", Const, 0}, - {"IFT_FIBRECHANNEL", Const, 0}, - {"IFT_FRAMERELAYINTERCONNECT", Const, 0}, - {"IFT_FRAMERELAYMPI", Const, 0}, - {"IFT_FRDLCIENDPT", Const, 0}, - {"IFT_FRELAY", Const, 0}, - {"IFT_FRELAYDCE", Const, 0}, - {"IFT_FRF16MFRBUNDLE", Const, 0}, - {"IFT_FRFORWARD", Const, 0}, - {"IFT_G703AT2MB", Const, 0}, - {"IFT_G703AT64K", Const, 0}, - {"IFT_GIF", Const, 0}, - {"IFT_GIGABITETHERNET", Const, 0}, - {"IFT_GR303IDT", Const, 0}, - {"IFT_GR303RDT", Const, 0}, - {"IFT_H323GATEKEEPER", Const, 0}, - {"IFT_H323PROXY", Const, 0}, - {"IFT_HDH1822", Const, 0}, - {"IFT_HDLC", Const, 0}, - {"IFT_HDSL2", Const, 0}, - {"IFT_HIPERLAN2", Const, 0}, - {"IFT_HIPPI", Const, 0}, - {"IFT_HIPPIINTERFACE", Const, 0}, - {"IFT_HOSTPAD", Const, 0}, - {"IFT_HSSI", Const, 0}, - {"IFT_HY", Const, 0}, - {"IFT_IBM370PARCHAN", Const, 0}, - {"IFT_IDSL", Const, 0}, - {"IFT_IEEE1394", Const, 0}, - {"IFT_IEEE80211", Const, 0}, - {"IFT_IEEE80212", Const, 0}, - {"IFT_IEEE8023ADLAG", Const, 0}, - {"IFT_IFGSN", Const, 0}, - {"IFT_IMT", Const, 0}, - {"IFT_INFINIBAND", Const, 1}, - {"IFT_INTERLEAVE", Const, 0}, - {"IFT_IP", Const, 0}, - {"IFT_IPFORWARD", Const, 0}, - {"IFT_IPOVERATM", Const, 0}, - {"IFT_IPOVERCDLC", Const, 0}, - {"IFT_IPOVERCLAW", Const, 0}, - {"IFT_IPSWITCH", Const, 0}, - {"IFT_IPXIP", Const, 0}, - {"IFT_ISDN", Const, 0}, - {"IFT_ISDNBASIC", Const, 0}, - {"IFT_ISDNPRIMARY", Const, 0}, - {"IFT_ISDNS", Const, 0}, - {"IFT_ISDNU", Const, 0}, - {"IFT_ISO88022LLC", Const, 0}, - {"IFT_ISO88023", Const, 0}, - {"IFT_ISO88024", Const, 0}, - {"IFT_ISO88025", Const, 0}, - {"IFT_ISO88025CRFPINT", Const, 0}, - {"IFT_ISO88025DTR", Const, 0}, - {"IFT_ISO88025FIBER", Const, 0}, - {"IFT_ISO88026", Const, 0}, - {"IFT_ISUP", Const, 0}, - {"IFT_L2VLAN", Const, 0}, - {"IFT_L3IPVLAN", Const, 0}, - {"IFT_L3IPXVLAN", Const, 0}, - {"IFT_LAPB", Const, 0}, - {"IFT_LAPD", Const, 0}, - {"IFT_LAPF", Const, 0}, - {"IFT_LINEGROUP", Const, 1}, - {"IFT_LOCALTALK", Const, 0}, - {"IFT_LOOP", Const, 0}, - {"IFT_MEDIAMAILOVERIP", Const, 0}, - {"IFT_MFSIGLINK", Const, 0}, - {"IFT_MIOX25", Const, 0}, - {"IFT_MODEM", Const, 0}, - {"IFT_MPC", Const, 0}, - {"IFT_MPLS", Const, 0}, - {"IFT_MPLSTUNNEL", Const, 0}, - {"IFT_MSDSL", Const, 0}, - {"IFT_MVL", Const, 0}, - {"IFT_MYRINET", Const, 0}, - {"IFT_NFAS", Const, 0}, - {"IFT_NSIP", Const, 0}, - {"IFT_OPTICALCHANNEL", Const, 0}, - {"IFT_OPTICALTRANSPORT", Const, 0}, - {"IFT_OTHER", Const, 0}, - {"IFT_P10", Const, 0}, - {"IFT_P80", Const, 0}, - {"IFT_PARA", Const, 0}, - {"IFT_PDP", Const, 0}, - {"IFT_PFLOG", Const, 0}, - {"IFT_PFLOW", Const, 1}, - {"IFT_PFSYNC", Const, 0}, - {"IFT_PLC", Const, 0}, - {"IFT_PON155", Const, 1}, - {"IFT_PON622", Const, 1}, - {"IFT_POS", Const, 0}, - {"IFT_PPP", Const, 0}, - {"IFT_PPPMULTILINKBUNDLE", Const, 0}, - {"IFT_PROPATM", Const, 1}, - {"IFT_PROPBWAP2MP", Const, 0}, - {"IFT_PROPCNLS", Const, 0}, - {"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0}, - {"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0}, - {"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0}, - {"IFT_PROPMUX", Const, 0}, - {"IFT_PROPVIRTUAL", Const, 0}, - {"IFT_PROPWIRELESSP2P", Const, 0}, - {"IFT_PTPSERIAL", Const, 0}, - {"IFT_PVC", Const, 0}, - {"IFT_Q2931", Const, 1}, - {"IFT_QLLC", Const, 0}, - {"IFT_RADIOMAC", Const, 0}, - {"IFT_RADSL", Const, 0}, - {"IFT_REACHDSL", Const, 0}, - {"IFT_RFC1483", Const, 0}, - {"IFT_RS232", Const, 0}, - {"IFT_RSRB", Const, 0}, - {"IFT_SDLC", Const, 0}, - {"IFT_SDSL", Const, 0}, - {"IFT_SHDSL", Const, 0}, - {"IFT_SIP", Const, 0}, - {"IFT_SIPSIG", Const, 1}, - {"IFT_SIPTG", Const, 1}, - {"IFT_SLIP", Const, 0}, - {"IFT_SMDSDXI", Const, 0}, - {"IFT_SMDSICIP", Const, 0}, - {"IFT_SONET", Const, 0}, - {"IFT_SONETOVERHEADCHANNEL", Const, 0}, - {"IFT_SONETPATH", Const, 0}, - {"IFT_SONETVT", Const, 0}, - {"IFT_SRP", Const, 0}, - {"IFT_SS7SIGLINK", Const, 0}, - {"IFT_STACKTOSTACK", Const, 0}, - {"IFT_STARLAN", Const, 0}, - {"IFT_STF", Const, 0}, - {"IFT_T1", Const, 0}, - {"IFT_TDLC", Const, 0}, - {"IFT_TELINK", Const, 1}, - {"IFT_TERMPAD", Const, 0}, - {"IFT_TR008", Const, 0}, - {"IFT_TRANSPHDLC", Const, 0}, - {"IFT_TUNNEL", Const, 0}, - {"IFT_ULTRA", Const, 0}, - {"IFT_USB", Const, 0}, - {"IFT_V11", Const, 0}, - {"IFT_V35", Const, 0}, - {"IFT_V36", Const, 0}, - {"IFT_V37", Const, 0}, - {"IFT_VDSL", Const, 0}, - {"IFT_VIRTUALIPADDRESS", Const, 0}, - {"IFT_VIRTUALTG", Const, 1}, - {"IFT_VOICEDID", Const, 1}, - {"IFT_VOICEEM", Const, 0}, - {"IFT_VOICEEMFGD", Const, 1}, - {"IFT_VOICEENCAP", Const, 0}, - {"IFT_VOICEFGDEANA", Const, 1}, - {"IFT_VOICEFXO", Const, 0}, - {"IFT_VOICEFXS", Const, 0}, - {"IFT_VOICEOVERATM", Const, 0}, - {"IFT_VOICEOVERCABLE", Const, 1}, - {"IFT_VOICEOVERFRAMERELAY", Const, 0}, - {"IFT_VOICEOVERIP", Const, 0}, - {"IFT_X213", Const, 0}, - {"IFT_X25", Const, 0}, - {"IFT_X25DDN", Const, 0}, - {"IFT_X25HUNTGROUP", Const, 0}, - {"IFT_X25MLP", Const, 0}, - {"IFT_X25PLE", Const, 0}, - {"IFT_XETHER", Const, 0}, - {"IGNBRK", Const, 0}, - {"IGNCR", Const, 0}, - {"IGNORE", Const, 0}, - {"IGNPAR", Const, 0}, - {"IMAXBEL", Const, 0}, - {"INFINITE", Const, 0}, - {"INLCR", Const, 0}, - {"INPCK", Const, 0}, - {"INVALID_FILE_ATTRIBUTES", Const, 0}, - {"IN_ACCESS", Const, 0}, - {"IN_ALL_EVENTS", Const, 0}, - {"IN_ATTRIB", Const, 0}, - {"IN_CLASSA_HOST", Const, 0}, - {"IN_CLASSA_MAX", Const, 0}, - {"IN_CLASSA_NET", Const, 0}, - {"IN_CLASSA_NSHIFT", Const, 0}, - {"IN_CLASSB_HOST", Const, 0}, - {"IN_CLASSB_MAX", Const, 0}, - {"IN_CLASSB_NET", Const, 0}, - {"IN_CLASSB_NSHIFT", Const, 0}, - {"IN_CLASSC_HOST", Const, 0}, - {"IN_CLASSC_NET", Const, 0}, - {"IN_CLASSC_NSHIFT", Const, 0}, - {"IN_CLASSD_HOST", Const, 0}, - {"IN_CLASSD_NET", Const, 0}, - {"IN_CLASSD_NSHIFT", Const, 0}, - {"IN_CLOEXEC", Const, 0}, - {"IN_CLOSE", Const, 0}, - {"IN_CLOSE_NOWRITE", Const, 0}, - {"IN_CLOSE_WRITE", Const, 0}, - {"IN_CREATE", Const, 0}, - {"IN_DELETE", Const, 0}, - {"IN_DELETE_SELF", Const, 0}, - {"IN_DONT_FOLLOW", Const, 0}, - {"IN_EXCL_UNLINK", Const, 0}, - {"IN_IGNORED", Const, 0}, - {"IN_ISDIR", Const, 0}, - {"IN_LINKLOCALNETNUM", Const, 0}, - {"IN_LOOPBACKNET", Const, 0}, - {"IN_MASK_ADD", Const, 0}, - {"IN_MODIFY", Const, 0}, - {"IN_MOVE", Const, 0}, - {"IN_MOVED_FROM", Const, 0}, - {"IN_MOVED_TO", Const, 0}, - {"IN_MOVE_SELF", Const, 0}, - {"IN_NONBLOCK", Const, 0}, - {"IN_ONESHOT", Const, 0}, - {"IN_ONLYDIR", Const, 0}, - {"IN_OPEN", Const, 0}, - {"IN_Q_OVERFLOW", Const, 0}, - {"IN_RFC3021_HOST", Const, 1}, - {"IN_RFC3021_MASK", Const, 1}, - {"IN_RFC3021_NET", Const, 1}, - {"IN_RFC3021_NSHIFT", Const, 1}, - {"IN_UNMOUNT", Const, 0}, - {"IOC_IN", Const, 1}, - {"IOC_INOUT", Const, 1}, - {"IOC_OUT", Const, 1}, - {"IOC_VENDOR", Const, 3}, - {"IOC_WS2", Const, 1}, - {"IO_REPARSE_TAG_SYMLINK", Const, 4}, - {"IPMreq", Type, 0}, - {"IPMreq.Interface", Field, 0}, - {"IPMreq.Multiaddr", Field, 0}, - {"IPMreqn", Type, 0}, - {"IPMreqn.Address", Field, 0}, - {"IPMreqn.Ifindex", Field, 0}, - {"IPMreqn.Multiaddr", Field, 0}, - {"IPPROTO_3PC", Const, 0}, - {"IPPROTO_ADFS", Const, 0}, - {"IPPROTO_AH", Const, 0}, - {"IPPROTO_AHIP", Const, 0}, - {"IPPROTO_APES", Const, 0}, - {"IPPROTO_ARGUS", Const, 0}, - {"IPPROTO_AX25", Const, 0}, - {"IPPROTO_BHA", Const, 0}, - {"IPPROTO_BLT", Const, 0}, - {"IPPROTO_BRSATMON", Const, 0}, - {"IPPROTO_CARP", Const, 0}, - {"IPPROTO_CFTP", Const, 0}, - {"IPPROTO_CHAOS", Const, 0}, - {"IPPROTO_CMTP", Const, 0}, - {"IPPROTO_COMP", Const, 0}, - {"IPPROTO_CPHB", Const, 0}, - {"IPPROTO_CPNX", Const, 0}, - {"IPPROTO_DCCP", Const, 0}, - {"IPPROTO_DDP", Const, 0}, - {"IPPROTO_DGP", Const, 0}, - {"IPPROTO_DIVERT", Const, 0}, - {"IPPROTO_DIVERT_INIT", Const, 3}, - {"IPPROTO_DIVERT_RESP", Const, 3}, - {"IPPROTO_DONE", Const, 0}, - {"IPPROTO_DSTOPTS", Const, 0}, - {"IPPROTO_EGP", Const, 0}, - {"IPPROTO_EMCON", Const, 0}, - {"IPPROTO_ENCAP", Const, 0}, - {"IPPROTO_EON", Const, 0}, - {"IPPROTO_ESP", Const, 0}, - {"IPPROTO_ETHERIP", Const, 0}, - {"IPPROTO_FRAGMENT", Const, 0}, - {"IPPROTO_GGP", Const, 0}, - {"IPPROTO_GMTP", Const, 0}, - {"IPPROTO_GRE", Const, 0}, - {"IPPROTO_HELLO", Const, 0}, - {"IPPROTO_HMP", Const, 0}, - {"IPPROTO_HOPOPTS", Const, 0}, - {"IPPROTO_ICMP", Const, 0}, - {"IPPROTO_ICMPV6", Const, 0}, - {"IPPROTO_IDP", Const, 0}, - {"IPPROTO_IDPR", Const, 0}, - {"IPPROTO_IDRP", Const, 0}, - {"IPPROTO_IGMP", Const, 0}, - {"IPPROTO_IGP", Const, 0}, - {"IPPROTO_IGRP", Const, 0}, - {"IPPROTO_IL", Const, 0}, - {"IPPROTO_INLSP", Const, 0}, - {"IPPROTO_INP", Const, 0}, - {"IPPROTO_IP", Const, 0}, - {"IPPROTO_IPCOMP", Const, 0}, - {"IPPROTO_IPCV", Const, 0}, - {"IPPROTO_IPEIP", Const, 0}, - {"IPPROTO_IPIP", Const, 0}, - {"IPPROTO_IPPC", Const, 0}, - {"IPPROTO_IPV4", Const, 0}, - {"IPPROTO_IPV6", Const, 0}, - {"IPPROTO_IPV6_ICMP", Const, 1}, - {"IPPROTO_IRTP", Const, 0}, - {"IPPROTO_KRYPTOLAN", Const, 0}, - {"IPPROTO_LARP", Const, 0}, - {"IPPROTO_LEAF1", Const, 0}, - {"IPPROTO_LEAF2", Const, 0}, - {"IPPROTO_MAX", Const, 0}, - {"IPPROTO_MAXID", Const, 0}, - {"IPPROTO_MEAS", Const, 0}, - {"IPPROTO_MH", Const, 1}, - {"IPPROTO_MHRP", Const, 0}, - {"IPPROTO_MICP", Const, 0}, - {"IPPROTO_MOBILE", Const, 0}, - {"IPPROTO_MPLS", Const, 1}, - {"IPPROTO_MTP", Const, 0}, - {"IPPROTO_MUX", Const, 0}, - {"IPPROTO_ND", Const, 0}, - {"IPPROTO_NHRP", Const, 0}, - {"IPPROTO_NONE", Const, 0}, - {"IPPROTO_NSP", Const, 0}, - {"IPPROTO_NVPII", Const, 0}, - {"IPPROTO_OLD_DIVERT", Const, 0}, - {"IPPROTO_OSPFIGP", Const, 0}, - {"IPPROTO_PFSYNC", Const, 0}, - {"IPPROTO_PGM", Const, 0}, - {"IPPROTO_PIGP", Const, 0}, - {"IPPROTO_PIM", Const, 0}, - {"IPPROTO_PRM", Const, 0}, - {"IPPROTO_PUP", Const, 0}, - {"IPPROTO_PVP", Const, 0}, - {"IPPROTO_RAW", Const, 0}, - {"IPPROTO_RCCMON", Const, 0}, - {"IPPROTO_RDP", Const, 0}, - {"IPPROTO_ROUTING", Const, 0}, - {"IPPROTO_RSVP", Const, 0}, - {"IPPROTO_RVD", Const, 0}, - {"IPPROTO_SATEXPAK", Const, 0}, - {"IPPROTO_SATMON", Const, 0}, - {"IPPROTO_SCCSP", Const, 0}, - {"IPPROTO_SCTP", Const, 0}, - {"IPPROTO_SDRP", Const, 0}, - {"IPPROTO_SEND", Const, 1}, - {"IPPROTO_SEP", Const, 0}, - {"IPPROTO_SKIP", Const, 0}, - {"IPPROTO_SPACER", Const, 0}, - {"IPPROTO_SRPC", Const, 0}, - {"IPPROTO_ST", Const, 0}, - {"IPPROTO_SVMTP", Const, 0}, - {"IPPROTO_SWIPE", Const, 0}, - {"IPPROTO_TCF", Const, 0}, - {"IPPROTO_TCP", Const, 0}, - {"IPPROTO_TLSP", Const, 0}, - {"IPPROTO_TP", Const, 0}, - {"IPPROTO_TPXX", Const, 0}, - {"IPPROTO_TRUNK1", Const, 0}, - {"IPPROTO_TRUNK2", Const, 0}, - {"IPPROTO_TTP", Const, 0}, - {"IPPROTO_UDP", Const, 0}, - {"IPPROTO_UDPLITE", Const, 0}, - {"IPPROTO_VINES", Const, 0}, - {"IPPROTO_VISA", Const, 0}, - {"IPPROTO_VMTP", Const, 0}, - {"IPPROTO_VRRP", Const, 1}, - {"IPPROTO_WBEXPAK", Const, 0}, - {"IPPROTO_WBMON", Const, 0}, - {"IPPROTO_WSN", Const, 0}, - {"IPPROTO_XNET", Const, 0}, - {"IPPROTO_XTP", Const, 0}, - {"IPV6_2292DSTOPTS", Const, 0}, - {"IPV6_2292HOPLIMIT", Const, 0}, - {"IPV6_2292HOPOPTS", Const, 0}, - {"IPV6_2292NEXTHOP", Const, 0}, - {"IPV6_2292PKTINFO", Const, 0}, - {"IPV6_2292PKTOPTIONS", Const, 0}, - {"IPV6_2292RTHDR", Const, 0}, - {"IPV6_ADDRFORM", Const, 0}, - {"IPV6_ADD_MEMBERSHIP", Const, 0}, - {"IPV6_AUTHHDR", Const, 0}, - {"IPV6_AUTH_LEVEL", Const, 1}, - {"IPV6_AUTOFLOWLABEL", Const, 0}, - {"IPV6_BINDANY", Const, 0}, - {"IPV6_BINDV6ONLY", Const, 0}, - {"IPV6_BOUND_IF", Const, 0}, - {"IPV6_CHECKSUM", Const, 0}, - {"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0}, - {"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0}, - {"IPV6_DEFHLIM", Const, 0}, - {"IPV6_DONTFRAG", Const, 0}, - {"IPV6_DROP_MEMBERSHIP", Const, 0}, - {"IPV6_DSTOPTS", Const, 0}, - {"IPV6_ESP_NETWORK_LEVEL", Const, 1}, - {"IPV6_ESP_TRANS_LEVEL", Const, 1}, - {"IPV6_FAITH", Const, 0}, - {"IPV6_FLOWINFO_MASK", Const, 0}, - {"IPV6_FLOWLABEL_MASK", Const, 0}, - {"IPV6_FRAGTTL", Const, 0}, - {"IPV6_FW_ADD", Const, 0}, - {"IPV6_FW_DEL", Const, 0}, - {"IPV6_FW_FLUSH", Const, 0}, - {"IPV6_FW_GET", Const, 0}, - {"IPV6_FW_ZERO", Const, 0}, - {"IPV6_HLIMDEC", Const, 0}, - {"IPV6_HOPLIMIT", Const, 0}, - {"IPV6_HOPOPTS", Const, 0}, - {"IPV6_IPCOMP_LEVEL", Const, 1}, - {"IPV6_IPSEC_POLICY", Const, 0}, - {"IPV6_JOIN_ANYCAST", Const, 0}, - {"IPV6_JOIN_GROUP", Const, 0}, - {"IPV6_LEAVE_ANYCAST", Const, 0}, - {"IPV6_LEAVE_GROUP", Const, 0}, - {"IPV6_MAXHLIM", Const, 0}, - {"IPV6_MAXOPTHDR", Const, 0}, - {"IPV6_MAXPACKET", Const, 0}, - {"IPV6_MAX_GROUP_SRC_FILTER", Const, 0}, - {"IPV6_MAX_MEMBERSHIPS", Const, 0}, - {"IPV6_MAX_SOCK_SRC_FILTER", Const, 0}, - {"IPV6_MIN_MEMBERSHIPS", Const, 0}, - {"IPV6_MMTU", Const, 0}, - {"IPV6_MSFILTER", Const, 0}, - {"IPV6_MTU", Const, 0}, - {"IPV6_MTU_DISCOVER", Const, 0}, - {"IPV6_MULTICAST_HOPS", Const, 0}, - {"IPV6_MULTICAST_IF", Const, 0}, - {"IPV6_MULTICAST_LOOP", Const, 0}, - {"IPV6_NEXTHOP", Const, 0}, - {"IPV6_OPTIONS", Const, 1}, - {"IPV6_PATHMTU", Const, 0}, - {"IPV6_PIPEX", Const, 1}, - {"IPV6_PKTINFO", Const, 0}, - {"IPV6_PMTUDISC_DO", Const, 0}, - {"IPV6_PMTUDISC_DONT", Const, 0}, - {"IPV6_PMTUDISC_PROBE", Const, 0}, - {"IPV6_PMTUDISC_WANT", Const, 0}, - {"IPV6_PORTRANGE", Const, 0}, - {"IPV6_PORTRANGE_DEFAULT", Const, 0}, - {"IPV6_PORTRANGE_HIGH", Const, 0}, - {"IPV6_PORTRANGE_LOW", Const, 0}, - {"IPV6_PREFER_TEMPADDR", Const, 0}, - {"IPV6_RECVDSTOPTS", Const, 0}, - {"IPV6_RECVDSTPORT", Const, 3}, - {"IPV6_RECVERR", Const, 0}, - {"IPV6_RECVHOPLIMIT", Const, 0}, - {"IPV6_RECVHOPOPTS", Const, 0}, - {"IPV6_RECVPATHMTU", Const, 0}, - {"IPV6_RECVPKTINFO", Const, 0}, - {"IPV6_RECVRTHDR", Const, 0}, - {"IPV6_RECVTCLASS", Const, 0}, - {"IPV6_ROUTER_ALERT", Const, 0}, - {"IPV6_RTABLE", Const, 1}, - {"IPV6_RTHDR", Const, 0}, - {"IPV6_RTHDRDSTOPTS", Const, 0}, - {"IPV6_RTHDR_LOOSE", Const, 0}, - {"IPV6_RTHDR_STRICT", Const, 0}, - {"IPV6_RTHDR_TYPE_0", Const, 0}, - {"IPV6_RXDSTOPTS", Const, 0}, - {"IPV6_RXHOPOPTS", Const, 0}, - {"IPV6_SOCKOPT_RESERVED1", Const, 0}, - {"IPV6_TCLASS", Const, 0}, - {"IPV6_UNICAST_HOPS", Const, 0}, - {"IPV6_USE_MIN_MTU", Const, 0}, - {"IPV6_V6ONLY", Const, 0}, - {"IPV6_VERSION", Const, 0}, - {"IPV6_VERSION_MASK", Const, 0}, - {"IPV6_XFRM_POLICY", Const, 0}, - {"IP_ADD_MEMBERSHIP", Const, 0}, - {"IP_ADD_SOURCE_MEMBERSHIP", Const, 0}, - {"IP_AUTH_LEVEL", Const, 1}, - {"IP_BINDANY", Const, 0}, - {"IP_BLOCK_SOURCE", Const, 0}, - {"IP_BOUND_IF", Const, 0}, - {"IP_DEFAULT_MULTICAST_LOOP", Const, 0}, - {"IP_DEFAULT_MULTICAST_TTL", Const, 0}, - {"IP_DF", Const, 0}, - {"IP_DIVERTFL", Const, 3}, - {"IP_DONTFRAG", Const, 0}, - {"IP_DROP_MEMBERSHIP", Const, 0}, - {"IP_DROP_SOURCE_MEMBERSHIP", Const, 0}, - {"IP_DUMMYNET3", Const, 0}, - {"IP_DUMMYNET_CONFIGURE", Const, 0}, - {"IP_DUMMYNET_DEL", Const, 0}, - {"IP_DUMMYNET_FLUSH", Const, 0}, - {"IP_DUMMYNET_GET", Const, 0}, - {"IP_EF", Const, 1}, - {"IP_ERRORMTU", Const, 1}, - {"IP_ESP_NETWORK_LEVEL", Const, 1}, - {"IP_ESP_TRANS_LEVEL", Const, 1}, - {"IP_FAITH", Const, 0}, - {"IP_FREEBIND", Const, 0}, - {"IP_FW3", Const, 0}, - {"IP_FW_ADD", Const, 0}, - {"IP_FW_DEL", Const, 0}, - {"IP_FW_FLUSH", Const, 0}, - {"IP_FW_GET", Const, 0}, - {"IP_FW_NAT_CFG", Const, 0}, - {"IP_FW_NAT_DEL", Const, 0}, - {"IP_FW_NAT_GET_CONFIG", Const, 0}, - {"IP_FW_NAT_GET_LOG", Const, 0}, - {"IP_FW_RESETLOG", Const, 0}, - {"IP_FW_TABLE_ADD", Const, 0}, - {"IP_FW_TABLE_DEL", Const, 0}, - {"IP_FW_TABLE_FLUSH", Const, 0}, - {"IP_FW_TABLE_GETSIZE", Const, 0}, - {"IP_FW_TABLE_LIST", Const, 0}, - {"IP_FW_ZERO", Const, 0}, - {"IP_HDRINCL", Const, 0}, - {"IP_IPCOMP_LEVEL", Const, 1}, - {"IP_IPSECFLOWINFO", Const, 1}, - {"IP_IPSEC_LOCAL_AUTH", Const, 1}, - {"IP_IPSEC_LOCAL_CRED", Const, 1}, - {"IP_IPSEC_LOCAL_ID", Const, 1}, - {"IP_IPSEC_POLICY", Const, 0}, - {"IP_IPSEC_REMOTE_AUTH", Const, 1}, - {"IP_IPSEC_REMOTE_CRED", Const, 1}, - {"IP_IPSEC_REMOTE_ID", Const, 1}, - {"IP_MAXPACKET", Const, 0}, - {"IP_MAX_GROUP_SRC_FILTER", Const, 0}, - {"IP_MAX_MEMBERSHIPS", Const, 0}, - {"IP_MAX_SOCK_MUTE_FILTER", Const, 0}, - {"IP_MAX_SOCK_SRC_FILTER", Const, 0}, - {"IP_MAX_SOURCE_FILTER", Const, 0}, - {"IP_MF", Const, 0}, - {"IP_MINFRAGSIZE", Const, 1}, - {"IP_MINTTL", Const, 0}, - {"IP_MIN_MEMBERSHIPS", Const, 0}, - {"IP_MSFILTER", Const, 0}, - {"IP_MSS", Const, 0}, - {"IP_MTU", Const, 0}, - {"IP_MTU_DISCOVER", Const, 0}, - {"IP_MULTICAST_IF", Const, 0}, - {"IP_MULTICAST_IFINDEX", Const, 0}, - {"IP_MULTICAST_LOOP", Const, 0}, - {"IP_MULTICAST_TTL", Const, 0}, - {"IP_MULTICAST_VIF", Const, 0}, - {"IP_NAT__XXX", Const, 0}, - {"IP_OFFMASK", Const, 0}, - {"IP_OLD_FW_ADD", Const, 0}, - {"IP_OLD_FW_DEL", Const, 0}, - {"IP_OLD_FW_FLUSH", Const, 0}, - {"IP_OLD_FW_GET", Const, 0}, - {"IP_OLD_FW_RESETLOG", Const, 0}, - {"IP_OLD_FW_ZERO", Const, 0}, - {"IP_ONESBCAST", Const, 0}, - {"IP_OPTIONS", Const, 0}, - {"IP_ORIGDSTADDR", Const, 0}, - {"IP_PASSSEC", Const, 0}, - {"IP_PIPEX", Const, 1}, - {"IP_PKTINFO", Const, 0}, - {"IP_PKTOPTIONS", Const, 0}, - {"IP_PMTUDISC", Const, 0}, - {"IP_PMTUDISC_DO", Const, 0}, - {"IP_PMTUDISC_DONT", Const, 0}, - {"IP_PMTUDISC_PROBE", Const, 0}, - {"IP_PMTUDISC_WANT", Const, 0}, - {"IP_PORTRANGE", Const, 0}, - {"IP_PORTRANGE_DEFAULT", Const, 0}, - {"IP_PORTRANGE_HIGH", Const, 0}, - {"IP_PORTRANGE_LOW", Const, 0}, - {"IP_RECVDSTADDR", Const, 0}, - {"IP_RECVDSTPORT", Const, 1}, - {"IP_RECVERR", Const, 0}, - {"IP_RECVIF", Const, 0}, - {"IP_RECVOPTS", Const, 0}, - {"IP_RECVORIGDSTADDR", Const, 0}, - {"IP_RECVPKTINFO", Const, 0}, - {"IP_RECVRETOPTS", Const, 0}, - {"IP_RECVRTABLE", Const, 1}, - {"IP_RECVTOS", Const, 0}, - {"IP_RECVTTL", Const, 0}, - {"IP_RETOPTS", Const, 0}, - {"IP_RF", Const, 0}, - {"IP_ROUTER_ALERT", Const, 0}, - {"IP_RSVP_OFF", Const, 0}, - {"IP_RSVP_ON", Const, 0}, - {"IP_RSVP_VIF_OFF", Const, 0}, - {"IP_RSVP_VIF_ON", Const, 0}, - {"IP_RTABLE", Const, 1}, - {"IP_SENDSRCADDR", Const, 0}, - {"IP_STRIPHDR", Const, 0}, - {"IP_TOS", Const, 0}, - {"IP_TRAFFIC_MGT_BACKGROUND", Const, 0}, - {"IP_TRANSPARENT", Const, 0}, - {"IP_TTL", Const, 0}, - {"IP_UNBLOCK_SOURCE", Const, 0}, - {"IP_XFRM_POLICY", Const, 0}, - {"IPv6MTUInfo", Type, 2}, - {"IPv6MTUInfo.Addr", Field, 2}, - {"IPv6MTUInfo.Mtu", Field, 2}, - {"IPv6Mreq", Type, 0}, - {"IPv6Mreq.Interface", Field, 0}, - {"IPv6Mreq.Multiaddr", Field, 0}, - {"ISIG", Const, 0}, - {"ISTRIP", Const, 0}, - {"IUCLC", Const, 0}, - {"IUTF8", Const, 0}, - {"IXANY", Const, 0}, - {"IXOFF", Const, 0}, - {"IXON", Const, 0}, - {"IfAddrmsg", Type, 0}, - {"IfAddrmsg.Family", Field, 0}, - {"IfAddrmsg.Flags", Field, 0}, - {"IfAddrmsg.Index", Field, 0}, - {"IfAddrmsg.Prefixlen", Field, 0}, - {"IfAddrmsg.Scope", Field, 0}, - {"IfAnnounceMsghdr", Type, 1}, - {"IfAnnounceMsghdr.Hdrlen", Field, 2}, - {"IfAnnounceMsghdr.Index", Field, 1}, - {"IfAnnounceMsghdr.Msglen", Field, 1}, - {"IfAnnounceMsghdr.Name", Field, 1}, - {"IfAnnounceMsghdr.Type", Field, 1}, - {"IfAnnounceMsghdr.Version", Field, 1}, - {"IfAnnounceMsghdr.What", Field, 1}, - {"IfData", Type, 0}, - {"IfData.Addrlen", Field, 0}, - {"IfData.Baudrate", Field, 0}, - {"IfData.Capabilities", Field, 2}, - {"IfData.Collisions", Field, 0}, - {"IfData.Datalen", Field, 0}, - {"IfData.Epoch", Field, 0}, - {"IfData.Hdrlen", Field, 0}, - {"IfData.Hwassist", Field, 0}, - {"IfData.Ibytes", Field, 0}, - {"IfData.Ierrors", Field, 0}, - {"IfData.Imcasts", Field, 0}, - {"IfData.Ipackets", Field, 0}, - {"IfData.Iqdrops", Field, 0}, - {"IfData.Lastchange", Field, 0}, - {"IfData.Link_state", Field, 0}, - {"IfData.Mclpool", Field, 2}, - {"IfData.Metric", Field, 0}, - {"IfData.Mtu", Field, 0}, - {"IfData.Noproto", Field, 0}, - {"IfData.Obytes", Field, 0}, - {"IfData.Oerrors", Field, 0}, - {"IfData.Omcasts", Field, 0}, - {"IfData.Opackets", Field, 0}, - {"IfData.Pad", Field, 2}, - {"IfData.Pad_cgo_0", Field, 2}, - {"IfData.Pad_cgo_1", Field, 2}, - {"IfData.Physical", Field, 0}, - {"IfData.Recvquota", Field, 0}, - {"IfData.Recvtiming", Field, 0}, - {"IfData.Reserved1", Field, 0}, - {"IfData.Reserved2", Field, 0}, - {"IfData.Spare_char1", Field, 0}, - {"IfData.Spare_char2", Field, 0}, - {"IfData.Type", Field, 0}, - {"IfData.Typelen", Field, 0}, - {"IfData.Unused1", Field, 0}, - {"IfData.Unused2", Field, 0}, - {"IfData.Xmitquota", Field, 0}, - {"IfData.Xmittiming", Field, 0}, - {"IfInfomsg", Type, 0}, - {"IfInfomsg.Change", Field, 0}, - {"IfInfomsg.Family", Field, 0}, - {"IfInfomsg.Flags", Field, 0}, - {"IfInfomsg.Index", Field, 0}, - {"IfInfomsg.Type", Field, 0}, - {"IfInfomsg.X__ifi_pad", Field, 0}, - {"IfMsghdr", Type, 0}, - {"IfMsghdr.Addrs", Field, 0}, - {"IfMsghdr.Data", Field, 0}, - {"IfMsghdr.Flags", Field, 0}, - {"IfMsghdr.Hdrlen", Field, 2}, - {"IfMsghdr.Index", Field, 0}, - {"IfMsghdr.Msglen", Field, 0}, - {"IfMsghdr.Pad1", Field, 2}, - {"IfMsghdr.Pad2", Field, 2}, - {"IfMsghdr.Pad_cgo_0", Field, 0}, - {"IfMsghdr.Pad_cgo_1", Field, 2}, - {"IfMsghdr.Tableid", Field, 2}, - {"IfMsghdr.Type", Field, 0}, - {"IfMsghdr.Version", Field, 0}, - {"IfMsghdr.Xflags", Field, 2}, - {"IfaMsghdr", Type, 0}, - {"IfaMsghdr.Addrs", Field, 0}, - {"IfaMsghdr.Flags", Field, 0}, - {"IfaMsghdr.Hdrlen", Field, 2}, - {"IfaMsghdr.Index", Field, 0}, - {"IfaMsghdr.Metric", Field, 0}, - {"IfaMsghdr.Msglen", Field, 0}, - {"IfaMsghdr.Pad1", Field, 2}, - {"IfaMsghdr.Pad2", Field, 2}, - {"IfaMsghdr.Pad_cgo_0", Field, 0}, - {"IfaMsghdr.Tableid", Field, 2}, - {"IfaMsghdr.Type", Field, 0}, - {"IfaMsghdr.Version", Field, 0}, - {"IfmaMsghdr", Type, 0}, - {"IfmaMsghdr.Addrs", Field, 0}, - {"IfmaMsghdr.Flags", Field, 0}, - {"IfmaMsghdr.Index", Field, 0}, - {"IfmaMsghdr.Msglen", Field, 0}, - {"IfmaMsghdr.Pad_cgo_0", Field, 0}, - {"IfmaMsghdr.Type", Field, 0}, - {"IfmaMsghdr.Version", Field, 0}, - {"IfmaMsghdr2", Type, 0}, - {"IfmaMsghdr2.Addrs", Field, 0}, - {"IfmaMsghdr2.Flags", Field, 0}, - {"IfmaMsghdr2.Index", Field, 0}, - {"IfmaMsghdr2.Msglen", Field, 0}, - {"IfmaMsghdr2.Pad_cgo_0", Field, 0}, - {"IfmaMsghdr2.Refcount", Field, 0}, - {"IfmaMsghdr2.Type", Field, 0}, - {"IfmaMsghdr2.Version", Field, 0}, - {"ImplementsGetwd", Const, 0}, - {"Inet4Pktinfo", Type, 0}, - {"Inet4Pktinfo.Addr", Field, 0}, - {"Inet4Pktinfo.Ifindex", Field, 0}, - {"Inet4Pktinfo.Spec_dst", Field, 0}, - {"Inet6Pktinfo", Type, 0}, - {"Inet6Pktinfo.Addr", Field, 0}, - {"Inet6Pktinfo.Ifindex", Field, 0}, - {"InotifyAddWatch", Func, 0}, - {"InotifyEvent", Type, 0}, - {"InotifyEvent.Cookie", Field, 0}, - {"InotifyEvent.Len", Field, 0}, - {"InotifyEvent.Mask", Field, 0}, - {"InotifyEvent.Name", Field, 0}, - {"InotifyEvent.Wd", Field, 0}, - {"InotifyInit", Func, 0}, - {"InotifyInit1", Func, 0}, - {"InotifyRmWatch", Func, 0}, - {"InterfaceAddrMessage", Type, 0}, - {"InterfaceAddrMessage.Data", Field, 0}, - {"InterfaceAddrMessage.Header", Field, 0}, - {"InterfaceAnnounceMessage", Type, 1}, - {"InterfaceAnnounceMessage.Header", Field, 1}, - {"InterfaceInfo", Type, 0}, - {"InterfaceInfo.Address", Field, 0}, - {"InterfaceInfo.BroadcastAddress", Field, 0}, - {"InterfaceInfo.Flags", Field, 0}, - {"InterfaceInfo.Netmask", Field, 0}, - {"InterfaceMessage", Type, 0}, - {"InterfaceMessage.Data", Field, 0}, - {"InterfaceMessage.Header", Field, 0}, - {"InterfaceMulticastAddrMessage", Type, 0}, - {"InterfaceMulticastAddrMessage.Data", Field, 0}, - {"InterfaceMulticastAddrMessage.Header", Field, 0}, - {"InvalidHandle", Const, 0}, - {"Ioperm", Func, 0}, - {"Iopl", Func, 0}, - {"Iovec", Type, 0}, - {"Iovec.Base", Field, 0}, - {"Iovec.Len", Field, 0}, - {"IpAdapterInfo", Type, 0}, - {"IpAdapterInfo.AdapterName", Field, 0}, - {"IpAdapterInfo.Address", Field, 0}, - {"IpAdapterInfo.AddressLength", Field, 0}, - {"IpAdapterInfo.ComboIndex", Field, 0}, - {"IpAdapterInfo.CurrentIpAddress", Field, 0}, - {"IpAdapterInfo.Description", Field, 0}, - {"IpAdapterInfo.DhcpEnabled", Field, 0}, - {"IpAdapterInfo.DhcpServer", Field, 0}, - {"IpAdapterInfo.GatewayList", Field, 0}, - {"IpAdapterInfo.HaveWins", Field, 0}, - {"IpAdapterInfo.Index", Field, 0}, - {"IpAdapterInfo.IpAddressList", Field, 0}, - {"IpAdapterInfo.LeaseExpires", Field, 0}, - {"IpAdapterInfo.LeaseObtained", Field, 0}, - {"IpAdapterInfo.Next", Field, 0}, - {"IpAdapterInfo.PrimaryWinsServer", Field, 0}, - {"IpAdapterInfo.SecondaryWinsServer", Field, 0}, - {"IpAdapterInfo.Type", Field, 0}, - {"IpAddrString", Type, 0}, - {"IpAddrString.Context", Field, 0}, - {"IpAddrString.IpAddress", Field, 0}, - {"IpAddrString.IpMask", Field, 0}, - {"IpAddrString.Next", Field, 0}, - {"IpAddressString", Type, 0}, - {"IpAddressString.String", Field, 0}, - {"IpMaskString", Type, 0}, - {"IpMaskString.String", Field, 2}, - {"Issetugid", Func, 0}, - {"KEY_ALL_ACCESS", Const, 0}, - {"KEY_CREATE_LINK", Const, 0}, - {"KEY_CREATE_SUB_KEY", Const, 0}, - {"KEY_ENUMERATE_SUB_KEYS", Const, 0}, - {"KEY_EXECUTE", Const, 0}, - {"KEY_NOTIFY", Const, 0}, - {"KEY_QUERY_VALUE", Const, 0}, - {"KEY_READ", Const, 0}, - {"KEY_SET_VALUE", Const, 0}, - {"KEY_WOW64_32KEY", Const, 0}, - {"KEY_WOW64_64KEY", Const, 0}, - {"KEY_WRITE", Const, 0}, - {"Kevent", Func, 0}, - {"Kevent_t", Type, 0}, - {"Kevent_t.Data", Field, 0}, - {"Kevent_t.Fflags", Field, 0}, - {"Kevent_t.Filter", Field, 0}, - {"Kevent_t.Flags", Field, 0}, - {"Kevent_t.Ident", Field, 0}, - {"Kevent_t.Pad_cgo_0", Field, 2}, - {"Kevent_t.Udata", Field, 0}, - {"Kill", Func, 0}, - {"Klogctl", Func, 0}, - {"Kqueue", Func, 0}, - {"LANG_ENGLISH", Const, 0}, - {"LAYERED_PROTOCOL", Const, 2}, - {"LCNT_OVERLOAD_FLUSH", Const, 1}, - {"LINUX_REBOOT_CMD_CAD_OFF", Const, 0}, - {"LINUX_REBOOT_CMD_CAD_ON", Const, 0}, - {"LINUX_REBOOT_CMD_HALT", Const, 0}, - {"LINUX_REBOOT_CMD_KEXEC", Const, 0}, - {"LINUX_REBOOT_CMD_POWER_OFF", Const, 0}, - {"LINUX_REBOOT_CMD_RESTART", Const, 0}, - {"LINUX_REBOOT_CMD_RESTART2", Const, 0}, - {"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0}, - {"LINUX_REBOOT_MAGIC1", Const, 0}, - {"LINUX_REBOOT_MAGIC2", Const, 0}, - {"LOCK_EX", Const, 0}, - {"LOCK_NB", Const, 0}, - {"LOCK_SH", Const, 0}, - {"LOCK_UN", Const, 0}, - {"LazyDLL", Type, 0}, - {"LazyDLL.Name", Field, 0}, - {"LazyProc", Type, 0}, - {"LazyProc.Name", Field, 0}, - {"Lchown", Func, 0}, - {"Linger", Type, 0}, - {"Linger.Linger", Field, 0}, - {"Linger.Onoff", Field, 0}, - {"Link", Func, 0}, - {"Listen", Func, 0}, - {"Listxattr", Func, 1}, - {"LoadCancelIoEx", Func, 1}, - {"LoadConnectEx", Func, 1}, - {"LoadCreateSymbolicLink", Func, 4}, - {"LoadDLL", Func, 0}, - {"LoadGetAddrInfo", Func, 1}, - {"LoadLibrary", Func, 0}, - {"LoadSetFileCompletionNotificationModes", Func, 2}, - {"LocalFree", Func, 0}, - {"Log2phys_t", Type, 0}, - {"Log2phys_t.Contigbytes", Field, 0}, - {"Log2phys_t.Devoffset", Field, 0}, - {"Log2phys_t.Flags", Field, 0}, - {"LookupAccountName", Func, 0}, - {"LookupAccountSid", Func, 0}, - {"LookupSID", Func, 0}, - {"LsfJump", Func, 0}, - {"LsfSocket", Func, 0}, - {"LsfStmt", Func, 0}, - {"Lstat", Func, 0}, - {"MADV_AUTOSYNC", Const, 1}, - {"MADV_CAN_REUSE", Const, 0}, - {"MADV_CORE", Const, 1}, - {"MADV_DOFORK", Const, 0}, - {"MADV_DONTFORK", Const, 0}, - {"MADV_DONTNEED", Const, 0}, - {"MADV_FREE", Const, 0}, - {"MADV_FREE_REUSABLE", Const, 0}, - {"MADV_FREE_REUSE", Const, 0}, - {"MADV_HUGEPAGE", Const, 0}, - {"MADV_HWPOISON", Const, 0}, - {"MADV_MERGEABLE", Const, 0}, - {"MADV_NOCORE", Const, 1}, - {"MADV_NOHUGEPAGE", Const, 0}, - {"MADV_NORMAL", Const, 0}, - {"MADV_NOSYNC", Const, 1}, - {"MADV_PROTECT", Const, 1}, - {"MADV_RANDOM", Const, 0}, - {"MADV_REMOVE", Const, 0}, - {"MADV_SEQUENTIAL", Const, 0}, - {"MADV_SPACEAVAIL", Const, 3}, - {"MADV_UNMERGEABLE", Const, 0}, - {"MADV_WILLNEED", Const, 0}, - {"MADV_ZERO_WIRED_PAGES", Const, 0}, - {"MAP_32BIT", Const, 0}, - {"MAP_ALIGNED_SUPER", Const, 3}, - {"MAP_ALIGNMENT_16MB", Const, 3}, - {"MAP_ALIGNMENT_1TB", Const, 3}, - {"MAP_ALIGNMENT_256TB", Const, 3}, - {"MAP_ALIGNMENT_4GB", Const, 3}, - {"MAP_ALIGNMENT_64KB", Const, 3}, - {"MAP_ALIGNMENT_64PB", Const, 3}, - {"MAP_ALIGNMENT_MASK", Const, 3}, - {"MAP_ALIGNMENT_SHIFT", Const, 3}, - {"MAP_ANON", Const, 0}, - {"MAP_ANONYMOUS", Const, 0}, - {"MAP_COPY", Const, 0}, - {"MAP_DENYWRITE", Const, 0}, - {"MAP_EXECUTABLE", Const, 0}, - {"MAP_FILE", Const, 0}, - {"MAP_FIXED", Const, 0}, - {"MAP_FLAGMASK", Const, 3}, - {"MAP_GROWSDOWN", Const, 0}, - {"MAP_HASSEMAPHORE", Const, 0}, - {"MAP_HUGETLB", Const, 0}, - {"MAP_INHERIT", Const, 3}, - {"MAP_INHERIT_COPY", Const, 3}, - {"MAP_INHERIT_DEFAULT", Const, 3}, - {"MAP_INHERIT_DONATE_COPY", Const, 3}, - {"MAP_INHERIT_NONE", Const, 3}, - {"MAP_INHERIT_SHARE", Const, 3}, - {"MAP_JIT", Const, 0}, - {"MAP_LOCKED", Const, 0}, - {"MAP_NOCACHE", Const, 0}, - {"MAP_NOCORE", Const, 1}, - {"MAP_NOEXTEND", Const, 0}, - {"MAP_NONBLOCK", Const, 0}, - {"MAP_NORESERVE", Const, 0}, - {"MAP_NOSYNC", Const, 1}, - {"MAP_POPULATE", Const, 0}, - {"MAP_PREFAULT_READ", Const, 1}, - {"MAP_PRIVATE", Const, 0}, - {"MAP_RENAME", Const, 0}, - {"MAP_RESERVED0080", Const, 0}, - {"MAP_RESERVED0100", Const, 1}, - {"MAP_SHARED", Const, 0}, - {"MAP_STACK", Const, 0}, - {"MAP_TRYFIXED", Const, 3}, - {"MAP_TYPE", Const, 0}, - {"MAP_WIRED", Const, 3}, - {"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4}, - {"MAXLEN_IFDESCR", Const, 0}, - {"MAXLEN_PHYSADDR", Const, 0}, - {"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0}, - {"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0}, - {"MAX_ADAPTER_NAME_LENGTH", Const, 0}, - {"MAX_COMPUTERNAME_LENGTH", Const, 0}, - {"MAX_INTERFACE_NAME_LEN", Const, 0}, - {"MAX_LONG_PATH", Const, 0}, - {"MAX_PATH", Const, 0}, - {"MAX_PROTOCOL_CHAIN", Const, 2}, - {"MCL_CURRENT", Const, 0}, - {"MCL_FUTURE", Const, 0}, - {"MNT_DETACH", Const, 0}, - {"MNT_EXPIRE", Const, 0}, - {"MNT_FORCE", Const, 0}, - {"MSG_BCAST", Const, 1}, - {"MSG_CMSG_CLOEXEC", Const, 0}, - {"MSG_COMPAT", Const, 0}, - {"MSG_CONFIRM", Const, 0}, - {"MSG_CONTROLMBUF", Const, 1}, - {"MSG_CTRUNC", Const, 0}, - {"MSG_DONTROUTE", Const, 0}, - {"MSG_DONTWAIT", Const, 0}, - {"MSG_EOF", Const, 0}, - {"MSG_EOR", Const, 0}, - {"MSG_ERRQUEUE", Const, 0}, - {"MSG_FASTOPEN", Const, 1}, - {"MSG_FIN", Const, 0}, - {"MSG_FLUSH", Const, 0}, - {"MSG_HAVEMORE", Const, 0}, - {"MSG_HOLD", Const, 0}, - {"MSG_IOVUSRSPACE", Const, 1}, - {"MSG_LENUSRSPACE", Const, 1}, - {"MSG_MCAST", Const, 1}, - {"MSG_MORE", Const, 0}, - {"MSG_NAMEMBUF", Const, 1}, - {"MSG_NBIO", Const, 0}, - {"MSG_NEEDSA", Const, 0}, - {"MSG_NOSIGNAL", Const, 0}, - {"MSG_NOTIFICATION", Const, 0}, - {"MSG_OOB", Const, 0}, - {"MSG_PEEK", Const, 0}, - {"MSG_PROXY", Const, 0}, - {"MSG_RCVMORE", Const, 0}, - {"MSG_RST", Const, 0}, - {"MSG_SEND", Const, 0}, - {"MSG_SYN", Const, 0}, - {"MSG_TRUNC", Const, 0}, - {"MSG_TRYHARD", Const, 0}, - {"MSG_USERFLAGS", Const, 1}, - {"MSG_WAITALL", Const, 0}, - {"MSG_WAITFORONE", Const, 0}, - {"MSG_WAITSTREAM", Const, 0}, - {"MS_ACTIVE", Const, 0}, - {"MS_ASYNC", Const, 0}, - {"MS_BIND", Const, 0}, - {"MS_DEACTIVATE", Const, 0}, - {"MS_DIRSYNC", Const, 0}, - {"MS_INVALIDATE", Const, 0}, - {"MS_I_VERSION", Const, 0}, - {"MS_KERNMOUNT", Const, 0}, - {"MS_KILLPAGES", Const, 0}, - {"MS_MANDLOCK", Const, 0}, - {"MS_MGC_MSK", Const, 0}, - {"MS_MGC_VAL", Const, 0}, - {"MS_MOVE", Const, 0}, - {"MS_NOATIME", Const, 0}, - {"MS_NODEV", Const, 0}, - {"MS_NODIRATIME", Const, 0}, - {"MS_NOEXEC", Const, 0}, - {"MS_NOSUID", Const, 0}, - {"MS_NOUSER", Const, 0}, - {"MS_POSIXACL", Const, 0}, - {"MS_PRIVATE", Const, 0}, - {"MS_RDONLY", Const, 0}, - {"MS_REC", Const, 0}, - {"MS_RELATIME", Const, 0}, - {"MS_REMOUNT", Const, 0}, - {"MS_RMT_MASK", Const, 0}, - {"MS_SHARED", Const, 0}, - {"MS_SILENT", Const, 0}, - {"MS_SLAVE", Const, 0}, - {"MS_STRICTATIME", Const, 0}, - {"MS_SYNC", Const, 0}, - {"MS_SYNCHRONOUS", Const, 0}, - {"MS_UNBINDABLE", Const, 0}, - {"Madvise", Func, 0}, - {"MapViewOfFile", Func, 0}, - {"MaxTokenInfoClass", Const, 0}, - {"Mclpool", Type, 2}, - {"Mclpool.Alive", Field, 2}, - {"Mclpool.Cwm", Field, 2}, - {"Mclpool.Grown", Field, 2}, - {"Mclpool.Hwm", Field, 2}, - {"Mclpool.Lwm", Field, 2}, - {"MibIfRow", Type, 0}, - {"MibIfRow.AdminStatus", Field, 0}, - {"MibIfRow.Descr", Field, 0}, - {"MibIfRow.DescrLen", Field, 0}, - {"MibIfRow.InDiscards", Field, 0}, - {"MibIfRow.InErrors", Field, 0}, - {"MibIfRow.InNUcastPkts", Field, 0}, - {"MibIfRow.InOctets", Field, 0}, - {"MibIfRow.InUcastPkts", Field, 0}, - {"MibIfRow.InUnknownProtos", Field, 0}, - {"MibIfRow.Index", Field, 0}, - {"MibIfRow.LastChange", Field, 0}, - {"MibIfRow.Mtu", Field, 0}, - {"MibIfRow.Name", Field, 0}, - {"MibIfRow.OperStatus", Field, 0}, - {"MibIfRow.OutDiscards", Field, 0}, - {"MibIfRow.OutErrors", Field, 0}, - {"MibIfRow.OutNUcastPkts", Field, 0}, - {"MibIfRow.OutOctets", Field, 0}, - {"MibIfRow.OutQLen", Field, 0}, - {"MibIfRow.OutUcastPkts", Field, 0}, - {"MibIfRow.PhysAddr", Field, 0}, - {"MibIfRow.PhysAddrLen", Field, 0}, - {"MibIfRow.Speed", Field, 0}, - {"MibIfRow.Type", Field, 0}, - {"Mkdir", Func, 0}, - {"Mkdirat", Func, 0}, - {"Mkfifo", Func, 0}, - {"Mknod", Func, 0}, - {"Mknodat", Func, 0}, - {"Mlock", Func, 0}, - {"Mlockall", Func, 0}, - {"Mmap", Func, 0}, - {"Mount", Func, 0}, - {"MoveFile", Func, 0}, - {"Mprotect", Func, 0}, - {"Msghdr", Type, 0}, - {"Msghdr.Control", Field, 0}, - {"Msghdr.Controllen", Field, 0}, - {"Msghdr.Flags", Field, 0}, - {"Msghdr.Iov", Field, 0}, - {"Msghdr.Iovlen", Field, 0}, - {"Msghdr.Name", Field, 0}, - {"Msghdr.Namelen", Field, 0}, - {"Msghdr.Pad_cgo_0", Field, 0}, - {"Msghdr.Pad_cgo_1", Field, 0}, - {"Munlock", Func, 0}, - {"Munlockall", Func, 0}, - {"Munmap", Func, 0}, - {"MustLoadDLL", Func, 0}, - {"NAME_MAX", Const, 0}, - {"NETLINK_ADD_MEMBERSHIP", Const, 0}, - {"NETLINK_AUDIT", Const, 0}, - {"NETLINK_BROADCAST_ERROR", Const, 0}, - {"NETLINK_CONNECTOR", Const, 0}, - {"NETLINK_DNRTMSG", Const, 0}, - {"NETLINK_DROP_MEMBERSHIP", Const, 0}, - {"NETLINK_ECRYPTFS", Const, 0}, - {"NETLINK_FIB_LOOKUP", Const, 0}, - {"NETLINK_FIREWALL", Const, 0}, - {"NETLINK_GENERIC", Const, 0}, - {"NETLINK_INET_DIAG", Const, 0}, - {"NETLINK_IP6_FW", Const, 0}, - {"NETLINK_ISCSI", Const, 0}, - {"NETLINK_KOBJECT_UEVENT", Const, 0}, - {"NETLINK_NETFILTER", Const, 0}, - {"NETLINK_NFLOG", Const, 0}, - {"NETLINK_NO_ENOBUFS", Const, 0}, - {"NETLINK_PKTINFO", Const, 0}, - {"NETLINK_RDMA", Const, 0}, - {"NETLINK_ROUTE", Const, 0}, - {"NETLINK_SCSITRANSPORT", Const, 0}, - {"NETLINK_SELINUX", Const, 0}, - {"NETLINK_UNUSED", Const, 0}, - {"NETLINK_USERSOCK", Const, 0}, - {"NETLINK_XFRM", Const, 0}, - {"NET_RT_DUMP", Const, 0}, - {"NET_RT_DUMP2", Const, 0}, - {"NET_RT_FLAGS", Const, 0}, - {"NET_RT_IFLIST", Const, 0}, - {"NET_RT_IFLIST2", Const, 0}, - {"NET_RT_IFLISTL", Const, 1}, - {"NET_RT_IFMALIST", Const, 0}, - {"NET_RT_MAXID", Const, 0}, - {"NET_RT_OIFLIST", Const, 1}, - {"NET_RT_OOIFLIST", Const, 1}, - {"NET_RT_STAT", Const, 0}, - {"NET_RT_STATS", Const, 1}, - {"NET_RT_TABLE", Const, 1}, - {"NET_RT_TRASH", Const, 0}, - {"NLA_ALIGNTO", Const, 0}, - {"NLA_F_NESTED", Const, 0}, - {"NLA_F_NET_BYTEORDER", Const, 0}, - {"NLA_HDRLEN", Const, 0}, - {"NLMSG_ALIGNTO", Const, 0}, - {"NLMSG_DONE", Const, 0}, - {"NLMSG_ERROR", Const, 0}, - {"NLMSG_HDRLEN", Const, 0}, - {"NLMSG_MIN_TYPE", Const, 0}, - {"NLMSG_NOOP", Const, 0}, - {"NLMSG_OVERRUN", Const, 0}, - {"NLM_F_ACK", Const, 0}, - {"NLM_F_APPEND", Const, 0}, - {"NLM_F_ATOMIC", Const, 0}, - {"NLM_F_CREATE", Const, 0}, - {"NLM_F_DUMP", Const, 0}, - {"NLM_F_ECHO", Const, 0}, - {"NLM_F_EXCL", Const, 0}, - {"NLM_F_MATCH", Const, 0}, - {"NLM_F_MULTI", Const, 0}, - {"NLM_F_REPLACE", Const, 0}, - {"NLM_F_REQUEST", Const, 0}, - {"NLM_F_ROOT", Const, 0}, - {"NOFLSH", Const, 0}, - {"NOTE_ABSOLUTE", Const, 0}, - {"NOTE_ATTRIB", Const, 0}, - {"NOTE_BACKGROUND", Const, 16}, - {"NOTE_CHILD", Const, 0}, - {"NOTE_CRITICAL", Const, 16}, - {"NOTE_DELETE", Const, 0}, - {"NOTE_EOF", Const, 1}, - {"NOTE_EXEC", Const, 0}, - {"NOTE_EXIT", Const, 0}, - {"NOTE_EXITSTATUS", Const, 0}, - {"NOTE_EXIT_CSERROR", Const, 16}, - {"NOTE_EXIT_DECRYPTFAIL", Const, 16}, - {"NOTE_EXIT_DETAIL", Const, 16}, - {"NOTE_EXIT_DETAIL_MASK", Const, 16}, - {"NOTE_EXIT_MEMORY", Const, 16}, - {"NOTE_EXIT_REPARENTED", Const, 16}, - {"NOTE_EXTEND", Const, 0}, - {"NOTE_FFAND", Const, 0}, - {"NOTE_FFCOPY", Const, 0}, - {"NOTE_FFCTRLMASK", Const, 0}, - {"NOTE_FFLAGSMASK", Const, 0}, - {"NOTE_FFNOP", Const, 0}, - {"NOTE_FFOR", Const, 0}, - {"NOTE_FORK", Const, 0}, - {"NOTE_LEEWAY", Const, 16}, - {"NOTE_LINK", Const, 0}, - {"NOTE_LOWAT", Const, 0}, - {"NOTE_NONE", Const, 0}, - {"NOTE_NSECONDS", Const, 0}, - {"NOTE_PCTRLMASK", Const, 0}, - {"NOTE_PDATAMASK", Const, 0}, - {"NOTE_REAP", Const, 0}, - {"NOTE_RENAME", Const, 0}, - {"NOTE_RESOURCEEND", Const, 0}, - {"NOTE_REVOKE", Const, 0}, - {"NOTE_SECONDS", Const, 0}, - {"NOTE_SIGNAL", Const, 0}, - {"NOTE_TRACK", Const, 0}, - {"NOTE_TRACKERR", Const, 0}, - {"NOTE_TRIGGER", Const, 0}, - {"NOTE_TRUNCATE", Const, 1}, - {"NOTE_USECONDS", Const, 0}, - {"NOTE_VM_ERROR", Const, 0}, - {"NOTE_VM_PRESSURE", Const, 0}, - {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0}, - {"NOTE_VM_PRESSURE_TERMINATE", Const, 0}, - {"NOTE_WRITE", Const, 0}, - {"NameCanonical", Const, 0}, - {"NameCanonicalEx", Const, 0}, - {"NameDisplay", Const, 0}, - {"NameDnsDomain", Const, 0}, - {"NameFullyQualifiedDN", Const, 0}, - {"NameSamCompatible", Const, 0}, - {"NameServicePrincipal", Const, 0}, - {"NameUniqueId", Const, 0}, - {"NameUnknown", Const, 0}, - {"NameUserPrincipal", Const, 0}, - {"Nanosleep", Func, 0}, - {"NetApiBufferFree", Func, 0}, - {"NetGetJoinInformation", Func, 2}, - {"NetSetupDomainName", Const, 2}, - {"NetSetupUnjoined", Const, 2}, - {"NetSetupUnknownStatus", Const, 2}, - {"NetSetupWorkgroupName", Const, 2}, - {"NetUserGetInfo", Func, 0}, - {"NetlinkMessage", Type, 0}, - {"NetlinkMessage.Data", Field, 0}, - {"NetlinkMessage.Header", Field, 0}, - {"NetlinkRIB", Func, 0}, - {"NetlinkRouteAttr", Type, 0}, - {"NetlinkRouteAttr.Attr", Field, 0}, - {"NetlinkRouteAttr.Value", Field, 0}, - {"NetlinkRouteRequest", Type, 0}, - {"NetlinkRouteRequest.Data", Field, 0}, - {"NetlinkRouteRequest.Header", Field, 0}, - {"NewCallback", Func, 0}, - {"NewCallbackCDecl", Func, 3}, - {"NewLazyDLL", Func, 0}, - {"NlAttr", Type, 0}, - {"NlAttr.Len", Field, 0}, - {"NlAttr.Type", Field, 0}, - {"NlMsgerr", Type, 0}, - {"NlMsgerr.Error", Field, 0}, - {"NlMsgerr.Msg", Field, 0}, - {"NlMsghdr", Type, 0}, - {"NlMsghdr.Flags", Field, 0}, - {"NlMsghdr.Len", Field, 0}, - {"NlMsghdr.Pid", Field, 0}, - {"NlMsghdr.Seq", Field, 0}, - {"NlMsghdr.Type", Field, 0}, - {"NsecToFiletime", Func, 0}, - {"NsecToTimespec", Func, 0}, - {"NsecToTimeval", Func, 0}, - {"Ntohs", Func, 0}, - {"OCRNL", Const, 0}, - {"OFDEL", Const, 0}, - {"OFILL", Const, 0}, - {"OFIOGETBMAP", Const, 1}, - {"OID_PKIX_KP_SERVER_AUTH", Var, 0}, - {"OID_SERVER_GATED_CRYPTO", Var, 0}, - {"OID_SGC_NETSCAPE", Var, 0}, - {"OLCUC", Const, 0}, - {"ONLCR", Const, 0}, - {"ONLRET", Const, 0}, - {"ONOCR", Const, 0}, - {"ONOEOT", Const, 1}, - {"OPEN_ALWAYS", Const, 0}, - {"OPEN_EXISTING", Const, 0}, - {"OPOST", Const, 0}, - {"O_ACCMODE", Const, 0}, - {"O_ALERT", Const, 0}, - {"O_ALT_IO", Const, 1}, - {"O_APPEND", Const, 0}, - {"O_ASYNC", Const, 0}, - {"O_CLOEXEC", Const, 0}, - {"O_CREAT", Const, 0}, - {"O_DIRECT", Const, 0}, - {"O_DIRECTORY", Const, 0}, - {"O_DP_GETRAWENCRYPTED", Const, 16}, - {"O_DSYNC", Const, 0}, - {"O_EVTONLY", Const, 0}, - {"O_EXCL", Const, 0}, - {"O_EXEC", Const, 0}, - {"O_EXLOCK", Const, 0}, - {"O_FSYNC", Const, 0}, - {"O_LARGEFILE", Const, 0}, - {"O_NDELAY", Const, 0}, - {"O_NOATIME", Const, 0}, - {"O_NOCTTY", Const, 0}, - {"O_NOFOLLOW", Const, 0}, - {"O_NONBLOCK", Const, 0}, - {"O_NOSIGPIPE", Const, 1}, - {"O_POPUP", Const, 0}, - {"O_RDONLY", Const, 0}, - {"O_RDWR", Const, 0}, - {"O_RSYNC", Const, 0}, - {"O_SHLOCK", Const, 0}, - {"O_SYMLINK", Const, 0}, - {"O_SYNC", Const, 0}, - {"O_TRUNC", Const, 0}, - {"O_TTY_INIT", Const, 0}, - {"O_WRONLY", Const, 0}, - {"Open", Func, 0}, - {"OpenCurrentProcessToken", Func, 0}, - {"OpenProcess", Func, 0}, - {"OpenProcessToken", Func, 0}, - {"Openat", Func, 0}, - {"Overlapped", Type, 0}, - {"Overlapped.HEvent", Field, 0}, - {"Overlapped.Internal", Field, 0}, - {"Overlapped.InternalHigh", Field, 0}, - {"Overlapped.Offset", Field, 0}, - {"Overlapped.OffsetHigh", Field, 0}, - {"PACKET_ADD_MEMBERSHIP", Const, 0}, - {"PACKET_BROADCAST", Const, 0}, - {"PACKET_DROP_MEMBERSHIP", Const, 0}, - {"PACKET_FASTROUTE", Const, 0}, - {"PACKET_HOST", Const, 0}, - {"PACKET_LOOPBACK", Const, 0}, - {"PACKET_MR_ALLMULTI", Const, 0}, - {"PACKET_MR_MULTICAST", Const, 0}, - {"PACKET_MR_PROMISC", Const, 0}, - {"PACKET_MULTICAST", Const, 0}, - {"PACKET_OTHERHOST", Const, 0}, - {"PACKET_OUTGOING", Const, 0}, - {"PACKET_RECV_OUTPUT", Const, 0}, - {"PACKET_RX_RING", Const, 0}, - {"PACKET_STATISTICS", Const, 0}, - {"PAGE_EXECUTE_READ", Const, 0}, - {"PAGE_EXECUTE_READWRITE", Const, 0}, - {"PAGE_EXECUTE_WRITECOPY", Const, 0}, - {"PAGE_READONLY", Const, 0}, - {"PAGE_READWRITE", Const, 0}, - {"PAGE_WRITECOPY", Const, 0}, - {"PARENB", Const, 0}, - {"PARMRK", Const, 0}, - {"PARODD", Const, 0}, - {"PENDIN", Const, 0}, - {"PFL_HIDDEN", Const, 2}, - {"PFL_MATCHES_PROTOCOL_ZERO", Const, 2}, - {"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2}, - {"PFL_NETWORKDIRECT_PROVIDER", Const, 2}, - {"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2}, - {"PF_FLUSH", Const, 1}, - {"PKCS_7_ASN_ENCODING", Const, 0}, - {"PMC5_PIPELINE_FLUSH", Const, 1}, - {"PRIO_PGRP", Const, 2}, - {"PRIO_PROCESS", Const, 2}, - {"PRIO_USER", Const, 2}, - {"PRI_IOFLUSH", Const, 1}, - {"PROCESS_QUERY_INFORMATION", Const, 0}, - {"PROCESS_TERMINATE", Const, 2}, - {"PROT_EXEC", Const, 0}, - {"PROT_GROWSDOWN", Const, 0}, - {"PROT_GROWSUP", Const, 0}, - {"PROT_NONE", Const, 0}, - {"PROT_READ", Const, 0}, - {"PROT_WRITE", Const, 0}, - {"PROV_DH_SCHANNEL", Const, 0}, - {"PROV_DSS", Const, 0}, - {"PROV_DSS_DH", Const, 0}, - {"PROV_EC_ECDSA_FULL", Const, 0}, - {"PROV_EC_ECDSA_SIG", Const, 0}, - {"PROV_EC_ECNRA_FULL", Const, 0}, - {"PROV_EC_ECNRA_SIG", Const, 0}, - {"PROV_FORTEZZA", Const, 0}, - {"PROV_INTEL_SEC", Const, 0}, - {"PROV_MS_EXCHANGE", Const, 0}, - {"PROV_REPLACE_OWF", Const, 0}, - {"PROV_RNG", Const, 0}, - {"PROV_RSA_AES", Const, 0}, - {"PROV_RSA_FULL", Const, 0}, - {"PROV_RSA_SCHANNEL", Const, 0}, - {"PROV_RSA_SIG", Const, 0}, - {"PROV_SPYRUS_LYNKS", Const, 0}, - {"PROV_SSL", Const, 0}, - {"PR_CAPBSET_DROP", Const, 0}, - {"PR_CAPBSET_READ", Const, 0}, - {"PR_CLEAR_SECCOMP_FILTER", Const, 0}, - {"PR_ENDIAN_BIG", Const, 0}, - {"PR_ENDIAN_LITTLE", Const, 0}, - {"PR_ENDIAN_PPC_LITTLE", Const, 0}, - {"PR_FPEMU_NOPRINT", Const, 0}, - {"PR_FPEMU_SIGFPE", Const, 0}, - {"PR_FP_EXC_ASYNC", Const, 0}, - {"PR_FP_EXC_DISABLED", Const, 0}, - {"PR_FP_EXC_DIV", Const, 0}, - {"PR_FP_EXC_INV", Const, 0}, - {"PR_FP_EXC_NONRECOV", Const, 0}, - {"PR_FP_EXC_OVF", Const, 0}, - {"PR_FP_EXC_PRECISE", Const, 0}, - {"PR_FP_EXC_RES", Const, 0}, - {"PR_FP_EXC_SW_ENABLE", Const, 0}, - {"PR_FP_EXC_UND", Const, 0}, - {"PR_GET_DUMPABLE", Const, 0}, - {"PR_GET_ENDIAN", Const, 0}, - {"PR_GET_FPEMU", Const, 0}, - {"PR_GET_FPEXC", Const, 0}, - {"PR_GET_KEEPCAPS", Const, 0}, - {"PR_GET_NAME", Const, 0}, - {"PR_GET_PDEATHSIG", Const, 0}, - {"PR_GET_SECCOMP", Const, 0}, - {"PR_GET_SECCOMP_FILTER", Const, 0}, - {"PR_GET_SECUREBITS", Const, 0}, - {"PR_GET_TIMERSLACK", Const, 0}, - {"PR_GET_TIMING", Const, 0}, - {"PR_GET_TSC", Const, 0}, - {"PR_GET_UNALIGN", Const, 0}, - {"PR_MCE_KILL", Const, 0}, - {"PR_MCE_KILL_CLEAR", Const, 0}, - {"PR_MCE_KILL_DEFAULT", Const, 0}, - {"PR_MCE_KILL_EARLY", Const, 0}, - {"PR_MCE_KILL_GET", Const, 0}, - {"PR_MCE_KILL_LATE", Const, 0}, - {"PR_MCE_KILL_SET", Const, 0}, - {"PR_SECCOMP_FILTER_EVENT", Const, 0}, - {"PR_SECCOMP_FILTER_SYSCALL", Const, 0}, - {"PR_SET_DUMPABLE", Const, 0}, - {"PR_SET_ENDIAN", Const, 0}, - {"PR_SET_FPEMU", Const, 0}, - {"PR_SET_FPEXC", Const, 0}, - {"PR_SET_KEEPCAPS", Const, 0}, - {"PR_SET_NAME", Const, 0}, - {"PR_SET_PDEATHSIG", Const, 0}, - {"PR_SET_PTRACER", Const, 0}, - {"PR_SET_SECCOMP", Const, 0}, - {"PR_SET_SECCOMP_FILTER", Const, 0}, - {"PR_SET_SECUREBITS", Const, 0}, - {"PR_SET_TIMERSLACK", Const, 0}, - {"PR_SET_TIMING", Const, 0}, - {"PR_SET_TSC", Const, 0}, - {"PR_SET_UNALIGN", Const, 0}, - {"PR_TASK_PERF_EVENTS_DISABLE", Const, 0}, - {"PR_TASK_PERF_EVENTS_ENABLE", Const, 0}, - {"PR_TIMING_STATISTICAL", Const, 0}, - {"PR_TIMING_TIMESTAMP", Const, 0}, - {"PR_TSC_ENABLE", Const, 0}, - {"PR_TSC_SIGSEGV", Const, 0}, - {"PR_UNALIGN_NOPRINT", Const, 0}, - {"PR_UNALIGN_SIGBUS", Const, 0}, - {"PTRACE_ARCH_PRCTL", Const, 0}, - {"PTRACE_ATTACH", Const, 0}, - {"PTRACE_CONT", Const, 0}, - {"PTRACE_DETACH", Const, 0}, - {"PTRACE_EVENT_CLONE", Const, 0}, - {"PTRACE_EVENT_EXEC", Const, 0}, - {"PTRACE_EVENT_EXIT", Const, 0}, - {"PTRACE_EVENT_FORK", Const, 0}, - {"PTRACE_EVENT_VFORK", Const, 0}, - {"PTRACE_EVENT_VFORK_DONE", Const, 0}, - {"PTRACE_GETCRUNCHREGS", Const, 0}, - {"PTRACE_GETEVENTMSG", Const, 0}, - {"PTRACE_GETFPREGS", Const, 0}, - {"PTRACE_GETFPXREGS", Const, 0}, - {"PTRACE_GETHBPREGS", Const, 0}, - {"PTRACE_GETREGS", Const, 0}, - {"PTRACE_GETREGSET", Const, 0}, - {"PTRACE_GETSIGINFO", Const, 0}, - {"PTRACE_GETVFPREGS", Const, 0}, - {"PTRACE_GETWMMXREGS", Const, 0}, - {"PTRACE_GET_THREAD_AREA", Const, 0}, - {"PTRACE_KILL", Const, 0}, - {"PTRACE_OLDSETOPTIONS", Const, 0}, - {"PTRACE_O_MASK", Const, 0}, - {"PTRACE_O_TRACECLONE", Const, 0}, - {"PTRACE_O_TRACEEXEC", Const, 0}, - {"PTRACE_O_TRACEEXIT", Const, 0}, - {"PTRACE_O_TRACEFORK", Const, 0}, - {"PTRACE_O_TRACESYSGOOD", Const, 0}, - {"PTRACE_O_TRACEVFORK", Const, 0}, - {"PTRACE_O_TRACEVFORKDONE", Const, 0}, - {"PTRACE_PEEKDATA", Const, 0}, - {"PTRACE_PEEKTEXT", Const, 0}, - {"PTRACE_PEEKUSR", Const, 0}, - {"PTRACE_POKEDATA", Const, 0}, - {"PTRACE_POKETEXT", Const, 0}, - {"PTRACE_POKEUSR", Const, 0}, - {"PTRACE_SETCRUNCHREGS", Const, 0}, - {"PTRACE_SETFPREGS", Const, 0}, - {"PTRACE_SETFPXREGS", Const, 0}, - {"PTRACE_SETHBPREGS", Const, 0}, - {"PTRACE_SETOPTIONS", Const, 0}, - {"PTRACE_SETREGS", Const, 0}, - {"PTRACE_SETREGSET", Const, 0}, - {"PTRACE_SETSIGINFO", Const, 0}, - {"PTRACE_SETVFPREGS", Const, 0}, - {"PTRACE_SETWMMXREGS", Const, 0}, - {"PTRACE_SET_SYSCALL", Const, 0}, - {"PTRACE_SET_THREAD_AREA", Const, 0}, - {"PTRACE_SINGLEBLOCK", Const, 0}, - {"PTRACE_SINGLESTEP", Const, 0}, - {"PTRACE_SYSCALL", Const, 0}, - {"PTRACE_SYSEMU", Const, 0}, - {"PTRACE_SYSEMU_SINGLESTEP", Const, 0}, - {"PTRACE_TRACEME", Const, 0}, - {"PT_ATTACH", Const, 0}, - {"PT_ATTACHEXC", Const, 0}, - {"PT_CONTINUE", Const, 0}, - {"PT_DATA_ADDR", Const, 0}, - {"PT_DENY_ATTACH", Const, 0}, - {"PT_DETACH", Const, 0}, - {"PT_FIRSTMACH", Const, 0}, - {"PT_FORCEQUOTA", Const, 0}, - {"PT_KILL", Const, 0}, - {"PT_MASK", Const, 1}, - {"PT_READ_D", Const, 0}, - {"PT_READ_I", Const, 0}, - {"PT_READ_U", Const, 0}, - {"PT_SIGEXC", Const, 0}, - {"PT_STEP", Const, 0}, - {"PT_TEXT_ADDR", Const, 0}, - {"PT_TEXT_END_ADDR", Const, 0}, - {"PT_THUPDATE", Const, 0}, - {"PT_TRACE_ME", Const, 0}, - {"PT_WRITE_D", Const, 0}, - {"PT_WRITE_I", Const, 0}, - {"PT_WRITE_U", Const, 0}, - {"ParseDirent", Func, 0}, - {"ParseNetlinkMessage", Func, 0}, - {"ParseNetlinkRouteAttr", Func, 0}, - {"ParseRoutingMessage", Func, 0}, - {"ParseRoutingSockaddr", Func, 0}, - {"ParseSocketControlMessage", Func, 0}, - {"ParseUnixCredentials", Func, 0}, - {"ParseUnixRights", Func, 0}, - {"PathMax", Const, 0}, - {"Pathconf", Func, 0}, - {"Pause", Func, 0}, - {"Pipe", Func, 0}, - {"Pipe2", Func, 1}, - {"PivotRoot", Func, 0}, - {"Pointer", Type, 11}, - {"PostQueuedCompletionStatus", Func, 0}, - {"Pread", Func, 0}, - {"Proc", Type, 0}, - {"Proc.Dll", Field, 0}, - {"Proc.Name", Field, 0}, - {"ProcAttr", Type, 0}, - {"ProcAttr.Dir", Field, 0}, - {"ProcAttr.Env", Field, 0}, - {"ProcAttr.Files", Field, 0}, - {"ProcAttr.Sys", Field, 0}, - {"Process32First", Func, 4}, - {"Process32Next", Func, 4}, - {"ProcessEntry32", Type, 4}, - {"ProcessEntry32.DefaultHeapID", Field, 4}, - {"ProcessEntry32.ExeFile", Field, 4}, - {"ProcessEntry32.Flags", Field, 4}, - {"ProcessEntry32.ModuleID", Field, 4}, - {"ProcessEntry32.ParentProcessID", Field, 4}, - {"ProcessEntry32.PriClassBase", Field, 4}, - {"ProcessEntry32.ProcessID", Field, 4}, - {"ProcessEntry32.Size", Field, 4}, - {"ProcessEntry32.Threads", Field, 4}, - {"ProcessEntry32.Usage", Field, 4}, - {"ProcessInformation", Type, 0}, - {"ProcessInformation.Process", Field, 0}, - {"ProcessInformation.ProcessId", Field, 0}, - {"ProcessInformation.Thread", Field, 0}, - {"ProcessInformation.ThreadId", Field, 0}, - {"Protoent", Type, 0}, - {"Protoent.Aliases", Field, 0}, - {"Protoent.Name", Field, 0}, - {"Protoent.Proto", Field, 0}, - {"PtraceAttach", Func, 0}, - {"PtraceCont", Func, 0}, - {"PtraceDetach", Func, 0}, - {"PtraceGetEventMsg", Func, 0}, - {"PtraceGetRegs", Func, 0}, - {"PtracePeekData", Func, 0}, - {"PtracePeekText", Func, 0}, - {"PtracePokeData", Func, 0}, - {"PtracePokeText", Func, 0}, - {"PtraceRegs", Type, 0}, - {"PtraceRegs.Cs", Field, 0}, - {"PtraceRegs.Ds", Field, 0}, - {"PtraceRegs.Eax", Field, 0}, - {"PtraceRegs.Ebp", Field, 0}, - {"PtraceRegs.Ebx", Field, 0}, - {"PtraceRegs.Ecx", Field, 0}, - {"PtraceRegs.Edi", Field, 0}, - {"PtraceRegs.Edx", Field, 0}, - {"PtraceRegs.Eflags", Field, 0}, - {"PtraceRegs.Eip", Field, 0}, - {"PtraceRegs.Es", Field, 0}, - {"PtraceRegs.Esi", Field, 0}, - {"PtraceRegs.Esp", Field, 0}, - {"PtraceRegs.Fs", Field, 0}, - {"PtraceRegs.Fs_base", Field, 0}, - {"PtraceRegs.Gs", Field, 0}, - {"PtraceRegs.Gs_base", Field, 0}, - {"PtraceRegs.Orig_eax", Field, 0}, - {"PtraceRegs.Orig_rax", Field, 0}, - {"PtraceRegs.R10", Field, 0}, - {"PtraceRegs.R11", Field, 0}, - {"PtraceRegs.R12", Field, 0}, - {"PtraceRegs.R13", Field, 0}, - {"PtraceRegs.R14", Field, 0}, - {"PtraceRegs.R15", Field, 0}, - {"PtraceRegs.R8", Field, 0}, - {"PtraceRegs.R9", Field, 0}, - {"PtraceRegs.Rax", Field, 0}, - {"PtraceRegs.Rbp", Field, 0}, - {"PtraceRegs.Rbx", Field, 0}, - {"PtraceRegs.Rcx", Field, 0}, - {"PtraceRegs.Rdi", Field, 0}, - {"PtraceRegs.Rdx", Field, 0}, - {"PtraceRegs.Rip", Field, 0}, - {"PtraceRegs.Rsi", Field, 0}, - {"PtraceRegs.Rsp", Field, 0}, - {"PtraceRegs.Ss", Field, 0}, - {"PtraceRegs.Uregs", Field, 0}, - {"PtraceRegs.Xcs", Field, 0}, - {"PtraceRegs.Xds", Field, 0}, - {"PtraceRegs.Xes", Field, 0}, - {"PtraceRegs.Xfs", Field, 0}, - {"PtraceRegs.Xgs", Field, 0}, - {"PtraceRegs.Xss", Field, 0}, - {"PtraceSetOptions", Func, 0}, - {"PtraceSetRegs", Func, 0}, - {"PtraceSingleStep", Func, 0}, - {"PtraceSyscall", Func, 1}, - {"Pwrite", Func, 0}, - {"REG_BINARY", Const, 0}, - {"REG_DWORD", Const, 0}, - {"REG_DWORD_BIG_ENDIAN", Const, 0}, - {"REG_DWORD_LITTLE_ENDIAN", Const, 0}, - {"REG_EXPAND_SZ", Const, 0}, - {"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0}, - {"REG_LINK", Const, 0}, - {"REG_MULTI_SZ", Const, 0}, - {"REG_NONE", Const, 0}, - {"REG_QWORD", Const, 0}, - {"REG_QWORD_LITTLE_ENDIAN", Const, 0}, - {"REG_RESOURCE_LIST", Const, 0}, - {"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0}, - {"REG_SZ", Const, 0}, - {"RLIMIT_AS", Const, 0}, - {"RLIMIT_CORE", Const, 0}, - {"RLIMIT_CPU", Const, 0}, - {"RLIMIT_CPU_USAGE_MONITOR", Const, 16}, - {"RLIMIT_DATA", Const, 0}, - {"RLIMIT_FSIZE", Const, 0}, - {"RLIMIT_NOFILE", Const, 0}, - {"RLIMIT_STACK", Const, 0}, - {"RLIM_INFINITY", Const, 0}, - {"RTAX_ADVMSS", Const, 0}, - {"RTAX_AUTHOR", Const, 0}, - {"RTAX_BRD", Const, 0}, - {"RTAX_CWND", Const, 0}, - {"RTAX_DST", Const, 0}, - {"RTAX_FEATURES", Const, 0}, - {"RTAX_FEATURE_ALLFRAG", Const, 0}, - {"RTAX_FEATURE_ECN", Const, 0}, - {"RTAX_FEATURE_SACK", Const, 0}, - {"RTAX_FEATURE_TIMESTAMP", Const, 0}, - {"RTAX_GATEWAY", Const, 0}, - {"RTAX_GENMASK", Const, 0}, - {"RTAX_HOPLIMIT", Const, 0}, - {"RTAX_IFA", Const, 0}, - {"RTAX_IFP", Const, 0}, - {"RTAX_INITCWND", Const, 0}, - {"RTAX_INITRWND", Const, 0}, - {"RTAX_LABEL", Const, 1}, - {"RTAX_LOCK", Const, 0}, - {"RTAX_MAX", Const, 0}, - {"RTAX_MTU", Const, 0}, - {"RTAX_NETMASK", Const, 0}, - {"RTAX_REORDERING", Const, 0}, - {"RTAX_RTO_MIN", Const, 0}, - {"RTAX_RTT", Const, 0}, - {"RTAX_RTTVAR", Const, 0}, - {"RTAX_SRC", Const, 1}, - {"RTAX_SRCMASK", Const, 1}, - {"RTAX_SSTHRESH", Const, 0}, - {"RTAX_TAG", Const, 1}, - {"RTAX_UNSPEC", Const, 0}, - {"RTAX_WINDOW", Const, 0}, - {"RTA_ALIGNTO", Const, 0}, - {"RTA_AUTHOR", Const, 0}, - {"RTA_BRD", Const, 0}, - {"RTA_CACHEINFO", Const, 0}, - {"RTA_DST", Const, 0}, - {"RTA_FLOW", Const, 0}, - {"RTA_GATEWAY", Const, 0}, - {"RTA_GENMASK", Const, 0}, - {"RTA_IFA", Const, 0}, - {"RTA_IFP", Const, 0}, - {"RTA_IIF", Const, 0}, - {"RTA_LABEL", Const, 1}, - {"RTA_MAX", Const, 0}, - {"RTA_METRICS", Const, 0}, - {"RTA_MULTIPATH", Const, 0}, - {"RTA_NETMASK", Const, 0}, - {"RTA_OIF", Const, 0}, - {"RTA_PREFSRC", Const, 0}, - {"RTA_PRIORITY", Const, 0}, - {"RTA_SRC", Const, 0}, - {"RTA_SRCMASK", Const, 1}, - {"RTA_TABLE", Const, 0}, - {"RTA_TAG", Const, 1}, - {"RTA_UNSPEC", Const, 0}, - {"RTCF_DIRECTSRC", Const, 0}, - {"RTCF_DOREDIRECT", Const, 0}, - {"RTCF_LOG", Const, 0}, - {"RTCF_MASQ", Const, 0}, - {"RTCF_NAT", Const, 0}, - {"RTCF_VALVE", Const, 0}, - {"RTF_ADDRCLASSMASK", Const, 0}, - {"RTF_ADDRCONF", Const, 0}, - {"RTF_ALLONLINK", Const, 0}, - {"RTF_ANNOUNCE", Const, 1}, - {"RTF_BLACKHOLE", Const, 0}, - {"RTF_BROADCAST", Const, 0}, - {"RTF_CACHE", Const, 0}, - {"RTF_CLONED", Const, 1}, - {"RTF_CLONING", Const, 0}, - {"RTF_CONDEMNED", Const, 0}, - {"RTF_DEFAULT", Const, 0}, - {"RTF_DELCLONE", Const, 0}, - {"RTF_DONE", Const, 0}, - {"RTF_DYNAMIC", Const, 0}, - {"RTF_FLOW", Const, 0}, - {"RTF_FMASK", Const, 0}, - {"RTF_GATEWAY", Const, 0}, - {"RTF_GWFLAG_COMPAT", Const, 3}, - {"RTF_HOST", Const, 0}, - {"RTF_IFREF", Const, 0}, - {"RTF_IFSCOPE", Const, 0}, - {"RTF_INTERFACE", Const, 0}, - {"RTF_IRTT", Const, 0}, - {"RTF_LINKRT", Const, 0}, - {"RTF_LLDATA", Const, 0}, - {"RTF_LLINFO", Const, 0}, - {"RTF_LOCAL", Const, 0}, - {"RTF_MASK", Const, 1}, - {"RTF_MODIFIED", Const, 0}, - {"RTF_MPATH", Const, 1}, - {"RTF_MPLS", Const, 1}, - {"RTF_MSS", Const, 0}, - {"RTF_MTU", Const, 0}, - {"RTF_MULTICAST", Const, 0}, - {"RTF_NAT", Const, 0}, - {"RTF_NOFORWARD", Const, 0}, - {"RTF_NONEXTHOP", Const, 0}, - {"RTF_NOPMTUDISC", Const, 0}, - {"RTF_PERMANENT_ARP", Const, 1}, - {"RTF_PINNED", Const, 0}, - {"RTF_POLICY", Const, 0}, - {"RTF_PRCLONING", Const, 0}, - {"RTF_PROTO1", Const, 0}, - {"RTF_PROTO2", Const, 0}, - {"RTF_PROTO3", Const, 0}, - {"RTF_PROXY", Const, 16}, - {"RTF_REINSTATE", Const, 0}, - {"RTF_REJECT", Const, 0}, - {"RTF_RNH_LOCKED", Const, 0}, - {"RTF_ROUTER", Const, 16}, - {"RTF_SOURCE", Const, 1}, - {"RTF_SRC", Const, 1}, - {"RTF_STATIC", Const, 0}, - {"RTF_STICKY", Const, 0}, - {"RTF_THROW", Const, 0}, - {"RTF_TUNNEL", Const, 1}, - {"RTF_UP", Const, 0}, - {"RTF_USETRAILERS", Const, 1}, - {"RTF_WASCLONED", Const, 0}, - {"RTF_WINDOW", Const, 0}, - {"RTF_XRESOLVE", Const, 0}, - {"RTM_ADD", Const, 0}, - {"RTM_BASE", Const, 0}, - {"RTM_CHANGE", Const, 0}, - {"RTM_CHGADDR", Const, 1}, - {"RTM_DELACTION", Const, 0}, - {"RTM_DELADDR", Const, 0}, - {"RTM_DELADDRLABEL", Const, 0}, - {"RTM_DELETE", Const, 0}, - {"RTM_DELLINK", Const, 0}, - {"RTM_DELMADDR", Const, 0}, - {"RTM_DELNEIGH", Const, 0}, - {"RTM_DELQDISC", Const, 0}, - {"RTM_DELROUTE", Const, 0}, - {"RTM_DELRULE", Const, 0}, - {"RTM_DELTCLASS", Const, 0}, - {"RTM_DELTFILTER", Const, 0}, - {"RTM_DESYNC", Const, 1}, - {"RTM_F_CLONED", Const, 0}, - {"RTM_F_EQUALIZE", Const, 0}, - {"RTM_F_NOTIFY", Const, 0}, - {"RTM_F_PREFIX", Const, 0}, - {"RTM_GET", Const, 0}, - {"RTM_GET2", Const, 0}, - {"RTM_GETACTION", Const, 0}, - {"RTM_GETADDR", Const, 0}, - {"RTM_GETADDRLABEL", Const, 0}, - {"RTM_GETANYCAST", Const, 0}, - {"RTM_GETDCB", Const, 0}, - {"RTM_GETLINK", Const, 0}, - {"RTM_GETMULTICAST", Const, 0}, - {"RTM_GETNEIGH", Const, 0}, - {"RTM_GETNEIGHTBL", Const, 0}, - {"RTM_GETQDISC", Const, 0}, - {"RTM_GETROUTE", Const, 0}, - {"RTM_GETRULE", Const, 0}, - {"RTM_GETTCLASS", Const, 0}, - {"RTM_GETTFILTER", Const, 0}, - {"RTM_IEEE80211", Const, 0}, - {"RTM_IFANNOUNCE", Const, 0}, - {"RTM_IFINFO", Const, 0}, - {"RTM_IFINFO2", Const, 0}, - {"RTM_LLINFO_UPD", Const, 1}, - {"RTM_LOCK", Const, 0}, - {"RTM_LOSING", Const, 0}, - {"RTM_MAX", Const, 0}, - {"RTM_MAXSIZE", Const, 1}, - {"RTM_MISS", Const, 0}, - {"RTM_NEWACTION", Const, 0}, - {"RTM_NEWADDR", Const, 0}, - {"RTM_NEWADDRLABEL", Const, 0}, - {"RTM_NEWLINK", Const, 0}, - {"RTM_NEWMADDR", Const, 0}, - {"RTM_NEWMADDR2", Const, 0}, - {"RTM_NEWNDUSEROPT", Const, 0}, - {"RTM_NEWNEIGH", Const, 0}, - {"RTM_NEWNEIGHTBL", Const, 0}, - {"RTM_NEWPREFIX", Const, 0}, - {"RTM_NEWQDISC", Const, 0}, - {"RTM_NEWROUTE", Const, 0}, - {"RTM_NEWRULE", Const, 0}, - {"RTM_NEWTCLASS", Const, 0}, - {"RTM_NEWTFILTER", Const, 0}, - {"RTM_NR_FAMILIES", Const, 0}, - {"RTM_NR_MSGTYPES", Const, 0}, - {"RTM_OIFINFO", Const, 1}, - {"RTM_OLDADD", Const, 0}, - {"RTM_OLDDEL", Const, 0}, - {"RTM_OOIFINFO", Const, 1}, - {"RTM_REDIRECT", Const, 0}, - {"RTM_RESOLVE", Const, 0}, - {"RTM_RTTUNIT", Const, 0}, - {"RTM_SETDCB", Const, 0}, - {"RTM_SETGATE", Const, 1}, - {"RTM_SETLINK", Const, 0}, - {"RTM_SETNEIGHTBL", Const, 0}, - {"RTM_VERSION", Const, 0}, - {"RTNH_ALIGNTO", Const, 0}, - {"RTNH_F_DEAD", Const, 0}, - {"RTNH_F_ONLINK", Const, 0}, - {"RTNH_F_PERVASIVE", Const, 0}, - {"RTNLGRP_IPV4_IFADDR", Const, 1}, - {"RTNLGRP_IPV4_MROUTE", Const, 1}, - {"RTNLGRP_IPV4_ROUTE", Const, 1}, - {"RTNLGRP_IPV4_RULE", Const, 1}, - {"RTNLGRP_IPV6_IFADDR", Const, 1}, - {"RTNLGRP_IPV6_IFINFO", Const, 1}, - {"RTNLGRP_IPV6_MROUTE", Const, 1}, - {"RTNLGRP_IPV6_PREFIX", Const, 1}, - {"RTNLGRP_IPV6_ROUTE", Const, 1}, - {"RTNLGRP_IPV6_RULE", Const, 1}, - {"RTNLGRP_LINK", Const, 1}, - {"RTNLGRP_ND_USEROPT", Const, 1}, - {"RTNLGRP_NEIGH", Const, 1}, - {"RTNLGRP_NONE", Const, 1}, - {"RTNLGRP_NOTIFY", Const, 1}, - {"RTNLGRP_TC", Const, 1}, - {"RTN_ANYCAST", Const, 0}, - {"RTN_BLACKHOLE", Const, 0}, - {"RTN_BROADCAST", Const, 0}, - {"RTN_LOCAL", Const, 0}, - {"RTN_MAX", Const, 0}, - {"RTN_MULTICAST", Const, 0}, - {"RTN_NAT", Const, 0}, - {"RTN_PROHIBIT", Const, 0}, - {"RTN_THROW", Const, 0}, - {"RTN_UNICAST", Const, 0}, - {"RTN_UNREACHABLE", Const, 0}, - {"RTN_UNSPEC", Const, 0}, - {"RTN_XRESOLVE", Const, 0}, - {"RTPROT_BIRD", Const, 0}, - {"RTPROT_BOOT", Const, 0}, - {"RTPROT_DHCP", Const, 0}, - {"RTPROT_DNROUTED", Const, 0}, - {"RTPROT_GATED", Const, 0}, - {"RTPROT_KERNEL", Const, 0}, - {"RTPROT_MRT", Const, 0}, - {"RTPROT_NTK", Const, 0}, - {"RTPROT_RA", Const, 0}, - {"RTPROT_REDIRECT", Const, 0}, - {"RTPROT_STATIC", Const, 0}, - {"RTPROT_UNSPEC", Const, 0}, - {"RTPROT_XORP", Const, 0}, - {"RTPROT_ZEBRA", Const, 0}, - {"RTV_EXPIRE", Const, 0}, - {"RTV_HOPCOUNT", Const, 0}, - {"RTV_MTU", Const, 0}, - {"RTV_RPIPE", Const, 0}, - {"RTV_RTT", Const, 0}, - {"RTV_RTTVAR", Const, 0}, - {"RTV_SPIPE", Const, 0}, - {"RTV_SSTHRESH", Const, 0}, - {"RTV_WEIGHT", Const, 0}, - {"RT_CACHING_CONTEXT", Const, 1}, - {"RT_CLASS_DEFAULT", Const, 0}, - {"RT_CLASS_LOCAL", Const, 0}, - {"RT_CLASS_MAIN", Const, 0}, - {"RT_CLASS_MAX", Const, 0}, - {"RT_CLASS_UNSPEC", Const, 0}, - {"RT_DEFAULT_FIB", Const, 1}, - {"RT_NORTREF", Const, 1}, - {"RT_SCOPE_HOST", Const, 0}, - {"RT_SCOPE_LINK", Const, 0}, - {"RT_SCOPE_NOWHERE", Const, 0}, - {"RT_SCOPE_SITE", Const, 0}, - {"RT_SCOPE_UNIVERSE", Const, 0}, - {"RT_TABLEID_MAX", Const, 1}, - {"RT_TABLE_COMPAT", Const, 0}, - {"RT_TABLE_DEFAULT", Const, 0}, - {"RT_TABLE_LOCAL", Const, 0}, - {"RT_TABLE_MAIN", Const, 0}, - {"RT_TABLE_MAX", Const, 0}, - {"RT_TABLE_UNSPEC", Const, 0}, - {"RUSAGE_CHILDREN", Const, 0}, - {"RUSAGE_SELF", Const, 0}, - {"RUSAGE_THREAD", Const, 0}, - {"Radvisory_t", Type, 0}, - {"Radvisory_t.Count", Field, 0}, - {"Radvisory_t.Offset", Field, 0}, - {"Radvisory_t.Pad_cgo_0", Field, 0}, - {"RawConn", Type, 9}, - {"RawSockaddr", Type, 0}, - {"RawSockaddr.Data", Field, 0}, - {"RawSockaddr.Family", Field, 0}, - {"RawSockaddr.Len", Field, 0}, - {"RawSockaddrAny", Type, 0}, - {"RawSockaddrAny.Addr", Field, 0}, - {"RawSockaddrAny.Pad", Field, 0}, - {"RawSockaddrDatalink", Type, 0}, - {"RawSockaddrDatalink.Alen", Field, 0}, - {"RawSockaddrDatalink.Data", Field, 0}, - {"RawSockaddrDatalink.Family", Field, 0}, - {"RawSockaddrDatalink.Index", Field, 0}, - {"RawSockaddrDatalink.Len", Field, 0}, - {"RawSockaddrDatalink.Nlen", Field, 0}, - {"RawSockaddrDatalink.Pad_cgo_0", Field, 2}, - {"RawSockaddrDatalink.Slen", Field, 0}, - {"RawSockaddrDatalink.Type", Field, 0}, - {"RawSockaddrInet4", Type, 0}, - {"RawSockaddrInet4.Addr", Field, 0}, - {"RawSockaddrInet4.Family", Field, 0}, - {"RawSockaddrInet4.Len", Field, 0}, - {"RawSockaddrInet4.Port", Field, 0}, - {"RawSockaddrInet4.Zero", Field, 0}, - {"RawSockaddrInet6", Type, 0}, - {"RawSockaddrInet6.Addr", Field, 0}, - {"RawSockaddrInet6.Family", Field, 0}, - {"RawSockaddrInet6.Flowinfo", Field, 0}, - {"RawSockaddrInet6.Len", Field, 0}, - {"RawSockaddrInet6.Port", Field, 0}, - {"RawSockaddrInet6.Scope_id", Field, 0}, - {"RawSockaddrLinklayer", Type, 0}, - {"RawSockaddrLinklayer.Addr", Field, 0}, - {"RawSockaddrLinklayer.Family", Field, 0}, - {"RawSockaddrLinklayer.Halen", Field, 0}, - {"RawSockaddrLinklayer.Hatype", Field, 0}, - {"RawSockaddrLinklayer.Ifindex", Field, 0}, - {"RawSockaddrLinklayer.Pkttype", Field, 0}, - {"RawSockaddrLinklayer.Protocol", Field, 0}, - {"RawSockaddrNetlink", Type, 0}, - {"RawSockaddrNetlink.Family", Field, 0}, - {"RawSockaddrNetlink.Groups", Field, 0}, - {"RawSockaddrNetlink.Pad", Field, 0}, - {"RawSockaddrNetlink.Pid", Field, 0}, - {"RawSockaddrUnix", Type, 0}, - {"RawSockaddrUnix.Family", Field, 0}, - {"RawSockaddrUnix.Len", Field, 0}, - {"RawSockaddrUnix.Pad_cgo_0", Field, 2}, - {"RawSockaddrUnix.Path", Field, 0}, - {"RawSyscall", Func, 0}, - {"RawSyscall6", Func, 0}, - {"Read", Func, 0}, - {"ReadConsole", Func, 1}, - {"ReadDirectoryChanges", Func, 0}, - {"ReadDirent", Func, 0}, - {"ReadFile", Func, 0}, - {"Readlink", Func, 0}, - {"Reboot", Func, 0}, - {"Recvfrom", Func, 0}, - {"Recvmsg", Func, 0}, - {"RegCloseKey", Func, 0}, - {"RegEnumKeyEx", Func, 0}, - {"RegOpenKeyEx", Func, 0}, - {"RegQueryInfoKey", Func, 0}, - {"RegQueryValueEx", Func, 0}, - {"RemoveDirectory", Func, 0}, - {"Removexattr", Func, 1}, - {"Rename", Func, 0}, - {"Renameat", Func, 0}, - {"Revoke", Func, 0}, - {"Rlimit", Type, 0}, - {"Rlimit.Cur", Field, 0}, - {"Rlimit.Max", Field, 0}, - {"Rmdir", Func, 0}, - {"RouteMessage", Type, 0}, - {"RouteMessage.Data", Field, 0}, - {"RouteMessage.Header", Field, 0}, - {"RouteRIB", Func, 0}, - {"RoutingMessage", Type, 0}, - {"RtAttr", Type, 0}, - {"RtAttr.Len", Field, 0}, - {"RtAttr.Type", Field, 0}, - {"RtGenmsg", Type, 0}, - {"RtGenmsg.Family", Field, 0}, - {"RtMetrics", Type, 0}, - {"RtMetrics.Expire", Field, 0}, - {"RtMetrics.Filler", Field, 0}, - {"RtMetrics.Hopcount", Field, 0}, - {"RtMetrics.Locks", Field, 0}, - {"RtMetrics.Mtu", Field, 0}, - {"RtMetrics.Pad", Field, 3}, - {"RtMetrics.Pksent", Field, 0}, - {"RtMetrics.Recvpipe", Field, 0}, - {"RtMetrics.Refcnt", Field, 2}, - {"RtMetrics.Rtt", Field, 0}, - {"RtMetrics.Rttvar", Field, 0}, - {"RtMetrics.Sendpipe", Field, 0}, - {"RtMetrics.Ssthresh", Field, 0}, - {"RtMetrics.Weight", Field, 0}, - {"RtMsg", Type, 0}, - {"RtMsg.Dst_len", Field, 0}, - {"RtMsg.Family", Field, 0}, - {"RtMsg.Flags", Field, 0}, - {"RtMsg.Protocol", Field, 0}, - {"RtMsg.Scope", Field, 0}, - {"RtMsg.Src_len", Field, 0}, - {"RtMsg.Table", Field, 0}, - {"RtMsg.Tos", Field, 0}, - {"RtMsg.Type", Field, 0}, - {"RtMsghdr", Type, 0}, - {"RtMsghdr.Addrs", Field, 0}, - {"RtMsghdr.Errno", Field, 0}, - {"RtMsghdr.Flags", Field, 0}, - {"RtMsghdr.Fmask", Field, 0}, - {"RtMsghdr.Hdrlen", Field, 2}, - {"RtMsghdr.Index", Field, 0}, - {"RtMsghdr.Inits", Field, 0}, - {"RtMsghdr.Mpls", Field, 2}, - {"RtMsghdr.Msglen", Field, 0}, - {"RtMsghdr.Pad_cgo_0", Field, 0}, - {"RtMsghdr.Pad_cgo_1", Field, 2}, - {"RtMsghdr.Pid", Field, 0}, - {"RtMsghdr.Priority", Field, 2}, - {"RtMsghdr.Rmx", Field, 0}, - {"RtMsghdr.Seq", Field, 0}, - {"RtMsghdr.Tableid", Field, 2}, - {"RtMsghdr.Type", Field, 0}, - {"RtMsghdr.Use", Field, 0}, - {"RtMsghdr.Version", Field, 0}, - {"RtNexthop", Type, 0}, - {"RtNexthop.Flags", Field, 0}, - {"RtNexthop.Hops", Field, 0}, - {"RtNexthop.Ifindex", Field, 0}, - {"RtNexthop.Len", Field, 0}, - {"Rusage", Type, 0}, - {"Rusage.CreationTime", Field, 0}, - {"Rusage.ExitTime", Field, 0}, - {"Rusage.Idrss", Field, 0}, - {"Rusage.Inblock", Field, 0}, - {"Rusage.Isrss", Field, 0}, - {"Rusage.Ixrss", Field, 0}, - {"Rusage.KernelTime", Field, 0}, - {"Rusage.Majflt", Field, 0}, - {"Rusage.Maxrss", Field, 0}, - {"Rusage.Minflt", Field, 0}, - {"Rusage.Msgrcv", Field, 0}, - {"Rusage.Msgsnd", Field, 0}, - {"Rusage.Nivcsw", Field, 0}, - {"Rusage.Nsignals", Field, 0}, - {"Rusage.Nswap", Field, 0}, - {"Rusage.Nvcsw", Field, 0}, - {"Rusage.Oublock", Field, 0}, - {"Rusage.Stime", Field, 0}, - {"Rusage.UserTime", Field, 0}, - {"Rusage.Utime", Field, 0}, - {"SCM_BINTIME", Const, 0}, - {"SCM_CREDENTIALS", Const, 0}, - {"SCM_CREDS", Const, 0}, - {"SCM_RIGHTS", Const, 0}, - {"SCM_TIMESTAMP", Const, 0}, - {"SCM_TIMESTAMPING", Const, 0}, - {"SCM_TIMESTAMPNS", Const, 0}, - {"SCM_TIMESTAMP_MONOTONIC", Const, 0}, - {"SHUT_RD", Const, 0}, - {"SHUT_RDWR", Const, 0}, - {"SHUT_WR", Const, 0}, - {"SID", Type, 0}, - {"SIDAndAttributes", Type, 0}, - {"SIDAndAttributes.Attributes", Field, 0}, - {"SIDAndAttributes.Sid", Field, 0}, - {"SIGABRT", Const, 0}, - {"SIGALRM", Const, 0}, - {"SIGBUS", Const, 0}, - {"SIGCHLD", Const, 0}, - {"SIGCLD", Const, 0}, - {"SIGCONT", Const, 0}, - {"SIGEMT", Const, 0}, - {"SIGFPE", Const, 0}, - {"SIGHUP", Const, 0}, - {"SIGILL", Const, 0}, - {"SIGINFO", Const, 0}, - {"SIGINT", Const, 0}, - {"SIGIO", Const, 0}, - {"SIGIOT", Const, 0}, - {"SIGKILL", Const, 0}, - {"SIGLIBRT", Const, 1}, - {"SIGLWP", Const, 0}, - {"SIGPIPE", Const, 0}, - {"SIGPOLL", Const, 0}, - {"SIGPROF", Const, 0}, - {"SIGPWR", Const, 0}, - {"SIGQUIT", Const, 0}, - {"SIGSEGV", Const, 0}, - {"SIGSTKFLT", Const, 0}, - {"SIGSTOP", Const, 0}, - {"SIGSYS", Const, 0}, - {"SIGTERM", Const, 0}, - {"SIGTHR", Const, 0}, - {"SIGTRAP", Const, 0}, - {"SIGTSTP", Const, 0}, - {"SIGTTIN", Const, 0}, - {"SIGTTOU", Const, 0}, - {"SIGUNUSED", Const, 0}, - {"SIGURG", Const, 0}, - {"SIGUSR1", Const, 0}, - {"SIGUSR2", Const, 0}, - {"SIGVTALRM", Const, 0}, - {"SIGWINCH", Const, 0}, - {"SIGXCPU", Const, 0}, - {"SIGXFSZ", Const, 0}, - {"SIOCADDDLCI", Const, 0}, - {"SIOCADDMULTI", Const, 0}, - {"SIOCADDRT", Const, 0}, - {"SIOCAIFADDR", Const, 0}, - {"SIOCAIFGROUP", Const, 0}, - {"SIOCALIFADDR", Const, 0}, - {"SIOCARPIPLL", Const, 0}, - {"SIOCATMARK", Const, 0}, - {"SIOCAUTOADDR", Const, 0}, - {"SIOCAUTONETMASK", Const, 0}, - {"SIOCBRDGADD", Const, 1}, - {"SIOCBRDGADDS", Const, 1}, - {"SIOCBRDGARL", Const, 1}, - {"SIOCBRDGDADDR", Const, 1}, - {"SIOCBRDGDEL", Const, 1}, - {"SIOCBRDGDELS", Const, 1}, - {"SIOCBRDGFLUSH", Const, 1}, - {"SIOCBRDGFRL", Const, 1}, - {"SIOCBRDGGCACHE", Const, 1}, - {"SIOCBRDGGFD", Const, 1}, - {"SIOCBRDGGHT", Const, 1}, - {"SIOCBRDGGIFFLGS", Const, 1}, - {"SIOCBRDGGMA", Const, 1}, - {"SIOCBRDGGPARAM", Const, 1}, - {"SIOCBRDGGPRI", Const, 1}, - {"SIOCBRDGGRL", Const, 1}, - {"SIOCBRDGGSIFS", Const, 1}, - {"SIOCBRDGGTO", Const, 1}, - {"SIOCBRDGIFS", Const, 1}, - {"SIOCBRDGRTS", Const, 1}, - {"SIOCBRDGSADDR", Const, 1}, - {"SIOCBRDGSCACHE", Const, 1}, - {"SIOCBRDGSFD", Const, 1}, - {"SIOCBRDGSHT", Const, 1}, - {"SIOCBRDGSIFCOST", Const, 1}, - {"SIOCBRDGSIFFLGS", Const, 1}, - {"SIOCBRDGSIFPRIO", Const, 1}, - {"SIOCBRDGSMA", Const, 1}, - {"SIOCBRDGSPRI", Const, 1}, - {"SIOCBRDGSPROTO", Const, 1}, - {"SIOCBRDGSTO", Const, 1}, - {"SIOCBRDGSTXHC", Const, 1}, - {"SIOCDARP", Const, 0}, - {"SIOCDELDLCI", Const, 0}, - {"SIOCDELMULTI", Const, 0}, - {"SIOCDELRT", Const, 0}, - {"SIOCDEVPRIVATE", Const, 0}, - {"SIOCDIFADDR", Const, 0}, - {"SIOCDIFGROUP", Const, 0}, - {"SIOCDIFPHYADDR", Const, 0}, - {"SIOCDLIFADDR", Const, 0}, - {"SIOCDRARP", Const, 0}, - {"SIOCGARP", Const, 0}, - {"SIOCGDRVSPEC", Const, 0}, - {"SIOCGETKALIVE", Const, 1}, - {"SIOCGETLABEL", Const, 1}, - {"SIOCGETPFLOW", Const, 1}, - {"SIOCGETPFSYNC", Const, 1}, - {"SIOCGETSGCNT", Const, 0}, - {"SIOCGETVIFCNT", Const, 0}, - {"SIOCGETVLAN", Const, 0}, - {"SIOCGHIWAT", Const, 0}, - {"SIOCGIFADDR", Const, 0}, - {"SIOCGIFADDRPREF", Const, 1}, - {"SIOCGIFALIAS", Const, 1}, - {"SIOCGIFALTMTU", Const, 0}, - {"SIOCGIFASYNCMAP", Const, 0}, - {"SIOCGIFBOND", Const, 0}, - {"SIOCGIFBR", Const, 0}, - {"SIOCGIFBRDADDR", Const, 0}, - {"SIOCGIFCAP", Const, 0}, - {"SIOCGIFCONF", Const, 0}, - {"SIOCGIFCOUNT", Const, 0}, - {"SIOCGIFDATA", Const, 1}, - {"SIOCGIFDESCR", Const, 0}, - {"SIOCGIFDEVMTU", Const, 0}, - {"SIOCGIFDLT", Const, 1}, - {"SIOCGIFDSTADDR", Const, 0}, - {"SIOCGIFENCAP", Const, 0}, - {"SIOCGIFFIB", Const, 1}, - {"SIOCGIFFLAGS", Const, 0}, - {"SIOCGIFGATTR", Const, 1}, - {"SIOCGIFGENERIC", Const, 0}, - {"SIOCGIFGMEMB", Const, 0}, - {"SIOCGIFGROUP", Const, 0}, - {"SIOCGIFHARDMTU", Const, 3}, - {"SIOCGIFHWADDR", Const, 0}, - {"SIOCGIFINDEX", Const, 0}, - {"SIOCGIFKPI", Const, 0}, - {"SIOCGIFMAC", Const, 0}, - {"SIOCGIFMAP", Const, 0}, - {"SIOCGIFMEDIA", Const, 0}, - {"SIOCGIFMEM", Const, 0}, - {"SIOCGIFMETRIC", Const, 0}, - {"SIOCGIFMTU", Const, 0}, - {"SIOCGIFNAME", Const, 0}, - {"SIOCGIFNETMASK", Const, 0}, - {"SIOCGIFPDSTADDR", Const, 0}, - {"SIOCGIFPFLAGS", Const, 0}, - {"SIOCGIFPHYS", Const, 0}, - {"SIOCGIFPRIORITY", Const, 1}, - {"SIOCGIFPSRCADDR", Const, 0}, - {"SIOCGIFRDOMAIN", Const, 1}, - {"SIOCGIFRTLABEL", Const, 1}, - {"SIOCGIFSLAVE", Const, 0}, - {"SIOCGIFSTATUS", Const, 0}, - {"SIOCGIFTIMESLOT", Const, 1}, - {"SIOCGIFTXQLEN", Const, 0}, - {"SIOCGIFVLAN", Const, 0}, - {"SIOCGIFWAKEFLAGS", Const, 0}, - {"SIOCGIFXFLAGS", Const, 1}, - {"SIOCGLIFADDR", Const, 0}, - {"SIOCGLIFPHYADDR", Const, 0}, - {"SIOCGLIFPHYRTABLE", Const, 1}, - {"SIOCGLIFPHYTTL", Const, 3}, - {"SIOCGLINKSTR", Const, 1}, - {"SIOCGLOWAT", Const, 0}, - {"SIOCGPGRP", Const, 0}, - {"SIOCGPRIVATE_0", Const, 0}, - {"SIOCGPRIVATE_1", Const, 0}, - {"SIOCGRARP", Const, 0}, - {"SIOCGSPPPPARAMS", Const, 3}, - {"SIOCGSTAMP", Const, 0}, - {"SIOCGSTAMPNS", Const, 0}, - {"SIOCGVH", Const, 1}, - {"SIOCGVNETID", Const, 3}, - {"SIOCIFCREATE", Const, 0}, - {"SIOCIFCREATE2", Const, 0}, - {"SIOCIFDESTROY", Const, 0}, - {"SIOCIFGCLONERS", Const, 0}, - {"SIOCINITIFADDR", Const, 1}, - {"SIOCPROTOPRIVATE", Const, 0}, - {"SIOCRSLVMULTI", Const, 0}, - {"SIOCRTMSG", Const, 0}, - {"SIOCSARP", Const, 0}, - {"SIOCSDRVSPEC", Const, 0}, - {"SIOCSETKALIVE", Const, 1}, - {"SIOCSETLABEL", Const, 1}, - {"SIOCSETPFLOW", Const, 1}, - {"SIOCSETPFSYNC", Const, 1}, - {"SIOCSETVLAN", Const, 0}, - {"SIOCSHIWAT", Const, 0}, - {"SIOCSIFADDR", Const, 0}, - {"SIOCSIFADDRPREF", Const, 1}, - {"SIOCSIFALTMTU", Const, 0}, - {"SIOCSIFASYNCMAP", Const, 0}, - {"SIOCSIFBOND", Const, 0}, - {"SIOCSIFBR", Const, 0}, - {"SIOCSIFBRDADDR", Const, 0}, - {"SIOCSIFCAP", Const, 0}, - {"SIOCSIFDESCR", Const, 0}, - {"SIOCSIFDSTADDR", Const, 0}, - {"SIOCSIFENCAP", Const, 0}, - {"SIOCSIFFIB", Const, 1}, - {"SIOCSIFFLAGS", Const, 0}, - {"SIOCSIFGATTR", Const, 1}, - {"SIOCSIFGENERIC", Const, 0}, - {"SIOCSIFHWADDR", Const, 0}, - {"SIOCSIFHWBROADCAST", Const, 0}, - {"SIOCSIFKPI", Const, 0}, - {"SIOCSIFLINK", Const, 0}, - {"SIOCSIFLLADDR", Const, 0}, - {"SIOCSIFMAC", Const, 0}, - {"SIOCSIFMAP", Const, 0}, - {"SIOCSIFMEDIA", Const, 0}, - {"SIOCSIFMEM", Const, 0}, - {"SIOCSIFMETRIC", Const, 0}, - {"SIOCSIFMTU", Const, 0}, - {"SIOCSIFNAME", Const, 0}, - {"SIOCSIFNETMASK", Const, 0}, - {"SIOCSIFPFLAGS", Const, 0}, - {"SIOCSIFPHYADDR", Const, 0}, - {"SIOCSIFPHYS", Const, 0}, - {"SIOCSIFPRIORITY", Const, 1}, - {"SIOCSIFRDOMAIN", Const, 1}, - {"SIOCSIFRTLABEL", Const, 1}, - {"SIOCSIFRVNET", Const, 0}, - {"SIOCSIFSLAVE", Const, 0}, - {"SIOCSIFTIMESLOT", Const, 1}, - {"SIOCSIFTXQLEN", Const, 0}, - {"SIOCSIFVLAN", Const, 0}, - {"SIOCSIFVNET", Const, 0}, - {"SIOCSIFXFLAGS", Const, 1}, - {"SIOCSLIFPHYADDR", Const, 0}, - {"SIOCSLIFPHYRTABLE", Const, 1}, - {"SIOCSLIFPHYTTL", Const, 3}, - {"SIOCSLINKSTR", Const, 1}, - {"SIOCSLOWAT", Const, 0}, - {"SIOCSPGRP", Const, 0}, - {"SIOCSRARP", Const, 0}, - {"SIOCSSPPPPARAMS", Const, 3}, - {"SIOCSVH", Const, 1}, - {"SIOCSVNETID", Const, 3}, - {"SIOCZIFDATA", Const, 1}, - {"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1}, - {"SIO_GET_INTERFACE_LIST", Const, 0}, - {"SIO_KEEPALIVE_VALS", Const, 3}, - {"SIO_UDP_CONNRESET", Const, 4}, - {"SOCK_CLOEXEC", Const, 0}, - {"SOCK_DCCP", Const, 0}, - {"SOCK_DGRAM", Const, 0}, - {"SOCK_FLAGS_MASK", Const, 1}, - {"SOCK_MAXADDRLEN", Const, 0}, - {"SOCK_NONBLOCK", Const, 0}, - {"SOCK_NOSIGPIPE", Const, 1}, - {"SOCK_PACKET", Const, 0}, - {"SOCK_RAW", Const, 0}, - {"SOCK_RDM", Const, 0}, - {"SOCK_SEQPACKET", Const, 0}, - {"SOCK_STREAM", Const, 0}, - {"SOL_AAL", Const, 0}, - {"SOL_ATM", Const, 0}, - {"SOL_DECNET", Const, 0}, - {"SOL_ICMPV6", Const, 0}, - {"SOL_IP", Const, 0}, - {"SOL_IPV6", Const, 0}, - {"SOL_IRDA", Const, 0}, - {"SOL_PACKET", Const, 0}, - {"SOL_RAW", Const, 0}, - {"SOL_SOCKET", Const, 0}, - {"SOL_TCP", Const, 0}, - {"SOL_X25", Const, 0}, - {"SOMAXCONN", Const, 0}, - {"SO_ACCEPTCONN", Const, 0}, - {"SO_ACCEPTFILTER", Const, 0}, - {"SO_ATTACH_FILTER", Const, 0}, - {"SO_BINDANY", Const, 1}, - {"SO_BINDTODEVICE", Const, 0}, - {"SO_BINTIME", Const, 0}, - {"SO_BROADCAST", Const, 0}, - {"SO_BSDCOMPAT", Const, 0}, - {"SO_DEBUG", Const, 0}, - {"SO_DETACH_FILTER", Const, 0}, - {"SO_DOMAIN", Const, 0}, - {"SO_DONTROUTE", Const, 0}, - {"SO_DONTTRUNC", Const, 0}, - {"SO_ERROR", Const, 0}, - {"SO_KEEPALIVE", Const, 0}, - {"SO_LABEL", Const, 0}, - {"SO_LINGER", Const, 0}, - {"SO_LINGER_SEC", Const, 0}, - {"SO_LISTENINCQLEN", Const, 0}, - {"SO_LISTENQLEN", Const, 0}, - {"SO_LISTENQLIMIT", Const, 0}, - {"SO_MARK", Const, 0}, - {"SO_NETPROC", Const, 1}, - {"SO_NKE", Const, 0}, - {"SO_NOADDRERR", Const, 0}, - {"SO_NOHEADER", Const, 1}, - {"SO_NOSIGPIPE", Const, 0}, - {"SO_NOTIFYCONFLICT", Const, 0}, - {"SO_NO_CHECK", Const, 0}, - {"SO_NO_DDP", Const, 0}, - {"SO_NO_OFFLOAD", Const, 0}, - {"SO_NP_EXTENSIONS", Const, 0}, - {"SO_NREAD", Const, 0}, - {"SO_NUMRCVPKT", Const, 16}, - {"SO_NWRITE", Const, 0}, - {"SO_OOBINLINE", Const, 0}, - {"SO_OVERFLOWED", Const, 1}, - {"SO_PASSCRED", Const, 0}, - {"SO_PASSSEC", Const, 0}, - {"SO_PEERCRED", Const, 0}, - {"SO_PEERLABEL", Const, 0}, - {"SO_PEERNAME", Const, 0}, - {"SO_PEERSEC", Const, 0}, - {"SO_PRIORITY", Const, 0}, - {"SO_PROTOCOL", Const, 0}, - {"SO_PROTOTYPE", Const, 1}, - {"SO_RANDOMPORT", Const, 0}, - {"SO_RCVBUF", Const, 0}, - {"SO_RCVBUFFORCE", Const, 0}, - {"SO_RCVLOWAT", Const, 0}, - {"SO_RCVTIMEO", Const, 0}, - {"SO_RESTRICTIONS", Const, 0}, - {"SO_RESTRICT_DENYIN", Const, 0}, - {"SO_RESTRICT_DENYOUT", Const, 0}, - {"SO_RESTRICT_DENYSET", Const, 0}, - {"SO_REUSEADDR", Const, 0}, - {"SO_REUSEPORT", Const, 0}, - {"SO_REUSESHAREUID", Const, 0}, - {"SO_RTABLE", Const, 1}, - {"SO_RXQ_OVFL", Const, 0}, - {"SO_SECURITY_AUTHENTICATION", Const, 0}, - {"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0}, - {"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0}, - {"SO_SETFIB", Const, 0}, - {"SO_SNDBUF", Const, 0}, - {"SO_SNDBUFFORCE", Const, 0}, - {"SO_SNDLOWAT", Const, 0}, - {"SO_SNDTIMEO", Const, 0}, - {"SO_SPLICE", Const, 1}, - {"SO_TIMESTAMP", Const, 0}, - {"SO_TIMESTAMPING", Const, 0}, - {"SO_TIMESTAMPNS", Const, 0}, - {"SO_TIMESTAMP_MONOTONIC", Const, 0}, - {"SO_TYPE", Const, 0}, - {"SO_UPCALLCLOSEWAIT", Const, 0}, - {"SO_UPDATE_ACCEPT_CONTEXT", Const, 0}, - {"SO_UPDATE_CONNECT_CONTEXT", Const, 1}, - {"SO_USELOOPBACK", Const, 0}, - {"SO_USER_COOKIE", Const, 1}, - {"SO_VENDOR", Const, 3}, - {"SO_WANTMORE", Const, 0}, - {"SO_WANTOOBFLAG", Const, 0}, - {"SSLExtraCertChainPolicyPara", Type, 0}, - {"SSLExtraCertChainPolicyPara.AuthType", Field, 0}, - {"SSLExtraCertChainPolicyPara.Checks", Field, 0}, - {"SSLExtraCertChainPolicyPara.ServerName", Field, 0}, - {"SSLExtraCertChainPolicyPara.Size", Field, 0}, - {"STANDARD_RIGHTS_ALL", Const, 0}, - {"STANDARD_RIGHTS_EXECUTE", Const, 0}, - {"STANDARD_RIGHTS_READ", Const, 0}, - {"STANDARD_RIGHTS_REQUIRED", Const, 0}, - {"STANDARD_RIGHTS_WRITE", Const, 0}, - {"STARTF_USESHOWWINDOW", Const, 0}, - {"STARTF_USESTDHANDLES", Const, 0}, - {"STD_ERROR_HANDLE", Const, 0}, - {"STD_INPUT_HANDLE", Const, 0}, - {"STD_OUTPUT_HANDLE", Const, 0}, - {"SUBLANG_ENGLISH_US", Const, 0}, - {"SW_FORCEMINIMIZE", Const, 0}, - {"SW_HIDE", Const, 0}, - {"SW_MAXIMIZE", Const, 0}, - {"SW_MINIMIZE", Const, 0}, - {"SW_NORMAL", Const, 0}, - {"SW_RESTORE", Const, 0}, - {"SW_SHOW", Const, 0}, - {"SW_SHOWDEFAULT", Const, 0}, - {"SW_SHOWMAXIMIZED", Const, 0}, - {"SW_SHOWMINIMIZED", Const, 0}, - {"SW_SHOWMINNOACTIVE", Const, 0}, - {"SW_SHOWNA", Const, 0}, - {"SW_SHOWNOACTIVATE", Const, 0}, - {"SW_SHOWNORMAL", Const, 0}, - {"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4}, - {"SYNCHRONIZE", Const, 0}, - {"SYSCTL_VERSION", Const, 1}, - {"SYSCTL_VERS_0", Const, 1}, - {"SYSCTL_VERS_1", Const, 1}, - {"SYSCTL_VERS_MASK", Const, 1}, - {"SYS_ABORT2", Const, 0}, - {"SYS_ACCEPT", Const, 0}, - {"SYS_ACCEPT4", Const, 0}, - {"SYS_ACCEPT_NOCANCEL", Const, 0}, - {"SYS_ACCESS", Const, 0}, - {"SYS_ACCESS_EXTENDED", Const, 0}, - {"SYS_ACCT", Const, 0}, - {"SYS_ADD_KEY", Const, 0}, - {"SYS_ADD_PROFIL", Const, 0}, - {"SYS_ADJFREQ", Const, 1}, - {"SYS_ADJTIME", Const, 0}, - {"SYS_ADJTIMEX", Const, 0}, - {"SYS_AFS_SYSCALL", Const, 0}, - {"SYS_AIO_CANCEL", Const, 0}, - {"SYS_AIO_ERROR", Const, 0}, - {"SYS_AIO_FSYNC", Const, 0}, - {"SYS_AIO_MLOCK", Const, 14}, - {"SYS_AIO_READ", Const, 0}, - {"SYS_AIO_RETURN", Const, 0}, - {"SYS_AIO_SUSPEND", Const, 0}, - {"SYS_AIO_SUSPEND_NOCANCEL", Const, 0}, - {"SYS_AIO_WAITCOMPLETE", Const, 14}, - {"SYS_AIO_WRITE", Const, 0}, - {"SYS_ALARM", Const, 0}, - {"SYS_ARCH_PRCTL", Const, 0}, - {"SYS_ARM_FADVISE64_64", Const, 0}, - {"SYS_ARM_SYNC_FILE_RANGE", Const, 0}, - {"SYS_ATGETMSG", Const, 0}, - {"SYS_ATPGETREQ", Const, 0}, - {"SYS_ATPGETRSP", Const, 0}, - {"SYS_ATPSNDREQ", Const, 0}, - {"SYS_ATPSNDRSP", Const, 0}, - {"SYS_ATPUTMSG", Const, 0}, - {"SYS_ATSOCKET", Const, 0}, - {"SYS_AUDIT", Const, 0}, - {"SYS_AUDITCTL", Const, 0}, - {"SYS_AUDITON", Const, 0}, - {"SYS_AUDIT_SESSION_JOIN", Const, 0}, - {"SYS_AUDIT_SESSION_PORT", Const, 0}, - {"SYS_AUDIT_SESSION_SELF", Const, 0}, - {"SYS_BDFLUSH", Const, 0}, - {"SYS_BIND", Const, 0}, - {"SYS_BINDAT", Const, 3}, - {"SYS_BREAK", Const, 0}, - {"SYS_BRK", Const, 0}, - {"SYS_BSDTHREAD_CREATE", Const, 0}, - {"SYS_BSDTHREAD_REGISTER", Const, 0}, - {"SYS_BSDTHREAD_TERMINATE", Const, 0}, - {"SYS_CAPGET", Const, 0}, - {"SYS_CAPSET", Const, 0}, - {"SYS_CAP_ENTER", Const, 0}, - {"SYS_CAP_FCNTLS_GET", Const, 1}, - {"SYS_CAP_FCNTLS_LIMIT", Const, 1}, - {"SYS_CAP_GETMODE", Const, 0}, - {"SYS_CAP_GETRIGHTS", Const, 0}, - {"SYS_CAP_IOCTLS_GET", Const, 1}, - {"SYS_CAP_IOCTLS_LIMIT", Const, 1}, - {"SYS_CAP_NEW", Const, 0}, - {"SYS_CAP_RIGHTS_GET", Const, 1}, - {"SYS_CAP_RIGHTS_LIMIT", Const, 1}, - {"SYS_CHDIR", Const, 0}, - {"SYS_CHFLAGS", Const, 0}, - {"SYS_CHFLAGSAT", Const, 3}, - {"SYS_CHMOD", Const, 0}, - {"SYS_CHMOD_EXTENDED", Const, 0}, - {"SYS_CHOWN", Const, 0}, - {"SYS_CHOWN32", Const, 0}, - {"SYS_CHROOT", Const, 0}, - {"SYS_CHUD", Const, 0}, - {"SYS_CLOCK_ADJTIME", Const, 0}, - {"SYS_CLOCK_GETCPUCLOCKID2", Const, 1}, - {"SYS_CLOCK_GETRES", Const, 0}, - {"SYS_CLOCK_GETTIME", Const, 0}, - {"SYS_CLOCK_NANOSLEEP", Const, 0}, - {"SYS_CLOCK_SETTIME", Const, 0}, - {"SYS_CLONE", Const, 0}, - {"SYS_CLOSE", Const, 0}, - {"SYS_CLOSEFROM", Const, 0}, - {"SYS_CLOSE_NOCANCEL", Const, 0}, - {"SYS_CONNECT", Const, 0}, - {"SYS_CONNECTAT", Const, 3}, - {"SYS_CONNECT_NOCANCEL", Const, 0}, - {"SYS_COPYFILE", Const, 0}, - {"SYS_CPUSET", Const, 0}, - {"SYS_CPUSET_GETAFFINITY", Const, 0}, - {"SYS_CPUSET_GETID", Const, 0}, - {"SYS_CPUSET_SETAFFINITY", Const, 0}, - {"SYS_CPUSET_SETID", Const, 0}, - {"SYS_CREAT", Const, 0}, - {"SYS_CREATE_MODULE", Const, 0}, - {"SYS_CSOPS", Const, 0}, - {"SYS_CSOPS_AUDITTOKEN", Const, 16}, - {"SYS_DELETE", Const, 0}, - {"SYS_DELETE_MODULE", Const, 0}, - {"SYS_DUP", Const, 0}, - {"SYS_DUP2", Const, 0}, - {"SYS_DUP3", Const, 0}, - {"SYS_EACCESS", Const, 0}, - {"SYS_EPOLL_CREATE", Const, 0}, - {"SYS_EPOLL_CREATE1", Const, 0}, - {"SYS_EPOLL_CTL", Const, 0}, - {"SYS_EPOLL_CTL_OLD", Const, 0}, - {"SYS_EPOLL_PWAIT", Const, 0}, - {"SYS_EPOLL_WAIT", Const, 0}, - {"SYS_EPOLL_WAIT_OLD", Const, 0}, - {"SYS_EVENTFD", Const, 0}, - {"SYS_EVENTFD2", Const, 0}, - {"SYS_EXCHANGEDATA", Const, 0}, - {"SYS_EXECVE", Const, 0}, - {"SYS_EXIT", Const, 0}, - {"SYS_EXIT_GROUP", Const, 0}, - {"SYS_EXTATTRCTL", Const, 0}, - {"SYS_EXTATTR_DELETE_FD", Const, 0}, - {"SYS_EXTATTR_DELETE_FILE", Const, 0}, - {"SYS_EXTATTR_DELETE_LINK", Const, 0}, - {"SYS_EXTATTR_GET_FD", Const, 0}, - {"SYS_EXTATTR_GET_FILE", Const, 0}, - {"SYS_EXTATTR_GET_LINK", Const, 0}, - {"SYS_EXTATTR_LIST_FD", Const, 0}, - {"SYS_EXTATTR_LIST_FILE", Const, 0}, - {"SYS_EXTATTR_LIST_LINK", Const, 0}, - {"SYS_EXTATTR_SET_FD", Const, 0}, - {"SYS_EXTATTR_SET_FILE", Const, 0}, - {"SYS_EXTATTR_SET_LINK", Const, 0}, - {"SYS_FACCESSAT", Const, 0}, - {"SYS_FADVISE64", Const, 0}, - {"SYS_FADVISE64_64", Const, 0}, - {"SYS_FALLOCATE", Const, 0}, - {"SYS_FANOTIFY_INIT", Const, 0}, - {"SYS_FANOTIFY_MARK", Const, 0}, - {"SYS_FCHDIR", Const, 0}, - {"SYS_FCHFLAGS", Const, 0}, - {"SYS_FCHMOD", Const, 0}, - {"SYS_FCHMODAT", Const, 0}, - {"SYS_FCHMOD_EXTENDED", Const, 0}, - {"SYS_FCHOWN", Const, 0}, - {"SYS_FCHOWN32", Const, 0}, - {"SYS_FCHOWNAT", Const, 0}, - {"SYS_FCHROOT", Const, 1}, - {"SYS_FCNTL", Const, 0}, - {"SYS_FCNTL64", Const, 0}, - {"SYS_FCNTL_NOCANCEL", Const, 0}, - {"SYS_FDATASYNC", Const, 0}, - {"SYS_FEXECVE", Const, 0}, - {"SYS_FFCLOCK_GETCOUNTER", Const, 0}, - {"SYS_FFCLOCK_GETESTIMATE", Const, 0}, - {"SYS_FFCLOCK_SETESTIMATE", Const, 0}, - {"SYS_FFSCTL", Const, 0}, - {"SYS_FGETATTRLIST", Const, 0}, - {"SYS_FGETXATTR", Const, 0}, - {"SYS_FHOPEN", Const, 0}, - {"SYS_FHSTAT", Const, 0}, - {"SYS_FHSTATFS", Const, 0}, - {"SYS_FILEPORT_MAKEFD", Const, 0}, - {"SYS_FILEPORT_MAKEPORT", Const, 0}, - {"SYS_FKTRACE", Const, 1}, - {"SYS_FLISTXATTR", Const, 0}, - {"SYS_FLOCK", Const, 0}, - {"SYS_FORK", Const, 0}, - {"SYS_FPATHCONF", Const, 0}, - {"SYS_FREEBSD6_FTRUNCATE", Const, 0}, - {"SYS_FREEBSD6_LSEEK", Const, 0}, - {"SYS_FREEBSD6_MMAP", Const, 0}, - {"SYS_FREEBSD6_PREAD", Const, 0}, - {"SYS_FREEBSD6_PWRITE", Const, 0}, - {"SYS_FREEBSD6_TRUNCATE", Const, 0}, - {"SYS_FREMOVEXATTR", Const, 0}, - {"SYS_FSCTL", Const, 0}, - {"SYS_FSETATTRLIST", Const, 0}, - {"SYS_FSETXATTR", Const, 0}, - {"SYS_FSGETPATH", Const, 0}, - {"SYS_FSTAT", Const, 0}, - {"SYS_FSTAT64", Const, 0}, - {"SYS_FSTAT64_EXTENDED", Const, 0}, - {"SYS_FSTATAT", Const, 0}, - {"SYS_FSTATAT64", Const, 0}, - {"SYS_FSTATFS", Const, 0}, - {"SYS_FSTATFS64", Const, 0}, - {"SYS_FSTATV", Const, 0}, - {"SYS_FSTATVFS1", Const, 1}, - {"SYS_FSTAT_EXTENDED", Const, 0}, - {"SYS_FSYNC", Const, 0}, - {"SYS_FSYNC_NOCANCEL", Const, 0}, - {"SYS_FSYNC_RANGE", Const, 1}, - {"SYS_FTIME", Const, 0}, - {"SYS_FTRUNCATE", Const, 0}, - {"SYS_FTRUNCATE64", Const, 0}, - {"SYS_FUTEX", Const, 0}, - {"SYS_FUTIMENS", Const, 1}, - {"SYS_FUTIMES", Const, 0}, - {"SYS_FUTIMESAT", Const, 0}, - {"SYS_GETATTRLIST", Const, 0}, - {"SYS_GETAUDIT", Const, 0}, - {"SYS_GETAUDIT_ADDR", Const, 0}, - {"SYS_GETAUID", Const, 0}, - {"SYS_GETCONTEXT", Const, 0}, - {"SYS_GETCPU", Const, 0}, - {"SYS_GETCWD", Const, 0}, - {"SYS_GETDENTS", Const, 0}, - {"SYS_GETDENTS64", Const, 0}, - {"SYS_GETDIRENTRIES", Const, 0}, - {"SYS_GETDIRENTRIES64", Const, 0}, - {"SYS_GETDIRENTRIESATTR", Const, 0}, - {"SYS_GETDTABLECOUNT", Const, 1}, - {"SYS_GETDTABLESIZE", Const, 0}, - {"SYS_GETEGID", Const, 0}, - {"SYS_GETEGID32", Const, 0}, - {"SYS_GETEUID", Const, 0}, - {"SYS_GETEUID32", Const, 0}, - {"SYS_GETFH", Const, 0}, - {"SYS_GETFSSTAT", Const, 0}, - {"SYS_GETFSSTAT64", Const, 0}, - {"SYS_GETGID", Const, 0}, - {"SYS_GETGID32", Const, 0}, - {"SYS_GETGROUPS", Const, 0}, - {"SYS_GETGROUPS32", Const, 0}, - {"SYS_GETHOSTUUID", Const, 0}, - {"SYS_GETITIMER", Const, 0}, - {"SYS_GETLCID", Const, 0}, - {"SYS_GETLOGIN", Const, 0}, - {"SYS_GETLOGINCLASS", Const, 0}, - {"SYS_GETPEERNAME", Const, 0}, - {"SYS_GETPGID", Const, 0}, - {"SYS_GETPGRP", Const, 0}, - {"SYS_GETPID", Const, 0}, - {"SYS_GETPMSG", Const, 0}, - {"SYS_GETPPID", Const, 0}, - {"SYS_GETPRIORITY", Const, 0}, - {"SYS_GETRESGID", Const, 0}, - {"SYS_GETRESGID32", Const, 0}, - {"SYS_GETRESUID", Const, 0}, - {"SYS_GETRESUID32", Const, 0}, - {"SYS_GETRLIMIT", Const, 0}, - {"SYS_GETRTABLE", Const, 1}, - {"SYS_GETRUSAGE", Const, 0}, - {"SYS_GETSGROUPS", Const, 0}, - {"SYS_GETSID", Const, 0}, - {"SYS_GETSOCKNAME", Const, 0}, - {"SYS_GETSOCKOPT", Const, 0}, - {"SYS_GETTHRID", Const, 1}, - {"SYS_GETTID", Const, 0}, - {"SYS_GETTIMEOFDAY", Const, 0}, - {"SYS_GETUID", Const, 0}, - {"SYS_GETUID32", Const, 0}, - {"SYS_GETVFSSTAT", Const, 1}, - {"SYS_GETWGROUPS", Const, 0}, - {"SYS_GETXATTR", Const, 0}, - {"SYS_GET_KERNEL_SYMS", Const, 0}, - {"SYS_GET_MEMPOLICY", Const, 0}, - {"SYS_GET_ROBUST_LIST", Const, 0}, - {"SYS_GET_THREAD_AREA", Const, 0}, - {"SYS_GSSD_SYSCALL", Const, 14}, - {"SYS_GTTY", Const, 0}, - {"SYS_IDENTITYSVC", Const, 0}, - {"SYS_IDLE", Const, 0}, - {"SYS_INITGROUPS", Const, 0}, - {"SYS_INIT_MODULE", Const, 0}, - {"SYS_INOTIFY_ADD_WATCH", Const, 0}, - {"SYS_INOTIFY_INIT", Const, 0}, - {"SYS_INOTIFY_INIT1", Const, 0}, - {"SYS_INOTIFY_RM_WATCH", Const, 0}, - {"SYS_IOCTL", Const, 0}, - {"SYS_IOPERM", Const, 0}, - {"SYS_IOPL", Const, 0}, - {"SYS_IOPOLICYSYS", Const, 0}, - {"SYS_IOPRIO_GET", Const, 0}, - {"SYS_IOPRIO_SET", Const, 0}, - {"SYS_IO_CANCEL", Const, 0}, - {"SYS_IO_DESTROY", Const, 0}, - {"SYS_IO_GETEVENTS", Const, 0}, - {"SYS_IO_SETUP", Const, 0}, - {"SYS_IO_SUBMIT", Const, 0}, - {"SYS_IPC", Const, 0}, - {"SYS_ISSETUGID", Const, 0}, - {"SYS_JAIL", Const, 0}, - {"SYS_JAIL_ATTACH", Const, 0}, - {"SYS_JAIL_GET", Const, 0}, - {"SYS_JAIL_REMOVE", Const, 0}, - {"SYS_JAIL_SET", Const, 0}, - {"SYS_KAS_INFO", Const, 16}, - {"SYS_KDEBUG_TRACE", Const, 0}, - {"SYS_KENV", Const, 0}, - {"SYS_KEVENT", Const, 0}, - {"SYS_KEVENT64", Const, 0}, - {"SYS_KEXEC_LOAD", Const, 0}, - {"SYS_KEYCTL", Const, 0}, - {"SYS_KILL", Const, 0}, - {"SYS_KLDFIND", Const, 0}, - {"SYS_KLDFIRSTMOD", Const, 0}, - {"SYS_KLDLOAD", Const, 0}, - {"SYS_KLDNEXT", Const, 0}, - {"SYS_KLDSTAT", Const, 0}, - {"SYS_KLDSYM", Const, 0}, - {"SYS_KLDUNLOAD", Const, 0}, - {"SYS_KLDUNLOADF", Const, 0}, - {"SYS_KMQ_NOTIFY", Const, 14}, - {"SYS_KMQ_OPEN", Const, 14}, - {"SYS_KMQ_SETATTR", Const, 14}, - {"SYS_KMQ_TIMEDRECEIVE", Const, 14}, - {"SYS_KMQ_TIMEDSEND", Const, 14}, - {"SYS_KMQ_UNLINK", Const, 14}, - {"SYS_KQUEUE", Const, 0}, - {"SYS_KQUEUE1", Const, 1}, - {"SYS_KSEM_CLOSE", Const, 14}, - {"SYS_KSEM_DESTROY", Const, 14}, - {"SYS_KSEM_GETVALUE", Const, 14}, - {"SYS_KSEM_INIT", Const, 14}, - {"SYS_KSEM_OPEN", Const, 14}, - {"SYS_KSEM_POST", Const, 14}, - {"SYS_KSEM_TIMEDWAIT", Const, 14}, - {"SYS_KSEM_TRYWAIT", Const, 14}, - {"SYS_KSEM_UNLINK", Const, 14}, - {"SYS_KSEM_WAIT", Const, 14}, - {"SYS_KTIMER_CREATE", Const, 0}, - {"SYS_KTIMER_DELETE", Const, 0}, - {"SYS_KTIMER_GETOVERRUN", Const, 0}, - {"SYS_KTIMER_GETTIME", Const, 0}, - {"SYS_KTIMER_SETTIME", Const, 0}, - {"SYS_KTRACE", Const, 0}, - {"SYS_LCHFLAGS", Const, 0}, - {"SYS_LCHMOD", Const, 0}, - {"SYS_LCHOWN", Const, 0}, - {"SYS_LCHOWN32", Const, 0}, - {"SYS_LEDGER", Const, 16}, - {"SYS_LGETFH", Const, 0}, - {"SYS_LGETXATTR", Const, 0}, - {"SYS_LINK", Const, 0}, - {"SYS_LINKAT", Const, 0}, - {"SYS_LIO_LISTIO", Const, 0}, - {"SYS_LISTEN", Const, 0}, - {"SYS_LISTXATTR", Const, 0}, - {"SYS_LLISTXATTR", Const, 0}, - {"SYS_LOCK", Const, 0}, - {"SYS_LOOKUP_DCOOKIE", Const, 0}, - {"SYS_LPATHCONF", Const, 0}, - {"SYS_LREMOVEXATTR", Const, 0}, - {"SYS_LSEEK", Const, 0}, - {"SYS_LSETXATTR", Const, 0}, - {"SYS_LSTAT", Const, 0}, - {"SYS_LSTAT64", Const, 0}, - {"SYS_LSTAT64_EXTENDED", Const, 0}, - {"SYS_LSTATV", Const, 0}, - {"SYS_LSTAT_EXTENDED", Const, 0}, - {"SYS_LUTIMES", Const, 0}, - {"SYS_MAC_SYSCALL", Const, 0}, - {"SYS_MADVISE", Const, 0}, - {"SYS_MADVISE1", Const, 0}, - {"SYS_MAXSYSCALL", Const, 0}, - {"SYS_MBIND", Const, 0}, - {"SYS_MIGRATE_PAGES", Const, 0}, - {"SYS_MINCORE", Const, 0}, - {"SYS_MINHERIT", Const, 0}, - {"SYS_MKCOMPLEX", Const, 0}, - {"SYS_MKDIR", Const, 0}, - {"SYS_MKDIRAT", Const, 0}, - {"SYS_MKDIR_EXTENDED", Const, 0}, - {"SYS_MKFIFO", Const, 0}, - {"SYS_MKFIFOAT", Const, 0}, - {"SYS_MKFIFO_EXTENDED", Const, 0}, - {"SYS_MKNOD", Const, 0}, - {"SYS_MKNODAT", Const, 0}, - {"SYS_MLOCK", Const, 0}, - {"SYS_MLOCKALL", Const, 0}, - {"SYS_MMAP", Const, 0}, - {"SYS_MMAP2", Const, 0}, - {"SYS_MODCTL", Const, 1}, - {"SYS_MODFIND", Const, 0}, - {"SYS_MODFNEXT", Const, 0}, - {"SYS_MODIFY_LDT", Const, 0}, - {"SYS_MODNEXT", Const, 0}, - {"SYS_MODSTAT", Const, 0}, - {"SYS_MODWATCH", Const, 0}, - {"SYS_MOUNT", Const, 0}, - {"SYS_MOVE_PAGES", Const, 0}, - {"SYS_MPROTECT", Const, 0}, - {"SYS_MPX", Const, 0}, - {"SYS_MQUERY", Const, 1}, - {"SYS_MQ_GETSETATTR", Const, 0}, - {"SYS_MQ_NOTIFY", Const, 0}, - {"SYS_MQ_OPEN", Const, 0}, - {"SYS_MQ_TIMEDRECEIVE", Const, 0}, - {"SYS_MQ_TIMEDSEND", Const, 0}, - {"SYS_MQ_UNLINK", Const, 0}, - {"SYS_MREMAP", Const, 0}, - {"SYS_MSGCTL", Const, 0}, - {"SYS_MSGGET", Const, 0}, - {"SYS_MSGRCV", Const, 0}, - {"SYS_MSGRCV_NOCANCEL", Const, 0}, - {"SYS_MSGSND", Const, 0}, - {"SYS_MSGSND_NOCANCEL", Const, 0}, - {"SYS_MSGSYS", Const, 0}, - {"SYS_MSYNC", Const, 0}, - {"SYS_MSYNC_NOCANCEL", Const, 0}, - {"SYS_MUNLOCK", Const, 0}, - {"SYS_MUNLOCKALL", Const, 0}, - {"SYS_MUNMAP", Const, 0}, - {"SYS_NAME_TO_HANDLE_AT", Const, 0}, - {"SYS_NANOSLEEP", Const, 0}, - {"SYS_NEWFSTATAT", Const, 0}, - {"SYS_NFSCLNT", Const, 0}, - {"SYS_NFSSERVCTL", Const, 0}, - {"SYS_NFSSVC", Const, 0}, - {"SYS_NFSTAT", Const, 0}, - {"SYS_NICE", Const, 0}, - {"SYS_NLM_SYSCALL", Const, 14}, - {"SYS_NLSTAT", Const, 0}, - {"SYS_NMOUNT", Const, 0}, - {"SYS_NSTAT", Const, 0}, - {"SYS_NTP_ADJTIME", Const, 0}, - {"SYS_NTP_GETTIME", Const, 0}, - {"SYS_NUMA_GETAFFINITY", Const, 14}, - {"SYS_NUMA_SETAFFINITY", Const, 14}, - {"SYS_OABI_SYSCALL_BASE", Const, 0}, - {"SYS_OBREAK", Const, 0}, - {"SYS_OLDFSTAT", Const, 0}, - {"SYS_OLDLSTAT", Const, 0}, - {"SYS_OLDOLDUNAME", Const, 0}, - {"SYS_OLDSTAT", Const, 0}, - {"SYS_OLDUNAME", Const, 0}, - {"SYS_OPEN", Const, 0}, - {"SYS_OPENAT", Const, 0}, - {"SYS_OPENBSD_POLL", Const, 0}, - {"SYS_OPEN_BY_HANDLE_AT", Const, 0}, - {"SYS_OPEN_DPROTECTED_NP", Const, 16}, - {"SYS_OPEN_EXTENDED", Const, 0}, - {"SYS_OPEN_NOCANCEL", Const, 0}, - {"SYS_OVADVISE", Const, 0}, - {"SYS_PACCEPT", Const, 1}, - {"SYS_PATHCONF", Const, 0}, - {"SYS_PAUSE", Const, 0}, - {"SYS_PCICONFIG_IOBASE", Const, 0}, - {"SYS_PCICONFIG_READ", Const, 0}, - {"SYS_PCICONFIG_WRITE", Const, 0}, - {"SYS_PDFORK", Const, 0}, - {"SYS_PDGETPID", Const, 0}, - {"SYS_PDKILL", Const, 0}, - {"SYS_PERF_EVENT_OPEN", Const, 0}, - {"SYS_PERSONALITY", Const, 0}, - {"SYS_PID_HIBERNATE", Const, 0}, - {"SYS_PID_RESUME", Const, 0}, - {"SYS_PID_SHUTDOWN_SOCKETS", Const, 0}, - {"SYS_PID_SUSPEND", Const, 0}, - {"SYS_PIPE", Const, 0}, - {"SYS_PIPE2", Const, 0}, - {"SYS_PIVOT_ROOT", Const, 0}, - {"SYS_PMC_CONTROL", Const, 1}, - {"SYS_PMC_GET_INFO", Const, 1}, - {"SYS_POLL", Const, 0}, - {"SYS_POLLTS", Const, 1}, - {"SYS_POLL_NOCANCEL", Const, 0}, - {"SYS_POSIX_FADVISE", Const, 0}, - {"SYS_POSIX_FALLOCATE", Const, 0}, - {"SYS_POSIX_OPENPT", Const, 0}, - {"SYS_POSIX_SPAWN", Const, 0}, - {"SYS_PPOLL", Const, 0}, - {"SYS_PRCTL", Const, 0}, - {"SYS_PREAD", Const, 0}, - {"SYS_PREAD64", Const, 0}, - {"SYS_PREADV", Const, 0}, - {"SYS_PREAD_NOCANCEL", Const, 0}, - {"SYS_PRLIMIT64", Const, 0}, - {"SYS_PROCCTL", Const, 3}, - {"SYS_PROCESS_POLICY", Const, 0}, - {"SYS_PROCESS_VM_READV", Const, 0}, - {"SYS_PROCESS_VM_WRITEV", Const, 0}, - {"SYS_PROC_INFO", Const, 0}, - {"SYS_PROF", Const, 0}, - {"SYS_PROFIL", Const, 0}, - {"SYS_PSELECT", Const, 0}, - {"SYS_PSELECT6", Const, 0}, - {"SYS_PSET_ASSIGN", Const, 1}, - {"SYS_PSET_CREATE", Const, 1}, - {"SYS_PSET_DESTROY", Const, 1}, - {"SYS_PSYNCH_CVBROAD", Const, 0}, - {"SYS_PSYNCH_CVCLRPREPOST", Const, 0}, - {"SYS_PSYNCH_CVSIGNAL", Const, 0}, - {"SYS_PSYNCH_CVWAIT", Const, 0}, - {"SYS_PSYNCH_MUTEXDROP", Const, 0}, - {"SYS_PSYNCH_MUTEXWAIT", Const, 0}, - {"SYS_PSYNCH_RW_DOWNGRADE", Const, 0}, - {"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0}, - {"SYS_PSYNCH_RW_RDLOCK", Const, 0}, - {"SYS_PSYNCH_RW_UNLOCK", Const, 0}, - {"SYS_PSYNCH_RW_UNLOCK2", Const, 0}, - {"SYS_PSYNCH_RW_UPGRADE", Const, 0}, - {"SYS_PSYNCH_RW_WRLOCK", Const, 0}, - {"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0}, - {"SYS_PTRACE", Const, 0}, - {"SYS_PUTPMSG", Const, 0}, - {"SYS_PWRITE", Const, 0}, - {"SYS_PWRITE64", Const, 0}, - {"SYS_PWRITEV", Const, 0}, - {"SYS_PWRITE_NOCANCEL", Const, 0}, - {"SYS_QUERY_MODULE", Const, 0}, - {"SYS_QUOTACTL", Const, 0}, - {"SYS_RASCTL", Const, 1}, - {"SYS_RCTL_ADD_RULE", Const, 0}, - {"SYS_RCTL_GET_LIMITS", Const, 0}, - {"SYS_RCTL_GET_RACCT", Const, 0}, - {"SYS_RCTL_GET_RULES", Const, 0}, - {"SYS_RCTL_REMOVE_RULE", Const, 0}, - {"SYS_READ", Const, 0}, - {"SYS_READAHEAD", Const, 0}, - {"SYS_READDIR", Const, 0}, - {"SYS_READLINK", Const, 0}, - {"SYS_READLINKAT", Const, 0}, - {"SYS_READV", Const, 0}, - {"SYS_READV_NOCANCEL", Const, 0}, - {"SYS_READ_NOCANCEL", Const, 0}, - {"SYS_REBOOT", Const, 0}, - {"SYS_RECV", Const, 0}, - {"SYS_RECVFROM", Const, 0}, - {"SYS_RECVFROM_NOCANCEL", Const, 0}, - {"SYS_RECVMMSG", Const, 0}, - {"SYS_RECVMSG", Const, 0}, - {"SYS_RECVMSG_NOCANCEL", Const, 0}, - {"SYS_REMAP_FILE_PAGES", Const, 0}, - {"SYS_REMOVEXATTR", Const, 0}, - {"SYS_RENAME", Const, 0}, - {"SYS_RENAMEAT", Const, 0}, - {"SYS_REQUEST_KEY", Const, 0}, - {"SYS_RESTART_SYSCALL", Const, 0}, - {"SYS_REVOKE", Const, 0}, - {"SYS_RFORK", Const, 0}, - {"SYS_RMDIR", Const, 0}, - {"SYS_RTPRIO", Const, 0}, - {"SYS_RTPRIO_THREAD", Const, 0}, - {"SYS_RT_SIGACTION", Const, 0}, - {"SYS_RT_SIGPENDING", Const, 0}, - {"SYS_RT_SIGPROCMASK", Const, 0}, - {"SYS_RT_SIGQUEUEINFO", Const, 0}, - {"SYS_RT_SIGRETURN", Const, 0}, - {"SYS_RT_SIGSUSPEND", Const, 0}, - {"SYS_RT_SIGTIMEDWAIT", Const, 0}, - {"SYS_RT_TGSIGQUEUEINFO", Const, 0}, - {"SYS_SBRK", Const, 0}, - {"SYS_SCHED_GETAFFINITY", Const, 0}, - {"SYS_SCHED_GETPARAM", Const, 0}, - {"SYS_SCHED_GETSCHEDULER", Const, 0}, - {"SYS_SCHED_GET_PRIORITY_MAX", Const, 0}, - {"SYS_SCHED_GET_PRIORITY_MIN", Const, 0}, - {"SYS_SCHED_RR_GET_INTERVAL", Const, 0}, - {"SYS_SCHED_SETAFFINITY", Const, 0}, - {"SYS_SCHED_SETPARAM", Const, 0}, - {"SYS_SCHED_SETSCHEDULER", Const, 0}, - {"SYS_SCHED_YIELD", Const, 0}, - {"SYS_SCTP_GENERIC_RECVMSG", Const, 0}, - {"SYS_SCTP_GENERIC_SENDMSG", Const, 0}, - {"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0}, - {"SYS_SCTP_PEELOFF", Const, 0}, - {"SYS_SEARCHFS", Const, 0}, - {"SYS_SECURITY", Const, 0}, - {"SYS_SELECT", Const, 0}, - {"SYS_SELECT_NOCANCEL", Const, 0}, - {"SYS_SEMCONFIG", Const, 1}, - {"SYS_SEMCTL", Const, 0}, - {"SYS_SEMGET", Const, 0}, - {"SYS_SEMOP", Const, 0}, - {"SYS_SEMSYS", Const, 0}, - {"SYS_SEMTIMEDOP", Const, 0}, - {"SYS_SEM_CLOSE", Const, 0}, - {"SYS_SEM_DESTROY", Const, 0}, - {"SYS_SEM_GETVALUE", Const, 0}, - {"SYS_SEM_INIT", Const, 0}, - {"SYS_SEM_OPEN", Const, 0}, - {"SYS_SEM_POST", Const, 0}, - {"SYS_SEM_TRYWAIT", Const, 0}, - {"SYS_SEM_UNLINK", Const, 0}, - {"SYS_SEM_WAIT", Const, 0}, - {"SYS_SEM_WAIT_NOCANCEL", Const, 0}, - {"SYS_SEND", Const, 0}, - {"SYS_SENDFILE", Const, 0}, - {"SYS_SENDFILE64", Const, 0}, - {"SYS_SENDMMSG", Const, 0}, - {"SYS_SENDMSG", Const, 0}, - {"SYS_SENDMSG_NOCANCEL", Const, 0}, - {"SYS_SENDTO", Const, 0}, - {"SYS_SENDTO_NOCANCEL", Const, 0}, - {"SYS_SETATTRLIST", Const, 0}, - {"SYS_SETAUDIT", Const, 0}, - {"SYS_SETAUDIT_ADDR", Const, 0}, - {"SYS_SETAUID", Const, 0}, - {"SYS_SETCONTEXT", Const, 0}, - {"SYS_SETDOMAINNAME", Const, 0}, - {"SYS_SETEGID", Const, 0}, - {"SYS_SETEUID", Const, 0}, - {"SYS_SETFIB", Const, 0}, - {"SYS_SETFSGID", Const, 0}, - {"SYS_SETFSGID32", Const, 0}, - {"SYS_SETFSUID", Const, 0}, - {"SYS_SETFSUID32", Const, 0}, - {"SYS_SETGID", Const, 0}, - {"SYS_SETGID32", Const, 0}, - {"SYS_SETGROUPS", Const, 0}, - {"SYS_SETGROUPS32", Const, 0}, - {"SYS_SETHOSTNAME", Const, 0}, - {"SYS_SETITIMER", Const, 0}, - {"SYS_SETLCID", Const, 0}, - {"SYS_SETLOGIN", Const, 0}, - {"SYS_SETLOGINCLASS", Const, 0}, - {"SYS_SETNS", Const, 0}, - {"SYS_SETPGID", Const, 0}, - {"SYS_SETPRIORITY", Const, 0}, - {"SYS_SETPRIVEXEC", Const, 0}, - {"SYS_SETREGID", Const, 0}, - {"SYS_SETREGID32", Const, 0}, - {"SYS_SETRESGID", Const, 0}, - {"SYS_SETRESGID32", Const, 0}, - {"SYS_SETRESUID", Const, 0}, - {"SYS_SETRESUID32", Const, 0}, - {"SYS_SETREUID", Const, 0}, - {"SYS_SETREUID32", Const, 0}, - {"SYS_SETRLIMIT", Const, 0}, - {"SYS_SETRTABLE", Const, 1}, - {"SYS_SETSGROUPS", Const, 0}, - {"SYS_SETSID", Const, 0}, - {"SYS_SETSOCKOPT", Const, 0}, - {"SYS_SETTID", Const, 0}, - {"SYS_SETTID_WITH_PID", Const, 0}, - {"SYS_SETTIMEOFDAY", Const, 0}, - {"SYS_SETUID", Const, 0}, - {"SYS_SETUID32", Const, 0}, - {"SYS_SETWGROUPS", Const, 0}, - {"SYS_SETXATTR", Const, 0}, - {"SYS_SET_MEMPOLICY", Const, 0}, - {"SYS_SET_ROBUST_LIST", Const, 0}, - {"SYS_SET_THREAD_AREA", Const, 0}, - {"SYS_SET_TID_ADDRESS", Const, 0}, - {"SYS_SGETMASK", Const, 0}, - {"SYS_SHARED_REGION_CHECK_NP", Const, 0}, - {"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0}, - {"SYS_SHMAT", Const, 0}, - {"SYS_SHMCTL", Const, 0}, - {"SYS_SHMDT", Const, 0}, - {"SYS_SHMGET", Const, 0}, - {"SYS_SHMSYS", Const, 0}, - {"SYS_SHM_OPEN", Const, 0}, - {"SYS_SHM_UNLINK", Const, 0}, - {"SYS_SHUTDOWN", Const, 0}, - {"SYS_SIGACTION", Const, 0}, - {"SYS_SIGALTSTACK", Const, 0}, - {"SYS_SIGNAL", Const, 0}, - {"SYS_SIGNALFD", Const, 0}, - {"SYS_SIGNALFD4", Const, 0}, - {"SYS_SIGPENDING", Const, 0}, - {"SYS_SIGPROCMASK", Const, 0}, - {"SYS_SIGQUEUE", Const, 0}, - {"SYS_SIGQUEUEINFO", Const, 1}, - {"SYS_SIGRETURN", Const, 0}, - {"SYS_SIGSUSPEND", Const, 0}, - {"SYS_SIGSUSPEND_NOCANCEL", Const, 0}, - {"SYS_SIGTIMEDWAIT", Const, 0}, - {"SYS_SIGWAIT", Const, 0}, - {"SYS_SIGWAITINFO", Const, 0}, - {"SYS_SOCKET", Const, 0}, - {"SYS_SOCKETCALL", Const, 0}, - {"SYS_SOCKETPAIR", Const, 0}, - {"SYS_SPLICE", Const, 0}, - {"SYS_SSETMASK", Const, 0}, - {"SYS_SSTK", Const, 0}, - {"SYS_STACK_SNAPSHOT", Const, 0}, - {"SYS_STAT", Const, 0}, - {"SYS_STAT64", Const, 0}, - {"SYS_STAT64_EXTENDED", Const, 0}, - {"SYS_STATFS", Const, 0}, - {"SYS_STATFS64", Const, 0}, - {"SYS_STATV", Const, 0}, - {"SYS_STATVFS1", Const, 1}, - {"SYS_STAT_EXTENDED", Const, 0}, - {"SYS_STIME", Const, 0}, - {"SYS_STTY", Const, 0}, - {"SYS_SWAPCONTEXT", Const, 0}, - {"SYS_SWAPCTL", Const, 1}, - {"SYS_SWAPOFF", Const, 0}, - {"SYS_SWAPON", Const, 0}, - {"SYS_SYMLINK", Const, 0}, - {"SYS_SYMLINKAT", Const, 0}, - {"SYS_SYNC", Const, 0}, - {"SYS_SYNCFS", Const, 0}, - {"SYS_SYNC_FILE_RANGE", Const, 0}, - {"SYS_SYSARCH", Const, 0}, - {"SYS_SYSCALL", Const, 0}, - {"SYS_SYSCALL_BASE", Const, 0}, - {"SYS_SYSFS", Const, 0}, - {"SYS_SYSINFO", Const, 0}, - {"SYS_SYSLOG", Const, 0}, - {"SYS_TEE", Const, 0}, - {"SYS_TGKILL", Const, 0}, - {"SYS_THREAD_SELFID", Const, 0}, - {"SYS_THR_CREATE", Const, 0}, - {"SYS_THR_EXIT", Const, 0}, - {"SYS_THR_KILL", Const, 0}, - {"SYS_THR_KILL2", Const, 0}, - {"SYS_THR_NEW", Const, 0}, - {"SYS_THR_SELF", Const, 0}, - {"SYS_THR_SET_NAME", Const, 0}, - {"SYS_THR_SUSPEND", Const, 0}, - {"SYS_THR_WAKE", Const, 0}, - {"SYS_TIME", Const, 0}, - {"SYS_TIMERFD_CREATE", Const, 0}, - {"SYS_TIMERFD_GETTIME", Const, 0}, - {"SYS_TIMERFD_SETTIME", Const, 0}, - {"SYS_TIMER_CREATE", Const, 0}, - {"SYS_TIMER_DELETE", Const, 0}, - {"SYS_TIMER_GETOVERRUN", Const, 0}, - {"SYS_TIMER_GETTIME", Const, 0}, - {"SYS_TIMER_SETTIME", Const, 0}, - {"SYS_TIMES", Const, 0}, - {"SYS_TKILL", Const, 0}, - {"SYS_TRUNCATE", Const, 0}, - {"SYS_TRUNCATE64", Const, 0}, - {"SYS_TUXCALL", Const, 0}, - {"SYS_UGETRLIMIT", Const, 0}, - {"SYS_ULIMIT", Const, 0}, - {"SYS_UMASK", Const, 0}, - {"SYS_UMASK_EXTENDED", Const, 0}, - {"SYS_UMOUNT", Const, 0}, - {"SYS_UMOUNT2", Const, 0}, - {"SYS_UNAME", Const, 0}, - {"SYS_UNDELETE", Const, 0}, - {"SYS_UNLINK", Const, 0}, - {"SYS_UNLINKAT", Const, 0}, - {"SYS_UNMOUNT", Const, 0}, - {"SYS_UNSHARE", Const, 0}, - {"SYS_USELIB", Const, 0}, - {"SYS_USTAT", Const, 0}, - {"SYS_UTIME", Const, 0}, - {"SYS_UTIMENSAT", Const, 0}, - {"SYS_UTIMES", Const, 0}, - {"SYS_UTRACE", Const, 0}, - {"SYS_UUIDGEN", Const, 0}, - {"SYS_VADVISE", Const, 1}, - {"SYS_VFORK", Const, 0}, - {"SYS_VHANGUP", Const, 0}, - {"SYS_VM86", Const, 0}, - {"SYS_VM86OLD", Const, 0}, - {"SYS_VMSPLICE", Const, 0}, - {"SYS_VM_PRESSURE_MONITOR", Const, 0}, - {"SYS_VSERVER", Const, 0}, - {"SYS_WAIT4", Const, 0}, - {"SYS_WAIT4_NOCANCEL", Const, 0}, - {"SYS_WAIT6", Const, 1}, - {"SYS_WAITEVENT", Const, 0}, - {"SYS_WAITID", Const, 0}, - {"SYS_WAITID_NOCANCEL", Const, 0}, - {"SYS_WAITPID", Const, 0}, - {"SYS_WATCHEVENT", Const, 0}, - {"SYS_WORKQ_KERNRETURN", Const, 0}, - {"SYS_WORKQ_OPEN", Const, 0}, - {"SYS_WRITE", Const, 0}, - {"SYS_WRITEV", Const, 0}, - {"SYS_WRITEV_NOCANCEL", Const, 0}, - {"SYS_WRITE_NOCANCEL", Const, 0}, - {"SYS_YIELD", Const, 0}, - {"SYS__LLSEEK", Const, 0}, - {"SYS__LWP_CONTINUE", Const, 1}, - {"SYS__LWP_CREATE", Const, 1}, - {"SYS__LWP_CTL", Const, 1}, - {"SYS__LWP_DETACH", Const, 1}, - {"SYS__LWP_EXIT", Const, 1}, - {"SYS__LWP_GETNAME", Const, 1}, - {"SYS__LWP_GETPRIVATE", Const, 1}, - {"SYS__LWP_KILL", Const, 1}, - {"SYS__LWP_PARK", Const, 1}, - {"SYS__LWP_SELF", Const, 1}, - {"SYS__LWP_SETNAME", Const, 1}, - {"SYS__LWP_SETPRIVATE", Const, 1}, - {"SYS__LWP_SUSPEND", Const, 1}, - {"SYS__LWP_UNPARK", Const, 1}, - {"SYS__LWP_UNPARK_ALL", Const, 1}, - {"SYS__LWP_WAIT", Const, 1}, - {"SYS__LWP_WAKEUP", Const, 1}, - {"SYS__NEWSELECT", Const, 0}, - {"SYS__PSET_BIND", Const, 1}, - {"SYS__SCHED_GETAFFINITY", Const, 1}, - {"SYS__SCHED_GETPARAM", Const, 1}, - {"SYS__SCHED_SETAFFINITY", Const, 1}, - {"SYS__SCHED_SETPARAM", Const, 1}, - {"SYS__SYSCTL", Const, 0}, - {"SYS__UMTX_LOCK", Const, 0}, - {"SYS__UMTX_OP", Const, 0}, - {"SYS__UMTX_UNLOCK", Const, 0}, - {"SYS___ACL_ACLCHECK_FD", Const, 0}, - {"SYS___ACL_ACLCHECK_FILE", Const, 0}, - {"SYS___ACL_ACLCHECK_LINK", Const, 0}, - {"SYS___ACL_DELETE_FD", Const, 0}, - {"SYS___ACL_DELETE_FILE", Const, 0}, - {"SYS___ACL_DELETE_LINK", Const, 0}, - {"SYS___ACL_GET_FD", Const, 0}, - {"SYS___ACL_GET_FILE", Const, 0}, - {"SYS___ACL_GET_LINK", Const, 0}, - {"SYS___ACL_SET_FD", Const, 0}, - {"SYS___ACL_SET_FILE", Const, 0}, - {"SYS___ACL_SET_LINK", Const, 0}, - {"SYS___CAP_RIGHTS_GET", Const, 14}, - {"SYS___CLONE", Const, 1}, - {"SYS___DISABLE_THREADSIGNAL", Const, 0}, - {"SYS___GETCWD", Const, 0}, - {"SYS___GETLOGIN", Const, 1}, - {"SYS___GET_TCB", Const, 1}, - {"SYS___MAC_EXECVE", Const, 0}, - {"SYS___MAC_GETFSSTAT", Const, 0}, - {"SYS___MAC_GET_FD", Const, 0}, - {"SYS___MAC_GET_FILE", Const, 0}, - {"SYS___MAC_GET_LCID", Const, 0}, - {"SYS___MAC_GET_LCTX", Const, 0}, - {"SYS___MAC_GET_LINK", Const, 0}, - {"SYS___MAC_GET_MOUNT", Const, 0}, - {"SYS___MAC_GET_PID", Const, 0}, - {"SYS___MAC_GET_PROC", Const, 0}, - {"SYS___MAC_MOUNT", Const, 0}, - {"SYS___MAC_SET_FD", Const, 0}, - {"SYS___MAC_SET_FILE", Const, 0}, - {"SYS___MAC_SET_LCTX", Const, 0}, - {"SYS___MAC_SET_LINK", Const, 0}, - {"SYS___MAC_SET_PROC", Const, 0}, - {"SYS___MAC_SYSCALL", Const, 0}, - {"SYS___OLD_SEMWAIT_SIGNAL", Const, 0}, - {"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, - {"SYS___POSIX_CHOWN", Const, 1}, - {"SYS___POSIX_FCHOWN", Const, 1}, - {"SYS___POSIX_LCHOWN", Const, 1}, - {"SYS___POSIX_RENAME", Const, 1}, - {"SYS___PTHREAD_CANCELED", Const, 0}, - {"SYS___PTHREAD_CHDIR", Const, 0}, - {"SYS___PTHREAD_FCHDIR", Const, 0}, - {"SYS___PTHREAD_KILL", Const, 0}, - {"SYS___PTHREAD_MARKCANCEL", Const, 0}, - {"SYS___PTHREAD_SIGMASK", Const, 0}, - {"SYS___QUOTACTL", Const, 1}, - {"SYS___SEMCTL", Const, 1}, - {"SYS___SEMWAIT_SIGNAL", Const, 0}, - {"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0}, - {"SYS___SETLOGIN", Const, 1}, - {"SYS___SETUGID", Const, 0}, - {"SYS___SET_TCB", Const, 1}, - {"SYS___SIGACTION_SIGTRAMP", Const, 1}, - {"SYS___SIGTIMEDWAIT", Const, 1}, - {"SYS___SIGWAIT", Const, 0}, - {"SYS___SIGWAIT_NOCANCEL", Const, 0}, - {"SYS___SYSCTL", Const, 0}, - {"SYS___TFORK", Const, 1}, - {"SYS___THREXIT", Const, 1}, - {"SYS___THRSIGDIVERT", Const, 1}, - {"SYS___THRSLEEP", Const, 1}, - {"SYS___THRWAKEUP", Const, 1}, - {"S_ARCH1", Const, 1}, - {"S_ARCH2", Const, 1}, - {"S_BLKSIZE", Const, 0}, - {"S_IEXEC", Const, 0}, - {"S_IFBLK", Const, 0}, - {"S_IFCHR", Const, 0}, - {"S_IFDIR", Const, 0}, - {"S_IFIFO", Const, 0}, - {"S_IFLNK", Const, 0}, - {"S_IFMT", Const, 0}, - {"S_IFREG", Const, 0}, - {"S_IFSOCK", Const, 0}, - {"S_IFWHT", Const, 0}, - {"S_IREAD", Const, 0}, - {"S_IRGRP", Const, 0}, - {"S_IROTH", Const, 0}, - {"S_IRUSR", Const, 0}, - {"S_IRWXG", Const, 0}, - {"S_IRWXO", Const, 0}, - {"S_IRWXU", Const, 0}, - {"S_ISGID", Const, 0}, - {"S_ISTXT", Const, 0}, - {"S_ISUID", Const, 0}, - {"S_ISVTX", Const, 0}, - {"S_IWGRP", Const, 0}, - {"S_IWOTH", Const, 0}, - {"S_IWRITE", Const, 0}, - {"S_IWUSR", Const, 0}, - {"S_IXGRP", Const, 0}, - {"S_IXOTH", Const, 0}, - {"S_IXUSR", Const, 0}, - {"S_LOGIN_SET", Const, 1}, - {"SecurityAttributes", Type, 0}, - {"SecurityAttributes.InheritHandle", Field, 0}, - {"SecurityAttributes.Length", Field, 0}, - {"SecurityAttributes.SecurityDescriptor", Field, 0}, - {"Seek", Func, 0}, - {"Select", Func, 0}, - {"Sendfile", Func, 0}, - {"Sendmsg", Func, 0}, - {"SendmsgN", Func, 3}, - {"Sendto", Func, 0}, - {"Servent", Type, 0}, - {"Servent.Aliases", Field, 0}, - {"Servent.Name", Field, 0}, - {"Servent.Port", Field, 0}, - {"Servent.Proto", Field, 0}, - {"SetBpf", Func, 0}, - {"SetBpfBuflen", Func, 0}, - {"SetBpfDatalink", Func, 0}, - {"SetBpfHeadercmpl", Func, 0}, - {"SetBpfImmediate", Func, 0}, - {"SetBpfInterface", Func, 0}, - {"SetBpfPromisc", Func, 0}, - {"SetBpfTimeout", Func, 0}, - {"SetCurrentDirectory", Func, 0}, - {"SetEndOfFile", Func, 0}, - {"SetEnvironmentVariable", Func, 0}, - {"SetFileAttributes", Func, 0}, - {"SetFileCompletionNotificationModes", Func, 2}, - {"SetFilePointer", Func, 0}, - {"SetFileTime", Func, 0}, - {"SetHandleInformation", Func, 0}, - {"SetKevent", Func, 0}, - {"SetLsfPromisc", Func, 0}, - {"SetNonblock", Func, 0}, - {"Setdomainname", Func, 0}, - {"Setegid", Func, 0}, - {"Setenv", Func, 0}, - {"Seteuid", Func, 0}, - {"Setfsgid", Func, 0}, - {"Setfsuid", Func, 0}, - {"Setgid", Func, 0}, - {"Setgroups", Func, 0}, - {"Sethostname", Func, 0}, - {"Setlogin", Func, 0}, - {"Setpgid", Func, 0}, - {"Setpriority", Func, 0}, - {"Setprivexec", Func, 0}, - {"Setregid", Func, 0}, - {"Setresgid", Func, 0}, - {"Setresuid", Func, 0}, - {"Setreuid", Func, 0}, - {"Setrlimit", Func, 0}, - {"Setsid", Func, 0}, - {"Setsockopt", Func, 0}, - {"SetsockoptByte", Func, 0}, - {"SetsockoptICMPv6Filter", Func, 2}, - {"SetsockoptIPMreq", Func, 0}, - {"SetsockoptIPMreqn", Func, 0}, - {"SetsockoptIPv6Mreq", Func, 0}, - {"SetsockoptInet4Addr", Func, 0}, - {"SetsockoptInt", Func, 0}, - {"SetsockoptLinger", Func, 0}, - {"SetsockoptString", Func, 0}, - {"SetsockoptTimeval", Func, 0}, - {"Settimeofday", Func, 0}, - {"Setuid", Func, 0}, - {"Setxattr", Func, 1}, - {"Shutdown", Func, 0}, - {"SidTypeAlias", Const, 0}, - {"SidTypeComputer", Const, 0}, - {"SidTypeDeletedAccount", Const, 0}, - {"SidTypeDomain", Const, 0}, - {"SidTypeGroup", Const, 0}, - {"SidTypeInvalid", Const, 0}, - {"SidTypeLabel", Const, 0}, - {"SidTypeUnknown", Const, 0}, - {"SidTypeUser", Const, 0}, - {"SidTypeWellKnownGroup", Const, 0}, - {"Signal", Type, 0}, - {"SizeofBpfHdr", Const, 0}, - {"SizeofBpfInsn", Const, 0}, - {"SizeofBpfProgram", Const, 0}, - {"SizeofBpfStat", Const, 0}, - {"SizeofBpfVersion", Const, 0}, - {"SizeofBpfZbuf", Const, 0}, - {"SizeofBpfZbufHeader", Const, 0}, - {"SizeofCmsghdr", Const, 0}, - {"SizeofICMPv6Filter", Const, 2}, - {"SizeofIPMreq", Const, 0}, - {"SizeofIPMreqn", Const, 0}, - {"SizeofIPv6MTUInfo", Const, 2}, - {"SizeofIPv6Mreq", Const, 0}, - {"SizeofIfAddrmsg", Const, 0}, - {"SizeofIfAnnounceMsghdr", Const, 1}, - {"SizeofIfData", Const, 0}, - {"SizeofIfInfomsg", Const, 0}, - {"SizeofIfMsghdr", Const, 0}, - {"SizeofIfaMsghdr", Const, 0}, - {"SizeofIfmaMsghdr", Const, 0}, - {"SizeofIfmaMsghdr2", Const, 0}, - {"SizeofInet4Pktinfo", Const, 0}, - {"SizeofInet6Pktinfo", Const, 0}, - {"SizeofInotifyEvent", Const, 0}, - {"SizeofLinger", Const, 0}, - {"SizeofMsghdr", Const, 0}, - {"SizeofNlAttr", Const, 0}, - {"SizeofNlMsgerr", Const, 0}, - {"SizeofNlMsghdr", Const, 0}, - {"SizeofRtAttr", Const, 0}, - {"SizeofRtGenmsg", Const, 0}, - {"SizeofRtMetrics", Const, 0}, - {"SizeofRtMsg", Const, 0}, - {"SizeofRtMsghdr", Const, 0}, - {"SizeofRtNexthop", Const, 0}, - {"SizeofSockFilter", Const, 0}, - {"SizeofSockFprog", Const, 0}, - {"SizeofSockaddrAny", Const, 0}, - {"SizeofSockaddrDatalink", Const, 0}, - {"SizeofSockaddrInet4", Const, 0}, - {"SizeofSockaddrInet6", Const, 0}, - {"SizeofSockaddrLinklayer", Const, 0}, - {"SizeofSockaddrNetlink", Const, 0}, - {"SizeofSockaddrUnix", Const, 0}, - {"SizeofTCPInfo", Const, 1}, - {"SizeofUcred", Const, 0}, - {"SlicePtrFromStrings", Func, 1}, - {"SockFilter", Type, 0}, - {"SockFilter.Code", Field, 0}, - {"SockFilter.Jf", Field, 0}, - {"SockFilter.Jt", Field, 0}, - {"SockFilter.K", Field, 0}, - {"SockFprog", Type, 0}, - {"SockFprog.Filter", Field, 0}, - {"SockFprog.Len", Field, 0}, - {"SockFprog.Pad_cgo_0", Field, 0}, - {"Sockaddr", Type, 0}, - {"SockaddrDatalink", Type, 0}, - {"SockaddrDatalink.Alen", Field, 0}, - {"SockaddrDatalink.Data", Field, 0}, - {"SockaddrDatalink.Family", Field, 0}, - {"SockaddrDatalink.Index", Field, 0}, - {"SockaddrDatalink.Len", Field, 0}, - {"SockaddrDatalink.Nlen", Field, 0}, - {"SockaddrDatalink.Slen", Field, 0}, - {"SockaddrDatalink.Type", Field, 0}, - {"SockaddrGen", Type, 0}, - {"SockaddrInet4", Type, 0}, - {"SockaddrInet4.Addr", Field, 0}, - {"SockaddrInet4.Port", Field, 0}, - {"SockaddrInet6", Type, 0}, - {"SockaddrInet6.Addr", Field, 0}, - {"SockaddrInet6.Port", Field, 0}, - {"SockaddrInet6.ZoneId", Field, 0}, - {"SockaddrLinklayer", Type, 0}, - {"SockaddrLinklayer.Addr", Field, 0}, - {"SockaddrLinklayer.Halen", Field, 0}, - {"SockaddrLinklayer.Hatype", Field, 0}, - {"SockaddrLinklayer.Ifindex", Field, 0}, - {"SockaddrLinklayer.Pkttype", Field, 0}, - {"SockaddrLinklayer.Protocol", Field, 0}, - {"SockaddrNetlink", Type, 0}, - {"SockaddrNetlink.Family", Field, 0}, - {"SockaddrNetlink.Groups", Field, 0}, - {"SockaddrNetlink.Pad", Field, 0}, - {"SockaddrNetlink.Pid", Field, 0}, - {"SockaddrUnix", Type, 0}, - {"SockaddrUnix.Name", Field, 0}, - {"Socket", Func, 0}, - {"SocketControlMessage", Type, 0}, - {"SocketControlMessage.Data", Field, 0}, - {"SocketControlMessage.Header", Field, 0}, - {"SocketDisableIPv6", Var, 0}, - {"Socketpair", Func, 0}, - {"Splice", Func, 0}, - {"StartProcess", Func, 0}, - {"StartupInfo", Type, 0}, - {"StartupInfo.Cb", Field, 0}, - {"StartupInfo.Desktop", Field, 0}, - {"StartupInfo.FillAttribute", Field, 0}, - {"StartupInfo.Flags", Field, 0}, - {"StartupInfo.ShowWindow", Field, 0}, - {"StartupInfo.StdErr", Field, 0}, - {"StartupInfo.StdInput", Field, 0}, - {"StartupInfo.StdOutput", Field, 0}, - {"StartupInfo.Title", Field, 0}, - {"StartupInfo.X", Field, 0}, - {"StartupInfo.XCountChars", Field, 0}, - {"StartupInfo.XSize", Field, 0}, - {"StartupInfo.Y", Field, 0}, - {"StartupInfo.YCountChars", Field, 0}, - {"StartupInfo.YSize", Field, 0}, - {"Stat", Func, 0}, - {"Stat_t", Type, 0}, - {"Stat_t.Atim", Field, 0}, - {"Stat_t.Atim_ext", Field, 12}, - {"Stat_t.Atimespec", Field, 0}, - {"Stat_t.Birthtimespec", Field, 0}, - {"Stat_t.Blksize", Field, 0}, - {"Stat_t.Blocks", Field, 0}, - {"Stat_t.Btim_ext", Field, 12}, - {"Stat_t.Ctim", Field, 0}, - {"Stat_t.Ctim_ext", Field, 12}, - {"Stat_t.Ctimespec", Field, 0}, - {"Stat_t.Dev", Field, 0}, - {"Stat_t.Flags", Field, 0}, - {"Stat_t.Gen", Field, 0}, - {"Stat_t.Gid", Field, 0}, - {"Stat_t.Ino", Field, 0}, - {"Stat_t.Lspare", Field, 0}, - {"Stat_t.Lspare0", Field, 2}, - {"Stat_t.Lspare1", Field, 2}, - {"Stat_t.Mode", Field, 0}, - {"Stat_t.Mtim", Field, 0}, - {"Stat_t.Mtim_ext", Field, 12}, - {"Stat_t.Mtimespec", Field, 0}, - {"Stat_t.Nlink", Field, 0}, - {"Stat_t.Pad_cgo_0", Field, 0}, - {"Stat_t.Pad_cgo_1", Field, 0}, - {"Stat_t.Pad_cgo_2", Field, 0}, - {"Stat_t.Padding0", Field, 12}, - {"Stat_t.Padding1", Field, 12}, - {"Stat_t.Qspare", Field, 0}, - {"Stat_t.Rdev", Field, 0}, - {"Stat_t.Size", Field, 0}, - {"Stat_t.Spare", Field, 2}, - {"Stat_t.Uid", Field, 0}, - {"Stat_t.X__pad0", Field, 0}, - {"Stat_t.X__pad1", Field, 0}, - {"Stat_t.X__pad2", Field, 0}, - {"Stat_t.X__st_birthtim", Field, 2}, - {"Stat_t.X__st_ino", Field, 0}, - {"Stat_t.X__unused", Field, 0}, - {"Statfs", Func, 0}, - {"Statfs_t", Type, 0}, - {"Statfs_t.Asyncreads", Field, 0}, - {"Statfs_t.Asyncwrites", Field, 0}, - {"Statfs_t.Bavail", Field, 0}, - {"Statfs_t.Bfree", Field, 0}, - {"Statfs_t.Blocks", Field, 0}, - {"Statfs_t.Bsize", Field, 0}, - {"Statfs_t.Charspare", Field, 0}, - {"Statfs_t.F_asyncreads", Field, 2}, - {"Statfs_t.F_asyncwrites", Field, 2}, - {"Statfs_t.F_bavail", Field, 2}, - {"Statfs_t.F_bfree", Field, 2}, - {"Statfs_t.F_blocks", Field, 2}, - {"Statfs_t.F_bsize", Field, 2}, - {"Statfs_t.F_ctime", Field, 2}, - {"Statfs_t.F_favail", Field, 2}, - {"Statfs_t.F_ffree", Field, 2}, - {"Statfs_t.F_files", Field, 2}, - {"Statfs_t.F_flags", Field, 2}, - {"Statfs_t.F_fsid", Field, 2}, - {"Statfs_t.F_fstypename", Field, 2}, - {"Statfs_t.F_iosize", Field, 2}, - {"Statfs_t.F_mntfromname", Field, 2}, - {"Statfs_t.F_mntfromspec", Field, 3}, - {"Statfs_t.F_mntonname", Field, 2}, - {"Statfs_t.F_namemax", Field, 2}, - {"Statfs_t.F_owner", Field, 2}, - {"Statfs_t.F_spare", Field, 2}, - {"Statfs_t.F_syncreads", Field, 2}, - {"Statfs_t.F_syncwrites", Field, 2}, - {"Statfs_t.Ffree", Field, 0}, - {"Statfs_t.Files", Field, 0}, - {"Statfs_t.Flags", Field, 0}, - {"Statfs_t.Frsize", Field, 0}, - {"Statfs_t.Fsid", Field, 0}, - {"Statfs_t.Fssubtype", Field, 0}, - {"Statfs_t.Fstypename", Field, 0}, - {"Statfs_t.Iosize", Field, 0}, - {"Statfs_t.Mntfromname", Field, 0}, - {"Statfs_t.Mntonname", Field, 0}, - {"Statfs_t.Mount_info", Field, 2}, - {"Statfs_t.Namelen", Field, 0}, - {"Statfs_t.Namemax", Field, 0}, - {"Statfs_t.Owner", Field, 0}, - {"Statfs_t.Pad_cgo_0", Field, 0}, - {"Statfs_t.Pad_cgo_1", Field, 2}, - {"Statfs_t.Reserved", Field, 0}, - {"Statfs_t.Spare", Field, 0}, - {"Statfs_t.Syncreads", Field, 0}, - {"Statfs_t.Syncwrites", Field, 0}, - {"Statfs_t.Type", Field, 0}, - {"Statfs_t.Version", Field, 0}, - {"Stderr", Var, 0}, - {"Stdin", Var, 0}, - {"Stdout", Var, 0}, - {"StringBytePtr", Func, 0}, - {"StringByteSlice", Func, 0}, - {"StringSlicePtr", Func, 0}, - {"StringToSid", Func, 0}, - {"StringToUTF16", Func, 0}, - {"StringToUTF16Ptr", Func, 0}, - {"Symlink", Func, 0}, - {"Sync", Func, 0}, - {"SyncFileRange", Func, 0}, - {"SysProcAttr", Type, 0}, - {"SysProcAttr.AdditionalInheritedHandles", Field, 17}, - {"SysProcAttr.AmbientCaps", Field, 9}, - {"SysProcAttr.CgroupFD", Field, 20}, - {"SysProcAttr.Chroot", Field, 0}, - {"SysProcAttr.Cloneflags", Field, 2}, - {"SysProcAttr.CmdLine", Field, 0}, - {"SysProcAttr.CreationFlags", Field, 1}, - {"SysProcAttr.Credential", Field, 0}, - {"SysProcAttr.Ctty", Field, 1}, - {"SysProcAttr.Foreground", Field, 5}, - {"SysProcAttr.GidMappings", Field, 4}, - {"SysProcAttr.GidMappingsEnableSetgroups", Field, 5}, - {"SysProcAttr.HideWindow", Field, 0}, - {"SysProcAttr.Jail", Field, 21}, - {"SysProcAttr.NoInheritHandles", Field, 16}, - {"SysProcAttr.Noctty", Field, 0}, - {"SysProcAttr.ParentProcess", Field, 17}, - {"SysProcAttr.Pdeathsig", Field, 0}, - {"SysProcAttr.Pgid", Field, 5}, - {"SysProcAttr.PidFD", Field, 22}, - {"SysProcAttr.ProcessAttributes", Field, 13}, - {"SysProcAttr.Ptrace", Field, 0}, - {"SysProcAttr.Setctty", Field, 0}, - {"SysProcAttr.Setpgid", Field, 0}, - {"SysProcAttr.Setsid", Field, 0}, - {"SysProcAttr.ThreadAttributes", Field, 13}, - {"SysProcAttr.Token", Field, 10}, - {"SysProcAttr.UidMappings", Field, 4}, - {"SysProcAttr.Unshareflags", Field, 7}, - {"SysProcAttr.UseCgroupFD", Field, 20}, - {"SysProcIDMap", Type, 4}, - {"SysProcIDMap.ContainerID", Field, 4}, - {"SysProcIDMap.HostID", Field, 4}, - {"SysProcIDMap.Size", Field, 4}, - {"Syscall", Func, 0}, - {"Syscall12", Func, 0}, - {"Syscall15", Func, 0}, - {"Syscall18", Func, 12}, - {"Syscall6", Func, 0}, - {"Syscall9", Func, 0}, - {"SyscallN", Func, 18}, - {"Sysctl", Func, 0}, - {"SysctlUint32", Func, 0}, - {"Sysctlnode", Type, 2}, - {"Sysctlnode.Flags", Field, 2}, - {"Sysctlnode.Name", Field, 2}, - {"Sysctlnode.Num", Field, 2}, - {"Sysctlnode.Un", Field, 2}, - {"Sysctlnode.Ver", Field, 2}, - {"Sysctlnode.X__rsvd", Field, 2}, - {"Sysctlnode.X_sysctl_desc", Field, 2}, - {"Sysctlnode.X_sysctl_func", Field, 2}, - {"Sysctlnode.X_sysctl_parent", Field, 2}, - {"Sysctlnode.X_sysctl_size", Field, 2}, - {"Sysinfo", Func, 0}, - {"Sysinfo_t", Type, 0}, - {"Sysinfo_t.Bufferram", Field, 0}, - {"Sysinfo_t.Freehigh", Field, 0}, - {"Sysinfo_t.Freeram", Field, 0}, - {"Sysinfo_t.Freeswap", Field, 0}, - {"Sysinfo_t.Loads", Field, 0}, - {"Sysinfo_t.Pad", Field, 0}, - {"Sysinfo_t.Pad_cgo_0", Field, 0}, - {"Sysinfo_t.Pad_cgo_1", Field, 0}, - {"Sysinfo_t.Procs", Field, 0}, - {"Sysinfo_t.Sharedram", Field, 0}, - {"Sysinfo_t.Totalhigh", Field, 0}, - {"Sysinfo_t.Totalram", Field, 0}, - {"Sysinfo_t.Totalswap", Field, 0}, - {"Sysinfo_t.Unit", Field, 0}, - {"Sysinfo_t.Uptime", Field, 0}, - {"Sysinfo_t.X_f", Field, 0}, - {"Systemtime", Type, 0}, - {"Systemtime.Day", Field, 0}, - {"Systemtime.DayOfWeek", Field, 0}, - {"Systemtime.Hour", Field, 0}, - {"Systemtime.Milliseconds", Field, 0}, - {"Systemtime.Minute", Field, 0}, - {"Systemtime.Month", Field, 0}, - {"Systemtime.Second", Field, 0}, - {"Systemtime.Year", Field, 0}, - {"TCGETS", Const, 0}, - {"TCIFLUSH", Const, 1}, - {"TCIOFLUSH", Const, 1}, - {"TCOFLUSH", Const, 1}, - {"TCPInfo", Type, 1}, - {"TCPInfo.Advmss", Field, 1}, - {"TCPInfo.Ato", Field, 1}, - {"TCPInfo.Backoff", Field, 1}, - {"TCPInfo.Ca_state", Field, 1}, - {"TCPInfo.Fackets", Field, 1}, - {"TCPInfo.Last_ack_recv", Field, 1}, - {"TCPInfo.Last_ack_sent", Field, 1}, - {"TCPInfo.Last_data_recv", Field, 1}, - {"TCPInfo.Last_data_sent", Field, 1}, - {"TCPInfo.Lost", Field, 1}, - {"TCPInfo.Options", Field, 1}, - {"TCPInfo.Pad_cgo_0", Field, 1}, - {"TCPInfo.Pmtu", Field, 1}, - {"TCPInfo.Probes", Field, 1}, - {"TCPInfo.Rcv_mss", Field, 1}, - {"TCPInfo.Rcv_rtt", Field, 1}, - {"TCPInfo.Rcv_space", Field, 1}, - {"TCPInfo.Rcv_ssthresh", Field, 1}, - {"TCPInfo.Reordering", Field, 1}, - {"TCPInfo.Retrans", Field, 1}, - {"TCPInfo.Retransmits", Field, 1}, - {"TCPInfo.Rto", Field, 1}, - {"TCPInfo.Rtt", Field, 1}, - {"TCPInfo.Rttvar", Field, 1}, - {"TCPInfo.Sacked", Field, 1}, - {"TCPInfo.Snd_cwnd", Field, 1}, - {"TCPInfo.Snd_mss", Field, 1}, - {"TCPInfo.Snd_ssthresh", Field, 1}, - {"TCPInfo.State", Field, 1}, - {"TCPInfo.Total_retrans", Field, 1}, - {"TCPInfo.Unacked", Field, 1}, - {"TCPKeepalive", Type, 3}, - {"TCPKeepalive.Interval", Field, 3}, - {"TCPKeepalive.OnOff", Field, 3}, - {"TCPKeepalive.Time", Field, 3}, - {"TCP_CA_NAME_MAX", Const, 0}, - {"TCP_CONGCTL", Const, 1}, - {"TCP_CONGESTION", Const, 0}, - {"TCP_CONNECTIONTIMEOUT", Const, 0}, - {"TCP_CORK", Const, 0}, - {"TCP_DEFER_ACCEPT", Const, 0}, - {"TCP_ENABLE_ECN", Const, 16}, - {"TCP_INFO", Const, 0}, - {"TCP_KEEPALIVE", Const, 0}, - {"TCP_KEEPCNT", Const, 0}, - {"TCP_KEEPIDLE", Const, 0}, - {"TCP_KEEPINIT", Const, 1}, - {"TCP_KEEPINTVL", Const, 0}, - {"TCP_LINGER2", Const, 0}, - {"TCP_MAXBURST", Const, 0}, - {"TCP_MAXHLEN", Const, 0}, - {"TCP_MAXOLEN", Const, 0}, - {"TCP_MAXSEG", Const, 0}, - {"TCP_MAXWIN", Const, 0}, - {"TCP_MAX_SACK", Const, 0}, - {"TCP_MAX_WINSHIFT", Const, 0}, - {"TCP_MD5SIG", Const, 0}, - {"TCP_MD5SIG_MAXKEYLEN", Const, 0}, - {"TCP_MINMSS", Const, 0}, - {"TCP_MINMSSOVERLOAD", Const, 0}, - {"TCP_MSS", Const, 0}, - {"TCP_NODELAY", Const, 0}, - {"TCP_NOOPT", Const, 0}, - {"TCP_NOPUSH", Const, 0}, - {"TCP_NOTSENT_LOWAT", Const, 16}, - {"TCP_NSTATES", Const, 1}, - {"TCP_QUICKACK", Const, 0}, - {"TCP_RXT_CONNDROPTIME", Const, 0}, - {"TCP_RXT_FINDROP", Const, 0}, - {"TCP_SACK_ENABLE", Const, 1}, - {"TCP_SENDMOREACKS", Const, 16}, - {"TCP_SYNCNT", Const, 0}, - {"TCP_VENDOR", Const, 3}, - {"TCP_WINDOW_CLAMP", Const, 0}, - {"TCSAFLUSH", Const, 1}, - {"TCSETS", Const, 0}, - {"TF_DISCONNECT", Const, 0}, - {"TF_REUSE_SOCKET", Const, 0}, - {"TF_USE_DEFAULT_WORKER", Const, 0}, - {"TF_USE_KERNEL_APC", Const, 0}, - {"TF_USE_SYSTEM_THREAD", Const, 0}, - {"TF_WRITE_BEHIND", Const, 0}, - {"TH32CS_INHERIT", Const, 4}, - {"TH32CS_SNAPALL", Const, 4}, - {"TH32CS_SNAPHEAPLIST", Const, 4}, - {"TH32CS_SNAPMODULE", Const, 4}, - {"TH32CS_SNAPMODULE32", Const, 4}, - {"TH32CS_SNAPPROCESS", Const, 4}, - {"TH32CS_SNAPTHREAD", Const, 4}, - {"TIME_ZONE_ID_DAYLIGHT", Const, 0}, - {"TIME_ZONE_ID_STANDARD", Const, 0}, - {"TIME_ZONE_ID_UNKNOWN", Const, 0}, - {"TIOCCBRK", Const, 0}, - {"TIOCCDTR", Const, 0}, - {"TIOCCONS", Const, 0}, - {"TIOCDCDTIMESTAMP", Const, 0}, - {"TIOCDRAIN", Const, 0}, - {"TIOCDSIMICROCODE", Const, 0}, - {"TIOCEXCL", Const, 0}, - {"TIOCEXT", Const, 0}, - {"TIOCFLAG_CDTRCTS", Const, 1}, - {"TIOCFLAG_CLOCAL", Const, 1}, - {"TIOCFLAG_CRTSCTS", Const, 1}, - {"TIOCFLAG_MDMBUF", Const, 1}, - {"TIOCFLAG_PPS", Const, 1}, - {"TIOCFLAG_SOFTCAR", Const, 1}, - {"TIOCFLUSH", Const, 0}, - {"TIOCGDEV", Const, 0}, - {"TIOCGDRAINWAIT", Const, 0}, - {"TIOCGETA", Const, 0}, - {"TIOCGETD", Const, 0}, - {"TIOCGFLAGS", Const, 1}, - {"TIOCGICOUNT", Const, 0}, - {"TIOCGLCKTRMIOS", Const, 0}, - {"TIOCGLINED", Const, 1}, - {"TIOCGPGRP", Const, 0}, - {"TIOCGPTN", Const, 0}, - {"TIOCGQSIZE", Const, 1}, - {"TIOCGRANTPT", Const, 1}, - {"TIOCGRS485", Const, 0}, - {"TIOCGSERIAL", Const, 0}, - {"TIOCGSID", Const, 0}, - {"TIOCGSIZE", Const, 1}, - {"TIOCGSOFTCAR", Const, 0}, - {"TIOCGTSTAMP", Const, 1}, - {"TIOCGWINSZ", Const, 0}, - {"TIOCINQ", Const, 0}, - {"TIOCIXOFF", Const, 0}, - {"TIOCIXON", Const, 0}, - {"TIOCLINUX", Const, 0}, - {"TIOCMBIC", Const, 0}, - {"TIOCMBIS", Const, 0}, - {"TIOCMGDTRWAIT", Const, 0}, - {"TIOCMGET", Const, 0}, - {"TIOCMIWAIT", Const, 0}, - {"TIOCMODG", Const, 0}, - {"TIOCMODS", Const, 0}, - {"TIOCMSDTRWAIT", Const, 0}, - {"TIOCMSET", Const, 0}, - {"TIOCM_CAR", Const, 0}, - {"TIOCM_CD", Const, 0}, - {"TIOCM_CTS", Const, 0}, - {"TIOCM_DCD", Const, 0}, - {"TIOCM_DSR", Const, 0}, - {"TIOCM_DTR", Const, 0}, - {"TIOCM_LE", Const, 0}, - {"TIOCM_RI", Const, 0}, - {"TIOCM_RNG", Const, 0}, - {"TIOCM_RTS", Const, 0}, - {"TIOCM_SR", Const, 0}, - {"TIOCM_ST", Const, 0}, - {"TIOCNOTTY", Const, 0}, - {"TIOCNXCL", Const, 0}, - {"TIOCOUTQ", Const, 0}, - {"TIOCPKT", Const, 0}, - {"TIOCPKT_DATA", Const, 0}, - {"TIOCPKT_DOSTOP", Const, 0}, - {"TIOCPKT_FLUSHREAD", Const, 0}, - {"TIOCPKT_FLUSHWRITE", Const, 0}, - {"TIOCPKT_IOCTL", Const, 0}, - {"TIOCPKT_NOSTOP", Const, 0}, - {"TIOCPKT_START", Const, 0}, - {"TIOCPKT_STOP", Const, 0}, - {"TIOCPTMASTER", Const, 0}, - {"TIOCPTMGET", Const, 1}, - {"TIOCPTSNAME", Const, 1}, - {"TIOCPTYGNAME", Const, 0}, - {"TIOCPTYGRANT", Const, 0}, - {"TIOCPTYUNLK", Const, 0}, - {"TIOCRCVFRAME", Const, 1}, - {"TIOCREMOTE", Const, 0}, - {"TIOCSBRK", Const, 0}, - {"TIOCSCONS", Const, 0}, - {"TIOCSCTTY", Const, 0}, - {"TIOCSDRAINWAIT", Const, 0}, - {"TIOCSDTR", Const, 0}, - {"TIOCSERCONFIG", Const, 0}, - {"TIOCSERGETLSR", Const, 0}, - {"TIOCSERGETMULTI", Const, 0}, - {"TIOCSERGSTRUCT", Const, 0}, - {"TIOCSERGWILD", Const, 0}, - {"TIOCSERSETMULTI", Const, 0}, - {"TIOCSERSWILD", Const, 0}, - {"TIOCSER_TEMT", Const, 0}, - {"TIOCSETA", Const, 0}, - {"TIOCSETAF", Const, 0}, - {"TIOCSETAW", Const, 0}, - {"TIOCSETD", Const, 0}, - {"TIOCSFLAGS", Const, 1}, - {"TIOCSIG", Const, 0}, - {"TIOCSLCKTRMIOS", Const, 0}, - {"TIOCSLINED", Const, 1}, - {"TIOCSPGRP", Const, 0}, - {"TIOCSPTLCK", Const, 0}, - {"TIOCSQSIZE", Const, 1}, - {"TIOCSRS485", Const, 0}, - {"TIOCSSERIAL", Const, 0}, - {"TIOCSSIZE", Const, 1}, - {"TIOCSSOFTCAR", Const, 0}, - {"TIOCSTART", Const, 0}, - {"TIOCSTAT", Const, 0}, - {"TIOCSTI", Const, 0}, - {"TIOCSTOP", Const, 0}, - {"TIOCSTSTAMP", Const, 1}, - {"TIOCSWINSZ", Const, 0}, - {"TIOCTIMESTAMP", Const, 0}, - {"TIOCUCNTL", Const, 0}, - {"TIOCVHANGUP", Const, 0}, - {"TIOCXMTFRAME", Const, 1}, - {"TOKEN_ADJUST_DEFAULT", Const, 0}, - {"TOKEN_ADJUST_GROUPS", Const, 0}, - {"TOKEN_ADJUST_PRIVILEGES", Const, 0}, - {"TOKEN_ADJUST_SESSIONID", Const, 11}, - {"TOKEN_ALL_ACCESS", Const, 0}, - {"TOKEN_ASSIGN_PRIMARY", Const, 0}, - {"TOKEN_DUPLICATE", Const, 0}, - {"TOKEN_EXECUTE", Const, 0}, - {"TOKEN_IMPERSONATE", Const, 0}, - {"TOKEN_QUERY", Const, 0}, - {"TOKEN_QUERY_SOURCE", Const, 0}, - {"TOKEN_READ", Const, 0}, - {"TOKEN_WRITE", Const, 0}, - {"TOSTOP", Const, 0}, - {"TRUNCATE_EXISTING", Const, 0}, - {"TUNATTACHFILTER", Const, 0}, - {"TUNDETACHFILTER", Const, 0}, - {"TUNGETFEATURES", Const, 0}, - {"TUNGETIFF", Const, 0}, - {"TUNGETSNDBUF", Const, 0}, - {"TUNGETVNETHDRSZ", Const, 0}, - {"TUNSETDEBUG", Const, 0}, - {"TUNSETGROUP", Const, 0}, - {"TUNSETIFF", Const, 0}, - {"TUNSETLINK", Const, 0}, - {"TUNSETNOCSUM", Const, 0}, - {"TUNSETOFFLOAD", Const, 0}, - {"TUNSETOWNER", Const, 0}, - {"TUNSETPERSIST", Const, 0}, - {"TUNSETSNDBUF", Const, 0}, - {"TUNSETTXFILTER", Const, 0}, - {"TUNSETVNETHDRSZ", Const, 0}, - {"Tee", Func, 0}, - {"TerminateProcess", Func, 0}, - {"Termios", Type, 0}, - {"Termios.Cc", Field, 0}, - {"Termios.Cflag", Field, 0}, - {"Termios.Iflag", Field, 0}, - {"Termios.Ispeed", Field, 0}, - {"Termios.Lflag", Field, 0}, - {"Termios.Line", Field, 0}, - {"Termios.Oflag", Field, 0}, - {"Termios.Ospeed", Field, 0}, - {"Termios.Pad_cgo_0", Field, 0}, - {"Tgkill", Func, 0}, - {"Time", Func, 0}, - {"Time_t", Type, 0}, - {"Times", Func, 0}, - {"Timespec", Type, 0}, - {"Timespec.Nsec", Field, 0}, - {"Timespec.Pad_cgo_0", Field, 2}, - {"Timespec.Sec", Field, 0}, - {"TimespecToNsec", Func, 0}, - {"Timeval", Type, 0}, - {"Timeval.Pad_cgo_0", Field, 0}, - {"Timeval.Sec", Field, 0}, - {"Timeval.Usec", Field, 0}, - {"Timeval32", Type, 0}, - {"Timeval32.Sec", Field, 0}, - {"Timeval32.Usec", Field, 0}, - {"TimevalToNsec", Func, 0}, - {"Timex", Type, 0}, - {"Timex.Calcnt", Field, 0}, - {"Timex.Constant", Field, 0}, - {"Timex.Errcnt", Field, 0}, - {"Timex.Esterror", Field, 0}, - {"Timex.Freq", Field, 0}, - {"Timex.Jitcnt", Field, 0}, - {"Timex.Jitter", Field, 0}, - {"Timex.Maxerror", Field, 0}, - {"Timex.Modes", Field, 0}, - {"Timex.Offset", Field, 0}, - {"Timex.Pad_cgo_0", Field, 0}, - {"Timex.Pad_cgo_1", Field, 0}, - {"Timex.Pad_cgo_2", Field, 0}, - {"Timex.Pad_cgo_3", Field, 0}, - {"Timex.Ppsfreq", Field, 0}, - {"Timex.Precision", Field, 0}, - {"Timex.Shift", Field, 0}, - {"Timex.Stabil", Field, 0}, - {"Timex.Status", Field, 0}, - {"Timex.Stbcnt", Field, 0}, - {"Timex.Tai", Field, 0}, - {"Timex.Tick", Field, 0}, - {"Timex.Time", Field, 0}, - {"Timex.Tolerance", Field, 0}, - {"Timezoneinformation", Type, 0}, - {"Timezoneinformation.Bias", Field, 0}, - {"Timezoneinformation.DaylightBias", Field, 0}, - {"Timezoneinformation.DaylightDate", Field, 0}, - {"Timezoneinformation.DaylightName", Field, 0}, - {"Timezoneinformation.StandardBias", Field, 0}, - {"Timezoneinformation.StandardDate", Field, 0}, - {"Timezoneinformation.StandardName", Field, 0}, - {"Tms", Type, 0}, - {"Tms.Cstime", Field, 0}, - {"Tms.Cutime", Field, 0}, - {"Tms.Stime", Field, 0}, - {"Tms.Utime", Field, 0}, - {"Token", Type, 0}, - {"TokenAccessInformation", Const, 0}, - {"TokenAuditPolicy", Const, 0}, - {"TokenDefaultDacl", Const, 0}, - {"TokenElevation", Const, 0}, - {"TokenElevationType", Const, 0}, - {"TokenGroups", Const, 0}, - {"TokenGroupsAndPrivileges", Const, 0}, - {"TokenHasRestrictions", Const, 0}, - {"TokenImpersonationLevel", Const, 0}, - {"TokenIntegrityLevel", Const, 0}, - {"TokenLinkedToken", Const, 0}, - {"TokenLogonSid", Const, 0}, - {"TokenMandatoryPolicy", Const, 0}, - {"TokenOrigin", Const, 0}, - {"TokenOwner", Const, 0}, - {"TokenPrimaryGroup", Const, 0}, - {"TokenPrivileges", Const, 0}, - {"TokenRestrictedSids", Const, 0}, - {"TokenSandBoxInert", Const, 0}, - {"TokenSessionId", Const, 0}, - {"TokenSessionReference", Const, 0}, - {"TokenSource", Const, 0}, - {"TokenStatistics", Const, 0}, - {"TokenType", Const, 0}, - {"TokenUIAccess", Const, 0}, - {"TokenUser", Const, 0}, - {"TokenVirtualizationAllowed", Const, 0}, - {"TokenVirtualizationEnabled", Const, 0}, - {"Tokenprimarygroup", Type, 0}, - {"Tokenprimarygroup.PrimaryGroup", Field, 0}, - {"Tokenuser", Type, 0}, - {"Tokenuser.User", Field, 0}, - {"TranslateAccountName", Func, 0}, - {"TranslateName", Func, 0}, - {"TransmitFile", Func, 0}, - {"TransmitFileBuffers", Type, 0}, - {"TransmitFileBuffers.Head", Field, 0}, - {"TransmitFileBuffers.HeadLength", Field, 0}, - {"TransmitFileBuffers.Tail", Field, 0}, - {"TransmitFileBuffers.TailLength", Field, 0}, - {"Truncate", Func, 0}, - {"UNIX_PATH_MAX", Const, 12}, - {"USAGE_MATCH_TYPE_AND", Const, 0}, - {"USAGE_MATCH_TYPE_OR", Const, 0}, - {"UTF16FromString", Func, 1}, - {"UTF16PtrFromString", Func, 1}, - {"UTF16ToString", Func, 0}, - {"Ucred", Type, 0}, - {"Ucred.Gid", Field, 0}, - {"Ucred.Pid", Field, 0}, - {"Ucred.Uid", Field, 0}, - {"Umask", Func, 0}, - {"Uname", Func, 0}, - {"Undelete", Func, 0}, - {"UnixCredentials", Func, 0}, - {"UnixRights", Func, 0}, - {"Unlink", Func, 0}, - {"Unlinkat", Func, 0}, - {"UnmapViewOfFile", Func, 0}, - {"Unmount", Func, 0}, - {"Unsetenv", Func, 4}, - {"Unshare", Func, 0}, - {"UserInfo10", Type, 0}, - {"UserInfo10.Comment", Field, 0}, - {"UserInfo10.FullName", Field, 0}, - {"UserInfo10.Name", Field, 0}, - {"UserInfo10.UsrComment", Field, 0}, - {"Ustat", Func, 0}, - {"Ustat_t", Type, 0}, - {"Ustat_t.Fname", Field, 0}, - {"Ustat_t.Fpack", Field, 0}, - {"Ustat_t.Pad_cgo_0", Field, 0}, - {"Ustat_t.Pad_cgo_1", Field, 0}, - {"Ustat_t.Tfree", Field, 0}, - {"Ustat_t.Tinode", Field, 0}, - {"Utimbuf", Type, 0}, - {"Utimbuf.Actime", Field, 0}, - {"Utimbuf.Modtime", Field, 0}, - {"Utime", Func, 0}, - {"Utimes", Func, 0}, - {"UtimesNano", Func, 1}, - {"Utsname", Type, 0}, - {"Utsname.Domainname", Field, 0}, - {"Utsname.Machine", Field, 0}, - {"Utsname.Nodename", Field, 0}, - {"Utsname.Release", Field, 0}, - {"Utsname.Sysname", Field, 0}, - {"Utsname.Version", Field, 0}, - {"VDISCARD", Const, 0}, - {"VDSUSP", Const, 1}, - {"VEOF", Const, 0}, - {"VEOL", Const, 0}, - {"VEOL2", Const, 0}, - {"VERASE", Const, 0}, - {"VERASE2", Const, 1}, - {"VINTR", Const, 0}, - {"VKILL", Const, 0}, - {"VLNEXT", Const, 0}, - {"VMIN", Const, 0}, - {"VQUIT", Const, 0}, - {"VREPRINT", Const, 0}, - {"VSTART", Const, 0}, - {"VSTATUS", Const, 1}, - {"VSTOP", Const, 0}, - {"VSUSP", Const, 0}, - {"VSWTC", Const, 0}, - {"VT0", Const, 1}, - {"VT1", Const, 1}, - {"VTDLY", Const, 1}, - {"VTIME", Const, 0}, - {"VWERASE", Const, 0}, - {"VirtualLock", Func, 0}, - {"VirtualUnlock", Func, 0}, - {"WAIT_ABANDONED", Const, 0}, - {"WAIT_FAILED", Const, 0}, - {"WAIT_OBJECT_0", Const, 0}, - {"WAIT_TIMEOUT", Const, 0}, - {"WALL", Const, 0}, - {"WALLSIG", Const, 1}, - {"WALTSIG", Const, 1}, - {"WCLONE", Const, 0}, - {"WCONTINUED", Const, 0}, - {"WCOREFLAG", Const, 0}, - {"WEXITED", Const, 0}, - {"WLINUXCLONE", Const, 0}, - {"WNOHANG", Const, 0}, - {"WNOTHREAD", Const, 0}, - {"WNOWAIT", Const, 0}, - {"WNOZOMBIE", Const, 1}, - {"WOPTSCHECKED", Const, 1}, - {"WORDSIZE", Const, 0}, - {"WSABuf", Type, 0}, - {"WSABuf.Buf", Field, 0}, - {"WSABuf.Len", Field, 0}, - {"WSACleanup", Func, 0}, - {"WSADESCRIPTION_LEN", Const, 0}, - {"WSAData", Type, 0}, - {"WSAData.Description", Field, 0}, - {"WSAData.HighVersion", Field, 0}, - {"WSAData.MaxSockets", Field, 0}, - {"WSAData.MaxUdpDg", Field, 0}, - {"WSAData.SystemStatus", Field, 0}, - {"WSAData.VendorInfo", Field, 0}, - {"WSAData.Version", Field, 0}, - {"WSAEACCES", Const, 2}, - {"WSAECONNABORTED", Const, 9}, - {"WSAECONNRESET", Const, 3}, - {"WSAENOPROTOOPT", Const, 23}, - {"WSAEnumProtocols", Func, 2}, - {"WSAID_CONNECTEX", Var, 1}, - {"WSAIoctl", Func, 0}, - {"WSAPROTOCOL_LEN", Const, 2}, - {"WSAProtocolChain", Type, 2}, - {"WSAProtocolChain.ChainEntries", Field, 2}, - {"WSAProtocolChain.ChainLen", Field, 2}, - {"WSAProtocolInfo", Type, 2}, - {"WSAProtocolInfo.AddressFamily", Field, 2}, - {"WSAProtocolInfo.CatalogEntryId", Field, 2}, - {"WSAProtocolInfo.MaxSockAddr", Field, 2}, - {"WSAProtocolInfo.MessageSize", Field, 2}, - {"WSAProtocolInfo.MinSockAddr", Field, 2}, - {"WSAProtocolInfo.NetworkByteOrder", Field, 2}, - {"WSAProtocolInfo.Protocol", Field, 2}, - {"WSAProtocolInfo.ProtocolChain", Field, 2}, - {"WSAProtocolInfo.ProtocolMaxOffset", Field, 2}, - {"WSAProtocolInfo.ProtocolName", Field, 2}, - {"WSAProtocolInfo.ProviderFlags", Field, 2}, - {"WSAProtocolInfo.ProviderId", Field, 2}, - {"WSAProtocolInfo.ProviderReserved", Field, 2}, - {"WSAProtocolInfo.SecurityScheme", Field, 2}, - {"WSAProtocolInfo.ServiceFlags1", Field, 2}, - {"WSAProtocolInfo.ServiceFlags2", Field, 2}, - {"WSAProtocolInfo.ServiceFlags3", Field, 2}, - {"WSAProtocolInfo.ServiceFlags4", Field, 2}, - {"WSAProtocolInfo.SocketType", Field, 2}, - {"WSAProtocolInfo.Version", Field, 2}, - {"WSARecv", Func, 0}, - {"WSARecvFrom", Func, 0}, - {"WSASYS_STATUS_LEN", Const, 0}, - {"WSASend", Func, 0}, - {"WSASendTo", Func, 0}, - {"WSASendto", Func, 0}, - {"WSAStartup", Func, 0}, - {"WSTOPPED", Const, 0}, - {"WTRAPPED", Const, 1}, - {"WUNTRACED", Const, 0}, - {"Wait4", Func, 0}, - {"WaitForSingleObject", Func, 0}, - {"WaitStatus", Type, 0}, - {"WaitStatus.ExitCode", Field, 0}, - {"Win32FileAttributeData", Type, 0}, - {"Win32FileAttributeData.CreationTime", Field, 0}, - {"Win32FileAttributeData.FileAttributes", Field, 0}, - {"Win32FileAttributeData.FileSizeHigh", Field, 0}, - {"Win32FileAttributeData.FileSizeLow", Field, 0}, - {"Win32FileAttributeData.LastAccessTime", Field, 0}, - {"Win32FileAttributeData.LastWriteTime", Field, 0}, - {"Win32finddata", Type, 0}, - {"Win32finddata.AlternateFileName", Field, 0}, - {"Win32finddata.CreationTime", Field, 0}, - {"Win32finddata.FileAttributes", Field, 0}, - {"Win32finddata.FileName", Field, 0}, - {"Win32finddata.FileSizeHigh", Field, 0}, - {"Win32finddata.FileSizeLow", Field, 0}, - {"Win32finddata.LastAccessTime", Field, 0}, - {"Win32finddata.LastWriteTime", Field, 0}, - {"Win32finddata.Reserved0", Field, 0}, - {"Win32finddata.Reserved1", Field, 0}, - {"Write", Func, 0}, - {"WriteConsole", Func, 1}, - {"WriteFile", Func, 0}, - {"X509_ASN_ENCODING", Const, 0}, - {"XCASE", Const, 0}, - {"XP1_CONNECTIONLESS", Const, 2}, - {"XP1_CONNECT_DATA", Const, 2}, - {"XP1_DISCONNECT_DATA", Const, 2}, - {"XP1_EXPEDITED_DATA", Const, 2}, - {"XP1_GRACEFUL_CLOSE", Const, 2}, - {"XP1_GUARANTEED_DELIVERY", Const, 2}, - {"XP1_GUARANTEED_ORDER", Const, 2}, - {"XP1_IFS_HANDLES", Const, 2}, - {"XP1_MESSAGE_ORIENTED", Const, 2}, - {"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2}, - {"XP1_MULTIPOINT_DATA_PLANE", Const, 2}, - {"XP1_PARTIAL_MESSAGE", Const, 2}, - {"XP1_PSEUDO_STREAM", Const, 2}, - {"XP1_QOS_SUPPORTED", Const, 2}, - {"XP1_SAN_SUPPORT_SDP", Const, 2}, - {"XP1_SUPPORT_BROADCAST", Const, 2}, - {"XP1_SUPPORT_MULTIPOINT", Const, 2}, - {"XP1_UNI_RECV", Const, 2}, - {"XP1_UNI_SEND", Const, 2}, - }, - "syscall/js": { - {"CopyBytesToGo", Func, 0}, - {"CopyBytesToJS", Func, 0}, - {"Error", Type, 0}, - {"Func", Type, 0}, - {"FuncOf", Func, 0}, - {"Global", Func, 0}, - {"Null", Func, 0}, - {"Type", Type, 0}, - {"TypeBoolean", Const, 0}, - {"TypeFunction", Const, 0}, - {"TypeNull", Const, 0}, - {"TypeNumber", Const, 0}, - {"TypeObject", Const, 0}, - {"TypeString", Const, 0}, - {"TypeSymbol", Const, 0}, - {"TypeUndefined", Const, 0}, - {"Undefined", Func, 0}, - {"Value", Type, 0}, - {"ValueError", Type, 0}, - {"ValueOf", Func, 0}, - }, - "testing": { - {"(*B).Chdir", Method, 24}, - {"(*B).Cleanup", Method, 14}, - {"(*B).Context", Method, 24}, - {"(*B).Elapsed", Method, 20}, - {"(*B).Error", Method, 0}, - {"(*B).Errorf", Method, 0}, - {"(*B).Fail", Method, 0}, - {"(*B).FailNow", Method, 0}, - {"(*B).Failed", Method, 0}, - {"(*B).Fatal", Method, 0}, - {"(*B).Fatalf", Method, 0}, - {"(*B).Helper", Method, 9}, - {"(*B).Log", Method, 0}, - {"(*B).Logf", Method, 0}, - {"(*B).Loop", Method, 24}, - {"(*B).Name", Method, 8}, - {"(*B).ReportAllocs", Method, 1}, - {"(*B).ReportMetric", Method, 13}, - {"(*B).ResetTimer", Method, 0}, - {"(*B).Run", Method, 7}, - {"(*B).RunParallel", Method, 3}, - {"(*B).SetBytes", Method, 0}, - {"(*B).SetParallelism", Method, 3}, - {"(*B).Setenv", Method, 17}, - {"(*B).Skip", Method, 1}, - {"(*B).SkipNow", Method, 1}, - {"(*B).Skipf", Method, 1}, - {"(*B).Skipped", Method, 1}, - {"(*B).StartTimer", Method, 0}, - {"(*B).StopTimer", Method, 0}, - {"(*B).TempDir", Method, 15}, - {"(*F).Add", Method, 18}, - {"(*F).Chdir", Method, 24}, - {"(*F).Cleanup", Method, 18}, - {"(*F).Context", Method, 24}, - {"(*F).Error", Method, 18}, - {"(*F).Errorf", Method, 18}, - {"(*F).Fail", Method, 18}, - {"(*F).FailNow", Method, 18}, - {"(*F).Failed", Method, 18}, - {"(*F).Fatal", Method, 18}, - {"(*F).Fatalf", Method, 18}, - {"(*F).Fuzz", Method, 18}, - {"(*F).Helper", Method, 18}, - {"(*F).Log", Method, 18}, - {"(*F).Logf", Method, 18}, - {"(*F).Name", Method, 18}, - {"(*F).Setenv", Method, 18}, - {"(*F).Skip", Method, 18}, - {"(*F).SkipNow", Method, 18}, - {"(*F).Skipf", Method, 18}, - {"(*F).Skipped", Method, 18}, - {"(*F).TempDir", Method, 18}, - {"(*M).Run", Method, 4}, - {"(*PB).Next", Method, 3}, - {"(*T).Chdir", Method, 24}, - {"(*T).Cleanup", Method, 14}, - {"(*T).Context", Method, 24}, - {"(*T).Deadline", Method, 15}, - {"(*T).Error", Method, 0}, - {"(*T).Errorf", Method, 0}, - {"(*T).Fail", Method, 0}, - {"(*T).FailNow", Method, 0}, - {"(*T).Failed", Method, 0}, - {"(*T).Fatal", Method, 0}, - {"(*T).Fatalf", Method, 0}, - {"(*T).Helper", Method, 9}, - {"(*T).Log", Method, 0}, - {"(*T).Logf", Method, 0}, - {"(*T).Name", Method, 8}, - {"(*T).Parallel", Method, 0}, - {"(*T).Run", Method, 7}, - {"(*T).Setenv", Method, 17}, - {"(*T).Skip", Method, 1}, - {"(*T).SkipNow", Method, 1}, - {"(*T).Skipf", Method, 1}, - {"(*T).Skipped", Method, 1}, - {"(*T).TempDir", Method, 15}, - {"(BenchmarkResult).AllocedBytesPerOp", Method, 1}, - {"(BenchmarkResult).AllocsPerOp", Method, 1}, - {"(BenchmarkResult).MemString", Method, 1}, - {"(BenchmarkResult).NsPerOp", Method, 0}, - {"(BenchmarkResult).String", Method, 0}, - {"AllocsPerRun", Func, 1}, - {"B", Type, 0}, - {"B.N", Field, 0}, - {"Benchmark", Func, 0}, - {"BenchmarkResult", Type, 0}, - {"BenchmarkResult.Bytes", Field, 0}, - {"BenchmarkResult.Extra", Field, 13}, - {"BenchmarkResult.MemAllocs", Field, 1}, - {"BenchmarkResult.MemBytes", Field, 1}, - {"BenchmarkResult.N", Field, 0}, - {"BenchmarkResult.T", Field, 0}, - {"Cover", Type, 2}, - {"Cover.Blocks", Field, 2}, - {"Cover.Counters", Field, 2}, - {"Cover.CoveredPackages", Field, 2}, - {"Cover.Mode", Field, 2}, - {"CoverBlock", Type, 2}, - {"CoverBlock.Col0", Field, 2}, - {"CoverBlock.Col1", Field, 2}, - {"CoverBlock.Line0", Field, 2}, - {"CoverBlock.Line1", Field, 2}, - {"CoverBlock.Stmts", Field, 2}, - {"CoverMode", Func, 8}, - {"Coverage", Func, 4}, - {"F", Type, 18}, - {"Init", Func, 13}, - {"InternalBenchmark", Type, 0}, - {"InternalBenchmark.F", Field, 0}, - {"InternalBenchmark.Name", Field, 0}, - {"InternalExample", Type, 0}, - {"InternalExample.F", Field, 0}, - {"InternalExample.Name", Field, 0}, - {"InternalExample.Output", Field, 0}, - {"InternalExample.Unordered", Field, 7}, - {"InternalFuzzTarget", Type, 18}, - {"InternalFuzzTarget.Fn", Field, 18}, - {"InternalFuzzTarget.Name", Field, 18}, - {"InternalTest", Type, 0}, - {"InternalTest.F", Field, 0}, - {"InternalTest.Name", Field, 0}, - {"M", Type, 4}, - {"Main", Func, 0}, - {"MainStart", Func, 4}, - {"PB", Type, 3}, - {"RegisterCover", Func, 2}, - {"RunBenchmarks", Func, 0}, - {"RunExamples", Func, 0}, - {"RunTests", Func, 0}, - {"Short", Func, 0}, - {"T", Type, 0}, - {"TB", Type, 2}, - {"Testing", Func, 21}, - {"Verbose", Func, 1}, - }, - "testing/fstest": { - {"(MapFS).Glob", Method, 16}, - {"(MapFS).Open", Method, 16}, - {"(MapFS).ReadDir", Method, 16}, - {"(MapFS).ReadFile", Method, 16}, - {"(MapFS).Stat", Method, 16}, - {"(MapFS).Sub", Method, 16}, - {"MapFS", Type, 16}, - {"MapFile", Type, 16}, - {"MapFile.Data", Field, 16}, - {"MapFile.ModTime", Field, 16}, - {"MapFile.Mode", Field, 16}, - {"MapFile.Sys", Field, 16}, - {"TestFS", Func, 16}, - }, - "testing/iotest": { - {"DataErrReader", Func, 0}, - {"ErrReader", Func, 16}, - {"ErrTimeout", Var, 0}, - {"HalfReader", Func, 0}, - {"NewReadLogger", Func, 0}, - {"NewWriteLogger", Func, 0}, - {"OneByteReader", Func, 0}, - {"TestReader", Func, 16}, - {"TimeoutReader", Func, 0}, - {"TruncateWriter", Func, 0}, - }, - "testing/quick": { - {"(*CheckEqualError).Error", Method, 0}, - {"(*CheckError).Error", Method, 0}, - {"(SetupError).Error", Method, 0}, - {"Check", Func, 0}, - {"CheckEqual", Func, 0}, - {"CheckEqualError", Type, 0}, - {"CheckEqualError.CheckError", Field, 0}, - {"CheckEqualError.Out1", Field, 0}, - {"CheckEqualError.Out2", Field, 0}, - {"CheckError", Type, 0}, - {"CheckError.Count", Field, 0}, - {"CheckError.In", Field, 0}, - {"Config", Type, 0}, - {"Config.MaxCount", Field, 0}, - {"Config.MaxCountScale", Field, 0}, - {"Config.Rand", Field, 0}, - {"Config.Values", Field, 0}, - {"Generator", Type, 0}, - {"SetupError", Type, 0}, - {"Value", Func, 0}, - }, - "testing/slogtest": { - {"Run", Func, 22}, - {"TestHandler", Func, 21}, - }, - "text/scanner": { - {"(*Position).IsValid", Method, 0}, - {"(*Scanner).Init", Method, 0}, - {"(*Scanner).IsValid", Method, 0}, - {"(*Scanner).Next", Method, 0}, - {"(*Scanner).Peek", Method, 0}, - {"(*Scanner).Pos", Method, 0}, - {"(*Scanner).Scan", Method, 0}, - {"(*Scanner).TokenText", Method, 0}, - {"(Position).String", Method, 0}, - {"(Scanner).String", Method, 0}, - {"Char", Const, 0}, - {"Comment", Const, 0}, - {"EOF", Const, 0}, - {"Float", Const, 0}, - {"GoTokens", Const, 0}, - {"GoWhitespace", Const, 0}, - {"Ident", Const, 0}, - {"Int", Const, 0}, - {"Position", Type, 0}, - {"Position.Column", Field, 0}, - {"Position.Filename", Field, 0}, - {"Position.Line", Field, 0}, - {"Position.Offset", Field, 0}, - {"RawString", Const, 0}, - {"ScanChars", Const, 0}, - {"ScanComments", Const, 0}, - {"ScanFloats", Const, 0}, - {"ScanIdents", Const, 0}, - {"ScanInts", Const, 0}, - {"ScanRawStrings", Const, 0}, - {"ScanStrings", Const, 0}, - {"Scanner", Type, 0}, - {"Scanner.Error", Field, 0}, - {"Scanner.ErrorCount", Field, 0}, - {"Scanner.IsIdentRune", Field, 4}, - {"Scanner.Mode", Field, 0}, - {"Scanner.Position", Field, 0}, - {"Scanner.Whitespace", Field, 0}, - {"SkipComments", Const, 0}, - {"String", Const, 0}, - {"TokenString", Func, 0}, - }, - "text/tabwriter": { - {"(*Writer).Flush", Method, 0}, - {"(*Writer).Init", Method, 0}, - {"(*Writer).Write", Method, 0}, - {"AlignRight", Const, 0}, - {"Debug", Const, 0}, - {"DiscardEmptyColumns", Const, 0}, - {"Escape", Const, 0}, - {"FilterHTML", Const, 0}, - {"NewWriter", Func, 0}, - {"StripEscape", Const, 0}, - {"TabIndent", Const, 0}, - {"Writer", Type, 0}, - }, - "text/template": { - {"(*Template).AddParseTree", Method, 0}, - {"(*Template).Clone", Method, 0}, - {"(*Template).DefinedTemplates", Method, 5}, - {"(*Template).Delims", Method, 0}, - {"(*Template).Execute", Method, 0}, - {"(*Template).ExecuteTemplate", Method, 0}, - {"(*Template).Funcs", Method, 0}, - {"(*Template).Lookup", Method, 0}, - {"(*Template).Name", Method, 0}, - {"(*Template).New", Method, 0}, - {"(*Template).Option", Method, 5}, - {"(*Template).Parse", Method, 0}, - {"(*Template).ParseFS", Method, 16}, - {"(*Template).ParseFiles", Method, 0}, - {"(*Template).ParseGlob", Method, 0}, - {"(*Template).Templates", Method, 0}, - {"(ExecError).Error", Method, 6}, - {"(ExecError).Unwrap", Method, 13}, - {"(Template).Copy", Method, 2}, - {"(Template).ErrorContext", Method, 1}, - {"ExecError", Type, 6}, - {"ExecError.Err", Field, 6}, - {"ExecError.Name", Field, 6}, - {"FuncMap", Type, 0}, - {"HTMLEscape", Func, 0}, - {"HTMLEscapeString", Func, 0}, - {"HTMLEscaper", Func, 0}, - {"IsTrue", Func, 6}, - {"JSEscape", Func, 0}, - {"JSEscapeString", Func, 0}, - {"JSEscaper", Func, 0}, - {"Must", Func, 0}, - {"New", Func, 0}, - {"ParseFS", Func, 16}, - {"ParseFiles", Func, 0}, - {"ParseGlob", Func, 0}, - {"Template", Type, 0}, - {"Template.Tree", Field, 0}, - {"URLQueryEscaper", Func, 0}, - }, - "text/template/parse": { - {"(*ActionNode).Copy", Method, 0}, - {"(*ActionNode).String", Method, 0}, - {"(*BoolNode).Copy", Method, 0}, - {"(*BoolNode).String", Method, 0}, - {"(*BranchNode).Copy", Method, 4}, - {"(*BranchNode).String", Method, 0}, - {"(*BreakNode).Copy", Method, 18}, - {"(*BreakNode).String", Method, 18}, - {"(*ChainNode).Add", Method, 1}, - {"(*ChainNode).Copy", Method, 1}, - {"(*ChainNode).String", Method, 1}, - {"(*CommandNode).Copy", Method, 0}, - {"(*CommandNode).String", Method, 0}, - {"(*CommentNode).Copy", Method, 16}, - {"(*CommentNode).String", Method, 16}, - {"(*ContinueNode).Copy", Method, 18}, - {"(*ContinueNode).String", Method, 18}, - {"(*DotNode).Copy", Method, 0}, - {"(*DotNode).String", Method, 0}, - {"(*DotNode).Type", Method, 0}, - {"(*FieldNode).Copy", Method, 0}, - {"(*FieldNode).String", Method, 0}, - {"(*IdentifierNode).Copy", Method, 0}, - {"(*IdentifierNode).SetPos", Method, 1}, - {"(*IdentifierNode).SetTree", Method, 4}, - {"(*IdentifierNode).String", Method, 0}, - {"(*IfNode).Copy", Method, 0}, - {"(*IfNode).String", Method, 0}, - {"(*ListNode).Copy", Method, 0}, - {"(*ListNode).CopyList", Method, 0}, - {"(*ListNode).String", Method, 0}, - {"(*NilNode).Copy", Method, 1}, - {"(*NilNode).String", Method, 1}, - {"(*NilNode).Type", Method, 1}, - {"(*NumberNode).Copy", Method, 0}, - {"(*NumberNode).String", Method, 0}, - {"(*PipeNode).Copy", Method, 0}, - {"(*PipeNode).CopyPipe", Method, 0}, - {"(*PipeNode).String", Method, 0}, - {"(*RangeNode).Copy", Method, 0}, - {"(*RangeNode).String", Method, 0}, - {"(*StringNode).Copy", Method, 0}, - {"(*StringNode).String", Method, 0}, - {"(*TemplateNode).Copy", Method, 0}, - {"(*TemplateNode).String", Method, 0}, - {"(*TextNode).Copy", Method, 0}, - {"(*TextNode).String", Method, 0}, - {"(*Tree).Copy", Method, 2}, - {"(*Tree).ErrorContext", Method, 1}, - {"(*Tree).Parse", Method, 0}, - {"(*VariableNode).Copy", Method, 0}, - {"(*VariableNode).String", Method, 0}, - {"(*WithNode).Copy", Method, 0}, - {"(*WithNode).String", Method, 0}, - {"(ActionNode).Position", Method, 1}, - {"(ActionNode).Type", Method, 0}, - {"(BoolNode).Position", Method, 1}, - {"(BoolNode).Type", Method, 0}, - {"(BranchNode).Position", Method, 1}, - {"(BranchNode).Type", Method, 0}, - {"(BreakNode).Position", Method, 18}, - {"(BreakNode).Type", Method, 18}, - {"(ChainNode).Position", Method, 1}, - {"(ChainNode).Type", Method, 1}, - {"(CommandNode).Position", Method, 1}, - {"(CommandNode).Type", Method, 0}, - {"(CommentNode).Position", Method, 16}, - {"(CommentNode).Type", Method, 16}, - {"(ContinueNode).Position", Method, 18}, - {"(ContinueNode).Type", Method, 18}, - {"(DotNode).Position", Method, 1}, - {"(FieldNode).Position", Method, 1}, - {"(FieldNode).Type", Method, 0}, - {"(IdentifierNode).Position", Method, 1}, - {"(IdentifierNode).Type", Method, 0}, - {"(IfNode).Position", Method, 1}, - {"(IfNode).Type", Method, 0}, - {"(ListNode).Position", Method, 1}, - {"(ListNode).Type", Method, 0}, - {"(NilNode).Position", Method, 1}, - {"(NodeType).Type", Method, 0}, - {"(NumberNode).Position", Method, 1}, - {"(NumberNode).Type", Method, 0}, - {"(PipeNode).Position", Method, 1}, - {"(PipeNode).Type", Method, 0}, - {"(Pos).Position", Method, 1}, - {"(RangeNode).Position", Method, 1}, - {"(RangeNode).Type", Method, 0}, - {"(StringNode).Position", Method, 1}, - {"(StringNode).Type", Method, 0}, - {"(TemplateNode).Position", Method, 1}, - {"(TemplateNode).Type", Method, 0}, - {"(TextNode).Position", Method, 1}, - {"(TextNode).Type", Method, 0}, - {"(VariableNode).Position", Method, 1}, - {"(VariableNode).Type", Method, 0}, - {"(WithNode).Position", Method, 1}, - {"(WithNode).Type", Method, 0}, - {"ActionNode", Type, 0}, - {"ActionNode.Line", Field, 0}, - {"ActionNode.NodeType", Field, 0}, - {"ActionNode.Pipe", Field, 0}, - {"ActionNode.Pos", Field, 1}, - {"BoolNode", Type, 0}, - {"BoolNode.NodeType", Field, 0}, - {"BoolNode.Pos", Field, 1}, - {"BoolNode.True", Field, 0}, - {"BranchNode", Type, 0}, - {"BranchNode.ElseList", Field, 0}, - {"BranchNode.Line", Field, 0}, - {"BranchNode.List", Field, 0}, - {"BranchNode.NodeType", Field, 0}, - {"BranchNode.Pipe", Field, 0}, - {"BranchNode.Pos", Field, 1}, - {"BreakNode", Type, 18}, - {"BreakNode.Line", Field, 18}, - {"BreakNode.NodeType", Field, 18}, - {"BreakNode.Pos", Field, 18}, - {"ChainNode", Type, 1}, - {"ChainNode.Field", Field, 1}, - {"ChainNode.Node", Field, 1}, - {"ChainNode.NodeType", Field, 1}, - {"ChainNode.Pos", Field, 1}, - {"CommandNode", Type, 0}, - {"CommandNode.Args", Field, 0}, - {"CommandNode.NodeType", Field, 0}, - {"CommandNode.Pos", Field, 1}, - {"CommentNode", Type, 16}, - {"CommentNode.NodeType", Field, 16}, - {"CommentNode.Pos", Field, 16}, - {"CommentNode.Text", Field, 16}, - {"ContinueNode", Type, 18}, - {"ContinueNode.Line", Field, 18}, - {"ContinueNode.NodeType", Field, 18}, - {"ContinueNode.Pos", Field, 18}, - {"DotNode", Type, 0}, - {"DotNode.NodeType", Field, 4}, - {"DotNode.Pos", Field, 1}, - {"FieldNode", Type, 0}, - {"FieldNode.Ident", Field, 0}, - {"FieldNode.NodeType", Field, 0}, - {"FieldNode.Pos", Field, 1}, - {"IdentifierNode", Type, 0}, - {"IdentifierNode.Ident", Field, 0}, - {"IdentifierNode.NodeType", Field, 0}, - {"IdentifierNode.Pos", Field, 1}, - {"IfNode", Type, 0}, - {"IfNode.BranchNode", Field, 0}, - {"IsEmptyTree", Func, 0}, - {"ListNode", Type, 0}, - {"ListNode.NodeType", Field, 0}, - {"ListNode.Nodes", Field, 0}, - {"ListNode.Pos", Field, 1}, - {"Mode", Type, 16}, - {"New", Func, 0}, - {"NewIdentifier", Func, 0}, - {"NilNode", Type, 1}, - {"NilNode.NodeType", Field, 4}, - {"NilNode.Pos", Field, 1}, - {"Node", Type, 0}, - {"NodeAction", Const, 0}, - {"NodeBool", Const, 0}, - {"NodeBreak", Const, 18}, - {"NodeChain", Const, 1}, - {"NodeCommand", Const, 0}, - {"NodeComment", Const, 16}, - {"NodeContinue", Const, 18}, - {"NodeDot", Const, 0}, - {"NodeField", Const, 0}, - {"NodeIdentifier", Const, 0}, - {"NodeIf", Const, 0}, - {"NodeList", Const, 0}, - {"NodeNil", Const, 1}, - {"NodeNumber", Const, 0}, - {"NodePipe", Const, 0}, - {"NodeRange", Const, 0}, - {"NodeString", Const, 0}, - {"NodeTemplate", Const, 0}, - {"NodeText", Const, 0}, - {"NodeType", Type, 0}, - {"NodeVariable", Const, 0}, - {"NodeWith", Const, 0}, - {"NumberNode", Type, 0}, - {"NumberNode.Complex128", Field, 0}, - {"NumberNode.Float64", Field, 0}, - {"NumberNode.Int64", Field, 0}, - {"NumberNode.IsComplex", Field, 0}, - {"NumberNode.IsFloat", Field, 0}, - {"NumberNode.IsInt", Field, 0}, - {"NumberNode.IsUint", Field, 0}, - {"NumberNode.NodeType", Field, 0}, - {"NumberNode.Pos", Field, 1}, - {"NumberNode.Text", Field, 0}, - {"NumberNode.Uint64", Field, 0}, - {"Parse", Func, 0}, - {"ParseComments", Const, 16}, - {"PipeNode", Type, 0}, - {"PipeNode.Cmds", Field, 0}, - {"PipeNode.Decl", Field, 0}, - {"PipeNode.IsAssign", Field, 11}, - {"PipeNode.Line", Field, 0}, - {"PipeNode.NodeType", Field, 0}, - {"PipeNode.Pos", Field, 1}, - {"Pos", Type, 1}, - {"RangeNode", Type, 0}, - {"RangeNode.BranchNode", Field, 0}, - {"SkipFuncCheck", Const, 17}, - {"StringNode", Type, 0}, - {"StringNode.NodeType", Field, 0}, - {"StringNode.Pos", Field, 1}, - {"StringNode.Quoted", Field, 0}, - {"StringNode.Text", Field, 0}, - {"TemplateNode", Type, 0}, - {"TemplateNode.Line", Field, 0}, - {"TemplateNode.Name", Field, 0}, - {"TemplateNode.NodeType", Field, 0}, - {"TemplateNode.Pipe", Field, 0}, - {"TemplateNode.Pos", Field, 1}, - {"TextNode", Type, 0}, - {"TextNode.NodeType", Field, 0}, - {"TextNode.Pos", Field, 1}, - {"TextNode.Text", Field, 0}, - {"Tree", Type, 0}, - {"Tree.Mode", Field, 16}, - {"Tree.Name", Field, 0}, - {"Tree.ParseName", Field, 1}, - {"Tree.Root", Field, 0}, - {"VariableNode", Type, 0}, - {"VariableNode.Ident", Field, 0}, - {"VariableNode.NodeType", Field, 0}, - {"VariableNode.Pos", Field, 1}, - {"WithNode", Type, 0}, - {"WithNode.BranchNode", Field, 0}, - }, - "time": { - {"(*Location).String", Method, 0}, - {"(*ParseError).Error", Method, 0}, - {"(*Ticker).Reset", Method, 15}, - {"(*Ticker).Stop", Method, 0}, - {"(*Time).GobDecode", Method, 0}, - {"(*Time).UnmarshalBinary", Method, 2}, - {"(*Time).UnmarshalJSON", Method, 0}, - {"(*Time).UnmarshalText", Method, 2}, - {"(*Timer).Reset", Method, 1}, - {"(*Timer).Stop", Method, 0}, - {"(Duration).Abs", Method, 19}, - {"(Duration).Hours", Method, 0}, - {"(Duration).Microseconds", Method, 13}, - {"(Duration).Milliseconds", Method, 13}, - {"(Duration).Minutes", Method, 0}, - {"(Duration).Nanoseconds", Method, 0}, - {"(Duration).Round", Method, 9}, - {"(Duration).Seconds", Method, 0}, - {"(Duration).String", Method, 0}, - {"(Duration).Truncate", Method, 9}, - {"(Month).String", Method, 0}, - {"(Time).Add", Method, 0}, - {"(Time).AddDate", Method, 0}, - {"(Time).After", Method, 0}, - {"(Time).AppendBinary", Method, 24}, - {"(Time).AppendFormat", Method, 5}, - {"(Time).AppendText", Method, 24}, - {"(Time).Before", Method, 0}, - {"(Time).Clock", Method, 0}, - {"(Time).Compare", Method, 20}, - {"(Time).Date", Method, 0}, - {"(Time).Day", Method, 0}, - {"(Time).Equal", Method, 0}, - {"(Time).Format", Method, 0}, - {"(Time).GoString", Method, 17}, - {"(Time).GobEncode", Method, 0}, - {"(Time).Hour", Method, 0}, - {"(Time).ISOWeek", Method, 0}, - {"(Time).In", Method, 0}, - {"(Time).IsDST", Method, 17}, - {"(Time).IsZero", Method, 0}, - {"(Time).Local", Method, 0}, - {"(Time).Location", Method, 0}, - {"(Time).MarshalBinary", Method, 2}, - {"(Time).MarshalJSON", Method, 0}, - {"(Time).MarshalText", Method, 2}, - {"(Time).Minute", Method, 0}, - {"(Time).Month", Method, 0}, - {"(Time).Nanosecond", Method, 0}, - {"(Time).Round", Method, 1}, - {"(Time).Second", Method, 0}, - {"(Time).String", Method, 0}, - {"(Time).Sub", Method, 0}, - {"(Time).Truncate", Method, 1}, - {"(Time).UTC", Method, 0}, - {"(Time).Unix", Method, 0}, - {"(Time).UnixMicro", Method, 17}, - {"(Time).UnixMilli", Method, 17}, - {"(Time).UnixNano", Method, 0}, - {"(Time).Weekday", Method, 0}, - {"(Time).Year", Method, 0}, - {"(Time).YearDay", Method, 1}, - {"(Time).Zone", Method, 0}, - {"(Time).ZoneBounds", Method, 19}, - {"(Weekday).String", Method, 0}, - {"ANSIC", Const, 0}, - {"After", Func, 0}, - {"AfterFunc", Func, 0}, - {"April", Const, 0}, - {"August", Const, 0}, - {"Date", Func, 0}, - {"DateOnly", Const, 20}, - {"DateTime", Const, 20}, - {"December", Const, 0}, - {"Duration", Type, 0}, - {"February", Const, 0}, - {"FixedZone", Func, 0}, - {"Friday", Const, 0}, - {"Hour", Const, 0}, - {"January", Const, 0}, - {"July", Const, 0}, - {"June", Const, 0}, - {"Kitchen", Const, 0}, - {"Layout", Const, 17}, - {"LoadLocation", Func, 0}, - {"LoadLocationFromTZData", Func, 10}, - {"Local", Var, 0}, - {"Location", Type, 0}, - {"March", Const, 0}, - {"May", Const, 0}, - {"Microsecond", Const, 0}, - {"Millisecond", Const, 0}, - {"Minute", Const, 0}, - {"Monday", Const, 0}, - {"Month", Type, 0}, - {"Nanosecond", Const, 0}, - {"NewTicker", Func, 0}, - {"NewTimer", Func, 0}, - {"November", Const, 0}, - {"Now", Func, 0}, - {"October", Const, 0}, - {"Parse", Func, 0}, - {"ParseDuration", Func, 0}, - {"ParseError", Type, 0}, - {"ParseError.Layout", Field, 0}, - {"ParseError.LayoutElem", Field, 0}, - {"ParseError.Message", Field, 0}, - {"ParseError.Value", Field, 0}, - {"ParseError.ValueElem", Field, 0}, - {"ParseInLocation", Func, 1}, - {"RFC1123", Const, 0}, - {"RFC1123Z", Const, 0}, - {"RFC3339", Const, 0}, - {"RFC3339Nano", Const, 0}, - {"RFC822", Const, 0}, - {"RFC822Z", Const, 0}, - {"RFC850", Const, 0}, - {"RubyDate", Const, 0}, - {"Saturday", Const, 0}, - {"Second", Const, 0}, - {"September", Const, 0}, - {"Since", Func, 0}, - {"Sleep", Func, 0}, - {"Stamp", Const, 0}, - {"StampMicro", Const, 0}, - {"StampMilli", Const, 0}, - {"StampNano", Const, 0}, - {"Sunday", Const, 0}, - {"Thursday", Const, 0}, - {"Tick", Func, 0}, - {"Ticker", Type, 0}, - {"Ticker.C", Field, 0}, - {"Time", Type, 0}, - {"TimeOnly", Const, 20}, - {"Timer", Type, 0}, - {"Timer.C", Field, 0}, - {"Tuesday", Const, 0}, - {"UTC", Var, 0}, - {"Unix", Func, 0}, - {"UnixDate", Const, 0}, - {"UnixMicro", Func, 17}, - {"UnixMilli", Func, 17}, - {"Until", Func, 8}, - {"Wednesday", Const, 0}, - {"Weekday", Type, 0}, - }, - "unicode": { - {"(SpecialCase).ToLower", Method, 0}, - {"(SpecialCase).ToTitle", Method, 0}, - {"(SpecialCase).ToUpper", Method, 0}, - {"ASCII_Hex_Digit", Var, 0}, - {"Adlam", Var, 7}, - {"Ahom", Var, 5}, - {"Anatolian_Hieroglyphs", Var, 5}, - {"Arabic", Var, 0}, - {"Armenian", Var, 0}, - {"Avestan", Var, 0}, - {"AzeriCase", Var, 0}, - {"Balinese", Var, 0}, - {"Bamum", Var, 0}, - {"Bassa_Vah", Var, 4}, - {"Batak", Var, 0}, - {"Bengali", Var, 0}, - {"Bhaiksuki", Var, 7}, - {"Bidi_Control", Var, 0}, - {"Bopomofo", Var, 0}, - {"Brahmi", Var, 0}, - {"Braille", Var, 0}, - {"Buginese", Var, 0}, - {"Buhid", Var, 0}, - {"C", Var, 0}, - {"Canadian_Aboriginal", Var, 0}, - {"Carian", Var, 0}, - {"CaseRange", Type, 0}, - {"CaseRange.Delta", Field, 0}, - {"CaseRange.Hi", Field, 0}, - {"CaseRange.Lo", Field, 0}, - {"CaseRanges", Var, 0}, - {"Categories", Var, 0}, - {"Caucasian_Albanian", Var, 4}, - {"Cc", Var, 0}, - {"Cf", Var, 0}, - {"Chakma", Var, 1}, - {"Cham", Var, 0}, - {"Cherokee", Var, 0}, - {"Chorasmian", Var, 16}, - {"Co", Var, 0}, - {"Common", Var, 0}, - {"Coptic", Var, 0}, - {"Cs", Var, 0}, - {"Cuneiform", Var, 0}, - {"Cypriot", Var, 0}, - {"Cypro_Minoan", Var, 21}, - {"Cyrillic", Var, 0}, - {"Dash", Var, 0}, - {"Deprecated", Var, 0}, - {"Deseret", Var, 0}, - {"Devanagari", Var, 0}, - {"Diacritic", Var, 0}, - {"Digit", Var, 0}, - {"Dives_Akuru", Var, 16}, - {"Dogra", Var, 13}, - {"Duployan", Var, 4}, - {"Egyptian_Hieroglyphs", Var, 0}, - {"Elbasan", Var, 4}, - {"Elymaic", Var, 14}, - {"Ethiopic", Var, 0}, - {"Extender", Var, 0}, - {"FoldCategory", Var, 0}, - {"FoldScript", Var, 0}, - {"Georgian", Var, 0}, - {"Glagolitic", Var, 0}, - {"Gothic", Var, 0}, - {"Grantha", Var, 4}, - {"GraphicRanges", Var, 0}, - {"Greek", Var, 0}, - {"Gujarati", Var, 0}, - {"Gunjala_Gondi", Var, 13}, - {"Gurmukhi", Var, 0}, - {"Han", Var, 0}, - {"Hangul", Var, 0}, - {"Hanifi_Rohingya", Var, 13}, - {"Hanunoo", Var, 0}, - {"Hatran", Var, 5}, - {"Hebrew", Var, 0}, - {"Hex_Digit", Var, 0}, - {"Hiragana", Var, 0}, - {"Hyphen", Var, 0}, - {"IDS_Binary_Operator", Var, 0}, - {"IDS_Trinary_Operator", Var, 0}, - {"Ideographic", Var, 0}, - {"Imperial_Aramaic", Var, 0}, - {"In", Func, 2}, - {"Inherited", Var, 0}, - {"Inscriptional_Pahlavi", Var, 0}, - {"Inscriptional_Parthian", Var, 0}, - {"Is", Func, 0}, - {"IsControl", Func, 0}, - {"IsDigit", Func, 0}, - {"IsGraphic", Func, 0}, - {"IsLetter", Func, 0}, - {"IsLower", Func, 0}, - {"IsMark", Func, 0}, - {"IsNumber", Func, 0}, - {"IsOneOf", Func, 0}, - {"IsPrint", Func, 0}, - {"IsPunct", Func, 0}, - {"IsSpace", Func, 0}, - {"IsSymbol", Func, 0}, - {"IsTitle", Func, 0}, - {"IsUpper", Func, 0}, - {"Javanese", Var, 0}, - {"Join_Control", Var, 0}, - {"Kaithi", Var, 0}, - {"Kannada", Var, 0}, - {"Katakana", Var, 0}, - {"Kawi", Var, 21}, - {"Kayah_Li", Var, 0}, - {"Kharoshthi", Var, 0}, - {"Khitan_Small_Script", Var, 16}, - {"Khmer", Var, 0}, - {"Khojki", Var, 4}, - {"Khudawadi", Var, 4}, - {"L", Var, 0}, - {"Lao", Var, 0}, - {"Latin", Var, 0}, - {"Lepcha", Var, 0}, - {"Letter", Var, 0}, - {"Limbu", Var, 0}, - {"Linear_A", Var, 4}, - {"Linear_B", Var, 0}, - {"Lisu", Var, 0}, - {"Ll", Var, 0}, - {"Lm", Var, 0}, - {"Lo", Var, 0}, - {"Logical_Order_Exception", Var, 0}, - {"Lower", Var, 0}, - {"LowerCase", Const, 0}, - {"Lt", Var, 0}, - {"Lu", Var, 0}, - {"Lycian", Var, 0}, - {"Lydian", Var, 0}, - {"M", Var, 0}, - {"Mahajani", Var, 4}, - {"Makasar", Var, 13}, - {"Malayalam", Var, 0}, - {"Mandaic", Var, 0}, - {"Manichaean", Var, 4}, - {"Marchen", Var, 7}, - {"Mark", Var, 0}, - {"Masaram_Gondi", Var, 10}, - {"MaxASCII", Const, 0}, - {"MaxCase", Const, 0}, - {"MaxLatin1", Const, 0}, - {"MaxRune", Const, 0}, - {"Mc", Var, 0}, - {"Me", Var, 0}, - {"Medefaidrin", Var, 13}, - {"Meetei_Mayek", Var, 0}, - {"Mende_Kikakui", Var, 4}, - {"Meroitic_Cursive", Var, 1}, - {"Meroitic_Hieroglyphs", Var, 1}, - {"Miao", Var, 1}, - {"Mn", Var, 0}, - {"Modi", Var, 4}, - {"Mongolian", Var, 0}, - {"Mro", Var, 4}, - {"Multani", Var, 5}, - {"Myanmar", Var, 0}, - {"N", Var, 0}, - {"Nabataean", Var, 4}, - {"Nag_Mundari", Var, 21}, - {"Nandinagari", Var, 14}, - {"Nd", Var, 0}, - {"New_Tai_Lue", Var, 0}, - {"Newa", Var, 7}, - {"Nko", Var, 0}, - {"Nl", Var, 0}, - {"No", Var, 0}, - {"Noncharacter_Code_Point", Var, 0}, - {"Number", Var, 0}, - {"Nushu", Var, 10}, - {"Nyiakeng_Puachue_Hmong", Var, 14}, - {"Ogham", Var, 0}, - {"Ol_Chiki", Var, 0}, - {"Old_Hungarian", Var, 5}, - {"Old_Italic", Var, 0}, - {"Old_North_Arabian", Var, 4}, - {"Old_Permic", Var, 4}, - {"Old_Persian", Var, 0}, - {"Old_Sogdian", Var, 13}, - {"Old_South_Arabian", Var, 0}, - {"Old_Turkic", Var, 0}, - {"Old_Uyghur", Var, 21}, - {"Oriya", Var, 0}, - {"Osage", Var, 7}, - {"Osmanya", Var, 0}, - {"Other", Var, 0}, - {"Other_Alphabetic", Var, 0}, - {"Other_Default_Ignorable_Code_Point", Var, 0}, - {"Other_Grapheme_Extend", Var, 0}, - {"Other_ID_Continue", Var, 0}, - {"Other_ID_Start", Var, 0}, - {"Other_Lowercase", Var, 0}, - {"Other_Math", Var, 0}, - {"Other_Uppercase", Var, 0}, - {"P", Var, 0}, - {"Pahawh_Hmong", Var, 4}, - {"Palmyrene", Var, 4}, - {"Pattern_Syntax", Var, 0}, - {"Pattern_White_Space", Var, 0}, - {"Pau_Cin_Hau", Var, 4}, - {"Pc", Var, 0}, - {"Pd", Var, 0}, - {"Pe", Var, 0}, - {"Pf", Var, 0}, - {"Phags_Pa", Var, 0}, - {"Phoenician", Var, 0}, - {"Pi", Var, 0}, - {"Po", Var, 0}, - {"Prepended_Concatenation_Mark", Var, 7}, - {"PrintRanges", Var, 0}, - {"Properties", Var, 0}, - {"Ps", Var, 0}, - {"Psalter_Pahlavi", Var, 4}, - {"Punct", Var, 0}, - {"Quotation_Mark", Var, 0}, - {"Radical", Var, 0}, - {"Range16", Type, 0}, - {"Range16.Hi", Field, 0}, - {"Range16.Lo", Field, 0}, - {"Range16.Stride", Field, 0}, - {"Range32", Type, 0}, - {"Range32.Hi", Field, 0}, - {"Range32.Lo", Field, 0}, - {"Range32.Stride", Field, 0}, - {"RangeTable", Type, 0}, - {"RangeTable.LatinOffset", Field, 1}, - {"RangeTable.R16", Field, 0}, - {"RangeTable.R32", Field, 0}, - {"Regional_Indicator", Var, 10}, - {"Rejang", Var, 0}, - {"ReplacementChar", Const, 0}, - {"Runic", Var, 0}, - {"S", Var, 0}, - {"STerm", Var, 0}, - {"Samaritan", Var, 0}, - {"Saurashtra", Var, 0}, - {"Sc", Var, 0}, - {"Scripts", Var, 0}, - {"Sentence_Terminal", Var, 7}, - {"Sharada", Var, 1}, - {"Shavian", Var, 0}, - {"Siddham", Var, 4}, - {"SignWriting", Var, 5}, - {"SimpleFold", Func, 0}, - {"Sinhala", Var, 0}, - {"Sk", Var, 0}, - {"Sm", Var, 0}, - {"So", Var, 0}, - {"Soft_Dotted", Var, 0}, - {"Sogdian", Var, 13}, - {"Sora_Sompeng", Var, 1}, - {"Soyombo", Var, 10}, - {"Space", Var, 0}, - {"SpecialCase", Type, 0}, - {"Sundanese", Var, 0}, - {"Syloti_Nagri", Var, 0}, - {"Symbol", Var, 0}, - {"Syriac", Var, 0}, - {"Tagalog", Var, 0}, - {"Tagbanwa", Var, 0}, - {"Tai_Le", Var, 0}, - {"Tai_Tham", Var, 0}, - {"Tai_Viet", Var, 0}, - {"Takri", Var, 1}, - {"Tamil", Var, 0}, - {"Tangsa", Var, 21}, - {"Tangut", Var, 7}, - {"Telugu", Var, 0}, - {"Terminal_Punctuation", Var, 0}, - {"Thaana", Var, 0}, - {"Thai", Var, 0}, - {"Tibetan", Var, 0}, - {"Tifinagh", Var, 0}, - {"Tirhuta", Var, 4}, - {"Title", Var, 0}, - {"TitleCase", Const, 0}, - {"To", Func, 0}, - {"ToLower", Func, 0}, - {"ToTitle", Func, 0}, - {"ToUpper", Func, 0}, - {"Toto", Var, 21}, - {"TurkishCase", Var, 0}, - {"Ugaritic", Var, 0}, - {"Unified_Ideograph", Var, 0}, - {"Upper", Var, 0}, - {"UpperCase", Const, 0}, - {"UpperLower", Const, 0}, - {"Vai", Var, 0}, - {"Variation_Selector", Var, 0}, - {"Version", Const, 0}, - {"Vithkuqi", Var, 21}, - {"Wancho", Var, 14}, - {"Warang_Citi", Var, 4}, - {"White_Space", Var, 0}, - {"Yezidi", Var, 16}, - {"Yi", Var, 0}, - {"Z", Var, 0}, - {"Zanabazar_Square", Var, 10}, - {"Zl", Var, 0}, - {"Zp", Var, 0}, - {"Zs", Var, 0}, - }, - "unicode/utf16": { - {"AppendRune", Func, 20}, - {"Decode", Func, 0}, - {"DecodeRune", Func, 0}, - {"Encode", Func, 0}, - {"EncodeRune", Func, 0}, - {"IsSurrogate", Func, 0}, - {"RuneLen", Func, 23}, - }, - "unicode/utf8": { - {"AppendRune", Func, 18}, - {"DecodeLastRune", Func, 0}, - {"DecodeLastRuneInString", Func, 0}, - {"DecodeRune", Func, 0}, - {"DecodeRuneInString", Func, 0}, - {"EncodeRune", Func, 0}, - {"FullRune", Func, 0}, - {"FullRuneInString", Func, 0}, - {"MaxRune", Const, 0}, - {"RuneCount", Func, 0}, - {"RuneCountInString", Func, 0}, - {"RuneError", Const, 0}, - {"RuneLen", Func, 0}, - {"RuneSelf", Const, 0}, - {"RuneStart", Func, 0}, - {"UTFMax", Const, 0}, - {"Valid", Func, 0}, - {"ValidRune", Func, 1}, - {"ValidString", Func, 0}, - }, - "unique": { - {"(Handle).Value", Method, 23}, - {"Handle", Type, 23}, - {"Make", Func, 23}, - }, - "unsafe": { - {"Add", Func, 0}, - {"Alignof", Func, 0}, - {"Offsetof", Func, 0}, - {"Pointer", Type, 0}, - {"Sizeof", Func, 0}, - {"Slice", Func, 0}, - {"SliceData", Func, 0}, - {"String", Func, 0}, - {"StringData", Func, 0}, - }, - "weak": { - {"(Pointer).Value", Method, 24}, - {"Make", Func, 24}, - {"Pointer", Type, 24}, - }, -} diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go deleted file mode 100644 index 9890401..0000000 --- a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2022 The Go 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:generate go run generate.go - -// Package stdlib provides a table of all exported symbols in the -// standard library, along with the version at which they first -// appeared. -package stdlib - -import ( - "fmt" - "strings" -) - -type Symbol struct { - Name string - Kind Kind - Version Version // Go version that first included the symbol -} - -// A Kind indicates the kind of a symbol: -// function, variable, constant, type, and so on. -type Kind int8 - -const ( - Invalid Kind = iota // Example name: - Type // "Buffer" - Func // "Println" - Var // "EOF" - Const // "Pi" - Field // "Point.X" - Method // "(*Buffer).Grow" -) - -func (kind Kind) String() string { - return [...]string{ - Invalid: "invalid", - Type: "type", - Func: "func", - Var: "var", - Const: "const", - Field: "field", - Method: "method", - }[kind] -} - -// A Version represents a version of Go of the form "go1.%d". -type Version int8 - -// String returns a version string of the form "go1.23", without allocating. -func (v Version) String() string { return versions[v] } - -var versions [30]string // (increase constant as needed) - -func init() { - for i := range versions { - versions[i] = fmt.Sprintf("go1.%d", i) - } -} - -// HasPackage reports whether the specified package path is part of -// the standard library's public API. -func HasPackage(path string) bool { - _, ok := PackageSymbols[path] - return ok -} - -// SplitField splits the field symbol name into type and field -// components. It must be called only on Field symbols. -// -// Example: "File.Package" -> ("File", "Package") -func (sym *Symbol) SplitField() (typename, name string) { - if sym.Kind != Field { - panic("not a field") - } - typename, name, _ = strings.Cut(sym.Name, ".") - return -} - -// SplitMethod splits the method symbol name into pointer, receiver, -// and method components. It must be called only on Method symbols. -// -// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow") -func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) { - if sym.Kind != Method { - panic("not a method") - } - recv, name, _ = strings.Cut(sym.Name, ".") - recv = recv[len("(") : len(recv)-len(")")] - ptr = recv[0] == '*' - if ptr { - recv = recv[len("*"):] - } - return -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go deleted file mode 100644 index cdae2b8..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ /dev/null @@ -1,68 +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 typeparams contains common utilities for writing tools that -// interact with generic Go code, as introduced with Go 1.18. It -// supplements the standard library APIs. Notably, the StructuralTerms -// API computes a minimal representation of the structural -// restrictions on a type parameter. -// -// An external version of these APIs is available in the -// golang.org/x/exp/typeparams module. -package typeparams - -import ( - "go/ast" - "go/token" - "go/types" -) - -// UnpackIndexExpr extracts data from AST nodes that represent index -// expressions. -// -// For an ast.IndexExpr, the resulting indices slice will contain exactly one -// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable -// number of index expressions. -// -// For nodes that don't represent index expressions, the first return value of -// UnpackIndexExpr will be nil. -func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { - switch e := n.(type) { - case *ast.IndexExpr: - return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack - case *ast.IndexListExpr: - return e.X, e.Lbrack, e.Indices, e.Rbrack - } - return nil, token.NoPos, nil, token.NoPos -} - -// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on -// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 -// will panic. -func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { - switch len(indices) { - case 0: - panic("empty indices") - case 1: - return &ast.IndexExpr{ - X: x, - Lbrack: lbrack, - Index: indices[0], - Rbrack: rbrack, - } - default: - return &ast.IndexListExpr{ - X: x, - Lbrack: lbrack, - Indices: indices, - Rbrack: rbrack, - } - } -} - -// IsTypeParam reports whether t is a type parameter (or an alias of one). -func IsTypeParam(t types.Type) bool { - _, ok := types.Unalias(t).(*types.TypeParam) - return ok -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go deleted file mode 100644 index 27a2b17..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2022 The Go 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 typeparams - -import ( - "fmt" - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// See https://go.dev/ref/spec#Core_types for the definition of a core type. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // https://go.dev/ref/spec#Core_types - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // https://go.dev/ref/spec#Core_types - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, NormalTerms returns ErrEmptyTypeSet. -// -// NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func NormalTerms(T types.Type) ([]*types.Term, error) { - // typeSetOf(T) == typeSetOf(Unalias(T)) - typ := types.Unalias(T) - if named, ok := typ.(*types.Named); ok { - typ = named.Underlying() - } - switch typ := typ.(type) { - case *types.TypeParam: - return StructuralTerms(typ) - case *types.Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*types.Term{types.NewTerm(false, T)}, nil - } -} - -// Deref returns the type of the variable pointed to by t, -// if t's core type is a pointer; otherwise it returns t. -// -// Do not assume that Deref(T)==T implies T is not a pointer: -// consider "type T *T", for example. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func Deref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - return t -} - -// MustDeref returns the type of the variable pointed to by t. -// It panics if t's core type is not a pointer. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func MustDeref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - panic(fmt.Sprintf("%v is not a pointer", t)) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/free.go b/vendor/golang.org/x/tools/internal/typeparams/free.go deleted file mode 100644 index 0ade5c2..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/free.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2024 The Go 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 typeparams - -import ( - "go/types" - - "golang.org/x/tools/internal/aliases" -) - -// Free is a memoization of the set of free type parameters within a -// type. It makes a sequence of calls to [Free.Has] for overlapping -// types more efficient. The zero value is ready for use. -// -// NOTE: Adapted from go/types/infer.go. If it is later exported, factor. -type Free struct { - seen map[types.Type]bool -} - -// Has reports whether the specified type has a free type parameter. -func (w *Free) Has(typ types.Type) (res bool) { - // detect cycles - if x, ok := w.seen[typ]; ok { - return x - } - if w.seen == nil { - w.seen = make(map[types.Type]bool) - } - w.seen[typ] = false - defer func() { - w.seen[typ] = res - }() - - switch t := typ.(type) { - case nil, *types.Basic: // TODO(gri) should nil be handled here? - break - - case *types.Alias: - if aliases.TypeParams(t).Len() > aliases.TypeArgs(t).Len() { - return true // This is an uninstantiated Alias. - } - // The expansion of an alias can have free type parameters, - // whether or not the alias itself has type parameters: - // - // func _[K comparable]() { - // type Set = map[K]bool // free(Set) = {K} - // type MapTo[V] = map[K]V // free(Map[foo]) = {V} - // } - // - // So, we must Unalias. - return w.Has(types.Unalias(t)) - - case *types.Array: - return w.Has(t.Elem()) - - case *types.Slice: - return w.Has(t.Elem()) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - if w.Has(t.Field(i).Type()) { - return true - } - } - - case *types.Pointer: - return w.Has(t.Elem()) - - case *types.Tuple: - n := t.Len() - for i := 0; i < n; i++ { - if w.Has(t.At(i).Type()) { - return true - } - } - - case *types.Signature: - // t.tparams may not be nil if we are looking at a signature - // of a generic function type (or an interface method) that is - // part of the type we're testing. We don't care about these type - // parameters. - // Similarly, the receiver of a method may declare (rather than - // use) type parameters, we don't care about those either. - // Thus, we only need to look at the input and result parameters. - return w.Has(t.Params()) || w.Has(t.Results()) - - case *types.Interface: - for i, n := 0, t.NumMethods(); i < n; i++ { - if w.Has(t.Method(i).Type()) { - return true - } - } - terms, err := InterfaceTermSet(t) - if err != nil { - return false // ill typed - } - for _, term := range terms { - if w.Has(term.Type()) { - return true - } - } - - case *types.Map: - return w.Has(t.Key()) || w.Has(t.Elem()) - - case *types.Chan: - return w.Has(t.Elem()) - - case *types.Named: - args := t.TypeArgs() - if params := t.TypeParams(); params.Len() > args.Len() { - return true // this is an uninstantiated named type. - } - for i, n := 0, args.Len(); i < n; i++ { - if w.Has(args.At(i)) { - return true - } - } - return w.Has(t.Underlying()) // recurse for types local to parameterized functions - - case *types.TypeParam: - return true - - default: - panic(t) // unreachable - } - - return false -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go deleted file mode 100644 index 93c80fd..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ /dev/null @@ -1,218 +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 typeparams - -import ( - "errors" - "fmt" - "go/types" - "os" - "strings" -) - -//go:generate go run copytermlist.go - -const debug = false - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *types.Union) ([]*types.Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*types.Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*types.Term - for _, term := range tset.terms { - terms = append(terms, types.NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -func indentf(depth int, format string, args ...interface{}) { - fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) -} - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - panic("nil type") - } - - if debug { - indentf(depth, "%s", t.String()) - defer func() { - if err != nil { - indentf(depth, "=> %s", err) - } else { - indentf(depth, "=> %s", res.terms.String()) - } - }() - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for i := 0; i < u.NumEmbeddeds(); i++ { - embedded := u.EmbeddedType(i) - if _, ok := embedded.Underlying().(*types.TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *types.Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for i := 0; i < u.Len(); i++ { - t := u.Term(i) - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *types.TypeParam, *types.Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *types.TypeParam: - panic("unreachable") - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go deleted file mode 100644 index cbd12f8..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go +++ /dev/null @@ -1,163 +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. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "bytes" - "go/types" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf bytes.Buffer - for i, x := range xl { - if i > 0 { - buf.WriteString(" | ") - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go deleted file mode 100644 index 7350bb7..0000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go +++ /dev/null @@ -1,169 +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. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - if debug && (x.typ == nil || y.typ == nil) { - panic("invalid argument(s)") - } - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/element.go b/vendor/golang.org/x/tools/internal/typesinternal/element.go deleted file mode 100644 index 4957f02..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/element.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -import ( - "fmt" - "go/types" - - "golang.org/x/tools/go/types/typeutil" -) - -// ForEachElement calls f for type T and each type reachable from its -// type through reflection. It does this by recursively stripping off -// type constructors; in addition, for each named type N, the type *N -// is added to the result as it may have additional methods. -// -// The caller must provide an initially empty set used to de-duplicate -// identical types, potentially across multiple calls to ForEachElement. -// (Its final value holds all the elements seen, matching the arguments -// passed to f.) -// -// TODO(adonovan): share/harmonize with go/callgraph/rta. -func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) { - var visit func(T types.Type, skip bool) - visit = func(T types.Type, skip bool) { - if !skip { - if seen, _ := rtypes.Set(T, true).(bool); seen { - return // de-dup - } - - f(T) // notify caller of new element type - } - - // Recursion over signatures of each method. - tmset := msets.MethodSet(T) - for i := 0; i < tmset.Len(); i++ { - sig := tmset.At(i).Type().(*types.Signature) - // It is tempting to call visit(sig, false) - // but, as noted in golang.org/cl/65450043, - // the Signature.Recv field is ignored by - // types.Identical and typeutil.Map, which - // is confusing at best. - // - // More importantly, the true signature rtype - // reachable from a method using reflection - // has no receiver but an extra ordinary parameter. - // For the Read method of io.Reader we want: - // func(Reader, []byte) (int, error) - // but here sig is: - // func([]byte) (int, error) - // with .Recv = Reader (though it is hard to - // notice because it doesn't affect Signature.String - // or types.Identical). - // - // TODO(adonovan): construct and visit the correct - // non-method signature with an extra parameter - // (though since unnamed func types have no methods - // there is essentially no actual demand for this). - // - // TODO(adonovan): document whether or not it is - // safe to skip non-exported methods (as RTA does). - visit(sig.Params(), true) // skip the Tuple - visit(sig.Results(), true) // skip the Tuple - } - - switch T := T.(type) { - case *types.Alias: - visit(types.Unalias(T), skip) // emulates the pre-Alias behavior - - case *types.Basic: - // nop - - case *types.Interface: - // nop---handled by recursion over method set. - - case *types.Pointer: - visit(T.Elem(), false) - - case *types.Slice: - visit(T.Elem(), false) - - case *types.Chan: - visit(T.Elem(), false) - - case *types.Map: - visit(T.Key(), false) - visit(T.Elem(), false) - - case *types.Signature: - if T.Recv() != nil { - panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv())) - } - visit(T.Params(), true) // skip the Tuple - visit(T.Results(), true) // skip the Tuple - - case *types.Named: - // A pointer-to-named type can be derived from a named - // type via reflection. It may have methods too. - visit(types.NewPointer(T), false) - - // Consider 'type T struct{S}' where S has methods. - // Reflection provides no way to get from T to struct{S}, - // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - visit(T.Underlying(), true) // skip the unnamed type - - case *types.Array: - visit(T.Elem(), false) - - case *types.Struct: - for i, n := 0, T.NumFields(); i < n; i++ { - // TODO(adonovan): document whether or not - // it is safe to skip non-exported fields. - visit(T.Field(i).Type(), false) - } - - case *types.Tuple: - for i, n := 0, T.Len(); i < n; i++ { - visit(T.At(i).Type(), false) - } - - case *types.TypeParam, *types.Union: - // forEachReachable must not be called on parameterized types. - panic(T) - - default: - panic(T) - } - } - visit(T, false) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go deleted file mode 100644 index 235a6de..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ /dev/null @@ -1,1560 +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 typesinternal - -//go:generate stringer -type=ErrorCode - -type ErrorCode int - -// This file defines the error codes that can be produced during type-checking. -// Collectively, these codes provide an identifier that may be used to -// implement special handling for certain types of errors. -// -// Error codes should be fine-grained enough that the exact nature of the error -// can be easily determined, but coarse enough that they are not an -// implementation detail of the type checking algorithm. As a rule-of-thumb, -// errors should be considered equivalent if there is a theoretical refactoring -// of the type checker in which they are emitted in exactly one place. For -// example, the type checker emits different error messages for "too many -// arguments" and "too few arguments", but one can imagine an alternative type -// checker where this check instead just emits a single "wrong number of -// arguments", so these errors should have the same code. -// -// Error code names should be as brief as possible while retaining accuracy and -// distinctiveness. In most cases names should start with an adjective -// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), -// and end with a noun identifying the relevant language object. For example, -// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the -// convention that "bad" implies a problem with syntax, and "invalid" implies a -// problem with types. - -const ( - // InvalidSyntaxTree occurs if an invalid syntax tree is provided - // to the type checker. It should never happen. - InvalidSyntaxTree ErrorCode = -1 -) - -const ( - _ ErrorCode = iota - - // Test is reserved for errors that only apply while in self-test mode. - Test - - /* package names */ - - // BlankPkgName occurs when a package name is the blank identifier "_". - // - // Per the spec: - // "The PackageName must not be the blank identifier." - BlankPkgName - - // MismatchedPkgName occurs when a file's package name doesn't match the - // package name already established by other files. - MismatchedPkgName - - // InvalidPkgUse occurs when a package identifier is used outside of a - // selector expression. - // - // Example: - // import "fmt" - // - // var _ = fmt - InvalidPkgUse - - /* imports */ - - // BadImportPath occurs when an import path is not valid. - BadImportPath - - // BrokenImport occurs when importing a package fails. - // - // Example: - // import "amissingpackage" - BrokenImport - - // ImportCRenamed occurs when the special import "C" is renamed. "C" is a - // pseudo-package, and must not be renamed. - // - // Example: - // import _ "C" - ImportCRenamed - - // UnusedImport occurs when an import is unused. - // - // Example: - // import "fmt" - // - // func main() {} - UnusedImport - - /* initialization */ - - // InvalidInitCycle occurs when an invalid cycle is detected within the - // initialization graph. - // - // Example: - // var x int = f() - // - // func f() int { return x } - InvalidInitCycle - - /* decls */ - - // DuplicateDecl occurs when an identifier is declared multiple times. - // - // Example: - // var x = 1 - // var x = 2 - DuplicateDecl - - // InvalidDeclCycle occurs when a declaration cycle is not valid. - // - // Example: - // import "unsafe" - // - // type T struct { - // a [n]int - // } - // - // var n = unsafe.Sizeof(T{}) - InvalidDeclCycle - - // InvalidTypeCycle occurs when a cycle in type definitions results in a - // type that is not well-defined. - // - // Example: - // import "unsafe" - // - // type T [unsafe.Sizeof(T{})]int - InvalidTypeCycle - - /* decls > const */ - - // InvalidConstInit occurs when a const declaration has a non-constant - // initializer. - // - // Example: - // var x int - // const _ = x - InvalidConstInit - - // InvalidConstVal occurs when a const value cannot be converted to its - // target type. - // - // TODO(findleyr): this error code and example are not very clear. Consider - // removing it. - // - // Example: - // const _ = 1 << "hello" - InvalidConstVal - - // InvalidConstType occurs when the underlying type in a const declaration - // is not a valid constant type. - // - // Example: - // const c *int = 4 - InvalidConstType - - /* decls > var (+ other variable assignment codes) */ - - // UntypedNilUse occurs when the predeclared (untyped) value nil is used to - // initialize a variable declared without an explicit type. - // - // Example: - // var x = nil - UntypedNilUse - - // WrongAssignCount occurs when the number of values on the right-hand side - // of an assignment or initialization expression does not match the number - // of variables on the left-hand side. - // - // Example: - // var x = 1, 2 - WrongAssignCount - - // UnassignableOperand occurs when the left-hand side of an assignment is - // not assignable. - // - // Example: - // func f() { - // const c = 1 - // c = 2 - // } - UnassignableOperand - - // NoNewVar occurs when a short variable declaration (':=') does not declare - // new variables. - // - // Example: - // func f() { - // x := 1 - // x := 2 - // } - NoNewVar - - // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does - // not have single-valued left-hand or right-hand side. - // - // Per the spec: - // "In assignment operations, both the left- and right-hand expression lists - // must contain exactly one single-valued expression" - // - // Example: - // func f() int { - // x, y := 1, 2 - // x, y += 1 - // return x + y - // } - MultiValAssignOp - - // InvalidIfaceAssign occurs when a value of type T is used as an - // interface, but T does not implement a method of the expected interface. - // - // Example: - // type I interface { - // f() - // } - // - // type T int - // - // var x I = T(1) - InvalidIfaceAssign - - // InvalidChanAssign occurs when a chan assignment is invalid. - // - // Per the spec, a value x is assignable to a channel type T if: - // "x is a bidirectional channel value, T is a channel type, x's type V and - // T have identical element types, and at least one of V or T is not a - // defined type." - // - // Example: - // type T1 chan int - // type T2 chan int - // - // var x T1 - // // Invalid assignment because both types are named - // var _ T2 = x - InvalidChanAssign - - // IncompatibleAssign occurs when the type of the right-hand side expression - // in an assignment cannot be assigned to the type of the variable being - // assigned. - // - // Example: - // var x []int - // var _ int = x - IncompatibleAssign - - // UnaddressableFieldAssign occurs when trying to assign to a struct field - // in a map value. - // - // Example: - // func f() { - // m := make(map[string]struct{i int}) - // m["foo"].i = 42 - // } - UnaddressableFieldAssign - - /* decls > type (+ other type expression codes) */ - - // NotAType occurs when the identifier used as the underlying type in a type - // declaration or the right-hand side of a type alias does not denote a type. - // - // Example: - // var S = 2 - // - // type T S - NotAType - - // InvalidArrayLen occurs when an array length is not a constant value. - // - // Example: - // var n = 3 - // var _ = [n]int{} - InvalidArrayLen - - // BlankIfaceMethod occurs when a method name is '_'. - // - // Per the spec: - // "The name of each explicitly specified method must be unique and not - // blank." - // - // Example: - // type T interface { - // _(int) - // } - BlankIfaceMethod - - // IncomparableMapKey occurs when a map key type does not support the == and - // != operators. - // - // Per the spec: - // "The comparison operators == and != must be fully defined for operands of - // the key type; thus the key type must not be a function, map, or slice." - // - // Example: - // var x map[T]int - // - // type T []int - IncomparableMapKey - - // InvalidIfaceEmbed occurs when a non-interface type is embedded in an - // interface. - // - // Example: - // type T struct {} - // - // func (T) m() - // - // type I interface { - // T - // } - InvalidIfaceEmbed - - // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, - // and T itself is itself a pointer, an unsafe.Pointer, or an interface. - // - // Per the spec: - // "An embedded field must be specified as a type name T or as a pointer to - // a non-interface type name *T, and T itself may not be a pointer type." - // - // Example: - // type T *int - // - // type S struct { - // *T - // } - InvalidPtrEmbed - - /* decls > func and method */ - - // BadRecv occurs when a method declaration does not have exactly one - // receiver parameter. - // - // Example: - // func () _() {} - BadRecv - - // InvalidRecv occurs when a receiver type expression is not of the form T - // or *T, or T is a pointer type. - // - // Example: - // type T struct {} - // - // func (**T) m() {} - InvalidRecv - - // DuplicateFieldAndMethod occurs when an identifier appears as both a field - // and method name. - // - // Example: - // type T struct { - // m int - // } - // - // func (T) m() {} - DuplicateFieldAndMethod - - // DuplicateMethod occurs when two methods on the same receiver type have - // the same name. - // - // Example: - // type T struct {} - // func (T) m() {} - // func (T) m(i int) int { return i } - DuplicateMethod - - /* decls > special */ - - // InvalidBlank occurs when a blank identifier is used as a value or type. - // - // Per the spec: - // "The blank identifier may appear as an operand only on the left-hand side - // of an assignment." - // - // Example: - // var x = _ - InvalidBlank - - // InvalidIota occurs when the predeclared identifier iota is used outside - // of a constant declaration. - // - // Example: - // var x = iota - InvalidIota - - // MissingInitBody occurs when an init function is missing its body. - // - // Example: - // func init() - MissingInitBody - - // InvalidInitSig occurs when an init function declares parameters or - // results. - // - // Example: - // func init() int { return 1 } - InvalidInitSig - - // InvalidInitDecl occurs when init is declared as anything other than a - // function. - // - // Example: - // var init = 1 - InvalidInitDecl - - // InvalidMainDecl occurs when main is declared as anything other than a - // function, in a main package. - InvalidMainDecl - - /* exprs */ - - // TooManyValues occurs when a function returns too many values for the - // expression context in which it is used. - // - // Example: - // func ReturnTwo() (int, int) { - // return 1, 2 - // } - // - // var x = ReturnTwo() - TooManyValues - - // NotAnExpr occurs when a type expression is used where a value expression - // is expected. - // - // Example: - // type T struct {} - // - // func f() { - // T - // } - NotAnExpr - - /* exprs > const */ - - // TruncatedFloat occurs when a float constant is truncated to an integer - // value. - // - // Example: - // var _ int = 98.6 - TruncatedFloat - - // NumericOverflow occurs when a numeric constant overflows its target type. - // - // Example: - // var x int8 = 1000 - NumericOverflow - - /* exprs > operation */ - - // UndefinedOp occurs when an operator is not defined for the type(s) used - // in an operation. - // - // Example: - // var c = "a" - "b" - UndefinedOp - - // MismatchedTypes occurs when operand types are incompatible in a binary - // operation. - // - // Example: - // var a = "hello" - // var b = 1 - // var c = a - b - MismatchedTypes - - // DivByZero occurs when a division operation is provable at compile - // time to be a division by zero. - // - // Example: - // const divisor = 0 - // var x int = 1/divisor - DivByZero - - // NonNumericIncDec occurs when an increment or decrement operator is - // applied to a non-numeric value. - // - // Example: - // func f() { - // var c = "c" - // c++ - // } - NonNumericIncDec - - /* exprs > ptr */ - - // UnaddressableOperand occurs when the & operator is applied to an - // unaddressable expression. - // - // Example: - // var x = &1 - UnaddressableOperand - - // InvalidIndirection occurs when a non-pointer value is indirected via the - // '*' operator. - // - // Example: - // var x int - // var y = *x - InvalidIndirection - - /* exprs > [] */ - - // NonIndexableOperand occurs when an index operation is applied to a value - // that cannot be indexed. - // - // Example: - // var x = 1 - // var y = x[1] - NonIndexableOperand - - // InvalidIndex occurs when an index argument is not of integer type, - // negative, or out-of-bounds. - // - // Example: - // var s = [...]int{1,2,3} - // var x = s[5] - // - // Example: - // var s = []int{1,2,3} - // var _ = s[-1] - // - // Example: - // var s = []int{1,2,3} - // var i string - // var _ = s[i] - InvalidIndex - - // SwappedSliceIndices occurs when constant indices in a slice expression - // are decreasing in value. - // - // Example: - // var _ = []int{1,2,3}[2:1] - SwappedSliceIndices - - /* operators > slice */ - - // NonSliceableOperand occurs when a slice operation is applied to a value - // whose type is not sliceable, or is unaddressable. - // - // Example: - // var x = [...]int{1, 2, 3}[:1] - // - // Example: - // var x = 1 - // var y = 1[:1] - NonSliceableOperand - - // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is - // applied to a string. - // - // Example: - // var s = "hello" - // var x = s[1:2:3] - InvalidSliceExpr - - /* exprs > shift */ - - // InvalidShiftCount occurs when the right-hand side of a shift operation is - // either non-integer, negative, or too large. - // - // Example: - // var ( - // x string - // y int = 1 << x - // ) - InvalidShiftCount - - // InvalidShiftOperand occurs when the shifted operand is not an integer. - // - // Example: - // var s = "hello" - // var x = s << 2 - InvalidShiftOperand - - /* exprs > chan */ - - // InvalidReceive occurs when there is a channel receive from a value that - // is either not a channel, or is a send-only channel. - // - // Example: - // func f() { - // var x = 1 - // <-x - // } - InvalidReceive - - // InvalidSend occurs when there is a channel send to a value that is not a - // channel, or is a receive-only channel. - // - // Example: - // func f() { - // var x = 1 - // x <- "hello!" - // } - InvalidSend - - /* exprs > literal */ - - // DuplicateLitKey occurs when an index is duplicated in a slice, array, or - // map literal. - // - // Example: - // var _ = []int{0:1, 0:2} - // - // Example: - // var _ = map[string]int{"a": 1, "a": 2} - DuplicateLitKey - - // MissingLitKey occurs when a map literal is missing a key expression. - // - // Example: - // var _ = map[string]int{1} - MissingLitKey - - // InvalidLitIndex occurs when the key in a key-value element of a slice or - // array literal is not an integer constant. - // - // Example: - // var i = 0 - // var x = []string{i: "world"} - InvalidLitIndex - - // OversizeArrayLit occurs when an array literal exceeds its length. - // - // Example: - // var _ = [2]int{1,2,3} - OversizeArrayLit - - // MixedStructLit occurs when a struct literal contains a mix of positional - // and named elements. - // - // Example: - // var _ = struct{i, j int}{i: 1, 2} - MixedStructLit - - // InvalidStructLit occurs when a positional struct literal has an incorrect - // number of values. - // - // Example: - // var _ = struct{i, j int}{1,2,3} - InvalidStructLit - - // MissingLitField occurs when a struct literal refers to a field that does - // not exist on the struct type. - // - // Example: - // var _ = struct{i int}{j: 2} - MissingLitField - - // DuplicateLitField occurs when a struct literal contains duplicated - // fields. - // - // Example: - // var _ = struct{i int}{i: 1, i: 2} - DuplicateLitField - - // UnexportedLitField occurs when a positional struct literal implicitly - // assigns an unexported field of an imported type. - UnexportedLitField - - // InvalidLitField occurs when a field name is not a valid identifier. - // - // Example: - // var _ = struct{i int}{1: 1} - InvalidLitField - - // UntypedLit occurs when a composite literal omits a required type - // identifier. - // - // Example: - // type outer struct{ - // inner struct { i int } - // } - // - // var _ = outer{inner: {1}} - UntypedLit - - // InvalidLit occurs when a composite literal expression does not match its - // type. - // - // Example: - // type P *struct{ - // x int - // } - // var _ = P {} - InvalidLit - - /* exprs > selector */ - - // AmbiguousSelector occurs when a selector is ambiguous. - // - // Example: - // type E1 struct { i int } - // type E2 struct { i int } - // type T struct { E1; E2 } - // - // var x T - // var _ = x.i - AmbiguousSelector - - // UndeclaredImportedName occurs when a package-qualified identifier is - // undeclared by the imported package. - // - // Example: - // import "go/types" - // - // var _ = types.NotAnActualIdentifier - UndeclaredImportedName - - // UnexportedName occurs when a selector refers to an unexported identifier - // of an imported package. - // - // Example: - // import "reflect" - // - // type _ reflect.flag - UnexportedName - - // UndeclaredName occurs when an identifier is not declared in the current - // scope. - // - // Example: - // var x T - UndeclaredName - - // MissingFieldOrMethod occurs when a selector references a field or method - // that does not exist. - // - // Example: - // type T struct {} - // - // var x = T{}.f - MissingFieldOrMethod - - /* exprs > ... */ - - // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is - // not valid. - // - // Example: - // var _ = map[int][...]int{0: {}} - BadDotDotDotSyntax - - // NonVariadicDotDotDot occurs when a "..." is used on the final argument to - // a non-variadic function. - // - // Example: - // func printArgs(s []string) { - // for _, a := range s { - // println(a) - // } - // } - // - // func f() { - // s := []string{"a", "b", "c"} - // printArgs(s...) - // } - NonVariadicDotDotDot - - // MisplacedDotDotDot occurs when a "..." is used somewhere other than the - // final argument to a function call. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := []int{1,2,3} - // printArgs(0, a...) - // } - MisplacedDotDotDot - - // InvalidDotDotDotOperand occurs when a "..." operator is applied to a - // single-valued operand. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := 1 - // printArgs(a...) - // } - // - // Example: - // func args() (int, int) { - // return 1, 2 - // } - // - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func g() { - // printArgs(args()...) - // } - InvalidDotDotDotOperand - - // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in - // function. - // - // Example: - // var s = []int{1, 2, 3} - // var l = len(s...) - InvalidDotDotDot - - /* exprs > built-in */ - - // UncalledBuiltin occurs when a built-in function is used as a - // function-valued expression, instead of being called. - // - // Per the spec: - // "The built-in functions do not have standard Go types, so they can only - // appear in call expressions; they cannot be used as function values." - // - // Example: - // var _ = copy - UncalledBuiltin - - // InvalidAppend occurs when append is called with a first argument that is - // not a slice. - // - // Example: - // var _ = append(1, 2) - InvalidAppend - - // InvalidCap occurs when an argument to the cap built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Length_and_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = cap(s) - InvalidCap - - // InvalidClose occurs when close(...) is called with an argument that is - // not of channel type, or that is a receive-only channel. - // - // Example: - // func f() { - // var x int - // close(x) - // } - InvalidClose - - // InvalidCopy occurs when the arguments are not of slice type or do not - // have compatible type. - // - // See https://golang.org/ref/spec#Appending_and_copying_slices for more - // information on the type requirements for the copy built-in. - // - // Example: - // func f() { - // var x []int - // y := []int64{1,2,3} - // copy(x, y) - // } - InvalidCopy - - // InvalidComplex occurs when the complex built-in function is called with - // arguments with incompatible types. - // - // Example: - // var _ = complex(float32(1), float64(2)) - InvalidComplex - - // InvalidDelete occurs when the delete built-in function is called with a - // first argument that is not a map. - // - // Example: - // func f() { - // m := "hello" - // delete(m, "e") - // } - InvalidDelete - - // InvalidImag occurs when the imag built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = imag(int(1)) - InvalidImag - - // InvalidLen occurs when an argument to the len built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Length_and_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = len(s) - InvalidLen - - // SwappedMakeArgs occurs when make is called with three arguments, and its - // length argument is larger than its capacity argument. - // - // Example: - // var x = make([]int, 3, 2) - SwappedMakeArgs - - // InvalidMake occurs when make is called with an unsupported type argument. - // - // See https://golang.org/ref/spec#Making_slices_maps_and_channels for - // information on the types that may be created using make. - // - // Example: - // var x = make(int) - InvalidMake - - // InvalidReal occurs when the real built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = real(int(1)) - InvalidReal - - /* exprs > assertion */ - - // InvalidAssert occurs when a type assertion is applied to a - // value that is not of interface type. - // - // Example: - // var x = 1 - // var _ = x.(float64) - InvalidAssert - - // ImpossibleAssert occurs for a type assertion x.(T) when the value x of - // interface cannot have dynamic type T, due to a missing or mismatching - // method on T. - // - // Example: - // type T int - // - // func (t *T) m() int { return int(*t) } - // - // type I interface { m() int } - // - // var x I - // var _ = x.(T) - ImpossibleAssert - - /* exprs > conversion */ - - // InvalidConversion occurs when the argument type cannot be converted to the - // target. - // - // See https://golang.org/ref/spec#Conversions for the rules of - // convertibility. - // - // Example: - // var x float64 - // var _ = string(x) - InvalidConversion - - // InvalidUntypedConversion occurs when there is no valid implicit - // conversion from an untyped value satisfying the type constraints of the - // context in which it is used. - // - // Example: - // var _ = 1 + "" - InvalidUntypedConversion - - /* offsetof */ - - // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument - // that is not a selector expression. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Offsetof(x) - BadOffsetofSyntax - - // InvalidOffsetof occurs when unsafe.Offsetof is called with a method - // selector, rather than a field selector, or when the field is embedded via - // a pointer. - // - // Per the spec: - // - // "If f is an embedded field, it must be reachable without pointer - // indirections through fields of the struct. " - // - // Example: - // import "unsafe" - // - // type T struct { f int } - // type S struct { *T } - // var s S - // var _ = unsafe.Offsetof(s.f) - // - // Example: - // import "unsafe" - // - // type S struct{} - // - // func (S) m() {} - // - // var s S - // var _ = unsafe.Offsetof(s.m) - InvalidOffsetof - - /* control flow > scope */ - - // UnusedExpr occurs when a side-effect free expression is used as a - // statement. Such a statement has no effect. - // - // Example: - // func f(i int) { - // i*i - // } - UnusedExpr - - // UnusedVar occurs when a variable is declared but unused. - // - // Example: - // func f() { - // x := 1 - // } - UnusedVar - - // MissingReturn occurs when a function with results is missing a return - // statement. - // - // Example: - // func f() int {} - MissingReturn - - // WrongResultCount occurs when a return statement returns an incorrect - // number of values. - // - // Example: - // func ReturnOne() int { - // return 1, 2 - // } - WrongResultCount - - // OutOfScopeResult occurs when the name of a value implicitly returned by - // an empty return statement is shadowed in a nested scope. - // - // Example: - // func factor(n int) (i int) { - // for i := 2; i < n; i++ { - // if n%i == 0 { - // return - // } - // } - // return 0 - // } - OutOfScopeResult - - /* control flow > if */ - - // InvalidCond occurs when an if condition is not a boolean expression. - // - // Example: - // func checkReturn(i int) { - // if i { - // panic("non-zero return") - // } - // } - InvalidCond - - /* control flow > for */ - - // InvalidPostDecl occurs when there is a declaration in a for-loop post - // statement. - // - // Example: - // func f() { - // for i := 0; i < 10; j := 0 {} - // } - InvalidPostDecl - - // InvalidChanRange occurs when a send-only channel used in a range - // expression. - // - // Example: - // func sum(c chan<- int) { - // s := 0 - // for i := range c { - // s += i - // } - // } - InvalidChanRange - - // InvalidIterVar occurs when two iteration variables are used while ranging - // over a channel. - // - // Example: - // func f(c chan int) { - // for k, v := range c { - // println(k, v) - // } - // } - InvalidIterVar - - // InvalidRangeExpr occurs when the type of a range expression is not array, - // slice, string, map, or channel. - // - // Example: - // func f(i int) { - // for j := range i { - // println(j) - // } - // } - InvalidRangeExpr - - /* control flow > switch */ - - // MisplacedBreak occurs when a break statement is not within a for, switch, - // or select statement of the innermost function definition. - // - // Example: - // func f() { - // break - // } - MisplacedBreak - - // MisplacedContinue occurs when a continue statement is not within a for - // loop of the innermost function definition. - // - // Example: - // func sumeven(n int) int { - // proceed := func() { - // continue - // } - // sum := 0 - // for i := 1; i <= n; i++ { - // if i % 2 != 0 { - // proceed() - // } - // sum += i - // } - // return sum - // } - MisplacedContinue - - // MisplacedFallthrough occurs when a fallthrough statement is not within an - // expression switch. - // - // Example: - // func typename(i interface{}) string { - // switch i.(type) { - // case int64: - // fallthrough - // case int: - // return "int" - // } - // return "unsupported" - // } - MisplacedFallthrough - - // DuplicateCase occurs when a type or expression switch has duplicate - // cases. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // case 1: - // println("One") - // } - // } - DuplicateCase - - // DuplicateDefault occurs when a type or expression switch has multiple - // default clauses. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // default: - // println("One") - // default: - // println("1") - // } - // } - DuplicateDefault - - // BadTypeKeyword occurs when a .(type) expression is used anywhere other - // than a type switch. - // - // Example: - // type I interface { - // m() - // } - // var t I - // var _ = t.(type) - BadTypeKeyword - - // InvalidTypeSwitch occurs when .(type) is used on an expression that is - // not of interface type. - // - // Example: - // func f(i int) { - // switch x := i.(type) {} - // } - InvalidTypeSwitch - - // InvalidExprSwitch occurs when a switch expression is not comparable. - // - // Example: - // func _() { - // var a struct{ _ func() } - // switch a /* ERROR cannot switch on a */ { - // } - // } - InvalidExprSwitch - - /* control flow > select */ - - // InvalidSelectCase occurs when a select case is not a channel send or - // receive. - // - // Example: - // func checkChan(c <-chan int) bool { - // select { - // case c: - // return true - // default: - // return false - // } - // } - InvalidSelectCase - - /* control flow > labels and jumps */ - - // UndeclaredLabel occurs when an undeclared label is jumped to. - // - // Example: - // func f() { - // goto L - // } - UndeclaredLabel - - // DuplicateLabel occurs when a label is declared more than once. - // - // Example: - // func f() int { - // L: - // L: - // return 1 - // } - DuplicateLabel - - // MisplacedLabel occurs when a break or continue label is not on a for, - // switch, or select statement. - // - // Example: - // func f() { - // L: - // a := []int{1,2,3} - // for _, e := range a { - // if e > 10 { - // break L - // } - // println(a) - // } - // } - MisplacedLabel - - // UnusedLabel occurs when a label is declared but not used. - // - // Example: - // func f() { - // L: - // } - UnusedLabel - - // JumpOverDecl occurs when a label jumps over a variable declaration. - // - // Example: - // func f() int { - // goto L - // x := 2 - // L: - // x++ - // return x - // } - JumpOverDecl - - // JumpIntoBlock occurs when a forward jump goes to a label inside a nested - // block. - // - // Example: - // func f(x int) { - // goto L - // if x > 0 { - // L: - // print("inside block") - // } - // } - JumpIntoBlock - - /* control flow > calls */ - - // InvalidMethodExpr occurs when a pointer method is called but the argument - // is not addressable. - // - // Example: - // type T struct {} - // - // func (*T) m() int { return 1 } - // - // var _ = T.m(T{}) - InvalidMethodExpr - - // WrongArgCount occurs when too few or too many arguments are passed by a - // function call. - // - // Example: - // func f(i int) {} - // var x = f() - WrongArgCount - - // InvalidCall occurs when an expression is called that is not of function - // type. - // - // Example: - // var x = "x" - // var y = x() - InvalidCall - - /* control flow > suspended */ - - // UnusedResults occurs when a restricted expression-only built-in function - // is suspended via go or defer. Such a suspension discards the results of - // these side-effect free built-in functions, and therefore is ineffectual. - // - // Example: - // func f(a []int) int { - // defer len(a) - // return i - // } - UnusedResults - - // InvalidDefer occurs when a deferred expression is not a function call, - // for example if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // defer int32(i) - // return i - // } - InvalidDefer - - // InvalidGo occurs when a go expression is not a function call, for example - // if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // go int32(i) - // return i - // } - InvalidGo - - // All codes below were added in Go 1.17. - - /* decl */ - - // BadDecl occurs when a declaration has invalid syntax. - BadDecl - - // RepeatedDecl occurs when an identifier occurs more than once on the left - // hand side of a short variable declaration. - // - // Example: - // func _() { - // x, y, y := 1, 2, 3 - // } - RepeatedDecl - - /* unsafe */ - - // InvalidUnsafeAdd occurs when unsafe.Add is called with a - // length argument that is not of integer type. - // - // Example: - // import "unsafe" - // - // var p unsafe.Pointer - // var _ = unsafe.Add(p, float64(1)) - InvalidUnsafeAdd - - // InvalidUnsafeSlice occurs when unsafe.Slice is called with a - // pointer argument that is not of pointer type or a length argument - // that is not of integer type, negative, or out of bounds. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(x, 1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, float64(1)) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, -1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, uint64(1) << 63) - InvalidUnsafeSlice - - // All codes below were added in Go 1.18. - - /* features */ - - // UnsupportedFeature occurs when a language feature is used that is not - // supported at this Go version. - UnsupportedFeature - - /* type params */ - - // NotAGenericType occurs when a non-generic type is used where a generic - // type is expected: in type or function instantiation. - // - // Example: - // type T int - // - // var _ T[int] - NotAGenericType - - // WrongTypeArgCount occurs when a type or function is instantiated with an - // incorrect number of type arguments, including when a generic type or - // function is used without instantiation. - // - // Errors involving failed type inference are assigned other error codes. - // - // Example: - // type T[p any] int - // - // var _ T[int, string] - // - // Example: - // func f[T any]() {} - // - // var x = f - WrongTypeArgCount - - // CannotInferTypeArgs occurs when type or function type argument inference - // fails to infer all type arguments. - // - // Example: - // func f[T any]() {} - // - // func _() { - // f() - // } - // - // Example: - // type N[P, Q any] struct{} - // - // var _ N[int] - CannotInferTypeArgs - - // InvalidTypeArg occurs when a type argument does not satisfy its - // corresponding type parameter constraints. - // - // Example: - // type T[P ~int] struct{} - // - // var _ T[string] - InvalidTypeArg // arguments? InferenceFailed - - // InvalidInstanceCycle occurs when an invalid cycle is detected - // within the instantiation graph. - // - // Example: - // func f[T any]() { f[*T]() } - InvalidInstanceCycle - - // InvalidUnion occurs when an embedded union or approximation element is - // not valid. - // - // Example: - // type _ interface { - // ~int | interface{ m() } - // } - InvalidUnion - - // MisplacedConstraintIface occurs when a constraint-type interface is used - // outside of constraint position. - // - // Example: - // type I interface { ~int } - // - // var _ I - MisplacedConstraintIface - - // InvalidMethodTypeParams occurs when methods have type parameters. - // - // It cannot be encountered with an AST parsed using go/parser. - InvalidMethodTypeParams - - // MisplacedTypeParam occurs when a type parameter is used in a place where - // it is not permitted. - // - // Example: - // type T[P any] P - // - // Example: - // type T[P any] struct{ *P } - MisplacedTypeParam - - // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with - // an argument that is not of slice type. It also occurs if it is used - // in a package compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.SliceData(x) - InvalidUnsafeSliceData - - // InvalidUnsafeString occurs when unsafe.String is called with - // a length argument that is not of integer type, negative, or - // out of bounds. It also occurs if it is used in a package - // compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var b [10]byte - // var _ = unsafe.String(&b[0], -1) - InvalidUnsafeString - - // InvalidUnsafeStringData occurs if it is used in a package - // compiled for a language version before go1.20. - _ // not used anymore - -) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go deleted file mode 100644 index 15ecf7c..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go +++ /dev/null @@ -1,179 +0,0 @@ -// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. - -package typesinternal - -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[InvalidSyntaxTree - -1] - _ = x[Test-1] - _ = x[BlankPkgName-2] - _ = x[MismatchedPkgName-3] - _ = x[InvalidPkgUse-4] - _ = x[BadImportPath-5] - _ = x[BrokenImport-6] - _ = x[ImportCRenamed-7] - _ = x[UnusedImport-8] - _ = x[InvalidInitCycle-9] - _ = x[DuplicateDecl-10] - _ = x[InvalidDeclCycle-11] - _ = x[InvalidTypeCycle-12] - _ = x[InvalidConstInit-13] - _ = x[InvalidConstVal-14] - _ = x[InvalidConstType-15] - _ = x[UntypedNilUse-16] - _ = x[WrongAssignCount-17] - _ = x[UnassignableOperand-18] - _ = x[NoNewVar-19] - _ = x[MultiValAssignOp-20] - _ = x[InvalidIfaceAssign-21] - _ = x[InvalidChanAssign-22] - _ = x[IncompatibleAssign-23] - _ = x[UnaddressableFieldAssign-24] - _ = x[NotAType-25] - _ = x[InvalidArrayLen-26] - _ = x[BlankIfaceMethod-27] - _ = x[IncomparableMapKey-28] - _ = x[InvalidIfaceEmbed-29] - _ = x[InvalidPtrEmbed-30] - _ = x[BadRecv-31] - _ = x[InvalidRecv-32] - _ = x[DuplicateFieldAndMethod-33] - _ = x[DuplicateMethod-34] - _ = x[InvalidBlank-35] - _ = x[InvalidIota-36] - _ = x[MissingInitBody-37] - _ = x[InvalidInitSig-38] - _ = x[InvalidInitDecl-39] - _ = x[InvalidMainDecl-40] - _ = x[TooManyValues-41] - _ = x[NotAnExpr-42] - _ = x[TruncatedFloat-43] - _ = x[NumericOverflow-44] - _ = x[UndefinedOp-45] - _ = x[MismatchedTypes-46] - _ = x[DivByZero-47] - _ = x[NonNumericIncDec-48] - _ = x[UnaddressableOperand-49] - _ = x[InvalidIndirection-50] - _ = x[NonIndexableOperand-51] - _ = x[InvalidIndex-52] - _ = x[SwappedSliceIndices-53] - _ = x[NonSliceableOperand-54] - _ = x[InvalidSliceExpr-55] - _ = x[InvalidShiftCount-56] - _ = x[InvalidShiftOperand-57] - _ = x[InvalidReceive-58] - _ = x[InvalidSend-59] - _ = x[DuplicateLitKey-60] - _ = x[MissingLitKey-61] - _ = x[InvalidLitIndex-62] - _ = x[OversizeArrayLit-63] - _ = x[MixedStructLit-64] - _ = x[InvalidStructLit-65] - _ = x[MissingLitField-66] - _ = x[DuplicateLitField-67] - _ = x[UnexportedLitField-68] - _ = x[InvalidLitField-69] - _ = x[UntypedLit-70] - _ = x[InvalidLit-71] - _ = x[AmbiguousSelector-72] - _ = x[UndeclaredImportedName-73] - _ = x[UnexportedName-74] - _ = x[UndeclaredName-75] - _ = x[MissingFieldOrMethod-76] - _ = x[BadDotDotDotSyntax-77] - _ = x[NonVariadicDotDotDot-78] - _ = x[MisplacedDotDotDot-79] - _ = x[InvalidDotDotDotOperand-80] - _ = x[InvalidDotDotDot-81] - _ = x[UncalledBuiltin-82] - _ = x[InvalidAppend-83] - _ = x[InvalidCap-84] - _ = x[InvalidClose-85] - _ = x[InvalidCopy-86] - _ = x[InvalidComplex-87] - _ = x[InvalidDelete-88] - _ = x[InvalidImag-89] - _ = x[InvalidLen-90] - _ = x[SwappedMakeArgs-91] - _ = x[InvalidMake-92] - _ = x[InvalidReal-93] - _ = x[InvalidAssert-94] - _ = x[ImpossibleAssert-95] - _ = x[InvalidConversion-96] - _ = x[InvalidUntypedConversion-97] - _ = x[BadOffsetofSyntax-98] - _ = x[InvalidOffsetof-99] - _ = x[UnusedExpr-100] - _ = x[UnusedVar-101] - _ = x[MissingReturn-102] - _ = x[WrongResultCount-103] - _ = x[OutOfScopeResult-104] - _ = x[InvalidCond-105] - _ = x[InvalidPostDecl-106] - _ = x[InvalidChanRange-107] - _ = x[InvalidIterVar-108] - _ = x[InvalidRangeExpr-109] - _ = x[MisplacedBreak-110] - _ = x[MisplacedContinue-111] - _ = x[MisplacedFallthrough-112] - _ = x[DuplicateCase-113] - _ = x[DuplicateDefault-114] - _ = x[BadTypeKeyword-115] - _ = x[InvalidTypeSwitch-116] - _ = x[InvalidExprSwitch-117] - _ = x[InvalidSelectCase-118] - _ = x[UndeclaredLabel-119] - _ = x[DuplicateLabel-120] - _ = x[MisplacedLabel-121] - _ = x[UnusedLabel-122] - _ = x[JumpOverDecl-123] - _ = x[JumpIntoBlock-124] - _ = x[InvalidMethodExpr-125] - _ = x[WrongArgCount-126] - _ = x[InvalidCall-127] - _ = x[UnusedResults-128] - _ = x[InvalidDefer-129] - _ = x[InvalidGo-130] - _ = x[BadDecl-131] - _ = x[RepeatedDecl-132] - _ = x[InvalidUnsafeAdd-133] - _ = x[InvalidUnsafeSlice-134] - _ = x[UnsupportedFeature-135] - _ = x[NotAGenericType-136] - _ = x[WrongTypeArgCount-137] - _ = x[CannotInferTypeArgs-138] - _ = x[InvalidTypeArg-139] - _ = x[InvalidInstanceCycle-140] - _ = x[InvalidUnion-141] - _ = x[MisplacedConstraintIface-142] - _ = x[InvalidMethodTypeParams-143] - _ = x[MisplacedTypeParam-144] - _ = x[InvalidUnsafeSliceData-145] - _ = x[InvalidUnsafeString-146] -} - -const ( - _ErrorCode_name_0 = "InvalidSyntaxTree" - _ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString" -) - -var ( - _ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180} -) - -func (i ErrorCode) String() string { - switch { - case i == -1: - return _ErrorCode_name_0 - case 1 <= i && i <= 146: - i -= 1 - return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]] - default: - return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go deleted file mode 100644 index b64f714..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -import ( - "go/ast" - "go/types" - "strconv" -) - -// FileQualifier returns a [types.Qualifier] function that qualifies -// imported symbols appropriately based on the import environment of a given -// file. -// If the same package is imported multiple times, the last appearance is -// recorded. -func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier { - // Construct mapping of import paths to their defined names. - // It is only necessary to look at renaming imports. - imports := make(map[string]string) - for _, imp := range f.Imports { - if imp.Name != nil && imp.Name.Name != "_" { - path, _ := strconv.Unquote(imp.Path.Value) - imports[path] = imp.Name.Name - } - } - - // Define qualifier to replace full package paths with names of the imports. - return func(p *types.Package) string { - if p == nil || p == pkg { - return "" - } - - if name, ok := imports[p.Path()]; ok { - if name == "." { - return "" - } else { - return name - } - } - - // If there is no local renaming, fall back to the package name. - return p.Name() - } -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go deleted file mode 100644 index 8352ea7..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/recv.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -import ( - "go/types" -) - -// ReceiverNamed returns the named type (if any) associated with the -// type of recv, which may be of the form N or *N, or aliases thereof. -// It also reports whether a Pointer was present. -// -// The named result may be nil if recv is from a method on an -// anonymous interface or struct types or in ill-typed code. -func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) { - t := recv.Type() - if ptr, ok := types.Unalias(t).(*types.Pointer); ok { - isPtr = true - t = ptr.Elem() - } - named, _ = types.Unalias(t).(*types.Named) - return -} - -// Unpointer returns T given *T or an alias thereof. -// For all other types it is the identity function. -// It does not look at underlying types. -// The result may be an alias. -// -// Use this function to strip off the optional pointer on a receiver -// in a field or method selection, without losing the named type -// (which is needed to compute the method set). -// -// See also [typeparams.MustDeref], which removes one level of -// indirection from the type, regardless of named types (analogous to -// a LOAD instruction). -func Unpointer(t types.Type) types.Type { - if ptr, ok := types.Unalias(t).(*types.Pointer); ok { - return ptr.Elem() - } - return t -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go deleted file mode 100644 index cc86487..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -import ( - "go/types" - - "golang.org/x/tools/internal/stdlib" - "golang.org/x/tools/internal/versions" -) - -// TooNewStdSymbols computes the set of package-level symbols -// exported by pkg that are not available at the specified version. -// The result maps each symbol to its minimum version. -// -// The pkg is allowed to contain type errors. -func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { - disallowed := make(map[types.Object]string) - - // Pass 1: package-level symbols. - symbols := stdlib.PackageSymbols[pkg.Path()] - for _, sym := range symbols { - symver := sym.Version.String() - if versions.Before(version, symver) { - switch sym.Kind { - case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: - disallowed[pkg.Scope().Lookup(sym.Name)] = symver - } - } - } - - // Pass 2: fields and methods. - // - // We allow fields and methods if their associated type is - // disallowed, as otherwise we would report false positives - // for compatibility shims. Consider: - // - // //go:build go1.22 - // type T struct { F std.Real } // correct new API - // - // //go:build !go1.22 - // type T struct { F fake } // shim - // type fake struct { ... } - // func (fake) M () {} - // - // These alternative declarations of T use either the std.Real - // type, introduced in go1.22, or a fake type, for the field - // F. (The fakery could be arbitrarily deep, involving more - // nested fields and methods than are shown here.) Clients - // that use the compatibility shim T will compile with any - // version of go, whether older or newer than go1.22, but only - // the newer version will use the std.Real implementation. - // - // Now consider a reference to method M in new(T).F.M() in a - // module that requires a minimum of go1.21. The analysis may - // occur using a version of Go higher than 1.21, selecting the - // first version of T, so the method M is Real.M. This would - // spuriously cause the analyzer to report a reference to a - // too-new symbol even though this expression compiles just - // fine (with the fake implementation) using go1.21. - for _, sym := range symbols { - symVersion := sym.Version.String() - if !versions.Before(version, symVersion) { - continue // allowed - } - - var obj types.Object - switch sym.Kind { - case stdlib.Field: - typename, name := sym.SplitField() - if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) - } - - case stdlib.Method: - ptr, recvname, name := sym.SplitMethod() - if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) - } - } - if obj != nil { - disallowed[obj] = symVersion - } - } - - return disallowed -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go deleted file mode 100644 index 3453487..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ /dev/null @@ -1,127 +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 typesinternal provides access to internal go/types APIs that are not -// yet exported. -package typesinternal - -import ( - "go/token" - "go/types" - "reflect" - "unsafe" - - "golang.org/x/tools/internal/aliases" -) - -func SetUsesCgo(conf *types.Config) bool { - v := reflect.ValueOf(conf).Elem() - - f := v.FieldByName("go115UsesCgo") - if !f.IsValid() { - f = v.FieldByName("UsesCgo") - if !f.IsValid() { - return false - } - } - - addr := unsafe.Pointer(f.UnsafeAddr()) - *(*bool)(addr) = true - - return true -} - -// ReadGo116ErrorData extracts additional information from types.Error values -// generated by Go version 1.16 and later: the error code, start position, and -// end position. If all positions are valid, start <= err.Pos <= end. -// -// If the data could not be read, the final result parameter will be false. -func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { - var data [3]int - // By coincidence all of these fields are ints, which simplifies things. - v := reflect.ValueOf(err) - for i, name := range []string{"go116code", "go116start", "go116end"} { - f := v.FieldByName(name) - if !f.IsValid() { - return 0, 0, 0, false - } - data[i] = int(f.Int()) - } - return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true -} - -// NameRelativeTo returns a types.Qualifier that qualifies members of -// all packages other than pkg, using only the package name. -// (By contrast, [types.RelativeTo] uses the complete package path, -// which is often excessive.) -// -// If pkg is nil, it is equivalent to [*types.Package.Name]. -func NameRelativeTo(pkg *types.Package) types.Qualifier { - return func(other *types.Package) string { - if pkg != nil && pkg == other { - return "" // same package; unqualified - } - return other.Name() - } -} - -// A NamedOrAlias is a [types.Type] that is named (as -// defined by the spec) and capable of bearing type parameters: it -// abstracts aliases ([types.Alias]) and defined types -// ([types.Named]). -// -// Every type declared by an explicit "type" declaration is a -// NamedOrAlias. (Built-in type symbols may additionally -// have type [types.Basic], which is not a NamedOrAlias, -// though the spec regards them as "named".) -// -// NamedOrAlias cannot expose the Origin method, because -// [types.Alias.Origin] and [types.Named.Origin] have different -// (covariant) result types; use [Origin] instead. -type NamedOrAlias interface { - types.Type - Obj() *types.TypeName - // TODO(hxjiang): add method TypeArgs() *types.TypeList after stop supporting go1.22. -} - -// TypeParams is a light shim around t.TypeParams(). -// (go/types.Alias).TypeParams requires >= 1.23. -func TypeParams(t NamedOrAlias) *types.TypeParamList { - switch t := t.(type) { - case *types.Alias: - return aliases.TypeParams(t) - case *types.Named: - return t.TypeParams() - } - return nil -} - -// TypeArgs is a light shim around t.TypeArgs(). -// (go/types.Alias).TypeArgs requires >= 1.23. -func TypeArgs(t NamedOrAlias) *types.TypeList { - switch t := t.(type) { - case *types.Alias: - return aliases.TypeArgs(t) - case *types.Named: - return t.TypeArgs() - } - return nil -} - -// Origin returns the generic type of the Named or Alias type t if it -// is instantiated, otherwise it returns t. -func Origin(t NamedOrAlias) NamedOrAlias { - switch t := t.(type) { - case *types.Alias: - return aliases.Origin(t) - case *types.Named: - return t.Origin() - } - return t -} - -// IsPackageLevel reports whether obj is a package-level symbol. -func IsPackageLevel(obj types.Object) bool { - return obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope() -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/varkind.go b/vendor/golang.org/x/tools/internal/typesinternal/varkind.go deleted file mode 100644 index e5da049..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/varkind.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -// TODO(adonovan): when CL 645115 lands, define the go1.25 version of -// this API that actually does something. - -import "go/types" - -type VarKind uint8 - -const ( - _ VarKind = iota // (not meaningful) - PackageVar // a package-level variable - LocalVar // a local variable - RecvVar // a method receiver variable - ParamVar // a function parameter variable - ResultVar // a function result variable - FieldVar // a struct field -) - -func (kind VarKind) String() string { - return [...]string{ - 0: "VarKind(0)", - PackageVar: "PackageVar", - LocalVar: "LocalVar", - RecvVar: "RecvVar", - ParamVar: "ParamVar", - ResultVar: "ResultVar", - FieldVar: "FieldVar", - }[kind] -} - -// GetVarKind returns an invalid VarKind. -func GetVarKind(v *types.Var) VarKind { return 0 } - -// SetVarKind has no effect. -func SetVarKind(v *types.Var, kind VarKind) {} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go deleted file mode 100644 index d272949..0000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright 2024 The Go 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 typesinternal - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" -) - -// ZeroString returns the string representation of the zero value for any type t. -// The boolean result indicates whether the type is or contains an invalid type -// or a non-basic (constraint) interface type. -// -// Even for invalid input types, ZeroString may return a partially correct -// string representation. The caller should use the returned isValid boolean -// to determine the validity of the expression. -// -// When assigning to a wider type (such as 'any'), it's the caller's -// responsibility to handle any necessary type conversions. -// -// This string can be used on the right-hand side of an assignment where the -// left-hand side has that explicit type. -// References to named types are qualified by an appropriate (optional) -// qualifier function. -// Exception: This does not apply to tuples. Their string representation is -// informational only and cannot be used in an assignment. -// -// See [ZeroExpr] for a variant that returns an [ast.Expr]. -func ZeroString(t types.Type, qual types.Qualifier) (_ string, isValid bool) { - switch t := t.(type) { - case *types.Basic: - switch { - case t.Info()&types.IsBoolean != 0: - return "false", true - case t.Info()&types.IsNumeric != 0: - return "0", true - case t.Info()&types.IsString != 0: - return `""`, true - case t.Kind() == types.UnsafePointer: - fallthrough - case t.Kind() == types.UntypedNil: - return "nil", true - case t.Kind() == types.Invalid: - return "invalid", false - default: - panic(fmt.Sprintf("ZeroString for unexpected type %v", t)) - } - - case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature: - return "nil", true - - case *types.Interface: - if !t.IsMethodSet() { - return "invalid", false - } - return "nil", true - - case *types.Named: - switch under := t.Underlying().(type) { - case *types.Struct, *types.Array: - return types.TypeString(t, qual) + "{}", true - default: - return ZeroString(under, qual) - } - - case *types.Alias: - switch t.Underlying().(type) { - case *types.Struct, *types.Array: - return types.TypeString(t, qual) + "{}", true - default: - // A type parameter can have alias but alias type's underlying type - // can never be a type parameter. - // Use types.Unalias to preserve the info of type parameter instead - // of call Underlying() going right through and get the underlying - // type of the type parameter which is always an interface. - return ZeroString(types.Unalias(t), qual) - } - - case *types.Array, *types.Struct: - return types.TypeString(t, qual) + "{}", true - - case *types.TypeParam: - // Assumes func new is not shadowed. - return "*new(" + types.TypeString(t, qual) + ")", true - - case *types.Tuple: - // Tuples are not normal values. - // We are currently format as "(t[0], ..., t[n])". Could be something else. - isValid := true - components := make([]string, t.Len()) - for i := 0; i < t.Len(); i++ { - comp, ok := ZeroString(t.At(i).Type(), qual) - - components[i] = comp - isValid = isValid && ok - } - return "(" + strings.Join(components, ", ") + ")", isValid - - case *types.Union: - // Variables of these types cannot be created, so it makes - // no sense to ask for their zero value. - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - default: - panic(t) // unreachable. - } -} - -// ZeroExpr returns the ast.Expr representation of the zero value for any type t. -// The boolean result indicates whether the type is or contains an invalid type -// or a non-basic (constraint) interface type. -// -// Even for invalid input types, ZeroExpr may return a partially correct ast.Expr -// representation. The caller should use the returned isValid boolean to determine -// the validity of the expression. -// -// This function is designed for types suitable for variables and should not be -// used with Tuple or Union types.References to named types are qualified by an -// appropriate (optional) qualifier function. -// -// See [ZeroString] for a variant that returns a string. -func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) { - switch t := t.(type) { - case *types.Basic: - switch { - case t.Info()&types.IsBoolean != 0: - return &ast.Ident{Name: "false"}, true - case t.Info()&types.IsNumeric != 0: - return &ast.BasicLit{Kind: token.INT, Value: "0"}, true - case t.Info()&types.IsString != 0: - return &ast.BasicLit{Kind: token.STRING, Value: `""`}, true - case t.Kind() == types.UnsafePointer: - fallthrough - case t.Kind() == types.UntypedNil: - return ast.NewIdent("nil"), true - case t.Kind() == types.Invalid: - return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false - default: - panic(fmt.Sprintf("ZeroExpr for unexpected type %v", t)) - } - - case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature: - return ast.NewIdent("nil"), true - - case *types.Interface: - if !t.IsMethodSet() { - return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false - } - return ast.NewIdent("nil"), true - - case *types.Named: - switch under := t.Underlying().(type) { - case *types.Struct, *types.Array: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - default: - return ZeroExpr(under, qual) - } - - case *types.Alias: - switch t.Underlying().(type) { - case *types.Struct, *types.Array: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - default: - return ZeroExpr(types.Unalias(t), qual) - } - - case *types.Array, *types.Struct: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - - case *types.TypeParam: - return &ast.StarExpr{ // *new(T) - X: &ast.CallExpr{ - // Assumes func new is not shadowed. - Fun: ast.NewIdent("new"), - Args: []ast.Expr{ - ast.NewIdent(t.Obj().Name()), - }, - }, - }, true - - case *types.Tuple: - // Unlike ZeroString, there is no ast.Expr can express tuple by - // "(t[0], ..., t[n])". - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - case *types.Union: - // Variables of these types cannot be created, so it makes - // no sense to ask for their zero value. - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - default: - panic(t) // unreachable. - } -} - -// IsZeroExpr uses simple syntactic heuristics to report whether expr -// is a obvious zero value, such as 0, "", nil, or false. -// It cannot do better without type information. -func IsZeroExpr(expr ast.Expr) bool { - switch e := expr.(type) { - case *ast.BasicLit: - return e.Value == "0" || e.Value == `""` - case *ast.Ident: - return e.Name == "nil" || e.Name == "false" - default: - return false - } -} - -// TypeExpr returns syntax for the specified type. References to named types -// are qualified by an appropriate (optional) qualifier function. -// It may panic for types such as Tuple or Union. -func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr { - switch t := t.(type) { - case *types.Basic: - switch t.Kind() { - case types.UnsafePointer: - return &ast.SelectorExpr{X: ast.NewIdent(qual(types.NewPackage("unsafe", "unsafe"))), Sel: ast.NewIdent("Pointer")} - default: - return ast.NewIdent(t.Name()) - } - - case *types.Pointer: - return &ast.UnaryExpr{ - Op: token.MUL, - X: TypeExpr(t.Elem(), qual), - } - - case *types.Array: - return &ast.ArrayType{ - Len: &ast.BasicLit{ - Kind: token.INT, - Value: fmt.Sprintf("%d", t.Len()), - }, - Elt: TypeExpr(t.Elem(), qual), - } - - case *types.Slice: - return &ast.ArrayType{ - Elt: TypeExpr(t.Elem(), qual), - } - - case *types.Map: - return &ast.MapType{ - Key: TypeExpr(t.Key(), qual), - Value: TypeExpr(t.Elem(), qual), - } - - case *types.Chan: - dir := ast.ChanDir(t.Dir()) - if t.Dir() == types.SendRecv { - dir = ast.SEND | ast.RECV - } - return &ast.ChanType{ - Dir: dir, - Value: TypeExpr(t.Elem(), qual), - } - - case *types.Signature: - var params []*ast.Field - for i := 0; i < t.Params().Len(); i++ { - params = append(params, &ast.Field{ - Type: TypeExpr(t.Params().At(i).Type(), qual), - Names: []*ast.Ident{ - { - Name: t.Params().At(i).Name(), - }, - }, - }) - } - if t.Variadic() { - last := params[len(params)-1] - last.Type = &ast.Ellipsis{Elt: last.Type.(*ast.ArrayType).Elt} - } - var returns []*ast.Field - for i := 0; i < t.Results().Len(); i++ { - returns = append(returns, &ast.Field{ - Type: TypeExpr(t.Results().At(i).Type(), qual), - }) - } - return &ast.FuncType{ - Params: &ast.FieldList{ - List: params, - }, - Results: &ast.FieldList{ - List: returns, - }, - } - - case *types.TypeParam: - pkgName := qual(t.Obj().Pkg()) - if pkgName == "" || t.Obj().Pkg() == nil { - return ast.NewIdent(t.Obj().Name()) - } - return &ast.SelectorExpr{ - X: ast.NewIdent(pkgName), - Sel: ast.NewIdent(t.Obj().Name()), - } - - // types.TypeParam also implements interface NamedOrAlias. To differentiate, - // case TypeParam need to be present before case NamedOrAlias. - // TODO(hxjiang): remove this comment once TypeArgs() is added to interface - // NamedOrAlias. - case NamedOrAlias: - var expr ast.Expr = ast.NewIdent(t.Obj().Name()) - if pkgName := qual(t.Obj().Pkg()); pkgName != "." && pkgName != "" { - expr = &ast.SelectorExpr{ - X: ast.NewIdent(pkgName), - Sel: expr.(*ast.Ident), - } - } - - // TODO(hxjiang): call t.TypeArgs after adding method TypeArgs() to - // typesinternal.NamedOrAlias. - if hasTypeArgs, ok := t.(interface{ TypeArgs() *types.TypeList }); ok { - if typeArgs := hasTypeArgs.TypeArgs(); typeArgs != nil && typeArgs.Len() > 0 { - var indices []ast.Expr - for i := range typeArgs.Len() { - indices = append(indices, TypeExpr(typeArgs.At(i), qual)) - } - expr = &ast.IndexListExpr{ - X: expr, - Indices: indices, - } - } - } - - return expr - - case *types.Struct: - return ast.NewIdent(t.String()) - - case *types.Interface: - return ast.NewIdent(t.String()) - - case *types.Union: - if t.Len() == 0 { - panic("Union type should have at least one term") - } - // Same as go/ast, the return expression will put last term in the - // Y field at topmost level of BinaryExpr. - // For union of type "float32 | float64 | int64", the structure looks - // similar to: - // { - // X: { - // X: float32, - // Op: | - // Y: float64, - // } - // Op: |, - // Y: int64, - // } - var union ast.Expr - for i := range t.Len() { - term := t.Term(i) - termExpr := TypeExpr(term.Type(), qual) - if term.Tilde() { - termExpr = &ast.UnaryExpr{ - Op: token.TILDE, - X: termExpr, - } - } - if i == 0 { - union = termExpr - } else { - union = &ast.BinaryExpr{ - X: union, - Op: token.OR, - Y: termExpr, - } - } - } - return union - - case *types.Tuple: - panic("invalid input type types.Tuple") - - default: - panic("unreachable") - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go deleted file mode 100644 index b53f178..0000000 --- a/vendor/golang.org/x/tools/internal/versions/features.go +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -package versions - -// This file contains predicates for working with file versions to -// decide when a tool should consider a language feature enabled. - -// GoVersions that features in x/tools can be gated to. -const ( - Go1_18 = "go1.18" - Go1_19 = "go1.19" - Go1_20 = "go1.20" - Go1_21 = "go1.21" - Go1_22 = "go1.22" -) - -// Future is an invalid unknown Go version sometime in the future. -// Do not use directly with Compare. -const Future = "" - -// AtLeast reports whether the file version v comes after a Go release. -// -// Use this predicate to enable a behavior once a certain Go release -// has happened (and stays enabled in the future). -func AtLeast(v, release string) bool { - if v == Future { - return true // an unknown future version is always after y. - } - return Compare(Lang(v), Lang(release)) >= 0 -} - -// Before reports whether the file version v is strictly before a Go release. -// -// Use this predicate to disable a behavior once a certain Go release -// has happened (and stays enabled in the future). -func Before(v, release string) bool { - if v == Future { - return false // an unknown future version happens after y. - } - return Compare(Lang(v), Lang(release)) < 0 -} diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go deleted file mode 100644 index bbabcd2..0000000 --- a/vendor/golang.org/x/tools/internal/versions/gover.go +++ /dev/null @@ -1,172 +0,0 @@ -// 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. - -// This is a fork of internal/gover for use by x/tools until -// go1.21 and earlier are no longer supported by x/tools. - -package versions - -import "strings" - -// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] -// The numbers are the original decimal strings to avoid integer overflows -// and since there is very little actual math. (Probably overflow doesn't matter in practice, -// but at the time this code was written, there was an existing test that used -// go1.99999999999, which does not fit in an int on 32-bit platforms. -// The "big decimal" representation avoids the problem entirely.) -type gover struct { - major string // decimal - minor string // decimal or "" - patch string // decimal or "" - kind string // "", "alpha", "beta", "rc" - pre string // decimal or "" -} - -// compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as toolchain versions. -// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". -// Malformed versions compare less than well-formed versions and equal to each other. -// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". -func compare(x, y string) int { - vx := parse(x) - vy := parse(y) - - if c := cmpInt(vx.major, vy.major); c != 0 { - return c - } - if c := cmpInt(vx.minor, vy.minor); c != 0 { - return c - } - if c := cmpInt(vx.patch, vy.patch); c != 0 { - return c - } - if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc - return c - } - if c := cmpInt(vx.pre, vy.pre); c != 0 { - return c - } - return 0 -} - -// lang returns the Go language version. For example, lang("1.2.3") == "1.2". -func lang(x string) string { - v := parse(x) - if v.minor == "" || v.major == "1" && v.minor == "0" { - return v.major - } - return v.major + "." + v.minor -} - -// isValid reports whether the version x is valid. -func isValid(x string) bool { - return parse(x) != gover{} -} - -// parse parses the Go version string x into a version. -// It returns the zero version if x is malformed. -func parse(x string) gover { - var v gover - - // Parse major version. - var ok bool - v.major, x, ok = cutInt(x) - if !ok { - return gover{} - } - if x == "" { - // Interpret "1" as "1.0.0". - v.minor = "0" - v.patch = "0" - return v - } - - // Parse . before minor version. - if x[0] != '.' { - return gover{} - } - - // Parse minor version. - v.minor, x, ok = cutInt(x[1:]) - if !ok { - return gover{} - } - if x == "" { - // Patch missing is same as "0" for older versions. - // Starting in Go 1.21, patch missing is different from explicit .0. - if cmpInt(v.minor, "21") < 0 { - v.patch = "0" - } - return v - } - - // Parse patch if present. - if x[0] == '.' { - v.patch, x, ok = cutInt(x[1:]) - if !ok || x != "" { - // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). - // Allowing them would be a bit confusing because we already have: - // 1.21 < 1.21rc1 - // But a prerelease of a patch would have the opposite effect: - // 1.21.3rc1 < 1.21.3 - // We've never needed them before, so let's not start now. - return gover{} - } - return v - } - - // Parse prerelease. - i := 0 - for i < len(x) && (x[i] < '0' || '9' < x[i]) { - if x[i] < 'a' || 'z' < x[i] { - return gover{} - } - i++ - } - if i == 0 { - return gover{} - } - v.kind, x = x[:i], x[i:] - if x == "" { - return v - } - v.pre, x, ok = cutInt(x) - if !ok || x != "" { - return gover{} - } - - return v -} - -// cutInt scans the leading decimal number at the start of x to an integer -// and returns that value and the rest of the string. -func cutInt(x string) (n, rest string, ok bool) { - i := 0 - for i < len(x) && '0' <= x[i] && x[i] <= '9' { - i++ - } - if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero - return "", "", false - } - return x[:i], x[i:], true -} - -// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. -// (Copied from golang.org/x/mod/semver's compareInt.) -func cmpInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go deleted file mode 100644 index 0fc10ce..0000000 --- a/vendor/golang.org/x/tools/internal/versions/types.go +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -package versions - -import ( - "go/ast" - "go/types" -) - -// FileVersion returns a file's Go version. -// The reported version is an unknown Future version if a -// version cannot be determined. -func FileVersion(info *types.Info, file *ast.File) string { - // In tools built with Go >= 1.22, the Go version of a file - // follow a cascades of sources: - // 1) types.Info.FileVersion, which follows the cascade: - // 1.a) file version (ast.File.GoVersion), - // 1.b) the package version (types.Config.GoVersion), or - // 2) is some unknown Future version. - // - // File versions require a valid package version to be provided to types - // in Config.GoVersion. Config.GoVersion is either from the package's module - // or the toolchain (go run). This value should be provided by go/packages - // or unitchecker.Config.GoVersion. - if v := info.FileVersions[file]; IsValid(v) { - return v - } - // Note: we could instead return runtime.Version() [if valid]. - // This would act as a max version on what a tool can support. - return Future -} diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go deleted file mode 100644 index 8d1f745..0000000 --- a/vendor/golang.org/x/tools/internal/versions/versions.go +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -package versions - -import ( - "strings" -) - -// Note: If we use build tags to use go/versions when go >=1.22, -// we run into go.dev/issue/53737. Under some operations users would see an -// import of "go/versions" even if they would not compile the file. -// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include -// For this reason, this library just a clone of go/versions for the moment. - -// Lang returns the Go language version for version x. -// If x is not a valid version, Lang returns the empty string. -// For example: -// -// Lang("go1.21rc2") = "go1.21" -// Lang("go1.21.2") = "go1.21" -// Lang("go1.21") = "go1.21" -// Lang("go1") = "go1" -// Lang("bad") = "" -// Lang("1.21") = "" -func Lang(x string) string { - v := lang(stripGo(x)) - if v == "" { - return "" - } - return x[:2+len(v)] // "go"+v without allocation -} - -// Compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as Go versions. -// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". -// Invalid versions, including the empty string, compare less than -// valid versions and equal to each other. -// The language version "go1.21" compares less than the -// release candidate and eventual releases "go1.21rc1" and "go1.21.0". -// Custom toolchain suffixes are ignored during comparison: -// "go1.21.0" and "go1.21.0-bigcorp" are equal. -func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } - -// IsValid reports whether the version x is valid. -func IsValid(x string) bool { return isValid(stripGo(x)) } - -// stripGo converts from a "go1.21" version to a "1.21" version. -// If v does not start with "go", stripGo returns the empty string (a known invalid version). -func stripGo(v string) string { - v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. - if len(v) < 2 || v[:2] != "go" { - return "" - } - return v[2:] -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 69db806..6a8ea22 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -10,10 +10,9 @@ github.com/akutz/memconn github.com/alexbrainman/sspi github.com/alexbrainman/sspi/internal/common github.com/alexbrainman/sspi/negotiate -# github.com/aws/aws-sdk-go-v2 v1.36.0 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2 v1.41.0 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/aws -github.com/aws/aws-sdk-go-v2/aws/arn github.com/aws/aws-sdk-go-v2/aws/defaults github.com/aws/aws-sdk-go-v2/aws/middleware github.com/aws/aws-sdk-go-v2/aws/protocol/query @@ -53,26 +52,21 @@ github.com/aws/aws-sdk-go-v2/credentials/stscreds ## explicit; go 1.21 github.com/aws/aws-sdk-go-v2/feature/ec2/imds github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config -# github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/internal/configsources -# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 # github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 ## explicit; go 1.21 github.com/aws/aws-sdk-go-v2/internal/ini -# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding -# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url -# github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 -## explicit; go 1.19 -github.com/aws/aws-sdk-go-v2/service/ssm -github.com/aws/aws-sdk-go-v2/service/ssm/internal/endpoints -github.com/aws/aws-sdk-go-v2/service/ssm/types # github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 ## explicit; go 1.21 github.com/aws/aws-sdk-go-v2/service/sso @@ -83,13 +77,13 @@ github.com/aws/aws-sdk-go-v2/service/sso/types github.com/aws/aws-sdk-go-v2/service/ssooidc github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints github.com/aws/aws-sdk-go-v2/service/ssooidc/types -# github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 -## explicit; go 1.21 +# github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 +## explicit; go 1.23 github.com/aws/aws-sdk-go-v2/service/sts github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints github.com/aws/aws-sdk-go-v2/service/sts/types -# github.com/aws/smithy-go v1.22.2 -## explicit; go 1.21 +# github.com/aws/smithy-go v1.24.0 +## explicit; go 1.23 github.com/aws/smithy-go github.com/aws/smithy-go/auth github.com/aws/smithy-go/auth/bearer @@ -100,6 +94,7 @@ github.com/aws/smithy-go/encoding/httpbinding github.com/aws/smithy-go/encoding/json github.com/aws/smithy-go/encoding/xml github.com/aws/smithy-go/endpoints +github.com/aws/smithy-go/endpoints/private/rulesfn github.com/aws/smithy-go/internal/sync/singleflight github.com/aws/smithy-go/io github.com/aws/smithy-go/logging @@ -112,7 +107,6 @@ github.com/aws/smithy-go/time github.com/aws/smithy-go/tracing github.com/aws/smithy-go/transport/http github.com/aws/smithy-go/transport/http/internal/io -github.com/aws/smithy-go/waiter # github.com/coder/websocket v1.8.12 ## explicit; go 1.19 github.com/coder/websocket @@ -121,9 +115,9 @@ github.com/coder/websocket/internal/errd github.com/coder/websocket/internal/util github.com/coder/websocket/internal/wsjs github.com/coder/websocket/internal/xsync -# github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 -## explicit; go 1.16 -github.com/coreos/go-iptables/iptables +# github.com/creachadair/msync v0.7.1 +## explicit; go 1.25 +github.com/creachadair/msync/trigger # github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa ## explicit; go 1.21 github.com/dblohm7/wingoes @@ -131,18 +125,15 @@ github.com/dblohm7/wingoes/com github.com/dblohm7/wingoes/com/automation github.com/dblohm7/wingoes/internal github.com/dblohm7/wingoes/pe -# github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e -## explicit -github.com/digitalocean/go-smbios/smbios -# github.com/fxamacker/cbor/v2 v2.7.0 -## explicit; go 1.17 +# github.com/fxamacker/cbor/v2 v2.9.0 +## explicit; go 1.20 github.com/fxamacker/cbor/v2 # github.com/gaissmai/bart v0.18.0 ## explicit; go 1.23.6 github.com/gaissmai/bart github.com/gaissmai/bart/internal/bitset github.com/gaissmai/bart/internal/sparse -# github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 +# github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced ## explicit; go 1.24 github.com/go-json-experiment/json github.com/go-json-experiment/json/internal @@ -150,102 +141,63 @@ github.com/go-json-experiment/json/internal/jsonflags github.com/go-json-experiment/json/internal/jsonopts github.com/go-json-experiment/json/internal/jsonwire github.com/go-json-experiment/json/jsontext -# github.com/go-ole/go-ole v1.3.0 -## explicit; go 1.12 -github.com/go-ole/go-ole -github.com/go-ole/go-ole/oleutil # github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 ## explicit; go 1.12 github.com/godbus/dbus/v5 -# github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da -## explicit +# github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 +## explicit; go 1.20 github.com/golang/groupcache/lru -# github.com/google/btree v1.1.2 +# github.com/google/btree v1.1.3 ## explicit; go 1.18 github.com/google/btree -# github.com/google/go-cmp v0.6.0 -## explicit; go 1.13 +# github.com/google/go-cmp v0.7.0 +## explicit; go 1.21 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 -## explicit; go 1.21 -github.com/google/nftables -github.com/google/nftables/alignedbuff -github.com/google/nftables/binaryutil -github.com/google/nftables/expr -github.com/google/nftables/internal/parseexprfunc -github.com/google/nftables/xt # github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid -# github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 -## explicit; go 1.20 -github.com/gorilla/csrf -# github.com/gorilla/securecookie v1.1.2 -## explicit; go 1.20 -github.com/gorilla/securecookie # github.com/hdevalence/ed25519consensus v0.2.0 ## explicit; go 1.19 github.com/hdevalence/ed25519consensus -# github.com/illarion/gonotify/v3 v3.0.2 -## explicit; go 1.12 -github.com/illarion/gonotify/v3 -github.com/illarion/gonotify/v3/syscallf -# github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 -## explicit; go 1.20 -github.com/insomniacslk/dhcp/dhcpv4 -github.com/insomniacslk/dhcp/iana -github.com/insomniacslk/dhcp/interfaces -github.com/insomniacslk/dhcp/rfc1035label -# github.com/jmespath/go-jmespath v0.4.0 +# github.com/huin/goupnp v1.3.0 ## explicit; go 1.14 -github.com/jmespath/go-jmespath +github.com/huin/goupnp +github.com/huin/goupnp/dcps/internetgateway2 +github.com/huin/goupnp/httpu +github.com/huin/goupnp/scpd +github.com/huin/goupnp/soap +github.com/huin/goupnp/ssdp # github.com/jsimonetti/rtnetlink v1.4.0 ## explicit; go 1.20 github.com/jsimonetti/rtnetlink github.com/jsimonetti/rtnetlink/internal/unix -# github.com/klauspost/compress v1.17.11 -## explicit; go 1.21 +# github.com/klauspost/compress v1.18.2 +## explicit; go 1.23 github.com/klauspost/compress github.com/klauspost/compress/fse github.com/klauspost/compress/huff0 github.com/klauspost/compress/internal/cpuinfo +github.com/klauspost/compress/internal/le github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a -## explicit; go 1.12 -github.com/kortschak/wol -# github.com/mdlayher/genetlink v1.3.2 -## explicit; go 1.18 -github.com/mdlayher/genetlink # github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 ## explicit; go 1.21 github.com/mdlayher/netlink github.com/mdlayher/netlink/nlenc -github.com/mdlayher/netlink/nltest -# github.com/mdlayher/sdnotify v1.0.0 -## explicit; go 1.18 -github.com/mdlayher/sdnotify # github.com/mdlayher/socket v0.5.0 ## explicit; go 1.21 github.com/mdlayher/socket -# github.com/miekg/dns v1.1.58 -## explicit; go 1.19 -github.com/miekg/dns # github.com/mitchellh/go-ps v1.0.0 ## explicit; go 1.13 github.com/mitchellh/go-ps -# 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/pires/go-proxyproto v0.8.1 +## explicit; go 1.24 +github.com/pires/go-proxyproto # github.com/prometheus-community/pro-bing v0.4.0 ## explicit; go 1.19 github.com/prometheus-community/pro-bing @@ -262,28 +214,16 @@ github.com/tailscale/go-winio/internal/fs github.com/tailscale/go-winio/internal/socket github.com/tailscale/go-winio/internal/stringbuffer github.com/tailscale/go-winio/pkg/guid -# github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 -## explicit; go 1.16 -github.com/tailscale/goupnp -github.com/tailscale/goupnp/dcps/internetgateway2 -github.com/tailscale/goupnp/httpu -github.com/tailscale/goupnp/scpd -github.com/tailscale/goupnp/soap -github.com/tailscale/goupnp/ssdp # github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a ## explicit; go 1.18 github.com/tailscale/hujson -# github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 -## explicit; go 1.12 -github.com/tailscale/netlink -github.com/tailscale/netlink/nl # github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc ## explicit; go 1.18 github.com/tailscale/peercred # github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 ## explicit; go 1.21 github.com/tailscale/web-client-prebuilt -# github.com/tailscale/wireguard-go v0.0.0-20250107165329-0b8b35511f19 +# github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da ## explicit; go 1.20 github.com/tailscale/wireguard-go/conn github.com/tailscale/wireguard-go/conn/winrio @@ -295,13 +235,6 @@ github.com/tailscale/wireguard-go/replay github.com/tailscale/wireguard-go/rwcancel github.com/tailscale/wireguard-go/tai64n github.com/tailscale/wireguard-go/tun -# 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/netns v0.0.4 -## explicit; go 1.17 -github.com/vishvananda/netns # github.com/x448/float16 v0.8.4 ## explicit; go 1.11 github.com/x448/float16 @@ -311,8 +244,8 @@ go4.org/mem # go4.org/netipx v0.0.0-20231129151722-fdeea329fbba ## explicit; go 1.18 go4.org/netipx -# golang.org/x/crypto v0.35.0 -## explicit; go 1.23.0 +# golang.org/x/crypto v0.46.0 +## explicit; go 1.24.0 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b golang.org/x/crypto/blake2s @@ -329,25 +262,18 @@ golang.org/x/crypto/poly1305 golang.org/x/crypto/salsa20/salsa golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac -## explicit; go 1.22.0 +# golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b +## explicit; go 1.23.0 golang.org/x/exp/constraints golang.org/x/exp/maps -# golang.org/x/mod v0.23.0 -## explicit; go 1.22.0 -golang.org/x/mod/semver -# golang.org/x/net v0.36.0 -## explicit; go 1.23.0 +# golang.org/x/net v0.48.0 +## explicit; go 1.24.0 golang.org/x/net/bpf golang.org/x/net/dns/dnsmessage golang.org/x/net/http/httpguts golang.org/x/net/http/httpproxy -golang.org/x/net/http2 -golang.org/x/net/http2/h2c -golang.org/x/net/http2/hpack golang.org/x/net/icmp golang.org/x/net/idna -golang.org/x/net/internal/httpcommon golang.org/x/net/internal/iana golang.org/x/net/internal/socket golang.org/x/net/internal/socks @@ -355,11 +281,16 @@ golang.org/x/net/ipv4 golang.org/x/net/ipv6 golang.org/x/net/proxy golang.org/x/net/route -# golang.org/x/sync v0.11.0 -## explicit; go 1.18 +# golang.org/x/oauth2 v0.32.0 +## explicit; go 1.24.0 +golang.org/x/oauth2 +golang.org/x/oauth2/clientcredentials +golang.org/x/oauth2/internal +# golang.org/x/sync v0.19.0 +## explicit; go 1.24.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.30.0 -## explicit; go 1.18 +# golang.org/x/sys v0.40.0 +## explicit; go 1.24.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 golang.org/x/sys/unix @@ -367,37 +298,18 @@ golang.org/x/sys/windows golang.org/x/sys/windows/registry golang.org/x/sys/windows/svc golang.org/x/sys/windows/svc/mgr -# golang.org/x/term v0.29.0 -## explicit; go 1.18 +# golang.org/x/term v0.38.0 +## explicit; go 1.24.0 golang.org/x/term -# golang.org/x/text v0.22.0 -## explicit; go 1.18 +# golang.org/x/text v0.32.0 +## explicit; go 1.24.0 golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm -# golang.org/x/time v0.10.0 -## explicit; go 1.18 +# golang.org/x/time v0.12.0 +## explicit; go 1.23.0 golang.org/x/time/rate -# golang.org/x/tools v0.30.0 -## explicit; go 1.22.0 -golang.org/x/tools/go/gcexportdata -golang.org/x/tools/go/packages -golang.org/x/tools/go/types/objectpath -golang.org/x/tools/go/types/typeutil -golang.org/x/tools/internal/aliases -golang.org/x/tools/internal/event -golang.org/x/tools/internal/event/core -golang.org/x/tools/internal/event/keys -golang.org/x/tools/internal/event/label -golang.org/x/tools/internal/gcimporter -golang.org/x/tools/internal/gocommand -golang.org/x/tools/internal/packagesinternal -golang.org/x/tools/internal/pkgbits -golang.org/x/tools/internal/stdlib -golang.org/x/tools/internal/typeparams -golang.org/x/tools/internal/typesinternal -golang.org/x/tools/internal/versions # golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 ## explicit; go 1.17 golang.zx2c4.com/wintun @@ -449,8 +361,8 @@ gvisor.dev/gvisor/pkg/tcpip/transport/tcp gvisor.dev/gvisor/pkg/tcpip/transport/tcpconntrack gvisor.dev/gvisor/pkg/tcpip/transport/udp gvisor.dev/gvisor/pkg/waiter -# tailscale.com v1.82.0 -## explicit; go 1.24.0 +# tailscale.com v1.94.1 +## explicit; go 1.25.5 tailscale.com tailscale.com/appc tailscale.com/atomicfile @@ -458,62 +370,58 @@ tailscale.com/client/local tailscale.com/client/tailscale tailscale.com/client/tailscale/apitype tailscale.com/client/web -tailscale.com/clientupdate -tailscale.com/clientupdate/distsign tailscale.com/control/controlbase tailscale.com/control/controlclient tailscale.com/control/controlhttp tailscale.com/control/controlhttp/controlhttpcommon tailscale.com/control/controlknobs +tailscale.com/control/ts2021 tailscale.com/derp +tailscale.com/derp/derpconst tailscale.com/derp/derphttp tailscale.com/disco -tailscale.com/doctor -tailscale.com/doctor/ethtool -tailscale.com/doctor/permissions -tailscale.com/doctor/routetable tailscale.com/drive tailscale.com/envknob tailscale.com/envknob/featureknob tailscale.com/feature -tailscale.com/feature/capture -tailscale.com/feature/condregister -tailscale.com/feature/tap -tailscale.com/feature/wakeonlan +tailscale.com/feature/buildfeatures +tailscale.com/feature/c2n +tailscale.com/feature/condlite/expvar +tailscale.com/feature/condregister/identityfederation +tailscale.com/feature/condregister/oauthkey +tailscale.com/feature/condregister/portmapper +tailscale.com/feature/condregister/useproxy +tailscale.com/feature/identityfederation +tailscale.com/feature/oauthkey +tailscale.com/feature/portmapper +tailscale.com/feature/syspolicy +tailscale.com/feature/useproxy tailscale.com/health tailscale.com/health/healthmsg tailscale.com/hostinfo -tailscale.com/internal/noiseconn +tailscale.com/internal/client/tailscale tailscale.com/ipn -tailscale.com/ipn/auditlog tailscale.com/ipn/conffile -tailscale.com/ipn/desktop tailscale.com/ipn/ipnauth +tailscale.com/ipn/ipnext tailscale.com/ipn/ipnlocal tailscale.com/ipn/ipnstate tailscale.com/ipn/localapi -tailscale.com/ipn/policy tailscale.com/ipn/store -tailscale.com/ipn/store/awsstore -tailscale.com/ipn/store/kubestore tailscale.com/ipn/store/mem -tailscale.com/kube/kubeapi -tailscale.com/kube/kubeclient tailscale.com/kube/kubetypes tailscale.com/licenses tailscale.com/log/filelogger tailscale.com/log/sockstatlog tailscale.com/logpolicy tailscale.com/logtail -tailscale.com/logtail/backoff tailscale.com/logtail/filch tailscale.com/metrics tailscale.com/net/bakedroots +tailscale.com/net/batching tailscale.com/net/captivedetection -tailscale.com/net/connstats tailscale.com/net/dns tailscale.com/net/dns/publicdns -tailscale.com/net/dns/recursive tailscale.com/net/dns/resolvconffile tailscale.com/net/dns/resolver tailscale.com/net/dnscache @@ -528,34 +436,33 @@ tailscale.com/net/netkernelconf tailscale.com/net/netknob tailscale.com/net/netmon tailscale.com/net/netns -tailscale.com/net/netstat tailscale.com/net/netutil +tailscale.com/net/netx tailscale.com/net/packet tailscale.com/net/packet/checksum tailscale.com/net/ping tailscale.com/net/portmapper +tailscale.com/net/portmapper/portmappertype tailscale.com/net/proxymux -tailscale.com/net/routetable +tailscale.com/net/sockopts tailscale.com/net/socks5 tailscale.com/net/sockstats tailscale.com/net/stun -tailscale.com/net/tcpinfo tailscale.com/net/tlsdial tailscale.com/net/tlsdial/blockblame tailscale.com/net/tsaddr tailscale.com/net/tsdial tailscale.com/net/tshttpproxy tailscale.com/net/tstun +tailscale.com/net/udprelay/endpoint +tailscale.com/net/udprelay/status tailscale.com/net/wsconn tailscale.com/omit tailscale.com/paths -tailscale.com/portlist -tailscale.com/posture tailscale.com/proxymap tailscale.com/safesocket tailscale.com/syncs tailscale.com/tailcfg -tailscale.com/taildrop tailscale.com/tempfork/acme tailscale.com/tempfork/heap tailscale.com/tempfork/httprec @@ -566,6 +473,7 @@ tailscale.com/tsnet tailscale.com/tstime tailscale.com/tstime/mono tailscale.com/tstime/rate +tailscale.com/tsweb tailscale.com/tsweb/varz tailscale.com/types/appctype tailscale.com/types/bools @@ -576,6 +484,8 @@ tailscale.com/types/key tailscale.com/types/lazy tailscale.com/types/logger tailscale.com/types/logid +tailscale.com/types/mapx +tailscale.com/types/netlogfunc tailscale.com/types/netlogtype tailscale.com/types/netmap tailscale.com/types/nettype @@ -587,35 +497,34 @@ tailscale.com/types/result tailscale.com/types/structs tailscale.com/types/tkatype tailscale.com/types/views +tailscale.com/util/backoff +tailscale.com/util/checkchange tailscale.com/util/cibuild tailscale.com/util/clientmetric tailscale.com/util/cloudenv +tailscale.com/util/cloudinfo tailscale.com/util/cmpver tailscale.com/util/ctxkey tailscale.com/util/deephash tailscale.com/util/dirwalk tailscale.com/util/dnsname +tailscale.com/util/eventbus tailscale.com/util/execqueue tailscale.com/util/goroutines tailscale.com/util/groupmember tailscale.com/util/hashx -tailscale.com/util/httphdr tailscale.com/util/httpm tailscale.com/util/lineiter -tailscale.com/util/linuxfw tailscale.com/util/mak -tailscale.com/util/multierr tailscale.com/util/must tailscale.com/util/nocasemaps tailscale.com/util/osdiag tailscale.com/util/osdiag/internal/wsc -tailscale.com/util/osshare tailscale.com/util/osuser -tailscale.com/util/progresstracking tailscale.com/util/race tailscale.com/util/racebuild tailscale.com/util/rands -tailscale.com/util/ringbuffer +tailscale.com/util/ringlog tailscale.com/util/set tailscale.com/util/singleflight tailscale.com/util/slicesx @@ -623,11 +532,12 @@ tailscale.com/util/syspolicy tailscale.com/util/syspolicy/internal tailscale.com/util/syspolicy/internal/loggerx tailscale.com/util/syspolicy/internal/metrics +tailscale.com/util/syspolicy/pkey +tailscale.com/util/syspolicy/policyclient +tailscale.com/util/syspolicy/ptype tailscale.com/util/syspolicy/rsop tailscale.com/util/syspolicy/setting tailscale.com/util/syspolicy/source -tailscale.com/util/sysresources -tailscale.com/util/systemd tailscale.com/util/testenv tailscale.com/util/truncate tailscale.com/util/usermetric @@ -652,4 +562,4 @@ tailscale.com/wgengine/wgcfg tailscale.com/wgengine/wgcfg/nmcfg tailscale.com/wgengine/wgint tailscale.com/wgengine/wglog -tailscale.com/wgengine/winnet +tailscale.com/wif diff --git a/vendor/tailscale.com/.gitignore b/vendor/tailscale.com/.gitignore index 47d2bbe..3941fd0 100644 --- a/vendor/tailscale.com/.gitignore +++ b/vendor/tailscale.com/.gitignore @@ -49,3 +49,6 @@ client/web/build/assets *.xcworkspacedata /tstest/tailmac/bin /tstest/tailmac/build + +# Ignore personal IntelliJ settings +.idea/ diff --git a/vendor/tailscale.com/.golangci.yml b/vendor/tailscale.com/.golangci.yml index 15f8b5d..eb34f9d 100644 --- a/vendor/tailscale.com/.golangci.yml +++ b/vendor/tailscale.com/.golangci.yml @@ -1,97 +1,110 @@ +version: "2" +# Configuration for how we run golangci-lint +# Timeout of 5m was the default in v1. +run: + timeout: 5m linters: # Don't enable any linters by default; just the ones that we explicitly # enable in the list below. - disable-all: true + default: none enable: - bidichk - - gofmt - - goimports - govet - misspell - revive - -# Configuration for how we run golangci-lint -run: - timeout: 5m - -issues: - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - # These are forks of an upstream package and thus are exempt from stylistic - # changes that would make pulling in upstream changes harder. - - path: tempfork/.*\.go - text: "File is not `gofmt`-ed with `-s` `-r 'interface{} -> any'`" - - path: util/singleflight/.*\.go - text: "File is not `gofmt`-ed with `-s` `-r 'interface{} -> any'`" - -# Per-linter settings are contained in this top-level key -linters-settings: - gofmt: - rewrite-rules: - - pattern: 'interface{}' - replacement: 'any' - - govet: + settings: # Matches what we use in corp as of 2023-12-07 - enable: - - asmdecl - - assign - - atomic - - bools - - buildtag - - cgocall - - copylocks - - deepequalerrors - - errorsas - - framepointer - - httpresponse - - ifaceassert - - loopclosure - - lostcancel - - nilfunc - - nilness - - printf - - reflectvaluecompare - - shift - - sigchanyzer - - sortslice - - stdmethods - - stringintconv - - structtag - - testinggoroutine - - tests - - unmarshal - - unreachable - - unsafeptr - - unusedresult - settings: - printf: - # List of print function names to check (in addition to default) - funcs: - - github.com/tailscale/tailscale/types/logger.Discard - # NOTE(andrew-d): this doesn't currently work because the printf - # analyzer doesn't support type declarations - #- github.com/tailscale/tailscale/types/logger.Logf - - revive: - enable-all-rules: false - ignore-generated-header: true + govet: + enable: + - asmdecl + - assign + - atomic + - bools + - buildtag + - cgocall + - copylocks + - deepequalerrors + - errorsas + - framepointer + - httpresponse + - ifaceassert + - loopclosure + - lostcancel + - nilfunc + - nilness + - printf + - reflectvaluecompare + - shift + - sigchanyzer + - sortslice + - stdmethods + - stringintconv + - structtag + - testinggoroutine + - tests + - unmarshal + - unreachable + - unsafeptr + - unusedresult + settings: + printf: + # List of print function names to check (in addition to default) + funcs: + - github.com/tailscale/tailscale/types/logger.Discard + # NOTE(andrew-d): this doesn't currently work because the printf + # analyzer doesn't support type declarations + #- github.com/tailscale/tailscale/types/logger.Logf + revive: + enable-all-rules: false + rules: + - name: atomic + - name: context-keys-type + - name: defer + arguments: [[ + # Calling 'recover' at the time a defer is registered (i.e. "defer recover()") has no effect. + "immediate-recover", + # Calling 'recover' outside of a deferred function has no effect + "recover", + # Returning values from a deferred function has no effect + "return", + ]] + - name: duplicated-imports + - name: errorf + - name: string-of-int + - name: time-equal + - name: unconditional-recursion + - name: useless-break + - name: waitgroup-by-value + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling rules: - - name: atomic - - name: context-keys-type - - name: defer - arguments: [[ - # Calling 'recover' at the time a defer is registered (i.e. "defer recover()") has no effect. - "immediate-recover", - # Calling 'recover' outside of a deferred function has no effect - "recover", - # Returning values from a deferred function has no effect - "return", - ]] - - name: duplicated-imports - - name: errorf - - name: string-of-int - - name: time-equal - - name: unconditional-recursion - - name: useless-break - - name: waitgroup-by-value + # These are forks of an upstream package and thus are exempt from stylistic + # changes that would make pulling in upstream changes harder. + - path: tempfork/.*\.go + text: File is not `gofmt`-ed with `-s` `-r 'interface{} -> any'` + - path: util/singleflight/.*\.go + text: File is not `gofmt`-ed with `-s` `-r 'interface{} -> any'` + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - goimports + settings: + gofmt: + rewrite-rules: + - pattern: interface{} + replacement: any + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/tailscale.com/ALPINE.txt b/vendor/tailscale.com/ALPINE.txt index 318956c..93a84c3 100644 --- a/vendor/tailscale.com/ALPINE.txt +++ b/vendor/tailscale.com/ALPINE.txt @@ -1 +1 @@ -3.19 \ No newline at end of file +3.22 \ No newline at end of file diff --git a/vendor/tailscale.com/CODE_OF_CONDUCT.md b/vendor/tailscale.com/CODE_OF_CONDUCT.md index be5564e..348483d 100644 --- a/vendor/tailscale.com/CODE_OF_CONDUCT.md +++ b/vendor/tailscale.com/CODE_OF_CONDUCT.md @@ -1,135 +1,103 @@ -# Contributor Covenant Code of Conduct +# Tailscale Community Code of Conduct ## Our Pledge -We as members, contributors, and leaders pledge to make participation -in our community a harassment-free experience for everyone, regardless -of age, body size, visible or invisible disability, ethnicity, sex -characteristics, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, -welcoming, diverse, inclusive, and healthy community. +We are committed to creating an open, welcoming, diverse, inclusive, healthy and respectful community. +Unacceptable, harmful and inappropriate behavior will not be tolerated. ## Our Standards -Examples of behavior that contributes to a positive environment for -our community include: +Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our - mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community +- Demonstrating empathy and kindness toward other people. +- Being respectful of differing opinions, viewpoints, and experiences. +- Giving and gracefully accepting constructive feedback. +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience. +- Focusing on what is best not just for us as individuals, but for the overall community. -Examples of unacceptable behavior include: +Examples of unacceptable behavior include without limitation: -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or - political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in - a professional setting +- The use of language, imagery or emojis (collectively "content") that is racist, sexist, homophobic, transphobic, or otherwise harassing or discriminatory based on any protected characteristic. +- The use of sexualized content and sexual attention or advances of any kind. +- The use of violent, intimidating or bullying content. +- Trolling, concern trolling, insulting or derogatory comments, and personal or political attacks. +- Public or private harassment. +- Publishing others' personal information, such as a photo, physical address, email address, online profile information, or other personal information, without their explicit permission or with the intent to bully or harass the other person. +- Posting deep fake or other AI generated content about or involving another person without the explicit permission. +- Spamming community channels and members, such as sending repeat messages, low-effort content, or automated messages. +- Phishing or any similar activity. +- Distributing or promoting malware. +- The use of any coded or suggestive content to hide or provoke otherwise unacceptable behavior. +- Other conduct which could reasonably be considered harmful, illegal, or inappropriate in a professional setting. -## Enforcement Responsibilities +Please also see the Tailscale Acceptable Use Policy, available at [tailscale.com/tailscale-aup](https://tailscale.com/tailscale-aup). -Community leaders are responsible for clarifying and enforcing our -standards of acceptable behavior and will take appropriate and fair -corrective action in response to any behavior that they deem -inappropriate, threatening, offensive, or harmful. +## Reporting Incidents -Community leaders have the right and responsibility to remove, edit, -or reject comments, commits, code, wiki edits, issues, and other -contributions that are not aligned to this Code of Conduct, and will -communicate reasons for moderation decisions when appropriate. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Tailscale directly via , or to the community leaders or moderators via DM or similar. +All complaints will be reviewed and investigated promptly and fairly. +We will respect the privacy and safety of the reporter of any issues. -## Scope - -This Code of Conduct applies within all community spaces, and also -applies when an individual is officially representing the community in -public spaces. Examples of representing our community include using an -official e-mail address, posting via an official social media account, -or acting as an appointed representative at an online or offline -event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported to the community leaders responsible for enforcement -at [info@tailscale.com](mailto:info@tailscale.com). All complaints -will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and -security of the reporter of any incident. +Please note that this community is not moderated by staff 24/7, and we do not have, and do not undertake, any obligation to prescreen, monitor, edit, or remove any content or data, or to actively seek facts or circumstances indicating illegal activity. +While we strive to keep the community safe and welcoming, moderation may not be immediate at all hours. +If you encounter any issues, report them using the appropriate channels. ## Enforcement Guidelines -Community leaders will follow these Community Impact Guidelines in -determining the consequences for any action they deem in violation of -this Code of Conduct: +Community leaders and moderators are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders and moderators have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Community Code of Conduct. +Tailscale retains full discretion to take action (or not) in response to a violation of these guidelines with or without notice or liability to you. +We will interpret our policies and resolve disputes in favor of protecting users, customers, the public, our community and our company, as a whole. + +Community leaders will follow these community enforcement guidelines in determining the consequences for any action they deem in violation of this Code of Conduct, +and retain full discretion to apply the enforcement guidelines as necessary depending on the circumstances: ### 1. Correction -**Community Impact**: Use of inappropriate language or other behavior -deemed unprofessional or unwelcome in the community. +Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. -**Consequence**: A private, written warning from community leaders, -providing clarity around the nature of the violation and an -explanation of why the behavior was inappropriate. A public apology -may be requested. +Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. +A public apology may be requested. ### 2. Warning -**Community Impact**: A violation through a single incident or series -of actions. +Community Impact: A violation through a single incident or series of actions. -**Consequence**: A warning with consequences for continued -behavior. No interaction with the people involved, including -unsolicited interaction with those enforcing the Code of Conduct, for -a specified period of time. This includes avoiding interactions in -community spaces as well as external channels like social -media. Violating these terms may lead to a temporary or permanent ban. +Consequence: A warning with consequences for continued behavior. +No interaction with the people involved, including unsolicited interaction with those enforcing this Community Code of Conduct, for a specified period of time. +This includes avoiding interactions in community spaces as well as external channels like social media. +Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban -**Community Impact**: A serious violation of community standards, -including sustained inappropriate behavior. +Community Impact: A serious violation of community standards, including sustained inappropriate behavior. -**Consequence**: A temporary ban from any sort of interaction or -public communication with the community for a specified period of -time. No public or private interaction with the people involved, -including unsolicited interaction with those enforcing the Code of -Conduct, is allowed during this period. Violating these terms may lead -to a permanent ban. +Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. +No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban -**Community Impact**: Demonstrating a pattern of violation of -community standards, including sustained inappropriate behavior, -harassment of an individual, or aggression toward or disparagement of -classes of individuals. +Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. -**Consequence**: A permanent ban from any sort of public interaction -within the community. +Consequence: A permanent ban from any sort of public interaction within the community. + +## Acceptable Use Policy + +Violation of this Community Code of Conduct may also violate the Tailscale Acceptable Use Policy, which may result in suspension or termination of your Tailscale account. +For more information, please see the Tailscale Acceptable Use Policy, available at [tailscale.com/tailscale-aup](https://tailscale.com/tailscale-aup). + +## Privacy + +Please see the Tailscale [Privacy Policy](https://tailscale.com/privacy-policy) for more information about how Tailscale collects, uses, discloses and protects information. ## Attribution -This Code of Conduct is adapted from the [Contributor -Covenant][homepage], version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at . -Community Impact Guidelines were inspired by [Mozilla's code of -conduct enforcement ladder](https://github.com/mozilla/diversity). +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org -For answers to common questions about this code of conduct, see the -FAQ at https://www.contributor-covenant.org/faq. Translations are -available at https://www.contributor-covenant.org/translations. - +For answers to common questions about this code of conduct, see the FAQ at . +Translations are available at . diff --git a/vendor/tailscale.com/Dockerfile b/vendor/tailscale.com/Dockerfile index 015022e..7122f99 100644 --- a/vendor/tailscale.com/Dockerfile +++ b/vendor/tailscale.com/Dockerfile @@ -7,6 +7,15 @@ # Tailscale images are currently built using https://github.com/tailscale/mkctr, # and the build script can be found in ./build_docker.sh. # +# If you want to build local images for testing, you can use make. +# +# To build a Tailscale image and push to the local docker registry: +# +# $ REPO=local/tailscale TAGS=v0.0.1 PLATFORM=local make publishdevimage +# +# To build a Tailscale image and push to a remote docker registry: +# +# $ REPO=//tailscale TAGS=v0.0.1 make publishdevimage # # This Dockerfile includes all the tailscale binaries. # @@ -27,7 +36,7 @@ # $ docker exec tailscaled tailscale status -FROM golang:1.24-alpine AS build-env +FROM golang:1.25-alpine AS build-env WORKDIR /go/src/tailscale @@ -62,10 +71,15 @@ RUN GOARCH=$TARGETARCH go install -ldflags="\ -X tailscale.com/version.gitCommitStamp=$VERSION_GIT_HASH" \ -v ./cmd/tailscale ./cmd/tailscaled ./cmd/containerboot -FROM alpine:3.19 +FROM alpine:3.22 RUN apk add --no-cache ca-certificates iptables iproute2 ip6tables -RUN rm /sbin/iptables && ln -s /sbin/iptables-legacy /sbin/iptables -RUN rm /sbin/ip6tables && ln -s /sbin/ip6tables-legacy /sbin/ip6tables +# Alpine 3.19 replaced legacy iptables with nftables based implementation. +# Tailscale is used on some hosts that don't support nftables, such as Synology +# NAS, so link iptables back to legacy version. Hosts that don't require legacy +# iptables should be able to use Tailscale in nftables mode. See +# https://github.com/tailscale/tailscale/issues/17854 +RUN rm /usr/sbin/iptables && ln -s /usr/sbin/iptables-legacy /usr/sbin/iptables +RUN rm /usr/sbin/ip6tables && ln -s /usr/sbin/ip6tables-legacy /usr/sbin/ip6tables COPY --from=build-env /go/bin/* /usr/local/bin/ # For compat with the previous run.sh, although ideally you should be diff --git a/vendor/tailscale.com/Dockerfile.base b/vendor/tailscale.com/Dockerfile.base index b7e79a4..9b7ae51 100644 --- a/vendor/tailscale.com/Dockerfile.base +++ b/vendor/tailscale.com/Dockerfile.base @@ -1,12 +1,12 @@ # Copyright (c) Tailscale Inc & AUTHORS # SPDX-License-Identifier: BSD-3-Clause -FROM alpine:3.19 +FROM alpine:3.22 RUN apk add --no-cache ca-certificates iptables iptables-legacy iproute2 ip6tables iputils -# Alpine 3.19 replaces legacy iptables with nftables based implementation. We -# can't be certain that all hosts that run Tailscale containers currently -# suppport nftables, so link back to legacy for backwards compatibility reasons. -# TODO(irbekrm): add some way how to determine if we still run on nodes that -# don't support nftables, so that we can eventually remove these symlinks. -RUN rm /sbin/iptables && ln -s /sbin/iptables-legacy /sbin/iptables -RUN rm /sbin/ip6tables && ln -s /sbin/ip6tables-legacy /sbin/ip6tables +# Alpine 3.19 replaced legacy iptables with nftables based implementation. +# Tailscale is used on some hosts that don't support nftables, such as Synology +# NAS, so link iptables back to legacy version. Hosts that don't require legacy +# iptables should be able to use Tailscale in nftables mode. See +# https://github.com/tailscale/tailscale/issues/17854 +RUN rm /usr/sbin/iptables && ln -s /usr/sbin/iptables-legacy /usr/sbin/iptables +RUN rm /usr/sbin/ip6tables && ln -s /usr/sbin/ip6tables-legacy /usr/sbin/ip6tables diff --git a/vendor/tailscale.com/Makefile b/vendor/tailscale.com/Makefile index 30ac532..b78ef04 100644 --- a/vendor/tailscale.com/Makefile +++ b/vendor/tailscale.com/Makefile @@ -8,8 +8,9 @@ PLATFORM ?= "flyio" ## flyio==linux/amd64. Set to "" to build all platforms. vet: ## Run go vet ./tool/go vet ./... -tidy: ## Run go mod tidy +tidy: ## Run go mod tidy and update nix flake hashes ./tool/go mod tidy + ./update-flake.sh lint: ## Run golangci-lint ./tool/go run github.com/golangci/golangci-lint/cmd/golangci-lint run @@ -17,22 +18,36 @@ lint: ## Run golangci-lint updatedeps: ## Update depaware deps # depaware (via x/tools/go/packages) shells back to "go", so make sure the "go" # it finds in its $$PATH is the right one. - PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update --internal \ + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update --vendor --internal \ tailscale.com/cmd/tailscaled \ tailscale.com/cmd/tailscale \ tailscale.com/cmd/derper \ tailscale.com/cmd/k8s-operator \ - tailscale.com/cmd/stund + tailscale.com/cmd/stund \ + tailscale.com/cmd/tsidp + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update --goos=linux,darwin,windows,android,ios --vendor --internal \ + tailscale.com/tsnet + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update --file=depaware-minbox.txt --goos=linux --tags="$$(./tool/go run ./cmd/featuretags --min --add=cli)" --vendor --internal \ + tailscale.com/cmd/tailscaled + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --update --file=depaware-min.txt --goos=linux --tags="$$(./tool/go run ./cmd/featuretags --min)" --vendor --internal \ + tailscale.com/cmd/tailscaled depaware: ## Run depaware checks # depaware (via x/tools/go/packages) shells back to "go", so make sure the "go" # it finds in its $$PATH is the right one. - PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check --internal \ + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check --vendor --internal \ tailscale.com/cmd/tailscaled \ tailscale.com/cmd/tailscale \ tailscale.com/cmd/derper \ tailscale.com/cmd/k8s-operator \ - tailscale.com/cmd/stund + tailscale.com/cmd/stund \ + tailscale.com/cmd/tsidp + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check --goos=linux,darwin,windows,android,ios --vendor --internal \ + tailscale.com/tsnet + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check --file=depaware-minbox.txt --goos=linux --tags="$$(./tool/go run ./cmd/featuretags --min --add=cli)" --vendor --internal \ + tailscale.com/cmd/tailscaled + PATH="$$(./tool/go env GOROOT)/bin:$$PATH" ./tool/go run github.com/tailscale/depaware --check --file=depaware-min.txt --goos=linux --tags="$$(./tool/go run ./cmd/featuretags --min)" --vendor --internal \ + tailscale.com/cmd/tailscaled buildwindows: ## Build tailscale CLI for windows/amd64 GOOS=windows GOARCH=amd64 ./tool/go install tailscale.com/cmd/tailscale tailscale.com/cmd/tailscaled @@ -58,7 +73,7 @@ buildmultiarchimage: ## Build (and optionally push) multiarch docker image check: staticcheck vet depaware buildwindows build386 buildlinuxarm buildwasm ## Perform basic checks and compilation tests staticcheck: ## Run staticcheck.io checks - ./tool/go run honnef.co/go/tools/cmd/staticcheck -- $$(./tool/go list ./... | grep -v tempfork) + ./tool/go run honnef.co/go/tools/cmd/staticcheck -- $$(./tool/go run ./tool/listpkgs --ignore-3p ./...) kube-generate-all: kube-generate-deepcopy ## Refresh generated files for Tailscale Kubernetes Operator ./tool/go generate ./cmd/k8s-operator @@ -86,42 +101,60 @@ pushspk: spk ## Push and install synology package on ${SYNO_HOST} host scp tailscale.spk root@${SYNO_HOST}: ssh root@${SYNO_HOST} /usr/syno/bin/synopkg install tailscale.spk -publishdevimage: ## Build and publish tailscale image to location specified by ${REPO} - @test -n "${REPO}" || (echo "REPO=... required; e.g. REPO=ghcr.io/${USER}/tailscale" && exit 1) - @test "${REPO}" != "tailscale/tailscale" || (echo "REPO=... must not be tailscale/tailscale" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/tailscale" || (echo "REPO=... must not be ghcr.io/tailscale/tailscale" && exit 1) - @test "${REPO}" != "tailscale/k8s-operator" || (echo "REPO=... must not be tailscale/k8s-operator" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/k8s-operator" || (echo "REPO=... must not be ghcr.io/tailscale/k8s-operator" && exit 1) +.PHONY: check-image-repo +check-image-repo: + @if [ -z "$(REPO)" ]; then \ + echo "REPO=... required; e.g. REPO=ghcr.io/$$USER/tailscale" >&2; \ + exit 1; \ + fi + @for repo in tailscale/tailscale ghcr.io/tailscale/tailscale \ + tailscale/k8s-operator ghcr.io/tailscale/k8s-operator \ + tailscale/k8s-nameserver ghcr.io/tailscale/k8s-nameserver \ + tailscale/tsidp ghcr.io/tailscale/tsidp \ + tailscale/k8s-proxy ghcr.io/tailscale/k8s-proxy; do \ + if [ "$(REPO)" = "$$repo" ]; then \ + echo "REPO=... must not be $$repo" >&2; \ + exit 1; \ + fi; \ + done + +publishdevimage: check-image-repo ## Build and publish tailscale image to location specified by ${REPO} TAGS="${TAGS}" REPOS=${REPO} PLATFORM=${PLATFORM} PUSH=true TARGET=client ./build_docker.sh -publishdevoperator: ## Build and publish k8s-operator image to location specified by ${REPO} - @test -n "${REPO}" || (echo "REPO=... required; e.g. REPO=ghcr.io/${USER}/tailscale" && exit 1) - @test "${REPO}" != "tailscale/tailscale" || (echo "REPO=... must not be tailscale/tailscale" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/tailscale" || (echo "REPO=... must not be ghcr.io/tailscale/tailscale" && exit 1) - @test "${REPO}" != "tailscale/k8s-operator" || (echo "REPO=... must not be tailscale/k8s-operator" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/k8s-operator" || (echo "REPO=... must not be ghcr.io/tailscale/k8s-operator" && exit 1) +publishdevoperator: check-image-repo ## Build and publish k8s-operator image to location specified by ${REPO} TAGS="${TAGS}" REPOS=${REPO} PLATFORM=${PLATFORM} PUSH=true TARGET=k8s-operator ./build_docker.sh -publishdevnameserver: ## Build and publish k8s-nameserver image to location specified by ${REPO} - @test -n "${REPO}" || (echo "REPO=... required; e.g. REPO=ghcr.io/${USER}/tailscale" && exit 1) - @test "${REPO}" != "tailscale/tailscale" || (echo "REPO=... must not be tailscale/tailscale" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/tailscale" || (echo "REPO=... must not be ghcr.io/tailscale/tailscale" && exit 1) - @test "${REPO}" != "tailscale/k8s-nameserver" || (echo "REPO=... must not be tailscale/k8s-nameserver" && exit 1) - @test "${REPO}" != "ghcr.io/tailscale/k8s-nameserver" || (echo "REPO=... must not be ghcr.io/tailscale/k8s-nameserver" && exit 1) +publishdevnameserver: check-image-repo ## Build and publish k8s-nameserver image to location specified by ${REPO} TAGS="${TAGS}" REPOS=${REPO} PLATFORM=${PLATFORM} PUSH=true TARGET=k8s-nameserver ./build_docker.sh +publishdevtsidp: check-image-repo ## Build and publish tsidp image to location specified by ${REPO} + TAGS="${TAGS}" REPOS=${REPO} PLATFORM=${PLATFORM} PUSH=true TARGET=tsidp ./build_docker.sh + +publishdevproxy: check-image-repo ## Build and publish k8s-proxy image to location specified by ${REPO} + TAGS="${TAGS}" REPOS=${REPO} PLATFORM=${PLATFORM} PUSH=true TARGET=k8s-proxy ./build_docker.sh + .PHONY: sshintegrationtest sshintegrationtest: ## Run the SSH integration tests in various Docker containers - @GOOS=linux GOARCH=amd64 ./tool/go test -tags integrationtest -c ./ssh/tailssh -o ssh/tailssh/testcontainers/tailssh.test && \ - GOOS=linux GOARCH=amd64 ./tool/go build -o ssh/tailssh/testcontainers/tailscaled ./cmd/tailscaled && \ + @GOOS=linux GOARCH=amd64 CGO_ENABLED=0 ./tool/go test -tags integrationtest -c ./ssh/tailssh -o ssh/tailssh/testcontainers/tailssh.test && \ + GOOS=linux GOARCH=amd64 CGO_ENABLED=0 ./tool/go build -o ssh/tailssh/testcontainers/tailscaled ./cmd/tailscaled && \ echo "Testing on ubuntu:focal" && docker build --build-arg="BASE=ubuntu:focal" -t ssh-ubuntu-focal ssh/tailssh/testcontainers && \ echo "Testing on ubuntu:jammy" && docker build --build-arg="BASE=ubuntu:jammy" -t ssh-ubuntu-jammy ssh/tailssh/testcontainers && \ echo "Testing on ubuntu:noble" && docker build --build-arg="BASE=ubuntu:noble" -t ssh-ubuntu-noble ssh/tailssh/testcontainers && \ echo "Testing on alpine:latest" && docker build --build-arg="BASE=alpine:latest" -t ssh-alpine-latest ssh/tailssh/testcontainers +.PHONY: generate +generate: ## Generate code + ./tool/go generate ./... + +.PHONY: pin-github-actions +pin-github-actions: + ./tool/go tool github.com/stacklok/frizbee actions .github/workflows + help: ## Show this help - @echo "\nSpecify a command. The choices are:\n" - @grep -hE '^[0-9a-zA-Z_-]+:.*?## .*$$' ${MAKEFILE_LIST} | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[0;36m%-20s\033[m %s\n", $$1, $$2}' + @echo "" + @echo "Specify a command. The choices are:" + @echo "" + @grep -hE '^[0-9a-zA-Z_-]+:.*?## .*$$' ${MAKEFILE_LIST} | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[0;36m%-20s\033[m %s\n", $$1, $$2}' @echo "" .PHONY: help diff --git a/vendor/tailscale.com/README.md b/vendor/tailscale.com/README.md index a20132a..70b92d4 100644 --- a/vendor/tailscale.com/README.md +++ b/vendor/tailscale.com/README.md @@ -37,7 +37,7 @@ not open source. ## Building -We always require the latest Go release, currently Go 1.23. (While we build +We always require the latest Go release, currently Go 1.25. (While we build releases with our [Go fork](https://github.com/tailscale/go/), its use is not required.) @@ -71,8 +71,7 @@ We require [Developer Certificate of Origin](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin) `Signed-off-by` lines in commits. -See `git log` for our commit message style. It's basically the same as -[Go's style](https://go.dev/wiki/CommitMessage). +See [commit-messages.md](docs/commit-messages.md) (or skim `git log`) for our commit message style. ## About Us diff --git a/vendor/tailscale.com/VERSION.txt b/vendor/tailscale.com/VERSION.txt index 71fae54..df83a51 100644 --- a/vendor/tailscale.com/VERSION.txt +++ b/vendor/tailscale.com/VERSION.txt @@ -1 +1 @@ -1.82.0 +1.94.1 diff --git a/vendor/tailscale.com/appc/appconnector.go b/vendor/tailscale.com/appc/appconnector.go index 89c6c9a..d41f9e8 100644 --- a/vendor/tailscale.com/appc/appconnector.go +++ b/vendor/tailscale.com/appc/appconnector.go @@ -12,19 +12,20 @@ package appc import ( "context" "fmt" + "maps" "net/netip" "slices" "strings" - "sync" "time" - "golang.org/x/net/dns/dnsmessage" + "tailscale.com/syncs" + "tailscale.com/types/appctype" "tailscale.com/types/logger" "tailscale.com/types/views" "tailscale.com/util/clientmetric" "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" "tailscale.com/util/execqueue" - "tailscale.com/util/mak" "tailscale.com/util/slicesx" ) @@ -115,19 +116,6 @@ func metricStoreRoutes(rate, nRoutes int64) { recordMetric(nRoutes, metricStoreRoutesNBuckets, metricStoreRoutesN) } -// RouteInfo is a data structure used to persist the in memory state of an AppConnector -// so that we can know, even after a restart, which routes came from ACLs and which were -// learned from domains. -type RouteInfo struct { - // Control is the routes from the 'routes' section of an app connector acl. - Control []netip.Prefix `json:",omitempty"` - // Domains are the routes discovered by observing DNS lookups for configured domains. - Domains map[string][]netip.Addr `json:",omitempty"` - // Wildcards are the configured DNS lookup domains to observe. When a DNS query matches Wildcards, - // its result is added to Domains. - Wildcards []string `json:",omitempty"` -} - // AppConnector is an implementation of an AppConnector that performs // its function as a subsystem inside of a tailscale node. At the control plane // side App Connector routing is configured in terms of domains rather than IP @@ -138,14 +126,20 @@ type RouteInfo struct { // routes not yet served by the AppConnector the local node configuration is // updated to advertise the new route. type AppConnector struct { + // These fields are immutable after initialization. logf logger.Logf + eventBus *eventbus.Bus routeAdvertiser RouteAdvertiser + pubClient *eventbus.Client + updatePub *eventbus.Publisher[appctype.RouteUpdate] + storePub *eventbus.Publisher[appctype.RouteInfo] - // storeRoutesFunc will be called to persist routes if it is not nil. - storeRoutesFunc func(*RouteInfo) error + // hasStoredRoutes records whether the connector was initialized with + // persisted route information. + hasStoredRoutes bool // mu guards the fields that follow - mu sync.Mutex + mu syncs.Mutex // domains is a map of lower case domain names with no trailing dot, to an // ordered list of resolved IP addresses. @@ -164,53 +158,83 @@ type AppConnector struct { writeRateDay *rateLogger } +// Config carries the settings for an [AppConnector]. +type Config struct { + // Logf is the logger to which debug logs from the connector will be sent. + // It must be non-nil. + Logf logger.Logf + + // EventBus receives events when the collection of routes maintained by the + // connector is updated. It must be non-nil. + EventBus *eventbus.Bus + + // RouteAdvertiser allows the connector to update the set of advertised routes. + RouteAdvertiser RouteAdvertiser + + // RouteInfo, if non-nil, use used as the initial set of routes for the + // connector. If nil, the connector starts empty. + RouteInfo *appctype.RouteInfo + + // HasStoredRoutes indicates that the connector should assume stored routes. + HasStoredRoutes bool +} + // NewAppConnector creates a new AppConnector. -func NewAppConnector(logf logger.Logf, routeAdvertiser RouteAdvertiser, routeInfo *RouteInfo, storeRoutesFunc func(*RouteInfo) error) *AppConnector { +func NewAppConnector(c Config) *AppConnector { + switch { + case c.Logf == nil: + panic("missing logger") + case c.EventBus == nil: + panic("missing event bus") + } + ec := c.EventBus.Client("appc.AppConnector") + ac := &AppConnector{ - logf: logger.WithPrefix(logf, "appc: "), - routeAdvertiser: routeAdvertiser, - storeRoutesFunc: storeRoutesFunc, + logf: logger.WithPrefix(c.Logf, "appc: "), + eventBus: c.EventBus, + pubClient: ec, + updatePub: eventbus.Publish[appctype.RouteUpdate](ec), + storePub: eventbus.Publish[appctype.RouteInfo](ec), + routeAdvertiser: c.RouteAdvertiser, + hasStoredRoutes: c.HasStoredRoutes, } - if routeInfo != nil { - ac.domains = routeInfo.Domains - ac.wildcards = routeInfo.Wildcards - ac.controlRoutes = routeInfo.Control + if c.RouteInfo != nil { + ac.domains = c.RouteInfo.Domains + ac.wildcards = c.RouteInfo.Wildcards + ac.controlRoutes = c.RouteInfo.Control } - ac.writeRateMinute = newRateLogger(time.Now, time.Minute, func(c int64, s time.Time, l int64) { - ac.logf("routeInfo write rate: %d in minute starting at %v (%d routes)", c, s, l) - metricStoreRoutes(c, l) + ac.writeRateMinute = newRateLogger(time.Now, time.Minute, func(c int64, s time.Time, ln int64) { + ac.logf("routeInfo write rate: %d in minute starting at %v (%d routes)", c, s, ln) + metricStoreRoutes(c, ln) }) - ac.writeRateDay = newRateLogger(time.Now, 24*time.Hour, func(c int64, s time.Time, l int64) { - ac.logf("routeInfo write rate: %d in 24 hours starting at %v (%d routes)", c, s, l) + ac.writeRateDay = newRateLogger(time.Now, 24*time.Hour, func(c int64, s time.Time, ln int64) { + ac.logf("routeInfo write rate: %d in 24 hours starting at %v (%d routes)", c, s, ln) }) return ac } // ShouldStoreRoutes returns true if the appconnector was created with the controlknob on // and is storing its discovered routes persistently. -func (e *AppConnector) ShouldStoreRoutes() bool { - return e.storeRoutesFunc != nil -} +func (e *AppConnector) ShouldStoreRoutes() bool { return e.hasStoredRoutes } // storeRoutesLocked takes the current state of the AppConnector and persists it -func (e *AppConnector) storeRoutesLocked() error { - if !e.ShouldStoreRoutes() { - return nil - } +func (e *AppConnector) storeRoutesLocked() { + if e.storePub.ShouldPublish() { + // log write rate and write size + numRoutes := int64(len(e.controlRoutes)) + for _, rs := range e.domains { + numRoutes += int64(len(rs)) + } + e.writeRateMinute.update(numRoutes) + e.writeRateDay.update(numRoutes) - // log write rate and write size - numRoutes := int64(len(e.controlRoutes)) - for _, rs := range e.domains { - numRoutes += int64(len(rs)) + e.storePub.Publish(appctype.RouteInfo{ + // Clone here, as the subscriber will handle these outside our lock. + Control: slices.Clone(e.controlRoutes), + Domains: maps.Clone(e.domains), + Wildcards: slices.Clone(e.wildcards), + }) } - e.writeRateMinute.update(numRoutes) - e.writeRateDay.update(numRoutes) - - return e.storeRoutesFunc(&RouteInfo{ - Control: e.controlRoutes, - Domains: e.domains, - Wildcards: e.wildcards, - }) } // ClearRoutes removes all route state from the AppConnector. @@ -220,7 +244,8 @@ func (e *AppConnector) ClearRoutes() error { e.controlRoutes = nil e.domains = nil e.wildcards = nil - return e.storeRoutesLocked() + e.storeRoutesLocked() + return nil } // UpdateDomainsAndRoutes starts an asynchronous update of the configuration @@ -249,6 +274,18 @@ func (e *AppConnector) Wait(ctx context.Context) { e.queue.Wait(ctx) } +// Close closes the connector and cleans up resources associated with it. +// It is safe (and a noop) to call Close on nil. +func (e *AppConnector) Close() { + if e == nil { + return + } + e.mu.Lock() + defer e.mu.Unlock() + e.queue.Shutdown() // TODO(creachadair): Should we wait for it too? + e.pubClient.Close() +} + func (e *AppConnector) updateDomains(domains []string) { e.mu.Lock() defer e.mu.Unlock() @@ -280,20 +317,26 @@ func (e *AppConnector) updateDomains(domains []string) { } } - // Everything left in oldDomains is a domain we're no longer tracking - // and if we are storing route info we can unadvertise the routes - if e.ShouldStoreRoutes() { + // Everything left in oldDomains is a domain we're no longer tracking and we + // can unadvertise the routes. + if e.hasStoredRoutes { toRemove := []netip.Prefix{} for _, addrs := range oldDomains { for _, a := range addrs { toRemove = append(toRemove, netip.PrefixFrom(a, a.BitLen())) } } - e.queue.Add(func() { - if err := e.routeAdvertiser.UnadvertiseRoute(toRemove...); err != nil { - e.logf("failed to unadvertise routes on domain removal: %v: %v: %v", slicesx.MapKeys(oldDomains), toRemove, err) + + if len(toRemove) != 0 { + if ra := e.routeAdvertiser; ra != nil { + e.queue.Add(func() { + if err := e.routeAdvertiser.UnadvertiseRoute(toRemove...); err != nil { + e.logf("failed to unadvertise routes on domain removal: %v: %v: %v", slicesx.MapKeys(oldDomains), toRemove, err) + } + }) } - }) + e.updatePub.Publish(appctype.RouteUpdate{Unadvertise: toRemove}) + } } e.logf("handling domains: %v and wildcards: %v", slicesx.MapKeys(e.domains), e.wildcards) @@ -314,11 +357,10 @@ func (e *AppConnector) updateRoutes(routes []netip.Prefix) { var toRemove []netip.Prefix - // If we're storing routes and know e.controlRoutes is a good - // representation of what should be in AdvertisedRoutes we can stop - // advertising routes that used to be in e.controlRoutes but are not - // in routes. - if e.ShouldStoreRoutes() { + // If we know e.controlRoutes is a good representation of what should be in + // AdvertisedRoutes we can stop advertising routes that used to be in + // e.controlRoutes but are not in routes. + if e.hasStoredRoutes { toRemove = routesWithout(e.controlRoutes, routes) } @@ -335,19 +377,23 @@ nextRoute: } } - e.queue.Add(func() { - if err := e.routeAdvertiser.AdvertiseRoute(routes...); err != nil { - e.logf("failed to advertise routes: %v: %v", routes, err) - } - if err := e.routeAdvertiser.UnadvertiseRoute(toRemove...); err != nil { - e.logf("failed to unadvertise routes: %v: %v", toRemove, err) - } + if e.routeAdvertiser != nil { + e.queue.Add(func() { + if err := e.routeAdvertiser.AdvertiseRoute(routes...); err != nil { + e.logf("failed to advertise routes: %v: %v", routes, err) + } + if err := e.routeAdvertiser.UnadvertiseRoute(toRemove...); err != nil { + e.logf("failed to unadvertise routes: %v: %v", toRemove, err) + } + }) + } + e.updatePub.Publish(appctype.RouteUpdate{ + Advertise: routes, + Unadvertise: toRemove, }) e.controlRoutes = routes - if err := e.storeRoutesLocked(); err != nil { - e.logf("failed to store route info: %v", err) - } + e.storeRoutesLocked() } // Domains returns the currently configured domain list. @@ -372,124 +418,6 @@ func (e *AppConnector) DomainRoutes() map[string][]netip.Addr { return drCopy } -// ObserveDNSResponse is a callback invoked by the DNS resolver when a DNS -// response is being returned over the PeerAPI. The response is parsed and -// matched against the configured domains, if matched the routeAdvertiser is -// advised to advertise the discovered route. -func (e *AppConnector) ObserveDNSResponse(res []byte) error { - var p dnsmessage.Parser - if _, err := p.Start(res); err != nil { - return err - } - if err := p.SkipAllQuestions(); err != nil { - return err - } - - // cnameChain tracks a chain of CNAMEs for a given query in order to reverse - // a CNAME chain back to the original query for flattening. The keys are - // CNAME record targets, and the value is the name the record answers, so - // for www.example.com CNAME example.com, the map would contain - // ["example.com"] = "www.example.com". - var cnameChain map[string]string - - // addressRecords is a list of address records found in the response. - var addressRecords map[string][]netip.Addr - - for { - h, err := p.AnswerHeader() - if err == dnsmessage.ErrSectionDone { - break - } - if err != nil { - return err - } - - if h.Class != dnsmessage.ClassINET { - if err := p.SkipAnswer(); err != nil { - return err - } - continue - } - - switch h.Type { - case dnsmessage.TypeCNAME, dnsmessage.TypeA, dnsmessage.TypeAAAA: - default: - if err := p.SkipAnswer(); err != nil { - return err - } - continue - - } - - domain := strings.TrimSuffix(strings.ToLower(h.Name.String()), ".") - if len(domain) == 0 { - continue - } - - if h.Type == dnsmessage.TypeCNAME { - res, err := p.CNAMEResource() - if err != nil { - return err - } - cname := strings.TrimSuffix(strings.ToLower(res.CNAME.String()), ".") - if len(cname) == 0 { - continue - } - mak.Set(&cnameChain, cname, domain) - continue - } - - switch h.Type { - case dnsmessage.TypeA: - r, err := p.AResource() - if err != nil { - return err - } - addr := netip.AddrFrom4(r.A) - mak.Set(&addressRecords, domain, append(addressRecords[domain], addr)) - case dnsmessage.TypeAAAA: - r, err := p.AAAAResource() - if err != nil { - return err - } - addr := netip.AddrFrom16(r.AAAA) - mak.Set(&addressRecords, domain, append(addressRecords[domain], addr)) - default: - if err := p.SkipAnswer(); err != nil { - return err - } - continue - } - } - - e.mu.Lock() - defer e.mu.Unlock() - - for domain, addrs := range addressRecords { - domain, isRouted := e.findRoutedDomainLocked(domain, cnameChain) - - // domain and none of the CNAMEs in the chain are routed - if !isRouted { - continue - } - - // advertise each address we have learned for the routed domain, that - // was not already known. - var toAdvertise []netip.Prefix - for _, addr := range addrs { - if !e.isAddrKnownLocked(domain, addr) { - toAdvertise = append(toAdvertise, netip.PrefixFrom(addr, addr.BitLen())) - } - } - - if len(toAdvertise) > 0 { - e.logf("[v2] observed new routes for %s: %s", domain, toAdvertise) - e.scheduleAdvertisement(domain, toAdvertise...) - } - } - return nil -} - // starting from the given domain that resolved to an address, find it, or any // of the domains in the CNAME chain toward resolving it, that are routed // domains, returning the routed domain name and a bool indicating whether a @@ -544,10 +472,13 @@ func (e *AppConnector) isAddrKnownLocked(domain string, addr netip.Addr) bool { // associated with the given domain. func (e *AppConnector) scheduleAdvertisement(domain string, routes ...netip.Prefix) { e.queue.Add(func() { - if err := e.routeAdvertiser.AdvertiseRoute(routes...); err != nil { - e.logf("failed to advertise routes for %s: %v: %v", domain, routes, err) - return + if e.routeAdvertiser != nil { + if err := e.routeAdvertiser.AdvertiseRoute(routes...); err != nil { + e.logf("failed to advertise routes for %s: %v: %v", domain, routes, err) + return + } } + e.updatePub.Publish(appctype.RouteUpdate{Advertise: routes}) e.mu.Lock() defer e.mu.Unlock() @@ -561,9 +492,7 @@ func (e *AppConnector) scheduleAdvertisement(domain string, routes ...netip.Pref e.logf("[v2] advertised route for %v: %v", domain, addr) } } - if err := e.storeRoutesLocked(); err != nil { - e.logf("failed to store route info: %v", err) - } + e.storeRoutesLocked() }) } @@ -581,8 +510,8 @@ func (e *AppConnector) addDomainAddrLocked(domain string, addr netip.Addr) { slices.SortFunc(e.domains[domain], compareAddr) } -func compareAddr(l, r netip.Addr) int { - return l.Compare(r) +func compareAddr(a, b netip.Addr) int { + return a.Compare(b) } // routesWithout returns a without b where a and b diff --git a/vendor/tailscale.com/appc/conn25.go b/vendor/tailscale.com/appc/conn25.go new file mode 100644 index 0000000..b4890c2 --- /dev/null +++ b/vendor/tailscale.com/appc/conn25.go @@ -0,0 +1,110 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package appc + +import ( + "net/netip" + "sync" + + "tailscale.com/tailcfg" +) + +// Conn25 holds the developing state for the as yet nascent next generation app connector. +// There is currently (2025-12-08) no actual app connecting functionality. +type Conn25 struct { + mu sync.Mutex + transitIPs map[tailcfg.NodeID]map[netip.Addr]netip.Addr +} + +const dupeTransitIPMessage = "Duplicate transit address in ConnectorTransitIPRequest" + +// HandleConnectorTransitIPRequest creates a ConnectorTransitIPResponse in response to a ConnectorTransitIPRequest. +// It updates the connectors mapping of TransitIP->DestinationIP per peer (tailcfg.NodeID). +// If a peer has stored this mapping in the connector Conn25 will route traffic to TransitIPs to DestinationIPs for that peer. +func (c *Conn25) HandleConnectorTransitIPRequest(nid tailcfg.NodeID, ctipr ConnectorTransitIPRequest) ConnectorTransitIPResponse { + resp := ConnectorTransitIPResponse{} + seen := map[netip.Addr]bool{} + for _, each := range ctipr.TransitIPs { + if seen[each.TransitIP] { + resp.TransitIPs = append(resp.TransitIPs, TransitIPResponse{ + Code: OtherFailure, + Message: dupeTransitIPMessage, + }) + continue + } + tipresp := c.handleTransitIPRequest(nid, each) + seen[each.TransitIP] = true + resp.TransitIPs = append(resp.TransitIPs, tipresp) + } + return resp +} + +func (c *Conn25) handleTransitIPRequest(nid tailcfg.NodeID, tipr TransitIPRequest) TransitIPResponse { + c.mu.Lock() + defer c.mu.Unlock() + if c.transitIPs == nil { + c.transitIPs = make(map[tailcfg.NodeID]map[netip.Addr]netip.Addr) + } + peerMap, ok := c.transitIPs[nid] + if !ok { + peerMap = make(map[netip.Addr]netip.Addr) + c.transitIPs[nid] = peerMap + } + peerMap[tipr.TransitIP] = tipr.DestinationIP + return TransitIPResponse{} +} + +func (c *Conn25) transitIPTarget(nid tailcfg.NodeID, tip netip.Addr) netip.Addr { + c.mu.Lock() + defer c.mu.Unlock() + return c.transitIPs[nid][tip] +} + +// TransitIPRequest details a single TransitIP allocation request from a client to a +// connector. +type TransitIPRequest struct { + // TransitIP is the intermediate destination IP that will be received at this + // connector and will be replaced by DestinationIP when performing DNAT. + TransitIP netip.Addr `json:"transitIP,omitzero"` + + // DestinationIP is the final destination IP that connections to the TransitIP + // should be mapped to when performing DNAT. + DestinationIP netip.Addr `json:"destinationIP,omitzero"` +} + +// ConnectorTransitIPRequest is the request body for a PeerAPI request to +// /connector/transit-ip and can include zero or more TransitIP allocation requests. +type ConnectorTransitIPRequest struct { + // TransitIPs is the list of requested mappings. + TransitIPs []TransitIPRequest `json:"transitIPs,omitempty"` +} + +// TransitIPResponseCode appears in TransitIPResponse and signifies success or failure status. +type TransitIPResponseCode int + +const ( + // OK indicates that the mapping was created as requested. + OK TransitIPResponseCode = 0 + + // OtherFailure indicates that the mapping failed for a reason that does not have + // another relevant [TransitIPResponsecode]. + OtherFailure TransitIPResponseCode = 1 +) + +// TransitIPResponse is the response to a TransitIPRequest +type TransitIPResponse struct { + // Code is an error code indicating success or failure of the [TransitIPRequest]. + Code TransitIPResponseCode `json:"code,omitzero"` + // Message is an error message explaining what happened, suitable for logging but + // not necessarily suitable for displaying in a UI to non-technical users. It + // should be empty when [Code] is [OK]. + Message string `json:"message,omitzero"` +} + +// ConnectorTransitIPResponse is the response to a ConnectorTransitIPRequest +type ConnectorTransitIPResponse struct { + // TransitIPs is the list of outcomes for each requested mapping. Elements + // correspond to the order of [ConnectorTransitIPRequest.TransitIPs]. + TransitIPs []TransitIPResponse `json:"transitIPs,omitempty"` +} diff --git a/vendor/tailscale.com/appc/ippool.go b/vendor/tailscale.com/appc/ippool.go new file mode 100644 index 0000000..a2e86a7 --- /dev/null +++ b/vendor/tailscale.com/appc/ippool.go @@ -0,0 +1,61 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package appc + +import ( + "errors" + "net/netip" + + "go4.org/netipx" +) + +// errPoolExhausted is returned when there are no more addresses to iterate over. +var errPoolExhausted = errors.New("ip pool exhausted") + +// ippool allows for iteration over all the addresses within a netipx.IPSet. +// netipx.IPSet has a Ranges call that returns the "minimum and sorted set of IP ranges that covers [the set]". +// netipx.IPRange is "an inclusive range of IP addresses from the same address family.". So we can iterate over +// all the addresses in the set by keeping a track of the last address we returned, calling Next on the last address +// to get the new one, and if we run off the edge of the current range, starting on the next one. +type ippool struct { + // ranges defines the addresses in the pool + ranges []netipx.IPRange + // last is internal tracking of which the last address provided was. + last netip.Addr + // rangeIdx is internal tracking of which netipx.IPRange from the IPSet we are currently on. + rangeIdx int +} + +func newIPPool(ipset *netipx.IPSet) *ippool { + if ipset == nil { + return &ippool{} + } + return &ippool{ranges: ipset.Ranges()} +} + +// next returns the next address from the set, or errPoolExhausted if we have +// iterated over the whole set. +func (ipp *ippool) next() (netip.Addr, error) { + if ipp.rangeIdx >= len(ipp.ranges) { + // ipset is empty or we have iterated off the end + return netip.Addr{}, errPoolExhausted + } + if !ipp.last.IsValid() { + // not initialized yet + ipp.last = ipp.ranges[0].From() + return ipp.last, nil + } + currRange := ipp.ranges[ipp.rangeIdx] + if ipp.last == currRange.To() { + // then we need to move to the next range + ipp.rangeIdx++ + if ipp.rangeIdx >= len(ipp.ranges) { + return netip.Addr{}, errPoolExhausted + } + ipp.last = ipp.ranges[ipp.rangeIdx].From() + return ipp.last, nil + } + ipp.last = ipp.last.Next() + return ipp.last, nil +} diff --git a/vendor/tailscale.com/appc/observe.go b/vendor/tailscale.com/appc/observe.go new file mode 100644 index 0000000..06dc04f --- /dev/null +++ b/vendor/tailscale.com/appc/observe.go @@ -0,0 +1,132 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_appconnectors + +package appc + +import ( + "net/netip" + "strings" + + "golang.org/x/net/dns/dnsmessage" + "tailscale.com/util/mak" +) + +// ObserveDNSResponse is a callback invoked by the DNS resolver when a DNS +// response is being returned over the PeerAPI. The response is parsed and +// matched against the configured domains, if matched the routeAdvertiser is +// advised to advertise the discovered route. +func (e *AppConnector) ObserveDNSResponse(res []byte) error { + var p dnsmessage.Parser + if _, err := p.Start(res); err != nil { + return err + } + if err := p.SkipAllQuestions(); err != nil { + return err + } + + // cnameChain tracks a chain of CNAMEs for a given query in order to reverse + // a CNAME chain back to the original query for flattening. The keys are + // CNAME record targets, and the value is the name the record answers, so + // for www.example.com CNAME example.com, the map would contain + // ["example.com"] = "www.example.com". + var cnameChain map[string]string + + // addressRecords is a list of address records found in the response. + var addressRecords map[string][]netip.Addr + + for { + h, err := p.AnswerHeader() + if err == dnsmessage.ErrSectionDone { + break + } + if err != nil { + return err + } + + if h.Class != dnsmessage.ClassINET { + if err := p.SkipAnswer(); err != nil { + return err + } + continue + } + + switch h.Type { + case dnsmessage.TypeCNAME, dnsmessage.TypeA, dnsmessage.TypeAAAA: + default: + if err := p.SkipAnswer(); err != nil { + return err + } + continue + + } + + domain := strings.TrimSuffix(strings.ToLower(h.Name.String()), ".") + if len(domain) == 0 { + continue + } + + if h.Type == dnsmessage.TypeCNAME { + res, err := p.CNAMEResource() + if err != nil { + return err + } + cname := strings.TrimSuffix(strings.ToLower(res.CNAME.String()), ".") + if len(cname) == 0 { + continue + } + mak.Set(&cnameChain, cname, domain) + continue + } + + switch h.Type { + case dnsmessage.TypeA: + r, err := p.AResource() + if err != nil { + return err + } + addr := netip.AddrFrom4(r.A) + mak.Set(&addressRecords, domain, append(addressRecords[domain], addr)) + case dnsmessage.TypeAAAA: + r, err := p.AAAAResource() + if err != nil { + return err + } + addr := netip.AddrFrom16(r.AAAA) + mak.Set(&addressRecords, domain, append(addressRecords[domain], addr)) + default: + if err := p.SkipAnswer(); err != nil { + return err + } + continue + } + } + + e.mu.Lock() + defer e.mu.Unlock() + + for domain, addrs := range addressRecords { + domain, isRouted := e.findRoutedDomainLocked(domain, cnameChain) + + // domain and none of the CNAMEs in the chain are routed + if !isRouted { + continue + } + + // advertise each address we have learned for the routed domain, that + // was not already known. + var toAdvertise []netip.Prefix + for _, addr := range addrs { + if !e.isAddrKnownLocked(domain, addr) { + toAdvertise = append(toAdvertise, netip.PrefixFrom(addr, addr.BitLen())) + } + } + + if len(toAdvertise) > 0 { + e.logf("[v2] observed new routes for %s: %s", domain, toAdvertise) + e.scheduleAdvertisement(domain, toAdvertise...) + } + } + return nil +} diff --git a/vendor/tailscale.com/appc/observe_disabled.go b/vendor/tailscale.com/appc/observe_disabled.go new file mode 100644 index 0000000..45aa285 --- /dev/null +++ b/vendor/tailscale.com/appc/observe_disabled.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_appconnectors + +package appc + +func (e *AppConnector) ObserveDNSResponse(res []byte) error { return nil } diff --git a/vendor/tailscale.com/atomicfile/atomicfile.go b/vendor/tailscale.com/atomicfile/atomicfile.go index b3c8c93..9cae9bb 100644 --- a/vendor/tailscale.com/atomicfile/atomicfile.go +++ b/vendor/tailscale.com/atomicfile/atomicfile.go @@ -48,5 +48,9 @@ func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { if err := f.Close(); err != nil { return err } - return rename(tmpName, filename) + return Rename(tmpName, filename) } + +// Rename srcFile to dstFile, similar to [os.Rename] but preserving file +// attributes and ACLs on Windows. +func Rename(srcFile, dstFile string) error { return rename(srcFile, dstFile) } diff --git a/vendor/tailscale.com/atomicfile/zsyscall_windows.go b/vendor/tailscale.com/atomicfile/zsyscall_windows.go index f2f0b6d..bd1bf81 100644 --- a/vendor/tailscale.com/atomicfile/zsyscall_windows.go +++ b/vendor/tailscale.com/atomicfile/zsyscall_windows.go @@ -44,7 +44,7 @@ var ( ) func replaceFileW(replaced *uint16, replacement *uint16, backup *uint16, flags uint32, exclude unsafe.Pointer, reserved unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall6(procReplaceFileW.Addr(), 6, uintptr(unsafe.Pointer(replaced)), uintptr(unsafe.Pointer(replacement)), uintptr(unsafe.Pointer(backup)), uintptr(flags), uintptr(exclude), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procReplaceFileW.Addr(), uintptr(unsafe.Pointer(replaced)), uintptr(unsafe.Pointer(replacement)), uintptr(unsafe.Pointer(backup)), uintptr(flags), uintptr(exclude), uintptr(reserved)) if int32(r1) == 0 { err = errnoErr(e1) } diff --git a/vendor/tailscale.com/build_dist.sh b/vendor/tailscale.com/build_dist.sh index ccd4ac8..c056447 100644 --- a/vendor/tailscale.com/build_dist.sh +++ b/vendor/tailscale.com/build_dist.sh @@ -18,7 +18,7 @@ fi eval `CGO_ENABLED=0 GOOS=$($go env GOHOSTOS) GOARCH=$($go env GOHOSTARCH) $go run ./cmd/mkversion` -if [ "$1" = "shellvars" ]; then +if [ "$#" -ge 1 ] && [ "$1" = "shellvars" ]; then cat <//tailscale TAGS=v0.0.1 make publishdevimage set -eu @@ -16,7 +26,7 @@ eval "$(./build_dist.sh shellvars)" DEFAULT_TARGET="client" DEFAULT_TAGS="v${VERSION_SHORT},v${VERSION_MINOR}" -DEFAULT_BASE="tailscale/alpine-base:3.19" +DEFAULT_BASE="tailscale/alpine-base:3.22" # Set a few pre-defined OCI annotations. The source annotation is used by tools such as Renovate that scan the linked # Github repo to find release notes for any new image tags. Note that for official Tailscale images the default # annotations defined here will be overriden by release scripts that call this script. @@ -28,6 +38,7 @@ TARGET="${TARGET:-${DEFAULT_TARGET}}" TAGS="${TAGS:-${DEFAULT_TAGS}}" BASE="${BASE:-${DEFAULT_BASE}}" PLATFORM="${PLATFORM:-}" # default to all platforms +FILES="${FILES:-}" # default to no extra files # OCI annotations that will be added to the image. # https://github.com/opencontainers/image-spec/blob/main/annotations.md ANNOTATIONS="${ANNOTATIONS:-${DEFAULT_ANNOTATIONS}}" @@ -52,6 +63,7 @@ case "$TARGET" in --push="${PUSH}" \ --target="${PLATFORM}" \ --annotations="${ANNOTATIONS}" \ + --files="${FILES}" \ /usr/local/bin/containerboot ;; k8s-operator) @@ -70,6 +82,7 @@ case "$TARGET" in --push="${PUSH}" \ --target="${PLATFORM}" \ --annotations="${ANNOTATIONS}" \ + --files="${FILES}" \ /usr/local/bin/operator ;; k8s-nameserver) @@ -88,8 +101,47 @@ case "$TARGET" in --push="${PUSH}" \ --target="${PLATFORM}" \ --annotations="${ANNOTATIONS}" \ + --files="${FILES}" \ /usr/local/bin/k8s-nameserver ;; + tsidp) + DEFAULT_REPOS="tailscale/tsidp" + REPOS="${REPOS:-${DEFAULT_REPOS}}" + go run github.com/tailscale/mkctr \ + --gopaths="tailscale.com/cmd/tsidp:/usr/local/bin/tsidp" \ + --ldflags=" \ + -X tailscale.com/version.longStamp=${VERSION_LONG} \ + -X tailscale.com/version.shortStamp=${VERSION_SHORT} \ + -X tailscale.com/version.gitCommitStamp=${VERSION_GIT_HASH}" \ + --base="${BASE}" \ + --tags="${TAGS}" \ + --gotags="ts_package_container" \ + --repos="${REPOS}" \ + --push="${PUSH}" \ + --target="${PLATFORM}" \ + --annotations="${ANNOTATIONS}" \ + --files="${FILES}" \ + /usr/local/bin/tsidp + ;; + k8s-proxy) + DEFAULT_REPOS="tailscale/k8s-proxy" + REPOS="${REPOS:-${DEFAULT_REPOS}}" + go run github.com/tailscale/mkctr \ + --gopaths="tailscale.com/cmd/k8s-proxy:/usr/local/bin/k8s-proxy" \ + --ldflags=" \ + -X tailscale.com/version.longStamp=${VERSION_LONG} \ + -X tailscale.com/version.shortStamp=${VERSION_SHORT} \ + -X tailscale.com/version.gitCommitStamp=${VERSION_GIT_HASH}" \ + --base="${BASE}" \ + --tags="${TAGS}" \ + --gotags="ts_kube,ts_package_container" \ + --repos="${REPOS}" \ + --push="${PUSH}" \ + --target="${PLATFORM}" \ + --annotations="${ANNOTATIONS}" \ + --files="${FILES}" \ + /usr/local/bin/k8s-proxy + ;; *) echo "unknown target: $TARGET" exit 1 diff --git a/vendor/tailscale.com/client/local/cert.go b/vendor/tailscale.com/client/local/cert.go new file mode 100644 index 0000000..bfaac73 --- /dev/null +++ b/vendor/tailscale.com/client/local/cert.go @@ -0,0 +1,151 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !js && !ts_omit_acme + +package local + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net/url" + "strings" + "time" + + "go4.org/mem" +) + +// SetDNS adds a DNS TXT record for the given domain name, containing +// the provided TXT value. The intended use case is answering +// LetsEncrypt/ACME dns-01 challenges. +// +// The control plane will only permit SetDNS requests with very +// specific names and values. The name should be +// "_acme-challenge." + your node's MagicDNS name. It's expected that +// clients cache the certs from LetsEncrypt (or whichever CA is +// providing them) and only request new ones as needed; the control plane +// rate limits SetDNS requests. +// +// This is a low-level interface; it's expected that most Tailscale +// users use a higher level interface to getting/using TLS +// certificates. +func (lc *Client) SetDNS(ctx context.Context, name, value string) error { + v := url.Values{} + v.Set("name", name) + v.Set("value", value) + _, err := lc.send(ctx, "POST", "/localapi/v0/set-dns?"+v.Encode(), 200, nil) + return err +} + +// CertPair returns a cert and private key for the provided DNS domain. +// +// It returns a cached certificate from disk if it's still valid. +// +// Deprecated: use [Client.CertPair]. +func CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { + return defaultClient.CertPair(ctx, domain) +} + +// CertPair returns a cert and private key for the provided DNS domain. +// +// It returns a cached certificate from disk if it's still valid. +// +// API maturity: this is considered a stable API. +func (lc *Client) CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { + return lc.CertPairWithValidity(ctx, domain, 0) +} + +// CertPairWithValidity returns a cert and private key for the provided DNS +// domain. +// +// It returns a cached certificate from disk if it's still valid. +// When minValidity is non-zero, the returned certificate will be valid for at +// least the given duration, if permitted by the CA. If the certificate is +// valid, but for less than minValidity, it will be synchronously renewed. +// +// API maturity: this is considered a stable API. +func (lc *Client) CertPairWithValidity(ctx context.Context, domain string, minValidity time.Duration) (certPEM, keyPEM []byte, err error) { + res, err := lc.send(ctx, "GET", fmt.Sprintf("/localapi/v0/cert/%s?type=pair&min_validity=%s", domain, minValidity), 200, nil) + if err != nil { + return nil, nil, err + } + // with ?type=pair, the response PEM is first the one private + // key PEM block, then the cert PEM blocks. + i := mem.Index(mem.B(res), mem.S("--\n--")) + if i == -1 { + return nil, nil, fmt.Errorf("unexpected output: no delimiter") + } + i += len("--\n") + keyPEM, certPEM = res[:i], res[i:] + if mem.Contains(mem.B(certPEM), mem.S(" PRIVATE KEY-----")) { + return nil, nil, fmt.Errorf("unexpected output: key in cert") + } + return certPEM, keyPEM, nil +} + +// GetCertificate fetches a TLS certificate for the TLS ClientHello in hi. +// +// It returns a cached certificate from disk if it's still valid. +// +// It's the right signature to use as the value of +// [tls.Config.GetCertificate]. +// +// Deprecated: use [Client.GetCertificate]. +func GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { + return defaultClient.GetCertificate(hi) +} + +// GetCertificate fetches a TLS certificate for the TLS ClientHello in hi. +// +// It returns a cached certificate from disk if it's still valid. +// +// It's the right signature to use as the value of +// [tls.Config.GetCertificate]. +// +// API maturity: this is considered a stable API. +func (lc *Client) GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { + if hi == nil || hi.ServerName == "" { + return nil, errors.New("no SNI ServerName") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + name := hi.ServerName + if !strings.Contains(name, ".") { + if v, ok := lc.ExpandSNIName(ctx, name); ok { + name = v + } + } + certPEM, keyPEM, err := lc.CertPair(ctx, name) + if err != nil { + return nil, err + } + cert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + return nil, err + } + return &cert, nil +} + +// ExpandSNIName expands bare label name into the most likely actual TLS cert name. +// +// Deprecated: use [Client.ExpandSNIName]. +func ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { + return defaultClient.ExpandSNIName(ctx, name) +} + +// ExpandSNIName expands bare label name into the most likely actual TLS cert name. +func (lc *Client) ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { + st, err := lc.StatusWithoutPeers(ctx) + if err != nil { + return "", false + } + for _, d := range st.CertDomains { + if len(d) > len(name)+1 && strings.HasPrefix(d, name) && d[len(name)] == '.' { + return d, true + } + } + return "", false +} diff --git a/vendor/tailscale.com/client/local/debugportmapper.go b/vendor/tailscale.com/client/local/debugportmapper.go new file mode 100644 index 0000000..04ed1c1 --- /dev/null +++ b/vendor/tailscale.com/client/local/debugportmapper.go @@ -0,0 +1,84 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_debugportmapper + +package local + +import ( + "cmp" + "context" + "fmt" + "io" + "net/http" + "net/netip" + "net/url" + "strconv" + "time" + + "tailscale.com/client/tailscale/apitype" +) + +// DebugPortmapOpts contains options for the [Client.DebugPortmap] command. +type DebugPortmapOpts struct { + // Duration is how long the mapping should be created for. It defaults + // to 5 seconds if not set. + Duration time.Duration + + // Type is the kind of portmap to debug. The empty string instructs the + // portmap client to perform all known types. Other valid options are + // "pmp", "pcp", and "upnp". + Type string + + // GatewayAddr specifies the gateway address used during portmapping. + // If set, SelfAddr must also be set. If unset, it will be + // autodetected. + GatewayAddr netip.Addr + + // SelfAddr specifies the gateway address used during portmapping. If + // set, GatewayAddr must also be set. If unset, it will be + // autodetected. + SelfAddr netip.Addr + + // LogHTTP instructs the debug-portmap endpoint to print all HTTP + // requests and responses made to the logs. + LogHTTP bool +} + +// DebugPortmap invokes the debug-portmap endpoint, and returns an +// io.ReadCloser that can be used to read the logs that are printed during this +// process. +// +// opts can be nil; if so, default values will be used. +func (lc *Client) DebugPortmap(ctx context.Context, opts *DebugPortmapOpts) (io.ReadCloser, error) { + vals := make(url.Values) + if opts == nil { + opts = &DebugPortmapOpts{} + } + + vals.Set("duration", cmp.Or(opts.Duration, 5*time.Second).String()) + vals.Set("type", opts.Type) + vals.Set("log_http", strconv.FormatBool(opts.LogHTTP)) + + if opts.GatewayAddr.IsValid() != opts.SelfAddr.IsValid() { + return nil, fmt.Errorf("both GatewayAddr and SelfAddr must be provided if one is") + } else if opts.GatewayAddr.IsValid() { + vals.Set("gateway_and_self", fmt.Sprintf("%s/%s", opts.GatewayAddr, opts.SelfAddr)) + } + + req, err := http.NewRequestWithContext(ctx, "GET", "http://"+apitype.LocalAPIHost+"/localapi/v0/debug-portmap?"+vals.Encode(), nil) + if err != nil { + return nil, err + } + res, err := lc.doLocalRequestNiceError(req) + if err != nil { + return nil, err + } + if res.StatusCode != 200 { + body, _ := io.ReadAll(res.Body) + res.Body.Close() + return nil, fmt.Errorf("HTTP %s: %s", res.Status, body) + } + + return res.Body, nil +} diff --git a/vendor/tailscale.com/client/local/local.go b/vendor/tailscale.com/client/local/local.go index 5312c1d..195a91b 100644 --- a/vendor/tailscale.com/client/local/local.go +++ b/vendor/tailscale.com/client/local/local.go @@ -1,21 +1,20 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build go1.22 - // Package local contains a Go client for the Tailscale LocalAPI. package local import ( + "bufio" "bytes" "cmp" "context" - "crypto/tls" "encoding/base64" "encoding/json" "errors" "fmt" "io" + "iter" "net" "net/http" "net/http/httptrace" @@ -28,21 +27,24 @@ import ( "sync" "time" - "go4.org/mem" "tailscale.com/client/tailscale/apitype" "tailscale.com/drive" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn" "tailscale.com/ipn/ipnstate" "tailscale.com/net/netutil" + "tailscale.com/net/udprelay/status" "tailscale.com/paths" "tailscale.com/safesocket" + "tailscale.com/syncs" "tailscale.com/tailcfg" - "tailscale.com/tka" + "tailscale.com/types/appctype" "tailscale.com/types/dnstype" "tailscale.com/types/key" - "tailscale.com/types/tkatype" - "tailscale.com/util/syspolicy/setting" + "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" ) // defaultClient is the default Client when using the legacy @@ -294,7 +296,7 @@ func (lc *Client) get200(ctx context.Context, path string) ([]byte, error) { // WhoIs returns the owner of the remoteAddr, which must be an IP or IP:port. // -// Deprecated: use Client.WhoIs. +// Deprecated: use [Client.WhoIs]. func WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsResponse, error) { return defaultClient.WhoIs(ctx, remoteAddr) } @@ -309,7 +311,7 @@ func decodeJSON[T any](b []byte) (ret T, err error) { // WhoIs returns the owner of the remoteAddr, which must be an IP or IP:port. // -// If not found, the error is ErrPeerNotFound. +// If not found, the error is [ErrPeerNotFound]. // // For connections proxied by tailscaled, this looks up the owner of the given // address as TCP first, falling back to UDP; if you want to only check a @@ -325,7 +327,8 @@ func (lc *Client) WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsR return decodeJSON[*apitype.WhoIsResponse](body) } -// ErrPeerNotFound is returned by WhoIs and WhoIsNodeKey when a peer is not found. +// ErrPeerNotFound is returned by [Client.WhoIs], [Client.WhoIsNodeKey] and +// [Client.WhoIsProto] when a peer is not found. var ErrPeerNotFound = errors.New("peer not found") // WhoIsNodeKey returns the owner of the given wireguard public key. @@ -345,7 +348,7 @@ func (lc *Client) WhoIsNodeKey(ctx context.Context, key key.NodePublic) (*apityp // WhoIsProto returns the owner of the remoteAddr, which must be an IP or // IP:port, for the given protocol (tcp or udp). // -// If not found, the error is ErrPeerNotFound. +// If not found, the error is [ErrPeerNotFound]. func (lc *Client) WhoIsProto(ctx context.Context, proto, remoteAddr string) (*apitype.WhoIsResponse, error) { body, err := lc.get200(ctx, "/localapi/v0/whois?proto="+url.QueryEscape(proto)+"&addr="+url.QueryEscape(remoteAddr)) if err != nil { @@ -380,18 +383,42 @@ func (lc *Client) UserMetrics(ctx context.Context) ([]byte, error) { // // IncrementCounter does not support gauge metrics or negative delta values. func (lc *Client) IncrementCounter(ctx context.Context, name string, delta int) error { - type metricUpdate struct { - Name string `json:"name"` - Type string `json:"type"` - Value int `json:"value"` // amount to increment by + if !buildfeatures.HasClientMetrics { + return nil } if delta < 0 { return errors.New("negative delta not allowed") } - _, err := lc.send(ctx, "POST", "/localapi/v0/upload-client-metrics", 200, jsonBody([]metricUpdate{{ + _, err := lc.send(ctx, "POST", "/localapi/v0/upload-client-metrics", 200, jsonBody([]clientmetric.MetricUpdate{{ Name: name, Type: "counter", Value: delta, + Op: "add", + }})) + return err +} + +// IncrementGauge increments the value of a Tailscale daemon's gauge +// metric by the given delta. If the metric has yet to exist, a new gauge +// metric is created and initialized to delta. The delta value can be negative. +func (lc *Client) IncrementGauge(ctx context.Context, name string, delta int) error { + _, err := lc.send(ctx, "POST", "/localapi/v0/upload-client-metrics", 200, jsonBody([]clientmetric.MetricUpdate{{ + Name: name, + Type: "gauge", + Value: delta, + Op: "add", + }})) + return err +} + +// SetGauge sets the value of a Tailscale daemon's gauge metric to the given value. +// If the metric has yet to exist, a new gauge metric is created and initialized to value. +func (lc *Client) SetGauge(ctx context.Context, name string, value int) error { + _, err := lc.send(ctx, "POST", "/localapi/v0/upload-client-metrics", 200, jsonBody([]clientmetric.MetricUpdate{{ + Name: name, + Type: "gauge", + Value: value, + Op: "set", }})) return err } @@ -413,6 +440,50 @@ func (lc *Client) TailDaemonLogs(ctx context.Context) (io.Reader, error) { return res.Body, nil } +// EventBusGraph returns a graph of active publishers and subscribers in the eventbus +// as a [eventbus.DebugTopics] +func (lc *Client) EventBusGraph(ctx context.Context) ([]byte, error) { + return lc.get200(ctx, "/localapi/v0/debug-bus-graph") +} + +// StreamBusEvents returns an iterator of Tailscale bus events as they arrive. +// Each pair is a valid event and a nil error, or a zero event a non-nil error. +// In case of error, the iterator ends after the pair reporting the error. +// Iteration stops if ctx ends. +func (lc *Client) StreamBusEvents(ctx context.Context) iter.Seq2[eventbus.DebugEvent, error] { + return func(yield func(eventbus.DebugEvent, error) bool) { + req, err := http.NewRequestWithContext(ctx, "GET", + "http://"+apitype.LocalAPIHost+"/localapi/v0/debug-bus-events", nil) + if err != nil { + yield(eventbus.DebugEvent{}, err) + return + } + res, err := lc.doLocalRequestNiceError(req) + if err != nil { + yield(eventbus.DebugEvent{}, err) + return + } + if res.StatusCode != http.StatusOK { + yield(eventbus.DebugEvent{}, errors.New(res.Status)) + return + } + defer res.Body.Close() + dec := json.NewDecoder(bufio.NewReader(res.Body)) + for { + var evt eventbus.DebugEvent + if err := dec.Decode(&evt); err == io.EOF { + return + } else if err != nil { + yield(eventbus.DebugEvent{}, err) + return + } + if !yield(evt, nil) { + return + } + } + } +} + // Pprof returns a pprof profile of the Tailscale daemon. func (lc *Client) Pprof(ctx context.Context, pprofType string, sec int) ([]byte, error) { var secArg string @@ -490,7 +561,7 @@ func (lc *Client) BugReportWithOpts(ctx context.Context, opts BugReportOpts) (st // BugReport logs and returns a log marker that can be shared by the user with support. // -// This is the same as calling BugReportWithOpts and only specifying the Note +// This is the same as calling [Client.BugReportWithOpts] and only specifying the Note // field. func (lc *Client) BugReport(ctx context.Context, note string) (string, error) { return lc.BugReportWithOpts(ctx, BugReportOpts{Note: note}) @@ -531,68 +602,17 @@ func (lc *Client) DebugResultJSON(ctx context.Context, action string) (any, erro return x, nil } -// DebugPortmapOpts contains options for the DebugPortmap command. -type DebugPortmapOpts struct { - // Duration is how long the mapping should be created for. It defaults - // to 5 seconds if not set. - Duration time.Duration - - // Type is the kind of portmap to debug. The empty string instructs the - // portmap client to perform all known types. Other valid options are - // "pmp", "pcp", and "upnp". - Type string - - // GatewayAddr specifies the gateway address used during portmapping. - // If set, SelfAddr must also be set. If unset, it will be - // autodetected. - GatewayAddr netip.Addr - - // SelfAddr specifies the gateway address used during portmapping. If - // set, GatewayAddr must also be set. If unset, it will be - // autodetected. - SelfAddr netip.Addr - - // LogHTTP instructs the debug-portmap endpoint to print all HTTP - // requests and responses made to the logs. - LogHTTP bool -} - -// DebugPortmap invokes the debug-portmap endpoint, and returns an -// io.ReadCloser that can be used to read the logs that are printed during this -// process. -// -// opts can be nil; if so, default values will be used. -func (lc *Client) DebugPortmap(ctx context.Context, opts *DebugPortmapOpts) (io.ReadCloser, error) { - vals := make(url.Values) - if opts == nil { - opts = &DebugPortmapOpts{} - } - - vals.Set("duration", cmp.Or(opts.Duration, 5*time.Second).String()) - vals.Set("type", opts.Type) - vals.Set("log_http", strconv.FormatBool(opts.LogHTTP)) - - if opts.GatewayAddr.IsValid() != opts.SelfAddr.IsValid() { - return nil, fmt.Errorf("both GatewayAddr and SelfAddr must be provided if one is") - } else if opts.GatewayAddr.IsValid() { - vals.Set("gateway_and_self", fmt.Sprintf("%s/%s", opts.GatewayAddr, opts.SelfAddr)) - } - - req, err := http.NewRequestWithContext(ctx, "GET", "http://"+apitype.LocalAPIHost+"/localapi/v0/debug-portmap?"+vals.Encode(), nil) +// QueryOptionalFeatures queries the optional features supported by the Tailscale daemon. +func (lc *Client) QueryOptionalFeatures(ctx context.Context) (*apitype.OptionalFeatures, error) { + body, err := lc.send(ctx, "POST", "/localapi/v0/debug-optional-features", 200, nil) if err != nil { + return nil, fmt.Errorf("error %w: %s", err, body) + } + var x apitype.OptionalFeatures + if err := json.Unmarshal(body, &x); err != nil { return nil, err } - res, err := lc.doLocalRequestNiceError(req) - if err != nil { - return nil, err - } - if res.StatusCode != 200 { - body, _ := io.ReadAll(res.Body) - res.Body.Close() - return nil, fmt.Errorf("HTTP %s: %s", res.Status, body) - } - - return res.Body, nil + return &x, nil } // SetDevStoreKeyValue set a statestore key/value. It's only meant for development. @@ -612,6 +632,9 @@ func (lc *Client) SetDevStoreKeyValue(ctx context.Context, key, value string) er // the provided duration. If the duration is in the past, the debug logging // is disabled. func (lc *Client) SetComponentDebugLogging(ctx context.Context, component string, d time.Duration) error { + if !buildfeatures.HasDebug { + return feature.ErrUnavailable + } body, err := lc.send(ctx, "POST", fmt.Sprintf("/localapi/v0/component-debug-logging?component=%s&secs=%d", url.QueryEscape(component), int64(d.Seconds())), 200, nil) @@ -677,7 +700,7 @@ func (lc *Client) WaitingFiles(ctx context.Context) ([]apitype.WaitingFile, erro return lc.AwaitWaitingFiles(ctx, 0) } -// AwaitWaitingFiles is like WaitingFiles but takes a duration to await for an answer. +// AwaitWaitingFiles is like [Client.WaitingFiles] but takes a duration to await for an answer. // If the duration is 0, it will return immediately. The duration is respected at second // granularity only. If no files are available, it returns (nil, nil). func (lc *Client) AwaitWaitingFiles(ctx context.Context, d time.Duration) ([]apitype.WaitingFile, error) { @@ -751,6 +774,9 @@ func (lc *Client) PushFile(ctx context.Context, target tailcfg.StableNodeID, siz // machine is properly configured to forward IP packets as a subnet router // or exit node. func (lc *Client) CheckIPForwarding(ctx context.Context) error { + if !buildfeatures.HasAdvertiseRoutes { + return nil + } body, err := lc.get200(ctx, "/localapi/v0/check-ip-forwarding") if err != nil { return err @@ -787,6 +813,25 @@ func (lc *Client) CheckUDPGROForwarding(ctx context.Context) error { return nil } +// CheckReversePathFiltering asks the local Tailscale daemon whether strict +// reverse path filtering is enabled, which would break exit node usage on Linux. +func (lc *Client) CheckReversePathFiltering(ctx context.Context) error { + body, err := lc.get200(ctx, "/localapi/v0/check-reverse-path-filtering") + if err != nil { + return err + } + var jres struct { + Warning string + } + if err := json.Unmarshal(body, &jres); err != nil { + return fmt.Errorf("invalid JSON from check-reverse-path-filtering: %w", err) + } + if jres.Warning != "" { + return errors.New(jres.Warning) + } + return nil +} + // SetUDPGROForwarding enables UDP GRO forwarding for the main interface of this // node. This can be done to improve performance of tailnet nodes acting as exit // nodes or subnet routers. @@ -844,36 +889,12 @@ func (lc *Client) EditPrefs(ctx context.Context, mp *ipn.MaskedPrefs) (*ipn.Pref return decodeJSON[*ipn.Prefs](body) } -// GetEffectivePolicy returns the effective policy for the specified scope. -func (lc *Client) GetEffectivePolicy(ctx context.Context, scope setting.PolicyScope) (*setting.Snapshot, error) { - scopeID, err := scope.MarshalText() - if err != nil { - return nil, err - } - body, err := lc.get200(ctx, "/localapi/v0/policy/"+string(scopeID)) - if err != nil { - return nil, err - } - return decodeJSON[*setting.Snapshot](body) -} - -// ReloadEffectivePolicy reloads the effective policy for the specified scope -// by reading and merging policy settings from all applicable policy sources. -func (lc *Client) ReloadEffectivePolicy(ctx context.Context, scope setting.PolicyScope) (*setting.Snapshot, error) { - scopeID, err := scope.MarshalText() - if err != nil { - return nil, err - } - body, err := lc.send(ctx, "POST", "/localapi/v0/policy/"+string(scopeID), 200, http.NoBody) - if err != nil { - return nil, err - } - return decodeJSON[*setting.Snapshot](body) -} - // GetDNSOSConfig returns the system DNS configuration for the current device. // That is, it returns the DNS configuration that the system would use if Tailscale weren't being used. func (lc *Client) GetDNSOSConfig(ctx context.Context) (*apitype.DNSOSConfig, error) { + if !buildfeatures.HasDNS { + return nil, feature.ErrUnavailable + } body, err := lc.get200(ctx, "/localapi/v0/dns-osconfig") if err != nil { return nil, err @@ -889,6 +910,9 @@ func (lc *Client) GetDNSOSConfig(ctx context.Context) (*apitype.DNSOSConfig, err // It returns the raw DNS response bytes and the resolvers that were used to answer the query // (often just one, but can be more if we raced multiple resolvers). func (lc *Client) QueryDNS(ctx context.Context, name string, queryType string) (bytes []byte, resolvers []*dnstype.Resolver, err error) { + if !buildfeatures.HasDNS { + return nil, nil, feature.ErrUnavailable + } body, err := lc.get200(ctx, fmt.Sprintf("/localapi/v0/dns-query?name=%s&type=%s", url.QueryEscape(name), queryType)) if err != nil { return nil, nil, err @@ -919,34 +943,12 @@ func (lc *Client) Logout(ctx context.Context) error { return err } -// SetDNS adds a DNS TXT record for the given domain name, containing -// the provided TXT value. The intended use case is answering -// LetsEncrypt/ACME dns-01 challenges. -// -// The control plane will only permit SetDNS requests with very -// specific names and values. The name should be -// "_acme-challenge." + your node's MagicDNS name. It's expected that -// clients cache the certs from LetsEncrypt (or whichever CA is -// providing them) and only request new ones as needed; the control plane -// rate limits SetDNS requests. -// -// This is a low-level interface; it's expected that most Tailscale -// users use a higher level interface to getting/using TLS -// certificates. -func (lc *Client) SetDNS(ctx context.Context, name, value string) error { - v := url.Values{} - v.Set("name", name) - v.Set("value", value) - _, err := lc.send(ctx, "POST", "/localapi/v0/set-dns?"+v.Encode(), 200, nil) - return err -} - // DialTCP connects to the host's port via Tailscale. // // The host may be a base DNS name (resolved from the netmap inside // tailscaled), a FQDN, or an IP address. // -// The ctx is only used for the duration of the call, not the lifetime of the net.Conn. +// The ctx is only used for the duration of the call, not the lifetime of the [net.Conn]. func (lc *Client) DialTCP(ctx context.Context, host string, port uint16) (net.Conn, error) { return lc.UserDial(ctx, "tcp", host, port) } @@ -957,7 +959,7 @@ func (lc *Client) DialTCP(ctx context.Context, host string, port uint16) (net.Co // a FQDN, or an IP address. // // The ctx is only used for the duration of the call, not the lifetime of the -// net.Conn. +// [net.Conn]. func (lc *Client) UserDial(ctx context.Context, network, host string, port uint16) (net.Conn, error) { connCh := make(chan net.Conn, 1) trace := httptrace.ClientTrace{ @@ -1021,117 +1023,6 @@ func (lc *Client) CurrentDERPMap(ctx context.Context) (*tailcfg.DERPMap, error) return &derpMap, nil } -// CertPair returns a cert and private key for the provided DNS domain. -// -// It returns a cached certificate from disk if it's still valid. -// -// Deprecated: use Client.CertPair. -func CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { - return defaultClient.CertPair(ctx, domain) -} - -// CertPair returns a cert and private key for the provided DNS domain. -// -// It returns a cached certificate from disk if it's still valid. -// -// API maturity: this is considered a stable API. -func (lc *Client) CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { - return lc.CertPairWithValidity(ctx, domain, 0) -} - -// CertPairWithValidity returns a cert and private key for the provided DNS -// domain. -// -// It returns a cached certificate from disk if it's still valid. -// When minValidity is non-zero, the returned certificate will be valid for at -// least the given duration, if permitted by the CA. If the certificate is -// valid, but for less than minValidity, it will be synchronously renewed. -// -// API maturity: this is considered a stable API. -func (lc *Client) CertPairWithValidity(ctx context.Context, domain string, minValidity time.Duration) (certPEM, keyPEM []byte, err error) { - res, err := lc.send(ctx, "GET", fmt.Sprintf("/localapi/v0/cert/%s?type=pair&min_validity=%s", domain, minValidity), 200, nil) - if err != nil { - return nil, nil, err - } - // with ?type=pair, the response PEM is first the one private - // key PEM block, then the cert PEM blocks. - i := mem.Index(mem.B(res), mem.S("--\n--")) - if i == -1 { - return nil, nil, fmt.Errorf("unexpected output: no delimiter") - } - i += len("--\n") - keyPEM, certPEM = res[:i], res[i:] - if mem.Contains(mem.B(certPEM), mem.S(" PRIVATE KEY-----")) { - return nil, nil, fmt.Errorf("unexpected output: key in cert") - } - return certPEM, keyPEM, nil -} - -// GetCertificate fetches a TLS certificate for the TLS ClientHello in hi. -// -// It returns a cached certificate from disk if it's still valid. -// -// It's the right signature to use as the value of -// tls.Config.GetCertificate. -// -// Deprecated: use Client.GetCertificate. -func GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { - return defaultClient.GetCertificate(hi) -} - -// GetCertificate fetches a TLS certificate for the TLS ClientHello in hi. -// -// It returns a cached certificate from disk if it's still valid. -// -// It's the right signature to use as the value of -// tls.Config.GetCertificate. -// -// API maturity: this is considered a stable API. -func (lc *Client) GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { - if hi == nil || hi.ServerName == "" { - return nil, errors.New("no SNI ServerName") - } - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - name := hi.ServerName - if !strings.Contains(name, ".") { - if v, ok := lc.ExpandSNIName(ctx, name); ok { - name = v - } - } - certPEM, keyPEM, err := lc.CertPair(ctx, name) - if err != nil { - return nil, err - } - cert, err := tls.X509KeyPair(certPEM, keyPEM) - if err != nil { - return nil, err - } - return &cert, nil -} - -// ExpandSNIName expands bare label name into the most likely actual TLS cert name. -// -// Deprecated: use Client.ExpandSNIName. -func ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { - return defaultClient.ExpandSNIName(ctx, name) -} - -// ExpandSNIName expands bare label name into the most likely actual TLS cert name. -func (lc *Client) ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { - st, err := lc.StatusWithoutPeers(ctx) - if err != nil { - return "", false - } - for _, d := range st.CertDomains { - if len(d) > len(name)+1 && strings.HasPrefix(d, name) && d[len(name)] == '.' { - return d, true - } - } - return "", false -} - // PingOpts contains options for the ping request. // // The zero value is valid, which means to use defaults. @@ -1165,197 +1056,6 @@ func (lc *Client) Ping(ctx context.Context, ip netip.Addr, pingtype tailcfg.Ping return lc.PingWithOpts(ctx, ip, pingtype, PingOpts{}) } -// NetworkLockStatus fetches information about the tailnet key authority, if one is configured. -func (lc *Client) NetworkLockStatus(ctx context.Context) (*ipnstate.NetworkLockStatus, error) { - body, err := lc.send(ctx, "GET", "/localapi/v0/tka/status", 200, nil) - if err != nil { - return nil, fmt.Errorf("error: %w", err) - } - return decodeJSON[*ipnstate.NetworkLockStatus](body) -} - -// NetworkLockInit initializes the tailnet key authority. -// -// TODO(tom): Plumb through disablement secrets. -func (lc *Client) NetworkLockInit(ctx context.Context, keys []tka.Key, disablementValues [][]byte, supportDisablement []byte) (*ipnstate.NetworkLockStatus, error) { - var b bytes.Buffer - type initRequest struct { - Keys []tka.Key - DisablementValues [][]byte - SupportDisablement []byte - } - - if err := json.NewEncoder(&b).Encode(initRequest{Keys: keys, DisablementValues: disablementValues, SupportDisablement: supportDisablement}); err != nil { - return nil, err - } - - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/init", 200, &b) - if err != nil { - return nil, fmt.Errorf("error: %w", err) - } - return decodeJSON[*ipnstate.NetworkLockStatus](body) -} - -// NetworkLockWrapPreauthKey wraps a pre-auth key with information to -// enable unattended bringup in the locked tailnet. -func (lc *Client) NetworkLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.NLPrivate) (string, error) { - encodedPrivate, err := tkaKey.MarshalText() - if err != nil { - return "", err - } - - var b bytes.Buffer - type wrapRequest struct { - TSKey string - TKAKey string // key.NLPrivate.MarshalText - } - if err := json.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil { - return "", err - } - - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/wrap-preauth-key", 200, &b) - if err != nil { - return "", fmt.Errorf("error: %w", err) - } - return string(body), nil -} - -// NetworkLockModify adds and/or removes key(s) to the tailnet key authority. -func (lc *Client) NetworkLockModify(ctx context.Context, addKeys, removeKeys []tka.Key) error { - var b bytes.Buffer - type modifyRequest struct { - AddKeys []tka.Key - RemoveKeys []tka.Key - } - - if err := json.NewEncoder(&b).Encode(modifyRequest{AddKeys: addKeys, RemoveKeys: removeKeys}); err != nil { - return err - } - - if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/modify", 204, &b); err != nil { - return fmt.Errorf("error: %w", err) - } - return nil -} - -// NetworkLockSign signs the specified node-key and transmits that signature to the control plane. -// rotationPublic, if specified, must be an ed25519 public key. -func (lc *Client) NetworkLockSign(ctx context.Context, nodeKey key.NodePublic, rotationPublic []byte) error { - var b bytes.Buffer - type signRequest struct { - NodeKey key.NodePublic - RotationPublic []byte - } - - if err := json.NewEncoder(&b).Encode(signRequest{NodeKey: nodeKey, RotationPublic: rotationPublic}); err != nil { - return err - } - - if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/sign", 200, &b); err != nil { - return fmt.Errorf("error: %w", err) - } - return nil -} - -// NetworkLockAffectedSigs returns all signatures signed by the specified keyID. -func (lc *Client) NetworkLockAffectedSigs(ctx context.Context, keyID tkatype.KeyID) ([]tkatype.MarshaledSignature, error) { - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/affected-sigs", 200, bytes.NewReader(keyID)) - if err != nil { - return nil, fmt.Errorf("error: %w", err) - } - return decodeJSON[[]tkatype.MarshaledSignature](body) -} - -// NetworkLockLog returns up to maxEntries number of changes to network-lock state. -func (lc *Client) NetworkLockLog(ctx context.Context, maxEntries int) ([]ipnstate.NetworkLockUpdate, error) { - v := url.Values{} - v.Set("limit", fmt.Sprint(maxEntries)) - body, err := lc.send(ctx, "GET", "/localapi/v0/tka/log?"+v.Encode(), 200, nil) - if err != nil { - return nil, fmt.Errorf("error %w: %s", err, body) - } - return decodeJSON[[]ipnstate.NetworkLockUpdate](body) -} - -// NetworkLockForceLocalDisable forcibly shuts down network lock on this node. -func (lc *Client) NetworkLockForceLocalDisable(ctx context.Context) error { - // This endpoint expects an empty JSON stanza as the payload. - var b bytes.Buffer - if err := json.NewEncoder(&b).Encode(struct{}{}); err != nil { - return err - } - - if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/force-local-disable", 200, &b); err != nil { - return fmt.Errorf("error: %w", err) - } - return nil -} - -// NetworkLockVerifySigningDeeplink verifies the network lock deeplink contained -// in url and returns information extracted from it. -func (lc *Client) NetworkLockVerifySigningDeeplink(ctx context.Context, url string) (*tka.DeeplinkValidationResult, error) { - vr := struct { - URL string - }{url} - - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/verify-deeplink", 200, jsonBody(vr)) - if err != nil { - return nil, fmt.Errorf("sending verify-deeplink: %w", err) - } - - return decodeJSON[*tka.DeeplinkValidationResult](body) -} - -// NetworkLockGenRecoveryAUM generates an AUM for recovering from a tailnet-lock key compromise. -func (lc *Client) NetworkLockGenRecoveryAUM(ctx context.Context, removeKeys []tkatype.KeyID, forkFrom tka.AUMHash) ([]byte, error) { - vr := struct { - Keys []tkatype.KeyID - ForkFrom string - }{removeKeys, forkFrom.String()} - - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/generate-recovery-aum", 200, jsonBody(vr)) - if err != nil { - return nil, fmt.Errorf("sending generate-recovery-aum: %w", err) - } - - return body, nil -} - -// NetworkLockCosignRecoveryAUM co-signs a recovery AUM using the node's tailnet lock key. -func (lc *Client) NetworkLockCosignRecoveryAUM(ctx context.Context, aum tka.AUM) ([]byte, error) { - r := bytes.NewReader(aum.Serialize()) - body, err := lc.send(ctx, "POST", "/localapi/v0/tka/cosign-recovery-aum", 200, r) - if err != nil { - return nil, fmt.Errorf("sending cosign-recovery-aum: %w", err) - } - - return body, nil -} - -// NetworkLockSubmitRecoveryAUM submits a recovery AUM to the control plane. -func (lc *Client) NetworkLockSubmitRecoveryAUM(ctx context.Context, aum tka.AUM) error { - r := bytes.NewReader(aum.Serialize()) - _, err := lc.send(ctx, "POST", "/localapi/v0/tka/submit-recovery-aum", 200, r) - if err != nil { - return fmt.Errorf("sending cosign-recovery-aum: %w", err) - } - return nil -} - -// SetServeConfig sets or replaces the serving settings. -// If config is nil, settings are cleared and serving is disabled. -func (lc *Client) SetServeConfig(ctx context.Context, config *ipn.ServeConfig) error { - h := make(http.Header) - if config != nil { - h.Set("If-Match", config.ETag) - } - _, _, err := lc.sendWithHeaders(ctx, "POST", "/localapi/v0/serve-config", 200, jsonBody(config), h) - if err != nil { - return fmt.Errorf("sending serve config: %w", err) - } - return nil -} - // DisconnectControl shuts down all connections to control, thus making control consider this node inactive. This can be // run on HA subnet router or app connector replicas before shutting them down to ensure peers get told to switch over // to another replica whilst there is still some grace period for the existing connections to terminate. @@ -1367,40 +1067,6 @@ func (lc *Client) DisconnectControl(ctx context.Context) error { return nil } -// NetworkLockDisable shuts down network-lock across the tailnet. -func (lc *Client) NetworkLockDisable(ctx context.Context, secret []byte) error { - if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/disable", 200, bytes.NewReader(secret)); err != nil { - return fmt.Errorf("error: %w", err) - } - return nil -} - -// GetServeConfig return the current serve config. -// -// If the serve config is empty, it returns (nil, nil). -func (lc *Client) GetServeConfig(ctx context.Context) (*ipn.ServeConfig, error) { - body, h, err := lc.sendWithHeaders(ctx, "GET", "/localapi/v0/serve-config", 200, nil, nil) - if err != nil { - return nil, fmt.Errorf("getting serve config: %w", err) - } - sc, err := getServeConfigFromJSON(body) - if err != nil { - return nil, err - } - if sc == nil { - sc = new(ipn.ServeConfig) - } - sc.ETag = h.Get("Etag") - return sc, nil -} - -func getServeConfigFromJSON(body []byte) (sc *ipn.ServeConfig, err error) { - if err := json.Unmarshal(body, &sc); err != nil { - return nil, err - } - return sc, nil -} - // tailscaledConnectHint gives a little thing about why tailscaled (or // platform equivalent) is not answering localapi connections. // @@ -1502,9 +1168,9 @@ func (lc *Client) SwitchProfile(ctx context.Context, profile ipn.ProfileID) erro // DeleteProfile removes the profile with the given ID. // If the profile is the current profile, an empty profile -// will be selected as if SwitchToEmptyProfile was called. +// will be selected as if [Client.SwitchToEmptyProfile] was called. func (lc *Client) DeleteProfile(ctx context.Context, profile ipn.ProfileID) error { - _, err := lc.send(ctx, "DELETE", "/localapi/v0/profiles"+url.PathEscape(string(profile)), http.StatusNoContent, nil) + _, err := lc.send(ctx, "DELETE", "/localapi/v0/profiles/"+url.PathEscape(string(profile)), http.StatusNoContent, nil) return err } @@ -1556,10 +1222,20 @@ func (lc *Client) DebugSetExpireIn(ctx context.Context, d time.Duration) error { return err } +// DebugPeerRelaySessions returns debug information about the current peer +// relay sessions running through this node. +func (lc *Client) DebugPeerRelaySessions(ctx context.Context) (*status.ServerStatus, error) { + body, err := lc.send(ctx, "GET", "/localapi/v0/debug-peer-relay-sessions", 200, nil) + if err != nil { + return nil, fmt.Errorf("error %w: %s", err, body) + } + return decodeJSON[*status.ServerStatus](body) +} + // StreamDebugCapture streams a pcap-formatted packet capture. // // The provided context does not determine the lifetime of the -// returned io.ReadCloser. +// returned [io.ReadCloser]. func (lc *Client) StreamDebugCapture(ctx context.Context) (io.ReadCloser, error) { req, err := http.NewRequestWithContext(ctx, "POST", "http://"+apitype.LocalAPIHost+"/localapi/v0/debug-capture", nil) if err != nil { @@ -1582,7 +1258,7 @@ func (lc *Client) StreamDebugCapture(ctx context.Context) (io.ReadCloser, error) // The context is used for the life of the watch, not just the call to // WatchIPNBus. // -// The returned IPNBusWatcher's Close method must be called when done to release +// The returned [IPNBusWatcher]'s Close method must be called when done to release // resources. // // A default set of ipn.Notify messages are returned but the set can be modified by mask. @@ -1609,7 +1285,7 @@ func (lc *Client) WatchIPNBus(ctx context.Context, mask ipn.NotifyWatchOpt) (*IP }, nil } -// CheckUpdate returns a tailcfg.ClientVersion indicating whether or not an update is available +// CheckUpdate returns a [*tailcfg.ClientVersion] indicating whether or not an update is available // to be installed via the LocalAPI. In case the LocalAPI can't install updates, it returns a // ClientVersion that says that we are up to date. func (lc *Client) CheckUpdate(ctx context.Context) (*tailcfg.ClientVersion, error) { @@ -1685,7 +1361,7 @@ func (lc *Client) DriveShareList(ctx context.Context) ([]*drive.Share, error) { } // IPNBusWatcher is an active subscription (watch) of the local tailscaled IPN bus. -// It's returned by Client.WatchIPNBus. +// It's returned by [Client.WatchIPNBus]. // // It must be closed when done. type IPNBusWatcher struct { @@ -1693,7 +1369,7 @@ type IPNBusWatcher struct { httpRes *http.Response dec *json.Decoder - mu sync.Mutex + mu syncs.Mutex closed bool } @@ -1729,3 +1405,34 @@ func (lc *Client) SuggestExitNode(ctx context.Context) (apitype.ExitNodeSuggesti } return decodeJSON[apitype.ExitNodeSuggestionResponse](body) } + +// CheckSOMarkInUse reports whether the socket mark option is in use. This will only +// be true if tailscale is running on Linux and tailscaled uses SO_MARK. +func (lc *Client) CheckSOMarkInUse(ctx context.Context) (bool, error) { + body, err := lc.get200(ctx, "/localapi/v0/check-so-mark-in-use") + if err != nil { + return false, err + } + var res struct { + UseSOMark bool `json:"useSoMark"` + } + + if err := json.Unmarshal(body, &res); err != nil { + return false, fmt.Errorf("invalid JSON from check-so-mark-in-use: %w", err) + } + return res.UseSOMark, nil +} + +// ShutdownTailscaled requests a graceful shutdown of tailscaled. +func (lc *Client) ShutdownTailscaled(ctx context.Context) error { + _, err := lc.send(ctx, "POST", "/localapi/v0/shutdown", 200, nil) + return err +} + +func (lc *Client) GetAppConnectorRouteInfo(ctx context.Context) (appctype.RouteInfo, error) { + body, err := lc.get200(ctx, "/localapi/v0/appc-route-info") + if err != nil { + return appctype.RouteInfo{}, err + } + return decodeJSON[appctype.RouteInfo](body) +} diff --git a/vendor/tailscale.com/client/local/serve.go b/vendor/tailscale.com/client/local/serve.go new file mode 100644 index 0000000..51d15e7 --- /dev/null +++ b/vendor/tailscale.com/client/local/serve.go @@ -0,0 +1,55 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_serve + +package local + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "tailscale.com/ipn" +) + +// GetServeConfig return the current serve config. +// +// If the serve config is empty, it returns (nil, nil). +func (lc *Client) GetServeConfig(ctx context.Context) (*ipn.ServeConfig, error) { + body, h, err := lc.sendWithHeaders(ctx, "GET", "/localapi/v0/serve-config", 200, nil, nil) + if err != nil { + return nil, fmt.Errorf("getting serve config: %w", err) + } + sc, err := getServeConfigFromJSON(body) + if err != nil { + return nil, err + } + if sc == nil { + sc = new(ipn.ServeConfig) + } + sc.ETag = h.Get("Etag") + return sc, nil +} + +func getServeConfigFromJSON(body []byte) (sc *ipn.ServeConfig, err error) { + if err := json.Unmarshal(body, &sc); err != nil { + return nil, err + } + return sc, nil +} + +// SetServeConfig sets or replaces the serving settings. +// If config is nil, settings are cleared and serving is disabled. +func (lc *Client) SetServeConfig(ctx context.Context, config *ipn.ServeConfig) error { + h := make(http.Header) + if config != nil { + h.Set("If-Match", config.ETag) + } + _, _, err := lc.sendWithHeaders(ctx, "POST", "/localapi/v0/serve-config", 200, jsonBody(config), h) + if err != nil { + return fmt.Errorf("sending serve config: %w", err) + } + return nil +} diff --git a/vendor/tailscale.com/client/local/syspolicy.go b/vendor/tailscale.com/client/local/syspolicy.go new file mode 100644 index 0000000..6eff177 --- /dev/null +++ b/vendor/tailscale.com/client/local/syspolicy.go @@ -0,0 +1,40 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_syspolicy + +package local + +import ( + "context" + "net/http" + + "tailscale.com/util/syspolicy/setting" +) + +// GetEffectivePolicy returns the effective policy for the specified scope. +func (lc *Client) GetEffectivePolicy(ctx context.Context, scope setting.PolicyScope) (*setting.Snapshot, error) { + scopeID, err := scope.MarshalText() + if err != nil { + return nil, err + } + body, err := lc.get200(ctx, "/localapi/v0/policy/"+string(scopeID)) + if err != nil { + return nil, err + } + return decodeJSON[*setting.Snapshot](body) +} + +// ReloadEffectivePolicy reloads the effective policy for the specified scope +// by reading and merging policy settings from all applicable policy sources. +func (lc *Client) ReloadEffectivePolicy(ctx context.Context, scope setting.PolicyScope) (*setting.Snapshot, error) { + scopeID, err := scope.MarshalText() + if err != nil { + return nil, err + } + body, err := lc.send(ctx, "POST", "/localapi/v0/policy/"+string(scopeID), 200, http.NoBody) + if err != nil { + return nil, err + } + return decodeJSON[*setting.Snapshot](body) +} diff --git a/vendor/tailscale.com/client/local/tailnetlock.go b/vendor/tailscale.com/client/local/tailnetlock.go new file mode 100644 index 0000000..9d37d2f --- /dev/null +++ b/vendor/tailscale.com/client/local/tailnetlock.go @@ -0,0 +1,204 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_tailnetlock + +package local + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/url" + + "tailscale.com/ipn/ipnstate" + "tailscale.com/tka" + "tailscale.com/types/key" + "tailscale.com/types/tkatype" +) + +// NetworkLockStatus fetches information about the tailnet key authority, if one is configured. +func (lc *Client) NetworkLockStatus(ctx context.Context) (*ipnstate.NetworkLockStatus, error) { + body, err := lc.send(ctx, "GET", "/localapi/v0/tka/status", 200, nil) + if err != nil { + return nil, fmt.Errorf("error: %w", err) + } + return decodeJSON[*ipnstate.NetworkLockStatus](body) +} + +// NetworkLockInit initializes the tailnet key authority. +// +// TODO(tom): Plumb through disablement secrets. +func (lc *Client) NetworkLockInit(ctx context.Context, keys []tka.Key, disablementValues [][]byte, supportDisablement []byte) (*ipnstate.NetworkLockStatus, error) { + var b bytes.Buffer + type initRequest struct { + Keys []tka.Key + DisablementValues [][]byte + SupportDisablement []byte + } + + if err := json.NewEncoder(&b).Encode(initRequest{Keys: keys, DisablementValues: disablementValues, SupportDisablement: supportDisablement}); err != nil { + return nil, err + } + + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/init", 200, &b) + if err != nil { + return nil, fmt.Errorf("error: %w", err) + } + return decodeJSON[*ipnstate.NetworkLockStatus](body) +} + +// NetworkLockWrapPreauthKey wraps a pre-auth key with information to +// enable unattended bringup in the locked tailnet. +func (lc *Client) NetworkLockWrapPreauthKey(ctx context.Context, preauthKey string, tkaKey key.NLPrivate) (string, error) { + encodedPrivate, err := tkaKey.MarshalText() + if err != nil { + return "", err + } + + var b bytes.Buffer + type wrapRequest struct { + TSKey string + TKAKey string // key.NLPrivate.MarshalText + } + if err := json.NewEncoder(&b).Encode(wrapRequest{TSKey: preauthKey, TKAKey: string(encodedPrivate)}); err != nil { + return "", err + } + + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/wrap-preauth-key", 200, &b) + if err != nil { + return "", fmt.Errorf("error: %w", err) + } + return string(body), nil +} + +// NetworkLockModify adds and/or removes key(s) to the tailnet key authority. +func (lc *Client) NetworkLockModify(ctx context.Context, addKeys, removeKeys []tka.Key) error { + var b bytes.Buffer + type modifyRequest struct { + AddKeys []tka.Key + RemoveKeys []tka.Key + } + + if err := json.NewEncoder(&b).Encode(modifyRequest{AddKeys: addKeys, RemoveKeys: removeKeys}); err != nil { + return err + } + + if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/modify", 204, &b); err != nil { + return fmt.Errorf("error: %w", err) + } + return nil +} + +// NetworkLockSign signs the specified node-key and transmits that signature to the control plane. +// rotationPublic, if specified, must be an ed25519 public key. +func (lc *Client) NetworkLockSign(ctx context.Context, nodeKey key.NodePublic, rotationPublic []byte) error { + var b bytes.Buffer + type signRequest struct { + NodeKey key.NodePublic + RotationPublic []byte + } + + if err := json.NewEncoder(&b).Encode(signRequest{NodeKey: nodeKey, RotationPublic: rotationPublic}); err != nil { + return err + } + + if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/sign", 200, &b); err != nil { + return fmt.Errorf("error: %w", err) + } + return nil +} + +// NetworkLockAffectedSigs returns all signatures signed by the specified keyID. +func (lc *Client) NetworkLockAffectedSigs(ctx context.Context, keyID tkatype.KeyID) ([]tkatype.MarshaledSignature, error) { + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/affected-sigs", 200, bytes.NewReader(keyID)) + if err != nil { + return nil, fmt.Errorf("error: %w", err) + } + return decodeJSON[[]tkatype.MarshaledSignature](body) +} + +// NetworkLockLog returns up to maxEntries number of changes to network-lock state. +func (lc *Client) NetworkLockLog(ctx context.Context, maxEntries int) ([]ipnstate.NetworkLockUpdate, error) { + v := url.Values{} + v.Set("limit", fmt.Sprint(maxEntries)) + body, err := lc.send(ctx, "GET", "/localapi/v0/tka/log?"+v.Encode(), 200, nil) + if err != nil { + return nil, fmt.Errorf("error %w: %s", err, body) + } + return decodeJSON[[]ipnstate.NetworkLockUpdate](body) +} + +// NetworkLockForceLocalDisable forcibly shuts down network lock on this node. +func (lc *Client) NetworkLockForceLocalDisable(ctx context.Context) error { + // This endpoint expects an empty JSON stanza as the payload. + var b bytes.Buffer + if err := json.NewEncoder(&b).Encode(struct{}{}); err != nil { + return err + } + + if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/force-local-disable", 200, &b); err != nil { + return fmt.Errorf("error: %w", err) + } + return nil +} + +// NetworkLockVerifySigningDeeplink verifies the network lock deeplink contained +// in url and returns information extracted from it. +func (lc *Client) NetworkLockVerifySigningDeeplink(ctx context.Context, url string) (*tka.DeeplinkValidationResult, error) { + vr := struct { + URL string + }{url} + + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/verify-deeplink", 200, jsonBody(vr)) + if err != nil { + return nil, fmt.Errorf("sending verify-deeplink: %w", err) + } + + return decodeJSON[*tka.DeeplinkValidationResult](body) +} + +// NetworkLockGenRecoveryAUM generates an AUM for recovering from a tailnet-lock key compromise. +func (lc *Client) NetworkLockGenRecoveryAUM(ctx context.Context, removeKeys []tkatype.KeyID, forkFrom tka.AUMHash) ([]byte, error) { + vr := struct { + Keys []tkatype.KeyID + ForkFrom string + }{removeKeys, forkFrom.String()} + + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/generate-recovery-aum", 200, jsonBody(vr)) + if err != nil { + return nil, fmt.Errorf("sending generate-recovery-aum: %w", err) + } + + return body, nil +} + +// NetworkLockCosignRecoveryAUM co-signs a recovery AUM using the node's tailnet lock key. +func (lc *Client) NetworkLockCosignRecoveryAUM(ctx context.Context, aum tka.AUM) ([]byte, error) { + r := bytes.NewReader(aum.Serialize()) + body, err := lc.send(ctx, "POST", "/localapi/v0/tka/cosign-recovery-aum", 200, r) + if err != nil { + return nil, fmt.Errorf("sending cosign-recovery-aum: %w", err) + } + + return body, nil +} + +// NetworkLockSubmitRecoveryAUM submits a recovery AUM to the control plane. +func (lc *Client) NetworkLockSubmitRecoveryAUM(ctx context.Context, aum tka.AUM) error { + r := bytes.NewReader(aum.Serialize()) + _, err := lc.send(ctx, "POST", "/localapi/v0/tka/submit-recovery-aum", 200, r) + if err != nil { + return fmt.Errorf("sending cosign-recovery-aum: %w", err) + } + return nil +} + +// NetworkLockDisable shuts down network-lock across the tailnet. +func (lc *Client) NetworkLockDisable(ctx context.Context, secret []byte) error { + if _, err := lc.send(ctx, "POST", "/localapi/v0/tka/disable", 200, bytes.NewReader(secret)); err != nil { + return fmt.Errorf("error: %w", err) + } + return nil +} diff --git a/vendor/tailscale.com/client/tailscale/apitype/apitype.go b/vendor/tailscale.com/client/tailscale/apitype/apitype.go index 58cdcec..6d239d0 100644 --- a/vendor/tailscale.com/client/tailscale/apitype/apitype.go +++ b/vendor/tailscale.com/client/tailscale/apitype/apitype.go @@ -94,3 +94,13 @@ type DNSQueryResponse struct { // Resolvers is the list of resolvers that the forwarder deemed able to resolve the query. Resolvers []*dnstype.Resolver } + +// OptionalFeatures describes which optional features are enabled in the build. +type OptionalFeatures struct { + // Features is the map of optional feature names to whether they are + // enabled. + // + // Disabled features may be absent from the map. (That is, false values + // are not guaranteed to be present.) + Features map[string]bool +} diff --git a/vendor/tailscale.com/client/tailscale/apitype/controltype.go b/vendor/tailscale.com/client/tailscale/apitype/controltype.go index 9a623be..d9d79f0 100644 --- a/vendor/tailscale.com/client/tailscale/apitype/controltype.go +++ b/vendor/tailscale.com/client/tailscale/apitype/controltype.go @@ -3,17 +3,50 @@ package apitype +// DNSConfig is the DNS configuration for a tailnet +// used in /tailnet/{tailnet}/dns/config. type DNSConfig struct { - Resolvers []DNSResolver `json:"resolvers"` - FallbackResolvers []DNSResolver `json:"fallbackResolvers"` - Routes map[string][]DNSResolver `json:"routes"` - Domains []string `json:"domains"` - Nameservers []string `json:"nameservers"` - Proxied bool `json:"proxied"` - TempCorpIssue13969 string `json:"TempCorpIssue13969,omitempty"` + // Resolvers are the global DNS resolvers to use + // overriding the local OS configuration. + Resolvers []DNSResolver `json:"resolvers"` + + // FallbackResolvers are used as global resolvers when + // the client is unable to determine the OS's preferred DNS servers. + FallbackResolvers []DNSResolver `json:"fallbackResolvers"` + + // Routes map DNS name suffixes to a set of DNS resolvers, + // used for Split DNS and other advanced routing overlays. + Routes map[string][]DNSResolver `json:"routes"` + + // Domains are the search domains to use. + Domains []string `json:"domains"` + + // Proxied means MagicDNS is enabled. + Proxied bool `json:"proxied"` + + // TempCorpIssue13969 is from an internal hack day prototype, + // See tailscale/corp#13969. + TempCorpIssue13969 string `json:"TempCorpIssue13969,omitempty"` + + // Nameservers are the IP addresses of global nameservers to use. + // This is a deprecated format but may still be found in tailnets + // that were configured a long time ago. When making updates, + // set Resolvers and leave Nameservers empty. + Nameservers []string `json:"nameservers"` } +// DNSResolver is a DNS resolver in a DNS configuration. type DNSResolver struct { - Addr string `json:"addr"` + // Addr is the address of the DNS resolver. + // It is usually an IP address or a DoH URL. + // See dnstype.Resolver.Addr for full details. + Addr string `json:"addr"` + + // BootstrapResolution is an optional suggested resolution for + // the DoT/DoH resolver. BootstrapResolution []string `json:"bootstrapResolution,omitempty"` + + // UseWithExitNode signals this resolver should be used + // even when a tailscale exit node is configured on a device. + UseWithExitNode bool `json:"useWithExitNode,omitempty"` } diff --git a/vendor/tailscale.com/client/tailscale/cert.go b/vendor/tailscale.com/client/tailscale/cert.go new file mode 100644 index 0000000..4f351ab --- /dev/null +++ b/vendor/tailscale.com/client/tailscale/cert.go @@ -0,0 +1,34 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !js && !ts_omit_acme + +package tailscale + +import ( + "context" + "crypto/tls" + + "tailscale.com/client/local" +) + +// GetCertificate is an alias for [tailscale.com/client/local.GetCertificate]. +// +// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.GetCertificate]. +func GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { + return local.GetCertificate(hi) +} + +// CertPair is an alias for [tailscale.com/client/local.CertPair]. +// +// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.CertPair]. +func CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { + return local.CertPair(ctx, domain) +} + +// ExpandSNIName is an alias for [tailscale.com/client/local.ExpandSNIName]. +// +// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.ExpandSNIName]. +func ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { + return local.ExpandSNIName(ctx, name) +} diff --git a/vendor/tailscale.com/client/tailscale/localclient_aliases.go b/vendor/tailscale.com/client/tailscale/localclient_aliases.go index 28d5972..e3492e8 100644 --- a/vendor/tailscale.com/client/tailscale/localclient_aliases.go +++ b/vendor/tailscale.com/client/tailscale/localclient_aliases.go @@ -5,102 +5,75 @@ package tailscale import ( "context" - "crypto/tls" "tailscale.com/client/local" "tailscale.com/client/tailscale/apitype" "tailscale.com/ipn/ipnstate" ) -// ErrPeerNotFound is an alias for tailscale.com/client/local. +// ErrPeerNotFound is an alias for [tailscale.com/client/local.ErrPeerNotFound]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. var ErrPeerNotFound = local.ErrPeerNotFound -// LocalClient is an alias for tailscale.com/client/local. +// LocalClient is an alias for [tailscale.com/client/local.Client]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. type LocalClient = local.Client -// IPNBusWatcher is an alias for tailscale.com/client/local. +// IPNBusWatcher is an alias for [tailscale.com/client/local.IPNBusWatcher]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. type IPNBusWatcher = local.IPNBusWatcher -// BugReportOpts is an alias for tailscale.com/client/local. +// BugReportOpts is an alias for [tailscale.com/client/local.BugReportOpts]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. type BugReportOpts = local.BugReportOpts -// DebugPortMapOpts is an alias for tailscale.com/client/local. +// PingOpts is an alias for [tailscale.com/client/local.PingOpts]. // -// Deprecated: import tailscale.com/client/local instead. -type DebugPortmapOpts = local.DebugPortmapOpts - -// PingOpts is an alias for tailscale.com/client/local. -// -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. type PingOpts = local.PingOpts -// GetCertificate is an alias for tailscale.com/client/local. +// SetVersionMismatchHandler is an alias for [tailscale.com/client/local.SetVersionMismatchHandler]. // -// Deprecated: import tailscale.com/client/local instead. -func GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { - return local.GetCertificate(hi) -} - -// SetVersionMismatchHandler is an alias for tailscale.com/client/local. -// -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. func SetVersionMismatchHandler(f func(clientVer, serverVer string)) { local.SetVersionMismatchHandler(f) } -// IsAccessDeniedError is an alias for tailscale.com/client/local. +// IsAccessDeniedError is an alias for [tailscale.com/client/local.IsAccessDeniedError]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. func IsAccessDeniedError(err error) bool { return local.IsAccessDeniedError(err) } -// IsPreconditionsFailedError is an alias for tailscale.com/client/local. +// IsPreconditionsFailedError is an alias for [tailscale.com/client/local.IsPreconditionsFailedError]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. func IsPreconditionsFailedError(err error) bool { return local.IsPreconditionsFailedError(err) } -// WhoIs is an alias for tailscale.com/client/local. +// WhoIs is an alias for [tailscale.com/client/local.WhoIs]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.WhoIs]. func WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsResponse, error) { return local.WhoIs(ctx, remoteAddr) } -// Status is an alias for tailscale.com/client/local. +// Status is an alias for [tailscale.com/client/local.Status]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. func Status(ctx context.Context) (*ipnstate.Status, error) { return local.Status(ctx) } -// StatusWithoutPeers is an alias for tailscale.com/client/local. +// StatusWithoutPeers is an alias for [tailscale.com/client/local.StatusWithoutPeers]. // -// Deprecated: import tailscale.com/client/local instead. +// Deprecated: import [tailscale.com/client/local] instead. func StatusWithoutPeers(ctx context.Context) (*ipnstate.Status, error) { return local.StatusWithoutPeers(ctx) } - -// CertPair is an alias for tailscale.com/client/local. -// -// Deprecated: import tailscale.com/client/local instead. -func CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) { - return local.CertPair(ctx, domain) -} - -// ExpandSNIName is an alias for tailscale.com/client/local. -// -// Deprecated: import tailscale.com/client/local instead. -func ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) { - return local.ExpandSNIName(ctx, name) -} diff --git a/vendor/tailscale.com/client/tailscale/tailscale.go b/vendor/tailscale.com/client/tailscale/tailscale.go index 4c6273c..76e4445 100644 --- a/vendor/tailscale.com/client/tailscale/tailscale.go +++ b/vendor/tailscale.com/client/tailscale/tailscale.go @@ -8,7 +8,7 @@ // This package is only intended for internal and transitional use. // // Deprecated: the official control plane client is available at -// tailscale.com/client/tailscale/v2. +// [tailscale.com/client/tailscale/v2]. package tailscale import ( @@ -22,7 +22,7 @@ import ( ) // I_Acknowledge_This_API_Is_Unstable must be set true to use this package -// for now. This package is being replaced by tailscale.com/client/tailscale/v2. +// for now. This package is being replaced by [tailscale.com/client/tailscale/v2]. var I_Acknowledge_This_API_Is_Unstable = false // TODO: use url.PathEscape() for deviceID and tailnets when constructing requests. @@ -34,10 +34,10 @@ const maxReadSize = 10 << 20 // Client makes API calls to the Tailscale control plane API server. // -// Use NewClient to instantiate one. Exported fields should be set before +// Use [NewClient] to instantiate one. Exported fields should be set before // the client is used and not changed thereafter. // -// Deprecated: use tailscale.com/client/tailscale/v2 instead. +// Deprecated: use [tailscale.com/client/tailscale/v2] instead. type Client struct { // tailnet is the globally unique identifier for a Tailscale network, such // as "example.com" or "user@gmail.com". @@ -51,7 +51,7 @@ type Client struct { BaseURL string // HTTPClient optionally specifies an alternate HTTP client to use. - // If nil, http.DefaultClient is used. + // If nil, [http.DefaultClient] is used. HTTPClient *http.Client // UserAgent optionally specifies an alternate User-Agent header @@ -119,7 +119,7 @@ type AuthMethod interface { modifyRequest(req *http.Request) } -// APIKey is an AuthMethod for NewClient that authenticates requests +// APIKey is an [AuthMethod] for [NewClient] that authenticates requests // using an authkey. type APIKey string @@ -133,15 +133,15 @@ func (c *Client) setAuth(r *http.Request) { } } -// NewClient is a convenience method for instantiating a new Client. +// NewClient is a convenience method for instantiating a new [Client]. // // tailnet is the globally unique identifier for a Tailscale network, such // as "example.com" or "user@gmail.com". -// If httpClient is nil, then http.DefaultClient is used. +// If httpClient is nil, then [http.DefaultClient] is used. // "api.tailscale.com" is set as the BaseURL for the returned client // and can be changed manually by the user. // -// Deprecated: use tailscale.com/client/tailscale/v2 instead. +// Deprecated: use [tailscale.com/client/tailscale/v2] instead. func NewClient(tailnet string, auth AuthMethod) *Client { return &Client{ tailnet: tailnet, @@ -193,9 +193,9 @@ func (e ErrResponse) Error() string { } // HandleErrorResponse decodes the error message from the server and returns -// an ErrResponse from it. +// an [ErrResponse] from it. // -// Deprecated: use tailscale.com/client/tailscale/v2 instead. +// Deprecated: use [tailscale.com/client/tailscale/v2] instead. func HandleErrorResponse(b []byte, resp *http.Response) error { var errResp ErrResponse if err := json.Unmarshal(b, &errResp); err != nil { diff --git a/vendor/tailscale.com/client/web/auth.go b/vendor/tailscale.com/client/web/auth.go index 8b195a4..27eb24e 100644 --- a/vendor/tailscale.com/client/web/auth.go +++ b/vendor/tailscale.com/client/web/auth.go @@ -192,7 +192,7 @@ func (s *Server) controlSupportsCheckMode(ctx context.Context) bool { if err != nil { return true } - controlURL, err := url.Parse(prefs.ControlURLOrDefault()) + controlURL, err := url.Parse(prefs.ControlURLOrDefault(s.polc)) if err != nil { return true } diff --git a/vendor/tailscale.com/client/web/package.json b/vendor/tailscale.com/client/web/package.json index 4b3afb1..c733b0d 100644 --- a/vendor/tailscale.com/client/web/package.json +++ b/vendor/tailscale.com/client/web/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "license": "BSD-3-Clause", "engines": { - "node": "18.20.4", + "node": "22.14.0", "yarn": "1.22.19" }, "type": "module", @@ -20,7 +20,7 @@ "zustand": "^4.4.7" }, "devDependencies": { - "@types/node": "^18.16.1", + "@types/node": "^22.14.0", "@types/react": "^18.0.20", "@types/react-dom": "^18.0.6", "@vitejs/plugin-react-swc": "^3.6.0", @@ -34,10 +34,10 @@ "prettier-plugin-organize-imports": "^3.2.2", "tailwindcss": "^3.3.3", "typescript": "^5.3.3", - "vite": "^5.1.7", + "vite": "^5.4.21", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^3.5.0", - "vitest": "^1.3.1" + "vitest": "^1.6.1" }, "resolutions": { "@typescript-eslint/eslint-plugin": "^6.2.1", diff --git a/vendor/tailscale.com/client/web/web.go b/vendor/tailscale.com/client/web/web.go index 6eccdad..dbd3d5d 100644 --- a/vendor/tailscale.com/client/web/web.go +++ b/vendor/tailscale.com/client/web/web.go @@ -5,8 +5,8 @@ package web import ( + "cmp" "context" - "crypto/rand" "encoding/json" "errors" "fmt" @@ -14,19 +14,20 @@ import ( "log" "net/http" "net/netip" + "net/url" "os" "path" - "path/filepath" + "slices" "strings" "sync" "time" - "github.com/gorilla/csrf" "tailscale.com/client/local" "tailscale.com/client/tailscale/apitype" - "tailscale.com/clientupdate" "tailscale.com/envknob" "tailscale.com/envknob/featureknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/hostinfo" "tailscale.com/ipn" "tailscale.com/ipn/ipnstate" @@ -37,6 +38,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/views" "tailscale.com/util/httpm" + "tailscale.com/util/syspolicy/policyclient" "tailscale.com/version" "tailscale.com/version/distro" ) @@ -50,6 +52,7 @@ type Server struct { mode ServerMode logf logger.Logf + polc policyclient.Client // must be non-nil lc *local.Client timeNow func() time.Time @@ -60,6 +63,12 @@ type Server struct { cgiMode bool pathPrefix string + // originOverride is the origin that the web UI is accessible from. + // This value is used in the fallback CSRF checks when Sec-Fetch-Site is not + // available. In this case the application will compare Host and Origin + // header values to determine if the request is from the same origin. + originOverride string + apiHandler http.Handler // serves api endpoints; csrf-protected assetsHandler http.Handler // serves frontend assets assetsCleanup func() // called from Server.Shutdown @@ -134,9 +143,13 @@ type ServerOpts struct { TimeNow func() time.Time // Logf optionally provides a logger function. - // log.Printf is used as default. + // If nil, log.Printf is used as default. Logf logger.Logf + // PolicyClient, if non-nil, will be used to fetch policy settings. + // If nil, the default policy client will be used. + PolicyClient policyclient.Client + // The following two fields are required and used exclusively // in ManageServerMode to facilitate the control server login // check step for authorizing browser sessions. @@ -150,6 +163,9 @@ type ServerOpts struct { // as completed. // This field is required for ManageServerMode mode. WaitAuthURL func(ctx context.Context, id string, src tailcfg.NodeID) (*tailcfg.WebClientAuthResponse, error) + + // OriginOverride specifies the origin that the web UI will be accessible from if hosted behind a reverse proxy or CGI. + OriginOverride string } // NewServer constructs a new Tailscale web client server. @@ -169,15 +185,17 @@ func NewServer(opts ServerOpts) (s *Server, err error) { opts.LocalClient = &local.Client{} } s = &Server{ - mode: opts.Mode, - logf: opts.Logf, - devMode: envknob.Bool("TS_DEBUG_WEB_CLIENT_DEV"), - lc: opts.LocalClient, - cgiMode: opts.CGIMode, - pathPrefix: opts.PathPrefix, - timeNow: opts.TimeNow, - newAuthURL: opts.NewAuthURL, - waitAuthURL: opts.WaitAuthURL, + mode: opts.Mode, + polc: cmp.Or(opts.PolicyClient, policyclient.Get()), + logf: opts.Logf, + devMode: envknob.Bool("TS_DEBUG_WEB_CLIENT_DEV"), + lc: opts.LocalClient, + cgiMode: opts.CGIMode, + pathPrefix: opts.PathPrefix, + timeNow: opts.TimeNow, + newAuthURL: opts.NewAuthURL, + waitAuthURL: opts.WaitAuthURL, + originOverride: opts.OriginOverride, } if opts.PathPrefix != "" { // Enforce that path prefix always has a single leading '/' @@ -205,7 +223,7 @@ func NewServer(opts ServerOpts) (s *Server, err error) { var metric string s.apiHandler, metric = s.modeAPIHandler(s.mode) - s.apiHandler = s.withCSRF(s.apiHandler) + s.apiHandler = s.csrfProtect(s.apiHandler) // Don't block startup on reporting metric. // Report in separate go routine with 5 second timeout. @@ -218,23 +236,64 @@ func NewServer(opts ServerOpts) (s *Server, err error) { return s, nil } -func (s *Server) withCSRF(h http.Handler) http.Handler { - csrfProtect := csrf.Protect(s.csrfKey(), csrf.Secure(false)) - - // ref https://github.com/tailscale/tailscale/pull/14822 - // signal to the CSRF middleware that the request is being served over - // plaintext HTTP to skip TLS-only header checks. - withSetPlaintext := func(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r = csrf.PlaintextHTTPRequest(r) +func (s *Server) csrfProtect(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // CSRF is not required for GET, HEAD, or OPTIONS requests. + if slices.Contains([]string{"GET", "HEAD", "OPTIONS"}, r.Method) { h.ServeHTTP(w, r) - }) - } + return + } - // NB: the order of the withSetPlaintext and csrfProtect calls is important - // to ensure that we signal to the CSRF middleware that the request is being - // served over plaintext HTTP and not over TLS as it presumes by default. - return withSetPlaintext(csrfProtect(h)) + // first attempt to use Sec-Fetch-Site header (sent by all modern + // browsers to "potentially trustworthy" origins i.e. localhost or those + // served over HTTPS) + secFetchSite := r.Header.Get("Sec-Fetch-Site") + if secFetchSite == "same-origin" { + h.ServeHTTP(w, r) + return + } else if secFetchSite != "" { + http.Error(w, fmt.Sprintf("CSRF request denied with Sec-Fetch-Site %q", secFetchSite), http.StatusForbidden) + return + } + + // if Sec-Fetch-Site is not available we presume we are operating over HTTP. + // We fall back to comparing the Origin & Host headers. + + // use the Host header to determine the expected origin + // (use the override if set to allow for reverse proxying) + host := r.Host + if host == "" { + http.Error(w, "CSRF request denied with no Host header", http.StatusForbidden) + return + } + if s.originOverride != "" { + host = s.originOverride + } + + originHeader := r.Header.Get("Origin") + if originHeader == "" { + http.Error(w, "CSRF request denied with no Origin header", http.StatusForbidden) + return + } + parsedOrigin, err := url.Parse(originHeader) + if err != nil { + http.Error(w, fmt.Sprintf("CSRF request denied with invalid Origin %q", r.Header.Get("Origin")), http.StatusForbidden) + return + } + origin := parsedOrigin.Host + if origin == "" { + http.Error(w, "CSRF request denied with no host in the Origin header", http.StatusForbidden) + return + } + + if origin != host { + http.Error(w, fmt.Sprintf("CSRF request denied with mismatched Origin %q and Host %q", origin, host), http.StatusForbidden) + return + } + + h.ServeHTTP(w, r) + + }) } func (s *Server) modeAPIHandler(mode ServerMode) (http.Handler, string) { @@ -438,6 +497,10 @@ func (s *Server) authorizeRequest(w http.ResponseWriter, r *http.Request) (ok bo // Client using system-specific auth. switch distro.Get() { case distro.Synology: + if !buildfeatures.HasSynology { + // Synology support not built in. + return false + } authorized, _ := authorizeSynology(r) return authorized case distro.QNAP: @@ -452,7 +515,6 @@ func (s *Server) authorizeRequest(w http.ResponseWriter, r *http.Request) (ok bo // It should only be called by Server.ServeHTTP, via Server.apiHandler, // which protects the handler using gorilla csrf. func (s *Server) serveLoginAPI(w http.ResponseWriter, r *http.Request) { - w.Header().Set("X-CSRF-Token", csrf.Token(r)) switch { case r.URL.Path == "/api/data" && r.Method == httpm.GET: s.serveGetNodeData(w, r) @@ -575,7 +637,6 @@ func (s *Server) serveAPI(w http.ResponseWriter, r *http.Request) { } } - w.Header().Set("X-CSRF-Token", csrf.Token(r)) path := strings.TrimPrefix(r.URL.Path, "/api") switch { case path == "/data" && r.Method == httpm.GET: @@ -902,7 +963,7 @@ func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) { UnraidToken: os.Getenv("UNRAID_CSRF_TOKEN"), RunningSSHServer: prefs.RunSSH, URLPrefix: strings.TrimSuffix(s.pathPrefix, "/"), - ControlAdminURL: prefs.AdminPageURL(), + ControlAdminURL: prefs.AdminPageURL(s.polc), LicensesURL: licenses.LicensesURL(), Features: availableFeatures(), @@ -922,9 +983,18 @@ func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) { data.ClientVersion = cv } - if st.CurrentTailnet != nil { - data.TailnetName = st.CurrentTailnet.MagicDNSSuffix - data.DomainName = st.CurrentTailnet.Name + profile, _, err := s.lc.ProfileStatus(r.Context()) + if err != nil { + s.logf("error fetching profiles: %v", err) + // If for some reason we can't fetch profiles, + // continue to use st.CurrentTailnet if set. + if st.CurrentTailnet != nil { + data.TailnetName = st.CurrentTailnet.MagicDNSSuffix + data.DomainName = st.CurrentTailnet.Name + } + } else { + data.TailnetName = profile.NetworkProfile.MagicDNSName + data.DomainName = profile.NetworkProfile.DisplayNameOrDefault() } if st.Self.Tags != nil { data.Tags = st.Self.Tags.AsSlice() @@ -984,7 +1054,7 @@ func availableFeatures() map[string]bool { "advertise-routes": true, // available on all platforms "use-exit-node": featureknob.CanUseExitNode() == nil, "ssh": featureknob.CanRunTailscaleSSH() == nil, - "auto-update": version.IsUnstableBuild() && clientupdate.CanAutoUpdate(), + "auto-update": version.IsUnstableBuild() && feature.CanAutoUpdate(), } return features } @@ -1276,37 +1346,6 @@ func (s *Server) proxyRequestToLocalAPI(w http.ResponseWriter, r *http.Request) } } -// csrfKey returns a key that can be used for CSRF protection. -// If an error occurs during key creation, the error is logged and the active process terminated. -// If the server is running in CGI mode, the key is cached to disk and reused between requests. -// If an error occurs during key storage, the error is logged and the active process terminated. -func (s *Server) csrfKey() []byte { - csrfFile := filepath.Join(os.TempDir(), "tailscale-web-csrf.key") - - // if running in CGI mode, try to read from disk, but ignore errors - if s.cgiMode { - key, _ := os.ReadFile(csrfFile) - if len(key) == 32 { - return key - } - } - - // create a new key - key := make([]byte, 32) - if _, err := rand.Read(key); err != nil { - log.Fatalf("error generating CSRF key: %v", err) - } - - // if running in CGI mode, try to write the newly created key to disk, and exit if it fails. - if s.cgiMode { - if err := os.WriteFile(csrfFile, key, 0600); err != nil { - log.Fatalf("unable to store CSRF key: %v", err) - } - } - - return key -} - // enforcePrefix returns a HandlerFunc that enforces a given path prefix is used in requests, // then strips it before invoking h. // Unlike http.StripPrefix, it does not return a 404 if the prefix is not present. diff --git a/vendor/tailscale.com/client/web/yarn.lock b/vendor/tailscale.com/client/web/yarn.lock index 2c8fca5..e8e5f5b 100644 --- a/vendor/tailscale.com/client/web/yarn.lock +++ b/vendor/tailscale.com/client/web/yarn.lock @@ -1087,11 +1087,9 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e" - integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg== - dependencies: - regenerator-runtime "^0.14.0" + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.2.tgz#2ae5a9d51cc583bd1f5673b3bb70d6d819682473" + integrity sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA== "@babel/template@^7.22.15": version "7.22.15" @@ -1132,120 +1130,120 @@ resolved "https://registry.yarnpkg.com/@cush/relative/-/relative-1.0.0.tgz#8cd1769bf9bde3bb27dac356b1bc94af40f6cc16" integrity sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA== -"@esbuild/aix-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" - integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== -"@esbuild/android-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" - integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== -"@esbuild/android-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" - integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== -"@esbuild/android-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" - integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== -"@esbuild/darwin-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" - integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== -"@esbuild/darwin-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" - integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== -"@esbuild/freebsd-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" - integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== -"@esbuild/freebsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" - integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== -"@esbuild/linux-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" - integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== -"@esbuild/linux-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" - integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== -"@esbuild/linux-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" - integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== -"@esbuild/linux-loong64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" - integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== -"@esbuild/linux-mips64el@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" - integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== -"@esbuild/linux-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" - integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== -"@esbuild/linux-riscv64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" - integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== -"@esbuild/linux-s390x@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" - integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== -"@esbuild/linux-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" - integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== -"@esbuild/netbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" - integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== -"@esbuild/openbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" - integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== -"@esbuild/sunos-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" - integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== -"@esbuild/win32-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" - integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== -"@esbuild/win32-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" - integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== -"@esbuild/win32-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" - integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -1628,70 +1626,115 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@rollup/rollup-android-arm-eabi@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz#38c3abd1955a3c21d492af6b1a1dca4bb1d894d6" - integrity sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w== +"@rollup/rollup-android-arm-eabi@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz#0f44a2f8668ed87b040b6fe659358ac9239da4db" + integrity sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ== -"@rollup/rollup-android-arm64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz#3822e929f415627609e53b11cec9a4be806de0e2" - integrity sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ== +"@rollup/rollup-android-arm64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz#25b9a01deef6518a948431564c987bcb205274f5" + integrity sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA== -"@rollup/rollup-darwin-arm64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz#6c082de71f481f57df6cfa3701ab2a7afde96f69" - integrity sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ== +"@rollup/rollup-darwin-arm64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz#8a102869c88f3780c7d5e6776afd3f19084ecd7f" + integrity sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA== -"@rollup/rollup-darwin-x64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz#c34ca0d31f3c46a22c9afa0e944403eea0edcfd8" - integrity sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg== +"@rollup/rollup-darwin-x64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz#8e526417cd6f54daf1d0c04cf361160216581956" + integrity sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA== -"@rollup/rollup-linux-arm-gnueabihf@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz#48e899c1e438629c072889b824a98787a7c2362d" - integrity sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA== +"@rollup/rollup-freebsd-arm64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz#0e7027054493f3409b1f219a3eac5efd128ef899" + integrity sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA== -"@rollup/rollup-linux-arm64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz#788c2698a119dc229062d40da6ada8a090a73a68" - integrity sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA== +"@rollup/rollup-freebsd-x64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz#72b204a920139e9ec3d331bd9cfd9a0c248ccb10" + integrity sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ== -"@rollup/rollup-linux-arm64-musl@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz#3882a4e3a564af9e55804beeb67076857b035ab7" - integrity sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ== +"@rollup/rollup-linux-arm-gnueabihf@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz#ab1b522ebe5b7e06c99504cc38f6cd8b808ba41c" + integrity sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ== -"@rollup/rollup-linux-riscv64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz#0c6ad792e1195c12bfae634425a3d2aa0fe93ab7" - integrity sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw== +"@rollup/rollup-linux-arm-musleabihf@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz#f8cc30b638f1ee7e3d18eac24af47ea29d9beb00" + integrity sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ== -"@rollup/rollup-linux-x64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz#9d62485ea0f18d8674033b57aa14fb758f6ec6e3" - integrity sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA== +"@rollup/rollup-linux-arm64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz#7af37a9e85f25db59dc8214172907b7e146c12cc" + integrity sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg== -"@rollup/rollup-linux-x64-musl@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz#50e8167e28b33c977c1f813def2b2074d1435e05" - integrity sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw== +"@rollup/rollup-linux-arm64-musl@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz#a623eb0d3617c03b7a73716eb85c6e37b776f7e0" + integrity sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q== -"@rollup/rollup-win32-arm64-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz#68d233272a2004429124494121a42c4aebdc5b8e" - integrity sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw== +"@rollup/rollup-linux-loong64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz#76ea038b549c5c6c5f0d062942627c4066642ee2" + integrity sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA== -"@rollup/rollup-win32-ia32-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz#366ca62221d1689e3b55a03f4ae12ae9ba595d40" - integrity sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA== +"@rollup/rollup-linux-ppc64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz#d9a4c3f0a3492bc78f6fdfe8131ac61c7359ccd5" + integrity sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw== -"@rollup/rollup-win32-x64-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz#9ffdf9ed133a7464f4ae187eb9e1294413fab235" - integrity sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg== +"@rollup/rollup-linux-riscv64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz#87ab033eebd1a9a1dd7b60509f6333ec1f82d994" + integrity sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw== + +"@rollup/rollup-linux-riscv64-musl@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz#bda3eb67e1c993c1ba12bc9c2f694e7703958d9f" + integrity sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg== + +"@rollup/rollup-linux-s390x-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz#f7bc10fbe096ab44694233dc42a2291ed5453d4b" + integrity sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ== + +"@rollup/rollup-linux-x64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz#a151cb1234cc9b2cf5e8cfc02aa91436b8f9e278" + integrity sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q== + +"@rollup/rollup-linux-x64-musl@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz#7859e196501cc3b3062d45d2776cfb4d2f3a9350" + integrity sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg== + +"@rollup/rollup-openharmony-arm64@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz#85d0df7233734df31e547c1e647d2a5300b3bf30" + integrity sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw== + +"@rollup/rollup-win32-arm64-msvc@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz#e62357d00458db17277b88adbf690bb855cac937" + integrity sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w== + +"@rollup/rollup-win32-ia32-msvc@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz#fc7cd40f44834a703c1f1c3fe8bcc27ce476cd50" + integrity sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg== + +"@rollup/rollup-win32-x64-gnu@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz#1a22acfc93c64a64a48c42672e857ee51774d0d3" + integrity sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ== + +"@rollup/rollup-win32-x64-msvc@4.52.5": + version "4.52.5" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz#1657f56326bbe0ac80eedc9f9c18fc1ddd24e107" + integrity sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg== "@rushstack/eslint-patch@^1.1.0": version "1.6.0" @@ -1865,7 +1908,12 @@ resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== -"@types/estree@1.0.5", "@types/estree@^1.0.0": +"@types/estree@1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -1880,12 +1928,12 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/node@^18.16.1": - version "18.19.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.18.tgz#7526471b28828d1fef1f7e4960fb9477e6e4369c" - integrity sha512-80CP7B8y4PzZF0GWx15/gVWRrB5y/bIjNI84NK3cmQJu0WZwvmj2WMA5LcofQFVfLqqCSp545+U2LsrVzX36Zg== +"@types/node@^22.14.0": + version "22.14.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.14.0.tgz#d3bfa3936fef0dbacd79ea3eb17d521c628bb47e" + integrity sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA== dependencies: - undici-types "~5.26.4" + undici-types "~6.21.0" "@types/parse-json@^4.0.0": version "4.0.2" @@ -2076,44 +2124,44 @@ dependencies: "@swc/core" "^1.3.107" -"@vitest/expect@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.3.1.tgz#d4c14b89c43a25fd400a6b941f51ba27fe0cb918" - integrity sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw== +"@vitest/expect@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.6.1.tgz#b90c213f587514a99ac0bf84f88cff9042b0f14d" + integrity sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog== dependencies: - "@vitest/spy" "1.3.1" - "@vitest/utils" "1.3.1" + "@vitest/spy" "1.6.1" + "@vitest/utils" "1.6.1" chai "^4.3.10" -"@vitest/runner@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.3.1.tgz#e7f96cdf74842934782bfd310eef4b8695bbfa30" - integrity sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg== +"@vitest/runner@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.6.1.tgz#10f5857c3e376218d58c2bfacfea1161e27e117f" + integrity sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA== dependencies: - "@vitest/utils" "1.3.1" + "@vitest/utils" "1.6.1" p-limit "^5.0.0" pathe "^1.1.1" -"@vitest/snapshot@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.3.1.tgz#193a5d7febf6ec5d22b3f8c5a093f9e4322e7a88" - integrity sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ== +"@vitest/snapshot@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.6.1.tgz#90414451a634bb36cd539ccb29ae0d048a8c0479" + integrity sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ== dependencies: magic-string "^0.30.5" pathe "^1.1.1" pretty-format "^29.7.0" -"@vitest/spy@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" - integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== +"@vitest/spy@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.6.1.tgz#33376be38a5ed1ecd829eb986edaecc3e798c95d" + integrity sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw== dependencies: tinyspy "^2.2.0" -"@vitest/utils@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.3.1.tgz#7b05838654557544f694a372de767fcc9594d61a" - integrity sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ== +"@vitest/utils@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.6.1.tgz#6d2f36cb6d866f2bbf59da854a324d6bf8040f17" + integrity sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g== dependencies: diff-sequences "^29.6.3" estree-walker "^3.0.3" @@ -2429,11 +2477,11 @@ brace-expansion@^2.0.1: balanced-match "^1.0.0" braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" browserslist@^4.21.10, browserslist@^4.21.9, browserslist@^4.22.1: version "4.22.1" @@ -2450,6 +2498,14 @@ cac@^6.7.14: resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -2621,9 +2677,9 @@ cosmiconfig@^8.1.3: path-type "^4.0.0" cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -2767,6 +2823,15 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + electron-to-chromium@^1.4.535: version "1.4.596" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.596.tgz#6752d1aa795d942d49dfc5d3764d6ea283fab1d7" @@ -2834,6 +2899,16 @@ es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.13" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" @@ -2854,6 +2929,13 @@ es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: iterator.prototype "^1.1.2" safe-array-concat "^1.0.1" +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + es-set-tostringtag@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" @@ -2863,6 +2945,16 @@ es-set-tostringtag@^2.0.1: has-tostringtag "^1.0.0" hasown "^2.0.0" +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + es-shim-unscopables@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" @@ -2879,34 +2971,34 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@^0.19.3: - version "0.19.12" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" - integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== optionalDependencies: - "@esbuild/aix-ppc64" "0.19.12" - "@esbuild/android-arm" "0.19.12" - "@esbuild/android-arm64" "0.19.12" - "@esbuild/android-x64" "0.19.12" - "@esbuild/darwin-arm64" "0.19.12" - "@esbuild/darwin-x64" "0.19.12" - "@esbuild/freebsd-arm64" "0.19.12" - "@esbuild/freebsd-x64" "0.19.12" - "@esbuild/linux-arm" "0.19.12" - "@esbuild/linux-arm64" "0.19.12" - "@esbuild/linux-ia32" "0.19.12" - "@esbuild/linux-loong64" "0.19.12" - "@esbuild/linux-mips64el" "0.19.12" - "@esbuild/linux-ppc64" "0.19.12" - "@esbuild/linux-riscv64" "0.19.12" - "@esbuild/linux-s390x" "0.19.12" - "@esbuild/linux-x64" "0.19.12" - "@esbuild/netbsd-x64" "0.19.12" - "@esbuild/openbsd-x64" "0.19.12" - "@esbuild/sunos-x64" "0.19.12" - "@esbuild/win32-arm64" "0.19.12" - "@esbuild/win32-ia32" "0.19.12" - "@esbuild/win32-x64" "0.19.12" + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" escalade@^3.1.1: version "3.1.1" @@ -3233,10 +3325,10 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -3270,12 +3362,14 @@ for-each@^0.3.3: is-callable "^1.1.3" form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + version "4.0.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4" + integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" mime-types "^2.1.12" fraction.js@^4.2.0: @@ -3333,11 +3427,35 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-nonce@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stream@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" @@ -3437,6 +3555,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -3474,6 +3597,11 @@ has-symbols@^1.0.2, has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -3481,6 +3609,13 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + hasown@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" @@ -3488,6 +3623,13 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + html-encoding-sniffer@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448" @@ -3793,9 +3935,9 @@ js-tokens@^8.0.2: integrity sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw== js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== dependencies: argparse "^2.0.1" @@ -3992,6 +4134,11 @@ magic-string@^0.30.5: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -4075,10 +4222,10 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== natural-compare@^1.4.0: version "1.4.0" @@ -4306,10 +4453,10 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.0, picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -4379,14 +4526,14 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.35: - version "8.4.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" - integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== +postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.43: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.0.2" + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" prelude-ls@^1.2.1: version "1.2.1" @@ -4543,11 +4690,6 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== - regenerator-transform@^0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" @@ -4623,26 +4765,35 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@^4.2.0: - version "4.12.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.12.0.tgz#0b6d1e5f3d46bbcf244deec41a7421dc54cc45b5" - integrity sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q== +rollup@^4.20.0: + version "4.52.5" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.5.tgz#96982cdcaedcdd51b12359981f240f94304ec235" + integrity sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw== dependencies: - "@types/estree" "1.0.5" + "@types/estree" "1.0.8" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.12.0" - "@rollup/rollup-android-arm64" "4.12.0" - "@rollup/rollup-darwin-arm64" "4.12.0" - "@rollup/rollup-darwin-x64" "4.12.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.12.0" - "@rollup/rollup-linux-arm64-gnu" "4.12.0" - "@rollup/rollup-linux-arm64-musl" "4.12.0" - "@rollup/rollup-linux-riscv64-gnu" "4.12.0" - "@rollup/rollup-linux-x64-gnu" "4.12.0" - "@rollup/rollup-linux-x64-musl" "4.12.0" - "@rollup/rollup-win32-arm64-msvc" "4.12.0" - "@rollup/rollup-win32-ia32-msvc" "4.12.0" - "@rollup/rollup-win32-x64-msvc" "4.12.0" + "@rollup/rollup-android-arm-eabi" "4.52.5" + "@rollup/rollup-android-arm64" "4.52.5" + "@rollup/rollup-darwin-arm64" "4.52.5" + "@rollup/rollup-darwin-x64" "4.52.5" + "@rollup/rollup-freebsd-arm64" "4.52.5" + "@rollup/rollup-freebsd-x64" "4.52.5" + "@rollup/rollup-linux-arm-gnueabihf" "4.52.5" + "@rollup/rollup-linux-arm-musleabihf" "4.52.5" + "@rollup/rollup-linux-arm64-gnu" "4.52.5" + "@rollup/rollup-linux-arm64-musl" "4.52.5" + "@rollup/rollup-linux-loong64-gnu" "4.52.5" + "@rollup/rollup-linux-ppc64-gnu" "4.52.5" + "@rollup/rollup-linux-riscv64-gnu" "4.52.5" + "@rollup/rollup-linux-riscv64-musl" "4.52.5" + "@rollup/rollup-linux-s390x-gnu" "4.52.5" + "@rollup/rollup-linux-x64-gnu" "4.52.5" + "@rollup/rollup-linux-x64-musl" "4.52.5" + "@rollup/rollup-openharmony-arm64" "4.52.5" + "@rollup/rollup-win32-arm64-msvc" "4.52.5" + "@rollup/rollup-win32-ia32-msvc" "4.52.5" + "@rollup/rollup-win32-x64-gnu" "4.52.5" + "@rollup/rollup-win32-x64-msvc" "4.52.5" fsevents "~2.3.2" rrweb-cssom@^0.6.0: @@ -4770,10 +4921,10 @@ snake-case@^3.0.4: dot-case "^3.0.4" tslib "^2.0.3" -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== stackback@0.0.2: version "0.0.2" @@ -4963,10 +5114,10 @@ tinybench@^2.5.1: resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.6.0.tgz#1423284ee22de07c91b3752c048d2764714b341b" integrity sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA== -tinypool@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.2.tgz#84013b03dc69dacb322563a475d4c0a9be00f82a" - integrity sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ== +tinypool@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.4.tgz#e217fe1270d941b39e98c625dcecebb1408c9aa8" + integrity sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ== tinyspy@^2.2.0: version "2.2.1" @@ -5124,10 +5275,10 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" @@ -5205,10 +5356,10 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -vite-node@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.3.1.tgz#a93f7372212f5d5df38e945046b945ac3f4855d2" - integrity sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng== +vite-node@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.6.1.tgz#fff3ef309296ea03ceaa6ca4bb660922f5416c57" + integrity sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA== dependencies: cac "^6.7.14" debug "^4.3.4" @@ -5235,27 +5386,27 @@ vite-tsconfig-paths@^3.5.0: recrawl-sync "^2.0.3" tsconfig-paths "^4.0.0" -vite@^5.0.0, vite@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.7.tgz#9f685a2c4c70707fef6d37341b0e809c366da619" - integrity sha512-sgnEEFTZYMui/sTlH1/XEnVNHMujOahPLGMxn1+5sIT45Xjng1Ec1K78jRP15dSmVgg5WBin9yO81j3o9OxofA== +vite@^5.0.0, vite@^5.4.21: + version "5.4.21" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.21.tgz#84a4f7c5d860b071676d39ba513c0d598fdc7027" + integrity sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw== dependencies: - esbuild "^0.19.3" - postcss "^8.4.35" - rollup "^4.2.0" + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" optionalDependencies: fsevents "~2.3.3" -vitest@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.3.1.tgz#2d7e9861f030d88a4669392a4aecb40569d90937" - integrity sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ== +vitest@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.6.1.tgz#b4a3097adf8f79ac18bc2e2e0024c534a7a78d2f" + integrity sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag== dependencies: - "@vitest/expect" "1.3.1" - "@vitest/runner" "1.3.1" - "@vitest/snapshot" "1.3.1" - "@vitest/spy" "1.3.1" - "@vitest/utils" "1.3.1" + "@vitest/expect" "1.6.1" + "@vitest/runner" "1.6.1" + "@vitest/snapshot" "1.6.1" + "@vitest/spy" "1.6.1" + "@vitest/utils" "1.6.1" acorn-walk "^8.3.2" chai "^4.3.10" debug "^4.3.4" @@ -5267,9 +5418,9 @@ vitest@^1.3.1: std-env "^3.5.0" strip-literal "^2.0.0" tinybench "^2.5.1" - tinypool "^0.8.2" + tinypool "^0.8.3" vite "^5.0.0" - vite-node "1.3.1" + vite-node "1.6.1" why-is-node-running "^2.2.2" w3c-xmlserializer@^5.0.0: diff --git a/vendor/tailscale.com/clientupdate/clientupdate.go b/vendor/tailscale.com/clientupdate/clientupdate.go deleted file mode 100644 index ffd3fb0..0000000 --- a/vendor/tailscale.com/clientupdate/clientupdate.go +++ /dev/null @@ -1,1228 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package clientupdate implements tailscale client update for all supported -// platforms. This package can be used from both tailscaled and tailscale -// binaries. -package clientupdate - -import ( - "archive/tar" - "bufio" - "bytes" - "compress/gzip" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "maps" - "net/http" - "os" - "os/exec" - "path" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - - "tailscale.com/hostinfo" - "tailscale.com/types/lazy" - "tailscale.com/types/logger" - "tailscale.com/util/cmpver" - "tailscale.com/version" - "tailscale.com/version/distro" -) - -const ( - StableTrack = "stable" - UnstableTrack = "unstable" -) - -var CurrentTrack = func() string { - if version.IsUnstableBuild() { - return UnstableTrack - } else { - return StableTrack - } -}() - -func versionToTrack(v string) (string, error) { - _, rest, ok := strings.Cut(v, ".") - if !ok { - return "", fmt.Errorf("malformed version %q", v) - } - minorStr, _, ok := strings.Cut(rest, ".") - if !ok { - return "", fmt.Errorf("malformed version %q", v) - } - minor, err := strconv.Atoi(minorStr) - if err != nil { - return "", fmt.Errorf("malformed version %q", v) - } - if minor%2 == 0 { - return "stable", nil - } - return "unstable", nil -} - -// Arguments contains arguments needed to run an update. -type Arguments struct { - // Version is the specific version to install. - // Mutually exclusive with Track. - Version string - // Track is the release track to use: - // - // - CurrentTrack will use the latest version from the same track as the - // running binary - // - StableTrack and UnstableTrack will use the latest versions of the - // corresponding tracks - // - // Leaving this empty will use Version or fall back to CurrentTrack if both - // Track and Version are empty. - Track string - // Logf is a logger for update progress messages. - Logf logger.Logf - // Stdout and Stderr should be used for output instead of os.Stdout and - // os.Stderr. - Stdout io.Writer - Stderr io.Writer - // Confirm is called when a new version is available and should return true - // if this new version should be installed. When Confirm returns false, the - // update is aborted. - Confirm func(newVer string) bool - // PkgsAddr is the address of the pkgs server to fetch updates from. - // Defaults to "https://pkgs.tailscale.com". - PkgsAddr string - // ForAutoUpdate should be true when Updater is created in auto-update - // context. When true, NewUpdater returns an error if it cannot be used for - // auto-updates (even if Updater.Update field is non-nil). - ForAutoUpdate bool -} - -func (args Arguments) validate() error { - if args.Confirm == nil { - return errors.New("missing Confirm callback in Arguments") - } - if args.Logf == nil { - return errors.New("missing Logf callback in Arguments") - } - if args.Version != "" && args.Track != "" { - return fmt.Errorf("only one of Version(%q) or Track(%q) can be set", args.Version, args.Track) - } - switch args.Track { - case StableTrack, UnstableTrack, "": - // All valid values. - default: - return fmt.Errorf("unsupported track %q", args.Track) - } - return nil -} - -type Updater struct { - Arguments - // Update is a platform-specific method that updates the installation. May be - // nil (not all platforms support updates from within Tailscale). - Update func() error - - // currentVersion is the short form of the current client version as - // returned by version.Short(), typically "x.y.z". Used for tests to - // override the actual current version. - currentVersion string -} - -func NewUpdater(args Arguments) (*Updater, error) { - up := Updater{ - Arguments: args, - currentVersion: version.Short(), - } - if up.Stdout == nil { - up.Stdout = os.Stdout - } - if up.Stderr == nil { - up.Stderr = os.Stderr - } - var canAutoUpdate bool - up.Update, canAutoUpdate = up.getUpdateFunction() - if up.Update == nil { - return nil, errors.ErrUnsupported - } - if args.ForAutoUpdate && !canAutoUpdate { - return nil, errors.ErrUnsupported - } - if up.Track == "" { - if up.Version != "" { - var err error - up.Track, err = versionToTrack(args.Version) - if err != nil { - return nil, err - } - } else { - up.Track = CurrentTrack - } - } - if up.Arguments.PkgsAddr == "" { - up.Arguments.PkgsAddr = "https://pkgs.tailscale.com" - } - return &up, nil -} - -type updateFunction func() error - -func (up *Updater) getUpdateFunction() (fn updateFunction, canAutoUpdate bool) { - hi := hostinfo.New() - // We don't know how to update custom tsnet binaries, it's up to the user. - if hi.Package == "tsnet" { - return nil, false - } - - switch runtime.GOOS { - case "windows": - return up.updateWindows, true - case "linux": - switch distro.Get() { - case distro.NixOS: - // NixOS packages are immutable and managed with a system-wide - // configuration. - return up.updateNixos, false - case distro.Synology: - // Synology updates use our own pkgs.tailscale.com instead of the - // Synology Package Center. We should eventually get to a regular - // release cadence with Synology Package Center and use their - // auto-update mechanism. - return up.updateSynology, false - case distro.Debian: // includes Ubuntu - return up.updateDebLike, true - case distro.Arch: - if up.archPackageInstalled() { - // Arch update func just prints a message about how to update, - // it doesn't support auto-updates. - return up.updateArchLike, false - } - return up.updateLinuxBinary, true - case distro.Alpine: - return up.updateAlpineLike, true - case distro.Unraid: - return up.updateUnraid, true - case distro.QNAP: - return up.updateQNAP, true - } - switch { - case haveExecutable("pacman"): - if up.archPackageInstalled() { - // Arch update func just prints a message about how to update, - // it doesn't support auto-updates. - return up.updateArchLike, false - } - return up.updateLinuxBinary, true - case haveExecutable("apt-get"): // TODO(awly): add support for "apt" - // The distro.Debian switch case above should catch most apt-based - // systems, but add this fallback just in case. - return up.updateDebLike, true - case haveExecutable("dnf"): - return up.updateFedoraLike("dnf"), true - case haveExecutable("yum"): - return up.updateFedoraLike("yum"), true - case haveExecutable("apk"): - return up.updateAlpineLike, true - } - // If nothing matched, fall back to tarball updates. - if up.Update == nil { - return up.updateLinuxBinary, true - } - case "darwin": - switch { - case version.IsMacAppStore(): - // App store update func just opens the store page, it doesn't - // support auto-updates. - return up.updateMacAppStore, false - case version.IsMacSysExt(): - // Macsys update func kicks off Sparkle. Auto-updates are done by - // Sparkle. - return up.updateMacSys, false - default: - return nil, false - } - case "freebsd": - return up.updateFreeBSD, true - } - return nil, false -} - -var canAutoUpdateCache lazy.SyncValue[bool] - -// CanAutoUpdate reports whether auto-updating via the clientupdate package -// is supported for the current os/distro. -func CanAutoUpdate() bool { return canAutoUpdateCache.Get(canAutoUpdateUncached) } - -func canAutoUpdateUncached() bool { - if version.IsMacSysExt() { - // Macsys uses Sparkle for auto-updates, which doesn't have an update - // function in this package. - return true - } - _, canAutoUpdate := (&Updater{}).getUpdateFunction() - return canAutoUpdate -} - -// Update runs a single update attempt using the platform-specific mechanism. -// -// On Windows, this copies the calling binary and re-executes it to apply the -// update. The calling binary should handle an "update" subcommand and call -// this function again for the re-executed binary to proceed. -func Update(args Arguments) error { - if err := args.validate(); err != nil { - return err - } - up, err := NewUpdater(args) - if err != nil { - return err - } - return up.Update() -} - -func (up *Updater) confirm(ver string) bool { - // Only check version when we're not switching tracks. - if up.Track == "" || up.Track == CurrentTrack { - switch c := cmpver.Compare(up.currentVersion, ver); { - case c == 0: - up.Logf("already running %v version %v; no update needed", up.Track, ver) - return false - case c > 0: - up.Logf("installed %v version %v is newer than the latest available version %v; no update needed", up.Track, up.currentVersion, ver) - return false - } - } - if up.Confirm != nil { - return up.Confirm(ver) - } - return true -} - -const synoinfoConfPath = "/etc/synoinfo.conf" - -func (up *Updater) updateSynology() error { - if up.Version != "" { - return errors.New("installing a specific version on Synology is not supported") - } - if err := requireRoot(); err != nil { - return err - } - - // Get the latest version and list of SPKs from pkgs.tailscale.com. - dsmVersion := distro.DSMVersion() - osName := fmt.Sprintf("dsm%d", dsmVersion) - arch, err := synoArch(runtime.GOARCH, synoinfoConfPath) - if err != nil { - return err - } - latest, err := latestPackages(up.Track) - if err != nil { - return err - } - spkName := latest.SPKs[osName][arch] - if spkName == "" { - return fmt.Errorf("cannot find Synology package for os=%s arch=%s, please report a bug with your device model", osName, arch) - } - - if !up.confirm(latest.SPKsVersion) { - return nil - } - - up.cleanupOldDownloads(filepath.Join(os.TempDir(), "tailscale-update*", "*.spk")) - // Download the SPK into a temporary directory. - spkDir, err := os.MkdirTemp("", "tailscale-update") - if err != nil { - return err - } - pkgsPath := fmt.Sprintf("%s/%s", up.Track, spkName) - spkPath := filepath.Join(spkDir, path.Base(pkgsPath)) - if err := up.downloadURLToFile(pkgsPath, spkPath); err != nil { - return err - } - - // Install the SPK. Run via nohup to allow install to succeed when we're - // connected over tailscale ssh and this parent process dies. Otherwise, if - // you abort synopkg install mid-way, tailscaled is not restarted. - cmd := exec.Command("nohup", "synopkg", "install", spkPath) - // Don't attach cmd.Stdout to Stdout because nohup will redirect that into - // nohup.out file. synopkg doesn't have any progress output anyway, it just - // spits out a JSON result when done. - out, err := cmd.CombinedOutput() - if err != nil { - if dsmVersion == 6 && bytes.Contains(out, []byte("error = [290]")) { - return fmt.Errorf("synopkg install failed: %w\noutput:\n%s\nplease make sure that packages from 'Any publisher' are allowed in the Package Center (Package Center -> Settings -> Trust Level -> Any publisher)", err, out) - } - return fmt.Errorf("synopkg install failed: %w\noutput:\n%s", err, out) - } - if dsmVersion == 6 { - // DSM6 does not automatically restart the package on install. Do it - // manually. - cmd := exec.Command("nohup", "synopkg", "start", "Tailscale") - out, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("synopkg start failed: %w\noutput:\n%s", err, out) - } - } - return nil -} - -// synoArch returns the Synology CPU architecture matching one of the SPK -// architectures served from pkgs.tailscale.com. -func synoArch(goArch, synoinfoPath string) (string, error) { - // Most Synology boxes just use a different arch name from GOARCH. - arch := map[string]string{ - "amd64": "x86_64", - "386": "i686", - "arm64": "armv8", - }[goArch] - - if arch == "" { - // Here's the fun part, some older ARM boxes require you to use SPKs - // specifically for their CPU. See - // https://github.com/SynoCommunity/spksrc/wiki/Synology-and-SynoCommunity-Package-Architectures - // for a complete list. - // - // Some CPUs will map to neither this list nor the goArch map above, and we - // don't have SPKs for them. - cpu, err := parseSynoinfo(synoinfoPath) - if err != nil { - return "", fmt.Errorf("failed to get CPU architecture: %w", err) - } - switch cpu { - case "88f6281", "88f6282", "hi3535", "alpine", "armada370", - "armada375", "armada38x", "armadaxp", "comcerto2k", "monaco": - arch = cpu - default: - return "", fmt.Errorf("unsupported Synology CPU architecture %q (Go arch %q), please report a bug at https://github.com/tailscale/tailscale/issues/new/choose", cpu, goArch) - } - } - return arch, nil -} - -func parseSynoinfo(path string) (string, error) { - f, err := os.Open(path) - if err != nil { - return "", err - } - defer f.Close() - - // Look for a line like: - // unique="synology_88f6282_413j" - // Extract the CPU in the middle (88f6282 in the above example). - s := bufio.NewScanner(f) - for s.Scan() { - l := s.Text() - if !strings.HasPrefix(l, "unique=") { - continue - } - parts := strings.SplitN(l, "_", 3) - if len(parts) != 3 { - return "", fmt.Errorf(`malformed %q: found %q, expected format like 'unique="synology_$cpu_$model'`, path, l) - } - return parts[1], nil - } - return "", fmt.Errorf(`missing "unique=" field in %q`, path) -} - -func (up *Updater) updateDebLike() error { - if err := requireRoot(); err != nil { - return err - } - if err := exec.Command("dpkg", "--status", "tailscale").Run(); err != nil && isExitError(err) { - // Tailscale was not installed via apt, update via tarball download - // instead. - return up.updateLinuxBinary() - } - ver, err := requestedTailscaleVersion(up.Version, up.Track) - if err != nil { - return err - } - if !up.confirm(ver) { - return nil - } - - if updated, err := updateDebianAptSourcesList(up.Track); err != nil { - return err - } else if updated { - up.Logf("Updated %s to use the %s track", aptSourcesFile, up.Track) - } - - cmd := exec.Command("apt-get", "update", - // Only update the tailscale repo, not the other ones, treating - // the tailscale.list file as the main "sources.list" file. - "-o", "Dir::Etc::SourceList=sources.list.d/tailscale.list", - // Disable the "sources.list.d" directory: - "-o", "Dir::Etc::SourceParts=-", - // Don't forget about packages in the other repos just because - // we're not updating them: - "-o", "APT::Get::List-Cleanup=0", - ) - if out, err := cmd.CombinedOutput(); err != nil { - return fmt.Errorf("apt-get update failed: %w; output:\n%s", err, out) - } - - for range 2 { - out, err := exec.Command("apt-get", "install", "--yes", "--allow-downgrades", "tailscale="+ver).CombinedOutput() - if err != nil { - if !bytes.Contains(out, []byte(`dpkg was interrupted`)) { - return fmt.Errorf("apt-get install failed: %w; output:\n%s", err, out) - } - up.Logf("apt-get install failed: %s; output:\n%s", err, out) - up.Logf("running dpkg --configure tailscale") - out, err = exec.Command("dpkg", "--force-confdef,downgrade", "--configure", "tailscale").CombinedOutput() - if err != nil { - return fmt.Errorf("dpkg --configure tailscale failed: %w; output:\n%s", err, out) - } - continue - } - break - } - - return nil -} - -const aptSourcesFile = "/etc/apt/sources.list.d/tailscale.list" - -// updateDebianAptSourcesList updates the /etc/apt/sources.list.d/tailscale.list -// file to make sure it has the provided track (stable or unstable) in it. -// -// If it already has the right track (including containing both stable and -// unstable), it does nothing. -func updateDebianAptSourcesList(dstTrack string) (rewrote bool, err error) { - was, err := os.ReadFile(aptSourcesFile) - if err != nil { - return false, err - } - newContent, err := updateDebianAptSourcesListBytes(was, dstTrack) - if err != nil { - return false, err - } - if bytes.Equal(was, newContent) { - return false, nil - } - return true, os.WriteFile(aptSourcesFile, newContent, 0644) -} - -func updateDebianAptSourcesListBytes(was []byte, dstTrack string) (newContent []byte, err error) { - trackURLPrefix := []byte("https://pkgs.tailscale.com/" + dstTrack + "/") - var buf bytes.Buffer - var changes int - bs := bufio.NewScanner(bytes.NewReader(was)) - hadCorrect := false - commentLine := regexp.MustCompile(`^\s*\#`) - pkgsURL := regexp.MustCompile(`\bhttps://pkgs\.tailscale\.com/((un)?stable)/`) - for bs.Scan() { - line := bs.Bytes() - if !commentLine.Match(line) { - line = pkgsURL.ReplaceAllFunc(line, func(m []byte) []byte { - if bytes.Equal(m, trackURLPrefix) { - hadCorrect = true - } else { - changes++ - } - return trackURLPrefix - }) - } - buf.Write(line) - buf.WriteByte('\n') - } - if hadCorrect || (changes == 1 && bytes.Equal(bytes.TrimSpace(was), bytes.TrimSpace(buf.Bytes()))) { - // Unchanged or close enough. - return was, nil - } - if changes != 1 { - // No changes, or an unexpected number of changes (what?). Bail. - // They probably editted it by hand and we don't know what to do. - return nil, fmt.Errorf("unexpected/unsupported %s contents", aptSourcesFile) - } - return buf.Bytes(), nil -} - -func (up *Updater) archPackageInstalled() bool { - err := exec.Command("pacman", "--query", "tailscale").Run() - return err == nil -} - -func (up *Updater) updateArchLike() error { - // Arch maintainer asked us not to implement "tailscale update" or - // auto-updates on Arch-based distros: - // https://github.com/tailscale/tailscale/issues/6995#issuecomment-1687080106 - return errors.New(`individual package updates are not supported on Arch-based distros, only full-system updates are: https://wiki.archlinux.org/title/System_maintenance#Partial_upgrades_are_unsupported. -you can use "pacman --sync --refresh --sysupgrade" or "pacman -Syu" to upgrade the system, including Tailscale.`) -} - -func (up *Updater) updateNixos() error { - // NixOS package updates are managed on a system level and not individually. - // Direct users to update their nix channel or nixpkgs flake input to - // receive the latest version. - return errors.New(`individual package updates are not supported on NixOS installations. Update your system channel or flake inputs to get the latest Tailscale version from nixpkgs.`) -} - -const yumRepoConfigFile = "/etc/yum.repos.d/tailscale.repo" - -// updateFedoraLike updates tailscale on any distros in the Fedora family, -// specifically anything that uses "dnf" or "yum" package managers. The actual -// package manager is passed via packageManager. -func (up *Updater) updateFedoraLike(packageManager string) func() error { - return func() (err error) { - if err := requireRoot(); err != nil { - return err - } - if err := exec.Command(packageManager, "info", "--installed", "tailscale").Run(); err != nil && isExitError(err) { - // Tailscale was not installed via yum/dnf, update via tarball - // download instead. - return up.updateLinuxBinary() - } - defer func() { - if err != nil { - err = fmt.Errorf(`%w; you can try updating using "%s upgrade tailscale"`, err, packageManager) - } - }() - - ver, err := requestedTailscaleVersion(up.Version, up.Track) - if err != nil { - return err - } - if !up.confirm(ver) { - return nil - } - - if updated, err := updateYUMRepoTrack(yumRepoConfigFile, up.Track); err != nil { - return err - } else if updated { - up.Logf("Updated %s to use the %s track", yumRepoConfigFile, up.Track) - } - - cmd := exec.Command(packageManager, "install", "--assumeyes", fmt.Sprintf("tailscale-%s-1", ver)) - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - if err := cmd.Run(); err != nil { - return err - } - return nil - } -} - -// updateYUMRepoTrack updates the repoFile file to make sure it has the -// provided track (stable or unstable) in it. -func updateYUMRepoTrack(repoFile, dstTrack string) (rewrote bool, err error) { - was, err := os.ReadFile(repoFile) - if err != nil { - return false, err - } - - urlRe := regexp.MustCompile(`^(baseurl|gpgkey)=https://pkgs\.tailscale\.com/(un)?stable/`) - urlReplacement := fmt.Sprintf("$1=https://pkgs.tailscale.com/%s/", dstTrack) - - s := bufio.NewScanner(bytes.NewReader(was)) - newContent := bytes.NewBuffer(make([]byte, 0, len(was))) - for s.Scan() { - line := s.Text() - // Handle repo section name, like "[tailscale-stable]". - if len(line) > 0 && line[0] == '[' { - if !strings.HasPrefix(line, "[tailscale-") { - return false, fmt.Errorf("%q does not look like a tailscale repo file, it contains an unexpected %q section", repoFile, line) - } - fmt.Fprintf(newContent, "[tailscale-%s]\n", dstTrack) - continue - } - // Update the track mentioned in repo name. - if strings.HasPrefix(line, "name=") { - fmt.Fprintf(newContent, "name=Tailscale %s\n", dstTrack) - continue - } - // Update the actual repo URLs. - if strings.HasPrefix(line, "baseurl=") || strings.HasPrefix(line, "gpgkey=") { - fmt.Fprintln(newContent, urlRe.ReplaceAllString(line, urlReplacement)) - continue - } - fmt.Fprintln(newContent, line) - } - if bytes.Equal(was, newContent.Bytes()) { - return false, nil - } - return true, os.WriteFile(repoFile, newContent.Bytes(), 0644) -} - -func (up *Updater) updateAlpineLike() (err error) { - if up.Version != "" { - return errors.New("installing a specific version on Alpine-based distros is not supported") - } - if err := requireRoot(); err != nil { - return err - } - if err := exec.Command("apk", "info", "--installed", "tailscale").Run(); err != nil && isExitError(err) { - // Tailscale was not installed via apk, update via tarball download - // instead. - return up.updateLinuxBinary() - } - - defer func() { - if err != nil { - err = fmt.Errorf(`%w; you can try updating using "apk upgrade tailscale"`, err) - } - }() - - out, err := exec.Command("apk", "update").CombinedOutput() - if err != nil { - return fmt.Errorf("failed refresh apk repository indexes: %w, output:\n%s", err, out) - } - out, err = exec.Command("apk", "info", "tailscale").CombinedOutput() - if err != nil { - return fmt.Errorf("failed checking apk for latest tailscale version: %w, output:\n%s", err, out) - } - ver, err := parseAlpinePackageVersion(out) - if err != nil { - return fmt.Errorf(`failed to parse latest version from "apk info tailscale": %w`, err) - } - if !up.confirm(ver) { - if err := checkOutdatedAlpineRepo(up.Logf, ver, up.Track); err != nil { - up.Logf("failed to check whether Alpine release is outdated: %v", err) - } - return nil - } - - cmd := exec.Command("apk", "upgrade", "tailscale") - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed tailscale update using apk: %w", err) - } - return nil -} - -func parseAlpinePackageVersion(out []byte) (string, error) { - s := bufio.NewScanner(bytes.NewReader(out)) - var maxVer string - for s.Scan() { - // The line should look like this: - // tailscale-1.44.2-r0 description: - line := strings.TrimSpace(s.Text()) - if !strings.HasPrefix(line, "tailscale-") { - continue - } - parts := strings.SplitN(line, "-", 3) - if len(parts) < 3 { - return "", fmt.Errorf("malformed info line: %q", line) - } - ver := parts[1] - if cmpver.Compare(ver, maxVer) > 0 { - maxVer = ver - } - } - if maxVer != "" { - return maxVer, nil - } - return "", errors.New("tailscale version not found in output") -} - -var apkRepoVersionRE = regexp.MustCompile(`v[0-9]+\.[0-9]+`) - -func checkOutdatedAlpineRepo(logf logger.Logf, apkVer, track string) error { - latest, err := LatestTailscaleVersion(track) - if err != nil { - return err - } - if latest == apkVer { - // Actually on latest release. - return nil - } - f, err := os.Open("/etc/apk/repositories") - if err != nil { - return err - } - defer f.Close() - // Read the first repo line. Typically, there are multiple repos that all - // contain the same version in the path, like: - // https://dl-cdn.alpinelinux.org/alpine/v3.20/main - // https://dl-cdn.alpinelinux.org/alpine/v3.20/community - s := bufio.NewScanner(f) - if !s.Scan() { - return s.Err() - } - alpineVer := apkRepoVersionRE.FindString(s.Text()) - if alpineVer != "" { - logf("The latest Tailscale release for Linux is %q, but your apk repository only provides %q.\nYour Alpine version is %q, you may need to upgrade the system to get the latest Tailscale version: https://wiki.alpinelinux.org/wiki/Upgrading_Alpine", latest, apkVer, alpineVer) - } - return nil -} - -func (up *Updater) updateMacSys() error { - return errors.New("NOTREACHED: On MacSys builds, `tailscale update` is handled in Swift to launch the GUI updater") -} - -func (up *Updater) updateMacAppStore() error { - // We can't trigger the update via App Store from the sandboxed app. At - // most, we can open the App Store page for them. - up.Logf("Please use the App Store to update Tailscale.\nConsider enabling Automatic Updates in the App Store Settings, if you haven't already.\nOpening the Tailscale app page...") - - out, err := exec.Command("open", "https://apps.apple.com/us/app/tailscale/id1475387142").CombinedOutput() - if err != nil { - return fmt.Errorf("can't open the Tailscale page in App Store: %w, output:\n%s", err, string(out)) - } - return nil -} - -// cleanupOldDownloads removes all files matching glob (see filepath.Glob). -// Only regular files are removed, so the glob must match specific files and -// not directories. -func (up *Updater) cleanupOldDownloads(glob string) { - matches, err := filepath.Glob(glob) - if err != nil { - up.Logf("cleaning up old downloads: %v", err) - return - } - for _, m := range matches { - s, err := os.Lstat(m) - if err != nil { - up.Logf("cleaning up old downloads: %v", err) - continue - } - if !s.Mode().IsRegular() { - continue - } - if err := os.Remove(m); err != nil { - up.Logf("cleaning up old downloads: %v", err) - } - } -} - -func (up *Updater) updateFreeBSD() (err error) { - if up.Version != "" { - return errors.New("installing a specific version on FreeBSD is not supported") - } - if err := requireRoot(); err != nil { - return err - } - if err := exec.Command("pkg", "query", "%n", "tailscale").Run(); err != nil && isExitError(err) { - // Tailscale was not installed via pkg and we don't pre-compile - // binaries for it. - return errors.New("Tailscale was not installed via pkg, binary updates on FreeBSD are not supported; please reinstall Tailscale using pkg or update manually") - } - - defer func() { - if err != nil { - err = fmt.Errorf(`%w; you can try updating using "pkg upgrade tailscale"`, err) - } - }() - - out, err := exec.Command("pkg", "update").CombinedOutput() - if err != nil { - return fmt.Errorf("failed refresh pkg repository indexes: %w, output:\n%s", err, out) - } - out, err = exec.Command("pkg", "rquery", "%v", "tailscale").CombinedOutput() - if err != nil { - return fmt.Errorf("failed checking pkg for latest tailscale version: %w, output:\n%s", err, out) - } - ver := string(bytes.TrimSpace(out)) - if !up.confirm(ver) { - return nil - } - - cmd := exec.Command("pkg", "upgrade", "-y", "tailscale") - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed tailscale update using pkg: %w", err) - } - - // pkg does not automatically restart services after upgrade. - out, err = exec.Command("service", "tailscaled", "restart").CombinedOutput() - if err != nil { - return fmt.Errorf("failed to restart tailscaled after update: %w, output:\n%s", err, out) - } - return nil -} - -func (up *Updater) updateLinuxBinary() error { - // Root is needed to overwrite binaries and restart systemd unit. - if err := requireRoot(); err != nil { - return err - } - ver, err := requestedTailscaleVersion(up.Version, up.Track) - if err != nil { - return err - } - if !up.confirm(ver) { - return nil - } - - dlPath, err := up.downloadLinuxTarball(ver) - if err != nil { - return err - } - up.Logf("Extracting %q", dlPath) - if err := up.unpackLinuxTarball(dlPath); err != nil { - return err - } - if err := os.Remove(dlPath); err != nil { - up.Logf("failed to clean up %q: %v", dlPath, err) - } - if err := restartSystemdUnit(context.Background()); err != nil { - if errors.Is(err, errors.ErrUnsupported) { - up.Logf("Tailscale binaries updated successfully.\nPlease restart tailscaled to finish the update.") - } else { - up.Logf("Tailscale binaries updated successfully, but failed to restart tailscaled: %s.\nPlease restart tailscaled to finish the update.", err) - } - } else { - up.Logf("Success") - } - - return nil -} - -func restartSystemdUnit(ctx context.Context) error { - if _, err := exec.LookPath("systemctl"); err != nil { - // Likely not a systemd-managed distro. - return errors.ErrUnsupported - } - if out, err := exec.Command("systemctl", "daemon-reload").CombinedOutput(); err != nil { - return fmt.Errorf("systemctl daemon-reload failed: %w\noutput: %s", err, out) - } - if out, err := exec.Command("systemctl", "restart", "tailscaled.service").CombinedOutput(); err != nil { - return fmt.Errorf("systemctl restart failed: %w\noutput: %s", err, out) - } - return nil -} - -func (up *Updater) downloadLinuxTarball(ver string) (string, error) { - dlDir, err := os.UserCacheDir() - if err != nil { - dlDir = os.TempDir() - } - dlDir = filepath.Join(dlDir, "tailscale-update") - if err := os.MkdirAll(dlDir, 0700); err != nil { - return "", err - } - pkgsPath := fmt.Sprintf("%s/tailscale_%s_%s.tgz", up.Track, ver, runtime.GOARCH) - dlPath := filepath.Join(dlDir, path.Base(pkgsPath)) - if err := up.downloadURLToFile(pkgsPath, dlPath); err != nil { - return "", err - } - return dlPath, nil -} - -func (up *Updater) unpackLinuxTarball(path string) error { - tailscale, tailscaled, err := binaryPaths() - if err != nil { - return err - } - f, err := os.Open(path) - if err != nil { - return err - } - defer f.Close() - gr, err := gzip.NewReader(f) - if err != nil { - return err - } - defer gr.Close() - tr := tar.NewReader(gr) - files := make(map[string]int) - wantFiles := map[string]int{ - "tailscale": 1, - "tailscaled": 1, - } - for { - th, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - return fmt.Errorf("failed extracting %q: %w", path, err) - } - // TODO(awly): try to also extract tailscaled.service. The tricky part - // is fixing up binary paths in that file if they differ from where - // local tailscale/tailscaled are installed. Also, this may not be a - // systemd distro. - switch filepath.Base(th.Name) { - case "tailscale": - files["tailscale"]++ - if err := writeFile(tr, tailscale+".new", 0755); err != nil { - return fmt.Errorf("failed extracting the new tailscale binary from %q: %w", path, err) - } - case "tailscaled": - files["tailscaled"]++ - if err := writeFile(tr, tailscaled+".new", 0755); err != nil { - return fmt.Errorf("failed extracting the new tailscaled binary from %q: %w", path, err) - } - } - } - if !maps.Equal(files, wantFiles) { - return fmt.Errorf("%q has missing or duplicate files: got %v, want %v", path, files, wantFiles) - } - - // Only place the files in final locations after everything extracted correctly. - if err := os.Rename(tailscale+".new", tailscale); err != nil { - return err - } - up.Logf("Updated %s", tailscale) - if err := os.Rename(tailscaled+".new", tailscaled); err != nil { - return err - } - up.Logf("Updated %s", tailscaled) - return nil -} - -func (up *Updater) updateQNAP() (err error) { - if up.Version != "" { - return errors.New("installing a specific version on QNAP is not supported") - } - if err := requireRoot(); err != nil { - return err - } - - defer func() { - if err != nil { - err = fmt.Errorf(`%w; you can try updating using "qpkg_cli --add Tailscale"`, err) - } - }() - - out, err := exec.Command("qpkg_cli", "--upgradable", "Tailscale").CombinedOutput() - if err != nil { - return fmt.Errorf("failed to check if Tailscale is upgradable using qpkg_cli: %w, output: %q", err, out) - } - - // Output should look like this: - // - // $ qpkg_cli -G Tailscale - // [Tailscale] - // upgradeStatus = 1 - statusRe := regexp.MustCompile(`upgradeStatus = (\d)`) - m := statusRe.FindStringSubmatch(string(out)) - if len(m) < 2 { - return fmt.Errorf("failed to check if Tailscale is upgradable using qpkg_cli, output: %q", out) - } - status, err := strconv.Atoi(m[1]) - if err != nil { - return fmt.Errorf("cannot parse upgradeStatus from qpkg_cli output %q: %w", out, err) - } - // Possible status values: - // 0:can upgrade - // 1:can not upgrade - // 2:error - // 3:can not get rss information - // 4:qpkg not found - // 5:qpkg not installed - // - // We want status 0. - switch status { - case 0: // proceed with upgrade - case 1: - up.Logf("no update available") - return nil - case 2, 3, 4: - return fmt.Errorf("failed to check update status with qpkg_cli (upgradeStatus = %d)", status) - case 5: - return errors.New("Tailscale was not found in the QNAP App Center") - default: - return fmt.Errorf("failed to check update status with qpkg_cli (upgradeStatus = %d)", status) - } - - // There doesn't seem to be a way to fetch what the available upgrade - // version is. Use the generic "latest" version in confirmation prompt. - if up.Confirm != nil && !up.Confirm("latest") { - return nil - } - - up.Logf("c2n: running qpkg_cli --add Tailscale") - cmd := exec.Command("qpkg_cli", "--add", "Tailscale") - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed tailscale update using qpkg_cli: %w", err) - } - return nil -} - -func (up *Updater) updateUnraid() (err error) { - if up.Version != "" { - return errors.New("installing a specific version on Unraid is not supported") - } - if err := requireRoot(); err != nil { - return err - } - - defer func() { - if err != nil { - err = fmt.Errorf(`%w; you can try updating using "plugin check tailscale.plg && plugin update tailscale.plg"`, err) - } - }() - - // We need to run `plugin check` for the latest tailscale.plg to get - // downloaded. Unfortunately, the output of this command does not contain - // the latest tailscale version available. So we'll parse the downloaded - // tailscale.plg file manually below. - out, err := exec.Command("plugin", "check", "tailscale.plg").CombinedOutput() - if err != nil { - return fmt.Errorf("failed to check if Tailscale plugin is upgradable: %w, output: %q", err, out) - } - - // Note: 'plugin check' downloads plugins to /tmp/plugins. - // The installed .plg files are in /boot/config/plugins/, but the pending - // ones are in /tmp/plugins. We should parse the pending file downloaded by - // 'plugin check'. - latest, err := parseUnraidPluginVersion("/tmp/plugins/tailscale.plg") - if err != nil { - return fmt.Errorf("failed to find latest Tailscale version in /boot/config/plugins/tailscale.plg: %w", err) - } - if !up.confirm(latest) { - return nil - } - - up.Logf("c2n: running 'plugin update tailscale.plg'") - cmd := exec.Command("plugin", "update", "tailscale.plg") - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed tailscale plugin update: %w", err) - } - return nil -} - -func parseUnraidPluginVersion(plgPath string) (string, error) { - plg, err := os.ReadFile(plgPath) - if err != nil { - return "", err - } - re := regexp.MustCompile(``) - match := re.FindStringSubmatch(string(plg)) - if len(match) < 2 { - return "", errors.New("version not found in plg file") - } - return match[1], nil -} - -func writeFile(r io.Reader, path string, perm os.FileMode) error { - if err := os.Remove(path); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to remove existing file at %q: %w", path, err) - } - f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) - if err != nil { - return err - } - defer f.Close() - if _, err := io.Copy(f, r); err != nil { - return err - } - return f.Close() -} - -// Var allows overriding this in tests. -var binaryPaths = func() (tailscale, tailscaled string, err error) { - // This can be either tailscale or tailscaled. - this, err := os.Executable() - if err != nil { - return "", "", err - } - otherName := "tailscaled" - if filepath.Base(this) == "tailscaled" { - otherName = "tailscale" - } - // Try to find the other binary in the same directory. - other := filepath.Join(filepath.Dir(this), otherName) - _, err = os.Stat(other) - if os.IsNotExist(err) { - // If it's not in the same directory, try to find it in $PATH. - other, err = exec.LookPath(otherName) - } - if err != nil { - return "", "", fmt.Errorf("cannot find %q in neither %q nor $PATH: %w", otherName, filepath.Dir(this), err) - } - if otherName == "tailscaled" { - return this, other, nil - } else { - return other, this, nil - } -} - -func haveExecutable(name string) bool { - path, err := exec.LookPath(name) - return err == nil && path != "" -} - -func requestedTailscaleVersion(ver, track string) (string, error) { - if ver != "" { - return ver, nil - } - return LatestTailscaleVersion(track) -} - -// LatestTailscaleVersion returns the latest released version for the given -// track from pkgs.tailscale.com. -func LatestTailscaleVersion(track string) (string, error) { - if track == "" { - track = CurrentTrack - } - - latest, err := latestPackages(track) - if err != nil { - return "", err - } - ver := latest.Version - switch runtime.GOOS { - case "windows": - ver = latest.MSIsVersion - case "darwin": - ver = latest.MacZipsVersion - case "linux": - ver = latest.TarballsVersion - if distro.Get() == distro.Synology { - ver = latest.SPKsVersion - } - } - - if ver == "" { - return "", fmt.Errorf("no latest version found for OS %q on %q track", runtime.GOOS, track) - } - return ver, nil -} - -type trackPackages struct { - Version string - Tarballs map[string]string - TarballsVersion string - Exes []string - ExesVersion string - MSIs map[string]string - MSIsVersion string - MacZips map[string]string - MacZipsVersion string - SPKs map[string]map[string]string - SPKsVersion string -} - -func latestPackages(track string) (*trackPackages, error) { - url := fmt.Sprintf("https://pkgs.tailscale.com/%s/?mode=json&os=%s", track, runtime.GOOS) - res, err := http.Get(url) - if err != nil { - return nil, fmt.Errorf("fetching latest tailscale version: %w", err) - } - defer res.Body.Close() - var latest trackPackages - if err := json.NewDecoder(res.Body).Decode(&latest); err != nil { - return nil, fmt.Errorf("decoding JSON: %v: %w", res.Status, err) - } - return &latest, nil -} - -func requireRoot() error { - if os.Geteuid() == 0 { - return nil - } - switch runtime.GOOS { - case "linux": - return errors.New("must be root; use sudo") - case "freebsd", "openbsd": - return errors.New("must be root; use doas") - default: - return errors.New("must be root") - } -} - -func isExitError(err error) bool { - var exitErr *exec.ExitError - return errors.As(err, &exitErr) -} diff --git a/vendor/tailscale.com/clientupdate/clientupdate_downloads.go b/vendor/tailscale.com/clientupdate/clientupdate_downloads.go deleted file mode 100644 index 18d3176..0000000 --- a/vendor/tailscale.com/clientupdate/clientupdate_downloads.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (linux && !android) || windows - -package clientupdate - -import ( - "context" - - "tailscale.com/clientupdate/distsign" -) - -func (up *Updater) downloadURLToFile(pathSrc, fileDst string) (ret error) { - c, err := distsign.NewClient(up.Logf, up.PkgsAddr) - if err != nil { - return err - } - return c.Download(context.Background(), pathSrc, fileDst) -} diff --git a/vendor/tailscale.com/clientupdate/clientupdate_not_downloads.go b/vendor/tailscale.com/clientupdate/clientupdate_not_downloads.go deleted file mode 100644 index 057b4f2..0000000 --- a/vendor/tailscale.com/clientupdate/clientupdate_not_downloads.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !((linux && !android) || windows) - -package clientupdate - -func (up *Updater) downloadURLToFile(pathSrc, fileDst string) (ret error) { - panic("unreachable") -} diff --git a/vendor/tailscale.com/clientupdate/clientupdate_windows.go b/vendor/tailscale.com/clientupdate/clientupdate_windows.go deleted file mode 100644 index 9737229..0000000 --- a/vendor/tailscale.com/clientupdate/clientupdate_windows.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Windows-specific stuff that can't go in clientupdate.go because it needs -// x/sys/windows. - -package clientupdate - -import ( - "errors" - "fmt" - "io" - "os" - "os/exec" - "path" - "path/filepath" - "runtime" - "strings" - - "github.com/google/uuid" - "golang.org/x/sys/windows" - "tailscale.com/util/winutil" - "tailscale.com/util/winutil/authenticode" -) - -const ( - // winMSIEnv is the environment variable that, if set, is the MSI file for - // the update command to install. It's passed like this so we can stop the - // tailscale.exe process from running before the msiexec process runs and - // tries to overwrite ourselves. - winMSIEnv = "TS_UPDATE_WIN_MSI" - // winExePathEnv is the environment variable that is set along with - // winMSIEnv and carries the full path of the calling tailscale.exe binary. - // It is used to re-launch the GUI process (tailscale-ipn.exe) after - // install is complete. - winExePathEnv = "TS_UPDATE_WIN_EXE_PATH" -) - -func makeSelfCopy() (origPathExe, tmpPathExe string, err error) { - selfExe, err := os.Executable() - if err != nil { - return "", "", err - } - f, err := os.Open(selfExe) - if err != nil { - return "", "", err - } - defer f.Close() - f2, err := os.CreateTemp("", "tailscale-updater-*.exe") - if err != nil { - return "", "", err - } - if err := markTempFileWindows(f2.Name()); err != nil { - return "", "", err - } - if _, err := io.Copy(f2, f); err != nil { - f2.Close() - return "", "", err - } - return selfExe, f2.Name(), f2.Close() -} - -func markTempFileWindows(name string) error { - name16 := windows.StringToUTF16Ptr(name) - return windows.MoveFileEx(name16, nil, windows.MOVEFILE_DELAY_UNTIL_REBOOT) -} - -const certSubjectTailscale = "Tailscale Inc." - -func verifyAuthenticode(path string) error { - return authenticode.Verify(path, certSubjectTailscale) -} - -func (up *Updater) updateWindows() error { - if msi := os.Getenv(winMSIEnv); msi != "" { - // stdout/stderr from this part of the install could be lost since the - // parent tailscaled is replaced. Create a temp log file to have some - // output to debug with in case update fails. - close, err := up.switchOutputToFile() - if err != nil { - up.Logf("failed to create log file for installation: %v; proceeding with existing outputs", err) - } else { - defer close.Close() - } - - up.Logf("installing %v ...", msi) - if err := up.installMSI(msi); err != nil { - up.Logf("MSI install failed: %v", err) - return err - } - - up.Logf("success.") - return nil - } - - if !winutil.IsCurrentProcessElevated() { - return errors.New(`update must be run as Administrator - -you can run the command prompt as Administrator one of these ways: -* right-click cmd.exe, select 'Run as administrator' -* press Windows+x, then press a -* press Windows+r, type in "cmd", then press Ctrl+Shift+Enter`) - } - ver, err := requestedTailscaleVersion(up.Version, up.Track) - if err != nil { - return err - } - arch := runtime.GOARCH - if arch == "386" { - arch = "x86" - } - if !up.confirm(ver) { - return nil - } - - tsDir := filepath.Join(os.Getenv("ProgramData"), "Tailscale") - msiDir := filepath.Join(tsDir, "MSICache") - if fi, err := os.Stat(tsDir); err != nil { - return fmt.Errorf("expected %s to exist, got stat error: %w", tsDir, err) - } else if !fi.IsDir() { - return fmt.Errorf("expected %s to be a directory; got %v", tsDir, fi.Mode()) - } - if err := os.MkdirAll(msiDir, 0700); err != nil { - return err - } - up.cleanupOldDownloads(filepath.Join(msiDir, "*.msi")) - pkgsPath := fmt.Sprintf("%s/tailscale-setup-%s-%s.msi", up.Track, ver, arch) - msiTarget := filepath.Join(msiDir, path.Base(pkgsPath)) - if err := up.downloadURLToFile(pkgsPath, msiTarget); err != nil { - return err - } - - up.Logf("verifying MSI authenticode...") - if err := verifyAuthenticode(msiTarget); err != nil { - return fmt.Errorf("authenticode verification of %s failed: %w", msiTarget, err) - } - up.Logf("authenticode verification succeeded") - - up.Logf("making tailscale.exe copy to switch to...") - up.cleanupOldDownloads(filepath.Join(os.TempDir(), "tailscale-updater-*.exe")) - selfOrig, selfCopy, err := makeSelfCopy() - if err != nil { - return err - } - defer os.Remove(selfCopy) - up.Logf("running tailscale.exe copy for final install...") - - cmd := exec.Command(selfCopy, "update") - cmd.Env = append(os.Environ(), winMSIEnv+"="+msiTarget, winExePathEnv+"="+selfOrig) - cmd.Stdout = up.Stderr - cmd.Stderr = up.Stderr - cmd.Stdin = os.Stdin - if err := cmd.Start(); err != nil { - return err - } - // Once it's started, exit ourselves, so the binary is free - // to be replaced. - os.Exit(0) - panic("unreachable") -} - -func (up *Updater) installMSI(msi string) error { - var err error - for tries := 0; tries < 2; tries++ { - cmd := exec.Command("msiexec.exe", "/i", filepath.Base(msi), "/quiet", "/norestart", "/qn") - cmd.Dir = filepath.Dir(msi) - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - cmd.Stdin = os.Stdin - err = cmd.Run() - if err == nil { - break - } - up.Logf("Install attempt failed: %v", err) - uninstallVersion := up.currentVersion - if v := os.Getenv("TS_DEBUG_UNINSTALL_VERSION"); v != "" { - uninstallVersion = v - } - // Assume it's a downgrade, which msiexec won't permit. Uninstall our current version first. - up.Logf("Uninstalling current version %q for downgrade...", uninstallVersion) - cmd = exec.Command("msiexec.exe", "/x", msiUUIDForVersion(uninstallVersion), "/norestart", "/qn") - cmd.Stdout = up.Stdout - cmd.Stderr = up.Stderr - cmd.Stdin = os.Stdin - err = cmd.Run() - up.Logf("msiexec uninstall: %v", err) - } - return err -} - -func msiUUIDForVersion(ver string) string { - arch := runtime.GOARCH - if arch == "386" { - arch = "x86" - } - track, err := versionToTrack(ver) - if err != nil { - track = UnstableTrack - } - msiURL := fmt.Sprintf("https://pkgs.tailscale.com/%s/tailscale-setup-%s-%s.msi", track, ver, arch) - return "{" + strings.ToUpper(uuid.NewSHA1(uuid.NameSpaceURL, []byte(msiURL)).String()) + "}" -} - -func (up *Updater) switchOutputToFile() (io.Closer, error) { - var logFilePath string - exePath, err := os.Executable() - if err != nil { - logFilePath = filepath.Join(os.TempDir(), "tailscale-updater.log") - } else { - logFilePath = strings.TrimSuffix(exePath, ".exe") + ".log" - } - - up.Logf("writing update output to %q", logFilePath) - logFile, err := os.Create(logFilePath) - if err != nil { - return nil, err - } - - up.Logf = func(m string, args ...any) { - fmt.Fprintf(logFile, m+"\n", args...) - } - up.Stdout = logFile - up.Stderr = logFile - return logFile, nil -} diff --git a/vendor/tailscale.com/clientupdate/distsign/distsign.go b/vendor/tailscale.com/clientupdate/distsign/distsign.go deleted file mode 100644 index eba4b92..0000000 --- a/vendor/tailscale.com/clientupdate/distsign/distsign.go +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package distsign implements signature and validation of arbitrary -// distributable files. -// -// There are 3 parties in this exchange: -// - builder, which creates files, signs them with signing keys and publishes -// to server -// - server, which distributes public signing keys, files and signatures -// - client, which downloads files and signatures from server, and validates -// the signatures -// -// There are 2 types of keys: -// - signing keys, that sign individual distributable files on the builder -// - root keys, that sign signing keys and are kept offline -// -// root keys -(sign)-> signing keys -(sign)-> files -// -// All keys are asymmetric Ed25519 key pairs. -// -// The server serves static files under some known prefix. The kinds of files are: -// - distsign.pub - bundle of PEM-encoded public signing keys -// - distsign.pub.sig - signature of distsign.pub using one of the root keys -// - $file - any distributable file -// - $file.sig - signature of $file using any of the signing keys -// -// The root public keys are baked into the client software at compile time. -// These keys are long-lived and prove the validity of current signing keys -// from distsign.pub. To rotate root keys, a new client release must be -// published, they are not rotated dynamically. There are multiple root keys in -// different locations specifically to allow this rotation without using the -// discarded root key for any new signatures. -// -// The signing public keys are fetched by the client dynamically before every -// download and can be rotated more readily, assuming that most deployed -// clients trust the root keys used to issue fresh signing keys. -package distsign - -import ( - "context" - "crypto/ed25519" - "crypto/rand" - "encoding/binary" - "encoding/pem" - "errors" - "fmt" - "hash" - "io" - "log" - "net/http" - "net/url" - "os" - "time" - - "github.com/hdevalence/ed25519consensus" - "golang.org/x/crypto/blake2s" - "tailscale.com/net/tshttpproxy" - "tailscale.com/types/logger" - "tailscale.com/util/httpm" - "tailscale.com/util/must" -) - -const ( - pemTypeRootPrivate = "ROOT PRIVATE KEY" - pemTypeRootPublic = "ROOT PUBLIC KEY" - pemTypeSigningPrivate = "SIGNING PRIVATE KEY" - pemTypeSigningPublic = "SIGNING PUBLIC KEY" - - downloadSizeLimit = 1 << 29 // 512MB - signingKeysSizeLimit = 1 << 20 // 1MB - signatureSizeLimit = ed25519.SignatureSize -) - -// RootKey is a root key used to sign signing keys. -type RootKey struct { - k ed25519.PrivateKey -} - -// GenerateRootKey generates a new root key pair and encodes it as PEM. -func GenerateRootKey() (priv, pub []byte, err error) { - pub, priv, err = ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, nil, err - } - return pem.EncodeToMemory(&pem.Block{ - Type: pemTypeRootPrivate, - Bytes: []byte(priv), - }), pem.EncodeToMemory(&pem.Block{ - Type: pemTypeRootPublic, - Bytes: []byte(pub), - }), nil -} - -// ParseRootKey parses the PEM-encoded private root key. The key must be in the -// same format as returned by GenerateRootKey. -func ParseRootKey(privKey []byte) (*RootKey, error) { - k, err := parsePrivateKey(privKey, pemTypeRootPrivate) - if err != nil { - return nil, fmt.Errorf("failed to parse root key: %w", err) - } - return &RootKey{k: k}, nil -} - -// SignSigningKeys signs the bundle of public signing keys. The bundle must be -// a sequence of PEM blocks joined with newlines. -func (r *RootKey) SignSigningKeys(pubBundle []byte) ([]byte, error) { - if _, err := ParseSigningKeyBundle(pubBundle); err != nil { - return nil, err - } - return ed25519.Sign(r.k, pubBundle), nil -} - -// SigningKey is a signing key used to sign packages. -type SigningKey struct { - k ed25519.PrivateKey -} - -// GenerateSigningKey generates a new signing key pair and encodes it as PEM. -func GenerateSigningKey() (priv, pub []byte, err error) { - pub, priv, err = ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, nil, err - } - return pem.EncodeToMemory(&pem.Block{ - Type: pemTypeSigningPrivate, - Bytes: []byte(priv), - }), pem.EncodeToMemory(&pem.Block{ - Type: pemTypeSigningPublic, - Bytes: []byte(pub), - }), nil -} - -// ParseSigningKey parses the PEM-encoded private signing key. The key must be -// in the same format as returned by GenerateSigningKey. -func ParseSigningKey(privKey []byte) (*SigningKey, error) { - k, err := parsePrivateKey(privKey, pemTypeSigningPrivate) - if err != nil { - return nil, fmt.Errorf("failed to parse root key: %w", err) - } - return &SigningKey{k: k}, nil -} - -// SignPackageHash signs the hash and the length of a package. Use PackageHash -// to compute the inputs. -func (s *SigningKey) SignPackageHash(hash []byte, len int64) ([]byte, error) { - if len <= 0 { - return nil, fmt.Errorf("package length must be positive, got %d", len) - } - msg := binary.LittleEndian.AppendUint64(hash, uint64(len)) - return ed25519.Sign(s.k, msg), nil -} - -// PackageHash is a hash.Hash that counts the number of bytes written. Use it -// to get the hash and length inputs to SigningKey.SignPackageHash. -type PackageHash struct { - hash.Hash - len int64 -} - -// NewPackageHash returns an initialized PackageHash using BLAKE2s. -func NewPackageHash() *PackageHash { - h, err := blake2s.New256(nil) - if err != nil { - // Should never happen with a nil key passed to blake2s. - panic(err) - } - return &PackageHash{Hash: h} -} - -func (ph *PackageHash) Write(b []byte) (int, error) { - ph.len += int64(len(b)) - return ph.Hash.Write(b) -} - -// Reset the PackageHash to its initial state. -func (ph *PackageHash) Reset() { - ph.len = 0 - ph.Hash.Reset() -} - -// Len returns the total number of bytes written. -func (ph *PackageHash) Len() int64 { return ph.len } - -// Client downloads and validates files from a distribution server. -type Client struct { - logf logger.Logf - roots []ed25519.PublicKey - pkgsAddr *url.URL -} - -// NewClient returns a new client for distribution server located at pkgsAddr, -// and uses embedded root keys from the roots/ subdirectory of this package. -func NewClient(logf logger.Logf, pkgsAddr string) (*Client, error) { - if logf == nil { - logf = log.Printf - } - u, err := url.Parse(pkgsAddr) - if err != nil { - return nil, fmt.Errorf("invalid pkgsAddr %q: %w", pkgsAddr, err) - } - return &Client{logf: logf, roots: roots(), pkgsAddr: u}, nil -} - -func (c *Client) url(path string) string { - return c.pkgsAddr.JoinPath(path).String() -} - -// Download fetches a file at path srcPath from pkgsAddr passed in NewClient. -// The file is downloaded to dstPath and its signature is validated using the -// embedded root keys. Download returns an error if anything goes wrong with -// the actual file download or with signature validation. -func (c *Client) Download(ctx context.Context, srcPath, dstPath string) error { - // Always fetch a fresh signing key. - sigPub, err := c.signingKeys() - if err != nil { - return err - } - - srcURL := c.url(srcPath) - sigURL := srcURL + ".sig" - - c.logf("Downloading %q", srcURL) - dstPathUnverified := dstPath + ".unverified" - hash, len, err := c.download(ctx, srcURL, dstPathUnverified, downloadSizeLimit) - if err != nil { - return err - } - c.logf("Downloading %q", sigURL) - sig, err := fetch(sigURL, signatureSizeLimit) - if err != nil { - // Best-effort clean up of downloaded package. - os.Remove(dstPathUnverified) - return err - } - msg := binary.LittleEndian.AppendUint64(hash, uint64(len)) - if !VerifyAny(sigPub, msg, sig) { - // Best-effort clean up of downloaded package. - os.Remove(dstPathUnverified) - return fmt.Errorf("signature %q for file %q does not validate with the current release signing key; either you are under attack, or attempting to download an old version of Tailscale which was signed with an older signing key", sigURL, srcURL) - } - c.logf("Signature OK") - - if err := os.Rename(dstPathUnverified, dstPath); err != nil { - return fmt.Errorf("failed to move %q to %q after signature validation", dstPathUnverified, dstPath) - } - - return nil -} - -// ValidateLocalBinary fetches the latest signature associated with the binary -// at srcURLPath and uses it to validate the file located on disk via -// localFilePath. ValidateLocalBinary returns an error if anything goes wrong -// with the signature download or with signature validation. -func (c *Client) ValidateLocalBinary(srcURLPath, localFilePath string) error { - // Always fetch a fresh signing key. - sigPub, err := c.signingKeys() - if err != nil { - return err - } - - srcURL := c.url(srcURLPath) - sigURL := srcURL + ".sig" - - localFile, err := os.Open(localFilePath) - if err != nil { - return err - } - defer localFile.Close() - - h := NewPackageHash() - _, err = io.Copy(h, localFile) - if err != nil { - return err - } - hash, hashLen := h.Sum(nil), h.Len() - - c.logf("Downloading %q", sigURL) - sig, err := fetch(sigURL, signatureSizeLimit) - if err != nil { - return err - } - - msg := binary.LittleEndian.AppendUint64(hash, uint64(hashLen)) - if !VerifyAny(sigPub, msg, sig) { - return fmt.Errorf("signature %q for file %q does not validate with the current release signing key; either you are under attack, or attempting to download an old version of Tailscale which was signed with an older signing key", sigURL, localFilePath) - } - c.logf("Signature OK") - - return nil -} - -// signingKeys fetches current signing keys from the server and validates them -// against the roots. Should be called before validation of any downloaded file -// to get the fresh keys. -func (c *Client) signingKeys() ([]ed25519.PublicKey, error) { - keyURL := c.url("distsign.pub") - sigURL := keyURL + ".sig" - raw, err := fetch(keyURL, signingKeysSizeLimit) - if err != nil { - return nil, err - } - sig, err := fetch(sigURL, signatureSizeLimit) - if err != nil { - return nil, err - } - if !VerifyAny(c.roots, raw, sig) { - return nil, fmt.Errorf("signature %q for key %q does not validate with any known root key; either you are under attack, or running a very old version of Tailscale with outdated root keys", sigURL, keyURL) - } - - keys, err := ParseSigningKeyBundle(raw) - if err != nil { - return nil, fmt.Errorf("cannot parse signing key bundle from %q: %w", keyURL, err) - } - return keys, nil -} - -// fetch reads the response body from url into memory, up to limit bytes. -func fetch(url string, limit int64) ([]byte, error) { - resp, err := http.Get(url) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - return io.ReadAll(io.LimitReader(resp.Body, limit)) -} - -// download writes the response body of url into a local file at dst, up to -// limit bytes. On success, the returned value is a BLAKE2s hash of the file. -func (c *Client) download(ctx context.Context, url, dst string, limit int64) ([]byte, int64, error) { - tr := http.DefaultTransport.(*http.Transport).Clone() - tr.Proxy = tshttpproxy.ProxyFromEnvironment - defer tr.CloseIdleConnections() - hc := &http.Client{Transport: tr} - - quickCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - headReq := must.Get(http.NewRequestWithContext(quickCtx, httpm.HEAD, url, nil)) - - res, err := hc.Do(headReq) - if err != nil { - return nil, 0, err - } - if res.StatusCode != http.StatusOK { - return nil, 0, fmt.Errorf("HEAD %q: %v", url, res.Status) - } - if res.ContentLength <= 0 { - return nil, 0, fmt.Errorf("HEAD %q: unexpected Content-Length %v", url, res.ContentLength) - } - c.logf("Download size: %v", res.ContentLength) - - dlReq := must.Get(http.NewRequestWithContext(ctx, httpm.GET, url, nil)) - dlRes, err := hc.Do(dlReq) - if err != nil { - return nil, 0, err - } - defer dlRes.Body.Close() - // TODO(bradfitz): resume from existing partial file on disk - if dlRes.StatusCode != http.StatusOK { - return nil, 0, fmt.Errorf("GET %q: %v", url, dlRes.Status) - } - - of, err := os.Create(dst) - if err != nil { - return nil, 0, err - } - defer of.Close() - pw := &progressWriter{total: res.ContentLength, logf: c.logf} - h := NewPackageHash() - n, err := io.Copy(io.MultiWriter(of, h, pw), io.LimitReader(dlRes.Body, limit)) - if err != nil { - return nil, n, err - } - if n != res.ContentLength { - return nil, n, fmt.Errorf("GET %q: downloaded %v, want %v", url, n, res.ContentLength) - } - if err := dlRes.Body.Close(); err != nil { - return nil, n, err - } - if err := of.Close(); err != nil { - return nil, n, err - } - pw.print() - - return h.Sum(nil), h.Len(), nil -} - -type progressWriter struct { - done int64 - total int64 - lastPrint time.Time - logf logger.Logf -} - -func (pw *progressWriter) Write(p []byte) (n int, err error) { - pw.done += int64(len(p)) - if time.Since(pw.lastPrint) > 2*time.Second { - pw.print() - } - return len(p), nil -} - -func (pw *progressWriter) print() { - pw.lastPrint = time.Now() - pw.logf("Downloaded %v/%v (%.1f%%)", pw.done, pw.total, float64(pw.done)/float64(pw.total)*100) -} - -func parsePrivateKey(data []byte, typeTag string) (ed25519.PrivateKey, error) { - b, rest := pem.Decode(data) - if b == nil { - return nil, errors.New("failed to decode PEM data") - } - if len(rest) > 0 { - return nil, errors.New("trailing PEM data") - } - if b.Type != typeTag { - return nil, fmt.Errorf("PEM type is %q, want %q", b.Type, typeTag) - } - if len(b.Bytes) != ed25519.PrivateKeySize { - return nil, errors.New("private key has incorrect length for an Ed25519 private key") - } - return ed25519.PrivateKey(b.Bytes), nil -} - -// ParseSigningKeyBundle parses the bundle of PEM-encoded public signing keys. -func ParseSigningKeyBundle(bundle []byte) ([]ed25519.PublicKey, error) { - return parsePublicKeyBundle(bundle, pemTypeSigningPublic) -} - -// ParseRootKeyBundle parses the bundle of PEM-encoded public root keys. -func ParseRootKeyBundle(bundle []byte) ([]ed25519.PublicKey, error) { - return parsePublicKeyBundle(bundle, pemTypeRootPublic) -} - -func parsePublicKeyBundle(bundle []byte, typeTag string) ([]ed25519.PublicKey, error) { - var keys []ed25519.PublicKey - for len(bundle) > 0 { - pub, rest, err := parsePublicKey(bundle, typeTag) - if err != nil { - return nil, err - } - keys = append(keys, pub) - bundle = rest - } - if len(keys) == 0 { - return nil, errors.New("no signing keys found in the bundle") - } - return keys, nil -} - -func parseSinglePublicKey(data []byte, typeTag string) (ed25519.PublicKey, error) { - pub, rest, err := parsePublicKey(data, typeTag) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, errors.New("trailing PEM data") - } - return pub, err -} - -func parsePublicKey(data []byte, typeTag string) (pub ed25519.PublicKey, rest []byte, retErr error) { - b, rest := pem.Decode(data) - if b == nil { - return nil, nil, errors.New("failed to decode PEM data") - } - if b.Type != typeTag { - return nil, nil, fmt.Errorf("PEM type is %q, want %q", b.Type, typeTag) - } - if len(b.Bytes) != ed25519.PublicKeySize { - return nil, nil, errors.New("public key has incorrect length for an Ed25519 public key") - } - return ed25519.PublicKey(b.Bytes), rest, nil -} - -// VerifyAny verifies whether sig is valid for msg using any of the keys. -// VerifyAny will panic if any of the keys have the wrong size for Ed25519. -func VerifyAny(keys []ed25519.PublicKey, msg, sig []byte) bool { - for _, k := range keys { - if ed25519consensus.Verify(k, msg, sig) { - return true - } - } - return false -} diff --git a/vendor/tailscale.com/clientupdate/distsign/roots.go b/vendor/tailscale.com/clientupdate/distsign/roots.go deleted file mode 100644 index d5b47b7..0000000 --- a/vendor/tailscale.com/clientupdate/distsign/roots.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package distsign - -import ( - "crypto/ed25519" - "embed" - "errors" - "fmt" - "path" - "path/filepath" - "sync" -) - -//go:embed roots -var rootsFS embed.FS - -var roots = sync.OnceValue(func() []ed25519.PublicKey { - roots, err := parseRoots() - if err != nil { - panic(err) - } - return roots -}) - -func parseRoots() ([]ed25519.PublicKey, error) { - files, err := rootsFS.ReadDir("roots") - if err != nil { - return nil, err - } - var keys []ed25519.PublicKey - for _, f := range files { - if !f.Type().IsRegular() { - continue - } - if filepath.Ext(f.Name()) != ".pem" { - continue - } - raw, err := rootsFS.ReadFile(path.Join("roots", f.Name())) - if err != nil { - return nil, err - } - key, err := parseSinglePublicKey(raw, pemTypeRootPublic) - if err != nil { - return nil, fmt.Errorf("parsing root key %q: %w", f.Name(), err) - } - keys = append(keys, key) - } - if len(keys) == 0 { - return nil, errors.New("no embedded root keys, please check clientupdate/distsign/roots/") - } - return keys, nil -} diff --git a/vendor/tailscale.com/clientupdate/distsign/roots/crawshaw-root.pem b/vendor/tailscale.com/clientupdate/distsign/roots/crawshaw-root.pem deleted file mode 100644 index f80b9ae..0000000 --- a/vendor/tailscale.com/clientupdate/distsign/roots/crawshaw-root.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN ROOT PUBLIC KEY----- -Psrabv2YNiEDhPlnLVSMtB5EKACm7zxvKxfvYD4i7X8= ------END ROOT PUBLIC KEY----- diff --git a/vendor/tailscale.com/clientupdate/distsign/roots/distsign-prod-root-1-pub.pem b/vendor/tailscale.com/clientupdate/distsign/roots/distsign-prod-root-1-pub.pem deleted file mode 100644 index d5d6516..0000000 --- a/vendor/tailscale.com/clientupdate/distsign/roots/distsign-prod-root-1-pub.pem +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN ROOT PUBLIC KEY----- -ZjjKhUHBtLNRSO1dhOTjrXJGJ8lDe1594WM2XDuheVQ= ------END ROOT PUBLIC KEY----- diff --git a/vendor/tailscale.com/control/controlbase/conn.go b/vendor/tailscale.com/control/controlbase/conn.go index dc22212..78ef73f 100644 --- a/vendor/tailscale.com/control/controlbase/conn.go +++ b/vendor/tailscale.com/control/controlbase/conn.go @@ -18,6 +18,7 @@ import ( "golang.org/x/crypto/blake2s" chp "golang.org/x/crypto/chacha20poly1305" + "tailscale.com/syncs" "tailscale.com/types/key" ) @@ -48,7 +49,7 @@ type Conn struct { // rxState is all the Conn state that Read uses. type rxState struct { - sync.Mutex + syncs.Mutex cipher cipher.AEAD nonce nonce buf *maxMsgBuffer // or nil when reads exhausted diff --git a/vendor/tailscale.com/control/controlclient/auto.go b/vendor/tailscale.com/control/controlclient/auto.go index e0168c1..336a8d4 100644 --- a/vendor/tailscale.com/control/controlclient/auto.go +++ b/vendor/tailscale.com/control/controlclient/auto.go @@ -12,7 +12,6 @@ import ( "sync/atomic" "time" - "tailscale.com/logtail/backoff" "tailscale.com/net/sockstats" "tailscale.com/tailcfg" "tailscale.com/tstime" @@ -21,8 +20,10 @@ import ( "tailscale.com/types/netmap" "tailscale.com/types/persist" "tailscale.com/types/structs" + "tailscale.com/util/backoff" "tailscale.com/util/clientmetric" "tailscale.com/util/execqueue" + "tailscale.com/util/testenv" ) type LoginGoal struct { @@ -117,14 +118,13 @@ type Auto struct { logf logger.Logf closed bool updateCh chan struct{} // readable when we should inform the server of a change - observer Observer // called to update Client status; always non-nil + observer Observer // if non-nil, called to update Client status observerQueue execqueue.ExecQueue shutdownFn func() // to be called prior to shutdown or nil - unregisterHealthWatch func() - mu sync.Mutex // mutex guards the following fields + started bool // whether [Auto.Start] has been called wantLoggedIn bool // whether the user wants to be logged in per last method call urlToVisit string // the last url we were told to visit expiry time.Time @@ -140,7 +140,6 @@ type Auto struct { loggedIn bool // true if currently logged in loginGoal *LoginGoal // non-nil if some login activity is desired inMapPoll bool // true once we get the first MapResponse in a stream; false when HTTP response ends - state State // TODO(bradfitz): delete this, make it computed by method from other state authCtx context.Context // context used for auth requests mapCtx context.Context // context used for netmap and update requests @@ -153,15 +152,21 @@ type Auto struct { // New creates and starts a new Auto. func New(opts Options) (*Auto, error) { - c, err := NewNoStart(opts) - if c != nil { - c.Start() + c, err := newNoStart(opts) + if err != nil { + return nil, err + } + if opts.StartPaused { + c.SetPaused(true) + } + if !opts.SkipStartForTests { + c.start() } return c, err } -// NewNoStart creates a new Auto, but without calling Start on it. -func NewNoStart(opts Options) (_ *Auto, err error) { +// newNoStart creates a new Auto, but without calling Start on it. +func newNoStart(opts Options) (_ *Auto, err error) { direct, err := NewDirect(opts) if err != nil { return nil, err @@ -172,9 +177,6 @@ func NewNoStart(opts Options) (_ *Auto, err error) { } }() - if opts.Observer == nil { - return nil, errors.New("missing required Options.Observer") - } if opts.Logf == nil { opts.Logf = func(fmt string, args ...any) {} } @@ -192,15 +194,14 @@ func NewNoStart(opts Options) (_ *Auto, err error) { observer: opts.Observer, shutdownFn: opts.Shutdown, } + c.authCtx, c.authCancel = context.WithCancel(context.Background()) c.authCtx = sockstats.WithSockStats(c.authCtx, sockstats.LabelControlClientAuto, opts.Logf) c.mapCtx, c.mapCancel = context.WithCancel(context.Background()) c.mapCtx = sockstats.WithSockStats(c.mapCtx, sockstats.LabelControlClientAuto, opts.Logf) - c.unregisterHealthWatch = opts.HealthTracker.RegisterWatcher(direct.ReportHealthChange) return c, nil - } // SetPaused controls whether HTTP activity should be paused. @@ -225,10 +226,21 @@ func (c *Auto) SetPaused(paused bool) { c.unpauseWaiters = nil } -// Start starts the client's goroutines. +// StartForTest starts the client's goroutines. // -// It should only be called for clients created by NewNoStart. -func (c *Auto) Start() { +// It should only be called for clients created with [Options.SkipStartForTests]. +func (c *Auto) StartForTest() { + testenv.AssertInTest() + c.start() +} + +func (c *Auto) start() { + c.mu.Lock() + defer c.mu.Unlock() + if c.started { + return + } + c.started = true go c.authRoutine() go c.mapRoutine() go c.updateRoutine() @@ -302,10 +314,11 @@ func (c *Auto) authRoutine() { c.mu.Lock() goal := c.loginGoal ctx := c.authCtx + loggedIn := c.loggedIn if goal != nil { - c.logf("[v1] authRoutine: %s; wantLoggedIn=%v", c.state, true) + c.logf("[v1] authRoutine: loggedIn=%v; wantLoggedIn=%v", loggedIn, true) } else { - c.logf("[v1] authRoutine: %s; goal=nil paused=%v", c.state, c.paused) + c.logf("[v1] authRoutine: loggedIn=%v; goal=nil paused=%v", loggedIn, c.paused) } c.mu.Unlock() @@ -328,11 +341,6 @@ func (c *Auto) authRoutine() { c.mu.Lock() c.urlToVisit = goal.url - if goal.url != "" { - c.state = StateURLVisitRequired - } else { - c.state = StateAuthenticating - } c.mu.Unlock() var url string @@ -366,7 +374,6 @@ func (c *Auto) authRoutine() { flags: LoginDefault, url: url, } - c.state = StateURLVisitRequired c.mu.Unlock() c.sendStatus("authRoutine-url", err, url, nil) @@ -386,7 +393,6 @@ func (c *Auto) authRoutine() { c.urlToVisit = "" c.loggedIn = true c.loginGoal = nil - c.state = StateAuthenticated c.mu.Unlock() c.sendStatus("authRoutine-success", nil, "", nil) @@ -419,6 +425,11 @@ func (c *Auto) unpausedChanLocked() <-chan bool { return unpaused } +// ClientID returns the ClientID of the direct controlClient +func (c *Auto) ClientID() int64 { + return c.direct.ClientID() +} + // mapRoutineState is the state of Auto.mapRoutine while it's running. type mapRoutineState struct { c *Auto @@ -431,21 +442,17 @@ func (mrs mapRoutineState) UpdateFullNetmap(nm *netmap.NetworkMap) { c := mrs.c c.mu.Lock() - ctx := c.mapCtx c.inMapPoll = true - if c.loggedIn { - c.state = StateSynchronized - } - c.expiry = nm.Expiry + c.expiry = nm.SelfKeyExpiry() stillAuthed := c.loggedIn - c.logf("[v1] mapRoutine: netmap received: %s", c.state) + c.logf("[v1] mapRoutine: netmap received: loggedIn=%v inMapPoll=true", stillAuthed) c.mu.Unlock() if stillAuthed { c.sendStatus("mapRoutine-got-netmap", nil, "", nm) } // Reset the backoff timer if we got a netmap. - mrs.bo.BackOff(ctx, nil) + mrs.bo.Reset() } func (mrs mapRoutineState) UpdateNetmapDelta(muts []netmap.NodeMutation) bool { @@ -486,8 +493,8 @@ func (c *Auto) mapRoutine() { } c.mu.Lock() - c.logf("[v1] mapRoutine: %s", c.state) loggedIn := c.loggedIn + c.logf("[v1] mapRoutine: loggedIn=%v", loggedIn) ctx := c.mapCtx c.mu.Unlock() @@ -518,9 +525,6 @@ func (c *Auto) mapRoutine() { c.direct.health.SetOutOfPollNetMap() c.mu.Lock() c.inMapPoll = false - if c.state == StateSynchronized { - c.state = StateAuthenticated - } paused := c.paused c.mu.Unlock() @@ -586,12 +590,12 @@ func (c *Auto) sendStatus(who string, err error, url string, nm *netmap.NetworkM c.mu.Unlock() return } - state := c.state loggedIn := c.loggedIn inMapPoll := c.inMapPoll + loginGoal := c.loginGoal c.mu.Unlock() - c.logf("[v1] sendStatus: %s: %v", who, state) + c.logf("[v1] sendStatus: %s: loggedIn=%v inMapPoll=%v", who, loggedIn, inMapPoll) var p persist.PersistView if nm != nil && loggedIn && inMapPoll { @@ -602,18 +606,31 @@ func (c *Auto) sendStatus(who string, err error, url string, nm *netmap.NetworkM nm = nil } newSt := &Status{ - URL: url, - Persist: p, - NetMap: nm, - Err: err, - state: state, + URL: url, + Persist: p, + NetMap: nm, + Err: err, + LoggedIn: loggedIn && loginGoal == nil, + InMapPoll: inMapPoll, } + + if c.observer == nil { + return + } + c.lastStatus.Store(newSt) // Launch a new goroutine to avoid blocking the caller while the observer // does its thing, which may result in a call back into the client. metricQueued.Add(1) c.observerQueue.Add(func() { + c.mu.Lock() + closed := c.closed + c.mu.Unlock() + if closed { + return + } + if canSkipStatus(newSt, c.lastStatus.Load()) { metricSkippable.Add(1) if !c.direct.controlKnobs.DisableSkipStatusQueue.Load() { @@ -657,14 +674,15 @@ func canSkipStatus(s1, s2 *Status) bool { // we can't skip it. return false } - if s1.Err != nil || s1.URL != "" { - // If s1 has an error or a URL, we shouldn't skip it, lest the error go - // away in s2 or in-between. We want to make sure all the subsystems see - // it. Plus there aren't many of these, so not worth skipping. + if s1.Err != nil || s1.URL != "" || s1.LoggedIn { + // If s1 has an error, a URL, or LoginFinished set, we shouldn't skip it, + // lest the error go away in s2 or in-between. We want to make sure all + // the subsystems see it. Plus there aren't many of these, so not worth + // skipping. return false } - if !s1.Persist.Equals(s2.Persist) || s1.state != s2.state { - // If s1 has a different Persist or state than s2, + if !s1.Persist.Equals(s2.Persist) || s1.LoggedIn != s2.LoggedIn || s1.InMapPoll != s2.InMapPoll || s1.URL != s2.URL { + // If s1 has a different Persist, LoginFinished, Synced, or URL than s2, // don't skip it. We only care about skipping the typical // entries where the only difference is the NetMap. return false @@ -726,7 +744,6 @@ func (c *Auto) Logout(ctx context.Context) error { } c.mu.Lock() c.loggedIn = false - c.state = StateNotAuthenticated c.cancelAuthCtxLocked() c.cancelMapCtxLocked() c.mu.Unlock() @@ -750,6 +767,13 @@ func (c *Auto) UpdateEndpoints(endpoints []tailcfg.Endpoint) { } } +// SetDiscoPublicKey sets the client's Disco public to key and sends the change +// to the control server. +func (c *Auto) SetDiscoPublicKey(key key.DiscoPublic) { + c.direct.SetDiscoPublicKey(key) + c.updateControl() +} + func (c *Auto) Shutdown() { c.mu.Lock() if c.closed { @@ -774,7 +798,6 @@ func (c *Auto) Shutdown() { shutdownFn() } - c.unregisterHealthWatch() <-c.authDone <-c.mapDone <-c.updateDone @@ -813,13 +836,3 @@ func (c *Auto) SetDNS(ctx context.Context, req *tailcfg.SetDNSRequest) error { func (c *Auto) DoNoiseRequest(req *http.Request) (*http.Response, error) { return c.direct.DoNoiseRequest(req) } - -// GetSingleUseNoiseRoundTripper returns a RoundTripper that can be only be used -// once (and must be used once) to make a single HTTP request over the noise -// channel to the coordination server. -// -// In addition to the RoundTripper, it returns the HTTP/2 channel's early noise -// payload, if any. -func (c *Auto) GetSingleUseNoiseRoundTripper(ctx context.Context) (http.RoundTripper, *tailcfg.EarlyNoise, error) { - return c.direct.GetSingleUseNoiseRoundTripper(ctx) -} diff --git a/vendor/tailscale.com/control/controlclient/client.go b/vendor/tailscale.com/control/controlclient/client.go index 8df64f9..41b3962 100644 --- a/vendor/tailscale.com/control/controlclient/client.go +++ b/vendor/tailscale.com/control/controlclient/client.go @@ -12,6 +12,7 @@ import ( "context" "tailscale.com/tailcfg" + "tailscale.com/types/key" ) // LoginFlags is a bitmask of options to change the behavior of Client.Login @@ -80,7 +81,15 @@ type Client interface { // TODO: a server-side change would let us simply upload this // in a separate http request. It has nothing to do with the rest of // the state machine. + // Note: the auto client uploads the new endpoints to control immediately. UpdateEndpoints(endpoints []tailcfg.Endpoint) + // SetDiscoPublicKey updates the disco public key that will be sent in + // future map requests. This should be called after rotating the discovery key. + // Note: the auto client uploads the new key to control immediately. + SetDiscoPublicKey(key.DiscoPublic) + // ClientID returns the ClientID of a client. This ID is meant to + // distinguish one client from another. + ClientID() int64 } // UserVisibleError is an error that should be shown to users. diff --git a/vendor/tailscale.com/control/controlclient/direct.go b/vendor/tailscale.com/control/controlclient/direct.go index 68ab9ca..d5cd6a1 100644 --- a/vendor/tailscale.com/control/controlclient/direct.go +++ b/vendor/tailscale.com/control/controlclient/direct.go @@ -4,9 +4,11 @@ package controlclient import ( - "bufio" "bytes" + "cmp" "context" + "crypto" + "crypto/sha256" "encoding/binary" "encoding/json" "errors" @@ -16,19 +18,20 @@ import ( "net" "net/http" "net/netip" - "net/url" "os" "reflect" "runtime" "slices" "strings" - "sync" "sync/atomic" "time" "go4.org/mem" "tailscale.com/control/controlknobs" + "tailscale.com/control/ts2021" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/hostinfo" "tailscale.com/ipn/ipnstate" @@ -37,11 +40,11 @@ import ( "tailscale.com/net/dnsfallback" "tailscale.com/net/netmon" "tailscale.com/net/netutil" + "tailscale.com/net/netx" "tailscale.com/net/tlsdial" "tailscale.com/net/tsdial" - "tailscale.com/net/tshttpproxy" + "tailscale.com/syncs" "tailscale.com/tailcfg" - "tailscale.com/tempfork/httprec" "tailscale.com/tka" "tailscale.com/tstime" "tailscale.com/types/key" @@ -51,62 +54,70 @@ import ( "tailscale.com/types/ptr" "tailscale.com/types/tkatype" "tailscale.com/util/clientmetric" - "tailscale.com/util/multierr" + "tailscale.com/util/eventbus" "tailscale.com/util/singleflight" - "tailscale.com/util/syspolicy" - "tailscale.com/util/systemd" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" "tailscale.com/util/testenv" "tailscale.com/util/zstdframe" ) // Direct is the client that connects to a tailcontrol server for a node. type Direct struct { - httpc *http.Client // HTTP client used to talk to tailcontrol - interceptedDial *atomic.Bool // if non-nil, pointer to bool whether ScreenTime intercepted our dial - dialer *tsdial.Dialer - dnsCache *dnscache.Resolver - controlKnobs *controlknobs.Knobs // always non-nil - serverURL string // URL of the tailcontrol server - clock tstime.Clock - logf logger.Logf - netMon *netmon.Monitor // non-nil - health *health.Tracker - discoPubKey key.DiscoPublic - getMachinePrivKey func() (key.MachinePrivate, error) - debugFlags []string - skipIPForwardingCheck bool - pinger Pinger - popBrowser func(url string) // or nil - c2nHandler http.Handler // or nil - onClientVersion func(*tailcfg.ClientVersion) // or nil - onControlTime func(time.Time) // or nil - onTailnetDefaultAutoUpdate func(bool) // or nil - panicOnUse bool // if true, panic if client is used (for testing) - closedCtx context.Context // alive until Direct.Close is called - closeCtx context.CancelFunc // cancels closedCtx + httpc *http.Client // HTTP client used to do TLS requests to control (just https://controlplane.tailscale.com/key?v=123) + interceptedDial *atomic.Bool // if non-nil, pointer to bool whether ScreenTime intercepted our dial + dialer *tsdial.Dialer + dnsCache *dnscache.Resolver + controlKnobs *controlknobs.Knobs // always non-nil + serverURL string // URL of the tailcontrol server + clock tstime.Clock + logf logger.Logf + netMon *netmon.Monitor // non-nil + health *health.Tracker + busClient *eventbus.Client + clientVersionPub *eventbus.Publisher[tailcfg.ClientVersion] + autoUpdatePub *eventbus.Publisher[AutoUpdate] + controlTimePub *eventbus.Publisher[ControlTime] + getMachinePrivKey func() (key.MachinePrivate, error) + debugFlags []string + skipIPForwardingCheck bool + pinger Pinger + popBrowser func(url string) // or nil + polc policyclient.Client // always non-nil + c2nHandler http.Handler // or nil + panicOnUse bool // if true, panic if client is used (for testing) + closedCtx context.Context // alive until Direct.Close is called + closeCtx context.CancelFunc // cancels closedCtx dialPlan ControlDialPlanner // can be nil - mu sync.Mutex // mutex guards the following fields + mu syncs.Mutex // mutex guards the following fields serverLegacyKey key.MachinePublic // original ("legacy") nacl crypto_box-based public key; only used for signRegisterRequest on Windows now serverNoiseKey key.MachinePublic + discoPubKey key.DiscoPublic // protected by mu; can be updated via [SetDiscoPublicKey] - sfGroup singleflight.Group[struct{}, *NoiseClient] // protects noiseClient creation. - noiseClient *NoiseClient + sfGroup singleflight.Group[struct{}, *ts2021.Client] // protects noiseClient creation. + noiseClient *ts2021.Client // also protected by mu - persist persist.PersistView - authKey string - tryingNewKey key.NodePrivate - expiry time.Time // or zero value if none/unknown - hostinfo *tailcfg.Hostinfo // always non-nil - netinfo *tailcfg.NetInfo - endpoints []tailcfg.Endpoint - tkaHead string - lastPingURL string // last PingRequest.URL received, for dup suppression + persist persist.PersistView + authKey string + tryingNewKey key.NodePrivate + expiry time.Time // or zero value if none/unknown + hostinfo *tailcfg.Hostinfo // always non-nil + netinfo *tailcfg.NetInfo + endpoints []tailcfg.Endpoint + tkaHead string + lastPingURL string // last PingRequest.URL received, for dup suppression + connectionHandleForTest string // sent in MapRequest.ConnectionHandleForTest + + controlClientID int64 // Random ID used to differentiate clients for consumers of messages. } // Observer is implemented by users of the control client (such as LocalBackend) // to get notified of changes in the control client's status. +// +// If an implementation of Observer also implements [NetmapDeltaUpdater], they get +// delta updates as well as full netmap updates. type Observer interface { // SetControlClientStatus is called when the client has a new status to // report. The Client is provided to allow the Observer to track which @@ -116,28 +127,36 @@ type Observer interface { } type Options struct { - Persist persist.Persist // initial persistent data - GetMachinePrivateKey func() (key.MachinePrivate, error) // returns the machine key to use - ServerURL string // URL of the tailcontrol server - AuthKey string // optional node auth key for auto registration - Clock tstime.Clock - Hostinfo *tailcfg.Hostinfo // non-nil passes ownership, nil means to use default using os.Hostname, etc - DiscoPublicKey key.DiscoPublic - Logf logger.Logf - HTTPTestClient *http.Client // optional HTTP client to use (for tests only) - NoiseTestClient *http.Client // optional HTTP client to use for noise RPCs (tests only) - DebugFlags []string // debug settings to send to control - HealthTracker *health.Tracker - PopBrowserURL func(url string) // optional func to open browser - OnClientVersion func(*tailcfg.ClientVersion) // optional func to inform GUI of client version status - OnControlTime func(time.Time) // optional func to notify callers of new time from control - OnTailnetDefaultAutoUpdate func(bool) // optional func to inform GUI of default auto-update setting for the tailnet - Dialer *tsdial.Dialer // non-nil - C2NHandler http.Handler // or nil - ControlKnobs *controlknobs.Knobs // or nil to ignore + Persist persist.Persist // initial persistent data + GetMachinePrivateKey func() (key.MachinePrivate, error) // returns the machine key to use + ServerURL string // URL of the tailcontrol server + AuthKey string // optional node auth key for auto registration + Clock tstime.Clock + Hostinfo *tailcfg.Hostinfo // non-nil passes ownership, nil means to use default using os.Hostname, etc + DiscoPublicKey key.DiscoPublic + PolicyClient policyclient.Client // or nil for none + Logf logger.Logf + HTTPTestClient *http.Client // optional HTTP client to use (for tests only) + NoiseTestClient *http.Client // optional HTTP client to use for noise RPCs (tests only) + DebugFlags []string // debug settings to send to control + HealthTracker *health.Tracker + PopBrowserURL func(url string) // optional func to open browser + Dialer *tsdial.Dialer // non-nil + C2NHandler http.Handler // or nil + ControlKnobs *controlknobs.Knobs // or nil to ignore + Bus *eventbus.Bus // non-nil, for setting up publishers + + SkipStartForTests bool // if true, don't call [Auto.Start] to avoid any background goroutines (for tests only) + + // StartPaused indicates whether the client should start in a paused state + // where it doesn't do network requests. This primarily exists for testing + // but not necessarily "go test" tests, so it isn't restricted to only + // being used in tests. + StartPaused bool // Observer is called when there's a change in status to report // from the control client. + // If nil, no status updates are reported. Observer Observer // SkipIPForwardingCheck declares that the host's IP @@ -213,6 +232,8 @@ type NetmapDeltaUpdater interface { UpdateNetmapDelta([]netmap.NodeMutation) (ok bool) } +var nextControlClientID atomic.Int64 + // NewDirect returns a new Direct client. func NewDirect(opts Options) (*Direct, error) { if opts.ServerURL == "" { @@ -238,10 +259,6 @@ func NewDirect(opts Options) (*Direct, error) { opts.ControlKnobs = &controlknobs.Knobs{} } opts.ServerURL = strings.TrimRight(opts.ServerURL, "/") - serverURL, err := url.Parse(opts.ServerURL) - if err != nil { - return nil, err - } if opts.Clock == nil { opts.Clock = tstime.StdClock{} } @@ -269,10 +286,14 @@ func NewDirect(opts Options) (*Direct, error) { var interceptedDial *atomic.Bool if httpc == nil { tr := http.DefaultTransport.(*http.Transport).Clone() - tr.Proxy = tshttpproxy.ProxyFromEnvironment - tshttpproxy.SetTransportGetProxyConnectHeader(tr) - tr.TLSClientConfig = tlsdial.Config(serverURL.Hostname(), opts.HealthTracker, tr.TLSClientConfig) - var dialFunc dialFunc + if buildfeatures.HasUseProxy { + tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil() + if f, ok := feature.HookProxySetTransportGetProxyConnectHeader.GetOk(); ok { + f(tr) + } + } + tr.TLSClientConfig = tlsdial.Config(opts.HealthTracker, tr.TLSClientConfig) + var dialFunc netx.DialFunc dialFunc, interceptedDial = makeScreenTimeDetectingDialFunc(opts.Dialer.SystemDial) tr.DialContext = dnscache.Dialer(dialFunc, dnsCache) tr.DialTLSContext = dnscache.TLSDialer(dialFunc, dnsCache, tr.TLSClientConfig) @@ -286,32 +307,32 @@ func NewDirect(opts Options) (*Direct, error) { } c := &Direct{ - httpc: httpc, - interceptedDial: interceptedDial, - controlKnobs: opts.ControlKnobs, - getMachinePrivKey: opts.GetMachinePrivateKey, - serverURL: opts.ServerURL, - clock: opts.Clock, - logf: opts.Logf, - persist: opts.Persist.View(), - authKey: opts.AuthKey, - discoPubKey: opts.DiscoPublicKey, - debugFlags: opts.DebugFlags, - netMon: netMon, - health: opts.HealthTracker, - skipIPForwardingCheck: opts.SkipIPForwardingCheck, - pinger: opts.Pinger, - popBrowser: opts.PopBrowserURL, - onClientVersion: opts.OnClientVersion, - onTailnetDefaultAutoUpdate: opts.OnTailnetDefaultAutoUpdate, - onControlTime: opts.OnControlTime, - c2nHandler: opts.C2NHandler, - dialer: opts.Dialer, - dnsCache: dnsCache, - dialPlan: opts.DialPlan, + httpc: httpc, + interceptedDial: interceptedDial, + controlKnobs: opts.ControlKnobs, + getMachinePrivKey: opts.GetMachinePrivateKey, + serverURL: opts.ServerURL, + clock: opts.Clock, + logf: opts.Logf, + persist: opts.Persist.View(), + authKey: opts.AuthKey, + debugFlags: opts.DebugFlags, + netMon: netMon, + health: opts.HealthTracker, + skipIPForwardingCheck: opts.SkipIPForwardingCheck, + pinger: opts.Pinger, + polc: cmp.Or(opts.PolicyClient, policyclient.Client(policyclient.NoPolicyClient{})), + popBrowser: opts.PopBrowserURL, + c2nHandler: opts.C2NHandler, + dialer: opts.Dialer, + dnsCache: dnsCache, + dialPlan: opts.DialPlan, } + c.discoPubKey = opts.DiscoPublicKey c.closedCtx, c.closeCtx = context.WithCancel(context.Background()) + c.controlClientID = nextControlClientID.Add(1) + if opts.Hostinfo == nil { c.SetHostinfo(hostinfo.New()) } else { @@ -321,7 +342,7 @@ func NewDirect(opts Options) (*Direct, error) { } } if opts.NoiseTestClient != nil { - c.noiseClient = &NoiseClient{ + c.noiseClient = &ts2021.Client{ Client: opts.NoiseTestClient, } c.serverNoiseKey = key.NewMachine().Public() // prevent early error before hitting test client @@ -329,6 +350,12 @@ func NewDirect(opts Options) (*Direct, error) { if strings.Contains(opts.ServerURL, "controlplane.tailscale.com") && envknob.Bool("TS_PANIC_IF_HIT_MAIN_CONTROL") { c.panicOnUse = true } + + c.busClient = opts.Bus.Client("controlClient.direct") + c.clientVersionPub = eventbus.Publish[tailcfg.ClientVersion](c.busClient) + c.autoUpdatePub = eventbus.Publish[AutoUpdate](c.busClient) + c.controlTimePub = eventbus.Publish[ControlTime](c.busClient) + return c, nil } @@ -338,15 +365,14 @@ func (c *Direct) Close() error { c.mu.Lock() defer c.mu.Unlock() + c.busClient.Close() if c.noiseClient != nil { if err := c.noiseClient.Close(); err != nil { return err } } c.noiseClient = nil - if tr, ok := c.httpc.Transport.(*http.Transport); ok { - tr.CloseIdleConnections() - } + c.httpc.CloseIdleConnections() return nil } @@ -387,7 +413,7 @@ func (c *Direct) SetNetInfo(ni *tailcfg.NetInfo) bool { return true } -// SetNetInfo stores a new TKA head value for next update. +// SetTKAHead stores a new TKA head value for next update. // It reports whether the TKA head changed. func (c *Direct) SetTKAHead(tkaHead string) bool { c.mu.Lock() @@ -402,6 +428,14 @@ func (c *Direct) SetTKAHead(tkaHead string) bool { return true } +// SetConnectionHandleForTest stores a new MapRequest.ConnectionHandleForTest +// value for the next update. +func (c *Direct) SetConnectionHandleForTest(handle string) { + c.mu.Lock() + defer c.mu.Unlock() + c.connectionHandleForTest = handle +} + func (c *Direct) GetPersist() persist.PersistView { c.mu.Lock() defer c.mu.Unlock() @@ -523,7 +557,9 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new } else { if expired { c.logf("Old key expired -> regen=true") - systemd.Status("key expired; run 'tailscale up' to authenticate") + if f, ok := feature.HookSystemdStatus.GetOk(); ok { + f("key expired; run 'tailscale up' to authenticate") + } regen = true } if (opt.Flags & LoginInteractive) != 0 { @@ -582,6 +618,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new if persist.NetworkLockKey.IsZero() { persist.NetworkLockKey = key.NewNLPrivate() } + nlPub := persist.NetworkLockKey.Public() if tryingNewKey.IsZero() { @@ -611,7 +648,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new return regen, opt.URL, nil, err } - tailnet, err := syspolicy.GetString(syspolicy.Tailnet, "") + tailnet, err := c.polc.GetString(pkey.Tailnet, "") if err != nil { c.logf("unable to provide Tailnet field in register request. err: %v", err) } @@ -641,7 +678,7 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new AuthKey: authKey, } } - err = signRegisterRequest(&request, c.serverURL, c.serverLegacyKey, machinePrivKey.Public()) + err = signRegisterRequest(c.polc, &request, c.serverURL, c.serverLegacyKey, machinePrivKey.Public()) if err != nil { // If signing failed, clear all related fields request.SignatureType = tailcfg.SignatureNone @@ -678,8 +715,8 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new if err != nil { return regen, opt.URL, nil, err } - addLBHeader(req, request.OldNodeKey) - addLBHeader(req, request.NodeKey) + ts2021.AddLBHeader(req, request.OldNodeKey) + ts2021.AddLBHeader(req, request.NodeKey) res, err := httpc.Do(req) if err != nil { @@ -816,6 +853,31 @@ func (c *Direct) SendUpdate(ctx context.Context) error { return c.sendMapRequest(ctx, false, nil) } +// SetDiscoPublicKey updates the disco public key in local state. +// It does not implicitly trigger [SendUpdate]; callers should arrange for that. +func (c *Direct) SetDiscoPublicKey(key key.DiscoPublic) { + c.mu.Lock() + defer c.mu.Unlock() + c.discoPubKey = key +} + +// ClientID returns the controlClientID of the controlClient. +func (c *Direct) ClientID() int64 { + return c.controlClientID +} + +// AutoUpdate is an eventbus value, reporting the value of tailcfg.MapResponse.DefaultAutoUpdate. +type AutoUpdate struct { + ClientID int64 // The ID field is used for consumers to differentiate instances of Direct. + Value bool // The Value represents DefaultAutoUpdate from [tailcfg.MapResponse]. +} + +// ControlTime is an eventbus value, reporting the value of tailcfg.MapResponse.ControlTime. +type ControlTime struct { + ClientID int64 // The ID field is used for consumers to differentiate instances of Direct. + Value time.Time // The Value represents ControlTime from [tailcfg.MapResponse]. +} + // If we go more than watchdogTimeout without hearing from the server, // end the long poll. We should be receiving a keep alive ping // every minute. @@ -848,8 +910,11 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap persist := c.persist serverURL := c.serverURL serverNoiseKey := c.serverNoiseKey + discoKey := c.discoPubKey hi := c.hostInfoLocked() backendLogID := hi.BackendLogID + connectionHandleForTest := c.connectionHandleForTest + tkaHead := c.tkaHead var epStrs []string var eps []netip.AddrPort var epTypes []tailcfg.EndpointType @@ -889,21 +954,44 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap } nodeKey := persist.PublicNodeKey() + request := &tailcfg.MapRequest{ - Version: tailcfg.CurrentCapabilityVersion, - KeepAlive: true, - NodeKey: nodeKey, - DiscoKey: c.discoPubKey, - Endpoints: eps, - EndpointTypes: epTypes, - Stream: isStreaming, - Hostinfo: hi, - DebugFlags: c.debugFlags, - OmitPeers: nu == nil, - TKAHead: c.tkaHead, + Version: tailcfg.CurrentCapabilityVersion, + KeepAlive: true, + NodeKey: nodeKey, + DiscoKey: discoKey, + Endpoints: eps, + EndpointTypes: epTypes, + Stream: isStreaming, + Hostinfo: hi, + DebugFlags: c.debugFlags, + OmitPeers: nu == nil, + TKAHead: tkaHead, + ConnectionHandleForTest: connectionHandleForTest, } + + // If we have a hardware attestation key, sign the node key with it and send + // the key & signature in the map request. + if buildfeatures.HasTPM { + if k := persist.AsStruct().AttestationKey; k != nil && !k.IsZero() { + hwPub := key.HardwareAttestationPublicFromPlatformKey(k) + request.HardwareAttestationKey = hwPub + + t := c.clock.Now() + msg := fmt.Sprintf("%d|%s", t.Unix(), nodeKey.String()) + digest := sha256.Sum256([]byte(msg)) + sig, err := k.Sign(nil, digest[:], crypto.SHA256) + if err != nil { + c.logf("failed to sign node key with hardware attestation key: %v", err) + } else { + request.HardwareAttestationKeySignature = sig + request.HardwareAttestationKeySignatureTimestamp = t + } + } + } + var extraDebugFlags []string - if hi != nil && c.netMon != nil && !c.skipIPForwardingCheck && + if buildfeatures.HasAdvertiseRoutes && hi != nil && c.netMon != nil && !c.skipIPForwardingCheck && ipForwardingBroken(hi.RoutableIPs, c.netMon.InterfaceState()) { extraDebugFlags = append(extraDebugFlags, "warn-ip-forwarding-off") } @@ -967,7 +1055,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap if err != nil { return err } - addLBHeader(req, nodeKey) + ts2021.AddLBHeader(req, nodeKey) res, err := httpc.Do(req) if err != nil { @@ -1015,7 +1103,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap c.persist = newPersist.View() persist = c.persist } - c.expiry = nm.Expiry + c.expiry = nm.SelfKeyExpiry() } // gotNonKeepAliveMessage is whether we've yet received a MapResponse message without @@ -1047,7 +1135,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap vlogf("netmap: read body after %v", time.Since(t0).Round(time.Millisecond)) var resp tailcfg.MapResponse - if err := c.decodeMsg(msg, &resp); err != nil { + if err := sess.decodeMsg(msg, &resp); err != nil { vlogf("netmap: decode error: %v", err) return err } @@ -1072,21 +1160,19 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap c.logf("netmap: control says to open URL %v; no popBrowser func", u) } } - if resp.ClientVersion != nil && c.onClientVersion != nil { - c.onClientVersion(resp.ClientVersion) + if resp.ClientVersion != nil { + c.clientVersionPub.Publish(*resp.ClientVersion) } if resp.ControlTime != nil && !resp.ControlTime.IsZero() { c.logf.JSON(1, "controltime", resp.ControlTime.UTC()) - if c.onControlTime != nil { - c.onControlTime(*resp.ControlTime) - } + c.controlTimePub.Publish(ControlTime{c.controlClientID, *resp.ControlTime}) } if resp.KeepAlive { vlogf("netmap: got keep-alive") } else { vlogf("netmap: got new map") } - if resp.ControlDialPlan != nil { + if resp.ControlDialPlan != nil && !ignoreDialPlan() { if c.dialPlan != nil { c.logf("netmap: got new dial plan from control") c.dialPlan.Store(resp.ControlDialPlan) @@ -1098,11 +1184,21 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap metricMapResponseKeepAlives.Add(1) continue } - if au, ok := resp.DefaultAutoUpdate.Get(); ok { - if c.onTailnetDefaultAutoUpdate != nil { - c.onTailnetDefaultAutoUpdate(au) + + // DefaultAutoUpdate in its CapMap and deprecated top-level field forms. + if self := resp.Node; self != nil { + for _, v := range self.CapMap[tailcfg.NodeAttrDefaultAutoUpdate] { + switch v { + case "true", "false": + c.autoUpdatePub.Publish(AutoUpdate{c.controlClientID, v == "true"}) + default: + c.logf("netmap: [unexpected] unknown %s in CapMap: %q", tailcfg.NodeAttrDefaultAutoUpdate, v) + } } } + if au, ok := resp.DeprecatedDefaultAutoUpdate.Get(); ok { + c.autoUpdatePub.Publish(AutoUpdate{c.controlClientID, au}) + } metricMapResponseMap.Add(1) if gotNonKeepAliveMessage { @@ -1125,12 +1221,33 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap return nil } +// NetmapFromMapResponseForDebug returns a NetworkMap from the given MapResponse. +// It is intended for debugging only. +func NetmapFromMapResponseForDebug(ctx context.Context, pr persist.PersistView, resp *tailcfg.MapResponse) (*netmap.NetworkMap, error) { + if resp == nil { + return nil, errors.New("nil MapResponse") + } + if resp.Node == nil { + return nil, errors.New("MapResponse lacks Node") + } + + nu := &rememberLastNetmapUpdater{} + sess := newMapSession(pr.PrivateNodeKey(), nu, nil) + defer sess.Close() + + if err := sess.HandleNonKeepAliveMapResponse(ctx, resp); err != nil { + return nil, fmt.Errorf("HandleNonKeepAliveMapResponse: %w", err) + } + + return sess.netmap(), nil +} + func (c *Direct) handleDebugMessage(ctx context.Context, debug *tailcfg.Debug) error { if code := debug.Exit; code != nil { c.logf("exiting process with status %v per controlplane", *code) os.Exit(*code) } - if debug.DisableLogTail { + if buildfeatures.HasLogTail && debug.DisableLogTail { logtail.Disable() envknob.SetNoLogsNoSupport() } @@ -1179,12 +1296,23 @@ func decode(res *http.Response, v any) error { var jsonEscapedZero = []byte(`\u0000`) +const justKeepAliveStr = `{"KeepAlive":true}` + // decodeMsg is responsible for uncompressing msg and unmarshaling into v. -func (c *Direct) decodeMsg(compressedMsg []byte, v any) error { +func (sess *mapSession) decodeMsg(compressedMsg []byte, v *tailcfg.MapResponse) error { + // Fast path for common case of keep-alive message. + // See tailscale/tailscale#17343. + if sess.keepAliveZ != nil && bytes.Equal(compressedMsg, sess.keepAliveZ) { + v.KeepAlive = true + return nil + } + b, err := zstdframe.AppendDecode(nil, compressedMsg) if err != nil { return err } + sess.ztdDecodesForTest++ + if DevKnob.DumpNetMaps() { var buf bytes.Buffer json.Indent(&buf, b, "", " ") @@ -1197,6 +1325,9 @@ func (c *Direct) decodeMsg(compressedMsg []byte, v any) error { if err := json.Unmarshal(b, v); err != nil { return fmt.Errorf("response: %v", err) } + if v.KeepAlive && string(b) == justKeepAliveStr { + sess.keepAliveZ = compressedMsg + } return nil } @@ -1244,7 +1375,7 @@ func loadServerPubKeys(ctx context.Context, httpc *http.Client, serverURL string out = tailcfg.OverTLSPublicKeyResponse{} k, err := key.ParseMachinePublicUntyped(mem.B(b)) if err != nil { - return nil, multierr.New(jsonErr, err) + return nil, errors.Join(jsonErr, err) } out.LegacyPublicKey = k return &out, nil @@ -1314,6 +1445,10 @@ func (c *Direct) isUniquePingRequest(pr *tailcfg.PingRequest) bool { return true } +// HookAnswerC2NPing is where feature/c2n conditionally registers support +// for handling C2N (control-to-node) HTTP requests. +var HookAnswerC2NPing feature.Hook[func(logger.Logf, http.Handler, *http.Client, *tailcfg.PingRequest)] + func (c *Direct) answerPing(pr *tailcfg.PingRequest) { httpc := c.httpc useNoise := pr.URLIsNoise || pr.Types == "c2n" @@ -1334,11 +1469,16 @@ func (c *Direct) answerPing(pr *tailcfg.PingRequest) { answerHeadPing(c.logf, httpc, pr) return case "c2n": + if !buildfeatures.HasC2N { + return + } if !useNoise && !envknob.Bool("TS_DEBUG_PERMIT_HTTP_C2N") { c.logf("refusing to answer c2n ping without noise") return } - answerC2NPing(c.logf, c.c2nHandler, httpc, pr) + if f, ok := HookAnswerC2NPing.GetOk(); ok { + f(c.logf, c.c2nHandler, httpc, pr) + } return } for _, t := range strings.Split(pr.Types, ",") { @@ -1373,54 +1513,6 @@ func answerHeadPing(logf logger.Logf, c *http.Client, pr *tailcfg.PingRequest) { } } -func answerC2NPing(logf logger.Logf, c2nHandler http.Handler, c *http.Client, pr *tailcfg.PingRequest) { - if c2nHandler == nil { - logf("answerC2NPing: c2nHandler not defined") - return - } - hreq, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(pr.Payload))) - if err != nil { - logf("answerC2NPing: ReadRequest: %v", err) - return - } - if pr.Log { - logf("answerC2NPing: got c2n request for %v ...", hreq.RequestURI) - } - handlerTimeout := time.Minute - if v := hreq.Header.Get("C2n-Handler-Timeout"); v != "" { - handlerTimeout, _ = time.ParseDuration(v) - } - handlerCtx, cancel := context.WithTimeout(context.Background(), handlerTimeout) - defer cancel() - hreq = hreq.WithContext(handlerCtx) - rec := httprec.NewRecorder() - c2nHandler.ServeHTTP(rec, hreq) - cancel() - - c2nResBuf := new(bytes.Buffer) - rec.Result().Write(c2nResBuf) - - replyCtx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - req, err := http.NewRequestWithContext(replyCtx, "POST", pr.URL, c2nResBuf) - if err != nil { - logf("answerC2NPing: NewRequestWithContext: %v", err) - return - } - if pr.Log { - logf("answerC2NPing: sending POST ping to %v ...", pr.URL) - } - t0 := clock.Now() - _, err = c.Do(req) - d := time.Since(t0).Round(time.Millisecond) - if err != nil { - logf("answerC2NPing error: %v to %v (after %v)", err, pr.URL, d) - } else if pr.Log { - logf("answerC2NPing complete to %v (after %v)", pr.URL, d) - } -} - // sleepAsRequest implements the sleep for a tailcfg.Debug message requesting // that the client sleep. The complication is that while we're sleeping (if for // a long time), we need to periodically reset the watchdog timer before it @@ -1445,7 +1537,7 @@ func sleepAsRequested(ctx context.Context, logf logger.Logf, d time.Duration, cl } // getNoiseClient returns the noise client, creating one if one doesn't exist. -func (c *Direct) getNoiseClient() (*NoiseClient, error) { +func (c *Direct) getNoiseClient() (*ts2021.Client, error) { c.mu.Lock() serverNoiseKey := c.serverNoiseKey nc := c.noiseClient @@ -1460,13 +1552,13 @@ func (c *Direct) getNoiseClient() (*NoiseClient, error) { if c.dialPlan != nil { dp = c.dialPlan.Load } - nc, err, _ := c.sfGroup.Do(struct{}{}, func() (*NoiseClient, error) { + nc, err, _ := c.sfGroup.Do(struct{}{}, func() (*ts2021.Client, error) { k, err := c.getMachinePrivKey() if err != nil { return nil, err } c.logf("[v1] creating new noise client") - nc, err := NewNoiseClient(NoiseOpts{ + nc, err := ts2021.NewClient(ts2021.ClientOpts{ PrivKey: k, ServerPubKey: serverNoiseKey, ServerURL: c.serverURL, @@ -1500,7 +1592,7 @@ func (c *Direct) setDNSNoise(ctx context.Context, req *tailcfg.SetDNSRequest) er if err != nil { return err } - res, err := nc.post(ctx, "/machine/set-dns", newReq.NodeKey, &newReq) + res, err := nc.Post(ctx, "/machine/set-dns", newReq.NodeKey, &newReq) if err != nil { return err } @@ -1521,6 +1613,9 @@ func (c *Direct) setDNSNoise(ctx context.Context, req *tailcfg.SetDNSRequest) er // SetDNS sends the SetDNSRequest request to the control plane server, // requesting a DNS record be created or updated. func (c *Direct) SetDNS(ctx context.Context, req *tailcfg.SetDNSRequest) (err error) { + if !buildfeatures.HasACME { + return feature.ErrUnavailable + } metricSetDNS.Add(1) defer func() { if err != nil { @@ -1541,20 +1636,6 @@ func (c *Direct) DoNoiseRequest(req *http.Request) (*http.Response, error) { return nc.Do(req) } -// GetSingleUseNoiseRoundTripper returns a RoundTripper that can be only be used -// once (and must be used once) to make a single HTTP request over the noise -// channel to the coordination server. -// -// In addition to the RoundTripper, it returns the HTTP/2 channel's early noise -// payload, if any. -func (c *Direct) GetSingleUseNoiseRoundTripper(ctx context.Context) (http.RoundTripper, *tailcfg.EarlyNoise, error) { - nc, err := c.getNoiseClient() - if err != nil { - return nil, nil, err - } - return nc.GetSingleUseRoundTripper(ctx) -} - // doPingerPing sends a Ping to pr.IP using pinger, and sends an http request back to // pr.URL with ping response data. func doPingerPing(logf logger.Logf, c *http.Client, pr *tailcfg.PingRequest, pinger Pinger, pingType tailcfg.PingType) { @@ -1611,47 +1692,6 @@ func postPingResult(start time.Time, logf logger.Logf, c *http.Client, pr *tailc return nil } -// ReportHealthChange reports to the control plane a change to this node's -// health. w must be non-nil. us can be nil to indicate a healthy state for w. -func (c *Direct) ReportHealthChange(w *health.Warnable, us *health.UnhealthyState) { - if w == health.NetworkStatusWarnable || w == health.IPNStateWarnable || w == health.LoginStateWarnable { - // We don't report these. These include things like the network is down - // (in which case we can't report anyway) or the user wanted things - // stopped, as opposed to the more unexpected failure types in the other - // subsystems. - return - } - np, err := c.getNoiseClient() - if err != nil { - // Don't report errors to control if the server doesn't support noise. - return - } - nodeKey, ok := c.GetPersist().PublicNodeKeyOK() - if !ok { - return - } - if c.panicOnUse { - panic("tainted client") - } - // TODO(angott): at some point, update `Subsys` in the request to be `Warnable` - req := &tailcfg.HealthChangeRequest{ - Subsys: string(w.Code), - NodeKey: nodeKey, - } - if us != nil { - req.Error = us.Text - } - - // Best effort, no logging: - ctx, cancel := context.WithTimeout(c.closedCtx, 5*time.Second) - defer cancel() - res, err := np.post(ctx, "/machine/update-health", nodeKey, req) - if err != nil { - return - } - res.Body.Close() -} - // SetDeviceAttrs does a synchronous call to the control plane to update // the node's attributes. // @@ -1690,7 +1730,7 @@ func (c *Direct) SetDeviceAttrs(ctx context.Context, attrs tailcfg.AttrUpdate) e ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - res, err := nc.doWithBody(ctx, "PATCH", "/machine/set-device-attr", nodeKey, req) + res, err := nc.DoWithBody(ctx, "PATCH", "/machine/set-device-attr", nodeKey, req) if err != nil { return err } @@ -1731,7 +1771,7 @@ func (c *Direct) sendAuditLog(ctx context.Context, auditLog tailcfg.AuditLogRequ panic("tainted client") } - res, err := nc.post(ctx, "/machine/audit-log", nodeKey, req) + res, err := nc.Post(ctx, "/machine/audit-log", nodeKey, req) if err != nil { return fmt.Errorf("%w: %w", errHTTPPostFailure, err) } @@ -1743,20 +1783,12 @@ func (c *Direct) sendAuditLog(ctx context.Context, auditLog tailcfg.AuditLogRequ return nil } -func addLBHeader(req *http.Request, nodeKey key.NodePublic) { - if !nodeKey.IsZero() { - req.Header.Add(tailcfg.LBHeader, nodeKey.String()) - } -} - -type dialFunc = func(ctx context.Context, network, addr string) (net.Conn, error) - // makeScreenTimeDetectingDialFunc returns dialFunc, optionally wrapped (on // Apple systems) with a func that sets the returned atomic.Bool for whether // Screen Time seemed to intercept the connection. // // The returned *atomic.Bool is nil on non-Apple systems. -func makeScreenTimeDetectingDialFunc(dial dialFunc) (dialFunc, *atomic.Bool) { +func makeScreenTimeDetectingDialFunc(dial netx.DialFunc) (netx.DialFunc, *atomic.Bool) { switch runtime.GOOS { case "darwin", "ios": // Continue below. @@ -1774,6 +1806,13 @@ func makeScreenTimeDetectingDialFunc(dial dialFunc) (dialFunc, *atomic.Bool) { }, ab } +func ignoreDialPlan() bool { + // If we're running in v86 (a JavaScript-based emulation of a 32-bit x86) + // our networking is very limited. Let's ignore the dial plan since it's too + // complicated to race that many IPs anyway. + return hostinfo.IsInVM86() +} + func isTCPLoopback(a net.Addr) bool { if ta, ok := a.(*net.TCPAddr); ok { return ta.IP.IsLoopback() diff --git a/vendor/tailscale.com/control/controlclient/map.go b/vendor/tailscale.com/control/controlclient/map.go index 769c8f1..9aa8e37 100644 --- a/vendor/tailscale.com/control/controlclient/map.go +++ b/vendor/tailscale.com/control/controlclient/map.go @@ -6,7 +6,10 @@ package controlclient import ( "cmp" "context" + "crypto/sha256" + "encoding/hex" "encoding/json" + "io" "maps" "net" "reflect" @@ -19,6 +22,7 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/envknob" + "tailscale.com/hostinfo" "tailscale.com/tailcfg" "tailscale.com/tstime" "tailscale.com/types/key" @@ -53,6 +57,9 @@ type mapSession struct { altClock tstime.Clock // if nil, regular time is used cancel context.CancelFunc // always non-nil, shuts down caller's base long poll context + keepAliveZ []byte // if non-nil, the learned zstd encoding of the just-KeepAlive message for this session + ztdDecodesForTest int // for testing + // sessionAliveCtx is a Background-based context that's alive for the // duration of the mapSession that we own the lifetime of. It's closed by // sessionAliveCtxClose. @@ -86,6 +93,7 @@ type mapSession struct { lastDomain string lastDomainAuditLogID string lastHealth []string + lastDisplayMessages map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage lastPopBrowserURL string lastTKAInfo *tailcfg.TKAInfo lastNetmapSummary string // from NetworkMap.VeryConcise @@ -308,6 +316,31 @@ func (ms *mapSession) updateStateFromResponse(resp *tailcfg.MapResponse) { } } + // In the copy/v86 wasm environment with limited networking, if the + // control plane didn't pick our DERP home for us, do it ourselves and + // mark all but the lowest region as NoMeasureNoHome. For prod, this + // will be Region 1, NYC, a compromise between the US and Europe. But + // really the control plane should pick this. This is only a fallback. + if hostinfo.IsInVM86() { + numCanMeasure := 0 + lowest := 0 + for rid, r := range dm.Regions { + if !r.NoMeasureNoHome { + numCanMeasure++ + if lowest == 0 || rid < lowest { + lowest = rid + } + } + } + if numCanMeasure > 1 { + for rid, r := range dm.Regions { + if rid != lowest { + r.NoMeasureNoHome = true + } + } + } + } + // Zero-valued fields in a DERPMap mean that we're not changing // anything and are using the previous value(s). if ldm := ms.lastDERPMap; ldm != nil { @@ -383,6 +416,21 @@ func (ms *mapSession) updateStateFromResponse(resp *tailcfg.MapResponse) { if resp.Health != nil { ms.lastHealth = resp.Health } + if resp.DisplayMessages != nil { + if v, ok := resp.DisplayMessages["*"]; ok && v == nil { + ms.lastDisplayMessages = nil + } + for k, v := range resp.DisplayMessages { + if k == "*" { + continue + } + if v != nil { + mak.Set(&ms.lastDisplayMessages, k, *v) + } else { + delete(ms.lastDisplayMessages, k) + } + } + } if resp.TKAInfo != nil { ms.lastTKAInfo = resp.TKAInfo } @@ -802,9 +850,23 @@ func (ms *mapSession) sortedPeers() []tailcfg.NodeView { func (ms *mapSession) netmap() *netmap.NetworkMap { peerViews := ms.sortedPeers() + var msgs map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage + if len(ms.lastDisplayMessages) != 0 { + msgs = ms.lastDisplayMessages + } else if len(ms.lastHealth) > 0 { + // Convert all ms.lastHealth to the new [netmap.NetworkMap.DisplayMessages] + for _, h := range ms.lastHealth { + id := "health-" + strhash(h) // Unique ID in case there is more than one health message + mak.Set(&msgs, tailcfg.DisplayMessageID(id), tailcfg.DisplayMessage{ + Title: "Coordination server reports an issue", + Severity: tailcfg.SeverityMedium, + Text: "The coordination server is reporting a health issue: " + h, + }) + } + } + nm := &netmap.NetworkMap{ NodeKey: ms.publicNodeKey, - PrivateKey: ms.privateNodeKey, MachineKey: ms.machinePubKey, Peers: peerViews, UserProfiles: make(map[tailcfg.UserID]tailcfg.UserProfileView), @@ -816,7 +878,7 @@ func (ms *mapSession) netmap() *netmap.NetworkMap { SSHPolicy: ms.lastSSHPolicy, CollectServices: ms.collectServices, DERPMap: ms.lastDERPMap, - ControlHealth: ms.lastHealth, + DisplayMessages: msgs, TKAEnabled: ms.lastTKAInfo != nil && !ms.lastTKAInfo.Disabled, } @@ -829,8 +891,6 @@ func (ms *mapSession) netmap() *netmap.NetworkMap { if node := ms.lastNode; node.Valid() { nm.SelfNode = node - nm.Expiry = node.KeyExpiry() - nm.Name = node.Name() nm.AllCaps = ms.lastCapSet } @@ -842,5 +902,12 @@ func (ms *mapSession) netmap() *netmap.NetworkMap { if DevKnob.ForceProxyDNS() { nm.DNS.Proxied = true } + return nm } + +func strhash(h string) string { + s := sha256.New() + io.WriteString(s, h) + return hex.EncodeToString(s.Sum(nil)) +} diff --git a/vendor/tailscale.com/control/controlclient/noise.go b/vendor/tailscale.com/control/controlclient/noise.go deleted file mode 100644 index 4bd8cfc..0000000 --- a/vendor/tailscale.com/control/controlclient/noise.go +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package controlclient - -import ( - "bytes" - "cmp" - "context" - "encoding/json" - "errors" - "math" - "net/http" - "net/netip" - "net/url" - "sync" - "time" - - "golang.org/x/net/http2" - "tailscale.com/control/controlhttp" - "tailscale.com/health" - "tailscale.com/internal/noiseconn" - "tailscale.com/net/dnscache" - "tailscale.com/net/netmon" - "tailscale.com/net/tsdial" - "tailscale.com/tailcfg" - "tailscale.com/tstime" - "tailscale.com/types/key" - "tailscale.com/types/logger" - "tailscale.com/util/mak" - "tailscale.com/util/multierr" - "tailscale.com/util/singleflight" -) - -// NoiseClient provides a http.Client to connect to tailcontrol over -// the ts2021 protocol. -type NoiseClient struct { - // Client is an HTTP client to talk to the coordination server. - // It automatically makes a new Noise connection as needed. - // It does not support node key proofs. To do that, call - // noiseClient.getConn instead to make a connection. - *http.Client - - // h2t is the HTTP/2 transport we use a bit to create new - // *http2.ClientConns. We don't use its connection pool and we don't use its - // dialing. We use it for exactly one reason: its idle timeout that can only - // be configured via the HTTP/1 config. And then we call NewClientConn (with - // an existing Noise connection) on the http2.Transport which sets up an - // http2.ClientConn using that idle timeout from an http1.Transport. - h2t *http2.Transport - - // sfDial ensures that two concurrent requests for a noise connection only - // produce one shared one between the two callers. - sfDial singleflight.Group[struct{}, *noiseconn.Conn] - - dialer *tsdial.Dialer - dnsCache *dnscache.Resolver - privKey key.MachinePrivate - serverPubKey key.MachinePublic - host string // the host part of serverURL - httpPort string // the default port to dial - httpsPort string // the fallback Noise-over-https port or empty if none - - // dialPlan optionally returns a ControlDialPlan previously received - // from the control server; either the function or the return value can - // be nil. - dialPlan func() *tailcfg.ControlDialPlan - - logf logger.Logf - netMon *netmon.Monitor - health *health.Tracker - - // mu only protects the following variables. - mu sync.Mutex - closed bool - last *noiseconn.Conn // or nil - nextID int - connPool map[int]*noiseconn.Conn // active connections not yet closed; see noiseconn.Conn.Close -} - -// NoiseOpts contains options for the NewNoiseClient function. All fields are -// required unless otherwise specified. -type NoiseOpts struct { - // PrivKey is this node's private key. - PrivKey key.MachinePrivate - // ServerPubKey is the public key of the server. - ServerPubKey key.MachinePublic - // ServerURL is the URL of the server to connect to. - ServerURL string - // Dialer's SystemDial function is used to connect to the server. - Dialer *tsdial.Dialer - // DNSCache is the caching Resolver to use to connect to the server. - // - // This field can be nil. - DNSCache *dnscache.Resolver - // Logf is the log function to use. This field can be nil. - Logf logger.Logf - // NetMon is the network monitor that, if set, will be used to get the - // network interface state. This field can be nil; if so, the current - // state will be looked up dynamically. - NetMon *netmon.Monitor - // HealthTracker, if non-nil, is the health tracker to use. - HealthTracker *health.Tracker - // DialPlan, if set, is a function that should return an explicit plan - // on how to connect to the server. - DialPlan func() *tailcfg.ControlDialPlan -} - -// NewNoiseClient returns a new noiseClient for the provided server and machine key. -// serverURL is of the form https://: (no trailing slash). -// -// netMon may be nil, if non-nil it's used to do faster interface lookups. -// dialPlan may be nil -func NewNoiseClient(opts NoiseOpts) (*NoiseClient, error) { - logf := opts.Logf - u, err := url.Parse(opts.ServerURL) - if err != nil { - return nil, err - } - - if u.Scheme != "http" && u.Scheme != "https" { - return nil, errors.New("invalid ServerURL scheme, must be http or https") - } - - var httpPort string - var httpsPort string - addr, _ := netip.ParseAddr(u.Hostname()) - isPrivateHost := addr.IsPrivate() || addr.IsLoopback() || u.Hostname() == "localhost" - if port := u.Port(); port != "" { - // If there is an explicit port specified, entirely rely on the scheme, - // unless it's http with a private host in which case we never try using HTTPS. - if u.Scheme == "https" { - httpPort = "" - httpsPort = port - } else if u.Scheme == "http" { - httpPort = port - httpsPort = "443" - if isPrivateHost { - logf("setting empty HTTPS port with http scheme and private host %s", u.Hostname()) - httpsPort = "" - } - } - } else if u.Scheme == "http" && isPrivateHost { - // Whenever the scheme is http and the hostname is an IP address, do not set the HTTPS port, - // as there cannot be a TLS certificate issued for an IP, unless it's a public IP. - httpPort = "80" - httpsPort = "" - } else { - // Otherwise, use the standard ports - httpPort = "80" - httpsPort = "443" - } - - np := &NoiseClient{ - serverPubKey: opts.ServerPubKey, - privKey: opts.PrivKey, - host: u.Hostname(), - httpPort: httpPort, - httpsPort: httpsPort, - dialer: opts.Dialer, - dnsCache: opts.DNSCache, - dialPlan: opts.DialPlan, - logf: opts.Logf, - netMon: opts.NetMon, - health: opts.HealthTracker, - } - - // Create the HTTP/2 Transport using a net/http.Transport - // (which only does HTTP/1) because it's the only way to - // configure certain properties on the http2.Transport. But we - // never actually use the net/http.Transport for any HTTP/1 - // requests. - h2Transport, err := http2.ConfigureTransports(&http.Transport{ - IdleConnTimeout: time.Minute, - }) - if err != nil { - return nil, err - } - np.h2t = h2Transport - - np.Client = &http.Client{Transport: np} - return np, nil -} - -// GetSingleUseRoundTripper returns a RoundTripper that can be only be used once -// (and must be used once) to make a single HTTP request over the noise channel -// to the coordination server. -// -// In addition to the RoundTripper, it returns the HTTP/2 channel's early noise -// payload, if any. -func (nc *NoiseClient) GetSingleUseRoundTripper(ctx context.Context) (http.RoundTripper, *tailcfg.EarlyNoise, error) { - for tries := 0; tries < 3; tries++ { - conn, err := nc.getConn(ctx) - if err != nil { - return nil, nil, err - } - ok, earlyPayloadMaybeNil, err := conn.ReserveNewRequest(ctx) - if err != nil { - return nil, nil, err - } - if ok { - return conn, earlyPayloadMaybeNil, nil - } - } - return nil, nil, errors.New("[unexpected] failed to reserve a request on a connection") -} - -// contextErr is an error that wraps another error and is used to indicate that -// the error was because a context expired. -type contextErr struct { - err error -} - -func (e contextErr) Error() string { - return e.err.Error() -} - -func (e contextErr) Unwrap() error { - return e.err -} - -// getConn returns a noiseconn.Conn that can be used to make requests to the -// coordination server. It may return a cached connection or create a new one. -// Dials are singleflighted, so concurrent calls to getConn may only dial once. -// As such, context values may not be respected as there are no guarantees that -// the context passed to getConn is the same as the context passed to dial. -func (nc *NoiseClient) getConn(ctx context.Context) (*noiseconn.Conn, error) { - nc.mu.Lock() - if last := nc.last; last != nil && last.CanTakeNewRequest() { - nc.mu.Unlock() - return last, nil - } - nc.mu.Unlock() - - for { - // We singeflight the dial to avoid making multiple connections, however - // that means that we can't simply cancel the dial if the context is - // canceled. Instead, we have to additionally check that the context - // which was canceled is our context and retry if our context is still - // valid. - conn, err, _ := nc.sfDial.Do(struct{}{}, func() (*noiseconn.Conn, error) { - c, err := nc.dial(ctx) - if err != nil { - if ctx.Err() != nil { - return nil, contextErr{ctx.Err()} - } - return nil, err - } - return c, nil - }) - var ce contextErr - if err == nil || !errors.As(err, &ce) { - return conn, err - } - if ctx.Err() == nil { - // The dial failed because of a context error, but our context - // is still valid. Retry. - continue - } - // The dial failed because our context was canceled. Return the - // underlying error. - return nil, ce.Unwrap() - } -} - -func (nc *NoiseClient) RoundTrip(req *http.Request) (*http.Response, error) { - ctx := req.Context() - conn, err := nc.getConn(ctx) - if err != nil { - return nil, err - } - return conn.RoundTrip(req) -} - -// connClosed removes the connection with the provided ID from the pool -// of active connections. -func (nc *NoiseClient) connClosed(id int) { - nc.mu.Lock() - defer nc.mu.Unlock() - conn := nc.connPool[id] - if conn != nil { - delete(nc.connPool, id) - if nc.last == conn { - nc.last = nil - } - } -} - -// Close closes all the underlying noise connections. -// It is a no-op and returns nil if the connection is already closed. -func (nc *NoiseClient) Close() error { - nc.mu.Lock() - nc.closed = true - conns := nc.connPool - nc.connPool = nil - nc.mu.Unlock() - - var errors []error - for _, c := range conns { - if err := c.Close(); err != nil { - errors = append(errors, err) - } - } - return multierr.New(errors...) -} - -// dial opens a new connection to tailcontrol, fetching the server noise key -// if not cached. -func (nc *NoiseClient) dial(ctx context.Context) (*noiseconn.Conn, error) { - nc.mu.Lock() - connID := nc.nextID - nc.nextID++ - nc.mu.Unlock() - - if tailcfg.CurrentCapabilityVersion > math.MaxUint16 { - // Panic, because a test should have started failing several - // thousand version numbers before getting to this point. - panic("capability version is too high to fit in the wire protocol") - } - - var dialPlan *tailcfg.ControlDialPlan - if nc.dialPlan != nil { - dialPlan = nc.dialPlan() - } - - // If we have a dial plan, then set our timeout as slightly longer than - // the maximum amount of time contained therein; we assume that - // explicit instructions on timeouts are more useful than a single - // hard-coded timeout. - // - // The default value of 5 is chosen so that, when there's no dial plan, - // we retain the previous behaviour of 10 seconds end-to-end timeout. - timeoutSec := 5.0 - if dialPlan != nil { - for _, c := range dialPlan.Candidates { - if v := c.DialStartDelaySec + c.DialTimeoutSec; v > timeoutSec { - timeoutSec = v - } - } - } - - // After we establish a connection, we need some time to actually - // upgrade it into a Noise connection. With a ballpark worst-case RTT - // of 1000ms, give ourselves an extra 5 seconds to complete the - // handshake. - timeoutSec += 5 - - // Be extremely defensive and ensure that the timeout is in the range - // [5, 60] seconds (e.g. if we accidentally get a negative number). - if timeoutSec > 60 { - timeoutSec = 60 - } else if timeoutSec < 5 { - timeoutSec = 5 - } - - timeout := time.Duration(timeoutSec * float64(time.Second)) - ctx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - - clientConn, err := (&controlhttp.Dialer{ - Hostname: nc.host, - HTTPPort: nc.httpPort, - HTTPSPort: cmp.Or(nc.httpsPort, controlhttp.NoPort), - MachineKey: nc.privKey, - ControlKey: nc.serverPubKey, - ProtocolVersion: uint16(tailcfg.CurrentCapabilityVersion), - Dialer: nc.dialer.SystemDial, - DNSCache: nc.dnsCache, - DialPlan: dialPlan, - Logf: nc.logf, - NetMon: nc.netMon, - HealthTracker: nc.health, - Clock: tstime.StdClock{}, - }).Dial(ctx) - if err != nil { - return nil, err - } - - ncc, err := noiseconn.New(clientConn.Conn, nc.h2t, connID, nc.connClosed) - if err != nil { - return nil, err - } - - nc.mu.Lock() - if nc.closed { - nc.mu.Unlock() - ncc.Close() // Needs to be called without holding the lock. - return nil, errors.New("noise client closed") - } - defer nc.mu.Unlock() - mak.Set(&nc.connPool, connID, ncc) - nc.last = ncc - return ncc, nil -} - -// post does a POST to the control server at the given path, JSON-encoding body. -// The provided nodeKey is an optional load balancing hint. -func (nc *NoiseClient) post(ctx context.Context, path string, nodeKey key.NodePublic, body any) (*http.Response, error) { - return nc.doWithBody(ctx, "POST", path, nodeKey, body) -} - -func (nc *NoiseClient) doWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error) { - jbody, err := json.Marshal(body) - if err != nil { - return nil, err - } - req, err := http.NewRequestWithContext(ctx, method, "https://"+nc.host+path, bytes.NewReader(jbody)) - if err != nil { - return nil, err - } - addLBHeader(req, nodeKey) - req.Header.Set("Content-Type", "application/json") - conn, err := nc.getConn(ctx) - if err != nil { - return nil, err - } - return conn.RoundTrip(req) -} diff --git a/vendor/tailscale.com/control/controlclient/sign_supported.go b/vendor/tailscale.com/control/controlclient/sign_supported.go index a5d42ad..439e6d3 100644 --- a/vendor/tailscale.com/control/controlclient/sign_supported.go +++ b/vendor/tailscale.com/control/controlclient/sign_supported.go @@ -18,7 +18,8 @@ import ( "github.com/tailscale/certstore" "tailscale.com/tailcfg" "tailscale.com/types/key" - "tailscale.com/util/syspolicy" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" ) // getMachineCertificateSubject returns the exact name of a Subject that needs @@ -30,8 +31,8 @@ import ( // each RegisterRequest will be unsigned. // // Example: "CN=Tailscale Inc Test Root CA,OU=Tailscale Inc Test Certificate Authority,O=Tailscale Inc,ST=ON,C=CA" -func getMachineCertificateSubject() string { - machineCertSubject, _ := syspolicy.GetString(syspolicy.MachineCertificateSubject, "") +func getMachineCertificateSubject(polc policyclient.Client) string { + machineCertSubject, _ := polc.GetString(pkey.MachineCertificateSubject, "") return machineCertSubject } @@ -136,7 +137,7 @@ func findIdentity(subject string, st certstore.Store) (certstore.Identity, []*x5 // using that identity's public key. In addition to the signature, the full // certificate chain is included so that the control server can validate the // certificate from a copy of the root CA's certificate. -func signRegisterRequest(req *tailcfg.RegisterRequest, serverURL string, serverPubKey, machinePubKey key.MachinePublic) (err error) { +func signRegisterRequest(polc policyclient.Client, req *tailcfg.RegisterRequest, serverURL string, serverPubKey, machinePubKey key.MachinePublic) (err error) { defer func() { if err != nil { err = fmt.Errorf("signRegisterRequest: %w", err) @@ -147,7 +148,7 @@ func signRegisterRequest(req *tailcfg.RegisterRequest, serverURL string, serverP return errBadRequest } - machineCertificateSubject := getMachineCertificateSubject() + machineCertificateSubject := getMachineCertificateSubject(polc) if machineCertificateSubject == "" { return errCertificateNotConfigured } diff --git a/vendor/tailscale.com/control/controlclient/sign_unsupported.go b/vendor/tailscale.com/control/controlclient/sign_unsupported.go index 5e161dc..f6c4ddc 100644 --- a/vendor/tailscale.com/control/controlclient/sign_unsupported.go +++ b/vendor/tailscale.com/control/controlclient/sign_unsupported.go @@ -8,9 +8,10 @@ package controlclient import ( "tailscale.com/tailcfg" "tailscale.com/types/key" + "tailscale.com/util/syspolicy/policyclient" ) // signRegisterRequest on non-supported platforms always returns errNoCertStore. -func signRegisterRequest(req *tailcfg.RegisterRequest, serverURL string, serverPubKey, machinePubKey key.MachinePublic) error { +func signRegisterRequest(polc policyclient.Client, req *tailcfg.RegisterRequest, serverURL string, serverPubKey, machinePubKey key.MachinePublic) error { return errNoCertStore } diff --git a/vendor/tailscale.com/control/controlclient/status.go b/vendor/tailscale.com/control/controlclient/status.go index d0fdf80..65afb7a 100644 --- a/vendor/tailscale.com/control/controlclient/status.go +++ b/vendor/tailscale.com/control/controlclient/status.go @@ -4,8 +4,6 @@ package controlclient import ( - "encoding/json" - "fmt" "reflect" "tailscale.com/types/netmap" @@ -13,57 +11,6 @@ import ( "tailscale.com/types/structs" ) -// State is the high-level state of the client. It is used only in -// unit tests for proper sequencing, don't depend on it anywhere else. -// -// TODO(apenwarr): eliminate the state, as it's now obsolete. -// -// apenwarr: Historical note: controlclient.Auto was originally -// intended to be the state machine for the whole tailscale client, but that -// turned out to not be the right abstraction layer, and it moved to -// ipn.Backend. Since ipn.Backend now has a state machine, it would be -// much better if controlclient could be a simple stateless API. But the -// current server-side API (two interlocking polling https calls) makes that -// very hard to implement. A server side API change could untangle this and -// remove all the statefulness. -type State int - -const ( - StateNew = State(iota) - StateNotAuthenticated - StateAuthenticating - StateURLVisitRequired - StateAuthenticated - StateSynchronized // connected and received map update -) - -func (s State) AppendText(b []byte) ([]byte, error) { - return append(b, s.String()...), nil -} - -func (s State) MarshalText() ([]byte, error) { - return []byte(s.String()), nil -} - -func (s State) String() string { - switch s { - case StateNew: - return "state:new" - case StateNotAuthenticated: - return "state:not-authenticated" - case StateAuthenticating: - return "state:authenticating" - case StateURLVisitRequired: - return "state:url-visit-required" - case StateAuthenticated: - return "state:authenticated" - case StateSynchronized: - return "state:synchronized" - default: - return fmt.Sprintf("state:unknown:%d", int(s)) - } -} - type Status struct { _ structs.Incomparable @@ -76,6 +23,14 @@ type Status struct { // URL, if non-empty, is the interactive URL to visit to finish logging in. URL string + // LoggedIn, if true, indicates that serveRegister has completed and no + // other login change is in progress. + LoggedIn bool + + // InMapPoll, if true, indicates that we've received at least one netmap + // and are connected to receive updates. + InMapPoll bool + // NetMap is the latest server-pushed state of the tailnet network. NetMap *netmap.NetworkMap @@ -83,26 +38,8 @@ type Status struct { // // TODO(bradfitz,maisem): clarify this. Persist persist.PersistView - - // state is the internal state. It should not be exposed outside this - // package, but we have some automated tests elsewhere that need to - // use it via the StateForTest accessor. - // TODO(apenwarr): Unexport or remove these. - state State } -// LoginFinished reports whether the controlclient is in its "StateAuthenticated" -// state where it's in a happy register state but not yet in a map poll. -// -// TODO(bradfitz): delete this and everything around Status.state. -func (s *Status) LoginFinished() bool { return s.state == StateAuthenticated } - -// StateForTest returns the internal state of s for tests only. -func (s *Status) StateForTest() State { return s.state } - -// SetStateForTest sets the internal state of s for tests only. -func (s *Status) SetStateForTest(state State) { s.state = state } - // Equal reports whether s and s2 are equal. func (s *Status) Equal(s2 *Status) bool { if s == nil && s2 == nil { @@ -111,15 +48,8 @@ func (s *Status) Equal(s2 *Status) bool { return s != nil && s2 != nil && s.Err == s2.Err && s.URL == s2.URL && - s.state == s2.state && + s.LoggedIn == s2.LoggedIn && + s.InMapPoll == s2.InMapPoll && reflect.DeepEqual(s.Persist, s2.Persist) && reflect.DeepEqual(s.NetMap, s2.NetMap) } - -func (s Status) String() string { - b, err := json.MarshalIndent(s, "", "\t") - if err != nil { - panic(err) - } - return s.state.String() + " " + string(b) -} diff --git a/vendor/tailscale.com/control/controlhttp/client.go b/vendor/tailscale.com/control/controlhttp/client.go index 3b95796..06a2131 100644 --- a/vendor/tailscale.com/control/controlhttp/client.go +++ b/vendor/tailscale.com/control/controlhttp/client.go @@ -20,37 +20,37 @@ package controlhttp import ( + "cmp" "context" "crypto/tls" "encoding/base64" "errors" "fmt" "io" - "math" "net" "net/http" "net/http/httptrace" "net/netip" "net/url" "runtime" - "sort" "sync/atomic" "time" "tailscale.com/control/controlbase" "tailscale.com/control/controlhttp/controlhttpcommon" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/dnscache" "tailscale.com/net/dnsfallback" "tailscale.com/net/netutil" + "tailscale.com/net/netx" "tailscale.com/net/sockstats" "tailscale.com/net/tlsdial" - "tailscale.com/net/tshttpproxy" "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tstime" - "tailscale.com/util/multierr" ) var stdDialer net.Dialer @@ -81,7 +81,7 @@ func (a *Dialer) getProxyFunc() func(*http.Request) (*url.URL, error) { if a.proxyFunc != nil { return a.proxyFunc } - return tshttpproxy.ProxyFromEnvironment + return feature.HookProxyFromEnvironment.GetOrNil() } // httpsFallbackDelay is how long we'll wait for a.HTTPPort to work before @@ -103,157 +103,71 @@ func (a *Dialer) dial(ctx context.Context) (*ClientConn, error) { // host we know about. useDialPlan := envknob.BoolDefaultTrue("TS_USE_CONTROL_DIAL_PLAN") if !useDialPlan || a.DialPlan == nil || len(a.DialPlan.Candidates) == 0 { - return a.dialHost(ctx, netip.Addr{}) + return a.dialHost(ctx) } candidates := a.DialPlan.Candidates - // Otherwise, we try dialing per the plan. Store the highest priority - // in the list, so that if we get a connection to one of those - // candidates we can return quickly. - var highestPriority int = math.MinInt - for _, c := range candidates { - if c.Priority > highestPriority { - highestPriority = c.Priority - } - } - - // This context allows us to cancel in-flight connections if we get a - // highest-priority connection before we're all done. + // Create a context to be canceled as we return, so once we get a good connection, + // we can drop all the other ones. ctx, cancel := context.WithCancel(ctx) defer cancel() // Now, for each candidate, kick off a dial in parallel. type dialResult struct { - conn *ClientConn - err error - addr netip.Addr - priority int - } - resultsCh := make(chan dialResult, len(candidates)) - - var pending atomic.Int32 - pending.Store(int32(len(candidates))) - for _, c := range candidates { - go func(ctx context.Context, c tailcfg.ControlIPCandidate) { - var ( - conn *ClientConn - err error - ) - - // Always send results back to our channel. - defer func() { - resultsCh <- dialResult{conn, err, c.IP, c.Priority} - if pending.Add(-1) == 0 { - close(resultsCh) - } - }() - - // If non-zero, wait the configured start timeout - // before we do anything. - if c.DialStartDelaySec > 0 { - a.logf("[v2] controlhttp: waiting %.2f seconds before dialing %q @ %v", c.DialStartDelaySec, a.Hostname, c.IP) - tmr, tmrChannel := a.clock().NewTimer(time.Duration(c.DialStartDelaySec * float64(time.Second))) - defer tmr.Stop() - select { - case <-ctx.Done(): - err = ctx.Err() - return - case <-tmrChannel: - } - } - - // Now, create a sub-context with the given timeout and - // try dialing the provided host. - ctx, cancel := context.WithTimeout(ctx, time.Duration(c.DialTimeoutSec*float64(time.Second))) - defer cancel() - - // This will dial, and the defer above sends it back to our parent. - a.logf("[v2] controlhttp: trying to dial %q @ %v", a.Hostname, c.IP) - conn, err = a.dialHost(ctx, c.IP) - }(ctx, c) - } - - var results []dialResult - for res := range resultsCh { - // If we get a response that has the highest priority, we don't - // need to wait for any of the other connections to finish; we - // can just return this connection. - // - // TODO(andrew): we could make this better by keeping track of - // the highest remaining priority dynamically, instead of just - // checking for the highest total - if res.priority == highestPriority && res.conn != nil { - a.logf("[v1] controlhttp: high-priority success dialing %q @ %v from dial plan", a.Hostname, res.addr) - - // Drain the channel and any existing connections in - // the background. - go func() { - for _, res := range results { - if res.conn != nil { - res.conn.Close() - } - } - for res := range resultsCh { - if res.conn != nil { - res.conn.Close() - } - } - if a.drainFinished != nil { - close(a.drainFinished) - } - }() - return res.conn, nil - } - - // This isn't a highest-priority result, so just store it until - // we're done. - results = append(results, res) - } - - // After we finish this function, close any remaining open connections. - defer func() { - for _, result := range results { - // Note: below, we nil out the returned connection (if - // any) in the slice so we don't close it. - if result.conn != nil { - result.conn.Close() - } - } - - // We don't drain asynchronously after this point, so notify our - // channel when we return. - if a.drainFinished != nil { - close(a.drainFinished) - } - }() - - // Sort by priority, then take the first non-error response. - sort.Slice(results, func(i, j int) bool { - // NOTE: intentionally inverted so that the highest priority - // item comes first - return results[i].priority > results[j].priority - }) - - var ( conn *ClientConn - errs []error - ) - for i, result := range results { - if result.err != nil { - errs = append(errs, result.err) - continue + err error + } + resultsCh := make(chan dialResult) // unbuffered, never closed + + dialCand := func(cand tailcfg.ControlIPCandidate) (*ClientConn, error) { + if cand.ACEHost != "" { + a.logf("[v2] controlhttp: waited %.2f seconds, dialing %q via ACE %s (%s)", cand.DialStartDelaySec, a.Hostname, cand.ACEHost, cmp.Or(cand.IP.String(), "dns")) + } else { + a.logf("[v2] controlhttp: waited %.2f seconds, dialing %q @ %s", cand.DialStartDelaySec, a.Hostname, cand.IP.String()) } - a.logf("[v1] controlhttp: succeeded dialing %q @ %v from dial plan", a.Hostname, result.addr) - conn = result.conn - results[i].conn = nil // so we don't close it in the defer - return conn, nil + ctx, cancel := context.WithTimeout(ctx, time.Duration(cand.DialTimeoutSec*float64(time.Second))) + defer cancel() + return a.dialHostOpt(ctx, cand.IP, cand.ACEHost) } - merr := multierr.New(errs...) - // If we get here, then we didn't get anywhere with our dial plan; fall back to just using DNS. - a.logf("controlhttp: failed dialing using DialPlan, falling back to DNS; errs=%s", merr.Error()) - return a.dialHost(ctx, netip.Addr{}) + for _, cand := range candidates { + timer := time.AfterFunc(time.Duration(cand.DialStartDelaySec*float64(time.Second)), func() { + go func() { + conn, err := dialCand(cand) + select { + case resultsCh <- dialResult{conn, err}: + if err == nil { + a.logf("[v1] controlhttp: succeeded dialing %q @ %v from dial plan", a.Hostname, cmp.Or(cand.ACEHost, cand.IP.String())) + } + case <-ctx.Done(): + if conn != nil { + conn.Close() + } + } + }() + }) + defer timer.Stop() + } + + var errs []error + for { + select { + case res := <-resultsCh: + if res.err == nil { + return res.conn, nil + } + errs = append(errs, res.err) + if len(errs) == len(candidates) { + // If we get here, then we didn't get anywhere with our dial plan; fall back to just using DNS. + a.logf("controlhttp: failed dialing using DialPlan, falling back to DNS; errs=%s", errors.Join(errs...)) + return a.dialHost(ctx) + } + case <-ctx.Done(): + a.logf("controlhttp: context aborted dialing") + return nil, ctx.Err() + } + } } // The TS_FORCE_NOISE_443 envknob forces the controlclient noise dialer to @@ -270,6 +184,15 @@ var forceNoise443 = envknob.RegisterBool("TS_FORCE_NOISE_443") // use HTTPS connections as its underlay connection (double crypto). This can // be necessary when networks or middle boxes are messing with port 80. func (d *Dialer) forceNoise443() bool { + if runtime.GOOS == "plan9" { + // For running demos of Plan 9 in a browser with network relays, + // we want to minimize the number of connections we're making. + // The main reason to use port 80 is to avoid double crypto + // costs server-side but the costs are tiny and number of Plan 9 + // users doesn't make it worth it. Just disable this and always use + // HTTPS for Plan 9. That also reduces some log spam. + return true + } if forceNoise443() { return true } @@ -301,10 +224,19 @@ var debugNoiseDial = envknob.RegisterBool("TS_DEBUG_NOISE_DIAL") // dialHost connects to the configured Dialer.Hostname and upgrades the // connection into a controlbase.Conn. +func (a *Dialer) dialHost(ctx context.Context) (*ClientConn, error) { + return a.dialHostOpt(ctx, + netip.Addr{}, // no pre-resolved IP + "", // don't use ACE + ) +} + +// dialHostOpt connects to the configured Dialer.Hostname and upgrades the +// connection into a controlbase.Conn. // // If optAddr is valid, then no DNS is used and the connection will be made to the // provided address. -func (a *Dialer) dialHost(ctx context.Context, optAddr netip.Addr) (*ClientConn, error) { +func (a *Dialer) dialHostOpt(ctx context.Context, optAddr netip.Addr, optACEHost string) (*ClientConn, error) { // Create one shared context used by both port 80 and port 443 dials. // If port 80 is still in flight when 443 returns, this deferred cancel // will stop the port 80 dial. @@ -326,7 +258,7 @@ func (a *Dialer) dialHost(ctx context.Context, optAddr netip.Addr) (*ClientConn, Host: net.JoinHostPort(a.Hostname, strDef(a.HTTPSPort, "443")), Path: serverUpgradePath, } - if a.HTTPSPort == NoPort { + if a.HTTPSPort == NoPort || optACEHost != "" { u443 = nil } @@ -338,11 +270,11 @@ func (a *Dialer) dialHost(ctx context.Context, optAddr netip.Addr) (*ClientConn, ch := make(chan tryURLRes) // must be unbuffered try := func(u *url.URL) { if debugNoiseDial() { - a.logf("trying noise dial (%v, %v) ...", u, optAddr) + a.logf("trying noise dial (%v, %v) ...", u, cmp.Or(optACEHost, optAddr.String())) } - cbConn, err := a.dialURL(ctx, u, optAddr) + cbConn, err := a.dialURL(ctx, u, optAddr, optACEHost) if debugNoiseDial() { - a.logf("noise dial (%v, %v) = (%v, %v)", u, optAddr, cbConn, err) + a.logf("noise dial (%v, %v) = (%v, %v)", u, cmp.Or(optACEHost, optAddr.String()), cbConn, err) } select { case ch <- tryURLRes{u, cbConn, err}: @@ -373,6 +305,9 @@ func (a *Dialer) dialHost(ctx context.Context, optAddr netip.Addr) (*ClientConn, } var err80, err443 error + if forceTLS { + err80 = errors.New("TLS forced: no port 80 dialed") + } for { select { case <-ctx.Done(): @@ -408,12 +343,12 @@ func (a *Dialer) dialHost(ctx context.Context, optAddr netip.Addr) (*ClientConn, // // If optAddr is valid, then no DNS is used and the connection will be made to the // provided address. -func (a *Dialer) dialURL(ctx context.Context, u *url.URL, optAddr netip.Addr) (*ClientConn, error) { +func (a *Dialer) dialURL(ctx context.Context, u *url.URL, optAddr netip.Addr, optACEHost string) (*ClientConn, error) { init, cont, err := controlbase.ClientDeferred(a.MachineKey, a.ControlKey, a.ProtocolVersion) if err != nil { return nil, err } - netConn, err := a.tryURLUpgrade(ctx, u, optAddr, init) + netConn, err := a.tryURLUpgrade(ctx, u, optAddr, optACEHost, init) if err != nil { return nil, err } @@ -459,13 +394,15 @@ var macOSScreenTime = health.Register(&health.Warnable{ ImpactsConnectivity: true, }) +var HookMakeACEDialer feature.Hook[func(dialer netx.DialFunc, aceHost string, optIP netip.Addr) netx.DialFunc] + // tryURLUpgrade connects to u, and tries to upgrade it to a net.Conn. // // If optAddr is valid, then no DNS is used and the connection will be made to // the provided address. // // Only the provided ctx is used, not a.ctx. -func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Addr, init []byte) (_ net.Conn, retErr error) { +func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Addr, optACEHost string, init []byte) (_ net.Conn, retErr error) { var dns *dnscache.Resolver // If we were provided an address to dial, then create a resolver that just @@ -480,13 +417,24 @@ func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Ad dns = a.resolver() } - var dialer dnscache.DialContextFunc + var dialer netx.DialFunc if a.Dialer != nil { dialer = a.Dialer } else { dialer = stdDialer.DialContext } + if optACEHost != "" { + if !buildfeatures.HasACE { + return nil, feature.ErrUnavailable + } + f, ok := HookMakeACEDialer.GetOk() + if !ok { + return nil, feature.ErrUnavailable + } + dialer = f(dialer, optACEHost, optAddr) + } + // On macOS, see if Screen Time is blocking things. if runtime.GOOS == "darwin" { var proxydIntercepted atomic.Bool // intercepted by macOS webfilterproxyd @@ -513,13 +461,25 @@ func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Ad tr := http.DefaultTransport.(*http.Transport).Clone() defer tr.CloseIdleConnections() - tr.Proxy = a.getProxyFunc() - tshttpproxy.SetTransportGetProxyConnectHeader(tr) - tr.DialContext = dnscache.Dialer(dialer, dns) + if optACEHost != "" { + // If using ACE, we don't want to use any HTTP proxy. + // ACE is already a tunnel+proxy. + // TODO(tailscale/corp#32483): use system proxy too? + tr.Proxy = nil + tr.DialContext = dialer + } else { + if buildfeatures.HasUseProxy { + tr.Proxy = a.getProxyFunc() + if set, ok := feature.HookProxySetTransportGetProxyConnectHeader.GetOk(); ok { + set(tr) + } + } + tr.DialContext = dnscache.Dialer(dialer, dns) + } // Disable HTTP2, since h2 can't do protocol switching. tr.TLSClientConfig.NextProtos = []string{} tr.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{} - tr.TLSClientConfig = tlsdial.Config(a.Hostname, a.HealthTracker, tr.TLSClientConfig) + tr.TLSClientConfig = tlsdial.Config(a.HealthTracker, tr.TLSClientConfig) if !tr.TLSClientConfig.InsecureSkipVerify { panic("unexpected") // should be set by tlsdial.Config } diff --git a/vendor/tailscale.com/control/controlhttp/constants.go b/vendor/tailscale.com/control/controlhttp/constants.go index 80b3fe6..359410a 100644 --- a/vendor/tailscale.com/control/controlhttp/constants.go +++ b/vendor/tailscale.com/control/controlhttp/constants.go @@ -12,6 +12,7 @@ import ( "tailscale.com/health" "tailscale.com/net/dnscache" "tailscale.com/net/netmon" + "tailscale.com/net/netx" "tailscale.com/tailcfg" "tailscale.com/tstime" "tailscale.com/types/key" @@ -66,7 +67,7 @@ type Dialer struct { // Dialer is the dialer used to make outbound connections. // // If not specified, this defaults to net.Dialer.DialContext. - Dialer dnscache.DialContextFunc + Dialer netx.DialFunc // DNSCache is the caching Resolver used by this Dialer. // @@ -77,8 +78,8 @@ type Dialer struct { // dropped. Logf logger.Logf - // NetMon is the [netmon.Monitor] to use for this Dialer. It must be - // non-nil. + // NetMon is the [netmon.Monitor] to use for this Dialer. + // It is optional. NetMon *netmon.Monitor // HealthTracker, if non-nil, is the health tracker to use. @@ -97,7 +98,6 @@ type Dialer struct { logPort80Failure atomic.Bool // For tests only - drainFinished chan struct{} omitCertErrorLogging bool testFallbackDelay time.Duration diff --git a/vendor/tailscale.com/control/controlknobs/controlknobs.go b/vendor/tailscale.com/control/controlknobs/controlknobs.go index a86f0af..09c16b8 100644 --- a/vendor/tailscale.com/control/controlknobs/controlknobs.go +++ b/vendor/tailscale.com/control/controlknobs/controlknobs.go @@ -62,8 +62,9 @@ type Knobs struct { // netfiltering, unless overridden by the user. LinuxForceNfTables atomic.Bool - // SeamlessKeyRenewal is whether to enable the alpha functionality of - // renewing node keys without breaking connections. + // SeamlessKeyRenewal is whether to renew node keys without breaking connections. + // This is enabled by default in 1.90 and later, but we but we can remotely disable + // it from the control plane if there's a problem. // http://go/seamless-key-renewal SeamlessKeyRenewal atomic.Bool @@ -98,10 +99,6 @@ type Knobs struct { // allows us to disable the new behavior remotely if needed. DisableLocalDNSOverrideViaNRPT atomic.Bool - // DisableCryptorouting indicates that the node should not use the - // magicsock crypto routing feature. - DisableCryptorouting atomic.Bool - // DisableCaptivePortalDetection is whether the node should not perform captive portal detection // automatically when the network state changes. DisableCaptivePortalDetection atomic.Bool @@ -132,12 +129,12 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) { forceIPTables = has(tailcfg.NodeAttrLinuxMustUseIPTables) forceNfTables = has(tailcfg.NodeAttrLinuxMustUseNfTables) seamlessKeyRenewal = has(tailcfg.NodeAttrSeamlessKeyRenewal) + disableSeamlessKeyRenewal = has(tailcfg.NodeAttrDisableSeamlessKeyRenewal) probeUDPLifetime = has(tailcfg.NodeAttrProbeUDPLifetime) appCStoreRoutes = has(tailcfg.NodeAttrStoreAppCRoutes) userDialUseRoutes = has(tailcfg.NodeAttrUserDialUseRoutes) disableSplitDNSWhenNoCustomResolvers = has(tailcfg.NodeAttrDisableSplitDNSWhenNoCustomResolvers) disableLocalDNSOverrideViaNRPT = has(tailcfg.NodeAttrDisableLocalDNSOverrideViaNRPT) - disableCryptorouting = has(tailcfg.NodeAttrDisableMagicSockCryptoRouting) disableCaptivePortalDetection = has(tailcfg.NodeAttrDisableCaptivePortalDetection) disableSkipStatusQueue = has(tailcfg.NodeAttrDisableSkipStatusQueue) ) @@ -159,15 +156,28 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) { k.SilentDisco.Store(silentDisco) k.LinuxForceIPTables.Store(forceIPTables) k.LinuxForceNfTables.Store(forceNfTables) - k.SeamlessKeyRenewal.Store(seamlessKeyRenewal) k.ProbeUDPLifetime.Store(probeUDPLifetime) k.AppCStoreRoutes.Store(appCStoreRoutes) k.UserDialUseRoutes.Store(userDialUseRoutes) k.DisableSplitDNSWhenNoCustomResolvers.Store(disableSplitDNSWhenNoCustomResolvers) k.DisableLocalDNSOverrideViaNRPT.Store(disableLocalDNSOverrideViaNRPT) - k.DisableCryptorouting.Store(disableCryptorouting) k.DisableCaptivePortalDetection.Store(disableCaptivePortalDetection) k.DisableSkipStatusQueue.Store(disableSkipStatusQueue) + + // If both attributes are present, then "enable" should win. This reflects + // the history of seamless key renewal. + // + // Before 1.90, seamless was a private alpha, opt-in feature. Devices would + // only seamless do if customers opted in using the seamless renewal attr. + // + // In 1.90 and later, seamless is the default behaviour, and devices will use + // seamless unless explicitly told not to by control (e.g. if we discover + // a bug and want clients to use the prior behaviour). + // + // If a customer has opted in to the pre-1.90 seamless implementation, we + // don't want to switch it off for them -- we only want to switch it off for + // devices that haven't opted in. + k.SeamlessKeyRenewal.Store(seamlessKeyRenewal || !disableSeamlessKeyRenewal) } // AsDebugJSON returns k as something that can be marshalled with json.Marshal diff --git a/vendor/tailscale.com/control/ts2021/client.go b/vendor/tailscale.com/control/ts2021/client.go new file mode 100644 index 0000000..ca10b1d --- /dev/null +++ b/vendor/tailscale.com/control/ts2021/client.go @@ -0,0 +1,312 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package ts2021 + +import ( + "bytes" + "cmp" + "context" + "encoding/json" + "errors" + "fmt" + "log" + "math" + "net" + "net/http" + "net/netip" + "net/url" + "sync" + "time" + + "tailscale.com/control/controlhttp" + "tailscale.com/health" + "tailscale.com/net/dnscache" + "tailscale.com/net/netmon" + "tailscale.com/net/tsdial" + "tailscale.com/tailcfg" + "tailscale.com/tstime" + "tailscale.com/types/key" + "tailscale.com/types/logger" + "tailscale.com/util/mak" + "tailscale.com/util/set" +) + +// Client provides a http.Client to connect to tailcontrol over +// the ts2021 protocol. +type Client struct { + // Client is an HTTP client to talk to the coordination server. + // It automatically makes a new Noise connection as needed. + *http.Client + + logf logger.Logf // non-nil + opts ClientOpts + host string // the host part of serverURL + httpPort string // the default port to dial + httpsPort string // the fallback Noise-over-https port or empty if none + + // mu protects the following + mu sync.Mutex + closed bool + connPool set.HandleSet[*Conn] // all live connections +} + +// ClientOpts contains options for the [NewClient] function. All fields are +// required unless otherwise specified. +type ClientOpts struct { + // ServerURL is the URL of the server to connect to. + ServerURL string + + // PrivKey is this node's private key. + PrivKey key.MachinePrivate + + // ServerPubKey is the public key of the server. + // It is of the form https://: (no trailing slash). + ServerPubKey key.MachinePublic + + // Dialer's SystemDial function is used to connect to the server. + Dialer *tsdial.Dialer + + // Optional fields follow + + // Logf is the log function to use. + // If nil, log.Printf is used. + Logf logger.Logf + + // NetMon is the network monitor that will be used to get the + // network interface state. This field can be nil; if so, the current + // state will be looked up dynamically. + NetMon *netmon.Monitor + + // DNSCache is the caching Resolver to use to connect to the server. + // + // This field can be nil. + DNSCache *dnscache.Resolver + + // HealthTracker, if non-nil, is the health tracker to use. + HealthTracker *health.Tracker + + // DialPlan, if set, is a function that should return an explicit plan + // on how to connect to the server. + DialPlan func() *tailcfg.ControlDialPlan + + // ProtocolVersion, if non-zero, specifies an alternate + // protocol version to use instead of the default, + // of [tailcfg.CurrentCapabilityVersion]. + ProtocolVersion uint16 +} + +// NewClient returns a new noiseClient for the provided server and machine key. +// +// netMon may be nil, if non-nil it's used to do faster interface lookups. +// dialPlan may be nil +func NewClient(opts ClientOpts) (*Client, error) { + logf := opts.Logf + if logf == nil { + logf = log.Printf + } + if opts.ServerURL == "" { + return nil, errors.New("ServerURL is required") + } + if opts.PrivKey.IsZero() { + return nil, errors.New("PrivKey is required") + } + if opts.ServerPubKey.IsZero() { + return nil, errors.New("ServerPubKey is required") + } + if opts.Dialer == nil { + return nil, errors.New("Dialer is required") + } + + u, err := url.Parse(opts.ServerURL) + if err != nil { + return nil, fmt.Errorf("invalid ClientOpts.ServerURL: %w", err) + } + if u.Scheme != "http" && u.Scheme != "https" { + return nil, errors.New("invalid ServerURL scheme, must be http or https") + } + + httpPort, httpsPort := "80", "443" + addr, _ := netip.ParseAddr(u.Hostname()) + isPrivateHost := addr.IsPrivate() || addr.IsLoopback() || u.Hostname() == "localhost" + if port := u.Port(); port != "" { + // If there is an explicit port specified, entirely rely on the scheme, + // unless it's http with a private host in which case we never try using HTTPS. + if u.Scheme == "https" { + httpPort = "" + httpsPort = port + } else if u.Scheme == "http" { + httpPort = port + httpsPort = "443" + if isPrivateHost { + logf("setting empty HTTPS port with http scheme and private host %s", u.Hostname()) + httpsPort = "" + } + } + } else if u.Scheme == "http" && isPrivateHost { + // Whenever the scheme is http and the hostname is an IP address, do not set the HTTPS port, + // as there cannot be a TLS certificate issued for an IP, unless it's a public IP. + httpPort = "80" + httpsPort = "" + } + + np := &Client{ + opts: opts, + host: u.Hostname(), + httpPort: httpPort, + httpsPort: httpsPort, + logf: logf, + } + + tr := &http.Transport{ + Protocols: new(http.Protocols), + MaxConnsPerHost: 1, + } + // We force only HTTP/2 for this transport, which is what the control server + // speaks inside the ts2021 Noise encryption. But Go doesn't know about that, + // so we use "SetUnencryptedHTTP2" even though it's actually encrypted. + tr.Protocols.SetUnencryptedHTTP2(true) + tr.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) { + return np.dial(ctx) + } + + np.Client = &http.Client{Transport: tr} + return np, nil +} + +// Close closes all the underlying noise connections. +// It is a no-op and returns nil if the connection is already closed. +func (nc *Client) Close() error { + nc.mu.Lock() + live := nc.connPool + nc.closed = true + nc.connPool = nil // stop noteConnClosed from mutating it as we loop over it (in live) below + nc.mu.Unlock() + + for _, c := range live { + c.Close() + } + nc.Client.CloseIdleConnections() + + return nil +} + +// dial opens a new connection to tailcontrol, fetching the server noise key +// if not cached. +func (nc *Client) dial(ctx context.Context) (*Conn, error) { + if tailcfg.CurrentCapabilityVersion > math.MaxUint16 { + // Panic, because a test should have started failing several + // thousand version numbers before getting to this point. + panic("capability version is too high to fit in the wire protocol") + } + + var dialPlan *tailcfg.ControlDialPlan + if nc.opts.DialPlan != nil { + dialPlan = nc.opts.DialPlan() + } + + // If we have a dial plan, then set our timeout as slightly longer than + // the maximum amount of time contained therein; we assume that + // explicit instructions on timeouts are more useful than a single + // hard-coded timeout. + // + // The default value of 5 is chosen so that, when there's no dial plan, + // we retain the previous behaviour of 10 seconds end-to-end timeout. + timeoutSec := 5.0 + if dialPlan != nil { + for _, c := range dialPlan.Candidates { + if v := c.DialStartDelaySec + c.DialTimeoutSec; v > timeoutSec { + timeoutSec = v + } + } + } + + // After we establish a connection, we need some time to actually + // upgrade it into a Noise connection. With a ballpark worst-case RTT + // of 1000ms, give ourselves an extra 5 seconds to complete the + // handshake. + timeoutSec += 5 + + // Be extremely defensive and ensure that the timeout is in the range + // [5, 60] seconds (e.g. if we accidentally get a negative number). + if timeoutSec > 60 { + timeoutSec = 60 + } else if timeoutSec < 5 { + timeoutSec = 5 + } + + timeout := time.Duration(timeoutSec * float64(time.Second)) + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + chd := &controlhttp.Dialer{ + Hostname: nc.host, + HTTPPort: nc.httpPort, + HTTPSPort: cmp.Or(nc.httpsPort, controlhttp.NoPort), + MachineKey: nc.opts.PrivKey, + ControlKey: nc.opts.ServerPubKey, + ProtocolVersion: cmp.Or(nc.opts.ProtocolVersion, uint16(tailcfg.CurrentCapabilityVersion)), + Dialer: nc.opts.Dialer.SystemDial, + DNSCache: nc.opts.DNSCache, + DialPlan: dialPlan, + Logf: nc.logf, + NetMon: nc.opts.NetMon, + HealthTracker: nc.opts.HealthTracker, + Clock: tstime.StdClock{}, + } + clientConn, err := chd.Dial(ctx) + if err != nil { + return nil, err + } + + nc.mu.Lock() + + handle := set.NewHandle() + ncc := NewConn(clientConn.Conn, func() { nc.noteConnClosed(handle) }) + mak.Set(&nc.connPool, handle, ncc) + + if nc.closed { + nc.mu.Unlock() + ncc.Close() // Needs to be called without holding the lock. + return nil, errors.New("noise client closed") + } + + defer nc.mu.Unlock() + return ncc, nil +} + +// noteConnClosed notes that the *Conn with the given handle has closed and +// should be removed from the live connPool (which is usually of size 0 or 1, +// except perhaps briefly 2 during a network failure and reconnect). +func (nc *Client) noteConnClosed(handle set.Handle) { + nc.mu.Lock() + defer nc.mu.Unlock() + nc.connPool.Delete(handle) +} + +// post does a POST to the control server at the given path, JSON-encoding body. +// The provided nodeKey is an optional load balancing hint. +func (nc *Client) Post(ctx context.Context, path string, nodeKey key.NodePublic, body any) (*http.Response, error) { + return nc.DoWithBody(ctx, "POST", path, nodeKey, body) +} + +func (nc *Client) DoWithBody(ctx context.Context, method, path string, nodeKey key.NodePublic, body any) (*http.Response, error) { + jbody, err := json.Marshal(body) + if err != nil { + return nil, err + } + req, err := http.NewRequestWithContext(ctx, method, "https://"+nc.host+path, bytes.NewReader(jbody)) + if err != nil { + return nil, err + } + AddLBHeader(req, nodeKey) + req.Header.Set("Content-Type", "application/json") + return nc.Do(req) +} + +// AddLBHeader adds the load balancer header to req if nodeKey is non-zero. +func AddLBHeader(req *http.Request, nodeKey key.NodePublic) { + if !nodeKey.IsZero() { + req.Header.Add(tailcfg.LBHeader, nodeKey.String()) + } +} diff --git a/vendor/tailscale.com/internal/noiseconn/conn.go b/vendor/tailscale.com/control/ts2021/conn.go similarity index 69% rename from vendor/tailscale.com/internal/noiseconn/conn.go rename to vendor/tailscale.com/control/ts2021/conn.go index 7476b7e..52d6632 100644 --- a/vendor/tailscale.com/internal/noiseconn/conn.go +++ b/vendor/tailscale.com/control/ts2021/conn.go @@ -1,12 +1,10 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -// Package noiseconn contains an internal-only wrapper around controlbase.Conn -// that properly handles the early payload sent by the server before the HTTP/2 -// session begins. -// -// See the documentation on the Conn type for more details. -package noiseconn +// Package ts2021 handles the details of the Tailscale 2021 control protocol +// that are after (above) the Noise layer. In particular, the +// "tailcfg.EarlyNoise" message and the subsequent HTTP/2 connection. +package ts2021 import ( "bytes" @@ -15,10 +13,8 @@ import ( "encoding/json" "errors" "io" - "net/http" "sync" - "golang.org/x/net/http2" "tailscale.com/control/controlbase" "tailscale.com/tailcfg" ) @@ -29,12 +25,13 @@ import ( // the pool when the connection is closed, properly handles an optional "early // payload" that's sent prior to beginning the HTTP/2 session, and provides a // way to return a connection to a pool when the connection is closed. +// +// Use [NewConn] to build a new Conn if you want [Conn.GetEarlyPayload] to work. +// Otherwise making a Conn directly, only setting Conn, is fine. type Conn struct { *controlbase.Conn - id int - onClose func(int) - h2cc *http2.ClientConn + onClose func() // or nil readHeaderOnce sync.Once // guards init of reader field reader io.Reader // (effectively Conn.Reader after header) earlyPayloadReady chan struct{} // closed after earlyPayload is set (including set to nil) @@ -42,31 +39,19 @@ type Conn struct { earlyPayloadErr error } -// New creates a new Conn that wraps the given controlbase.Conn. +// NewConn creates a new Conn that wraps the given controlbase.Conn. // // h2t is the HTTP/2 transport to use for the connection; a new // http2.ClientConn will be created that reads from the returned Conn. // // connID should be a unique ID for this connection. When the Conn is closed, -// the onClose function will be called with the connID if it is non-nil. -func New(conn *controlbase.Conn, h2t *http2.Transport, connID int, onClose func(int)) (*Conn, error) { - ncc := &Conn{ +// the onClose function will be called if it is non-nil. +func NewConn(conn *controlbase.Conn, onClose func()) *Conn { + return &Conn{ Conn: conn, - id: connID, - onClose: onClose, earlyPayloadReady: make(chan struct{}), + onClose: sync.OnceFunc(onClose), } - h2cc, err := h2t.NewClientConn(ncc) - if err != nil { - return nil, err - } - ncc.h2cc = h2cc - return ncc, nil -} - -// RoundTrip implements the http.RoundTripper interface. -func (c *Conn) RoundTrip(r *http.Request) (*http.Response, error) { - return c.h2cc.RoundTrip(r) } // GetEarlyPayload waits for the early Noise payload to arrive. @@ -76,6 +61,15 @@ func (c *Conn) RoundTrip(r *http.Request) (*http.Response, error) { // early Noise payload is ready (if any) and will return the same result for // the lifetime of the Conn. func (c *Conn) GetEarlyPayload(ctx context.Context) (*tailcfg.EarlyNoise, error) { + if c.earlyPayloadReady == nil { + return nil, errors.New("Conn was not created with NewConn; early payload not supported") + } + select { + case <-c.earlyPayloadReady: + return c.earlyPayload, c.earlyPayloadErr + default: + go c.readHeaderOnce.Do(c.readHeader) + } select { case <-c.earlyPayloadReady: return c.earlyPayload, c.earlyPayloadErr @@ -84,28 +78,6 @@ func (c *Conn) GetEarlyPayload(ctx context.Context) (*tailcfg.EarlyNoise, error) } } -// ReserveNewRequest will reserve a new concurrent request on the connection. -// -// It returns whether the reservation was successful, and any early Noise -// payload if present. If a reservation was not successful, it will return -// false and nil for the early payload. -func (c *Conn) ReserveNewRequest(ctx context.Context) (bool, *tailcfg.EarlyNoise, error) { - earlyPayloadMaybeNil, err := c.GetEarlyPayload(ctx) - if err != nil { - return false, nil, err - } - if c.h2cc.ReserveNewRequest() { - return true, earlyPayloadMaybeNil, nil - } - return false, nil, nil -} - -// CanTakeNewRequest reports whether the underlying HTTP/2 connection can take -// a new request, meaning it has not been closed or received or sent a GOAWAY. -func (c *Conn) CanTakeNewRequest() bool { - return c.h2cc.CanTakeNewRequest() -} - // The first 9 bytes from the server to client over Noise are either an HTTP/2 // settings frame (a normal HTTP/2 setup) or, as we added later, an "early payload" // header that's also 9 bytes long: 5 bytes (EarlyPayloadMagic) followed by 4 bytes @@ -133,6 +105,14 @@ func (c *Conn) Read(p []byte) (n int, err error) { return c.reader.Read(p) } +// Close closes the connection. +func (c *Conn) Close() error { + if c.onClose != nil { + defer c.onClose() + } + return c.Conn.Close() +} + // readHeader reads the optional "early payload" from the server that arrives // after the Noise handshake but before the HTTP/2 session begins. // @@ -140,7 +120,9 @@ func (c *Conn) Read(p []byte) (n int, err error) { // c.earlyPayload, closing c.earlyPayloadReady, and initializing c.reader for // future reads. func (c *Conn) readHeader() { - defer close(c.earlyPayloadReady) + if c.earlyPayloadReady != nil { + defer close(c.earlyPayloadReady) + } setErr := func(err error) { c.reader = returnErrReader{err} @@ -174,14 +156,3 @@ func (c *Conn) readHeader() { } c.reader = c.Conn } - -// Close closes the connection. -func (c *Conn) Close() error { - if err := c.Conn.Close(); err != nil { - return err - } - if c.onClose != nil { - c.onClose(c.id) - } - return nil -} diff --git a/vendor/tailscale.com/derp/derp.go b/vendor/tailscale.com/derp/derp.go index 65acd43..e19a99b 100644 --- a/vendor/tailscale.com/derp/derp.go +++ b/vendor/tailscale.com/derp/derp.go @@ -27,27 +27,31 @@ import ( // including its on-wire framing overhead) const MaxPacketSize = 64 << 10 -// magic is the DERP magic number, sent in the frameServerKey frame +// Magic is the DERP Magic number, sent in the frameServerKey frame // upon initial connection. -const magic = "DERP🔑" // 8 bytes: 0x44 45 52 50 f0 9f 94 91 +const Magic = "DERP🔑" // 8 bytes: 0x44 45 52 50 f0 9f 94 91 const ( - nonceLen = 24 - frameHeaderLen = 1 + 4 // frameType byte + 4 byte length - keyLen = 32 - maxInfoLen = 1 << 20 - keepAlive = 60 * time.Second + NonceLen = 24 + FrameHeaderLen = 1 + 4 // frameType byte + 4 byte length + KeyLen = 32 + MaxInfoLen = 1 << 20 ) +// KeepAlive is the minimum frequency at which the DERP server sends +// keep alive frames. The server adds some jitter, so this timing is not +// exact, but 2x this value can be considered a missed keep alive. +const KeepAlive = 60 * time.Second + // ProtocolVersion is bumped whenever there's a wire-incompatible change. // - version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit // - version 2: received packets have src addrs in frameRecvPacket at beginning const ProtocolVersion = 2 -// frameType is the one byte frame type at the beginning of the frame +// FrameType is the one byte frame type at the beginning of the frame // header. The second field is a big-endian uint32 describing the // length of the remaining frame (not including the initial 5 bytes). -type frameType byte +type FrameType byte /* Protocol flow: @@ -65,14 +69,14 @@ Steady state: * server then sends frameRecvPacket to recipient */ const ( - frameServerKey = frameType(0x01) // 8B magic + 32B public key + (0+ bytes future use) - frameClientInfo = frameType(0x02) // 32B pub key + 24B nonce + naclbox(json) - frameServerInfo = frameType(0x03) // 24B nonce + naclbox(json) - frameSendPacket = frameType(0x04) // 32B dest pub key + packet bytes - frameForwardPacket = frameType(0x0a) // 32B src pub key + 32B dst pub key + packet bytes - frameRecvPacket = frameType(0x05) // v0/1: packet bytes, v2: 32B src pub key + packet bytes - frameKeepAlive = frameType(0x06) // no payload, no-op (to be replaced with ping/pong) - frameNotePreferred = frameType(0x07) // 1 byte payload: 0x01 or 0x00 for whether this is client's home node + FrameServerKey = FrameType(0x01) // 8B magic + 32B public key + (0+ bytes future use) + FrameClientInfo = FrameType(0x02) // 32B pub key + 24B nonce + naclbox(json) + FrameServerInfo = FrameType(0x03) // 24B nonce + naclbox(json) + FrameSendPacket = FrameType(0x04) // 32B dest pub key + packet bytes + FrameForwardPacket = FrameType(0x0a) // 32B src pub key + 32B dst pub key + packet bytes + FrameRecvPacket = FrameType(0x05) // v0/1: packet bytes, v2: 32B src pub key + packet bytes + FrameKeepAlive = FrameType(0x06) // no payload, no-op (to be replaced with ping/pong) + FrameNotePreferred = FrameType(0x07) // 1 byte payload: 0x01 or 0x00 for whether this is client's home node // framePeerGone is sent from server to client to signal that // a previous sender is no longer connected. That is, if A @@ -81,7 +85,7 @@ const ( // exists on that connection to get back to A. It is also sent // if A tries to send a CallMeMaybe to B and the server has no // record of B - framePeerGone = frameType(0x08) // 32B pub key of peer that's gone + 1 byte reason + FramePeerGone = FrameType(0x08) // 32B pub key of peer that's gone + 1 byte reason // framePeerPresent is like framePeerGone, but for other members of the DERP // region when they're meshed up together. @@ -92,7 +96,7 @@ const ( // remaining after that, it's a PeerPresentFlags byte. // While current servers send 41 bytes, old servers will send fewer, and newer // servers might send more. - framePeerPresent = frameType(0x09) + FramePeerPresent = FrameType(0x09) // frameWatchConns is how one DERP node in a regional mesh // subscribes to the others in the region. @@ -100,30 +104,30 @@ const ( // is closed. Otherwise, the client is initially flooded with // framePeerPresent for all connected nodes, and then a stream of // framePeerPresent & framePeerGone has peers connect and disconnect. - frameWatchConns = frameType(0x10) + FrameWatchConns = FrameType(0x10) // frameClosePeer is a privileged frame type (requires the // mesh key for now) that closes the provided peer's // connection. (To be used for cluster load balancing // purposes, when clients end up on a non-ideal node) - frameClosePeer = frameType(0x11) // 32B pub key of peer to close. + FrameClosePeer = FrameType(0x11) // 32B pub key of peer to close. - framePing = frameType(0x12) // 8 byte ping payload, to be echoed back in framePong - framePong = frameType(0x13) // 8 byte payload, the contents of the ping being replied to + FramePing = FrameType(0x12) // 8 byte ping payload, to be echoed back in framePong + FramePong = FrameType(0x13) // 8 byte payload, the contents of the ping being replied to // frameHealth is sent from server to client to tell the client // if their connection is unhealthy somehow. Currently the only unhealthy state // is whether the connection is detected as a duplicate. // The entire frame body is the text of the error message. An empty message // clears the error state. - frameHealth = frameType(0x14) + FrameHealth = FrameType(0x14) // frameRestarting is sent from server to client for the // server to declare that it's restarting. Payload is two big // endian uint32 durations in milliseconds: when to reconnect, // and how long to try total. See ServerRestartingMessage docs for // more details on how the client should interpret them. - frameRestarting = frameType(0x15) + FrameRestarting = FrameType(0x15) ) // PeerGoneReasonType is a one byte reason code explaining why a @@ -150,6 +154,18 @@ const ( PeerPresentNotIdeal = 1 << 3 // client said derp server is not its Region.Nodes[0] ideal node ) +// IdealNodeHeader is the HTTP request header sent on DERP HTTP client requests +// to indicate that they're connecting to their ideal (Region.Nodes[0]) node. +// The HTTP header value is the name of the node they wish they were connected +// to. This is an optional header. +const IdealNodeHeader = "Ideal-Node" + +// FastStartHeader is the header (with value "1") that signals to the HTTP +// server that the DERP HTTP client does not want the HTTP 101 response +// headers and it will begin writing & reading the DERP protocol immediately +// following its HTTP request. +const FastStartHeader = "Derp-Fast-Start" + var bin = binary.BigEndian func writeUint32(bw *bufio.Writer, v uint32) error { @@ -182,15 +198,24 @@ func readUint32(br *bufio.Reader) (uint32, error) { return bin.Uint32(b[:]), nil } -func readFrameTypeHeader(br *bufio.Reader, wantType frameType) (frameLen uint32, err error) { - gotType, frameLen, err := readFrameHeader(br) +// ReadFrameTypeHeader reads a frame header from br and +// verifies that the frame type matches wantType. +// +// If it does, it returns the frame length (not including +// the 5 byte header) and a nil error. +// +// If it doesn't, it returns an error and a zero length. +func ReadFrameTypeHeader(br *bufio.Reader, wantType FrameType) (frameLen uint32, err error) { + gotType, frameLen, err := ReadFrameHeader(br) if err == nil && wantType != gotType { err = fmt.Errorf("bad frame type 0x%X, want 0x%X", gotType, wantType) } return frameLen, err } -func readFrameHeader(br *bufio.Reader) (t frameType, frameLen uint32, err error) { +// ReadFrameHeader reads the header of a DERP frame, +// reading 5 bytes from br. +func ReadFrameHeader(br *bufio.Reader) (t FrameType, frameLen uint32, err error) { tb, err := br.ReadByte() if err != nil { return 0, 0, err @@ -199,7 +224,7 @@ func readFrameHeader(br *bufio.Reader) (t frameType, frameLen uint32, err error) if err != nil { return 0, 0, err } - return frameType(tb), frameLen, nil + return FrameType(tb), frameLen, nil } // readFrame reads a frame header and then reads its payload into @@ -212,8 +237,8 @@ func readFrameHeader(br *bufio.Reader) (t frameType, frameLen uint32, err error) // bytes are read, err will be io.ErrShortBuffer, and frameLen and t // will both be set. That is, callers need to explicitly handle when // they get more data than expected. -func readFrame(br *bufio.Reader, maxSize uint32, b []byte) (t frameType, frameLen uint32, err error) { - t, frameLen, err = readFrameHeader(br) +func readFrame(br *bufio.Reader, maxSize uint32, b []byte) (t FrameType, frameLen uint32, err error) { + t, frameLen, err = ReadFrameHeader(br) if err != nil { return 0, 0, err } @@ -235,19 +260,26 @@ func readFrame(br *bufio.Reader, maxSize uint32, b []byte) (t frameType, frameLe return t, frameLen, err } -func writeFrameHeader(bw *bufio.Writer, t frameType, frameLen uint32) error { +// WriteFrameHeader writes a frame header to bw. +// +// The frame header is 5 bytes: a one byte frame type +// followed by a big-endian uint32 length of the +// remaining frame (not including the 5 byte header). +// +// It does not flush bw. +func WriteFrameHeader(bw *bufio.Writer, t FrameType, frameLen uint32) error { if err := bw.WriteByte(byte(t)); err != nil { return err } return writeUint32(bw, frameLen) } -// writeFrame writes a complete frame & flushes it. -func writeFrame(bw *bufio.Writer, t frameType, b []byte) error { +// WriteFrame writes a complete frame & flushes it. +func WriteFrame(bw *bufio.Writer, t FrameType, b []byte) error { if len(b) > 10<<20 { return errors.New("unreasonably large frame write") } - if err := writeFrameHeader(bw, t, uint32(len(b))); err != nil { + if err := WriteFrameHeader(bw, t, uint32(len(b))); err != nil { return err } if _, err := bw.Write(b); err != nil { @@ -266,3 +298,12 @@ type Conn interface { SetReadDeadline(time.Time) error SetWriteDeadline(time.Time) error } + +// ServerInfo is the message sent from the server to clients during +// the connection setup. +type ServerInfo struct { + Version int `json:"version,omitempty"` + + TokenBucketBytesPerSecond int `json:",omitempty"` + TokenBucketBytesBurst int `json:",omitempty"` +} diff --git a/vendor/tailscale.com/derp/derp_client.go b/vendor/tailscale.com/derp/derp_client.go index 7a646fa..d28905c 100644 --- a/vendor/tailscale.com/derp/derp_client.go +++ b/vendor/tailscale.com/derp/derp_client.go @@ -30,7 +30,7 @@ type Client struct { logf logger.Logf nc Conn br *bufio.Reader - meshKey string + meshKey key.DERPMesh canAckPings bool isProber bool @@ -56,7 +56,7 @@ func (f clientOptFunc) update(o *clientOpt) { f(o) } // clientOpt are the options passed to newClient. type clientOpt struct { - MeshKey string + MeshKey key.DERPMesh ServerPub key.NodePublic CanAckPings bool IsProber bool @@ -66,7 +66,7 @@ type clientOpt struct { // access to join the mesh. // // An empty key means to not use a mesh key. -func MeshKey(key string) ClientOpt { return clientOptFunc(func(o *clientOpt) { o.MeshKey = key }) } +func MeshKey(k key.DERPMesh) ClientOpt { return clientOptFunc(func(o *clientOpt) { o.MeshKey = k }) } // IsProber returns a ClientOpt to pass to the DERP server during connect to // declare that this client is a a prober. @@ -133,17 +133,17 @@ func (c *Client) recvServerKey() error { if err != nil { return err } - if flen < uint32(len(buf)) || t != frameServerKey || string(buf[:len(magic)]) != magic { + if flen < uint32(len(buf)) || t != FrameServerKey || string(buf[:len(Magic)]) != Magic { return errors.New("invalid server greeting") } - c.serverKey = key.NodePublicFromRaw32(mem.B(buf[len(magic):])) + c.serverKey = key.NodePublicFromRaw32(mem.B(buf[len(Magic):])) return nil } -func (c *Client) parseServerInfo(b []byte) (*serverInfo, error) { - const maxLength = nonceLen + maxInfoLen +func (c *Client) parseServerInfo(b []byte) (*ServerInfo, error) { + const maxLength = NonceLen + MaxInfoLen fl := len(b) - if fl < nonceLen { + if fl < NonceLen { return nil, fmt.Errorf("short serverInfo frame") } if fl > maxLength { @@ -153,19 +153,21 @@ func (c *Client) parseServerInfo(b []byte) (*serverInfo, error) { if !ok { return nil, fmt.Errorf("failed to open naclbox from server key %s", c.serverKey) } - info := new(serverInfo) + info := new(ServerInfo) if err := json.Unmarshal(msg, info); err != nil { return nil, fmt.Errorf("invalid JSON: %v", err) } return info, nil } -type clientInfo struct { +// ClientInfo is the information a DERP client sends to the server +// about itself when it connects. +type ClientInfo struct { // MeshKey optionally specifies a pre-shared key used by // trusted clients. It's required to subscribe to the // connection list & forward packets. It's empty for regular // users. - MeshKey string `json:"meshKey,omitempty"` + MeshKey key.DERPMesh `json:"meshKey,omitempty,omitzero"` // Version is the DERP protocol version that the client was built with. // See the ProtocolVersion const. @@ -179,8 +181,19 @@ type clientInfo struct { IsProber bool `json:",omitempty"` } +// Equal reports if two clientInfo values are equal. +func (c *ClientInfo) Equal(other *ClientInfo) bool { + if c == nil || other == nil { + return c == other + } + if c.Version != other.Version || c.CanAckPings != other.CanAckPings || c.IsProber != other.IsProber { + return false + } + return c.MeshKey.Equal(other.MeshKey) +} + func (c *Client) sendClientKey() error { - msg, err := json.Marshal(clientInfo{ + msg, err := json.Marshal(ClientInfo{ Version: ProtocolVersion, MeshKey: c.meshKey, CanAckPings: c.canAckPings, @@ -191,10 +204,10 @@ func (c *Client) sendClientKey() error { } msgbox := c.privateKey.SealTo(c.serverKey, msg) - buf := make([]byte, 0, keyLen+len(msgbox)) + buf := make([]byte, 0, KeyLen+len(msgbox)) buf = c.publicKey.AppendTo(buf) buf = append(buf, msgbox...) - return writeFrame(c.bw, frameClientInfo, buf) + return WriteFrame(c.bw, FrameClientInfo, buf) } // ServerPublicKey returns the server's public key. @@ -219,12 +232,12 @@ func (c *Client) send(dstKey key.NodePublic, pkt []byte) (ret error) { c.wmu.Lock() defer c.wmu.Unlock() if c.rate != nil { - pktLen := frameHeaderLen + key.NodePublicRawLen + len(pkt) + pktLen := FrameHeaderLen + key.NodePublicRawLen + len(pkt) if !c.rate.AllowN(c.clock.Now(), pktLen) { return nil // drop } } - if err := writeFrameHeader(c.bw, frameSendPacket, uint32(key.NodePublicRawLen+len(pkt))); err != nil { + if err := WriteFrameHeader(c.bw, FrameSendPacket, uint32(key.NodePublicRawLen+len(pkt))); err != nil { return err } if _, err := c.bw.Write(dstKey.AppendTo(nil)); err != nil { @@ -253,7 +266,7 @@ func (c *Client) ForwardPacket(srcKey, dstKey key.NodePublic, pkt []byte) (err e timer := c.clock.AfterFunc(5*time.Second, c.writeTimeoutFired) defer timer.Stop() - if err := writeFrameHeader(c.bw, frameForwardPacket, uint32(keyLen*2+len(pkt))); err != nil { + if err := WriteFrameHeader(c.bw, FrameForwardPacket, uint32(KeyLen*2+len(pkt))); err != nil { return err } if _, err := c.bw.Write(srcKey.AppendTo(nil)); err != nil { @@ -271,17 +284,17 @@ func (c *Client) ForwardPacket(srcKey, dstKey key.NodePublic, pkt []byte) (err e func (c *Client) writeTimeoutFired() { c.nc.Close() } func (c *Client) SendPing(data [8]byte) error { - return c.sendPingOrPong(framePing, data) + return c.sendPingOrPong(FramePing, data) } func (c *Client) SendPong(data [8]byte) error { - return c.sendPingOrPong(framePong, data) + return c.sendPingOrPong(FramePong, data) } -func (c *Client) sendPingOrPong(typ frameType, data [8]byte) error { +func (c *Client) sendPingOrPong(typ FrameType, data [8]byte) error { c.wmu.Lock() defer c.wmu.Unlock() - if err := writeFrameHeader(c.bw, typ, 8); err != nil { + if err := WriteFrameHeader(c.bw, typ, 8); err != nil { return err } if _, err := c.bw.Write(data[:]); err != nil { @@ -303,7 +316,7 @@ func (c *Client) NotePreferred(preferred bool) (err error) { c.wmu.Lock() defer c.wmu.Unlock() - if err := writeFrameHeader(c.bw, frameNotePreferred, 1); err != nil { + if err := WriteFrameHeader(c.bw, FrameNotePreferred, 1); err != nil { return err } var b byte = 0x00 @@ -321,7 +334,7 @@ func (c *Client) NotePreferred(preferred bool) (err error) { func (c *Client) WatchConnectionChanges() error { c.wmu.Lock() defer c.wmu.Unlock() - if err := writeFrameHeader(c.bw, frameWatchConns, 0); err != nil { + if err := WriteFrameHeader(c.bw, FrameWatchConns, 0); err != nil { return err } return c.bw.Flush() @@ -332,7 +345,7 @@ func (c *Client) WatchConnectionChanges() error { func (c *Client) ClosePeer(target key.NodePublic) error { c.wmu.Lock() defer c.wmu.Unlock() - return writeFrame(c.bw, frameClosePeer, target.AppendTo(nil)) + return WriteFrame(c.bw, FrameClosePeer, target.AppendTo(nil)) } // ReceivedMessage represents a type returned by Client.Recv. Unless @@ -491,7 +504,7 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro c.peeked = 0 } - t, n, err := readFrameHeader(c.br) + t, n, err := ReadFrameHeader(c.br) if err != nil { return nil, err } @@ -522,7 +535,7 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro switch t { default: continue - case frameServerInfo: + case FrameServerInfo: // Server sends this at start-up. Currently unused. // Just has a JSON message saying "version: 2", // but the protocol seems extensible enough as-is without @@ -539,29 +552,29 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro } c.setSendRateLimiter(sm) return sm, nil - case frameKeepAlive: + case FrameKeepAlive: // A one-way keep-alive message that doesn't require an acknowledgement. // This predated framePing/framePong. return KeepAliveMessage{}, nil - case framePeerGone: - if n < keyLen { + case FramePeerGone: + if n < KeyLen { c.logf("[unexpected] dropping short peerGone frame from DERP server") continue } // Backward compatibility for the older peerGone without reason byte reason := PeerGoneReasonDisconnected - if n > keyLen { - reason = PeerGoneReasonType(b[keyLen]) + if n > KeyLen { + reason = PeerGoneReasonType(b[KeyLen]) } pg := PeerGoneMessage{ - Peer: key.NodePublicFromRaw32(mem.B(b[:keyLen])), + Peer: key.NodePublicFromRaw32(mem.B(b[:KeyLen])), Reason: reason, } return pg, nil - case framePeerPresent: + case FramePeerPresent: remain := b - chunk, remain, ok := cutLeadingN(remain, keyLen) + chunk, remain, ok := cutLeadingN(remain, KeyLen) if !ok { c.logf("[unexpected] dropping short peerPresent frame from DERP server") continue @@ -589,17 +602,17 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro msg.Flags = PeerPresentFlags(chunk[0]) return msg, nil - case frameRecvPacket: + case FrameRecvPacket: var rp ReceivedPacket - if n < keyLen { + if n < KeyLen { c.logf("[unexpected] dropping short packet from DERP server") continue } - rp.Source = key.NodePublicFromRaw32(mem.B(b[:keyLen])) - rp.Data = b[keyLen:n] + rp.Source = key.NodePublicFromRaw32(mem.B(b[:KeyLen])) + rp.Data = b[KeyLen:n] return rp, nil - case framePing: + case FramePing: var pm PingMessage if n < 8 { c.logf("[unexpected] dropping short ping frame") @@ -608,7 +621,7 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro copy(pm[:], b[:]) return pm, nil - case framePong: + case FramePong: var pm PongMessage if n < 8 { c.logf("[unexpected] dropping short ping frame") @@ -617,10 +630,10 @@ func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err erro copy(pm[:], b[:]) return pm, nil - case frameHealth: + case FrameHealth: return HealthMessage{Problem: string(b[:])}, nil - case frameRestarting: + case FrameRestarting: var m ServerRestartingMessage if n < 8 { c.logf("[unexpected] dropping short server restarting frame") diff --git a/vendor/tailscale.com/derp/derp_server.go b/vendor/tailscale.com/derp/derp_server.go deleted file mode 100644 index c330572..0000000 --- a/vendor/tailscale.com/derp/derp_server.go +++ /dev/null @@ -1,2387 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package derp - -// TODO(crawshaw): with predefined serverKey in clients and HMAC on packets we could skip TLS - -import ( - "bufio" - "bytes" - "context" - "crypto/ed25519" - crand "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/binary" - "encoding/json" - "errors" - "expvar" - "fmt" - "io" - "log" - "math" - "math/big" - "math/rand/v2" - "net/http" - "net/netip" - "os" - "os/exec" - "runtime" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "go4.org/mem" - "golang.org/x/sync/errgroup" - "tailscale.com/client/local" - "tailscale.com/client/tailscale" - "tailscale.com/disco" - "tailscale.com/envknob" - "tailscale.com/metrics" - "tailscale.com/syncs" - "tailscale.com/tailcfg" - "tailscale.com/tstime" - "tailscale.com/tstime/rate" - "tailscale.com/types/key" - "tailscale.com/types/logger" - "tailscale.com/util/ctxkey" - "tailscale.com/util/mak" - "tailscale.com/util/set" - "tailscale.com/util/slicesx" - "tailscale.com/version" -) - -// verboseDropKeys is the set of destination public keys that should -// verbosely log whenever DERP drops a packet. -var verboseDropKeys = map[key.NodePublic]bool{} - -// IdealNodeHeader is the HTTP request header sent on DERP HTTP client requests -// to indicate that they're connecting to their ideal (Region.Nodes[0]) node. -// The HTTP header value is the name of the node they wish they were connected -// to. This is an optional header. -const IdealNodeHeader = "Ideal-Node" - -// IdealNodeContextKey is the context key used to pass the IdealNodeHeader value -// from the HTTP handler to the DERP server's Accept method. -var IdealNodeContextKey = ctxkey.New[string]("ideal-node", "") - -func init() { - keys := envknob.String("TS_DEBUG_VERBOSE_DROPS") - if keys == "" { - return - } - for _, keyStr := range strings.Split(keys, ",") { - k, err := key.ParseNodePublicUntyped(mem.S(keyStr)) - if err != nil { - log.Printf("ignoring invalid debug key %q: %v", keyStr, err) - } else { - verboseDropKeys[k] = true - } - } -} - -const ( - defaultPerClientSendQueueDepth = 32 // default packets buffered for sending - DefaultTCPWiteTimeout = 2 * time.Second - privilegedWriteTimeout = 30 * time.Second // for clients with the mesh key -) - -func getPerClientSendQueueDepth() int { - if v, ok := envknob.LookupInt("TS_DEBUG_DERP_PER_CLIENT_SEND_QUEUE_DEPTH"); ok { - return v - } - - return defaultPerClientSendQueueDepth -} - -// dupPolicy is a temporary (2021-08-30) mechanism to change the policy -// of how duplicate connection for the same key are handled. -type dupPolicy int8 - -const ( - // lastWriterIsActive is a dupPolicy where the connection - // to send traffic for a peer is the active one. - lastWriterIsActive dupPolicy = iota - - // disableFighters is a dupPolicy that detects if peers - // are trying to send interleaved with each other and - // then disables all of them. - disableFighters -) - -// packetKind is the kind of packet being sent through DERP -type packetKind string - -const ( - packetKindDisco packetKind = "disco" - packetKindOther packetKind = "other" -) - -type align64 [0]atomic.Int64 // for side effect of its 64-bit alignment - -// Server is a DERP server. -type Server struct { - // WriteTimeout, if non-zero, specifies how long to wait - // before failing when writing to a client. - WriteTimeout time.Duration - - privateKey key.NodePrivate - publicKey key.NodePublic - logf logger.Logf - memSys0 uint64 // runtime.MemStats.Sys at start (or early-ish) - meshKey string - limitedLogf logger.Logf - metaCert []byte // the encoded x509 cert to send after LetsEncrypt cert+intermediate - dupPolicy dupPolicy - debug bool - localClient local.Client - - // Counters: - packetsSent, bytesSent expvar.Int - packetsRecv, bytesRecv expvar.Int - packetsRecvByKind metrics.LabelMap - packetsRecvDisco *expvar.Int - packetsRecvOther *expvar.Int - _ align64 - packetsForwardedOut expvar.Int - packetsForwardedIn expvar.Int - peerGoneDisconnectedFrames expvar.Int // number of peer disconnected frames sent - peerGoneNotHereFrames expvar.Int // number of peer not here frames sent - gotPing expvar.Int // number of ping frames from client - sentPong expvar.Int // number of pong frames enqueued to client - accepts expvar.Int - curClients expvar.Int - curClientsNotIdeal expvar.Int - curHomeClients expvar.Int // ones with preferred - dupClientKeys expvar.Int // current number of public keys we have 2+ connections for - dupClientConns expvar.Int // current number of connections sharing a public key - dupClientConnTotal expvar.Int // total number of accepted connections when a dup key existed - unknownFrames expvar.Int - homeMovesIn expvar.Int // established clients announce home server moves in - homeMovesOut expvar.Int // established clients announce home server moves out - multiForwarderCreated expvar.Int - multiForwarderDeleted expvar.Int - removePktForwardOther expvar.Int - sclientWriteTimeouts expvar.Int - avgQueueDuration *uint64 // In milliseconds; accessed atomically - tcpRtt metrics.LabelMap // histogram - meshUpdateBatchSize *metrics.Histogram - meshUpdateLoopCount *metrics.Histogram - bufferedWriteFrames *metrics.Histogram // how many sendLoop frames (or groups of related frames) get written per flush - - // verifyClientsLocalTailscaled only accepts client connections to the DERP - // server if the clientKey is a known peer in the network, as specified by a - // running tailscaled's client's LocalAPI. - verifyClientsLocalTailscaled bool - - verifyClientsURL string - verifyClientsURLFailOpen bool - - mu sync.Mutex - closed bool - netConns map[Conn]chan struct{} // chan is closed when conn closes - clients map[key.NodePublic]*clientSet - watchers set.Set[*sclient] // mesh peers - // clientsMesh tracks all clients in the cluster, both locally - // and to mesh peers. If the value is nil, that means the - // peer is only local (and thus in the clients Map, but not - // remote). If the value is non-nil, it's remote (+ maybe also - // local). - clientsMesh map[key.NodePublic]PacketForwarder - // peerGoneWatchers is the set of watchers that subscribed to a - // peer disconnecting from the region overall. When a peer - // is gone from the region, we notify all of these watchers, - // calling their funcs in a new goroutine. - peerGoneWatchers map[key.NodePublic]set.HandleSet[func(key.NodePublic)] - - // maps from netip.AddrPort to a client's public key - keyOfAddr map[netip.AddrPort]key.NodePublic - - // Sets the client send queue depth for the server. - perClientSendQueueDepth int - - tcpWriteTimeout time.Duration - - clock tstime.Clock -} - -// clientSet represents 1 or more *sclients. -// -// In the common case, client should only have one connection to the -// DERP server for a given key. When they're connected multiple times, -// we record their set of connections in dupClientSet and keep their -// connections open to make them happy (to keep them from spinning, -// etc) and keep track of which is the latest connection. If only the last -// is sending traffic, that last one is the active connection and it -// gets traffic. Otherwise, in the case of a cloned node key, the -// whole set of dups doesn't receive data frames. -// -// All methods should only be called while holding Server.mu. -// -// TODO(bradfitz): Issue 2746: in the future we'll send some sort of -// "health_error" frame to them that'll communicate to the end users -// that they cloned a device key, and we'll also surface it in the -// admin panel, etc. -type clientSet struct { - // activeClient holds the currently active connection for the set. It's nil - // if there are no connections or the connection is disabled. - // - // A pointer to a clientSet can be held by peers for long periods of time - // without holding Server.mu to avoid mutex contention on Server.mu, only - // re-acquiring the mutex and checking the clients map if activeClient is - // nil. - activeClient atomic.Pointer[sclient] - - // dup is non-nil if there are multiple connections for the - // public key. It's nil in the common case of only one - // client being connected. - // - // dup is guarded by Server.mu. - dup *dupClientSet -} - -// Len returns the number of clients in s, which can be -// 0, 1 (the common case), or more (for buggy or transiently -// reconnecting clients). -func (s *clientSet) Len() int { - if s.dup != nil { - return len(s.dup.set) - } - if s.activeClient.Load() != nil { - return 1 - } - return 0 -} - -// ForeachClient calls f for each client in the set. -// -// The Server.mu must be held. -func (s *clientSet) ForeachClient(f func(*sclient)) { - if s.dup != nil { - for c := range s.dup.set { - f(c) - } - } else if c := s.activeClient.Load(); c != nil { - f(c) - } -} - -// A dupClientSet is a clientSet of more than 1 connection. -// -// This can occur in some reasonable cases (temporarily while users -// are changing networks) or in the case of a cloned key. In the -// cloned key case, both peers are speaking and the clients get -// disabled. -// -// All fields are guarded by Server.mu. -type dupClientSet struct { - // set is the set of connected clients for sclient.key, - // including the clientSet's active one. - set set.Set[*sclient] - - // last is the most recent addition to set, or nil if the most - // recent one has since disconnected and nobody else has sent - // data since. - last *sclient - - // sendHistory is a log of which members of set have sent - // frames to the derp server, with adjacent duplicates - // removed. When a member of set is removed, the same - // element(s) are removed from sendHistory. - sendHistory []*sclient -} - -func (s *clientSet) pickActiveClient() *sclient { - d := s.dup - if d == nil { - return s.activeClient.Load() - } - if d.last != nil && !d.last.isDisabled.Load() { - return d.last - } - return nil -} - -// removeClient removes c from s and reports whether it was in s -// to begin with. -func (s *dupClientSet) removeClient(c *sclient) bool { - n := len(s.set) - delete(s.set, c) - if s.last == c { - s.last = nil - } - if len(s.set) == n { - return false - } - - trim := s.sendHistory[:0] - for _, v := range s.sendHistory { - if s.set.Contains(v) && (len(trim) == 0 || trim[len(trim)-1] != v) { - trim = append(trim, v) - } - } - for i := len(trim); i < len(s.sendHistory); i++ { - s.sendHistory[i] = nil - } - s.sendHistory = trim - if s.last == nil && len(s.sendHistory) > 0 { - s.last = s.sendHistory[len(s.sendHistory)-1] - } - return true -} - -// PacketForwarder is something that can forward packets. -// -// It's mostly an interface for circular dependency reasons; the -// typical implementation is derphttp.Client. The other implementation -// is a multiForwarder, which this package creates as needed if a -// public key gets more than one PacketForwarder registered for it. -type PacketForwarder interface { - ForwardPacket(src, dst key.NodePublic, payload []byte) error - String() string -} - -var packetsDropped = metrics.NewMultiLabelMap[dropReasonKindLabels]( - "derp_packets_dropped", - "counter", - "DERP packets dropped by reason and by kind") - -var bytesDropped = metrics.NewMultiLabelMap[dropReasonKindLabels]( - "derp_bytes_dropped", - "counter", - "DERP bytes dropped by reason and by kind", -) - -// NewServer returns a new DERP server. It doesn't listen on its own. -// Connections are given to it via Server.Accept. -func NewServer(privateKey key.NodePrivate, logf logger.Logf) *Server { - var ms runtime.MemStats - runtime.ReadMemStats(&ms) - - s := &Server{ - debug: envknob.Bool("DERP_DEBUG_LOGS"), - privateKey: privateKey, - publicKey: privateKey.Public(), - logf: logf, - limitedLogf: logger.RateLimitedFn(logf, 30*time.Second, 5, 100), - packetsRecvByKind: metrics.LabelMap{Label: "kind"}, - clients: map[key.NodePublic]*clientSet{}, - clientsMesh: map[key.NodePublic]PacketForwarder{}, - netConns: map[Conn]chan struct{}{}, - memSys0: ms.Sys, - watchers: set.Set[*sclient]{}, - peerGoneWatchers: map[key.NodePublic]set.HandleSet[func(key.NodePublic)]{}, - avgQueueDuration: new(uint64), - tcpRtt: metrics.LabelMap{Label: "le"}, - meshUpdateBatchSize: metrics.NewHistogram([]float64{0, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000}), - meshUpdateLoopCount: metrics.NewHistogram([]float64{0, 1, 2, 5, 10, 20, 50, 100}), - bufferedWriteFrames: metrics.NewHistogram([]float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 50, 100}), - keyOfAddr: map[netip.AddrPort]key.NodePublic{}, - clock: tstime.StdClock{}, - tcpWriteTimeout: DefaultTCPWiteTimeout, - } - s.initMetacert() - s.packetsRecvDisco = s.packetsRecvByKind.Get(string(packetKindDisco)) - s.packetsRecvOther = s.packetsRecvByKind.Get(string(packetKindOther)) - - genDroppedCounters() - - s.perClientSendQueueDepth = getPerClientSendQueueDepth() - return s -} - -func genDroppedCounters() { - initMetrics := func(reason dropReason) { - packetsDropped.Add(dropReasonKindLabels{ - Kind: string(packetKindDisco), - Reason: string(reason), - }, 0) - packetsDropped.Add(dropReasonKindLabels{ - Kind: string(packetKindOther), - Reason: string(reason), - }, 0) - bytesDropped.Add(dropReasonKindLabels{ - Kind: string(packetKindDisco), - Reason: string(reason), - }, 0) - bytesDropped.Add(dropReasonKindLabels{ - Kind: string(packetKindOther), - Reason: string(reason), - }, 0) - } - getMetrics := func(reason dropReason) []expvar.Var { - return []expvar.Var{ - packetsDropped.Get(dropReasonKindLabels{ - Kind: string(packetKindDisco), - Reason: string(reason), - }), - packetsDropped.Get(dropReasonKindLabels{ - Kind: string(packetKindOther), - Reason: string(reason), - }), - bytesDropped.Get(dropReasonKindLabels{ - Kind: string(packetKindDisco), - Reason: string(reason), - }), - bytesDropped.Get(dropReasonKindLabels{ - Kind: string(packetKindOther), - Reason: string(reason), - }), - } - } - - dropReasons := []dropReason{ - dropReasonUnknownDest, - dropReasonUnknownDestOnFwd, - dropReasonGoneDisconnected, - dropReasonQueueHead, - dropReasonQueueTail, - dropReasonWriteError, - dropReasonDupClient, - } - - for _, dr := range dropReasons { - initMetrics(dr) - m := getMetrics(dr) - if len(m) != 4 { - panic("dropReason metrics out of sync") - } - - for _, v := range m { - if v == nil { - panic("dropReason metrics out of sync") - } - } - } -} - -// SetMesh sets the pre-shared key that regional DERP servers used to mesh -// amongst themselves. -// -// It must be called before serving begins. -func (s *Server) SetMeshKey(v string) { - s.meshKey = v -} - -// SetVerifyClients sets whether this DERP server verifies clients through tailscaled. -// -// It must be called before serving begins. -func (s *Server) SetVerifyClient(v bool) { - s.verifyClientsLocalTailscaled = v -} - -// SetVerifyClientURL sets the admission controller URL to use for verifying clients. -// If empty, all clients are accepted (unless restricted by SetVerifyClient checking -// against tailscaled). -func (s *Server) SetVerifyClientURL(v string) { - s.verifyClientsURL = v -} - -// SetVerifyClientURLFailOpen sets whether to allow clients to connect if the -// admission controller URL is unreachable. -func (s *Server) SetVerifyClientURLFailOpen(v bool) { - s.verifyClientsURLFailOpen = v -} - -// SetTailscaledSocketPath sets the unix socket path to use to talk to -// tailscaled if client verification is enabled. -// -// If unset or set to the empty string, the default path for the operating -// system is used. -func (s *Server) SetTailscaledSocketPath(path string) { - s.localClient.Socket = path - s.localClient.UseSocketOnly = path != "" -} - -// SetTCPWriteTimeout sets the timeout for writing to connected clients. -// This timeout does not apply to mesh connections. -// Defaults to 2 seconds. -func (s *Server) SetTCPWriteTimeout(d time.Duration) { - s.tcpWriteTimeout = d -} - -// HasMeshKey reports whether the server is configured with a mesh key. -func (s *Server) HasMeshKey() bool { return s.meshKey != "" } - -// MeshKey returns the configured mesh key, if any. -func (s *Server) MeshKey() string { return s.meshKey } - -// PrivateKey returns the server's private key. -func (s *Server) PrivateKey() key.NodePrivate { return s.privateKey } - -// PublicKey returns the server's public key. -func (s *Server) PublicKey() key.NodePublic { return s.publicKey } - -// Close closes the server and waits for the connections to disconnect. -func (s *Server) Close() error { - s.mu.Lock() - wasClosed := s.closed - s.closed = true - s.mu.Unlock() - if wasClosed { - return nil - } - - var closedChs []chan struct{} - - s.mu.Lock() - for nc, closed := range s.netConns { - nc.Close() - closedChs = append(closedChs, closed) - } - s.mu.Unlock() - - for _, closed := range closedChs { - <-closed - } - - return nil -} - -func (s *Server) isClosed() bool { - s.mu.Lock() - defer s.mu.Unlock() - return s.closed -} - -// IsClientConnectedForTest reports whether the client with specified key is connected. -// This is used in tests to verify that nodes are connected. -func (s *Server) IsClientConnectedForTest(k key.NodePublic) bool { - s.mu.Lock() - defer s.mu.Unlock() - x, ok := s.clients[k] - if !ok { - return false - } - return x.activeClient.Load() != nil -} - -// Accept adds a new connection to the server and serves it. -// -// The provided bufio ReadWriter must be already connected to nc. -// Accept blocks until the Server is closed or the connection closes -// on its own. -// -// Accept closes nc. -func (s *Server) Accept(ctx context.Context, nc Conn, brw *bufio.ReadWriter, remoteAddr string) { - closed := make(chan struct{}) - - s.mu.Lock() - s.accepts.Add(1) // while holding s.mu for connNum read on next line - connNum := s.accepts.Value() // expvar sadly doesn't return new value on Add(1) - s.netConns[nc] = closed - s.mu.Unlock() - - defer func() { - nc.Close() - close(closed) - - s.mu.Lock() - delete(s.netConns, nc) - s.mu.Unlock() - }() - - if err := s.accept(ctx, nc, brw, remoteAddr, connNum); err != nil && !s.isClosed() { - s.logf("derp: %s: %v", remoteAddr, err) - } -} - -// initMetacert initialized s.metaCert with a self-signed x509 cert -// encoding this server's public key and protocol version. cmd/derper -// then sends this after the Let's Encrypt leaf + intermediate certs -// after the ServerHello (encrypted in TLS 1.3, not that it matters -// much). -// -// Then the client can save a round trip getting that and can start -// speaking DERP right away. (We don't use ALPN because that's sent in -// the clear and we're being paranoid to not look too weird to any -// middleboxes, given that DERP is an ultimate fallback path). But -// since the post-ServerHello certs are encrypted we can have the -// client also use them as a signal to be able to start speaking DERP -// right away, starting with its identity proof, encrypted to the -// server's public key. -// -// This RTT optimization fails where there's a corp-mandated -// TLS proxy with corp-mandated root certs on employee machines and -// and TLS proxy cleans up unnecessary certs. In that case we just fall -// back to the extra RTT. -func (s *Server) initMetacert() { - pub, priv, err := ed25519.GenerateKey(crand.Reader) - if err != nil { - log.Fatal(err) - } - tmpl := &x509.Certificate{ - SerialNumber: big.NewInt(ProtocolVersion), - Subject: pkix.Name{ - CommonName: fmt.Sprintf("derpkey%s", s.publicKey.UntypedHexString()), - }, - // Windows requires NotAfter and NotBefore set: - NotAfter: s.clock.Now().Add(30 * 24 * time.Hour), - NotBefore: s.clock.Now().Add(-30 * 24 * time.Hour), - // Per https://github.com/golang/go/issues/51759#issuecomment-1071147836, - // macOS requires BasicConstraints when subject == issuer: - BasicConstraintsValid: true, - } - cert, err := x509.CreateCertificate(crand.Reader, tmpl, tmpl, pub, priv) - if err != nil { - log.Fatalf("CreateCertificate: %v", err) - } - s.metaCert = cert -} - -// MetaCert returns the server metadata cert that can be sent by the -// TLS server to let the client skip a round trip during start-up. -func (s *Server) MetaCert() []byte { return s.metaCert } - -// registerClient notes that client c is now authenticated and ready for packets. -// -// If c.key is connected more than once, the earlier connection(s) are -// placed in a non-active state where we read from them (primarily to -// observe EOFs/timeouts) but won't send them frames on the assumption -// that they're dead. -func (s *Server) registerClient(c *sclient) { - s.mu.Lock() - defer s.mu.Unlock() - - cs, ok := s.clients[c.key] - if !ok { - c.debugLogf("register single client") - cs = &clientSet{} - s.clients[c.key] = cs - } - was := cs.activeClient.Load() - if was == nil { - // Common case. - } else { - was.isDup.Store(true) - c.isDup.Store(true) - } - - dup := cs.dup - if dup == nil && was != nil { - s.dupClientKeys.Add(1) - s.dupClientConns.Add(2) // both old and new count - s.dupClientConnTotal.Add(1) - dup = &dupClientSet{ - set: set.Of(c, was), - last: c, - sendHistory: []*sclient{was}, - } - cs.dup = dup - c.debugLogf("register duplicate client") - } else if dup != nil { - s.dupClientConns.Add(1) // the gauge - s.dupClientConnTotal.Add(1) // the counter - dup.set.Add(c) - dup.last = c - dup.sendHistory = append(dup.sendHistory, c) - c.debugLogf("register another duplicate client") - } - - cs.activeClient.Store(c) - - if _, ok := s.clientsMesh[c.key]; !ok { - s.clientsMesh[c.key] = nil // just for varz of total users in cluster - } - s.keyOfAddr[c.remoteIPPort] = c.key - s.curClients.Add(1) - if c.isNotIdealConn { - s.curClientsNotIdeal.Add(1) - } - s.broadcastPeerStateChangeLocked(c.key, c.remoteIPPort, c.presentFlags(), true) -} - -// broadcastPeerStateChangeLocked enqueues a message to all watchers -// (other DERP nodes in the region, or trusted clients) that peer's -// presence changed. -// -// s.mu must be held. -func (s *Server) broadcastPeerStateChangeLocked(peer key.NodePublic, ipPort netip.AddrPort, flags PeerPresentFlags, present bool) { - for w := range s.watchers { - w.peerStateChange = append(w.peerStateChange, peerConnState{ - peer: peer, - present: present, - ipPort: ipPort, - flags: flags, - }) - go w.requestMeshUpdate() - } -} - -// unregisterClient removes a client from the server. -func (s *Server) unregisterClient(c *sclient) { - s.mu.Lock() - defer s.mu.Unlock() - - set, ok := s.clients[c.key] - if !ok { - c.logf("[unexpected]; clients map is empty") - return - } - - dup := set.dup - if dup == nil { - // The common case. - cur := set.activeClient.Load() - if cur == nil { - c.logf("[unexpected]; active client is nil") - return - } - if cur != c { - c.logf("[unexpected]; active client is not c") - return - } - c.debugLogf("removed connection") - set.activeClient.Store(nil) - delete(s.clients, c.key) - if v, ok := s.clientsMesh[c.key]; ok && v == nil { - delete(s.clientsMesh, c.key) - s.notePeerGoneFromRegionLocked(c.key) - } - s.broadcastPeerStateChangeLocked(c.key, netip.AddrPort{}, 0, false) - } else { - c.debugLogf("removed duplicate client") - if dup.removeClient(c) { - s.dupClientConns.Add(-1) - } else { - c.logf("[unexpected]; dup client set didn't shrink") - } - if dup.set.Len() == 1 { - // If we drop down to one connection, demote it down - // to a regular single client (a nil dup set). - set.dup = nil - s.dupClientConns.Add(-1) // again; for the original one's - s.dupClientKeys.Add(-1) - var remain *sclient - for remain = range dup.set { - break - } - if remain == nil { - panic("unexpected nil remain from single element dup set") - } - remain.isDisabled.Store(false) - remain.isDup.Store(false) - set.activeClient.Store(remain) - } else { - // Still a duplicate. Pick a winner. - set.activeClient.Store(set.pickActiveClient()) - } - } - - if c.canMesh { - delete(s.watchers, c) - } - - delete(s.keyOfAddr, c.remoteIPPort) - - s.curClients.Add(-1) - if c.preferred { - s.curHomeClients.Add(-1) - } - if c.isNotIdealConn { - s.curClientsNotIdeal.Add(-1) - } -} - -// addPeerGoneFromRegionWatcher adds a function to be called when peer is gone -// from the region overall. It returns a handle that can be used to remove the -// watcher later. -// -// The provided f func is usually [sclient.onPeerGoneFromRegion], added by -// [sclient.noteSendFromSrc]; this func doesn't take a whole *sclient to make it -// clear what has access to what. -func (s *Server) addPeerGoneFromRegionWatcher(peer key.NodePublic, f func(key.NodePublic)) set.Handle { - s.mu.Lock() - defer s.mu.Unlock() - hset, ok := s.peerGoneWatchers[peer] - if !ok { - hset = set.HandleSet[func(key.NodePublic)]{} - s.peerGoneWatchers[peer] = hset - } - return hset.Add(f) -} - -// removePeerGoneFromRegionWatcher removes a peer watcher previously added by -// addPeerGoneFromRegionWatcher, using the handle returned by -// addPeerGoneFromRegionWatcher. -func (s *Server) removePeerGoneFromRegionWatcher(peer key.NodePublic, h set.Handle) { - s.mu.Lock() - defer s.mu.Unlock() - hset, ok := s.peerGoneWatchers[peer] - if !ok { - return - } - delete(hset, h) - if len(hset) == 0 { - delete(s.peerGoneWatchers, peer) - } -} - -// notePeerGoneFromRegionLocked sends peerGone frames to parties that -// key has sent to previously (whether those sends were from a local -// client or forwarded). It must only be called after the key has -// been removed from clientsMesh. -func (s *Server) notePeerGoneFromRegionLocked(key key.NodePublic) { - if _, ok := s.clientsMesh[key]; ok { - panic("usage") - } - - // Find still-connected peers and either notify that we've gone away - // so they can drop their route entries to us (issue 150) - // or move them over to the active client (in case a replaced client - // connection is being unregistered). - set := s.peerGoneWatchers[key] - for _, f := range set { - go f(key) - } - delete(s.peerGoneWatchers, key) -} - -// requestPeerGoneWriteLimited sends a request to write a "peer gone" -// frame, but only in reply to a disco packet, and only if we haven't -// sent one recently. -func (c *sclient) requestPeerGoneWriteLimited(peer key.NodePublic, contents []byte, reason PeerGoneReasonType) { - if disco.LooksLikeDiscoWrapper(contents) != true { - return - } - - if c.peerGoneLim.Allow() { - go c.requestPeerGoneWrite(peer, reason) - } -} - -func (s *Server) addWatcher(c *sclient) { - if !c.canMesh { - panic("invariant: addWatcher called without permissions") - } - - if c.key == s.publicKey { - // We're connecting to ourself. Do nothing. - return - } - - s.mu.Lock() - defer s.mu.Unlock() - - // Queue messages for each already-connected client. - for peer, clientSet := range s.clients { - ac := clientSet.activeClient.Load() - if ac == nil { - continue - } - c.peerStateChange = append(c.peerStateChange, peerConnState{ - peer: peer, - present: true, - ipPort: ac.remoteIPPort, - flags: ac.presentFlags(), - }) - } - - // And enroll the watcher in future updates (of both - // connections & disconnections). - s.watchers.Add(c) - - go c.requestMeshUpdate() -} - -func (s *Server) accept(ctx context.Context, nc Conn, brw *bufio.ReadWriter, remoteAddr string, connNum int64) error { - br := brw.Reader - nc.SetDeadline(time.Now().Add(10 * time.Second)) - bw := &lazyBufioWriter{w: nc, lbw: brw.Writer} - if err := s.sendServerKey(bw); err != nil { - return fmt.Errorf("send server key: %v", err) - } - nc.SetDeadline(time.Now().Add(10 * time.Second)) - clientKey, clientInfo, err := s.recvClientKey(br) - if err != nil { - return fmt.Errorf("receive client key: %v", err) - } - - remoteIPPort, _ := netip.ParseAddrPort(remoteAddr) - if err := s.verifyClient(ctx, clientKey, clientInfo, remoteIPPort.Addr()); err != nil { - return fmt.Errorf("client %v rejected: %v", clientKey, err) - } - - // At this point we trust the client so we don't time out. - nc.SetDeadline(time.Time{}) - - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - c := &sclient{ - connNum: connNum, - s: s, - key: clientKey, - nc: nc, - br: br, - bw: bw, - logf: logger.WithPrefix(s.logf, fmt.Sprintf("derp client %v%s: ", remoteAddr, clientKey.ShortString())), - done: ctx.Done(), - remoteIPPort: remoteIPPort, - connectedAt: s.clock.Now(), - sendQueue: make(chan pkt, s.perClientSendQueueDepth), - discoSendQueue: make(chan pkt, s.perClientSendQueueDepth), - sendPongCh: make(chan [8]byte, 1), - peerGone: make(chan peerGoneMsg), - canMesh: s.isMeshPeer(clientInfo), - isNotIdealConn: IdealNodeContextKey.Value(ctx) != "", - peerGoneLim: rate.NewLimiter(rate.Every(time.Second), 3), - } - - if c.canMesh { - c.meshUpdate = make(chan struct{}, 1) // must be buffered; >1 is fine but wasteful - } - if clientInfo != nil { - c.info = *clientInfo - if envknob.Bool("DERP_PROBER_DEBUG_LOGS") && clientInfo.IsProber { - c.debug = true - } - } - if s.debug { - c.debug = true - } - - s.registerClient(c) - defer s.unregisterClient(c) - - err = s.sendServerInfo(c.bw, clientKey) - if err != nil { - return fmt.Errorf("send server info: %v", err) - } - - return c.run(ctx) -} - -func (s *Server) debugLogf(format string, v ...any) { - if s.debug { - s.logf(format, v...) - } -} - -// run serves the client until there's an error. -// If the client hangs up or the server is closed, run returns nil, otherwise run returns an error. -func (c *sclient) run(ctx context.Context) error { - // Launch sender, but don't return from run until sender goroutine is done. - var grp errgroup.Group - sendCtx, cancelSender := context.WithCancel(ctx) - grp.Go(func() error { return c.sendLoop(sendCtx) }) - defer func() { - cancelSender() - if err := grp.Wait(); err != nil && !c.s.isClosed() { - if errors.Is(err, context.Canceled) { - c.debugLogf("sender canceled by reader exiting") - } else { - if errors.Is(err, os.ErrDeadlineExceeded) { - c.s.sclientWriteTimeouts.Add(1) - } - c.logf("sender failed: %v", err) - } - } - }() - - c.startStatsLoop(sendCtx) - - for { - ft, fl, err := readFrameHeader(c.br) - c.debugLogf("read frame type %d len %d err %v", ft, fl, err) - if err != nil { - if errors.Is(err, io.EOF) { - c.debugLogf("read EOF") - return nil - } - if c.s.isClosed() { - c.logf("closing; server closed") - return nil - } - return fmt.Errorf("client %s: readFrameHeader: %w", c.key.ShortString(), err) - } - c.s.noteClientActivity(c) - switch ft { - case frameNotePreferred: - err = c.handleFrameNotePreferred(ft, fl) - case frameSendPacket: - err = c.handleFrameSendPacket(ft, fl) - case frameForwardPacket: - err = c.handleFrameForwardPacket(ft, fl) - case frameWatchConns: - err = c.handleFrameWatchConns(ft, fl) - case frameClosePeer: - err = c.handleFrameClosePeer(ft, fl) - case framePing: - err = c.handleFramePing(ft, fl) - default: - err = c.handleUnknownFrame(ft, fl) - } - if err != nil { - return err - } - } -} - -func (c *sclient) handleUnknownFrame(ft frameType, fl uint32) error { - _, err := io.CopyN(io.Discard, c.br, int64(fl)) - return err -} - -func (c *sclient) handleFrameNotePreferred(ft frameType, fl uint32) error { - if fl != 1 { - return fmt.Errorf("frameNotePreferred wrong size") - } - v, err := c.br.ReadByte() - if err != nil { - return fmt.Errorf("frameNotePreferred ReadByte: %v", err) - } - c.setPreferred(v != 0) - return nil -} - -func (c *sclient) handleFrameWatchConns(ft frameType, fl uint32) error { - if fl != 0 { - return fmt.Errorf("handleFrameWatchConns wrong size") - } - if !c.canMesh { - return fmt.Errorf("insufficient permissions") - } - c.s.addWatcher(c) - return nil -} - -func (c *sclient) handleFramePing(ft frameType, fl uint32) error { - c.s.gotPing.Add(1) - var m PingMessage - if fl < uint32(len(m)) { - return fmt.Errorf("short ping: %v", fl) - } - if fl > 1000 { - // unreasonably extra large. We leave some extra - // space for future extensibility, but not too much. - return fmt.Errorf("ping body too large: %v", fl) - } - _, err := io.ReadFull(c.br, m[:]) - if err != nil { - return err - } - if extra := int64(fl) - int64(len(m)); extra > 0 { - _, err = io.CopyN(io.Discard, c.br, extra) - } - select { - case c.sendPongCh <- [8]byte(m): - default: - // They're pinging too fast. Ignore. - // TODO(bradfitz): add a rate limiter too. - } - return err -} - -func (c *sclient) handleFrameClosePeer(ft frameType, fl uint32) error { - if fl != keyLen { - return fmt.Errorf("handleFrameClosePeer wrong size") - } - if !c.canMesh { - return fmt.Errorf("insufficient permissions") - } - var targetKey key.NodePublic - if err := targetKey.ReadRawWithoutAllocating(c.br); err != nil { - return err - } - s := c.s - - s.mu.Lock() - defer s.mu.Unlock() - - if set, ok := s.clients[targetKey]; ok { - if set.Len() == 1 { - c.logf("frameClosePeer closing peer %x", targetKey) - } else { - c.logf("frameClosePeer closing peer %x (%d connections)", targetKey, set.Len()) - } - set.ForeachClient(func(target *sclient) { - go target.nc.Close() - }) - } else { - c.logf("frameClosePeer failed to find peer %x", targetKey) - } - - return nil -} - -// handleFrameForwardPacket reads a "forward packet" frame from the client -// (which must be a trusted client, a peer in our mesh). -func (c *sclient) handleFrameForwardPacket(ft frameType, fl uint32) error { - if !c.canMesh { - return fmt.Errorf("insufficient permissions") - } - s := c.s - - srcKey, dstKey, contents, err := s.recvForwardPacket(c.br, fl) - if err != nil { - return fmt.Errorf("client %v: recvForwardPacket: %v", c.key, err) - } - s.packetsForwardedIn.Add(1) - - var dstLen int - var dst *sclient - - s.mu.Lock() - if set, ok := s.clients[dstKey]; ok { - dstLen = set.Len() - dst = set.activeClient.Load() - } - s.mu.Unlock() - - if dst == nil { - reason := dropReasonUnknownDestOnFwd - if dstLen > 1 { - reason = dropReasonDupClient - } else { - c.requestPeerGoneWriteLimited(dstKey, contents, PeerGoneReasonNotHere) - } - s.recordDrop(contents, srcKey, dstKey, reason) - return nil - } - - dst.debugLogf("received forwarded packet from %s via %s", srcKey.ShortString(), c.key.ShortString()) - - return c.sendPkt(dst, pkt{ - bs: contents, - enqueuedAt: c.s.clock.Now(), - src: srcKey, - }) -} - -// handleFrameSendPacket reads a "send packet" frame from the client. -func (c *sclient) handleFrameSendPacket(ft frameType, fl uint32) error { - s := c.s - - dstKey, contents, err := s.recvPacket(c.br, fl) - if err != nil { - return fmt.Errorf("client %v: recvPacket: %v", c.key, err) - } - - var fwd PacketForwarder - var dstLen int - var dst *sclient - - s.mu.Lock() - if set, ok := s.clients[dstKey]; ok { - dstLen = set.Len() - dst = set.activeClient.Load() - } - if dst == nil && dstLen < 1 { - fwd = s.clientsMesh[dstKey] - } - s.mu.Unlock() - - if dst == nil { - if fwd != nil { - s.packetsForwardedOut.Add(1) - err := fwd.ForwardPacket(c.key, dstKey, contents) - c.debugLogf("SendPacket for %s, forwarding via %s: %v", dstKey.ShortString(), fwd, err) - if err != nil { - // TODO: - return nil - } - return nil - } - reason := dropReasonUnknownDest - if dstLen > 1 { - reason = dropReasonDupClient - } else { - c.requestPeerGoneWriteLimited(dstKey, contents, PeerGoneReasonNotHere) - } - s.recordDrop(contents, c.key, dstKey, reason) - c.debugLogf("SendPacket for %s, dropping with reason=%s", dstKey.ShortString(), reason) - return nil - } - c.debugLogf("SendPacket for %s, sending directly", dstKey.ShortString()) - - p := pkt{ - bs: contents, - enqueuedAt: c.s.clock.Now(), - src: c.key, - } - return c.sendPkt(dst, p) -} - -func (c *sclient) debugLogf(format string, v ...any) { - if c.debug { - c.logf(format, v...) - } -} - -type dropReasonKindLabels struct { - Reason string // metric label corresponding to a given dropReason - Kind string // either `disco` or `other` -} - -// dropReason is why we dropped a DERP frame. -type dropReason string - -const ( - dropReasonUnknownDest dropReason = "unknown_dest" // unknown destination pubkey - dropReasonUnknownDestOnFwd dropReason = "unknown_dest_on_fwd" // unknown destination pubkey on a derp-forwarded packet - dropReasonGoneDisconnected dropReason = "gone_disconnected" // destination tailscaled disconnected before we could send - dropReasonQueueHead dropReason = "queue_head" // destination queue is full, dropped packet at queue head - dropReasonQueueTail dropReason = "queue_tail" // destination queue is full, dropped packet at queue tail - dropReasonWriteError dropReason = "write_error" // OS write() failed - dropReasonDupClient dropReason = "dup_client" // the public key is connected 2+ times (active/active, fighting) -) - -func (s *Server) recordDrop(packetBytes []byte, srcKey, dstKey key.NodePublic, reason dropReason) { - labels := dropReasonKindLabels{ - Reason: string(reason), - } - looksDisco := disco.LooksLikeDiscoWrapper(packetBytes) - if looksDisco { - labels.Kind = string(packetKindDisco) - } else { - labels.Kind = string(packetKindOther) - } - packetsDropped.Add(labels, 1) - bytesDropped.Add(labels, int64(len(packetBytes))) - - if verboseDropKeys[dstKey] { - // Preformat the log string prior to calling limitedLogf. The - // limiter acts based on the format string, and we want to - // rate-limit per src/dst keys, not on the generic "dropped - // stuff" message. - msg := fmt.Sprintf("drop (%s) %s -> %s", srcKey.ShortString(), reason, dstKey.ShortString()) - s.limitedLogf(msg) - } - s.debugLogf("dropping packet reason=%s dst=%s disco=%v", reason, dstKey, looksDisco) -} - -func (c *sclient) sendPkt(dst *sclient, p pkt) error { - s := c.s - dstKey := dst.key - - // Attempt to queue for sending up to 3 times. On each attempt, if - // the queue is full, try to drop from queue head to prioritize - // fresher packets. - sendQueue := dst.sendQueue - if disco.LooksLikeDiscoWrapper(p.bs) { - sendQueue = dst.discoSendQueue - } - for attempt := 0; attempt < 3; attempt++ { - select { - case <-dst.done: - s.recordDrop(p.bs, c.key, dstKey, dropReasonGoneDisconnected) - dst.debugLogf("sendPkt attempt %d dropped, dst gone", attempt) - return nil - default: - } - select { - case sendQueue <- p: - dst.debugLogf("sendPkt attempt %d enqueued", attempt) - return nil - default: - } - - select { - case pkt := <-sendQueue: - s.recordDrop(pkt.bs, c.key, dstKey, dropReasonQueueHead) - c.recordQueueTime(pkt.enqueuedAt) - default: - } - } - // Failed to make room for packet. This can happen in a heavily - // contended queue with racing writers. Give up and tail-drop in - // this case to keep reader unblocked. - s.recordDrop(p.bs, c.key, dstKey, dropReasonQueueTail) - dst.debugLogf("sendPkt attempt %d dropped, queue full") - - return nil -} - -// onPeerGoneFromRegion is the callback registered with the Server to be -// notified (in a new goroutine) whenever a peer has disconnected from all DERP -// nodes in the current region. -func (c *sclient) onPeerGoneFromRegion(peer key.NodePublic) { - c.requestPeerGoneWrite(peer, PeerGoneReasonDisconnected) -} - -// requestPeerGoneWrite sends a request to write a "peer gone" frame -// with an explanation of why it is gone. It blocks until either the -// write request is scheduled, or the client has closed. -func (c *sclient) requestPeerGoneWrite(peer key.NodePublic, reason PeerGoneReasonType) { - select { - case c.peerGone <- peerGoneMsg{ - peer: peer, - reason: reason, - }: - case <-c.done: - } -} - -// requestMeshUpdate notes that a c's peerStateChange has been appended to and -// should now be written. -// -// It does not block. If a meshUpdate is already pending for this client, it -// does nothing. -func (c *sclient) requestMeshUpdate() { - if !c.canMesh { - panic("unexpected requestMeshUpdate") - } - select { - case c.meshUpdate <- struct{}{}: - default: - } -} - -// isMeshPeer reports whether the client is a trusted mesh peer -// node in the DERP region. -func (s *Server) isMeshPeer(info *clientInfo) bool { - return info != nil && info.MeshKey != "" && info.MeshKey == s.meshKey -} - -// verifyClient checks whether the client is allowed to connect to the derper, -// depending on how & whether the server's been configured to verify. -func (s *Server) verifyClient(ctx context.Context, clientKey key.NodePublic, info *clientInfo, clientIP netip.Addr) error { - if s.isMeshPeer(info) { - // Trusted mesh peer. No need to verify further. In fact, verifying - // further wouldn't work: it's not part of the tailnet so tailscaled and - // likely the admission control URL wouldn't know about it. - return nil - } - - // tailscaled-based verification: - if s.verifyClientsLocalTailscaled { - _, err := s.localClient.WhoIsNodeKey(ctx, clientKey) - if err == tailscale.ErrPeerNotFound { - return fmt.Errorf("peer %v not authorized (not found in local tailscaled)", clientKey) - } - if err != nil { - if strings.Contains(err.Error(), "invalid 'addr' parameter") { - // Issue 12617 - return errors.New("tailscaled version is too old (out of sync with derper binary)") - } - return fmt.Errorf("failed to query local tailscaled status for %v: %w", clientKey, err) - } - } - - // admission controller-based verification: - if s.verifyClientsURL != "" { - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - jreq, err := json.Marshal(&tailcfg.DERPAdmitClientRequest{ - NodePublic: clientKey, - Source: clientIP, - }) - if err != nil { - return err - } - req, err := http.NewRequestWithContext(ctx, "POST", s.verifyClientsURL, bytes.NewReader(jreq)) - if err != nil { - return err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - if s.verifyClientsURLFailOpen { - s.logf("admission controller unreachable; allowing client %v", clientKey) - return nil - } - return err - } - defer res.Body.Close() - if res.StatusCode != 200 { - return fmt.Errorf("admission controller: %v", res.Status) - } - var jres tailcfg.DERPAdmitClientResponse - if err := json.NewDecoder(io.LimitReader(res.Body, 4<<10)).Decode(&jres); err != nil { - return err - } - if !jres.Allow { - return fmt.Errorf("admission controller: %v/%v not allowed", clientKey, clientIP) - } - // TODO(bradfitz): add policy for configurable bandwidth rate per client? - } - return nil -} - -func (s *Server) sendServerKey(lw *lazyBufioWriter) error { - buf := make([]byte, 0, len(magic)+key.NodePublicRawLen) - buf = append(buf, magic...) - buf = s.publicKey.AppendTo(buf) - err := writeFrame(lw.bw(), frameServerKey, buf) - lw.Flush() // redundant (no-op) flush to release bufio.Writer - return err -} - -func (s *Server) noteClientActivity(c *sclient) { - if !c.isDup.Load() { - // Fast path for clients that aren't in a dup set. - return - } - if c.isDisabled.Load() { - // If they're already disabled, no point checking more. - return - } - s.mu.Lock() - defer s.mu.Unlock() - - cs, ok := s.clients[c.key] - if !ok { - return - } - dup := cs.dup - if dup == nil { - // It became unduped in between the isDup fast path check above - // and the mutex check. Nothing to do. - return - } - - if s.dupPolicy == lastWriterIsActive { - dup.last = c - cs.activeClient.Store(c) - } else if dup.last == nil { - // If we didn't have a primary, let the current - // speaker be the primary. - dup.last = c - cs.activeClient.Store(c) - } - - if slicesx.LastEqual(dup.sendHistory, c) { - // The client c was the last client to make activity - // in this set and it was already recorded. Nothing to - // do. - return - } - - // If we saw this connection send previously, then consider - // the group fighting and disable them all. - if s.dupPolicy == disableFighters { - for _, prior := range dup.sendHistory { - if prior == c { - cs.ForeachClient(func(c *sclient) { - c.isDisabled.Store(true) - if cs.activeClient.Load() == c { - cs.activeClient.Store(nil) - } - }) - break - } - } - } - - // Append this client to the list of clients who spoke last. - dup.sendHistory = append(dup.sendHistory, c) -} - -type serverInfo struct { - Version int `json:"version,omitempty"` - - TokenBucketBytesPerSecond int `json:",omitempty"` - TokenBucketBytesBurst int `json:",omitempty"` -} - -func (s *Server) sendServerInfo(bw *lazyBufioWriter, clientKey key.NodePublic) error { - msg, err := json.Marshal(serverInfo{Version: ProtocolVersion}) - if err != nil { - return err - } - - msgbox := s.privateKey.SealTo(clientKey, msg) - if err := writeFrameHeader(bw.bw(), frameServerInfo, uint32(len(msgbox))); err != nil { - return err - } - if _, err := bw.Write(msgbox); err != nil { - return err - } - return bw.Flush() -} - -// recvClientKey reads the frameClientInfo frame from the client (its -// proof of identity) upon its initial connection. It should be -// considered especially untrusted at this point. -func (s *Server) recvClientKey(br *bufio.Reader) (clientKey key.NodePublic, info *clientInfo, err error) { - fl, err := readFrameTypeHeader(br, frameClientInfo) - if err != nil { - return zpub, nil, err - } - const minLen = keyLen + nonceLen - if fl < minLen { - return zpub, nil, errors.New("short client info") - } - // We don't trust the client at all yet, so limit its input size to limit - // things like JSON resource exhausting (http://github.com/golang/go/issues/31789). - if fl > 256<<10 { - return zpub, nil, errors.New("long client info") - } - if err := clientKey.ReadRawWithoutAllocating(br); err != nil { - return zpub, nil, err - } - msgLen := int(fl - keyLen) - msgbox := make([]byte, msgLen) - if _, err := io.ReadFull(br, msgbox); err != nil { - return zpub, nil, fmt.Errorf("msgbox: %v", err) - } - msg, ok := s.privateKey.OpenFrom(clientKey, msgbox) - if !ok { - return zpub, nil, fmt.Errorf("msgbox: cannot open len=%d with client key %s", msgLen, clientKey) - } - info = new(clientInfo) - if err := json.Unmarshal(msg, info); err != nil { - return zpub, nil, fmt.Errorf("msg: %v", err) - } - return clientKey, info, nil -} - -func (s *Server) recvPacket(br *bufio.Reader, frameLen uint32) (dstKey key.NodePublic, contents []byte, err error) { - if frameLen < keyLen { - return zpub, nil, errors.New("short send packet frame") - } - if err := dstKey.ReadRawWithoutAllocating(br); err != nil { - return zpub, nil, err - } - packetLen := frameLen - keyLen - if packetLen > MaxPacketSize { - return zpub, nil, fmt.Errorf("data packet longer (%d) than max of %v", packetLen, MaxPacketSize) - } - contents = make([]byte, packetLen) - if _, err := io.ReadFull(br, contents); err != nil { - return zpub, nil, err - } - s.packetsRecv.Add(1) - s.bytesRecv.Add(int64(len(contents))) - if disco.LooksLikeDiscoWrapper(contents) { - s.packetsRecvDisco.Add(1) - } else { - s.packetsRecvOther.Add(1) - } - return dstKey, contents, nil -} - -// zpub is the key.NodePublic zero value. -var zpub key.NodePublic - -func (s *Server) recvForwardPacket(br *bufio.Reader, frameLen uint32) (srcKey, dstKey key.NodePublic, contents []byte, err error) { - if frameLen < keyLen*2 { - return zpub, zpub, nil, errors.New("short send packet frame") - } - if err := srcKey.ReadRawWithoutAllocating(br); err != nil { - return zpub, zpub, nil, err - } - if err := dstKey.ReadRawWithoutAllocating(br); err != nil { - return zpub, zpub, nil, err - } - packetLen := frameLen - keyLen*2 - if packetLen > MaxPacketSize { - return zpub, zpub, nil, fmt.Errorf("data packet longer (%d) than max of %v", packetLen, MaxPacketSize) - } - contents = make([]byte, packetLen) - if _, err := io.ReadFull(br, contents); err != nil { - return zpub, zpub, nil, err - } - // TODO: was s.packetsRecv.Add(1) - // TODO: was s.bytesRecv.Add(int64(len(contents))) - return srcKey, dstKey, contents, nil -} - -// sclient is a client connection to the server. -// -// A node (a wireguard public key) can be connected multiple times to a DERP server -// and thus have multiple sclient instances. An sclient represents -// only one of these possibly multiple connections. See clientSet for the -// type that represents the set of all connections for a given key. -// -// (The "s" prefix is to more explicitly distinguish it from Client in derp_client.go) -type sclient struct { - // Static after construction. - connNum int64 // process-wide unique counter, incremented each Accept - s *Server - nc Conn - key key.NodePublic - info clientInfo - logf logger.Logf - done <-chan struct{} // closed when connection closes - remoteIPPort netip.AddrPort // zero if remoteAddr is not ip:port. - sendQueue chan pkt // packets queued to this client; never closed - discoSendQueue chan pkt // important packets queued to this client; never closed - sendPongCh chan [8]byte // pong replies to send to the client; never closed - peerGone chan peerGoneMsg // write request that a peer is not at this server (not used by mesh peers) - meshUpdate chan struct{} // write request to write peerStateChange - canMesh bool // clientInfo had correct mesh token for inter-region routing - isNotIdealConn bool // client indicated it is not its ideal node in the region - isDup atomic.Bool // whether more than 1 sclient for key is connected - isDisabled atomic.Bool // whether sends to this peer are disabled due to active/active dups - debug bool // turn on for verbose logging - - // Owned by run, not thread-safe. - br *bufio.Reader - connectedAt time.Time - preferred bool - - // Owned by sendLoop, not thread-safe. - sawSrc map[key.NodePublic]set.Handle - bw *lazyBufioWriter - - // Guarded by s.mu - // - // peerStateChange is used by mesh peers (a set of regional - // DERP servers) and contains records that need to be sent to - // the client for them to update their map of who's connected - // to this node. - peerStateChange []peerConnState - - // peerGoneLimiter limits how often the server will inform a - // client that it's trying to establish a direct connection - // through us with a peer we have no record of. - peerGoneLim *rate.Limiter -} - -func (c *sclient) presentFlags() PeerPresentFlags { - var f PeerPresentFlags - if c.info.IsProber { - f |= PeerPresentIsProber - } - if c.canMesh { - f |= PeerPresentIsMeshPeer - } - if c.isNotIdealConn { - f |= PeerPresentNotIdeal - } - if f == 0 { - return PeerPresentIsRegular - } - return f -} - -// peerConnState represents whether a peer is connected to the server -// or not. -type peerConnState struct { - ipPort netip.AddrPort // if present, the peer's IP:port - peer key.NodePublic - flags PeerPresentFlags - present bool -} - -// pkt is a request to write a data frame to an sclient. -type pkt struct { - // enqueuedAt is when a packet was put onto a queue before it was sent, - // and is used for reporting metrics on the duration of packets in the queue. - enqueuedAt time.Time - - // bs is the data packet bytes. - // The memory is owned by pkt. - bs []byte - - // src is the who's the sender of the packet. - src key.NodePublic -} - -// peerGoneMsg is a request to write a peerGone frame to an sclient -type peerGoneMsg struct { - peer key.NodePublic - reason PeerGoneReasonType -} - -func (c *sclient) setPreferred(v bool) { - if c.preferred == v { - return - } - c.preferred = v - var homeMove *expvar.Int - if v { - c.s.curHomeClients.Add(1) - homeMove = &c.s.homeMovesIn - } else { - c.s.curHomeClients.Add(-1) - homeMove = &c.s.homeMovesOut - } - - // Keep track of varz for home serve moves in/out. But ignore - // the initial packet set when a client connects, which we - // assume happens within 5 seconds. In any case, just for - // graphs, so not important to miss a move. But it shouldn't: - // the netcheck/re-STUNs in magicsock only happen about every - // 30 seconds. - if c.s.clock.Since(c.connectedAt) > 5*time.Second { - homeMove.Add(1) - } -} - -// expMovingAverage returns the new moving average given the previous average, -// a new value, and an alpha decay factor. -// https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average -func expMovingAverage(prev, newValue, alpha float64) float64 { - return alpha*newValue + (1-alpha)*prev -} - -// recordQueueTime updates the average queue duration metric after a packet has been sent. -func (c *sclient) recordQueueTime(enqueuedAt time.Time) { - elapsed := float64(c.s.clock.Since(enqueuedAt).Milliseconds()) - for { - old := atomic.LoadUint64(c.s.avgQueueDuration) - newAvg := expMovingAverage(math.Float64frombits(old), elapsed, 0.1) - if atomic.CompareAndSwapUint64(c.s.avgQueueDuration, old, math.Float64bits(newAvg)) { - break - } - } -} - -// onSendLoopDone is called when the send loop is done -// to clean up. -// -// It must only be called from the sendLoop goroutine. -func (c *sclient) onSendLoopDone() { - // If the sender shuts down unilaterally due to an error, close so - // that the receive loop unblocks and cleans up the rest. - c.nc.Close() - - // Clean up watches. - for peer, h := range c.sawSrc { - c.s.removePeerGoneFromRegionWatcher(peer, h) - } - - // Drain the send queue to count dropped packets - for { - select { - case pkt := <-c.sendQueue: - c.s.recordDrop(pkt.bs, pkt.src, c.key, dropReasonGoneDisconnected) - case pkt := <-c.discoSendQueue: - c.s.recordDrop(pkt.bs, pkt.src, c.key, dropReasonGoneDisconnected) - default: - return - } - } - -} - -func (c *sclient) sendLoop(ctx context.Context) error { - defer c.onSendLoopDone() - - jitter := rand.N(5 * time.Second) - keepAliveTick, keepAliveTickChannel := c.s.clock.NewTicker(keepAlive + jitter) - defer keepAliveTick.Stop() - - var werr error // last write error - inBatch := -1 // for bufferedWriteFrames - for { - if werr != nil { - return werr - } - inBatch++ - // First, a non-blocking select (with a default) that - // does as many non-flushing writes as possible. - select { - case <-ctx.Done(): - return nil - case msg := <-c.peerGone: - werr = c.sendPeerGone(msg.peer, msg.reason) - continue - case <-c.meshUpdate: - werr = c.sendMeshUpdates() - continue - case msg := <-c.sendQueue: - werr = c.sendPacket(msg.src, msg.bs) - c.recordQueueTime(msg.enqueuedAt) - continue - case msg := <-c.discoSendQueue: - werr = c.sendPacket(msg.src, msg.bs) - c.recordQueueTime(msg.enqueuedAt) - continue - case msg := <-c.sendPongCh: - werr = c.sendPong(msg) - continue - case <-keepAliveTickChannel: - werr = c.sendKeepAlive() - continue - default: - // Flush any writes from the 3 sends above, or from - // the blocking loop below. - if werr = c.bw.Flush(); werr != nil { - return werr - } - if inBatch != 0 { // the first loop will almost always hit default & be size zero - c.s.bufferedWriteFrames.Observe(float64(inBatch)) - inBatch = 0 - } - } - - // Then a blocking select with same: - select { - case <-ctx.Done(): - return nil - case msg := <-c.peerGone: - werr = c.sendPeerGone(msg.peer, msg.reason) - case <-c.meshUpdate: - werr = c.sendMeshUpdates() - case msg := <-c.sendQueue: - werr = c.sendPacket(msg.src, msg.bs) - c.recordQueueTime(msg.enqueuedAt) - case msg := <-c.discoSendQueue: - werr = c.sendPacket(msg.src, msg.bs) - c.recordQueueTime(msg.enqueuedAt) - case msg := <-c.sendPongCh: - werr = c.sendPong(msg) - case <-keepAliveTickChannel: - werr = c.sendKeepAlive() - } - } -} - -func (c *sclient) setWriteDeadline() { - d := c.s.tcpWriteTimeout - if c.canMesh { - // Trusted peers get more tolerance. - // - // The "canMesh" is a bit of a misnomer; mesh peers typically run over a - // different interface for a per-region private VPC and are not - // throttled. But monitoring software elsewhere over the internet also - // use the private mesh key to subscribe to connect/disconnect events - // and might hit throttling and need more time to get the initial dump - // of connected peers. - d = privilegedWriteTimeout - } - if d == 0 { - // A zero value should disable the write deadline per - // --tcp-write-timeout docs. The flag should only be applicable for - // non-mesh connections, again per its docs. If mesh happened to use a - // zero value constant above it would be a bug, so we don't bother - // with a condition on c.canMesh. - return - } - // Ignore the error from setting the write deadline. In practice, - // setting the deadline will only fail if the connection is closed - // or closing, so the subsequent Write() will fail anyway. - _ = c.nc.SetWriteDeadline(time.Now().Add(d)) -} - -// sendKeepAlive sends a keep-alive frame, without flushing. -func (c *sclient) sendKeepAlive() error { - c.setWriteDeadline() - return writeFrameHeader(c.bw.bw(), frameKeepAlive, 0) -} - -// sendPong sends a pong reply, without flushing. -func (c *sclient) sendPong(data [8]byte) error { - c.s.sentPong.Add(1) - c.setWriteDeadline() - if err := writeFrameHeader(c.bw.bw(), framePong, uint32(len(data))); err != nil { - return err - } - _, err := c.bw.Write(data[:]) - return err -} - -const ( - peerGoneFrameLen = keyLen + 1 - peerPresentFrameLen = keyLen + 16 + 2 + 1 // 16 byte IP + 2 byte port + 1 byte flags -) - -// sendPeerGone sends a peerGone frame, without flushing. -func (c *sclient) sendPeerGone(peer key.NodePublic, reason PeerGoneReasonType) error { - switch reason { - case PeerGoneReasonDisconnected: - c.s.peerGoneDisconnectedFrames.Add(1) - case PeerGoneReasonNotHere: - c.s.peerGoneNotHereFrames.Add(1) - } - c.setWriteDeadline() - data := make([]byte, 0, peerGoneFrameLen) - data = peer.AppendTo(data) - data = append(data, byte(reason)) - if err := writeFrameHeader(c.bw.bw(), framePeerGone, uint32(len(data))); err != nil { - return err - } - - _, err := c.bw.Write(data) - return err -} - -// sendPeerPresent sends a peerPresent frame, without flushing. -func (c *sclient) sendPeerPresent(peer key.NodePublic, ipPort netip.AddrPort, flags PeerPresentFlags) error { - c.setWriteDeadline() - if err := writeFrameHeader(c.bw.bw(), framePeerPresent, peerPresentFrameLen); err != nil { - return err - } - payload := make([]byte, peerPresentFrameLen) - _ = peer.AppendTo(payload[:0]) - a16 := ipPort.Addr().As16() - copy(payload[keyLen:], a16[:]) - binary.BigEndian.PutUint16(payload[keyLen+16:], ipPort.Port()) - payload[keyLen+18] = byte(flags) - _, err := c.bw.Write(payload) - return err -} - -// sendMeshUpdates drains all mesh peerStateChange entries into the write buffer -// without flushing. -func (c *sclient) sendMeshUpdates() error { - var lastBatch []peerConnState // memory to best effort reuse - - // takeAll returns c.peerStateChange and empties it. - takeAll := func() []peerConnState { - c.s.mu.Lock() - defer c.s.mu.Unlock() - if len(c.peerStateChange) == 0 { - return nil - } - batch := c.peerStateChange - if cap(lastBatch) > 16 { - lastBatch = nil - } - c.peerStateChange = lastBatch[:0] - return batch - } - - for loops := 0; ; loops++ { - batch := takeAll() - if len(batch) == 0 { - c.s.meshUpdateLoopCount.Observe(float64(loops)) - return nil - } - c.s.meshUpdateBatchSize.Observe(float64(len(batch))) - - for _, pcs := range batch { - var err error - if pcs.present { - err = c.sendPeerPresent(pcs.peer, pcs.ipPort, pcs.flags) - } else { - err = c.sendPeerGone(pcs.peer, PeerGoneReasonDisconnected) - } - if err != nil { - return err - } - } - lastBatch = batch - } -} - -// sendPacket writes contents to the client in a RecvPacket frame. If -// srcKey.IsZero, uses the old DERPv1 framing format, otherwise uses -// DERPv2. The bytes of contents are only valid until this function -// returns, do not retain slices. -// It does not flush its bufio.Writer. -func (c *sclient) sendPacket(srcKey key.NodePublic, contents []byte) (err error) { - defer func() { - // Stats update. - if err != nil { - c.s.recordDrop(contents, srcKey, c.key, dropReasonWriteError) - } else { - c.s.packetsSent.Add(1) - c.s.bytesSent.Add(int64(len(contents))) - } - c.debugLogf("sendPacket from %s: %v", srcKey.ShortString(), err) - }() - - c.setWriteDeadline() - - withKey := !srcKey.IsZero() - pktLen := len(contents) - if withKey { - pktLen += key.NodePublicRawLen - c.noteSendFromSrc(srcKey) - } - if err = writeFrameHeader(c.bw.bw(), frameRecvPacket, uint32(pktLen)); err != nil { - return err - } - if withKey { - if err := srcKey.WriteRawWithoutAllocating(c.bw.bw()); err != nil { - return err - } - } - _, err = c.bw.Write(contents) - return err -} - -// noteSendFromSrc notes that we are about to write a packet -// from src to sclient. -// -// It must only be called from the sendLoop goroutine. -func (c *sclient) noteSendFromSrc(src key.NodePublic) { - if _, ok := c.sawSrc[src]; ok { - return - } - h := c.s.addPeerGoneFromRegionWatcher(src, c.onPeerGoneFromRegion) - mak.Set(&c.sawSrc, src, h) -} - -// AddPacketForwarder registers fwd as a packet forwarder for dst. -// fwd must be comparable. -func (s *Server) AddPacketForwarder(dst key.NodePublic, fwd PacketForwarder) { - s.mu.Lock() - defer s.mu.Unlock() - if prev, ok := s.clientsMesh[dst]; ok { - if prev == fwd { - // Duplicate registration of same forwarder. Ignore. - return - } - if m, ok := prev.(*multiForwarder); ok { - if _, ok := m.all[fwd]; ok { - // Duplicate registration of same forwarder in set; ignore. - return - } - m.add(fwd) - return - } - if prev != nil { - // Otherwise, the existing value is not a set, - // not a dup, and not local-only (nil) so make - // it a set. `prev` existed first, so will have higher - // priority. - fwd = newMultiForwarder(prev, fwd) - s.multiForwarderCreated.Add(1) - } - } - s.clientsMesh[dst] = fwd -} - -// RemovePacketForwarder removes fwd as a packet forwarder for dst. -// fwd must be comparable. -func (s *Server) RemovePacketForwarder(dst key.NodePublic, fwd PacketForwarder) { - s.mu.Lock() - defer s.mu.Unlock() - v, ok := s.clientsMesh[dst] - if !ok { - return - } - if m, ok := v.(*multiForwarder); ok { - if len(m.all) < 2 { - panic("unexpected") - } - if remain, isLast := m.deleteLocked(fwd); isLast { - // If fwd was in m and we no longer need to be a - // multiForwarder, replace the entry with the - // remaining PacketForwarder. - s.clientsMesh[dst] = remain - s.multiForwarderDeleted.Add(1) - } - return - } - if v != fwd { - s.removePktForwardOther.Add(1) - // Delete of an entry that wasn't in the - // map. Harmless, so ignore. - // (This might happen if a user is moving around - // between nodes and/or the server sent duplicate - // connection change broadcasts.) - return - } - - if _, isLocal := s.clients[dst]; isLocal { - s.clientsMesh[dst] = nil - } else { - delete(s.clientsMesh, dst) - s.notePeerGoneFromRegionLocked(dst) - } -} - -// multiForwarder is a PacketForwarder that represents a set of -// forwarding options. It's used in the rare cases that a client is -// connected to multiple DERP nodes in a region. That shouldn't really -// happen except for perhaps during brief moments while the client is -// reconfiguring, in which case we don't want to forget where the -// client is. The map value is unique connection number; the lowest -// one has been seen the longest. It's used to make sure we forward -// packets consistently to the same node and don't pick randomly. -type multiForwarder struct { - fwd syncs.AtomicValue[PacketForwarder] // preferred forwarder. - all map[PacketForwarder]uint8 // all forwarders, protected by s.mu. -} - -// newMultiForwarder creates a new multiForwarder. -// The first PacketForwarder passed to this function will be the preferred one. -func newMultiForwarder(fwds ...PacketForwarder) *multiForwarder { - f := &multiForwarder{all: make(map[PacketForwarder]uint8)} - f.fwd.Store(fwds[0]) - for idx, fwd := range fwds { - f.all[fwd] = uint8(idx) - } - return f -} - -// add adds a new forwarder to the map with a connection number that -// is higher than the existing ones. -func (f *multiForwarder) add(fwd PacketForwarder) { - var max uint8 - for _, v := range f.all { - if v > max { - max = v - } - } - f.all[fwd] = max + 1 -} - -// deleteLocked removes a packet forwarder from the map. It expects Server.mu to be held. -// If only one forwarder remains after the removal, it will be returned alongside a `true` boolean value. -func (f *multiForwarder) deleteLocked(fwd PacketForwarder) (_ PacketForwarder, isLast bool) { - delete(f.all, fwd) - - if fwd == f.fwd.Load() { - // The preferred forwarder has been removed, choose a new one - // based on the lowest index. - var lowestfwd PacketForwarder - var lowest uint8 - for k, v := range f.all { - if lowestfwd == nil || v < lowest { - lowestfwd = k - lowest = v - } - } - if lowestfwd != nil { - f.fwd.Store(lowestfwd) - } - } - - if len(f.all) == 1 { - for k := range f.all { - return k, true - } - } - return nil, false -} - -func (f *multiForwarder) ForwardPacket(src, dst key.NodePublic, payload []byte) error { - return f.fwd.Load().ForwardPacket(src, dst, payload) -} - -func (f *multiForwarder) String() string { - return fmt.Sprintf("", f.fwd.Load(), len(f.all)) -} - -func (s *Server) expVarFunc(f func() any) expvar.Func { - return expvar.Func(func() any { - s.mu.Lock() - defer s.mu.Unlock() - return f() - }) -} - -// ExpVar returns an expvar variable suitable for registering with expvar.Publish. -func (s *Server) ExpVar() expvar.Var { - m := new(metrics.Set) - m.Set("gauge_memstats_sys0", expvar.Func(func() any { return int64(s.memSys0) })) - m.Set("gauge_watchers", s.expVarFunc(func() any { return len(s.watchers) })) - m.Set("gauge_current_file_descriptors", expvar.Func(func() any { return metrics.CurrentFDs() })) - m.Set("gauge_current_connections", &s.curClients) - m.Set("gauge_current_home_connections", &s.curHomeClients) - m.Set("gauge_current_notideal_connections", &s.curClientsNotIdeal) - m.Set("gauge_clients_total", expvar.Func(func() any { return len(s.clientsMesh) })) - m.Set("gauge_clients_local", expvar.Func(func() any { return len(s.clients) })) - m.Set("gauge_clients_remote", expvar.Func(func() any { return len(s.clientsMesh) - len(s.clients) })) - m.Set("gauge_current_dup_client_keys", &s.dupClientKeys) - m.Set("gauge_current_dup_client_conns", &s.dupClientConns) - m.Set("counter_total_dup_client_conns", &s.dupClientConnTotal) - m.Set("accepts", &s.accepts) - m.Set("bytes_received", &s.bytesRecv) - m.Set("bytes_sent", &s.bytesSent) - m.Set("counter_packets_received_kind", &s.packetsRecvByKind) - m.Set("packets_sent", &s.packetsSent) - m.Set("packets_received", &s.packetsRecv) - m.Set("unknown_frames", &s.unknownFrames) - m.Set("home_moves_in", &s.homeMovesIn) - m.Set("home_moves_out", &s.homeMovesOut) - m.Set("got_ping", &s.gotPing) - m.Set("sent_pong", &s.sentPong) - m.Set("peer_gone_disconnected_frames", &s.peerGoneDisconnectedFrames) - m.Set("peer_gone_not_here_frames", &s.peerGoneNotHereFrames) - m.Set("packets_forwarded_out", &s.packetsForwardedOut) - m.Set("packets_forwarded_in", &s.packetsForwardedIn) - m.Set("multiforwarder_created", &s.multiForwarderCreated) - m.Set("multiforwarder_deleted", &s.multiForwarderDeleted) - m.Set("packet_forwarder_delete_other_value", &s.removePktForwardOther) - m.Set("sclient_write_timeouts", &s.sclientWriteTimeouts) - m.Set("average_queue_duration_ms", expvar.Func(func() any { - return math.Float64frombits(atomic.LoadUint64(s.avgQueueDuration)) - })) - m.Set("counter_tcp_rtt", &s.tcpRtt) - m.Set("counter_mesh_update_batch_size", s.meshUpdateBatchSize) - m.Set("counter_mesh_update_loop_count", s.meshUpdateLoopCount) - m.Set("counter_buffered_write_frames", s.bufferedWriteFrames) - var expvarVersion expvar.String - expvarVersion.Set(version.Long()) - m.Set("version", &expvarVersion) - return m -} - -func (s *Server) ConsistencyCheck() error { - s.mu.Lock() - defer s.mu.Unlock() - - var errs []string - - var nilMeshNotInClient int - for k, f := range s.clientsMesh { - if f == nil { - if _, ok := s.clients[k]; !ok { - nilMeshNotInClient++ - } - } - } - if nilMeshNotInClient != 0 { - errs = append(errs, fmt.Sprintf("%d s.clientsMesh keys not in s.clients", nilMeshNotInClient)) - } - - var clientNotInMesh int - for k := range s.clients { - if _, ok := s.clientsMesh[k]; !ok { - clientNotInMesh++ - } - } - if clientNotInMesh != 0 { - errs = append(errs, fmt.Sprintf("%d s.clients keys not in s.clientsMesh", clientNotInMesh)) - } - - if s.curClients.Value() != int64(len(s.clients)) { - errs = append(errs, fmt.Sprintf("expvar connections = %d != clients map says of %d", - s.curClients.Value(), - len(s.clients))) - } - - if s.verifyClientsLocalTailscaled { - if err := s.checkVerifyClientsLocalTailscaled(); err != nil { - errs = append(errs, err.Error()) - } - } - - if len(errs) == 0 { - return nil - } - return errors.New(strings.Join(errs, ", ")) -} - -// checkVerifyClientsLocalTailscaled checks that a verifyClients call can be made successfully for the derper hosts own node key. -func (s *Server) checkVerifyClientsLocalTailscaled() error { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - status, err := s.localClient.StatusWithoutPeers(ctx) - if err != nil { - return fmt.Errorf("localClient.Status: %w", err) - } - info := &clientInfo{ - IsProber: true, - } - clientIP := netip.IPv6Loopback() - if err := s.verifyClient(ctx, status.Self.PublicKey, info, clientIP); err != nil { - return fmt.Errorf("verifyClient for self nodekey: %w", err) - } - return nil -} - -const minTimeBetweenLogs = 2 * time.Second - -// BytesSentRecv records the number of bytes that have been sent since the last traffic check -// for a given process, as well as the public key of the process sending those bytes. -type BytesSentRecv struct { - Sent uint64 - Recv uint64 - // Key is the public key of the client which sent/received these bytes. - Key key.NodePublic -} - -// parseSSOutput parses the output from the specific call to ss in ServeDebugTraffic. -// Separated out for ease of testing. -func parseSSOutput(raw string) map[netip.AddrPort]BytesSentRecv { - newState := map[netip.AddrPort]BytesSentRecv{} - // parse every 2 lines and get src and dst ips, and kv pairs - lines := strings.Split(raw, "\n") - for i := 0; i < len(lines); i += 2 { - ipInfo := strings.Fields(strings.TrimSpace(lines[i])) - if len(ipInfo) < 5 { - continue - } - src, err := netip.ParseAddrPort(ipInfo[4]) - if err != nil { - continue - } - stats := strings.Fields(strings.TrimSpace(lines[i+1])) - stat := BytesSentRecv{} - for _, s := range stats { - if strings.Contains(s, "bytes_sent") { - sent, err := strconv.Atoi(s[strings.Index(s, ":")+1:]) - if err == nil { - stat.Sent = uint64(sent) - } - } else if strings.Contains(s, "bytes_received") { - recv, err := strconv.Atoi(s[strings.Index(s, ":")+1:]) - if err == nil { - stat.Recv = uint64(recv) - } - } - } - newState[src] = stat - } - return newState -} - -func (s *Server) ServeDebugTraffic(w http.ResponseWriter, r *http.Request) { - prevState := map[netip.AddrPort]BytesSentRecv{} - enc := json.NewEncoder(w) - for r.Context().Err() == nil { - output, err := exec.Command("ss", "-i", "-H", "-t").Output() - if err != nil { - fmt.Fprintf(w, "ss failed: %v", err) - return - } - newState := parseSSOutput(string(output)) - s.mu.Lock() - for k, next := range newState { - prev := prevState[k] - if prev.Sent < next.Sent || prev.Recv < next.Recv { - if pkey, ok := s.keyOfAddr[k]; ok { - next.Key = pkey - if err := enc.Encode(next); err != nil { - s.mu.Unlock() - return - } - } - } - } - s.mu.Unlock() - prevState = newState - if _, err := fmt.Fprintln(w); err != nil { - return - } - if f, ok := w.(http.Flusher); ok { - f.Flush() - } - time.Sleep(minTimeBetweenLogs) - } -} - -var bufioWriterPool = &sync.Pool{ - New: func() any { - return bufio.NewWriterSize(io.Discard, 2<<10) - }, -} - -// lazyBufioWriter is a bufio.Writer-like wrapping writer that lazily -// allocates its actual bufio.Writer from a sync.Pool, releasing it to -// the pool upon flush. -// -// We do this to reduce memory overhead; most DERP connections are -// idle and the idle bufio.Writers were 30% of overall memory usage. -type lazyBufioWriter struct { - w io.Writer // underlying - lbw *bufio.Writer // lazy; nil means it needs an associated buffer -} - -func (w *lazyBufioWriter) bw() *bufio.Writer { - if w.lbw == nil { - w.lbw = bufioWriterPool.Get().(*bufio.Writer) - w.lbw.Reset(w.w) - } - return w.lbw -} - -func (w *lazyBufioWriter) Available() int { return w.bw().Available() } - -func (w *lazyBufioWriter) Write(p []byte) (int, error) { return w.bw().Write(p) } - -func (w *lazyBufioWriter) Flush() error { - if w.lbw == nil { - return nil - } - err := w.lbw.Flush() - - w.lbw.Reset(io.Discard) - bufioWriterPool.Put(w.lbw) - w.lbw = nil - - return err -} diff --git a/vendor/tailscale.com/derp/derp_server_default.go b/vendor/tailscale.com/derp/derp_server_default.go deleted file mode 100644 index 3e0b5b5..0000000 --- a/vendor/tailscale.com/derp/derp_server_default.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package derp - -import "context" - -func (c *sclient) startStatsLoop(ctx context.Context) { - // Nothing to do - return -} diff --git a/vendor/tailscale.com/derp/derp_server_linux.go b/vendor/tailscale.com/derp/derp_server_linux.go deleted file mode 100644 index bfc2aad..0000000 --- a/vendor/tailscale.com/derp/derp_server_linux.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package derp - -import ( - "context" - "crypto/tls" - "net" - "time" - - "tailscale.com/net/tcpinfo" -) - -func (c *sclient) startStatsLoop(ctx context.Context) { - // Get the RTT initially to verify it's supported. - conn := c.tcpConn() - if conn == nil { - c.s.tcpRtt.Add("non-tcp", 1) - return - } - if _, err := tcpinfo.RTT(conn); err != nil { - c.logf("error fetching initial RTT: %v", err) - c.s.tcpRtt.Add("error", 1) - return - } - - const statsInterval = 10 * time.Second - - // Don't launch a goroutine; use a timer instead. - var gatherStats func() - gatherStats = func() { - // Do nothing if the context is finished. - if ctx.Err() != nil { - return - } - - // Reschedule ourselves when this stats gathering is finished. - defer c.s.clock.AfterFunc(statsInterval, gatherStats) - - // Gather TCP RTT information. - rtt, err := tcpinfo.RTT(conn) - if err == nil { - c.s.tcpRtt.Add(durationToLabel(rtt), 1) - } - - // TODO(andrew): more metrics? - } - - // Kick off the initial timer. - c.s.clock.AfterFunc(statsInterval, gatherStats) -} - -// tcpConn attempts to get the underlying *net.TCPConn from this client's -// Conn; if it cannot, then it will return nil. -func (c *sclient) tcpConn() *net.TCPConn { - nc := c.nc - for { - switch v := nc.(type) { - case *net.TCPConn: - return v - case *tls.Conn: - nc = v.NetConn() - default: - return nil - } - } -} - -func durationToLabel(dur time.Duration) string { - switch { - case dur <= 10*time.Millisecond: - return "10ms" - case dur <= 20*time.Millisecond: - return "20ms" - case dur <= 50*time.Millisecond: - return "50ms" - case dur <= 100*time.Millisecond: - return "100ms" - case dur <= 150*time.Millisecond: - return "150ms" - case dur <= 250*time.Millisecond: - return "250ms" - case dur <= 500*time.Millisecond: - return "500ms" - default: - return "inf" - } -} diff --git a/vendor/tailscale.com/derp/derpconst/derpconst.go b/vendor/tailscale.com/derp/derpconst/derpconst.go new file mode 100644 index 0000000..74ca09c --- /dev/null +++ b/vendor/tailscale.com/derp/derpconst/derpconst.go @@ -0,0 +1,11 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package derpconst contains constants used by the DERP client and server. +package derpconst + +// MetaCertCommonNamePrefix is the prefix that the DERP server +// puts on for the common name of its "metacert". The suffix of +// the common name after "derpkey" is the hex key.NodePublic +// of the DERP server. +const MetaCertCommonNamePrefix = "derpkey" diff --git a/vendor/tailscale.com/derp/derphttp/derphttp_client.go b/vendor/tailscale.com/derp/derphttp/derphttp_client.go index 319c024..db56c4a 100644 --- a/vendor/tailscale.com/derp/derphttp/derphttp_client.go +++ b/vendor/tailscale.com/derp/derphttp/derphttp_client.go @@ -30,14 +30,17 @@ import ( "go4.org/mem" "tailscale.com/derp" + "tailscale.com/derp/derpconst" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/dnscache" "tailscale.com/net/netmon" "tailscale.com/net/netns" + "tailscale.com/net/netx" "tailscale.com/net/sockstats" "tailscale.com/net/tlsdial" - "tailscale.com/net/tshttpproxy" "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tstime" @@ -55,7 +58,7 @@ type Client struct { TLSConfig *tls.Config // optional; nil means default HealthTracker *health.Tracker // optional; used if non-nil only DNSCache *dnscache.Resolver // optional; nil means no caching - MeshKey string // optional; for trusted clients + MeshKey key.DERPMesh // optional; for trusted clients IsProber bool // optional; for probers to optional declare themselves as such // WatchConnectionChanges is whether the client wishes to subscribe to @@ -520,7 +523,7 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien // just to get routed into the server's HTTP Handler so it // can Hijack the request, but we signal with a special header // that we don't want to deal with its HTTP response. - req.Header.Set(fastStartHeader, "1") // suppresses the server's HTTP response + req.Header.Set(derp.FastStartHeader, "1") // suppresses the server's HTTP response if err := req.Write(brw); err != nil { return nil, 0, err } @@ -587,7 +590,7 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien // // The primary use for this is the derper mesh mode to connect to each // other over a VPC network. -func (c *Client) SetURLDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) { +func (c *Client) SetURLDialer(dialer netx.DialFunc) { c.dialer = dialer } @@ -645,7 +648,10 @@ func (c *Client) dialRegion(ctx context.Context, reg *tailcfg.DERPRegion) (net.C } func (c *Client) tlsClient(nc net.Conn, node *tailcfg.DERPNode) *tls.Conn { - tlsConf := tlsdial.Config(c.tlsServerName(node), c.HealthTracker, c.TLSConfig) + tlsConf := tlsdial.Config(c.HealthTracker, c.TLSConfig) + // node is allowed to be nil here, tlsServerName falls back to using the URL + // if node is nil. + tlsConf.ServerName = c.tlsServerName(node) if node != nil { if node.InsecureForTests { tlsConf.InsecureSkipVerify = true @@ -729,8 +735,12 @@ func (c *Client) dialNode(ctx context.Context, n *tailcfg.DERPNode) (net.Conn, e Path: "/", // unused }, } - if proxyURL, err := tshttpproxy.ProxyFromEnvironment(proxyReq); err == nil && proxyURL != nil { - return c.dialNodeUsingProxy(ctx, n, proxyURL) + if buildfeatures.HasUseProxy { + if proxyFromEnv, ok := feature.HookProxyFromEnvironment.GetOk(); ok { + if proxyURL, err := proxyFromEnv(proxyReq); err == nil && proxyURL != nil { + return c.dialNodeUsingProxy(ctx, n, proxyURL) + } + } } type res struct { @@ -860,10 +870,14 @@ func (c *Client) dialNodeUsingProxy(ctx context.Context, n *tailcfg.DERPNode, pr target := net.JoinHostPort(n.HostName, "443") var authHeader string - if v, err := tshttpproxy.GetAuthHeader(pu); err != nil { - c.logf("derphttp: error getting proxy auth header for %v: %v", proxyURL, err) - } else if v != "" { - authHeader = fmt.Sprintf("Proxy-Authorization: %s\r\n", v) + if buildfeatures.HasUseProxy { + if getAuthHeader, ok := feature.HookProxyGetAuthHeader.GetOk(); ok { + if v, err := getAuthHeader(pu); err != nil { + c.logf("derphttp: error getting proxy auth header for %v: %v", proxyURL, err) + } else if v != "" { + authHeader = fmt.Sprintf("Proxy-Authorization: %s\r\n", v) + } + } } if _, err := fmt.Fprintf(proxyConn, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n%s\r\n", target, target, authHeader); err != nil { @@ -1151,7 +1165,7 @@ var ErrClientClosed = errors.New("derphttp.Client closed") func parseMetaCert(certs []*x509.Certificate) (serverPub key.NodePublic, serverProtoVersion int) { for _, cert := range certs { // Look for derpkey prefix added by initMetacert() on the server side. - if pubHex, ok := strings.CutPrefix(cert.Subject.CommonName, "derpkey"); ok { + if pubHex, ok := strings.CutPrefix(cert.Subject.CommonName, derpconst.MetaCertCommonNamePrefix); ok { var err error serverPub, err = key.ParseNodePublicUntyped(mem.S(pubHex)) if err == nil && cert.SerialNumber.BitLen() <= 8 { // supports up to version 255 diff --git a/vendor/tailscale.com/derp/derphttp/derphttp_server.go b/vendor/tailscale.com/derp/derphttp/derphttp_server.go deleted file mode 100644 index 50aba77..0000000 --- a/vendor/tailscale.com/derp/derphttp/derphttp_server.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package derphttp - -import ( - "fmt" - "log" - "net/http" - "strings" - - "tailscale.com/derp" -) - -// fastStartHeader is the header (with value "1") that signals to the HTTP -// server that the DERP HTTP client does not want the HTTP 101 response -// headers and it will begin writing & reading the DERP protocol immediately -// following its HTTP request. -const fastStartHeader = "Derp-Fast-Start" - -// Handler returns an http.Handler to be mounted at /derp, serving s. -func Handler(s *derp.Server) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - // These are installed both here and in cmd/derper. The check here - // catches both cmd/derper run with DERP disabled (STUN only mode) as - // well as DERP being run in tests with derphttp.Handler directly, - // as netcheck still assumes this replies. - switch r.URL.Path { - case "/derp/probe", "/derp/latency-check": - ProbeHandler(w, r) - return - } - - up := strings.ToLower(r.Header.Get("Upgrade")) - if up != "websocket" && up != "derp" { - if up != "" { - log.Printf("Weird upgrade: %q", up) - } - http.Error(w, "DERP requires connection upgrade", http.StatusUpgradeRequired) - return - } - - fastStart := r.Header.Get(fastStartHeader) == "1" - - h, ok := w.(http.Hijacker) - if !ok { - http.Error(w, "HTTP does not support general TCP support", 500) - return - } - - netConn, conn, err := h.Hijack() - if err != nil { - log.Printf("Hijack failed: %v", err) - http.Error(w, "HTTP does not support general TCP support", 500) - return - } - - if !fastStart { - pubKey := s.PublicKey() - fmt.Fprintf(conn, "HTTP/1.1 101 Switching Protocols\r\n"+ - "Upgrade: DERP\r\n"+ - "Connection: Upgrade\r\n"+ - "Derp-Version: %v\r\n"+ - "Derp-Public-Key: %s\r\n\r\n", - derp.ProtocolVersion, - pubKey.UntypedHexString()) - } - - if v := r.Header.Get(derp.IdealNodeHeader); v != "" { - ctx = derp.IdealNodeContextKey.WithValue(ctx, v) - } - - s.Accept(ctx, netConn, conn, netConn.RemoteAddr().String()) - }) -} - -// ProbeHandler is the endpoint that clients without UDP access (including js/wasm) hit to measure -// DERP latency, as a replacement for UDP STUN queries. -func ProbeHandler(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case "HEAD", "GET": - w.Header().Set("Access-Control-Allow-Origin", "*") - default: - http.Error(w, "bogus probe method", http.StatusMethodNotAllowed) - } -} - -// ServeNoContent generates the /generate_204 response used by Tailscale's -// captive portal detection. -func ServeNoContent(w http.ResponseWriter, r *http.Request) { - if challenge := r.Header.Get(NoContentChallengeHeader); challenge != "" { - badChar := strings.IndexFunc(challenge, func(r rune) bool { - return !isChallengeChar(r) - }) != -1 - if len(challenge) <= 64 && !badChar { - w.Header().Set(NoContentResponseHeader, "response "+challenge) - } - } - w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate, no-transform, max-age=0") - w.WriteHeader(http.StatusNoContent) -} - -func isChallengeChar(c rune) bool { - // Semi-randomly chosen as a limited set of valid characters - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || - c == '.' || c == '-' || c == '_' || c == ':' -} - -const ( - NoContentChallengeHeader = "X-Tailscale-Challenge" - NoContentResponseHeader = "X-Tailscale-Response" -) diff --git a/vendor/tailscale.com/derp/derphttp/mesh_client.go b/vendor/tailscale.com/derp/derphttp/mesh_client.go index 66b8c16..c14a9a7 100644 --- a/vendor/tailscale.com/derp/derphttp/mesh_client.go +++ b/vendor/tailscale.com/derp/derphttp/mesh_client.go @@ -31,6 +31,9 @@ var testHookWatchLookConnectResult func(connectError error, wasSelfConnect bool) // This behavior will likely change. Callers should do their own accounting // and dup suppression as needed. // +// If set the notifyError func is called with any error that occurs within the ctx +// main loop connection setup, or the inner loop receiving messages via RecvDetail. +// // infoLogf, if non-nil, is the logger to write periodic status updates about // how many peers are on the server. Error log output is set to the c's logger, // regardless of infoLogf's value. @@ -42,10 +45,11 @@ var testHookWatchLookConnectResult func(connectError error, wasSelfConnect bool) // initialized Client.WatchConnectionChanges to true. // // If the DERP connection breaks and reconnects, remove will be called for all -// previously seen peers, with Reason type PeerGoneReasonSynthetic. Those +// previously seen peers, with Reason type PeerGoneReasonMeshConnBroke. Those // clients are likely still connected and their add message will appear after // reconnect. -func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key.NodePublic, infoLogf logger.Logf, add func(derp.PeerPresentMessage), remove func(derp.PeerGoneMessage)) { +func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key.NodePublic, infoLogf logger.Logf, + add func(derp.PeerPresentMessage), remove func(derp.PeerGoneMessage), notifyError func(error)) { if !c.WatchConnectionChanges { if c.isStarted() { panic("invalid use of RunWatchConnectionLoop on already-started Client without setting Client.RunWatchConnectionLoop") @@ -121,6 +125,10 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key // Make sure we're connected before calling s.ServerPublicKey. _, _, err := c.connect(ctx, "RunWatchConnectionLoop") if err != nil { + logf("mesh connect: %v", err) + if notifyError != nil { + notifyError(err) + } if f := testHookWatchLookConnectResult; f != nil && !f(err, false) { return } @@ -141,6 +149,9 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key if err != nil { clear() logf("Recv: %v", err) + if notifyError != nil { + notifyError(err) + } sleep(retryInterval) break } diff --git a/vendor/tailscale.com/disco/disco.go b/vendor/tailscale.com/disco/disco.go index b9a9002..f58bc1b 100644 --- a/vendor/tailscale.com/disco/disco.go +++ b/vendor/tailscale.com/disco/disco.go @@ -25,6 +25,7 @@ import ( "fmt" "net" "net/netip" + "time" "go4.org/mem" "tailscale.com/types/key" @@ -41,9 +42,15 @@ const NonceLen = 24 type MessageType byte const ( - TypePing = MessageType(0x01) - TypePong = MessageType(0x02) - TypeCallMeMaybe = MessageType(0x03) + TypePing = MessageType(0x01) + TypePong = MessageType(0x02) + TypeCallMeMaybe = MessageType(0x03) + TypeBindUDPRelayEndpoint = MessageType(0x04) + TypeBindUDPRelayEndpointChallenge = MessageType(0x05) + TypeBindUDPRelayEndpointAnswer = MessageType(0x06) + TypeCallMeMaybeVia = MessageType(0x07) + TypeAllocateUDPRelayEndpointRequest = MessageType(0x08) + TypeAllocateUDPRelayEndpointResponse = MessageType(0x09) ) const v0 = byte(0) @@ -77,12 +84,25 @@ func Parse(p []byte) (Message, error) { } t, ver, p := MessageType(p[0]), p[1], p[2:] switch t { + // TODO(jwhited): consider using a signature matching encoding.BinaryUnmarshaler case TypePing: return parsePing(ver, p) case TypePong: return parsePong(ver, p) case TypeCallMeMaybe: return parseCallMeMaybe(ver, p) + case TypeBindUDPRelayEndpoint: + return parseBindUDPRelayEndpoint(ver, p) + case TypeBindUDPRelayEndpointChallenge: + return parseBindUDPRelayEndpointChallenge(ver, p) + case TypeBindUDPRelayEndpointAnswer: + return parseBindUDPRelayEndpointAnswer(ver, p) + case TypeCallMeMaybeVia: + return parseCallMeMaybeVia(ver, p) + case TypeAllocateUDPRelayEndpointRequest: + return parseAllocateUDPRelayEndpointRequest(ver, p) + case TypeAllocateUDPRelayEndpointResponse: + return parseAllocateUDPRelayEndpointResponse(ver, p) default: return nil, fmt.Errorf("unknown message type 0x%02x", byte(t)) } @@ -91,6 +111,7 @@ func Parse(p []byte) (Message, error) { // Message a discovery message. type Message interface { // AppendMarshal appends the message's marshaled representation. + // TODO(jwhited): consider using a signature matching encoding.BinaryAppender AppendMarshal([]byte) []byte } @@ -266,7 +287,368 @@ func MessageSummary(m Message) string { return fmt.Sprintf("pong tx=%x", m.TxID[:6]) case *CallMeMaybe: return "call-me-maybe" + case *CallMeMaybeVia: + return "call-me-maybe-via" + case *BindUDPRelayEndpoint: + return "bind-udp-relay-endpoint" + case *BindUDPRelayEndpointChallenge: + return "bind-udp-relay-endpoint-challenge" + case *BindUDPRelayEndpointAnswer: + return "bind-udp-relay-endpoint-answer" + case *AllocateUDPRelayEndpointRequest: + return "allocate-udp-relay-endpoint-request" + case *AllocateUDPRelayEndpointResponse: + return "allocate-udp-relay-endpoint-response" default: return fmt.Sprintf("%#v", m) } } + +// BindUDPRelayHandshakeState represents the state of the 3-way bind handshake +// between UDP relay client and UDP relay server. Its potential values include +// those for both participants, UDP relay client and UDP relay server. A UDP +// relay server implementation can be found in net/udprelay. This is currently +// considered experimental. +type BindUDPRelayHandshakeState int + +const ( + // BindUDPRelayHandshakeStateInit represents the initial state prior to any + // message being transmitted. + BindUDPRelayHandshakeStateInit BindUDPRelayHandshakeState = iota + // BindUDPRelayHandshakeStateBindSent is the first client state after + // transmitting a BindUDPRelayEndpoint message to a UDP relay server. + BindUDPRelayHandshakeStateBindSent + // BindUDPRelayHandshakeStateChallengeSent is the first server state after + // receiving a BindUDPRelayEndpoint message from a UDP relay client and + // replying with a BindUDPRelayEndpointChallenge. + BindUDPRelayHandshakeStateChallengeSent + // BindUDPRelayHandshakeStateAnswerSent is a client state that is entered + // after transmitting a BindUDPRelayEndpointAnswer message towards a UDP + // relay server in response to a BindUDPRelayEndpointChallenge message. + BindUDPRelayHandshakeStateAnswerSent + // BindUDPRelayHandshakeStateAnswerReceived is a server state that is + // entered after it has received a correct BindUDPRelayEndpointAnswer + // message from a UDP relay client in response to a + // BindUDPRelayEndpointChallenge message. + BindUDPRelayHandshakeStateAnswerReceived +) + +// bindUDPRelayEndpointCommonLen is the length of a marshalled +// [BindUDPRelayEndpointCommon], without the message header. +const bindUDPRelayEndpointCommonLen = 72 + +// BindUDPRelayChallengeLen is the length of the Challenge field carried in +// [BindUDPRelayEndpointChallenge] & [BindUDPRelayEndpointAnswer] messages. +const BindUDPRelayChallengeLen = 32 + +// BindUDPRelayEndpointCommon contains fields that are common across all 3 +// UDP relay handshake message types. All 4 field values are expected to be +// consistent for the lifetime of a handshake besides Challenge, which is +// irrelevant in a [BindUDPRelayEndpoint] message. +type BindUDPRelayEndpointCommon struct { + // VNI is the Geneve header Virtual Network Identifier field value, which + // must match this disco-sealed value upon reception. If they are + // non-matching it indicates the cleartext Geneve header was tampered with + // and/or mangled. + VNI uint32 + // Generation represents the handshake generation. Clients must set a new, + // nonzero value at the start of every handshake. + Generation uint32 + // RemoteKey is the disco key of the remote peer participating over this + // relay endpoint. + RemoteKey key.DiscoPublic + // Challenge is set by the server in a [BindUDPRelayEndpointChallenge] + // message, and expected to be echoed back by the client in a + // [BindUDPRelayEndpointAnswer] message. Its value is irrelevant in a + // [BindUDPRelayEndpoint] message, where it simply serves a padding purpose + // ensuring all handshake messages are equal in size. + Challenge [BindUDPRelayChallengeLen]byte +} + +// encode encodes m in b. b must be at least bindUDPRelayEndpointCommonLen bytes +// long. +func (m *BindUDPRelayEndpointCommon) encode(b []byte) { + binary.BigEndian.PutUint32(b, m.VNI) + b = b[4:] + binary.BigEndian.PutUint32(b, m.Generation) + b = b[4:] + m.RemoteKey.AppendTo(b[:0]) + b = b[key.DiscoPublicRawLen:] + copy(b, m.Challenge[:]) +} + +// decode decodes m from b. +func (m *BindUDPRelayEndpointCommon) decode(b []byte) error { + if len(b) < bindUDPRelayEndpointCommonLen { + return errShort + } + m.VNI = binary.BigEndian.Uint32(b) + b = b[4:] + m.Generation = binary.BigEndian.Uint32(b) + b = b[4:] + m.RemoteKey = key.DiscoPublicFromRaw32(mem.B(b[:key.DiscoPublicRawLen])) + b = b[key.DiscoPublicRawLen:] + copy(m.Challenge[:], b[:BindUDPRelayChallengeLen]) + return nil +} + +// BindUDPRelayEndpoint is the first messaged transmitted from UDP relay client +// towards UDP relay server as part of the 3-way bind handshake. +type BindUDPRelayEndpoint struct { + BindUDPRelayEndpointCommon +} + +func (m *BindUDPRelayEndpoint) AppendMarshal(b []byte) []byte { + ret, d := appendMsgHeader(b, TypeBindUDPRelayEndpoint, v0, bindUDPRelayEndpointCommonLen) + m.BindUDPRelayEndpointCommon.encode(d) + return ret +} + +func parseBindUDPRelayEndpoint(ver uint8, p []byte) (m *BindUDPRelayEndpoint, err error) { + m = new(BindUDPRelayEndpoint) + err = m.BindUDPRelayEndpointCommon.decode(p) + if err != nil { + return nil, err + } + return m, nil +} + +// BindUDPRelayEndpointChallenge is transmitted from UDP relay server towards +// UDP relay client in response to a BindUDPRelayEndpoint message as part of the +// 3-way bind handshake. +type BindUDPRelayEndpointChallenge struct { + BindUDPRelayEndpointCommon +} + +func (m *BindUDPRelayEndpointChallenge) AppendMarshal(b []byte) []byte { + ret, d := appendMsgHeader(b, TypeBindUDPRelayEndpointChallenge, v0, bindUDPRelayEndpointCommonLen) + m.BindUDPRelayEndpointCommon.encode(d) + return ret +} + +func parseBindUDPRelayEndpointChallenge(ver uint8, p []byte) (m *BindUDPRelayEndpointChallenge, err error) { + m = new(BindUDPRelayEndpointChallenge) + err = m.BindUDPRelayEndpointCommon.decode(p) + if err != nil { + return nil, err + } + return m, nil +} + +// BindUDPRelayEndpointAnswer is transmitted from UDP relay client to UDP relay +// server in response to a BindUDPRelayEndpointChallenge message. +type BindUDPRelayEndpointAnswer struct { + BindUDPRelayEndpointCommon +} + +func (m *BindUDPRelayEndpointAnswer) AppendMarshal(b []byte) []byte { + ret, d := appendMsgHeader(b, TypeBindUDPRelayEndpointAnswer, v0, bindUDPRelayEndpointCommonLen) + m.BindUDPRelayEndpointCommon.encode(d) + return ret +} + +func parseBindUDPRelayEndpointAnswer(ver uint8, p []byte) (m *BindUDPRelayEndpointAnswer, err error) { + m = new(BindUDPRelayEndpointAnswer) + err = m.BindUDPRelayEndpointCommon.decode(p) + if err != nil { + return nil, err + } + return m, nil +} + +// AllocateUDPRelayEndpointRequest is a message sent only over DERP to request +// allocation of a relay endpoint on a [tailscale.com/net/udprelay.Server] +type AllocateUDPRelayEndpointRequest struct { + // ClientDisco are the Disco public keys of the clients that should be + // permitted to handshake with the endpoint. + ClientDisco [2]key.DiscoPublic + // Generation represents the allocation request generation. The server must + // echo it back in the [AllocateUDPRelayEndpointResponse] to enable request + // and response alignment client-side. + Generation uint32 +} + +// allocateUDPRelayEndpointRequestLen is the length of a marshaled +// [AllocateUDPRelayEndpointRequest] message without the message header. +const allocateUDPRelayEndpointRequestLen = key.DiscoPublicRawLen*2 + // ClientDisco + 4 // Generation + +func (m *AllocateUDPRelayEndpointRequest) AppendMarshal(b []byte) []byte { + ret, p := appendMsgHeader(b, TypeAllocateUDPRelayEndpointRequest, v0, allocateUDPRelayEndpointRequestLen) + for i := 0; i < len(m.ClientDisco); i++ { + disco := m.ClientDisco[i].AppendTo(nil) + copy(p, disco) + p = p[key.DiscoPublicRawLen:] + } + binary.BigEndian.PutUint32(p, m.Generation) + return ret +} + +func parseAllocateUDPRelayEndpointRequest(ver uint8, p []byte) (m *AllocateUDPRelayEndpointRequest, err error) { + m = new(AllocateUDPRelayEndpointRequest) + if ver != 0 { + return + } + if len(p) < allocateUDPRelayEndpointRequestLen { + return m, errShort + } + for i := 0; i < len(m.ClientDisco); i++ { + m.ClientDisco[i] = key.DiscoPublicFromRaw32(mem.B(p[:key.DiscoPublicRawLen])) + p = p[key.DiscoPublicRawLen:] + } + m.Generation = binary.BigEndian.Uint32(p) + return m, nil +} + +// AllocateUDPRelayEndpointResponse is a message sent only over DERP in response +// to a [AllocateUDPRelayEndpointRequest]. +type AllocateUDPRelayEndpointResponse struct { + // Generation represents the allocation request generation. The server must + // echo back the [AllocateUDPRelayEndpointRequest.Generation] here to enable + // request and response alignment client-side. + Generation uint32 + UDPRelayEndpoint +} + +func (m *AllocateUDPRelayEndpointResponse) AppendMarshal(b []byte) []byte { + endpointsLen := epLength * len(m.AddrPorts) + generationLen := 4 + ret, d := appendMsgHeader(b, TypeAllocateUDPRelayEndpointResponse, v0, generationLen+udpRelayEndpointLenMinusAddrPorts+endpointsLen) + binary.BigEndian.PutUint32(d, m.Generation) + m.encode(d[4:]) + return ret +} + +func parseAllocateUDPRelayEndpointResponse(ver uint8, p []byte) (m *AllocateUDPRelayEndpointResponse, err error) { + m = new(AllocateUDPRelayEndpointResponse) + if ver != 0 { + return m, nil + } + if len(p) < 4 { + return m, errShort + } + m.Generation = binary.BigEndian.Uint32(p) + err = m.decode(p[4:]) + return m, err +} + +const udpRelayEndpointLenMinusAddrPorts = key.DiscoPublicRawLen + // ServerDisco + (key.DiscoPublicRawLen * 2) + // ClientDisco + 8 + // LamportID + 4 + // VNI + 8 + // BindLifetime + 8 // SteadyStateLifetime + +// UDPRelayEndpoint is a mirror of [tailscale.com/net/udprelay/endpoint.ServerEndpoint], +// refer to it for field documentation. [UDPRelayEndpoint] is carried in both +// [CallMeMaybeVia] and [AllocateUDPRelayEndpointResponse] messages. +type UDPRelayEndpoint struct { + // ServerDisco is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.ServerDisco] + ServerDisco key.DiscoPublic + // ClientDisco is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.ClientDisco] + ClientDisco [2]key.DiscoPublic + // LamportID is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.LamportID] + LamportID uint64 + // VNI is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.VNI] + VNI uint32 + // BindLifetime is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.BindLifetime] + BindLifetime time.Duration + // SteadyStateLifetime is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.SteadyStateLifetime] + SteadyStateLifetime time.Duration + // AddrPorts is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.AddrPorts] + AddrPorts []netip.AddrPort +} + +// encode encodes m in b. b must be at least [udpRelayEndpointLenMinusAddrPorts] +// + [epLength] * len(m.AddrPorts) bytes long. +func (m *UDPRelayEndpoint) encode(b []byte) { + disco := m.ServerDisco.AppendTo(nil) + copy(b, disco) + b = b[key.DiscoPublicRawLen:] + for i := 0; i < len(m.ClientDisco); i++ { + disco = m.ClientDisco[i].AppendTo(nil) + copy(b, disco) + b = b[key.DiscoPublicRawLen:] + } + binary.BigEndian.PutUint64(b[:8], m.LamportID) + b = b[8:] + binary.BigEndian.PutUint32(b[:4], m.VNI) + b = b[4:] + binary.BigEndian.PutUint64(b[:8], uint64(m.BindLifetime)) + b = b[8:] + binary.BigEndian.PutUint64(b[:8], uint64(m.SteadyStateLifetime)) + b = b[8:] + for _, ipp := range m.AddrPorts { + a := ipp.Addr().As16() + copy(b, a[:]) + binary.BigEndian.PutUint16(b[16:18], ipp.Port()) + b = b[epLength:] + } +} + +// decode decodes m from b. +func (m *UDPRelayEndpoint) decode(b []byte) error { + if len(b) < udpRelayEndpointLenMinusAddrPorts+epLength || + (len(b)-udpRelayEndpointLenMinusAddrPorts)%epLength != 0 { + return errShort + } + m.ServerDisco = key.DiscoPublicFromRaw32(mem.B(b[:key.DiscoPublicRawLen])) + b = b[key.DiscoPublicRawLen:] + for i := 0; i < len(m.ClientDisco); i++ { + m.ClientDisco[i] = key.DiscoPublicFromRaw32(mem.B(b[:key.DiscoPublicRawLen])) + b = b[key.DiscoPublicRawLen:] + } + m.LamportID = binary.BigEndian.Uint64(b[:8]) + b = b[8:] + m.VNI = binary.BigEndian.Uint32(b[:4]) + b = b[4:] + m.BindLifetime = time.Duration(binary.BigEndian.Uint64(b[:8])) + b = b[8:] + m.SteadyStateLifetime = time.Duration(binary.BigEndian.Uint64(b[:8])) + b = b[8:] + m.AddrPorts = make([]netip.AddrPort, 0, len(b)-udpRelayEndpointLenMinusAddrPorts/epLength) + for len(b) > 0 { + var a [16]byte + copy(a[:], b) + m.AddrPorts = append(m.AddrPorts, netip.AddrPortFrom( + netip.AddrFrom16(a).Unmap(), + binary.BigEndian.Uint16(b[16:18]))) + b = b[epLength:] + } + return nil +} + +// CallMeMaybeVia is a message sent only over DERP to request that the recipient +// try to open up a magicsock path back to the sender. The 'Via' in +// CallMeMaybeVia highlights that candidate paths are served through an +// intermediate relay, likely a [tailscale.com/net/udprelay.Server]. +// +// Usage of the candidate paths in magicsock requires a 3-way handshake +// involving [BindUDPRelayEndpoint], [BindUDPRelayEndpointChallenge], and +// [BindUDPRelayEndpointAnswer]. +// +// CallMeMaybeVia mirrors [tailscale.com/net/udprelay/endpoint.ServerEndpoint], +// which contains field documentation. +// +// The recipient may choose to not open a path back if it's already happy with +// its path. Direct connections, e.g. [CallMeMaybe]-signaled, take priority over +// CallMeMaybeVia paths. +type CallMeMaybeVia struct { + UDPRelayEndpoint +} + +func (m *CallMeMaybeVia) AppendMarshal(b []byte) []byte { + endpointsLen := epLength * len(m.AddrPorts) + ret, p := appendMsgHeader(b, TypeCallMeMaybeVia, v0, udpRelayEndpointLenMinusAddrPorts+endpointsLen) + m.encode(p) + return ret +} + +func parseCallMeMaybeVia(ver uint8, p []byte) (m *CallMeMaybeVia, err error) { + m = new(CallMeMaybeVia) + if ver != 0 { + return m, nil + } + err = m.decode(p) + return m, err +} diff --git a/vendor/tailscale.com/doctor/doctor.go b/vendor/tailscale.com/doctor/doctor.go deleted file mode 100644 index 7c3047e..0000000 --- a/vendor/tailscale.com/doctor/doctor.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package doctor contains more in-depth healthchecks that can be run to aid in -// diagnosing Tailscale issues. -package doctor - -import ( - "context" - "sync" - - "tailscale.com/types/logger" -) - -// Check is the interface defining a singular check. -// -// A check should log information that it gathers using the provided log -// function, and should attempt to make as much progress as possible in error -// conditions. -type Check interface { - // Name should return a name describing this check, in lower-kebab-case - // (i.e. "my-check", not "MyCheck" or "my_check"). - Name() string - // Run executes the check, logging diagnostic information to the - // provided logger function. - Run(context.Context, logger.Logf) error -} - -// RunChecks runs a list of checks in parallel, and logs any returned errors -// after all checks have returned. -func RunChecks(ctx context.Context, log logger.Logf, checks ...Check) { - if len(checks) == 0 { - return - } - - type namedErr struct { - name string - err error - } - errs := make(chan namedErr, len(checks)) - - var wg sync.WaitGroup - wg.Add(len(checks)) - for _, check := range checks { - go func(c Check) { - defer wg.Done() - - plog := logger.WithPrefix(log, c.Name()+": ") - errs <- namedErr{ - name: c.Name(), - err: c.Run(ctx, plog), - } - }(check) - } - - wg.Wait() - close(errs) - - for n := range errs { - if n.err == nil { - continue - } - - log("check %s: %v", n.name, n.err) - } -} - -// CheckFunc creates a Check from a name and a function. -func CheckFunc(name string, run func(context.Context, logger.Logf) error) Check { - return checkFunc{name, run} -} - -type checkFunc struct { - name string - run func(context.Context, logger.Logf) error -} - -func (c checkFunc) Name() string { return c.name } -func (c checkFunc) Run(ctx context.Context, log logger.Logf) error { return c.run(ctx, log) } diff --git a/vendor/tailscale.com/doctor/ethtool/ethtool.go b/vendor/tailscale.com/doctor/ethtool/ethtool.go deleted file mode 100644 index f80b00a..0000000 --- a/vendor/tailscale.com/doctor/ethtool/ethtool.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package ethtool provides a doctor.Check that prints diagnostic information -// obtained from the 'ethtool' utility on the current system. -package ethtool - -import ( - "context" - - "tailscale.com/types/logger" -) - -// Check implements the doctor.Check interface. -type Check struct{} - -func (Check) Name() string { - return "ethtool" -} - -func (Check) Run(_ context.Context, logf logger.Logf) error { - return ethtoolImpl(logf) -} diff --git a/vendor/tailscale.com/doctor/ethtool/ethtool_linux.go b/vendor/tailscale.com/doctor/ethtool/ethtool_linux.go deleted file mode 100644 index b8cc080..0000000 --- a/vendor/tailscale.com/doctor/ethtool/ethtool_linux.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package ethtool - -import ( - "net/netip" - "sort" - - "github.com/safchain/ethtool" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" - "tailscale.com/util/set" -) - -func ethtoolImpl(logf logger.Logf) error { - et, err := ethtool.NewEthtool() - if err != nil { - logf("could not create ethtool: %v", err) - return nil - } - defer et.Close() - - netmon.ForeachInterface(func(iface netmon.Interface, _ []netip.Prefix) { - ilogf := logger.WithPrefix(logf, iface.Name+": ") - features, err := et.Features(iface.Name) - if err == nil { - enabled := []string{} - for feature, value := range features { - if value { - enabled = append(enabled, feature) - } - } - sort.Strings(enabled) - ilogf("features: %v", enabled) - } else { - ilogf("features: error: %v", err) - } - - stats, err := et.Stats(iface.Name) - if err == nil { - printStats(ilogf, stats) - } else { - ilogf("stats: error: %v", err) - } - }) - - return nil -} - -// Stats that should be printed if non-zero -var nonzeroStats = set.SetOf([]string{ - // AWS ENA driver statistics; see: - // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html - "bw_in_allowance_exceeded", - "bw_out_allowance_exceeded", - "conntrack_allowance_exceeded", - "linklocal_allowance_exceeded", - "pps_allowance_exceeded", -}) - -// Stats that should be printed if zero -var zeroStats = set.SetOf([]string{ - // AWS ENA driver statistics; see: - // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html - "conntrack_allowance_available", -}) - -func printStats(logf logger.Logf, stats map[string]uint64) { - for name, value := range stats { - if value != 0 && nonzeroStats.Contains(name) { - logf("stats: warning: %s = %d > 0", name, value) - } - if value == 0 && zeroStats.Contains(name) { - logf("stats: warning: %s = %d == 0", name, value) - } - } -} diff --git a/vendor/tailscale.com/doctor/ethtool/ethtool_other.go b/vendor/tailscale.com/doctor/ethtool/ethtool_other.go deleted file mode 100644 index 9aaa9dd..0000000 --- a/vendor/tailscale.com/doctor/ethtool/ethtool_other.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package ethtool - -import ( - "runtime" - - "tailscale.com/types/logger" -) - -func ethtoolImpl(logf logger.Logf) error { - logf("unsupported on %s/%s", runtime.GOOS, runtime.GOARCH) - return nil -} diff --git a/vendor/tailscale.com/doctor/permissions/permissions.go b/vendor/tailscale.com/doctor/permissions/permissions.go deleted file mode 100644 index 77fe526..0000000 --- a/vendor/tailscale.com/doctor/permissions/permissions.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package permissions provides a doctor.Check that prints the process -// permissions for the running process. -package permissions - -import ( - "context" - "fmt" - "os/user" - "strings" - - "golang.org/x/exp/constraints" - "tailscale.com/types/logger" -) - -// Check implements the doctor.Check interface. -type Check struct{} - -func (Check) Name() string { - return "permissions" -} - -func (Check) Run(_ context.Context, logf logger.Logf) error { - return permissionsImpl(logf) -} - -//lint:ignore U1000 used in non-windows implementations. -func formatUserID[T constraints.Integer](id T) string { - idStr := fmt.Sprint(id) - if uu, err := user.LookupId(idStr); err != nil { - return idStr + "()" - } else { - return fmt.Sprintf("%s(%q)", idStr, uu.Username) - } -} - -//lint:ignore U1000 used in non-windows implementations. -func formatGroupID[T constraints.Integer](id T) string { - idStr := fmt.Sprint(id) - if g, err := user.LookupGroupId(idStr); err != nil { - return idStr + "()" - } else { - return fmt.Sprintf("%s(%q)", idStr, g.Name) - } -} - -//lint:ignore U1000 used in non-windows implementations. -func formatGroups[T constraints.Integer](groups []T) string { - var buf strings.Builder - for i, group := range groups { - if i > 0 { - buf.WriteByte(',') - } - buf.WriteString(formatGroupID(group)) - } - return buf.String() -} diff --git a/vendor/tailscale.com/doctor/permissions/permissions_bsd.go b/vendor/tailscale.com/doctor/permissions/permissions_bsd.go deleted file mode 100644 index 8b034cf..0000000 --- a/vendor/tailscale.com/doctor/permissions/permissions_bsd.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin || freebsd || openbsd - -package permissions - -import ( - "golang.org/x/sys/unix" - "tailscale.com/types/logger" -) - -func permissionsImpl(logf logger.Logf) error { - groups, _ := unix.Getgroups() - logf("uid=%s euid=%s gid=%s egid=%s groups=%s", - formatUserID(unix.Getuid()), - formatUserID(unix.Geteuid()), - formatGroupID(unix.Getgid()), - formatGroupID(unix.Getegid()), - formatGroups(groups), - ) - return nil -} diff --git a/vendor/tailscale.com/doctor/permissions/permissions_linux.go b/vendor/tailscale.com/doctor/permissions/permissions_linux.go deleted file mode 100644 index 12bb393..0000000 --- a/vendor/tailscale.com/doctor/permissions/permissions_linux.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package permissions - -import ( - "fmt" - "strings" - "unsafe" - - "golang.org/x/sys/unix" - "tailscale.com/types/logger" -) - -func permissionsImpl(logf logger.Logf) error { - // NOTE: getresuid and getresgid never fail unless passed an - // invalid address. - var ruid, euid, suid uint64 - unix.Syscall(unix.SYS_GETRESUID, - uintptr(unsafe.Pointer(&ruid)), - uintptr(unsafe.Pointer(&euid)), - uintptr(unsafe.Pointer(&suid)), - ) - - var rgid, egid, sgid uint64 - unix.Syscall(unix.SYS_GETRESGID, - uintptr(unsafe.Pointer(&rgid)), - uintptr(unsafe.Pointer(&egid)), - uintptr(unsafe.Pointer(&sgid)), - ) - - groups, _ := unix.Getgroups() - - var buf strings.Builder - fmt.Fprintf(&buf, "ruid=%s euid=%s suid=%s rgid=%s egid=%s sgid=%s groups=%s", - formatUserID(ruid), formatUserID(euid), formatUserID(suid), - formatGroupID(rgid), formatGroupID(egid), formatGroupID(sgid), - formatGroups(groups), - ) - - // Get process capabilities - var ( - capHeader = unix.CapUserHeader{ - Version: unix.LINUX_CAPABILITY_VERSION_3, - Pid: 0, // 0 means 'ourselves' - } - capData unix.CapUserData - ) - - if err := unix.Capget(&capHeader, &capData); err != nil { - fmt.Fprintf(&buf, " caperr=%v", err) - } else { - fmt.Fprintf(&buf, " cap_effective=%08x cap_permitted=%08x cap_inheritable=%08x", - capData.Effective, capData.Permitted, capData.Inheritable, - ) - } - - logf("%s", buf.String()) - return nil -} diff --git a/vendor/tailscale.com/doctor/permissions/permissions_other.go b/vendor/tailscale.com/doctor/permissions/permissions_other.go deleted file mode 100644 index 7e6912b..0000000 --- a/vendor/tailscale.com/doctor/permissions/permissions_other.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !(linux || darwin || freebsd || openbsd) - -package permissions - -import ( - "runtime" - - "tailscale.com/types/logger" -) - -func permissionsImpl(logf logger.Logf) error { - logf("unsupported on %s/%s", runtime.GOOS, runtime.GOARCH) - return nil -} diff --git a/vendor/tailscale.com/doctor/routetable/routetable.go b/vendor/tailscale.com/doctor/routetable/routetable.go deleted file mode 100644 index 76e4ef9..0000000 --- a/vendor/tailscale.com/doctor/routetable/routetable.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package routetable provides a doctor.Check that dumps the current system's -// route table to the log. -package routetable - -import ( - "context" - - "tailscale.com/net/routetable" - "tailscale.com/types/logger" -) - -// MaxRoutes is the maximum number of routes that will be displayed. -const MaxRoutes = 1000 - -// Check implements the doctor.Check interface. -type Check struct{} - -func (Check) Name() string { - return "routetable" -} - -func (Check) Run(_ context.Context, logf logger.Logf) error { - rs, err := routetable.Get(MaxRoutes) - if err != nil { - return err - } - for _, r := range rs { - logf("%s", r) - } - return nil -} diff --git a/vendor/tailscale.com/drive/drive_view.go b/vendor/tailscale.com/drive/drive_view.go index 0f6686f..b481751 100644 --- a/vendor/tailscale.com/drive/drive_view.go +++ b/vendor/tailscale.com/drive/drive_view.go @@ -6,9 +6,11 @@ package drive import ( - "encoding/json" + jsonv1 "encoding/json" "errors" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "tailscale.com/types/views" ) @@ -42,8 +44,17 @@ func (v ShareView) AsStruct() *Share { return v.ж.Clone() } -func (v ShareView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ShareView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ShareView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *ShareView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -52,16 +63,44 @@ func (v *ShareView) UnmarshalJSON(b []byte) error { return nil } var x Share - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ShareView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Share + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Name is how this share appears on remote nodes. func (v ShareView) Name() string { return v.ж.Name } + +// Path is the path to the directory on this machine that's being shared. func (v ShareView) Path() string { return v.ж.Path } -func (v ShareView) As() string { return v.ж.As } + +// As is the UNIX or Windows username of the local account used for this +// share. File read/write permissions are enforced based on this username. +// Can be left blank to use the default value of "whoever is running the +// Tailscale GUI". +func (v ShareView) As() string { return v.ж.As } + +// BookmarkData contains security-scoped bookmark data for the Sandboxed +// Mac application. The Sandboxed Mac application gains permission to +// access the Share's folder as a result of a user selecting it in a file +// picker. In order to retain access to it across restarts, it needs to +// hold on to a security-scoped bookmark. That bookmark is stored here. See +// https://developer.apple.com/documentation/security/app_sandbox/accessing_files_from_the_macos_app_sandbox#4144043 func (v ShareView) BookmarkData() views.ByteSlice[[]byte] { return views.ByteSliceOf(v.ж.BookmarkData) } diff --git a/vendor/tailscale.com/drive/local.go b/vendor/tailscale.com/drive/local.go index aff79a5..052efb3 100644 --- a/vendor/tailscale.com/drive/local.go +++ b/vendor/tailscale.com/drive/local.go @@ -17,7 +17,7 @@ import ( // Remote represents a remote Taildrive node. type Remote struct { Name string - URL string + URL func() string Available func() bool } diff --git a/vendor/tailscale.com/drive/remote.go b/vendor/tailscale.com/drive/remote.go index 9aeead7..2c6fba8 100644 --- a/vendor/tailscale.com/drive/remote.go +++ b/vendor/tailscale.com/drive/remote.go @@ -9,7 +9,6 @@ import ( "bytes" "errors" "net/http" - "regexp" "strings" ) @@ -21,10 +20,6 @@ var ( ErrInvalidShareName = errors.New("Share names may only contain the letters a-z, underscore _, parentheses (), or spaces") ) -var ( - shareNameRegex = regexp.MustCompile(`^[a-z0-9_\(\) ]+$`) -) - // AllowShareAs reports whether sharing files as a specific user is allowed. func AllowShareAs() bool { return !DisallowShareAs && doAllowShareAs() @@ -125,9 +120,26 @@ func NormalizeShareName(name string) (string, error) { // Trim whitespace name = strings.TrimSpace(name) - if !shareNameRegex.MatchString(name) { + if !validShareName(name) { return "", ErrInvalidShareName } return name, nil } + +func validShareName(name string) bool { + if name == "" { + return false + } + for _, r := range name { + if 'a' <= r && r <= 'z' || '0' <= r && r <= '9' { + continue + } + switch r { + case '_', ' ', '(', ')': + continue + } + return false + } + return true +} diff --git a/vendor/tailscale.com/drive/remote_permissions.go b/vendor/tailscale.com/drive/remote_permissions.go index d3d41c6..420eff9 100644 --- a/vendor/tailscale.com/drive/remote_permissions.go +++ b/vendor/tailscale.com/drive/remote_permissions.go @@ -32,7 +32,7 @@ type grant struct { Access string } -// ParsePermissions builds a Permissions map from a lis of raw grants. +// ParsePermissions builds a Permissions map from a list of raw grants. func ParsePermissions(rawGrants [][]byte) (Permissions, error) { permissions := make(Permissions) for _, rawGrant := range rawGrants { diff --git a/vendor/tailscale.com/envknob/envknob.go b/vendor/tailscale.com/envknob/envknob.go index e581eb2..17a2138 100644 --- a/vendor/tailscale.com/envknob/envknob.go +++ b/vendor/tailscale.com/envknob/envknob.go @@ -28,18 +28,19 @@ import ( "slices" "strconv" "strings" - "sync" "sync/atomic" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/kube/kubetypes" + "tailscale.com/syncs" "tailscale.com/types/opt" "tailscale.com/version" "tailscale.com/version/distro" ) var ( - mu sync.Mutex + mu syncs.Mutex // +checklocks:mu set = map[string]string{} // +checklocks:mu @@ -463,7 +464,12 @@ var allowRemoteUpdate = RegisterBool("TS_ALLOW_ADMIN_CONSOLE_REMOTE_UPDATE") // AllowsRemoteUpdate reports whether this node has opted-in to letting the // Tailscale control plane initiate a Tailscale update (e.g. on behalf of an // admin on the admin console). -func AllowsRemoteUpdate() bool { return allowRemoteUpdate() } +func AllowsRemoteUpdate() bool { + if !buildfeatures.HasClientUpdate { + return false + } + return allowRemoteUpdate() +} // SetNoLogsNoSupport enables no-logs-no-support mode. func SetNoLogsNoSupport() { @@ -474,6 +480,9 @@ func SetNoLogsNoSupport() { var notInInit atomic.Bool func assertNotInInit() { + if !buildfeatures.HasDebug { + return + } if notInInit.Load() { return } @@ -533,6 +542,11 @@ func ApplyDiskConfigError() error { return applyDiskConfigErr } // for App Store builds // - /etc/tailscale/tailscaled-env.txt for tailscaled-on-macOS (homebrew, etc) func ApplyDiskConfig() (err error) { + if runtime.GOOS == "linux" && !(buildfeatures.HasDebug || buildfeatures.HasSynology) { + // This function does nothing on Linux, unless you're + // using TS_DEBUG_ENV_FILE or are on Synology. + return nil + } var f *os.File defer func() { if err != nil { @@ -593,7 +607,7 @@ func getPlatformEnvFiles() []string { filepath.Join(os.Getenv("ProgramData"), "Tailscale", "tailscaled-env.txt"), } case "linux": - if distro.Get() == distro.Synology { + if buildfeatures.HasSynology && distro.Get() == distro.Synology { return []string{"/etc/tailscale/tailscaled-env.txt"} } case "darwin": diff --git a/vendor/tailscale.com/envknob/featureknob/featureknob.go b/vendor/tailscale.com/envknob/featureknob/featureknob.go index 210414b..5a54a1c 100644 --- a/vendor/tailscale.com/envknob/featureknob/featureknob.go +++ b/vendor/tailscale.com/envknob/featureknob/featureknob.go @@ -10,7 +10,6 @@ import ( "runtime" "tailscale.com/envknob" - "tailscale.com/hostinfo" "tailscale.com/version" "tailscale.com/version/distro" ) @@ -26,21 +25,13 @@ func CanRunTailscaleSSH() error { if distro.Get() == distro.QNAP && !envknob.UseWIPCode() { return errors.New("The Tailscale SSH server does not run on QNAP.") } - - // Setting SSH on Home Assistant causes trouble on startup - // (since the flag is not being passed to `tailscale up`). - // Although Tailscale SSH does work here, - // it's not terribly useful since it's running in a separate container. - if hostinfo.GetEnvType() == hostinfo.HomeAssistantAddOn { - return errors.New("The Tailscale SSH server does not run on HomeAssistant.") - } // otherwise okay case "darwin": // okay only in tailscaled mode for now. if version.IsSandboxedMacOS() { return errors.New("The Tailscale SSH server does not run in sandboxed Tailscale GUI builds.") } - case "freebsd", "openbsd": + case "freebsd", "openbsd", "plan9": default: return errors.New("The Tailscale SSH server is not supported on " + runtime.GOOS) } @@ -58,10 +49,5 @@ func CanUseExitNode() error { distro.QNAP: return errors.New("Tailscale exit nodes cannot be used on " + string(dist)) } - - if hostinfo.GetEnvType() == hostinfo.HomeAssistantAddOn { - return errors.New("Tailscale exit nodes cannot be used on HomeAssistant.") - } - return nil } diff --git a/vendor/tailscale.com/feature/buildfeatures/buildfeatures.go b/vendor/tailscale.com/feature/buildfeatures/buildfeatures.go new file mode 100644 index 0000000..cdb31dc --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/buildfeatures.go @@ -0,0 +1,10 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:generate go run gen.go + +// The buildfeatures package contains boolean constants indicating which +// features were included in the binary (via build tags), for use in dead code +// elimination when using separate build tag protected files is impractical +// or undesirable. +package buildfeatures diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_ace_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_ace_disabled.go new file mode 100644 index 0000000..b4808d4 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_ace_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_ace + +package buildfeatures + +// HasACE is whether the binary was built with support for modular feature "Alternate Connectivity Endpoints". +// Specifically, it's whether the binary was NOT built with the "ts_omit_ace" build tag. +// It's a const so it can be used for dead code elimination. +const HasACE = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_ace_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_ace_enabled.go new file mode 100644 index 0000000..4812f9a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_ace_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_ace + +package buildfeatures + +// HasACE is whether the binary was built with support for modular feature "Alternate Connectivity Endpoints". +// Specifically, it's whether the binary was NOT built with the "ts_omit_ace" build tag. +// It's a const so it can be used for dead code elimination. +const HasACE = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_acme_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_acme_disabled.go new file mode 100644 index 0000000..0a7f25a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_acme_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_acme + +package buildfeatures + +// HasACME is whether the binary was built with support for modular feature "ACME TLS certificate management". +// Specifically, it's whether the binary was NOT built with the "ts_omit_acme" build tag. +// It's a const so it can be used for dead code elimination. +const HasACME = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_acme_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_acme_enabled.go new file mode 100644 index 0000000..f074bfb --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_acme_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_acme + +package buildfeatures + +// HasACME is whether the binary was built with support for modular feature "ACME TLS certificate management". +// Specifically, it's whether the binary was NOT built with the "ts_omit_acme" build tag. +// It's a const so it can be used for dead code elimination. +const HasACME = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_disabled.go new file mode 100644 index 0000000..d4fdcec --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_advertiseexitnode + +package buildfeatures + +// HasAdvertiseExitNode is whether the binary was built with support for modular feature "Run an exit node". +// Specifically, it's whether the binary was NOT built with the "ts_omit_advertiseexitnode" build tag. +// It's a const so it can be used for dead code elimination. +const HasAdvertiseExitNode = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_enabled.go new file mode 100644 index 0000000..2824614 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseexitnode_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_advertiseexitnode + +package buildfeatures + +// HasAdvertiseExitNode is whether the binary was built with support for modular feature "Run an exit node". +// Specifically, it's whether the binary was NOT built with the "ts_omit_advertiseexitnode" build tag. +// It's a const so it can be used for dead code elimination. +const HasAdvertiseExitNode = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_disabled.go new file mode 100644 index 0000000..5904272 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_advertiseroutes + +package buildfeatures + +// HasAdvertiseRoutes is whether the binary was built with support for modular feature "Advertise routes for other nodes to use". +// Specifically, it's whether the binary was NOT built with the "ts_omit_advertiseroutes" build tag. +// It's a const so it can be used for dead code elimination. +const HasAdvertiseRoutes = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_enabled.go new file mode 100644 index 0000000..118fcd5 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_advertiseroutes_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_advertiseroutes + +package buildfeatures + +// HasAdvertiseRoutes is whether the binary was built with support for modular feature "Advertise routes for other nodes to use". +// Specifically, it's whether the binary was NOT built with the "ts_omit_advertiseroutes" build tag. +// It's a const so it can be used for dead code elimination. +const HasAdvertiseRoutes = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_disabled.go new file mode 100644 index 0000000..64ea8f8 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_appconnectors + +package buildfeatures + +// HasAppConnectors is whether the binary was built with support for modular feature "App Connectors support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_appconnectors" build tag. +// It's a const so it can be used for dead code elimination. +const HasAppConnectors = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_enabled.go new file mode 100644 index 0000000..e00eaff --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_appconnectors_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_appconnectors + +package buildfeatures + +// HasAppConnectors is whether the binary was built with support for modular feature "App Connectors support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_appconnectors" build tag. +// It's a const so it can be used for dead code elimination. +const HasAppConnectors = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_aws_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_aws_disabled.go new file mode 100644 index 0000000..66b670c --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_aws_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_aws + +package buildfeatures + +// HasAWS is whether the binary was built with support for modular feature "AWS integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_aws" build tag. +// It's a const so it can be used for dead code elimination. +const HasAWS = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_aws_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_aws_enabled.go new file mode 100644 index 0000000..30203b2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_aws_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_aws + +package buildfeatures + +// HasAWS is whether the binary was built with support for modular feature "AWS integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_aws" build tag. +// It's a const so it can be used for dead code elimination. +const HasAWS = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_disabled.go new file mode 100644 index 0000000..f203bc1 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_bakedroots + +package buildfeatures + +// HasBakedRoots is whether the binary was built with support for modular feature "Embed CA (LetsEncrypt) x509 roots to use as fallback". +// Specifically, it's whether the binary was NOT built with the "ts_omit_bakedroots" build tag. +// It's a const so it can be used for dead code elimination. +const HasBakedRoots = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_enabled.go new file mode 100644 index 0000000..69cf2c3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_bakedroots_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_bakedroots + +package buildfeatures + +// HasBakedRoots is whether the binary was built with support for modular feature "Embed CA (LetsEncrypt) x509 roots to use as fallback". +// Specifically, it's whether the binary was NOT built with the "ts_omit_bakedroots" build tag. +// It's a const so it can be used for dead code elimination. +const HasBakedRoots = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_bird_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_bird_disabled.go new file mode 100644 index 0000000..469aa41 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_bird_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_bird + +package buildfeatures + +// HasBird is whether the binary was built with support for modular feature "Bird BGP integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_bird" build tag. +// It's a const so it can be used for dead code elimination. +const HasBird = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_bird_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_bird_enabled.go new file mode 100644 index 0000000..792129f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_bird_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_bird + +package buildfeatures + +// HasBird is whether the binary was built with support for modular feature "Bird BGP integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_bird" build tag. +// It's a const so it can be used for dead code elimination. +const HasBird = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_c2n_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_c2n_disabled.go new file mode 100644 index 0000000..bc37e9e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_c2n_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_c2n + +package buildfeatures + +// HasC2N is whether the binary was built with support for modular feature "Control-to-node (C2N) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_c2n" build tag. +// It's a const so it can be used for dead code elimination. +const HasC2N = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_c2n_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_c2n_enabled.go new file mode 100644 index 0000000..5950e71 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_c2n_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_c2n + +package buildfeatures + +// HasC2N is whether the binary was built with support for modular feature "Control-to-node (C2N) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_c2n" build tag. +// It's a const so it can be used for dead code elimination. +const HasC2N = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_disabled.go new file mode 100644 index 0000000..22407fe --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_cachenetmap + +package buildfeatures + +// HasCacheNetMap is whether the binary was built with support for modular feature "Cache the netmap on disk between runs". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cachenetmap" build tag. +// It's a const so it can be used for dead code elimination. +const HasCacheNetMap = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_enabled.go new file mode 100644 index 0000000..02663c4 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cachenetmap_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_cachenetmap + +package buildfeatures + +// HasCacheNetMap is whether the binary was built with support for modular feature "Cache the netmap on disk between runs". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cachenetmap" build tag. +// It's a const so it can be used for dead code elimination. +const HasCacheNetMap = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_disabled.go new file mode 100644 index 0000000..367fef8 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_captiveportal + +package buildfeatures + +// HasCaptivePortal is whether the binary was built with support for modular feature "Captive portal detection". +// Specifically, it's whether the binary was NOT built with the "ts_omit_captiveportal" build tag. +// It's a const so it can be used for dead code elimination. +const HasCaptivePortal = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_enabled.go new file mode 100644 index 0000000..bd8e1f6 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_captiveportal_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_captiveportal + +package buildfeatures + +// HasCaptivePortal is whether the binary was built with support for modular feature "Captive portal detection". +// Specifically, it's whether the binary was NOT built with the "ts_omit_captiveportal" build tag. +// It's a const so it can be used for dead code elimination. +const HasCaptivePortal = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_capture_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_capture_disabled.go new file mode 100644 index 0000000..5853595 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_capture_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_capture + +package buildfeatures + +// HasCapture is whether the binary was built with support for modular feature "Packet capture". +// Specifically, it's whether the binary was NOT built with the "ts_omit_capture" build tag. +// It's a const so it can be used for dead code elimination. +const HasCapture = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_capture_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_capture_enabled.go new file mode 100644 index 0000000..7120a3d --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_capture_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_capture + +package buildfeatures + +// HasCapture is whether the binary was built with support for modular feature "Packet capture". +// Specifically, it's whether the binary was NOT built with the "ts_omit_capture" build tag. +// It's a const so it can be used for dead code elimination. +const HasCapture = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_disabled.go new file mode 100644 index 0000000..06d8c79 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_cliconndiag + +package buildfeatures + +// HasCLIConnDiag is whether the binary was built with support for modular feature "CLI connection error diagnostics". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cliconndiag" build tag. +// It's a const so it can be used for dead code elimination. +const HasCLIConnDiag = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_enabled.go new file mode 100644 index 0000000..d6125ef --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cliconndiag_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_cliconndiag + +package buildfeatures + +// HasCLIConnDiag is whether the binary was built with support for modular feature "CLI connection error diagnostics". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cliconndiag" build tag. +// It's a const so it can be used for dead code elimination. +const HasCLIConnDiag = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_disabled.go new file mode 100644 index 0000000..721908b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_clientmetrics + +package buildfeatures + +// HasClientMetrics is whether the binary was built with support for modular feature "Client metrics support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_clientmetrics" build tag. +// It's a const so it can be used for dead code elimination. +const HasClientMetrics = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_enabled.go new file mode 100644 index 0000000..deaeb6e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_clientmetrics_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_clientmetrics + +package buildfeatures + +// HasClientMetrics is whether the binary was built with support for modular feature "Client metrics support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_clientmetrics" build tag. +// It's a const so it can be used for dead code elimination. +const HasClientMetrics = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_disabled.go new file mode 100644 index 0000000..165c9cc --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_clientupdate + +package buildfeatures + +// HasClientUpdate is whether the binary was built with support for modular feature "Client auto-update support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_clientupdate" build tag. +// It's a const so it can be used for dead code elimination. +const HasClientUpdate = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_enabled.go new file mode 100644 index 0000000..3c3c787 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_clientupdate_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_clientupdate + +package buildfeatures + +// HasClientUpdate is whether the binary was built with support for modular feature "Client auto-update support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_clientupdate" build tag. +// It's a const so it can be used for dead code elimination. +const HasClientUpdate = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cloud_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cloud_disabled.go new file mode 100644 index 0000000..3b877a9 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cloud_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_cloud + +package buildfeatures + +// HasCloud is whether the binary was built with support for modular feature "detect cloud environment to learn instances IPs and DNS servers". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cloud" build tag. +// It's a const so it can be used for dead code elimination. +const HasCloud = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_cloud_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_cloud_enabled.go new file mode 100644 index 0000000..8fd748d --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_cloud_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_cloud + +package buildfeatures + +// HasCloud is whether the binary was built with support for modular feature "detect cloud environment to learn instances IPs and DNS servers". +// Specifically, it's whether the binary was NOT built with the "ts_omit_cloud" build tag. +// It's a const so it can be used for dead code elimination. +const HasCloud = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_completion_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_completion_disabled.go new file mode 100644 index 0000000..ea319be --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_completion_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_completion + +package buildfeatures + +// HasCompletion is whether the binary was built with support for modular feature "CLI shell completion". +// Specifically, it's whether the binary was NOT built with the "ts_omit_completion" build tag. +// It's a const so it can be used for dead code elimination. +const HasCompletion = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_completion_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_completion_enabled.go new file mode 100644 index 0000000..6db41c9 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_completion_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_completion + +package buildfeatures + +// HasCompletion is whether the binary was built with support for modular feature "CLI shell completion". +// Specifically, it's whether the binary was NOT built with the "ts_omit_completion" build tag. +// It's a const so it can be used for dead code elimination. +const HasCompletion = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_dbus_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_dbus_disabled.go new file mode 100644 index 0000000..e6ab896 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_dbus_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_dbus + +package buildfeatures + +// HasDBus is whether the binary was built with support for modular feature "Linux DBus support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_dbus" build tag. +// It's a const so it can be used for dead code elimination. +const HasDBus = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_dbus_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_dbus_enabled.go new file mode 100644 index 0000000..374331c --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_dbus_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_dbus + +package buildfeatures + +// HasDBus is whether the binary was built with support for modular feature "Linux DBus support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_dbus" build tag. +// It's a const so it can be used for dead code elimination. +const HasDBus = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debug_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debug_disabled.go new file mode 100644 index 0000000..eb048c0 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debug_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_debug + +package buildfeatures + +// HasDebug is whether the binary was built with support for modular feature "various debug support, for things that don't have or need their own more specific feature". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debug" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebug = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debug_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debug_enabled.go new file mode 100644 index 0000000..12a2700 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debug_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_debug + +package buildfeatures + +// HasDebug is whether the binary was built with support for modular feature "various debug support, for things that don't have or need their own more specific feature". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debug" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebug = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_disabled.go new file mode 100644 index 0000000..2eb5999 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_debugeventbus + +package buildfeatures + +// HasDebugEventBus is whether the binary was built with support for modular feature "eventbus debug support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebugEventBus = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_enabled.go new file mode 100644 index 0000000..df13b6f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debugeventbus_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_debugeventbus + +package buildfeatures + +// HasDebugEventBus is whether the binary was built with support for modular feature "eventbus debug support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebugEventBus = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_disabled.go new file mode 100644 index 0000000..eff85b8 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_debugportmapper + +package buildfeatures + +// HasDebugPortMapper is whether the binary was built with support for modular feature "portmapper debug support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debugportmapper" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebugPortMapper = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_enabled.go new file mode 100644 index 0000000..491aa5e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_debugportmapper_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_debugportmapper + +package buildfeatures + +// HasDebugPortMapper is whether the binary was built with support for modular feature "portmapper debug support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_debugportmapper" build tag. +// It's a const so it can be used for dead code elimination. +const HasDebugPortMapper = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_disabled.go new file mode 100644 index 0000000..1536c88 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_desktop_sessions + +package buildfeatures + +// HasDesktopSessions is whether the binary was built with support for modular feature "Desktop sessions support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_desktop_sessions" build tag. +// It's a const so it can be used for dead code elimination. +const HasDesktopSessions = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_enabled.go new file mode 100644 index 0000000..84658de --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_desktop_sessions_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_desktop_sessions + +package buildfeatures + +// HasDesktopSessions is whether the binary was built with support for modular feature "Desktop sessions support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_desktop_sessions" build tag. +// It's a const so it can be used for dead code elimination. +const HasDesktopSessions = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_dns_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_dns_disabled.go new file mode 100644 index 0000000..30d7379 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_dns_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_dns + +package buildfeatures + +// HasDNS is whether the binary was built with support for modular feature "MagicDNS and system DNS configuration support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_dns" build tag. +// It's a const so it can be used for dead code elimination. +const HasDNS = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_dns_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_dns_enabled.go new file mode 100644 index 0000000..962f259 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_dns_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_dns + +package buildfeatures + +// HasDNS is whether the binary was built with support for modular feature "MagicDNS and system DNS configuration support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_dns" build tag. +// It's a const so it can be used for dead code elimination. +const HasDNS = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_doctor_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_doctor_disabled.go new file mode 100644 index 0000000..8c15e95 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_doctor_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_doctor + +package buildfeatures + +// HasDoctor is whether the binary was built with support for modular feature "Diagnose possible issues with Tailscale and its host environment". +// Specifically, it's whether the binary was NOT built with the "ts_omit_doctor" build tag. +// It's a const so it can be used for dead code elimination. +const HasDoctor = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_doctor_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_doctor_enabled.go new file mode 100644 index 0000000..a8a0bb7 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_doctor_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_doctor + +package buildfeatures + +// HasDoctor is whether the binary was built with support for modular feature "Diagnose possible issues with Tailscale and its host environment". +// Specifically, it's whether the binary was NOT built with the "ts_omit_doctor" build tag. +// It's a const so it can be used for dead code elimination. +const HasDoctor = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_drive_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_drive_disabled.go new file mode 100644 index 0000000..0720263 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_drive_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_drive + +package buildfeatures + +// HasDrive is whether the binary was built with support for modular feature "Tailscale Drive (file server) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_drive" build tag. +// It's a const so it can be used for dead code elimination. +const HasDrive = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_drive_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_drive_enabled.go new file mode 100644 index 0000000..9f58836 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_drive_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_drive + +package buildfeatures + +// HasDrive is whether the binary was built with support for modular feature "Tailscale Drive (file server) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_drive" build tag. +// It's a const so it can be used for dead code elimination. +const HasDrive = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_gro_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_gro_disabled.go new file mode 100644 index 0000000..ffbd0da --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_gro_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_gro + +package buildfeatures + +// HasGRO is whether the binary was built with support for modular feature "Generic Receive Offload support (performance)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_gro" build tag. +// It's a const so it can be used for dead code elimination. +const HasGRO = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_gro_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_gro_enabled.go new file mode 100644 index 0000000..e2c8024 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_gro_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_gro + +package buildfeatures + +// HasGRO is whether the binary was built with support for modular feature "Generic Receive Offload support (performance)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_gro" build tag. +// It's a const so it can be used for dead code elimination. +const HasGRO = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_health_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_health_disabled.go new file mode 100644 index 0000000..2f2bcf2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_health_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_health + +package buildfeatures + +// HasHealth is whether the binary was built with support for modular feature "Health checking support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_health" build tag. +// It's a const so it can be used for dead code elimination. +const HasHealth = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_health_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_health_enabled.go new file mode 100644 index 0000000..00ce368 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_health_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_health + +package buildfeatures + +// HasHealth is whether the binary was built with support for modular feature "Health checking support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_health" build tag. +// It's a const so it can be used for dead code elimination. +const HasHealth = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_disabled.go new file mode 100644 index 0000000..cee076b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_hujsonconf + +package buildfeatures + +// HasHuJSONConf is whether the binary was built with support for modular feature "HuJSON config file support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_hujsonconf" build tag. +// It's a const so it can be used for dead code elimination. +const HasHuJSONConf = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_enabled.go new file mode 100644 index 0000000..aefeeac --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_hujsonconf_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_hujsonconf + +package buildfeatures + +// HasHuJSONConf is whether the binary was built with support for modular feature "HuJSON config file support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_hujsonconf" build tag. +// It's a const so it can be used for dead code elimination. +const HasHuJSONConf = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_disabled.go new file mode 100644 index 0000000..94488ad --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_identityfederation + +package buildfeatures + +// HasIdentityFederation is whether the binary was built with support for modular feature "Auth key generation via identity federation support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_identityfederation" build tag. +// It's a const so it can be used for dead code elimination. +const HasIdentityFederation = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_enabled.go new file mode 100644 index 0000000..892d62d --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_identityfederation_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_identityfederation + +package buildfeatures + +// HasIdentityFederation is whether the binary was built with support for modular feature "Auth key generation via identity federation support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_identityfederation" build tag. +// It's a const so it can be used for dead code elimination. +const HasIdentityFederation = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_iptables_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_iptables_disabled.go new file mode 100644 index 0000000..8cda5be --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_iptables_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_iptables + +package buildfeatures + +// HasIPTables is whether the binary was built with support for modular feature "Linux iptables support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_iptables" build tag. +// It's a const so it can be used for dead code elimination. +const HasIPTables = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_iptables_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_iptables_enabled.go new file mode 100644 index 0000000..44d9847 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_iptables_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_iptables + +package buildfeatures + +// HasIPTables is whether the binary was built with support for modular feature "Linux iptables support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_iptables" build tag. +// It's a const so it can be used for dead code elimination. +const HasIPTables = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_kube_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_kube_disabled.go new file mode 100644 index 0000000..2b76c57 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_kube_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_kube + +package buildfeatures + +// HasKube is whether the binary was built with support for modular feature "Kubernetes integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_kube" build tag. +// It's a const so it can be used for dead code elimination. +const HasKube = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_kube_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_kube_enabled.go new file mode 100644 index 0000000..7abca17 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_kube_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_kube + +package buildfeatures + +// HasKube is whether the binary was built with support for modular feature "Kubernetes integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_kube" build tag. +// It's a const so it can be used for dead code elimination. +const HasKube = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_disabled.go new file mode 100644 index 0000000..ce81d80 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_lazywg + +package buildfeatures + +// HasLazyWG is whether the binary was built with support for modular feature "Lazy WireGuard configuration for memory-constrained devices with large netmaps". +// Specifically, it's whether the binary was NOT built with the "ts_omit_lazywg" build tag. +// It's a const so it can be used for dead code elimination. +const HasLazyWG = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_enabled.go new file mode 100644 index 0000000..259357f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_lazywg_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_lazywg + +package buildfeatures + +// HasLazyWG is whether the binary was built with support for modular feature "Lazy WireGuard configuration for memory-constrained devices with large netmaps". +// Specifically, it's whether the binary was NOT built with the "ts_omit_lazywg" build tag. +// It's a const so it can be used for dead code elimination. +const HasLazyWG = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_disabled.go new file mode 100644 index 0000000..19e254a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_linkspeed + +package buildfeatures + +// HasLinkSpeed is whether the binary was built with support for modular feature "Set link speed on TUN device for better OS integration (Linux only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_linkspeed" build tag. +// It's a const so it can be used for dead code elimination. +const HasLinkSpeed = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_enabled.go new file mode 100644 index 0000000..939858a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_linkspeed_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_linkspeed + +package buildfeatures + +// HasLinkSpeed is whether the binary was built with support for modular feature "Set link speed on TUN device for better OS integration (Linux only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_linkspeed" build tag. +// It's a const so it can be used for dead code elimination. +const HasLinkSpeed = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_disabled.go new file mode 100644 index 0000000..2e5b50e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_linuxdnsfight + +package buildfeatures + +// HasLinuxDNSFight is whether the binary was built with support for modular feature "Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_linuxdnsfight" build tag. +// It's a const so it can be used for dead code elimination. +const HasLinuxDNSFight = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_enabled.go new file mode 100644 index 0000000..b9419fc --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_linuxdnsfight_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_linuxdnsfight + +package buildfeatures + +// HasLinuxDNSFight is whether the binary was built with support for modular feature "Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_linuxdnsfight" build tag. +// It's a const so it can be used for dead code elimination. +const HasLinuxDNSFight = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_disabled.go new file mode 100644 index 0000000..2911780 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_listenrawdisco + +package buildfeatures + +// HasListenRawDisco is whether the binary was built with support for modular feature "Use raw sockets for more robust disco (NAT traversal) message receiving (Linux only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_listenrawdisco" build tag. +// It's a const so it can be used for dead code elimination. +const HasListenRawDisco = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_enabled.go new file mode 100644 index 0000000..4a4f85a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_listenrawdisco_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_listenrawdisco + +package buildfeatures + +// HasListenRawDisco is whether the binary was built with support for modular feature "Use raw sockets for more robust disco (NAT traversal) message receiving (Linux only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_listenrawdisco" build tag. +// It's a const so it can be used for dead code elimination. +const HasListenRawDisco = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_logtail_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_logtail_disabled.go new file mode 100644 index 0000000..140092a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_logtail_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_logtail + +package buildfeatures + +// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag. +// It's a const so it can be used for dead code elimination. +const HasLogTail = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_logtail_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_logtail_enabled.go new file mode 100644 index 0000000..6e77721 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_logtail_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_logtail + +package buildfeatures + +// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag. +// It's a const so it can be used for dead code elimination. +const HasLogTail = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_netlog_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_netlog_disabled.go new file mode 100644 index 0000000..60367a1 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_netlog_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_netlog + +package buildfeatures + +// HasNetLog is whether the binary was built with support for modular feature "Network flow logging support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_netlog" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetLog = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_netlog_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_netlog_enabled.go new file mode 100644 index 0000000..f9d2aba --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_netlog_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_netlog + +package buildfeatures + +// HasNetLog is whether the binary was built with support for modular feature "Network flow logging support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_netlog" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetLog = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_netstack_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_netstack_disabled.go new file mode 100644 index 0000000..acb6e8e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_netstack_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_netstack + +package buildfeatures + +// HasNetstack is whether the binary was built with support for modular feature "gVisor netstack (userspace networking) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_netstack" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetstack = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_netstack_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_netstack_enabled.go new file mode 100644 index 0000000..04f6711 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_netstack_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_netstack + +package buildfeatures + +// HasNetstack is whether the binary was built with support for modular feature "gVisor netstack (userspace networking) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_netstack" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetstack = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_disabled.go new file mode 100644 index 0000000..d0ec6f0 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_networkmanager + +package buildfeatures + +// HasNetworkManager is whether the binary was built with support for modular feature "Linux NetworkManager integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_networkmanager" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetworkManager = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_enabled.go new file mode 100644 index 0000000..ec284c3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_networkmanager_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_networkmanager + +package buildfeatures + +// HasNetworkManager is whether the binary was built with support for modular feature "Linux NetworkManager integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_networkmanager" build tag. +// It's a const so it can be used for dead code elimination. +const HasNetworkManager = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_disabled.go new file mode 100644 index 0000000..72ad172 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_oauthkey + +package buildfeatures + +// HasOAuthKey is whether the binary was built with support for modular feature "OAuth secret-to-authkey resolution support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_oauthkey" build tag. +// It's a const so it can be used for dead code elimination. +const HasOAuthKey = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_enabled.go new file mode 100644 index 0000000..39c52a2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_oauthkey_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_oauthkey + +package buildfeatures + +// HasOAuthKey is whether the binary was built with support for modular feature "OAuth secret-to-authkey resolution support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_oauthkey" build tag. +// It's a const so it can be used for dead code elimination. +const HasOAuthKey = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_disabled.go new file mode 100644 index 0000000..ccd7192 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_osrouter + +package buildfeatures + +// HasOSRouter is whether the binary was built with support for modular feature "Configure the operating system's network stack, IPs, and routing tables". +// Specifically, it's whether the binary was NOT built with the "ts_omit_osrouter" build tag. +// It's a const so it can be used for dead code elimination. +const HasOSRouter = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_enabled.go new file mode 100644 index 0000000..a5dacc5 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_osrouter_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_osrouter + +package buildfeatures + +// HasOSRouter is whether the binary was built with support for modular feature "Configure the operating system's network stack, IPs, and routing tables". +// Specifically, it's whether the binary was NOT built with the "ts_omit_osrouter" build tag. +// It's a const so it can be used for dead code elimination. +const HasOSRouter = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_disabled.go new file mode 100644 index 0000000..bf74db0 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_outboundproxy + +package buildfeatures + +// HasOutboundProxy is whether the binary was built with support for modular feature "Support running an outbound localhost HTTP/SOCK5 proxy support that sends traffic over Tailscale". +// Specifically, it's whether the binary was NOT built with the "ts_omit_outboundproxy" build tag. +// It's a const so it can be used for dead code elimination. +const HasOutboundProxy = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_enabled.go new file mode 100644 index 0000000..53bb99d --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_outboundproxy_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_outboundproxy + +package buildfeatures + +// HasOutboundProxy is whether the binary was built with support for modular feature "Support running an outbound localhost HTTP/SOCK5 proxy support that sends traffic over Tailscale". +// Specifically, it's whether the binary was NOT built with the "ts_omit_outboundproxy" build tag. +// It's a const so it can be used for dead code elimination. +const HasOutboundProxy = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_disabled.go new file mode 100644 index 0000000..83cc2bd --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_peerapiclient + +package buildfeatures + +// HasPeerAPIClient is whether the binary was built with support for modular feature "PeerAPI client support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_peerapiclient" build tag. +// It's a const so it can be used for dead code elimination. +const HasPeerAPIClient = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_enabled.go new file mode 100644 index 0000000..0bd3f50 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiclient_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_peerapiclient + +package buildfeatures + +// HasPeerAPIClient is whether the binary was built with support for modular feature "PeerAPI client support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_peerapiclient" build tag. +// It's a const so it can be used for dead code elimination. +const HasPeerAPIClient = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_disabled.go new file mode 100644 index 0000000..4a4f32b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_peerapiserver + +package buildfeatures + +// HasPeerAPIServer is whether the binary was built with support for modular feature "PeerAPI server support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_peerapiserver" build tag. +// It's a const so it can be used for dead code elimination. +const HasPeerAPIServer = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_enabled.go new file mode 100644 index 0000000..17d0547 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_peerapiserver_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_peerapiserver + +package buildfeatures + +// HasPeerAPIServer is whether the binary was built with support for modular feature "PeerAPI server support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_peerapiserver" build tag. +// It's a const so it can be used for dead code elimination. +const HasPeerAPIServer = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_portlist_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_portlist_disabled.go new file mode 100644 index 0000000..934061f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_portlist_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_portlist + +package buildfeatures + +// HasPortList is whether the binary was built with support for modular feature "Optionally advertise listening service ports". +// Specifically, it's whether the binary was NOT built with the "ts_omit_portlist" build tag. +// It's a const so it can be used for dead code elimination. +const HasPortList = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_portlist_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_portlist_enabled.go new file mode 100644 index 0000000..c1dc1c1 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_portlist_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_portlist + +package buildfeatures + +// HasPortList is whether the binary was built with support for modular feature "Optionally advertise listening service ports". +// Specifically, it's whether the binary was NOT built with the "ts_omit_portlist" build tag. +// It's a const so it can be used for dead code elimination. +const HasPortList = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_disabled.go new file mode 100644 index 0000000..212b22d --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_portmapper + +package buildfeatures + +// HasPortMapper is whether the binary was built with support for modular feature "NAT-PMP/PCP/UPnP port mapping support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_portmapper" build tag. +// It's a const so it can be used for dead code elimination. +const HasPortMapper = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_enabled.go new file mode 100644 index 0000000..2f915d2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_portmapper_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_portmapper + +package buildfeatures + +// HasPortMapper is whether the binary was built with support for modular feature "NAT-PMP/PCP/UPnP port mapping support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_portmapper" build tag. +// It's a const so it can be used for dead code elimination. +const HasPortMapper = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_posture_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_posture_disabled.go new file mode 100644 index 0000000..a78b1a9 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_posture_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_posture + +package buildfeatures + +// HasPosture is whether the binary was built with support for modular feature "Device posture checking support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_posture" build tag. +// It's a const so it can be used for dead code elimination. +const HasPosture = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_posture_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_posture_enabled.go new file mode 100644 index 0000000..dcd9595 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_posture_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_posture + +package buildfeatures + +// HasPosture is whether the binary was built with support for modular feature "Device posture checking support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_posture" build tag. +// It's a const so it can be used for dead code elimination. +const HasPosture = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_disabled.go new file mode 100644 index 0000000..4b99250 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_qrcodes + +package buildfeatures + +// HasQRCodes is whether the binary was built with support for modular feature "QR codes in tailscale CLI". +// Specifically, it's whether the binary was NOT built with the "ts_omit_qrcodes" build tag. +// It's a const so it can be used for dead code elimination. +const HasQRCodes = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_enabled.go new file mode 100644 index 0000000..5b74e2b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_qrcodes_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_qrcodes + +package buildfeatures + +// HasQRCodes is whether the binary was built with support for modular feature "QR codes in tailscale CLI". +// Specifically, it's whether the binary was NOT built with the "ts_omit_qrcodes" build tag. +// It's a const so it can be used for dead code elimination. +const HasQRCodes = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_disabled.go new file mode 100644 index 0000000..08ced83 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_relayserver + +package buildfeatures + +// HasRelayServer is whether the binary was built with support for modular feature "Relay server". +// Specifically, it's whether the binary was NOT built with the "ts_omit_relayserver" build tag. +// It's a const so it can be used for dead code elimination. +const HasRelayServer = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_enabled.go new file mode 100644 index 0000000..6a35f83 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_relayserver_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_relayserver + +package buildfeatures + +// HasRelayServer is whether the binary was built with support for modular feature "Relay server". +// Specifically, it's whether the binary was NOT built with the "ts_omit_relayserver" build tag. +// It's a const so it can be used for dead code elimination. +const HasRelayServer = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_resolved_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_resolved_disabled.go new file mode 100644 index 0000000..283dd20 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_resolved_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_resolved + +package buildfeatures + +// HasResolved is whether the binary was built with support for modular feature "Linux systemd-resolved integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_resolved" build tag. +// It's a const so it can be used for dead code elimination. +const HasResolved = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_resolved_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_resolved_enabled.go new file mode 100644 index 0000000..af1b3b4 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_resolved_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_resolved + +package buildfeatures + +// HasResolved is whether the binary was built with support for modular feature "Linux systemd-resolved integration". +// Specifically, it's whether the binary was NOT built with the "ts_omit_resolved" build tag. +// It's a const so it can be used for dead code elimination. +const HasResolved = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_disabled.go new file mode 100644 index 0000000..7efa2d2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_sdnotify + +package buildfeatures + +// HasSDNotify is whether the binary was built with support for modular feature "systemd notification support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_sdnotify" build tag. +// It's a const so it can be used for dead code elimination. +const HasSDNotify = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_enabled.go new file mode 100644 index 0000000..40fec97 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_sdnotify_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_sdnotify + +package buildfeatures + +// HasSDNotify is whether the binary was built with support for modular feature "systemd notification support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_sdnotify" build tag. +// It's a const so it can be used for dead code elimination. +const HasSDNotify = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_serve_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_serve_disabled.go new file mode 100644 index 0000000..6d79713 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_serve_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_serve + +package buildfeatures + +// HasServe is whether the binary was built with support for modular feature "Serve and Funnel support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_serve" build tag. +// It's a const so it can be used for dead code elimination. +const HasServe = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_serve_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_serve_enabled.go new file mode 100644 index 0000000..57bf2c6 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_serve_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_serve + +package buildfeatures + +// HasServe is whether the binary was built with support for modular feature "Serve and Funnel support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_serve" build tag. +// It's a const so it can be used for dead code elimination. +const HasServe = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_ssh_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_ssh_disabled.go new file mode 100644 index 0000000..754f50e --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_ssh_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_ssh + +package buildfeatures + +// HasSSH is whether the binary was built with support for modular feature "Tailscale SSH support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_ssh" build tag. +// It's a const so it can be used for dead code elimination. +const HasSSH = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_ssh_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_ssh_enabled.go new file mode 100644 index 0000000..dbdc3a8 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_ssh_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_ssh + +package buildfeatures + +// HasSSH is whether the binary was built with support for modular feature "Tailscale SSH support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_ssh" build tag. +// It's a const so it can be used for dead code elimination. +const HasSSH = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_synology_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_synology_disabled.go new file mode 100644 index 0000000..0cdf084 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_synology_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_synology + +package buildfeatures + +// HasSynology is whether the binary was built with support for modular feature "Synology NAS integration (applies to Linux builds only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_synology" build tag. +// It's a const so it can be used for dead code elimination. +const HasSynology = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_synology_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_synology_enabled.go new file mode 100644 index 0000000..dde4123 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_synology_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_synology + +package buildfeatures + +// HasSynology is whether the binary was built with support for modular feature "Synology NAS integration (applies to Linux builds only)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_synology" build tag. +// It's a const so it can be used for dead code elimination. +const HasSynology = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_disabled.go new file mode 100644 index 0000000..54d32e3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_syspolicy + +package buildfeatures + +// HasSystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag. +// It's a const so it can be used for dead code elimination. +const HasSystemPolicy = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_enabled.go new file mode 100644 index 0000000..f7c403a --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_syspolicy_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_syspolicy + +package buildfeatures + +// HasSystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag. +// It's a const so it can be used for dead code elimination. +const HasSystemPolicy = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_systray_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_systray_disabled.go new file mode 100644 index 0000000..4ae1edb --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_systray_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_systray + +package buildfeatures + +// HasSysTray is whether the binary was built with support for modular feature "Linux system tray". +// Specifically, it's whether the binary was NOT built with the "ts_omit_systray" build tag. +// It's a const so it can be used for dead code elimination. +const HasSysTray = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_systray_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_systray_enabled.go new file mode 100644 index 0000000..5fd7fd2 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_systray_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_systray + +package buildfeatures + +// HasSysTray is whether the binary was built with support for modular feature "Linux system tray". +// Specifically, it's whether the binary was NOT built with the "ts_omit_systray" build tag. +// It's a const so it can be used for dead code elimination. +const HasSysTray = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_disabled.go new file mode 100644 index 0000000..8ffe906 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_taildrop + +package buildfeatures + +// HasTaildrop is whether the binary was built with support for modular feature "Taildrop (file sending) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_taildrop" build tag. +// It's a const so it can be used for dead code elimination. +const HasTaildrop = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_enabled.go new file mode 100644 index 0000000..4f55d28 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_taildrop_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_taildrop + +package buildfeatures + +// HasTaildrop is whether the binary was built with support for modular feature "Taildrop (file sending) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_taildrop" build tag. +// It's a const so it can be used for dead code elimination. +const HasTaildrop = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_disabled.go new file mode 100644 index 0000000..6b5a57f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_tailnetlock + +package buildfeatures + +// HasTailnetLock is whether the binary was built with support for modular feature "Tailnet Lock support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tailnetlock" build tag. +// It's a const so it can be used for dead code elimination. +const HasTailnetLock = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_enabled.go new file mode 100644 index 0000000..afedb7f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tailnetlock_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_tailnetlock + +package buildfeatures + +// HasTailnetLock is whether the binary was built with support for modular feature "Tailnet Lock support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tailnetlock" build tag. +// It's a const so it can be used for dead code elimination. +const HasTailnetLock = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tap_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tap_disabled.go new file mode 100644 index 0000000..f0b3eec --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tap_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_tap + +package buildfeatures + +// HasTap is whether the binary was built with support for modular feature "Experimental Layer 2 (ethernet) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tap" build tag. +// It's a const so it can be used for dead code elimination. +const HasTap = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tap_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tap_enabled.go new file mode 100644 index 0000000..1363c4b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tap_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_tap + +package buildfeatures + +// HasTap is whether the binary was built with support for modular feature "Experimental Layer 2 (ethernet) support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tap" build tag. +// It's a const so it can be used for dead code elimination. +const HasTap = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tpm_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tpm_disabled.go new file mode 100644 index 0000000..b9d5581 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tpm_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_tpm + +package buildfeatures + +// HasTPM is whether the binary was built with support for modular feature "TPM support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tpm" build tag. +// It's a const so it can be used for dead code elimination. +const HasTPM = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_tpm_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_tpm_enabled.go new file mode 100644 index 0000000..dcfc8a3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_tpm_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_tpm + +package buildfeatures + +// HasTPM is whether the binary was built with support for modular feature "TPM support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_tpm" build tag. +// It's a const so it can be used for dead code elimination. +const HasTPM = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_disabled.go new file mode 100644 index 0000000..d64e48b --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_unixsocketidentity + +package buildfeatures + +// HasUnixSocketIdentity is whether the binary was built with support for modular feature "differentiate between users accessing the LocalAPI over unix sockets (if omitted, all users have full access)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_unixsocketidentity" build tag. +// It's a const so it can be used for dead code elimination. +const HasUnixSocketIdentity = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_enabled.go new file mode 100644 index 0000000..463ac2c --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_unixsocketidentity_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_unixsocketidentity + +package buildfeatures + +// HasUnixSocketIdentity is whether the binary was built with support for modular feature "differentiate between users accessing the LocalAPI over unix sockets (if omitted, all users have full access)". +// Specifically, it's whether the binary was NOT built with the "ts_omit_unixsocketidentity" build tag. +// It's a const so it can be used for dead code elimination. +const HasUnixSocketIdentity = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_disabled.go new file mode 100644 index 0000000..51bec80 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_useexitnode + +package buildfeatures + +// HasUseExitNode is whether the binary was built with support for modular feature "Use exit nodes". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useexitnode" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseExitNode = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_enabled.go new file mode 100644 index 0000000..f7ab414 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useexitnode_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_useexitnode + +package buildfeatures + +// HasUseExitNode is whether the binary was built with support for modular feature "Use exit nodes". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useexitnode" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseExitNode = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_disabled.go new file mode 100644 index 0000000..9f29a98 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_useproxy + +package buildfeatures + +// HasUseProxy is whether the binary was built with support for modular feature "Support using system proxies as specified by env vars or the system configuration to reach Tailscale servers.". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useproxy" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseProxy = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_enabled.go new file mode 100644 index 0000000..9195f2f --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useproxy_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_useproxy + +package buildfeatures + +// HasUseProxy is whether the binary was built with support for modular feature "Support using system proxies as specified by env vars or the system configuration to reach Tailscale servers.". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useproxy" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseProxy = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_disabled.go new file mode 100644 index 0000000..092c89c --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_usermetrics + +package buildfeatures + +// HasUserMetrics is whether the binary was built with support for modular feature "Usermetrics (documented, stable) metrics support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_usermetrics" build tag. +// It's a const so it can be used for dead code elimination. +const HasUserMetrics = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_enabled.go new file mode 100644 index 0000000..813e3c3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_usermetrics_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_usermetrics + +package buildfeatures + +// HasUserMetrics is whether the binary was built with support for modular feature "Usermetrics (documented, stable) metrics support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_usermetrics" build tag. +// It's a const so it can be used for dead code elimination. +const HasUserMetrics = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_disabled.go new file mode 100644 index 0000000..ecf9d02 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_useroutes + +package buildfeatures + +// HasUseRoutes is whether the binary was built with support for modular feature "Use routes advertised by other nodes". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useroutes" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseRoutes = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_enabled.go new file mode 100644 index 0000000..c0a5932 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_useroutes_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_useroutes + +package buildfeatures + +// HasUseRoutes is whether the binary was built with support for modular feature "Use routes advertised by other nodes". +// Specifically, it's whether the binary was NOT built with the "ts_omit_useroutes" build tag. +// It's a const so it can be used for dead code elimination. +const HasUseRoutes = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_disabled.go new file mode 100644 index 0000000..816ac66 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_wakeonlan + +package buildfeatures + +// HasWakeOnLAN is whether the binary was built with support for modular feature "Wake-on-LAN support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_wakeonlan" build tag. +// It's a const so it can be used for dead code elimination. +const HasWakeOnLAN = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_enabled.go new file mode 100644 index 0000000..34b3348 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_wakeonlan_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_wakeonlan + +package buildfeatures + +// HasWakeOnLAN is whether the binary was built with support for modular feature "Wake-on-LAN support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_wakeonlan" build tag. +// It's a const so it can be used for dead code elimination. +const HasWakeOnLAN = true diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_webclient_disabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_webclient_disabled.go new file mode 100644 index 0000000..a7b24f4 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_webclient_disabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build ts_omit_webclient + +package buildfeatures + +// HasWebClient is whether the binary was built with support for modular feature "Web client support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag. +// It's a const so it can be used for dead code elimination. +const HasWebClient = false diff --git a/vendor/tailscale.com/feature/buildfeatures/feature_webclient_enabled.go b/vendor/tailscale.com/feature/buildfeatures/feature_webclient_enabled.go new file mode 100644 index 0000000..e40dad3 --- /dev/null +++ b/vendor/tailscale.com/feature/buildfeatures/feature_webclient_enabled.go @@ -0,0 +1,13 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by gen.go; DO NOT EDIT. + +//go:build !ts_omit_webclient + +package buildfeatures + +// HasWebClient is whether the binary was built with support for modular feature "Web client support". +// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag. +// It's a const so it can be used for dead code elimination. +const HasWebClient = true diff --git a/vendor/tailscale.com/feature/c2n/c2n.go b/vendor/tailscale.com/feature/c2n/c2n.go new file mode 100644 index 0000000..ae942e3 --- /dev/null +++ b/vendor/tailscale.com/feature/c2n/c2n.go @@ -0,0 +1,70 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package c2n registers support for C2N (Control-to-Node) communications. +package c2n + +import ( + "bufio" + "bytes" + "context" + "net/http" + "time" + + "tailscale.com/control/controlclient" + "tailscale.com/tailcfg" + "tailscale.com/tempfork/httprec" + "tailscale.com/types/logger" +) + +func init() { + controlclient.HookAnswerC2NPing.Set(answerC2NPing) +} + +func answerC2NPing(logf logger.Logf, c2nHandler http.Handler, c *http.Client, pr *tailcfg.PingRequest) { + if c2nHandler == nil { + logf("answerC2NPing: c2nHandler not defined") + return + } + hreq, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(pr.Payload))) + if err != nil { + logf("answerC2NPing: ReadRequest: %v", err) + return + } + if pr.Log { + logf("answerC2NPing: got c2n request for %v ...", hreq.RequestURI) + } + handlerTimeout := time.Minute + if v := hreq.Header.Get("C2n-Handler-Timeout"); v != "" { + handlerTimeout, _ = time.ParseDuration(v) + } + handlerCtx, cancel := context.WithTimeout(context.Background(), handlerTimeout) + defer cancel() + hreq = hreq.WithContext(handlerCtx) + rec := httprec.NewRecorder() + c2nHandler.ServeHTTP(rec, hreq) + cancel() + + c2nResBuf := new(bytes.Buffer) + rec.Result().Write(c2nResBuf) + + replyCtx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + req, err := http.NewRequestWithContext(replyCtx, "POST", pr.URL, c2nResBuf) + if err != nil { + logf("answerC2NPing: NewRequestWithContext: %v", err) + return + } + if pr.Log { + logf("answerC2NPing: sending POST ping to %v ...", pr.URL) + } + t0 := time.Now() + _, err = c.Do(req) + d := time.Since(t0).Round(time.Millisecond) + if err != nil { + logf("answerC2NPing error: %v to %v (after %v)", err, pr.URL, d) + } else if pr.Log { + logf("answerC2NPing complete to %v (after %v)", pr.URL, d) + } +} diff --git a/vendor/tailscale.com/feature/capture/capture.go b/vendor/tailscale.com/feature/capture/capture.go deleted file mode 100644 index e5e150d..0000000 --- a/vendor/tailscale.com/feature/capture/capture.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package capture formats packet logging into a debug pcap stream. -package capture - -import ( - "bytes" - "context" - "encoding/binary" - "io" - "net/http" - "sync" - "time" - - "tailscale.com/feature" - "tailscale.com/ipn/localapi" - "tailscale.com/net/packet" - "tailscale.com/util/set" -) - -func init() { - feature.Register("capture") - localapi.Register("debug-capture", serveLocalAPIDebugCapture) -} - -func serveLocalAPIDebugCapture(h *localapi.Handler, w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - if r.Method != "POST" { - http.Error(w, "POST required", http.StatusMethodNotAllowed) - return - } - - w.WriteHeader(http.StatusOK) - w.(http.Flusher).Flush() - - b := h.LocalBackend() - s := b.GetOrSetCaptureSink(newSink) - - unregister := s.RegisterOutput(w) - - select { - case <-ctx.Done(): - case <-s.WaitCh(): - } - unregister() - - b.ClearCaptureSink() -} - -var bufferPool = sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, -} - -const flushPeriod = 100 * time.Millisecond - -func writePcapHeader(w io.Writer) { - binary.Write(w, binary.LittleEndian, uint32(0xA1B2C3D4)) // pcap magic number - binary.Write(w, binary.LittleEndian, uint16(2)) // version major - binary.Write(w, binary.LittleEndian, uint16(4)) // version minor - binary.Write(w, binary.LittleEndian, uint32(0)) // this zone - binary.Write(w, binary.LittleEndian, uint32(0)) // zone significant figures - binary.Write(w, binary.LittleEndian, uint32(65535)) // max packet len - binary.Write(w, binary.LittleEndian, uint32(147)) // link-layer ID - USER0 -} - -func writePktHeader(w *bytes.Buffer, when time.Time, length int) { - s := when.Unix() - us := when.UnixMicro() - (s * 1000000) - - binary.Write(w, binary.LittleEndian, uint32(s)) // timestamp in seconds - binary.Write(w, binary.LittleEndian, uint32(us)) // timestamp microseconds - binary.Write(w, binary.LittleEndian, uint32(length)) // length present - binary.Write(w, binary.LittleEndian, uint32(length)) // total length -} - -// newSink creates a new capture sink. -func newSink() packet.CaptureSink { - ctx, c := context.WithCancel(context.Background()) - return &Sink{ - ctx: ctx, - ctxCancel: c, - } -} - -// Type Sink handles callbacks with packets to be logged, -// formatting them into a pcap stream which is mirrored to -// all registered outputs. -type Sink struct { - ctx context.Context - ctxCancel context.CancelFunc - - mu sync.Mutex - outputs set.HandleSet[io.Writer] - flushTimer *time.Timer // or nil if none running -} - -// RegisterOutput connects an output to this sink, which -// will be written to with a pcap stream as packets are logged. -// A function is returned which unregisters the output when -// called. -// -// If w implements io.Closer, it will be closed upon error -// or when the sink is closed. If w implements http.Flusher, -// it will be flushed periodically. -func (s *Sink) RegisterOutput(w io.Writer) (unregister func()) { - select { - case <-s.ctx.Done(): - return func() {} - default: - } - - writePcapHeader(w) - s.mu.Lock() - hnd := s.outputs.Add(w) - s.mu.Unlock() - - return func() { - s.mu.Lock() - defer s.mu.Unlock() - delete(s.outputs, hnd) - } -} - -func (s *Sink) CaptureCallback() packet.CaptureCallback { - return s.LogPacket -} - -// NumOutputs returns the number of outputs registered with the sink. -func (s *Sink) NumOutputs() int { - s.mu.Lock() - defer s.mu.Unlock() - return len(s.outputs) -} - -// Close shuts down the sink. Future calls to LogPacket -// are ignored, and any registered output that implements -// io.Closer is closed. -func (s *Sink) Close() error { - s.ctxCancel() - s.mu.Lock() - defer s.mu.Unlock() - if s.flushTimer != nil { - s.flushTimer.Stop() - s.flushTimer = nil - } - - for _, o := range s.outputs { - if o, ok := o.(io.Closer); ok { - o.Close() - } - } - s.outputs = nil - return nil -} - -// WaitCh returns a channel which blocks until -// the sink is closed. -func (s *Sink) WaitCh() <-chan struct{} { - return s.ctx.Done() -} - -func customDataLen(meta packet.CaptureMeta) int { - length := 4 - if meta.DidSNAT { - length += meta.OriginalSrc.Addr().BitLen() / 8 - } - if meta.DidDNAT { - length += meta.OriginalDst.Addr().BitLen() / 8 - } - return length -} - -// LogPacket is called to insert a packet into the capture. -// -// This function does not take ownership of the provided data slice. -func (s *Sink) LogPacket(path packet.CapturePath, when time.Time, data []byte, meta packet.CaptureMeta) { - select { - case <-s.ctx.Done(): - return - default: - } - - extraLen := customDataLen(meta) - b := bufferPool.Get().(*bytes.Buffer) - b.Reset() - b.Grow(16 + extraLen + len(data)) // 16b pcap header + len(metadata) + len(payload) - defer bufferPool.Put(b) - - writePktHeader(b, when, len(data)+extraLen) - - // Custom tailscale debugging data - binary.Write(b, binary.LittleEndian, uint16(path)) - if meta.DidSNAT { - binary.Write(b, binary.LittleEndian, uint8(meta.OriginalSrc.Addr().BitLen()/8)) - b.Write(meta.OriginalSrc.Addr().AsSlice()) - } else { - binary.Write(b, binary.LittleEndian, uint8(0)) // SNAT addr len == 0 - } - if meta.DidDNAT { - binary.Write(b, binary.LittleEndian, uint8(meta.OriginalDst.Addr().BitLen()/8)) - b.Write(meta.OriginalDst.Addr().AsSlice()) - } else { - binary.Write(b, binary.LittleEndian, uint8(0)) // DNAT addr len == 0 - } - - b.Write(data) - - s.mu.Lock() - defer s.mu.Unlock() - - var hadError []set.Handle - for hnd, o := range s.outputs { - if _, err := o.Write(b.Bytes()); err != nil { - hadError = append(hadError, hnd) - continue - } - } - for _, hnd := range hadError { - if o, ok := s.outputs[hnd].(io.Closer); ok { - o.Close() - } - delete(s.outputs, hnd) - } - - if s.flushTimer == nil { - s.flushTimer = time.AfterFunc(flushPeriod, func() { - s.mu.Lock() - defer s.mu.Unlock() - for _, o := range s.outputs { - if f, ok := o.(http.Flusher); ok { - f.Flush() - } - } - s.flushTimer = nil - }) - } -} diff --git a/vendor/tailscale.com/feature/condlite/expvar/expvar.go b/vendor/tailscale.com/feature/condlite/expvar/expvar.go new file mode 100644 index 0000000..edc16ac --- /dev/null +++ b/vendor/tailscale.com/feature/condlite/expvar/expvar.go @@ -0,0 +1,12 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !(ts_omit_debug && ts_omit_clientmetrics && ts_omit_usermetrics) + +// Package expvar contains type aliases for expvar types, to allow conditionally +// excluding the package from builds. +package expvar + +import "expvar" + +type Int = expvar.Int diff --git a/vendor/tailscale.com/feature/condlite/expvar/omit.go b/vendor/tailscale.com/feature/condlite/expvar/omit.go new file mode 100644 index 0000000..a21d94d --- /dev/null +++ b/vendor/tailscale.com/feature/condlite/expvar/omit.go @@ -0,0 +1,11 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_debug && ts_omit_clientmetrics && ts_omit_usermetrics + +// excluding the package from builds. +package expvar + +type Int int64 + +func (*Int) Add(int64) {} diff --git a/vendor/tailscale.com/feature/condregister/condregister.go b/vendor/tailscale.com/feature/condregister/condregister.go deleted file mode 100644 index f902509..0000000 --- a/vendor/tailscale.com/feature/condregister/condregister.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// The condregister package registers all conditional features guarded -// by build tags. It is one central package that callers can empty import -// to ensure all conditional features are registered. -package condregister diff --git a/vendor/tailscale.com/feature/condregister/identityfederation/doc.go b/vendor/tailscale.com/feature/condregister/identityfederation/doc.go new file mode 100644 index 0000000..503b2c8 --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/identityfederation/doc.go @@ -0,0 +1,7 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package identityfederation registers support for authkey resolution +// via identity federation if it's not disabled by the +// ts_omit_identityfederation build tag. +package identityfederation diff --git a/vendor/tailscale.com/feature/condregister/identityfederation/maybe_identityfederation.go b/vendor/tailscale.com/feature/condregister/identityfederation/maybe_identityfederation.go new file mode 100644 index 0000000..b1db42f --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/identityfederation/maybe_identityfederation.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_identityfederation + +package identityfederation + +import _ "tailscale.com/feature/identityfederation" diff --git a/vendor/tailscale.com/feature/condregister/maybe_capture.go b/vendor/tailscale.com/feature/condregister/maybe_capture.go deleted file mode 100644 index 0c68331..0000000 --- a/vendor/tailscale.com/feature/condregister/maybe_capture.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !ios && !ts_omit_capture - -package condregister - -import _ "tailscale.com/feature/capture" diff --git a/vendor/tailscale.com/feature/condregister/maybe_tap.go b/vendor/tailscale.com/feature/condregister/maybe_tap.go deleted file mode 100644 index eca4fc3..0000000 --- a/vendor/tailscale.com/feature/condregister/maybe_tap.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && !ts_omit_tap - -package condregister - -import _ "tailscale.com/feature/tap" diff --git a/vendor/tailscale.com/feature/condregister/maybe_wakeonlan.go b/vendor/tailscale.com/feature/condregister/maybe_wakeonlan.go deleted file mode 100644 index 14cae60..0000000 --- a/vendor/tailscale.com/feature/condregister/maybe_wakeonlan.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !ts_omit_wakeonlan - -package condregister - -import _ "tailscale.com/feature/wakeonlan" diff --git a/vendor/tailscale.com/feature/condregister/oauthkey/doc.go b/vendor/tailscale.com/feature/condregister/oauthkey/doc.go new file mode 100644 index 0000000..4c4ea5e --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/oauthkey/doc.go @@ -0,0 +1,10 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package oauthkey registers support for OAuth key resolution +// if it's not disabled via the ts_omit_oauthkey build tag. +// Currently (2025-09-19), tailscaled does not need OAuth key +// resolution, only the CLI and tsnet do, so this package is +// pulled out separately to avoid linking OAuth packages into +// tailscaled. +package oauthkey diff --git a/vendor/tailscale.com/feature/condregister/oauthkey/maybe_oauthkey.go b/vendor/tailscale.com/feature/condregister/oauthkey/maybe_oauthkey.go new file mode 100644 index 0000000..be8d04b --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/oauthkey/maybe_oauthkey.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_oauthkey + +package oauthkey + +import _ "tailscale.com/feature/oauthkey" diff --git a/vendor/tailscale.com/feature/condregister/portmapper/doc.go b/vendor/tailscale.com/feature/condregister/portmapper/doc.go new file mode 100644 index 0000000..5c30538 --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/portmapper/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package portmapper registers support for portmapper +// if it's not disabled via the ts_omit_portmapper build tag. +package portmapper diff --git a/vendor/tailscale.com/feature/condregister/portmapper/maybe_portmapper.go b/vendor/tailscale.com/feature/condregister/portmapper/maybe_portmapper.go new file mode 100644 index 0000000..c306fd3 --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/portmapper/maybe_portmapper.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_portmapper + +package portmapper + +import _ "tailscale.com/feature/portmapper" diff --git a/vendor/tailscale.com/feature/condregister/useproxy/doc.go b/vendor/tailscale.com/feature/condregister/useproxy/doc.go new file mode 100644 index 0000000..1e8abb3 --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/useproxy/doc.go @@ -0,0 +1,6 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package useproxy registers support for using proxies +// if it's not disabled via the ts_omit_useproxy build tag. +package useproxy diff --git a/vendor/tailscale.com/feature/condregister/useproxy/useproxy.go b/vendor/tailscale.com/feature/condregister/useproxy/useproxy.go new file mode 100644 index 0000000..bda6e49 --- /dev/null +++ b/vendor/tailscale.com/feature/condregister/useproxy/useproxy.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_useproxy + +package useproxy + +import _ "tailscale.com/feature/useproxy" diff --git a/vendor/tailscale.com/feature/feature.go b/vendor/tailscale.com/feature/feature.go index 6415cfc..48a4aff 100644 --- a/vendor/tailscale.com/feature/feature.go +++ b/vendor/tailscale.com/feature/feature.go @@ -4,10 +4,23 @@ // Package feature tracks which features are linked into the binary. package feature -import "reflect" +import ( + "errors" + "reflect" + + "tailscale.com/util/testenv" +) + +var ErrUnavailable = errors.New("feature not included in this build") var in = map[string]bool{} +// Registered reports the set of registered features. +// +// The returned map should not be modified by the caller, +// not accessed concurrently with calls to Register. +func Registered() map[string]bool { return in } + // Register notes that the named feature is linked into the binary. func Register(name string) { if _, ok := in[name]; ok { @@ -44,11 +57,54 @@ func (h *Hook[Func]) Set(f Func) { h.ok = true } +// SetForTest sets the hook function for tests, blowing +// away any previous value. It will panic if called from +// non-test code. +// +// It returns a restore function that resets the hook +// to its previous value. +func (h *Hook[Func]) SetForTest(f Func) (restore func()) { + testenv.AssertInTest() + old := *h + h.f, h.ok = f, true + return func() { *h = old } +} + // Get returns the hook function, or panics if it hasn't been set. -// Use IsSet to check if it's been set. +// Use IsSet to check if it's been set, or use GetOrNil if you're +// okay with a nil return value. func (h *Hook[Func]) Get() Func { if !h.ok { panic("Get on unset feature hook, without IsSet") } return h.f } + +// GetOk returns the hook function and true if it has been set, +// otherwise its zero value and false. +func (h *Hook[Func]) GetOk() (f Func, ok bool) { + return h.f, h.ok +} + +// GetOrNil returns the hook function or nil if it hasn't been set. +func (h *Hook[Func]) GetOrNil() Func { + return h.f +} + +// Hooks is a slice of funcs. +// +// As opposed to a single Hook, this is meant to be used when +// multiple parties are able to install the same hook. +type Hooks[Func any] []Func + +// Add adds a hook to the list of hooks. +// +// Add should only be called during early program +// startup before Tailscale has started. +// It is not safe for concurrent use. +func (h *Hooks[Func]) Add(f Func) { + if reflect.ValueOf(f).IsZero() { + panic("Add with zero value") + } + *h = append(*h, f) +} diff --git a/vendor/tailscale.com/feature/hooks.go b/vendor/tailscale.com/feature/hooks.go new file mode 100644 index 0000000..7e31061 --- /dev/null +++ b/vendor/tailscale.com/feature/hooks.go @@ -0,0 +1,82 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package feature + +import ( + "net/http" + "net/url" + "os" + "sync" + + "tailscale.com/types/logger" + "tailscale.com/types/persist" +) + +// HookCanAutoUpdate is a hook for the clientupdate package +// to conditionally initialize. +var HookCanAutoUpdate Hook[func() bool] + +var testAllowAutoUpdate = sync.OnceValue(func() bool { + return os.Getenv("TS_TEST_ALLOW_AUTO_UPDATE") == "1" +}) + +// CanAutoUpdate reports whether the current binary is built with auto-update +// support and, if so, whether the current platform supports it. +func CanAutoUpdate() bool { + if testAllowAutoUpdate() { + return true + } + if f, ok := HookCanAutoUpdate.GetOk(); ok { + return f() + } + return false +} + +// HookProxyFromEnvironment is a hook for feature/useproxy to register +// a function to use as http.ProxyFromEnvironment. +var HookProxyFromEnvironment Hook[func(*http.Request) (*url.URL, error)] + +// HookProxyInvalidateCache is a hook for feature/useproxy to register +// [tshttpproxy.InvalidateCache]. +var HookProxyInvalidateCache Hook[func()] + +// HookProxyGetAuthHeader is a hook for feature/useproxy to register +// [tshttpproxy.GetAuthHeader]. +var HookProxyGetAuthHeader Hook[func(*url.URL) (string, error)] + +// HookProxySetSelfProxy is a hook for feature/useproxy to register +// [tshttpproxy.SetSelfProxy]. +var HookProxySetSelfProxy Hook[func(...string)] + +// HookProxySetTransportGetProxyConnectHeader is a hook for feature/useproxy to register +// [tshttpproxy.SetTransportGetProxyConnectHeader]. +var HookProxySetTransportGetProxyConnectHeader Hook[func(*http.Transport)] + +// HookTPMAvailable is a hook that reports whether a TPM device is supported +// and available. +var HookTPMAvailable Hook[func() bool] + +var HookGenerateAttestationKeyIfEmpty Hook[func(p *persist.Persist, logf logger.Logf) (bool, error)] + +// TPMAvailable reports whether a TPM device is supported and available. +func TPMAvailable() bool { + if f, ok := HookTPMAvailable.GetOk(); ok { + return f() + } + return false +} + +// HookHardwareAttestationAvailable is a hook that reports whether hardware +// attestation is supported and available. +var HookHardwareAttestationAvailable Hook[func() bool] + +// HardwareAttestationAvailable reports whether hardware attestation is +// supported and available (TPM on Windows/Linux, Secure Enclave on macOS|iOS, +// KeyStore on Android) +func HardwareAttestationAvailable() bool { + if f, ok := HookHardwareAttestationAvailable.GetOk(); ok { + return f() + } + return false +} diff --git a/vendor/tailscale.com/feature/identityfederation/identityfederation.go b/vendor/tailscale.com/feature/identityfederation/identityfederation.go new file mode 100644 index 0000000..f75b096 --- /dev/null +++ b/vendor/tailscale.com/feature/identityfederation/identityfederation.go @@ -0,0 +1,139 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package identityfederation registers support for using ID tokens to +// automatically request authkeys for logging in. +package identityfederation + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "golang.org/x/oauth2" + "tailscale.com/feature" + "tailscale.com/internal/client/tailscale" + "tailscale.com/ipn" + "tailscale.com/wif" +) + +func init() { + feature.Register("identityfederation") + tailscale.HookResolveAuthKeyViaWIF.Set(resolveAuthKey) + tailscale.HookExchangeJWTForTokenViaWIF.Set(exchangeJWTForToken) +} + +// resolveAuthKey uses OIDC identity federation to exchange the provided ID token and client ID for an authkey. +func resolveAuthKey(ctx context.Context, baseURL, clientID, idToken, audience string, tags []string) (string, error) { + if clientID == "" { + return "", nil // Short-circuit, no client ID means not using identity federation + } + + if idToken == "" { + if audience == "" { + return "", errors.New("federated identity requires either an ID token or an audience") + } + providerIdToken, err := wif.ObtainProviderToken(ctx, audience) + if err != nil { + return "", errors.New("federated identity authkeys require --id-token") + } + idToken = providerIdToken + } + if len(tags) == 0 { + return "", errors.New("federated identity authkeys require --advertise-tags") + } + if baseURL == "" { + baseURL = ipn.DefaultControlURL + } + + strippedID, ephemeral, preauth, err := parseOptionalAttributes(clientID) + if err != nil { + return "", fmt.Errorf("failed to parse optional config attributes: %w", err) + } + + accessToken, err := exchangeJWTForToken(ctx, baseURL, strippedID, idToken) + if err != nil { + return "", fmt.Errorf("failed to exchange JWT for access token: %w", err) + } + if accessToken == "" { + return "", errors.New("received empty access token from Tailscale") + } + + tsClient := tailscale.NewClient("-", tailscale.APIKey(accessToken)) + tsClient.UserAgent = "tailscale-cli-identity-federation" + tsClient.BaseURL = baseURL + + authkey, _, err := tsClient.CreateKey(ctx, tailscale.KeyCapabilities{ + Devices: tailscale.KeyDeviceCapabilities{ + Create: tailscale.KeyDeviceCreateCapabilities{ + Reusable: false, + Ephemeral: ephemeral, + Preauthorized: preauth, + Tags: tags, + }, + }, + }) + if err != nil { + return "", fmt.Errorf("unexpected error while creating authkey: %w", err) + } + if authkey == "" { + return "", errors.New("received empty authkey from control server") + } + + return authkey, nil +} + +func parseOptionalAttributes(clientID string) (strippedID string, ephemeral bool, preauthorized bool, err error) { + strippedID, attrs, found := strings.Cut(clientID, "?") + if !found { + return clientID, true, false, nil + } + + parsed, err := url.ParseQuery(attrs) + if err != nil { + return "", false, false, fmt.Errorf("failed to parse optional config attributes: %w", err) + } + + for k := range parsed { + switch k { + case "ephemeral": + ephemeral, err = strconv.ParseBool(parsed.Get(k)) + case "preauthorized": + preauthorized, err = strconv.ParseBool(parsed.Get(k)) + default: + return "", false, false, fmt.Errorf("unknown optional config attribute %q", k) + } + } + if err != nil { + return "", false, false, err + } + + return strippedID, ephemeral, preauthorized, nil +} + +// exchangeJWTForToken exchanges a JWT for a Tailscale access token. +func exchangeJWTForToken(ctx context.Context, baseURL, clientID, idToken string) (string, error) { + httpClient := &http.Client{Timeout: 10 * time.Second} + ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient) + + token, err := (&oauth2.Config{ + Endpoint: oauth2.Endpoint{ + TokenURL: fmt.Sprintf("%s/api/v2/oauth/token-exchange", baseURL), + }, + }).Exchange(ctx, "", oauth2.SetAuthURLParam("client_id", clientID), oauth2.SetAuthURLParam("jwt", idToken)) + if err != nil { + // Try to extract more detailed error message + var retrieveErr *oauth2.RetrieveError + if errors.As(err, &retrieveErr) { + return "", fmt.Errorf("token exchange failed with status %d: %s", retrieveErr.Response.StatusCode, string(retrieveErr.Body)) + } + return "", fmt.Errorf("unexpected token exchange request error: %w", err) + } + + return token.AccessToken, nil +} diff --git a/vendor/tailscale.com/feature/oauthkey/oauthkey.go b/vendor/tailscale.com/feature/oauthkey/oauthkey.go new file mode 100644 index 0000000..336340c --- /dev/null +++ b/vendor/tailscale.com/feature/oauthkey/oauthkey.go @@ -0,0 +1,115 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package oauthkey registers support for using OAuth client secrets to +// automatically request authkeys for logging in. +package oauthkey + +import ( + "context" + "errors" + "fmt" + "net/url" + "strconv" + "strings" + + "golang.org/x/oauth2/clientcredentials" + "tailscale.com/feature" + "tailscale.com/internal/client/tailscale" +) + +func init() { + feature.Register("oauthkey") + tailscale.HookResolveAuthKey.Set(resolveAuthKey) +} + +// resolveAuthKey either returns v unchanged (in the common case) or, if it +// starts with "tskey-client-" (as Tailscale OAuth secrets do) parses it like +// +// tskey-client-xxxx[?ephemeral=false&bar&preauthorized=BOOL&baseURL=...] +// +// and does the OAuth2 dance to get and return an authkey. The "ephemeral" +// property defaults to true if unspecified. The "preauthorized" defaults to +// false. The "baseURL" defaults to https://api.tailscale.com. +// The passed in tags are required, and must be non-empty. These will be +// set on the authkey generated by the OAuth2 dance. +func resolveAuthKey(ctx context.Context, clientSecret string, tags []string) (string, error) { + if !strings.HasPrefix(clientSecret, "tskey-client-") { + return clientSecret, nil + } + if len(tags) == 0 { + return "", errors.New("oauth authkeys require --advertise-tags") + } + + strippedSecret, ephemeral, preauth, baseURL, err := parseOptionalAttributes(clientSecret) + if err != nil { + return "", err + } + + credentials := clientcredentials.Config{ + ClientID: "some-client-id", // ignored + ClientSecret: strippedSecret, + TokenURL: baseURL + "/api/v2/oauth/token", + } + + tsClient := tailscale.NewClient("-", nil) + tsClient.UserAgent = "tailscale-cli" + tsClient.HTTPClient = credentials.Client(ctx) + tsClient.BaseURL = baseURL + + caps := tailscale.KeyCapabilities{ + Devices: tailscale.KeyDeviceCapabilities{ + Create: tailscale.KeyDeviceCreateCapabilities{ + Reusable: false, + Ephemeral: ephemeral, + Preauthorized: preauth, + Tags: tags, + }, + }, + } + + authkey, _, err := tsClient.CreateKey(ctx, caps) + if err != nil { + return "", err + } + return authkey, nil +} + +func parseOptionalAttributes(clientSecret string) (strippedSecret string, ephemeral bool, preauth bool, baseURL string, err error) { + strippedSecret, named, _ := strings.Cut(clientSecret, "?") + attrs, err := url.ParseQuery(named) + if err != nil { + return "", false, false, "", err + } + for k := range attrs { + switch k { + case "ephemeral", "preauthorized", "baseURL": + default: + return "", false, false, "", fmt.Errorf("unknown attribute %q", k) + } + } + getBool := func(name string, def bool) (bool, error) { + v := attrs.Get(name) + if v == "" { + return def, nil + } + ret, err := strconv.ParseBool(v) + if err != nil { + return false, fmt.Errorf("invalid attribute boolean attribute %s value %q", name, v) + } + return ret, nil + } + ephemeral, err = getBool("ephemeral", true) + if err != nil { + return "", false, false, "", err + } + preauth, err = getBool("preauthorized", false) + if err != nil { + return "", false, false, "", err + } + baseURL = "https://api.tailscale.com" + if v := attrs.Get("baseURL"); v != "" { + baseURL = v + } + return strippedSecret, ephemeral, preauth, baseURL, nil +} diff --git a/vendor/tailscale.com/feature/portmapper/portmapper.go b/vendor/tailscale.com/feature/portmapper/portmapper.go new file mode 100644 index 0000000..d1b903c --- /dev/null +++ b/vendor/tailscale.com/feature/portmapper/portmapper.go @@ -0,0 +1,40 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package portmapper registers support for NAT-PMP, PCP, and UPnP port +// mapping protocols to help get direction connections through NATs. +package portmapper + +import ( + "tailscale.com/feature" + "tailscale.com/net/netmon" + "tailscale.com/net/portmapper" + "tailscale.com/net/portmapper/portmappertype" + "tailscale.com/types/logger" + "tailscale.com/util/eventbus" +) + +func init() { + feature.Register("portmapper") + portmappertype.HookNewPortMapper.Set(newPortMapper) +} + +func newPortMapper( + logf logger.Logf, + bus *eventbus.Bus, + netMon *netmon.Monitor, + disableUPnPOrNil func() bool, + onlyTCP443OrNil func() bool) portmappertype.Client { + + pm := portmapper.NewClient(portmapper.Config{ + EventBus: bus, + Logf: logf, + NetMon: netMon, + DebugKnobs: &portmapper.DebugKnobs{ + DisableAll: onlyTCP443OrNil, + DisableUPnPFunc: disableUPnPOrNil, + }, + }) + pm.SetGatewayLookupFunc(netMon.GatewayAndSelfIP) + return pm +} diff --git a/vendor/tailscale.com/feature/sdnotify.go b/vendor/tailscale.com/feature/sdnotify.go new file mode 100644 index 0000000..7a786df --- /dev/null +++ b/vendor/tailscale.com/feature/sdnotify.go @@ -0,0 +1,39 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package feature + +import ( + "runtime" + + "tailscale.com/feature/buildfeatures" +) + +// HookSystemdReady sends a readiness to systemd. This will unblock service +// dependents from starting. +var HookSystemdReady Hook[func()] + +// HookSystemdStatus holds a func that will send a single line status update to +// systemd so that information shows up in systemctl output. +var HookSystemdStatus Hook[func(format string, args ...any)] + +// SystemdStatus sends a single line status update to systemd so that +// information shows up in systemctl output. +// +// It does nothing on non-Linux systems or if the binary was built without +// the sdnotify feature. +func SystemdStatus(format string, args ...any) { + if !CanSystemdStatus { // mid-stack inlining DCE + return + } + if f, ok := HookSystemdStatus.GetOk(); ok { + f(format, args...) + } +} + +// CanSystemdStatus reports whether the current build has systemd notifications +// linked in. +// +// It's effectively the same as HookSystemdStatus.IsSet(), but a constant for +// dead code elimination reasons. +const CanSystemdStatus = runtime.GOOS == "linux" && buildfeatures.HasSDNotify diff --git a/vendor/tailscale.com/feature/syspolicy/syspolicy.go b/vendor/tailscale.com/feature/syspolicy/syspolicy.go new file mode 100644 index 0000000..08c3cf3 --- /dev/null +++ b/vendor/tailscale.com/feature/syspolicy/syspolicy.go @@ -0,0 +1,7 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package syspolicy provides an interface for system-wide policy management. +package syspolicy + +import _ "tailscale.com/util/syspolicy" // for its registration side effects diff --git a/vendor/tailscale.com/feature/tap/tap_linux.go b/vendor/tailscale.com/feature/tap/tap_linux.go deleted file mode 100644 index 58ac005..0000000 --- a/vendor/tailscale.com/feature/tap/tap_linux.go +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package tap registers Tailscale's experimental (demo) Linux TAP (Layer 2) support. -package tap - -import ( - "bytes" - "fmt" - "net" - "net/netip" - "os" - "os/exec" - "sync" - - "github.com/insomniacslk/dhcp/dhcpv4" - "github.com/tailscale/wireguard-go/tun" - "golang.org/x/sys/unix" - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/checksum" - "gvisor.dev/gvisor/pkg/tcpip/header" - "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" - "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" - "gvisor.dev/gvisor/pkg/tcpip/transport/udp" - "tailscale.com/net/netaddr" - "tailscale.com/net/packet" - "tailscale.com/net/tsaddr" - "tailscale.com/net/tstun" - "tailscale.com/syncs" - "tailscale.com/types/ipproto" - "tailscale.com/types/logger" - "tailscale.com/util/multierr" -) - -// TODO: this was randomly generated once. Maybe do it per process start? But -// then an upgraded tailscaled would be visible to devices behind it. So -// maybe instead make it a function of the tailscaled's wireguard public key? -// For now just hard code it. -var ourMAC = net.HardwareAddr{0x30, 0x2D, 0x66, 0xEC, 0x7A, 0x93} - -const tapDebug = tstun.TAPDebug - -func init() { - tstun.CreateTAP.Set(createTAPLinux) -} - -func createTAPLinux(logf logger.Logf, tapName, bridgeName string) (tun.Device, error) { - fd, err := unix.Open("/dev/net/tun", unix.O_RDWR, 0) - if err != nil { - return nil, err - } - - dev, err := openDevice(logf, fd, tapName, bridgeName) - if err != nil { - unix.Close(fd) - return nil, err - } - - return dev, nil -} - -func openDevice(logf logger.Logf, fd int, tapName, bridgeName string) (tun.Device, error) { - ifr, err := unix.NewIfreq(tapName) - if err != nil { - return nil, err - } - - // Flags are stored as a uint16 in the ifreq union. - ifr.SetUint16(unix.IFF_TAP | unix.IFF_NO_PI) - if err := unix.IoctlIfreq(fd, unix.TUNSETIFF, ifr); err != nil { - return nil, err - } - - if err := run("ip", "link", "set", "dev", tapName, "up"); err != nil { - return nil, err - } - if bridgeName != "" { - if err := run("brctl", "addif", bridgeName, tapName); err != nil { - return nil, err - } - } - - return newTAPDevice(logf, fd, tapName) -} - -type etherType [2]byte - -var ( - etherTypeARP = etherType{0x08, 0x06} - etherTypeIPv4 = etherType{0x08, 0x00} - etherTypeIPv6 = etherType{0x86, 0xDD} -) - -const ( - ipv4HeaderLen = 20 - ethernetFrameSize = 14 // 2 six byte MACs, 2 bytes ethertype -) - -const ( - consumePacket = true - passOnPacket = false -) - -// handleTAPFrame handles receiving a raw TAP ethernet frame and reports whether -// it's been handled (that is, whether it should NOT be passed to wireguard). -func (t *tapDevice) handleTAPFrame(ethBuf []byte) bool { - - if len(ethBuf) < ethernetFrameSize { - // Corrupt. Ignore. - if tapDebug { - t.logf("tap: short TAP frame") - } - return consumePacket - } - ethDstMAC, ethSrcMAC := ethBuf[:6], ethBuf[6:12] - _ = ethDstMAC - et := etherType{ethBuf[12], ethBuf[13]} - switch et { - default: - if tapDebug { - t.logf("tap: ignoring etherType %v", et) - } - return consumePacket // filter out packet we should ignore - case etherTypeIPv6: - // TODO: support DHCPv6/ND/etc later. For now pass all to WireGuard. - if tapDebug { - t.logf("tap: ignoring IPv6 %v", et) - } - return passOnPacket - case etherTypeIPv4: - if len(ethBuf) < ethernetFrameSize+ipv4HeaderLen { - // Bogus IPv4. Eat. - if tapDebug { - t.logf("tap: short ipv4") - } - return consumePacket - } - return t.handleDHCPRequest(ethBuf) - case etherTypeARP: - arpPacket := header.ARP(ethBuf[ethernetFrameSize:]) - if !arpPacket.IsValid() { - // Bogus ARP. Eat. - return consumePacket - } - switch arpPacket.Op() { - case header.ARPRequest: - req := arpPacket // better name at this point - buf := make([]byte, header.EthernetMinimumSize+header.ARPSize) - - // Our ARP "Table" of one: - var srcMAC [6]byte - copy(srcMAC[:], ethSrcMAC) - if old := t.destMAC(); old != srcMAC { - t.destMACAtomic.Store(srcMAC) - } - - eth := header.Ethernet(buf) - eth.Encode(&header.EthernetFields{ - SrcAddr: tcpip.LinkAddress(ourMAC[:]), - DstAddr: tcpip.LinkAddress(ethSrcMAC), - Type: 0x0806, // arp - }) - res := header.ARP(buf[header.EthernetMinimumSize:]) - res.SetIPv4OverEthernet() - res.SetOp(header.ARPReply) - - // If the client's asking about their own IP, tell them it's - // their own MAC. TODO(bradfitz): remove String allocs. - if net.IP(req.ProtocolAddressTarget()).String() == t.clientIPv4.Load() { - copy(res.HardwareAddressSender(), ethSrcMAC) - } else { - copy(res.HardwareAddressSender(), ourMAC[:]) - } - - copy(res.ProtocolAddressSender(), req.ProtocolAddressTarget()) - copy(res.HardwareAddressTarget(), req.HardwareAddressSender()) - copy(res.ProtocolAddressTarget(), req.ProtocolAddressSender()) - - n, err := t.WriteEthernet(buf) - if tapDebug { - t.logf("tap: wrote ARP reply %v, %v", n, err) - } - } - - return consumePacket - } -} - -var ( - // routerIP is the IP address of the DHCP server. - routerIP = net.ParseIP(tsaddr.TailscaleServiceIPString) - // cgnatNetMask is the netmask of the 100.64.0.0/10 CGNAT range. - cgnatNetMask = net.IPMask(net.ParseIP("255.192.0.0").To4()) -) - -// parsedPacketPool holds a pool of Parsed structs for use in filtering. -// This is needed because escape analysis cannot see that parsed packets -// do not escape through {Pre,Post}Filter{In,Out}. -var parsedPacketPool = sync.Pool{New: func() any { return new(packet.Parsed) }} - -// handleDHCPRequest handles receiving a raw TAP ethernet frame and reports whether -// it's been handled as a DHCP request. That is, it reports whether the frame should -// be ignored by the caller and not passed on. -func (t *tapDevice) handleDHCPRequest(ethBuf []byte) bool { - const udpHeader = 8 - if len(ethBuf) < ethernetFrameSize+ipv4HeaderLen+udpHeader { - if tapDebug { - t.logf("tap: DHCP short") - } - return passOnPacket - } - ethDstMAC, ethSrcMAC := ethBuf[:6], ethBuf[6:12] - - if string(ethDstMAC) != "\xff\xff\xff\xff\xff\xff" { - // Not a broadcast - if tapDebug { - t.logf("tap: dhcp no broadcast") - } - return passOnPacket - } - - p := parsedPacketPool.Get().(*packet.Parsed) - defer parsedPacketPool.Put(p) - p.Decode(ethBuf[ethernetFrameSize:]) - - if p.IPProto != ipproto.UDP || p.Src.Port() != 68 || p.Dst.Port() != 67 { - // Not a DHCP request. - if tapDebug { - t.logf("tap: DHCP wrong meta: %+v", p) - } - return passOnPacket - } - - dp, err := dhcpv4.FromBytes(ethBuf[ethernetFrameSize+ipv4HeaderLen+udpHeader:]) - if err != nil { - // Bogus. Trash it. - if tapDebug { - t.logf("tap: DHCP FromBytes bad") - } - return consumePacket - } - if tapDebug { - t.logf("tap: DHCP request: %+v", dp) - } - switch dp.MessageType() { - case dhcpv4.MessageTypeDiscover: - ips := t.clientIPv4.Load() - if ips == "" { - t.logf("tap: DHCP no client IP") - return consumePacket - } - offer, err := dhcpv4.New( - dhcpv4.WithReply(dp), - dhcpv4.WithMessageType(dhcpv4.MessageTypeOffer), - dhcpv4.WithRouter(routerIP), // the default route - dhcpv4.WithDNS(routerIP), - dhcpv4.WithServerIP(routerIP), // TODO: what is this? - dhcpv4.WithOption(dhcpv4.OptServerIdentifier(routerIP)), - dhcpv4.WithYourIP(net.ParseIP(ips)), - dhcpv4.WithLeaseTime(3600), // hour works - //dhcpv4.WithHwAddr(ethSrcMAC), - dhcpv4.WithNetmask(cgnatNetMask), - //dhcpv4.WithTransactionID(dp.TransactionID), - ) - if err != nil { - t.logf("error building DHCP offer: %v", err) - return consumePacket - } - // Make a layer 2 packet to write out: - pkt := packLayer2UDP( - offer.ToBytes(), - ourMAC, ethSrcMAC, - netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src - netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst - ) - - n, err := t.WriteEthernet(pkt) - if tapDebug { - t.logf("tap: wrote DHCP OFFER %v, %v", n, err) - } - case dhcpv4.MessageTypeRequest: - ips := t.clientIPv4.Load() - if ips == "" { - t.logf("tap: DHCP no client IP") - return consumePacket - } - ack, err := dhcpv4.New( - dhcpv4.WithReply(dp), - dhcpv4.WithMessageType(dhcpv4.MessageTypeAck), - dhcpv4.WithDNS(routerIP), - dhcpv4.WithRouter(routerIP), // the default route - dhcpv4.WithServerIP(routerIP), // TODO: what is this? - dhcpv4.WithOption(dhcpv4.OptServerIdentifier(routerIP)), - dhcpv4.WithYourIP(net.ParseIP(ips)), // Hello world - dhcpv4.WithLeaseTime(3600), // hour works - dhcpv4.WithNetmask(cgnatNetMask), - ) - if err != nil { - t.logf("error building DHCP ack: %v", err) - return consumePacket - } - // Make a layer 2 packet to write out: - pkt := packLayer2UDP( - ack.ToBytes(), - ourMAC, ethSrcMAC, - netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src - netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst - ) - n, err := t.WriteEthernet(pkt) - if tapDebug { - t.logf("tap: wrote DHCP ACK %v, %v", n, err) - } - default: - if tapDebug { - t.logf("tap: unknown DHCP type") - } - } - return consumePacket -} - -func writeEthernetFrame(buf []byte, srcMAC, dstMAC net.HardwareAddr, proto tcpip.NetworkProtocolNumber) { - // Ethernet header - eth := header.Ethernet(buf) - eth.Encode(&header.EthernetFields{ - SrcAddr: tcpip.LinkAddress(srcMAC), - DstAddr: tcpip.LinkAddress(dstMAC), - Type: proto, - }) -} - -func packLayer2UDP(payload []byte, srcMAC, dstMAC net.HardwareAddr, src, dst netip.AddrPort) []byte { - buf := make([]byte, header.EthernetMinimumSize+header.UDPMinimumSize+header.IPv4MinimumSize+len(payload)) - payloadStart := len(buf) - len(payload) - copy(buf[payloadStart:], payload) - srcB := src.Addr().As4() - srcIP := tcpip.AddrFromSlice(srcB[:]) - dstB := dst.Addr().As4() - dstIP := tcpip.AddrFromSlice(dstB[:]) - // Ethernet header - writeEthernetFrame(buf, srcMAC, dstMAC, ipv4.ProtocolNumber) - // IP header - ipbuf := buf[header.EthernetMinimumSize:] - ip := header.IPv4(ipbuf) - ip.Encode(&header.IPv4Fields{ - TotalLength: uint16(len(ipbuf)), - TTL: 65, - Protocol: uint8(udp.ProtocolNumber), - SrcAddr: srcIP, - DstAddr: dstIP, - }) - ip.SetChecksum(^ip.CalculateChecksum()) - // UDP header - u := header.UDP(buf[header.EthernetMinimumSize+header.IPv4MinimumSize:]) - u.Encode(&header.UDPFields{ - SrcPort: src.Port(), - DstPort: dst.Port(), - Length: uint16(header.UDPMinimumSize + len(payload)), - }) - // Calculate the UDP pseudo-header checksum. - xsum := header.PseudoHeaderChecksum(udp.ProtocolNumber, srcIP, dstIP, uint16(len(u))) - // Calculate the UDP checksum and set it. - xsum = checksum.Checksum(payload, xsum) - u.SetChecksum(^u.CalculateChecksum(xsum)) - return []byte(buf) -} - -func run(prog string, args ...string) error { - cmd := exec.Command(prog, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("error running %v: %v", cmd, err) - } - return nil -} - -func (t *tapDevice) destMAC() [6]byte { - return t.destMACAtomic.Load() -} - -func newTAPDevice(logf logger.Logf, fd int, tapName string) (tun.Device, error) { - err := unix.SetNonblock(fd, true) - if err != nil { - return nil, err - } - file := os.NewFile(uintptr(fd), "/dev/tap") - d := &tapDevice{ - logf: logf, - file: file, - events: make(chan tun.Event), - name: tapName, - } - return d, nil -} - -type tapDevice struct { - file *os.File - logf func(format string, args ...any) - events chan tun.Event - name string - closeOnce sync.Once - clientIPv4 syncs.AtomicValue[string] - - destMACAtomic syncs.AtomicValue[[6]byte] -} - -var _ tstun.SetIPer = (*tapDevice)(nil) - -func (t *tapDevice) SetIP(ipV4, ipV6TODO netip.Addr) error { - t.clientIPv4.Store(ipV4.String()) - return nil -} - -func (t *tapDevice) File() *os.File { - return t.file -} - -func (t *tapDevice) Name() (string, error) { - return t.name, nil -} - -// Read reads an IP packet from the TAP device. It strips the ethernet frame header. -func (t *tapDevice) Read(buffs [][]byte, sizes []int, offset int) (int, error) { - n, err := t.ReadEthernet(buffs, sizes, offset) - if err != nil || n == 0 { - return n, err - } - // Strip the ethernet frame header. - copy(buffs[0][offset:], buffs[0][offset+ethernetFrameSize:offset+sizes[0]]) - sizes[0] -= ethernetFrameSize - return 1, nil -} - -// ReadEthernet reads a raw ethernet frame from the TAP device. -func (t *tapDevice) ReadEthernet(buffs [][]byte, sizes []int, offset int) (int, error) { - n, err := t.file.Read(buffs[0][offset:]) - if err != nil { - return 0, err - } - if t.handleTAPFrame(buffs[0][offset : offset+n]) { - return 0, nil - } - sizes[0] = n - return 1, nil -} - -// WriteEthernet writes a raw ethernet frame to the TAP device. -func (t *tapDevice) WriteEthernet(buf []byte) (int, error) { - return t.file.Write(buf) -} - -// ethBufPool holds a pool of bytes.Buffers for use in [tapDevice.Write]. -var ethBufPool = syncs.Pool[*bytes.Buffer]{New: func() *bytes.Buffer { return new(bytes.Buffer) }} - -// Write writes a raw IP packet to the TAP device. It adds the ethernet frame header. -func (t *tapDevice) Write(buffs [][]byte, offset int) (int, error) { - errs := make([]error, 0) - wrote := 0 - m := t.destMAC() - dstMac := net.HardwareAddr(m[:]) - buf := ethBufPool.Get() - defer ethBufPool.Put(buf) - for _, buff := range buffs { - buf.Reset() - buf.Grow(header.EthernetMinimumSize + len(buff) - offset) - - var ebuf [14]byte - switch buff[offset] >> 4 { - case 4: - writeEthernetFrame(ebuf[:], ourMAC, dstMac, ipv4.ProtocolNumber) - case 6: - writeEthernetFrame(ebuf[:], ourMAC, dstMac, ipv6.ProtocolNumber) - default: - continue - } - buf.Write(ebuf[:]) - buf.Write(buff[offset:]) - _, err := t.WriteEthernet(buf.Bytes()) - if err != nil { - errs = append(errs, err) - } else { - wrote++ - } - } - return wrote, multierr.New(errs...) -} - -func (t *tapDevice) MTU() (int, error) { - ifr, err := unix.NewIfreq(t.name) - if err != nil { - return 0, err - } - if err := unix.IoctlIfreq(int(t.file.Fd()), unix.SIOCGIFMTU, ifr); err != nil { - return 0, err - } - return int(ifr.Uint32()), nil -} - -func (t *tapDevice) Events() <-chan tun.Event { - return t.events -} - -func (t *tapDevice) Close() error { - var err error - t.closeOnce.Do(func() { - close(t.events) - err = t.file.Close() - }) - return err -} - -func (t *tapDevice) BatchSize() int { - return 1 -} diff --git a/vendor/tailscale.com/feature/useproxy/useproxy.go b/vendor/tailscale.com/feature/useproxy/useproxy.go new file mode 100644 index 0000000..a18e605 --- /dev/null +++ b/vendor/tailscale.com/feature/useproxy/useproxy.go @@ -0,0 +1,18 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package useproxy registers support for using system proxies. +package useproxy + +import ( + "tailscale.com/feature" + "tailscale.com/net/tshttpproxy" +) + +func init() { + feature.HookProxyFromEnvironment.Set(tshttpproxy.ProxyFromEnvironment) + feature.HookProxyInvalidateCache.Set(tshttpproxy.InvalidateCache) + feature.HookProxyGetAuthHeader.Set(tshttpproxy.GetAuthHeader) + feature.HookProxySetSelfProxy.Set(tshttpproxy.SetSelfProxy) + feature.HookProxySetTransportGetProxyConnectHeader.Set(tshttpproxy.SetTransportGetProxyConnectHeader) +} diff --git a/vendor/tailscale.com/feature/wakeonlan/wakeonlan.go b/vendor/tailscale.com/feature/wakeonlan/wakeonlan.go deleted file mode 100644 index 96c4240..0000000 --- a/vendor/tailscale.com/feature/wakeonlan/wakeonlan.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package wakeonlan registers the Wake-on-LAN feature. -package wakeonlan - -import ( - "encoding/json" - "log" - "net" - "net/http" - "runtime" - "sort" - "strings" - "unicode" - - "github.com/kortschak/wol" - "tailscale.com/envknob" - "tailscale.com/feature" - "tailscale.com/hostinfo" - "tailscale.com/ipn/ipnlocal" - "tailscale.com/tailcfg" - "tailscale.com/util/clientmetric" -) - -func init() { - feature.Register("wakeonlan") - ipnlocal.RegisterC2N("POST /wol", handleC2NWoL) - ipnlocal.RegisterPeerAPIHandler("/v0/wol", handlePeerAPIWakeOnLAN) - hostinfo.RegisterHostinfoNewHook(func(h *tailcfg.Hostinfo) { - h.WoLMACs = getWoLMACs() - }) -} - -func handleC2NWoL(b *ipnlocal.LocalBackend, w http.ResponseWriter, r *http.Request) { - r.ParseForm() - var macs []net.HardwareAddr - for _, macStr := range r.Form["mac"] { - mac, err := net.ParseMAC(macStr) - if err != nil { - http.Error(w, "bad 'mac' param", http.StatusBadRequest) - return - } - macs = append(macs, mac) - } - var res struct { - SentTo []string - Errors []string - } - st := b.NetMon().InterfaceState() - if st == nil { - res.Errors = append(res.Errors, "no interface state") - writeJSON(w, &res) - return - } - var password []byte // TODO(bradfitz): support? does anything use WoL passwords? - for _, mac := range macs { - for ifName, ips := range st.InterfaceIPs { - for _, ip := range ips { - if ip.Addr().IsLoopback() || ip.Addr().Is6() { - continue - } - local := &net.UDPAddr{ - IP: ip.Addr().AsSlice(), - Port: 0, - } - remote := &net.UDPAddr{ - IP: net.IPv4bcast, - Port: 0, - } - if err := wol.Wake(mac, password, local, remote); err != nil { - res.Errors = append(res.Errors, err.Error()) - } else { - res.SentTo = append(res.SentTo, ifName) - } - break // one per interface is enough - } - } - } - sort.Strings(res.SentTo) - writeJSON(w, &res) -} - -func writeJSON(w http.ResponseWriter, v any) { - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(v) -} - -func canWakeOnLAN(h ipnlocal.PeerAPIHandler) bool { - if h.Peer().UnsignedPeerAPIOnly() { - return false - } - return h.IsSelfUntagged() || h.PeerCaps().HasCapability(tailcfg.PeerCapabilityWakeOnLAN) -} - -var metricWakeOnLANCalls = clientmetric.NewCounter("peerapi_wol") - -func handlePeerAPIWakeOnLAN(h ipnlocal.PeerAPIHandler, w http.ResponseWriter, r *http.Request) { - metricWakeOnLANCalls.Add(1) - if !canWakeOnLAN(h) { - http.Error(w, "no WoL access", http.StatusForbidden) - return - } - if r.Method != "POST" { - http.Error(w, "bad method", http.StatusMethodNotAllowed) - return - } - macStr := r.FormValue("mac") - if macStr == "" { - http.Error(w, "missing 'mac' param", http.StatusBadRequest) - return - } - mac, err := net.ParseMAC(macStr) - if err != nil { - http.Error(w, "bad 'mac' param", http.StatusBadRequest) - return - } - var password []byte // TODO(bradfitz): support? does anything use WoL passwords? - st := h.LocalBackend().NetMon().InterfaceState() - if st == nil { - http.Error(w, "failed to get interfaces state", http.StatusInternalServerError) - return - } - var res struct { - SentTo []string - Errors []string - } - for ifName, ips := range st.InterfaceIPs { - for _, ip := range ips { - if ip.Addr().IsLoopback() || ip.Addr().Is6() { - continue - } - local := &net.UDPAddr{ - IP: ip.Addr().AsSlice(), - Port: 0, - } - remote := &net.UDPAddr{ - IP: net.IPv4bcast, - Port: 0, - } - if err := wol.Wake(mac, password, local, remote); err != nil { - res.Errors = append(res.Errors, err.Error()) - } else { - res.SentTo = append(res.SentTo, ifName) - } - break // one per interface is enough - } - } - sort.Strings(res.SentTo) - writeJSON(w, res) -} - -// TODO(bradfitz): this is all too simplistic and static. It needs to run -// continuously in response to netmon events (USB ethernet adapters might get -// plugged in) and look for the media type/status/etc. Right now on macOS it -// still detects a half dozen "up" en0, en1, en2, en3 etc interfaces that don't -// have any media. We should only report the one that's actually connected. -// But it works for now (2023-10-05) for fleshing out the rest. - -var wakeMAC = envknob.RegisterString("TS_WAKE_MAC") // mac address, "false" or "auto". for https://github.com/tailscale/tailscale/issues/306 - -// getWoLMACs returns up to 10 MAC address of the local machine to send -// wake-on-LAN packets to in order to wake it up. The returned MACs are in -// lowercase hex colon-separated form ("xx:xx:xx:xx:xx:xx"). -// -// If TS_WAKE_MAC=auto, it tries to automatically find the MACs based on the OS -// type and interface properties. (TODO(bradfitz): incomplete) If TS_WAKE_MAC is -// set to a MAC address, that sole MAC address is returned. -func getWoLMACs() (macs []string) { - switch runtime.GOOS { - case "ios", "android": - return nil - } - if s := wakeMAC(); s != "" { - switch s { - case "auto": - ifs, _ := net.Interfaces() - for _, iface := range ifs { - if iface.Flags&net.FlagLoopback != 0 { - continue - } - if iface.Flags&net.FlagBroadcast == 0 || - iface.Flags&net.FlagRunning == 0 || - iface.Flags&net.FlagUp == 0 { - continue - } - if keepMAC(iface.Name, iface.HardwareAddr) { - macs = append(macs, iface.HardwareAddr.String()) - } - if len(macs) == 10 { - break - } - } - return macs - case "false", "off": // fast path before ParseMAC error - return nil - } - mac, err := net.ParseMAC(s) - if err != nil { - log.Printf("invalid MAC %q", s) - return nil - } - return []string{mac.String()} - } - return nil -} - -var ignoreWakeOUI = map[[3]byte]bool{ - {0x00, 0x15, 0x5d}: true, // Hyper-V - {0x00, 0x50, 0x56}: true, // VMware - {0x00, 0x1c, 0x14}: true, // VMware - {0x00, 0x05, 0x69}: true, // VMware - {0x00, 0x0c, 0x29}: true, // VMware - {0x00, 0x1c, 0x42}: true, // Parallels - {0x08, 0x00, 0x27}: true, // VirtualBox - {0x00, 0x21, 0xf6}: true, // VirtualBox - {0x00, 0x14, 0x4f}: true, // VirtualBox - {0x00, 0x0f, 0x4b}: true, // VirtualBox - {0x52, 0x54, 0x00}: true, // VirtualBox/Vagrant -} - -func keepMAC(ifName string, mac []byte) bool { - if len(mac) != 6 { - return false - } - base := strings.TrimRightFunc(ifName, unicode.IsNumber) - switch runtime.GOOS { - case "darwin": - switch base { - case "llw", "awdl", "utun", "bridge", "lo", "gif", "stf", "anpi", "ap": - return false - } - } - if mac[0] == 0x02 && mac[1] == 0x42 { - // Docker container. - return false - } - oui := [3]byte{mac[0], mac[1], mac[2]} - if ignoreWakeOUI[oui] { - return false - } - return true -} diff --git a/vendor/tailscale.com/flake.lock b/vendor/tailscale.com/flake.lock index 8c4aa7d..1623342 100644 --- a/vendor/tailscale.com/flake.lock +++ b/vendor/tailscale.com/flake.lock @@ -16,31 +16,13 @@ "type": "github" } }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1724748588, - "narHash": "sha256-NlpGA4+AIf1dKNq76ps90rxowlFXUsV9x7vK/mN37JM=", + "lastModified": 1753151930, + "narHash": "sha256-XSQy6wRKHhRe//iVY5lS/ZpI/Jn6crWI8fQzl647wCg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a6292e34000dc93d43bccf78338770c1c5ec8a99", + "rev": "83e677f31c84212343f4cc553bab85c2efcad60a", "type": "github" }, "original": { @@ -53,8 +35,8 @@ "root": { "inputs": { "flake-compat": "flake-compat", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "systems": "systems" } }, "systems": { diff --git a/vendor/tailscale.com/flake.nix b/vendor/tailscale.com/flake.nix index 95d5c30..149223d 100644 --- a/vendor/tailscale.com/flake.nix +++ b/vendor/tailscale.com/flake.nix @@ -32,7 +32,7 @@ { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-utils.url = "github:numtide/flake-utils"; + systems.url = "github:nix-systems/default"; # Used by shell.nix as a compat shim. flake-compat = { url = "github:edolstra/flake-compat"; @@ -43,13 +43,32 @@ outputs = { self, nixpkgs, - flake-utils, + systems, flake-compat, }: let - # tailscaleRev is the git commit at which this flake was imported, - # or the empty string when building from a local checkout of the - # tailscale repo. + goVersion = nixpkgs.lib.fileContents ./go.toolchain.version; + toolChainRev = nixpkgs.lib.fileContents ./go.toolchain.rev; + gitHash = nixpkgs.lib.fileContents ./go.toolchain.rev.sri; + eachSystem = f: + nixpkgs.lib.genAttrs (import systems) (system: + f (import nixpkgs { + system = system; + overlays = [ + (final: prev: { + go_1_25 = prev.go_1_25.overrideAttrs { + version = goVersion; + src = prev.fetchFromGitHub { + owner = "tailscale"; + repo = "go"; + rev = toolChainRev; + sha256 = gitHash; + }; + }; + }) + ]; + })); tailscaleRev = self.rev or ""; + in { # tailscale takes a nixpkgs package set, and builds Tailscale from # the same commit as this flake. IOW, it provides "tailscale built # from HEAD", where HEAD is "whatever commit you imported the @@ -67,16 +86,20 @@ # So really, this flake is for tailscale devs to dogfood with, if # you're an end user you should be prepared for this flake to not # build periodically. - tailscale = pkgs: - pkgs.buildGo123Module rec { + packages = eachSystem (pkgs: rec { + default = pkgs.buildGo125Module { name = "tailscale"; - + pname = "tailscale"; src = ./.; vendorHash = pkgs.lib.fileContents ./go.mod.sri; - nativeBuildInputs = pkgs.lib.optionals pkgs.stdenv.isLinux [pkgs.makeWrapper]; + nativeBuildInputs = [pkgs.makeWrapper pkgs.installShellFiles]; ldflags = ["-X tailscale.com/version.gitCommitStamp=${tailscaleRev}"]; - CGO_ENABLED = 0; - subPackages = ["cmd/tailscale" "cmd/tailscaled"]; + env.CGO_ENABLED = 0; + subPackages = [ + "cmd/tailscale" + "cmd/tailscaled" + "cmd/tsidp" + ]; doCheck = false; # NOTE: We strip the ${PORT} and $FLAGS because they are unset in the @@ -84,32 +107,31 @@ # point, there should be a NixOS module that allows configuration of these # things, but for now, we hardcode the default of port 41641 (taken from # ./cmd/tailscaled/tailscaled.defaults). - postInstall = pkgs.lib.optionalString pkgs.stdenv.isLinux '' - wrapProgram $out/bin/tailscaled --prefix PATH : ${pkgs.lib.makeBinPath [pkgs.iproute2 pkgs.iptables pkgs.getent pkgs.shadow]} - wrapProgram $out/bin/tailscale --suffix PATH : ${pkgs.lib.makeBinPath [pkgs.procps]} + postInstall = + pkgs.lib.optionalString pkgs.stdenv.isLinux '' + wrapProgram $out/bin/tailscaled --prefix PATH : ${pkgs.lib.makeBinPath [pkgs.iproute2 pkgs.iptables pkgs.getent pkgs.shadow]} + wrapProgram $out/bin/tailscale --suffix PATH : ${pkgs.lib.makeBinPath [pkgs.procps]} - sed -i \ - -e "s#/usr/sbin#$out/bin#" \ - -e "/^EnvironmentFile/d" \ - -e 's/''${PORT}/41641/' \ - -e 's/$FLAGS//' \ - ./cmd/tailscaled/tailscaled.service + sed -i \ + -e "s#/usr/sbin#$out/bin#" \ + -e "/^EnvironmentFile/d" \ + -e 's/''${PORT}/41641/' \ + -e 's/$FLAGS//' \ + ./cmd/tailscaled/tailscaled.service - install -D -m0444 -t $out/lib/systemd/system ./cmd/tailscaled/tailscaled.service - ''; + install -D -m0444 -t $out/lib/systemd/system ./cmd/tailscaled/tailscaled.service + '' + + pkgs.lib.optionalString (pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform) '' + installShellCompletion --cmd tailscale \ + --bash <($out/bin/tailscale completion bash) \ + --fish <($out/bin/tailscale completion fish) \ + --zsh <($out/bin/tailscale completion zsh) + ''; }; + tailscale = default; + }); - # This whole blob makes the tailscale package available for all - # OS/CPU combos that nix supports, as well as a dev shell so that - # "nix develop" and "nix-shell" give you a dev env. - flakeForSystem = nixpkgs: system: let - pkgs = nixpkgs.legacyPackages.${system}; - ts = tailscale pkgs; - in { - packages = { - default = ts; - tailscale = ts; - }; + devShells = eachSystem (pkgs: { devShell = pkgs.mkShell { packages = with pkgs; [ curl @@ -118,7 +140,7 @@ gotools graphviz perl - go_1_23 + go_1_25 yarn # qemu and e2fsprogs are needed for natlab @@ -126,8 +148,7 @@ e2fsprogs ]; }; - }; - in - flake-utils.lib.eachDefaultSystem (system: flakeForSystem nixpkgs system); + }); + }; } -# nix-direnv cache busting line: sha256-xO1DuLWi6/lpA9ubA2ZYVJM+CkVNA5IaVGZxX9my0j0= +# nix-direnv cache busting line: sha256-WeMTOkERj4hvdg4yPaZ1gRgKnhRIBXX55kUVbX/k/xM= diff --git a/vendor/tailscale.com/go.mod.sri b/vendor/tailscale.com/go.mod.sri index 4abb3c5..b533a75 100644 --- a/vendor/tailscale.com/go.mod.sri +++ b/vendor/tailscale.com/go.mod.sri @@ -1 +1 @@ -sha256-xO1DuLWi6/lpA9ubA2ZYVJM+CkVNA5IaVGZxX9my0j0= +sha256-WeMTOkERj4hvdg4yPaZ1gRgKnhRIBXX55kUVbX/k/xM= diff --git a/vendor/tailscale.com/go.toolchain.branch b/vendor/tailscale.com/go.toolchain.branch index 5e1cd06..a2bebbe 100644 --- a/vendor/tailscale.com/go.toolchain.branch +++ b/vendor/tailscale.com/go.toolchain.branch @@ -1 +1 @@ -tailscale.go1.24 +tailscale.go1.25 diff --git a/vendor/tailscale.com/go.toolchain.rev b/vendor/tailscale.com/go.toolchain.rev index 69aec16..16058a4 100644 --- a/vendor/tailscale.com/go.toolchain.rev +++ b/vendor/tailscale.com/go.toolchain.rev @@ -1 +1 @@ -4fdaeeb8fe43bcdb4e8cc736433b9cd9c0ddd221 +0bab982699fa5903259ba9b4cba3e5fd6cb3baf2 diff --git a/vendor/tailscale.com/go.toolchain.rev.sri b/vendor/tailscale.com/go.toolchain.rev.sri new file mode 100644 index 0000000..310dcf8 --- /dev/null +++ b/vendor/tailscale.com/go.toolchain.rev.sri @@ -0,0 +1 @@ +sha256-fBezkBGRHCnfJiOUmMMqBCPCqjlGC4F6KEt5h1JhsCg= diff --git a/vendor/tailscale.com/go.toolchain.version b/vendor/tailscale.com/go.toolchain.version new file mode 100644 index 0000000..b45fe31 --- /dev/null +++ b/vendor/tailscale.com/go.toolchain.version @@ -0,0 +1 @@ +1.25.5 diff --git a/vendor/tailscale.com/health/health.go b/vendor/tailscale.com/health/health.go index b0733f3..f0f6a6f 100644 --- a/vendor/tailscale.com/health/health.go +++ b/vendor/tailscale.com/health/health.go @@ -8,7 +8,6 @@ package health import ( "context" "errors" - "expvar" "fmt" "maps" "net/http" @@ -20,20 +19,19 @@ import ( "time" "tailscale.com/envknob" - "tailscale.com/metrics" + "tailscale.com/feature/buildfeatures" + "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tstime" "tailscale.com/types/opt" "tailscale.com/util/cibuild" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" - "tailscale.com/util/multierr" - "tailscale.com/util/set" - "tailscale.com/util/usermetric" "tailscale.com/version" ) var ( - mu sync.Mutex + mu syncs.Mutex debugHandler map[string]http.Handler ) @@ -64,6 +62,21 @@ var receiveNames = []string{ // Tracker tracks the health of various Tailscale subsystems, // comparing each subsystems' state with each other to make sure // they're consistent based on the user's intended state. +// +// If a client [Warnable] becomes unhealthy or its unhealthy state is updated, +// an event will be emitted with WarnableChanged set to true and the Warnable +// and its UnhealthyState: +// +// Change{WarnableChanged: true, Warnable: w, UnhealthyState: us} +// +// If a Warnable becomes healthy, an event will be emitted with +// WarnableChanged set to true, the Warnable set, and UnhealthyState set to nil: +// +// Change{WarnableChanged: true, Warnable: w, UnhealthyState: nil} +// +// If the health messages from the control-plane change, an event will be +// emitted with ControlHealthChanged set to true. Recipients can fetch the set of +// control-plane health messages by calling [Tracker.CurrentState]: type Tracker struct { // MagicSockReceiveFuncs tracks the state of the three // magicsock receive functions: IPv4, IPv6, and DERP. @@ -76,6 +89,9 @@ type Tracker struct { testClock tstime.Clock // nil means use time.Now / tstime.StdClock{} + eventClient *eventbus.Client + changePub *eventbus.Publisher[Change] + // mu guards everything that follows. mu sync.Mutex @@ -87,35 +103,69 @@ type Tracker struct { // sysErr maps subsystems to their current error (or nil if the subsystem is healthy) // Deprecated: using Warnables should be preferred - sysErr map[Subsystem]error - watchers set.HandleSet[func(*Warnable, *UnhealthyState)] // opt func to run if error state changes - timer tstime.TimerController + sysErr map[Subsystem]error + timer tstime.TimerController latestVersion *tailcfg.ClientVersion // or nil checkForUpdates bool applyUpdates opt.Bool - inMapPoll bool - inMapPollSince time.Time - lastMapPollEndedAt time.Time - lastStreamedMapResponse time.Time - lastNoiseDial time.Time - derpHomeRegion int - derpHomeless bool - derpRegionConnected map[int]bool - derpRegionHealthProblem map[int]string - derpRegionLastFrame map[int]time.Time - derpMap *tailcfg.DERPMap // last DERP map from control, could be nil if never received one - lastMapRequestHeard time.Time // time we got a 200 from control for a MapRequest - ipnState string - ipnWantRunning bool - ipnWantRunningLastTrue time.Time // when ipnWantRunning last changed false -> true - anyInterfaceUp opt.Bool // empty means unknown (assume true) - controlHealth []string - lastLoginErr error - localLogConfigErr error - tlsConnectionErrors map[string]error // map[ServerName]error - metricHealthMessage *metrics.MultiLabelMap[metricHealthMessageLabel] + inMapPoll bool + inMapPollSince time.Time + lastMapPollEndedAt time.Time + lastStreamedMapResponse time.Time + lastNoiseDial time.Time + derpHomeRegion int + derpHomeless bool + derpRegionConnected map[int]bool + derpRegionHealthProblem map[int]string + derpRegionLastFrame map[int]time.Time + derpMap *tailcfg.DERPMap // last DERP map from control, could be nil if never received one + lastMapRequestHeard time.Time // time we got a 200 from control for a MapRequest + ipnState string + ipnWantRunning bool + ipnWantRunningLastTrue time.Time // when ipnWantRunning last changed false -> true + anyInterfaceUp opt.Bool // empty means unknown (assume true) + lastNotifiedControlMessages map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage // latest control messages processed, kept for change detection + controlMessages map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage // latest control messages received + lastLoginErr error + localLogConfigErr error + tlsConnectionErrors map[string]error // map[ServerName]error + metricHealthMessage any // nil or *metrics.MultiLabelMap[metricHealthMessageLabel] +} + +// NewTracker contructs a new [Tracker] and attaches the given eventbus. +// NewTracker will panic is no eventbus is given. +func NewTracker(bus *eventbus.Bus) *Tracker { + if !buildfeatures.HasHealth { + return &Tracker{} + } + if bus == nil { + panic("no eventbus set") + } + + ec := bus.Client("health.Tracker") + t := &Tracker{ + eventClient: ec, + changePub: eventbus.Publish[Change](ec), + } + t.timer = t.clock().AfterFunc(time.Minute, t.timerSelfCheck) + + ec.Monitor(t.awaitEventClientDone) + + return t +} + +func (t *Tracker) awaitEventClientDone(ec *eventbus.Client) { + <-ec.Done() + t.mu.Lock() + defer t.mu.Unlock() + + for _, timer := range t.pendingVisibleTimers { + timer.Stop() + } + t.timer.Stop() + clear(t.pendingVisibleTimers) } func (t *Tracker) now() time.Time { @@ -173,6 +223,9 @@ const legacyErrorArgKey = "LegacyError" // temporarily (2024-06-14) while we migrate the old health infrastructure based // on Subsystems to the new Warnables architecture. func (s Subsystem) Warnable() *Warnable { + if !buildfeatures.HasHealth { + return &noopWarnable + } w, ok := subsystemsWarnables[s] if !ok { panic(fmt.Sprintf("health: no Warnable for Subsystem %q", s)) @@ -182,10 +235,15 @@ func (s Subsystem) Warnable() *Warnable { var registeredWarnables = map[WarnableCode]*Warnable{} +var noopWarnable Warnable + // Register registers a new Warnable with the health package and returns it. // Register panics if the Warnable was already registered, because Warnables // should be unique across the program. func Register(w *Warnable) *Warnable { + if !buildfeatures.HasHealth { + return &noopWarnable + } if registeredWarnables[w.Code] != nil { panic(fmt.Sprintf("health: a Warnable with code %q was already registered", w.Code)) } @@ -197,6 +255,9 @@ func Register(w *Warnable) *Warnable { // unregister removes a Warnable from the health package. It should only be used // for testing purposes. func unregister(w *Warnable) { + if !buildfeatures.HasHealth { + return + } if registeredWarnables[w.Code] == nil { panic(fmt.Sprintf("health: attempting to unregister Warnable %q that was not registered", w.Code)) } @@ -207,13 +268,15 @@ func unregister(w *Warnable) { // the program. type WarnableCode string -// A Warnable is something that we might want to warn the user about, or not. A Warnable is either -// in an healthy or unhealth state. A Warnable is unhealthy if the Tracker knows about a WarningState -// affecting the Warnable. -// In most cases, Warnables are components of the backend (for instance, "DNS" or "Magicsock"). -// Warnables are similar to the Subsystem type previously used in this package, but they provide -// a unique identifying code for each Warnable, along with more metadata that makes it easier for -// a GUI to display the Warnable in a user-friendly way. +// A Warnable is something that we might want to warn the user about, or not. A +// Warnable is either in a healthy or unhealthy state. A Warnable is unhealthy if +// the Tracker knows about a WarningState affecting the Warnable. +// +// In most cases, Warnables are components of the backend (for instance, "DNS" +// or "Magicsock"). Warnables are similar to the Subsystem type previously used +// in this package, but they provide a unique identifying code for each +// Warnable, along with more metadata that makes it easier for a GUI to display +// the Warnable in a user-friendly way. type Warnable struct { // Code is a string that uniquely identifies this Warnable across the entire Tailscale backend, // and can be mapped to a user-displayable localized string. @@ -267,6 +330,9 @@ func StaticMessage(s string) func(Args) string { // some lost Tracker plumbing, we want to capture stack trace // samples when it occurs. func (t *Tracker) nil() bool { + if !buildfeatures.HasHealth { + return true + } if t != nil { return false } @@ -335,31 +401,16 @@ func (w *Warnable) IsVisible(ws *warningState, clockNow func() time.Time) bool { return clockNow().Sub(ws.BrokenSince) >= w.TimeToVisible } -// SetMetricsRegistry sets up the metrics for the Tracker. It takes -// a usermetric.Registry and registers the metrics there. -func (t *Tracker) SetMetricsRegistry(reg *usermetric.Registry) { - if reg == nil || t.metricHealthMessage != nil { - return +// IsUnhealthy reports whether the current state is unhealthy because the given +// warnable is set. +func (t *Tracker) IsUnhealthy(w *Warnable) bool { + if !buildfeatures.HasHealth || t.nil() { + return false } - - t.metricHealthMessage = usermetric.NewMultiLabelMapWithRegistry[metricHealthMessageLabel]( - reg, - "tailscaled_health_messages", - "gauge", - "Number of health messages broken down by type.", - ) - - t.metricHealthMessage.Set(metricHealthMessageLabel{ - Type: MetricLabelWarning, - }, expvar.Func(func() any { - if t.nil() { - return 0 - } - t.mu.Lock() - defer t.mu.Unlock() - t.updateBuiltinWarnablesLocked() - return int64(len(t.stringsLocked())) - })) + t.mu.Lock() + defer t.mu.Unlock() + _, exists := t.warnableVal[w] + return exists } // SetUnhealthy sets a warningState for the given Warnable with the provided Args, and should be @@ -367,7 +418,7 @@ func (t *Tracker) SetMetricsRegistry(reg *usermetric.Registry) { // SetUnhealthy takes ownership of args. The args can be nil if no additional information is // needed for the unhealthy state. func (t *Tracker) SetUnhealthy(w *Warnable, args Args) { - if t.nil() { + if !buildfeatures.HasHealth || t.nil() { return } t.mu.Lock() @@ -376,7 +427,7 @@ func (t *Tracker) SetUnhealthy(w *Warnable, args Args) { } func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) { - if w == nil { + if !buildfeatures.HasHealth || w == nil { return } @@ -397,25 +448,26 @@ func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) { prevWs := t.warnableVal[w] mak.Set(&t.warnableVal, w, ws) if !ws.Equal(prevWs) { - for _, cb := range t.watchers { - // If the Warnable has been unhealthy for more than its TimeToVisible, the callback should be - // executed immediately. Otherwise, the callback should be enqueued to run once the Warnable - // becomes visible. - if w.IsVisible(ws, t.now) { - go cb(w, w.unhealthyState(ws)) - continue - } - // The time remaining until the Warnable will be visible to the user is the TimeToVisible - // minus the time that has already passed since the Warnable became unhealthy. + change := Change{ + WarnableChanged: true, + Warnable: w, + UnhealthyState: w.unhealthyState(ws), + } + // Publish the change to the event bus. If the change is already visible + // now, publish it immediately; otherwise queue a timer to publish it at + // a future time when it becomes visible. + if w.IsVisible(ws, t.now) { + t.changePub.Publish(change) + } else { visibleIn := w.TimeToVisible - t.now().Sub(brokenSince) - var tc tstime.TimerController = t.clock().AfterFunc(visibleIn, func() { + tc := t.clock().AfterFunc(visibleIn, func() { t.mu.Lock() defer t.mu.Unlock() // Check if the Warnable is still unhealthy, as it could have become healthy between the time // the timer was set for and the time it was executed. if t.warnableVal[w] != nil { - go cb(w, w.unhealthyState(ws)) + t.changePub.Publish(change) delete(t.pendingVisibleTimers, w) } }) @@ -426,7 +478,7 @@ func (t *Tracker) setUnhealthyLocked(w *Warnable, args Args) { // SetHealthy removes any warningState for the given Warnable. func (t *Tracker) SetHealthy(w *Warnable) { - if t.nil() { + if !buildfeatures.HasHealth || t.nil() { return } t.mu.Lock() @@ -435,7 +487,7 @@ func (t *Tracker) SetHealthy(w *Warnable) { } func (t *Tracker) setHealthyLocked(w *Warnable) { - if t.warnableVal[w] == nil { + if !buildfeatures.HasHealth || t.warnableVal[w] == nil { // Nothing to remove return } @@ -448,9 +500,20 @@ func (t *Tracker) setHealthyLocked(w *Warnable) { delete(t.pendingVisibleTimers, w) } - for _, cb := range t.watchers { - go cb(w, nil) + change := Change{ + WarnableChanged: true, + Warnable: w, } + t.changePub.Publish(change) +} + +// notifyWatchersControlChangedLocked calls each watcher to signal that control +// health messages have changed (and should be fetched via CurrentState). +func (t *Tracker) notifyWatchersControlChangedLocked() { + change := Change{ + ControlHealthChanged: true, + } + t.changePub.Publish(change) } // AppendWarnableDebugFlags appends to base any health items that are currently in failed @@ -476,35 +539,23 @@ func (t *Tracker) AppendWarnableDebugFlags(base []string) []string { return ret } -// RegisterWatcher adds a function that will be called whenever the health state of any Warnable changes. -// If a Warnable becomes unhealthy or its unhealthy state is updated, the callback will be called with its -// current Representation. -// If a Warnable becomes healthy, the callback will be called with ws set to nil. -// The provided callback function will be executed in its own goroutine. The returned function can be used -// to unregister the callback. -func (t *Tracker) RegisterWatcher(cb func(w *Warnable, r *UnhealthyState)) (unregister func()) { - if t.nil() { - return func() {} - } - t.initOnce.Do(t.doOnceInit) - t.mu.Lock() - defer t.mu.Unlock() - if t.watchers == nil { - t.watchers = set.HandleSet[func(*Warnable, *UnhealthyState)]{} - } - handle := t.watchers.Add(cb) - if t.timer == nil { - t.timer = t.clock().AfterFunc(time.Minute, t.timerSelfCheck) - } - return func() { - t.mu.Lock() - defer t.mu.Unlock() - delete(t.watchers, handle) - if len(t.watchers) == 0 && t.timer != nil { - t.timer.Stop() - t.timer = nil - } - } +// Change is used to communicate a change to health. This could either be due to +// a Warnable changing from health to unhealthy (or vice-versa), or because the +// health messages received from the control-plane have changed. +// +// Exactly one *Changed field will be true. +type Change struct { + // ControlHealthChanged indicates it was health messages from the + // control-plane server that changed. + ControlHealthChanged bool + + // WarnableChanged indicates it was a client Warnable which changed state. + WarnableChanged bool + // Warnable is whose health changed, as indicated in UnhealthyState. + Warnable *Warnable + // UnhealthyState is set if the changed Warnable is now unhealthy, or nil + // if Warnable is now healthy. + UnhealthyState *UnhealthyState } // SetRouterHealth sets the state of the wgengine/router.Router. @@ -637,13 +688,15 @@ func (t *Tracker) updateLegacyErrorWarnableLocked(key Subsystem, err error) { } } -func (t *Tracker) SetControlHealth(problems []string) { +func (t *Tracker) SetControlHealth(problems map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage) { if t.nil() { return } t.mu.Lock() defer t.mu.Unlock() - t.controlHealth = problems + + t.controlMessages = problems + t.selfCheckLocked() } @@ -927,8 +980,8 @@ func (t *Tracker) selfCheckLocked() { // OverallError returns a summary of the health state. // -// If there are multiple problems, the error will be of type -// multierr.Error. +// If there are multiple problems, the error will be joined using +// [errors.Join]. func (t *Tracker) OverallError() error { if t.nil() { return nil @@ -939,13 +992,13 @@ func (t *Tracker) OverallError() error { return t.multiErrLocked() } -// Strings() returns a string array containing the Text of all Warnings -// currently known to the Tracker. These strings can be presented to the -// user, although ideally you would use the Code property on each Warning -// to show a localized version of them instead. -// This function is here for legacy compatibility purposes and is deprecated. +// Strings() returns a string array containing the Text of all Warnings and +// ControlHealth messages currently known to the Tracker. These strings can be +// presented to the user, although ideally you would use the Code property on +// each Warning to show a localized version of them instead. This function is +// here for legacy compatibility purposes and is deprecated. func (t *Tracker) Strings() []string { - if t.nil() { + if !buildfeatures.HasHealth || t.nil() { return nil } t.mu.Lock() @@ -954,6 +1007,9 @@ func (t *Tracker) Strings() []string { } func (t *Tracker) stringsLocked() []string { + if !buildfeatures.HasHealth { + return nil + } result := []string{} for w, ws := range t.warnableVal { if !w.IsVisible(ws, t.now) { @@ -969,6 +1025,24 @@ func (t *Tracker) stringsLocked() []string { result = append(result, w.Text(ws.Args)) } } + + warnLen := len(result) + for _, c := range t.controlMessages { + var msg string + if c.Title != "" && c.Text != "" { + msg = c.Title + ": " + c.Text + } else if c.Title != "" { + msg = c.Title + "." + } else if c.Text != "" { + msg = c.Text + } + if c.PrimaryAction != nil { + msg = msg + " " + c.PrimaryAction.Label + ": " + c.PrimaryAction.URL + } + result = append(result, msg) + } + sort.Strings(result[warnLen:]) + return result } @@ -988,7 +1062,7 @@ func (t *Tracker) errorsLocked() []error { // This function is here for legacy compatibility purposes and is deprecated. func (t *Tracker) multiErrLocked() error { errs := t.errorsLocked() - return multierr.New(errs...) + return errors.Join(errs...) } var fakeErrForTesting = envknob.RegisterString("TS_DEBUG_FAKE_HEALTH_ERROR") @@ -996,6 +1070,9 @@ var fakeErrForTesting = envknob.RegisterString("TS_DEBUG_FAKE_HEALTH_ERROR") // updateBuiltinWarnablesLocked performs a number of checks on the state of the backend, // and adds/removes Warnings from the Tracker as needed. func (t *Tracker) updateBuiltinWarnablesLocked() { + if !buildfeatures.HasHealth { + return + } t.updateWarmingUpWarnableLocked() if w, show := t.showUpdateWarnable(); show { @@ -1149,14 +1226,10 @@ func (t *Tracker) updateBuiltinWarnablesLocked() { t.setHealthyLocked(derpRegionErrorWarnable) } - if len(t.controlHealth) > 0 { - for _, s := range t.controlHealth { - t.setUnhealthyLocked(controlHealthWarnable, Args{ - ArgError: s, - }) - } - } else { - t.setHealthyLocked(controlHealthWarnable) + // Check if control health messages have changed + if !maps.EqualFunc(t.lastNotifiedControlMessages, t.controlMessages, tailcfg.DisplayMessage.Equal) { + t.lastNotifiedControlMessages = t.controlMessages + t.notifyWatchersControlChangedLocked() } if err := envknob.ApplyDiskConfigError(); err != nil { @@ -1238,11 +1311,17 @@ func (s *ReceiveFuncStats) Name() string { } func (s *ReceiveFuncStats) Enter() { + if !buildfeatures.HasHealth { + return + } s.numCalls.Add(1) s.inCall.Store(true) } func (s *ReceiveFuncStats) Exit() { + if !buildfeatures.HasHealth { + return + } s.inCall.Store(false) } @@ -1251,7 +1330,7 @@ func (s *ReceiveFuncStats) Exit() { // // If t is nil, it returns nil. func (t *Tracker) ReceiveFuncStats(which ReceiveFunc) *ReceiveFuncStats { - if t == nil { + if !buildfeatures.HasHealth || t == nil { return nil } t.initOnce.Do(t.doOnceInit) @@ -1259,6 +1338,9 @@ func (t *Tracker) ReceiveFuncStats(which ReceiveFunc) *ReceiveFuncStats { } func (t *Tracker) doOnceInit() { + if !buildfeatures.HasHealth { + return + } for i := range t.MagicSockReceiveFuncs { f := &t.MagicSockReceiveFuncs[i] f.name = (ReceiveFunc(i)).String() @@ -1307,10 +1389,3 @@ func (t *Tracker) LastNoiseDialWasRecent() bool { t.lastNoiseDial = now return dur < 2*time.Minute } - -const MetricLabelWarning = "warning" - -type metricHealthMessageLabel struct { - // TODO: break down by warnable.severity as well? - Type string -} diff --git a/vendor/tailscale.com/health/healthmsg/healthmsg.go b/vendor/tailscale.com/health/healthmsg/healthmsg.go index 6c23767..5ea1c73 100644 --- a/vendor/tailscale.com/health/healthmsg/healthmsg.go +++ b/vendor/tailscale.com/health/healthmsg/healthmsg.go @@ -8,8 +8,10 @@ package healthmsg const ( - WarnAcceptRoutesOff = "Some peers are advertising routes but --accept-routes is false" - TailscaleSSHOnBut = "Tailscale SSH enabled, but " // + ... something from caller - LockedOut = "this node is locked out; it will not have connectivity until it is signed. For more info, see https://tailscale.com/s/locked-out" - WarnExitNodeUsage = "The following issues on your machine will likely make usage of exit nodes impossible" + WarnAcceptRoutesOff = "Some peers are advertising routes but --accept-routes is false" + TailscaleSSHOnBut = "Tailscale SSH enabled, but " // + ... something from caller + LockedOut = "this node is locked out; it will not have connectivity until it is signed. For more info, see https://tailscale.com/s/locked-out" + WarnExitNodeUsage = "The following issues on your machine will likely make usage of exit nodes impossible" + DisableRPFilter = "Please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310" + InMemoryTailnetLockState = "Tailnet Lock state is only being stored in-memory. Set --statedir to store state on disk, which is more secure. See https://tailscale.com/kb/1226/tailnet-lock#tailnet-lock-state" ) diff --git a/vendor/tailscale.com/health/state.go b/vendor/tailscale.com/health/state.go index c06f6ef..e6d937b 100644 --- a/vendor/tailscale.com/health/state.go +++ b/vendor/tailscale.com/health/state.go @@ -4,11 +4,20 @@ package health import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" "time" + + "tailscale.com/feature/buildfeatures" + "tailscale.com/tailcfg" ) // State contains the health status of the backend, and is // provided to the client UI via LocalAPI through ipn.Notify. +// +// It is also exposed via c2n for debugging purposes, so try +// not to change its structure too gratuitously. type State struct { // Each key-value pair in Warnings represents a Warnable that is currently // unhealthy. If a Warnable is healthy, it will not be present in this map. @@ -21,16 +30,56 @@ type State struct { } // UnhealthyState contains information to be shown to the user to inform them -// that a Warnable is currently unhealthy. +// that a [Warnable] is currently unhealthy or [tailcfg.DisplayMessage] is being +// sent from the control-plane. type UnhealthyState struct { WarnableCode WarnableCode Severity Severity Title string Text string - BrokenSince *time.Time `json:",omitempty"` - Args Args `json:",omitempty"` - DependsOn []WarnableCode `json:",omitempty"` - ImpactsConnectivity bool `json:",omitempty"` + BrokenSince *time.Time `json:",omitempty"` + Args Args `json:",omitempty"` + DependsOn []WarnableCode `json:",omitempty"` + ImpactsConnectivity bool `json:",omitempty"` + PrimaryAction *UnhealthyStateAction `json:",omitempty"` + + // ETag identifies a specific version of an UnhealthyState. If the contents + // of the other fields of two UnhealthyStates are the same, the ETags will + // be the same. If the contents differ, the ETags will also differ. The + // implementation is not defined and the value is opaque: it might be a + // hash, it might be a simple counter. Implementations should not rely on + // any specific implementation detail or format of the ETag string other + // than string (in)equality. + ETag string `json:",omitzero"` +} + +// hash computes a deep hash of UnhealthyState which will be stable across +// different runs of the same binary. +func (u UnhealthyState) hash() []byte { + hasher := sha256.New() + enc := json.NewEncoder(hasher) + + // hash.Hash.Write never returns an error, so this will only fail if u is + // not marshalable, in which case we have much bigger problems. + _ = enc.Encode(u) + return hasher.Sum(nil) +} + +// withETag returns a copy of UnhealthyState with an ETag set. The ETag will be +// the same for all UnhealthyState instances that are equal. If calculating the +// ETag errors, it returns a copy of the UnhealthyState with an empty ETag. +func (u UnhealthyState) withETag() UnhealthyState { + u.ETag = "" + u.ETag = hex.EncodeToString(u.hash()) + return u +} + +// UnhealthyStateAction represents an action (URL and link) to be presented to +// the user associated with an [UnhealthyState]. Analogous to +// [tailcfg.DisplayMessageAction]. +type UnhealthyStateAction struct { + URL string + Label string } // unhealthyState returns a unhealthyState of the Warnable given its current warningState. @@ -72,7 +121,7 @@ func (w *Warnable) unhealthyState(ws *warningState) *UnhealthyState { // The returned State is a snapshot of shared memory, and the caller should not // mutate the returned value. func (t *Tracker) CurrentState() *State { - if t.nil() { + if !buildfeatures.HasHealth || t.nil() { return &State{} } @@ -95,7 +144,28 @@ func (t *Tracker) CurrentState() *State { // that are unhealthy. continue } - wm[w.Code] = *w.unhealthyState(ws) + state := w.unhealthyState(ws) + wm[w.Code] = state.withETag() + } + + for id, msg := range t.lastNotifiedControlMessages { + state := UnhealthyState{ + WarnableCode: WarnableCode("control-health." + id), + Severity: severityFromTailcfg(msg.Severity), + Title: msg.Title, + Text: msg.Text, + ImpactsConnectivity: msg.ImpactsConnectivity, + // TODO(tailscale/corp#27759): DependsOn? + } + + if msg.PrimaryAction != nil { + state.PrimaryAction = &UnhealthyStateAction{ + URL: msg.PrimaryAction.URL, + Label: msg.PrimaryAction.Label, + } + } + + wm[state.WarnableCode] = state.withETag() } return &State{ @@ -103,6 +173,17 @@ func (t *Tracker) CurrentState() *State { } } +func severityFromTailcfg(s tailcfg.DisplayMessageSeverity) Severity { + switch s { + case tailcfg.SeverityHigh: + return SeverityHigh + case tailcfg.SeverityLow: + return SeverityLow + default: + return SeverityMedium + } +} + // isEffectivelyHealthyLocked reports whether w is effectively healthy. // That means it's either actually healthy or it has a dependency that // that's unhealthy, so we should treat w as healthy to not spam users diff --git a/vendor/tailscale.com/health/usermetrics.go b/vendor/tailscale.com/health/usermetrics.go new file mode 100644 index 0000000..110c57b --- /dev/null +++ b/vendor/tailscale.com/health/usermetrics.go @@ -0,0 +1,52 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_health && !ts_omit_usermetrics + +package health + +import ( + "expvar" + + "tailscale.com/feature/buildfeatures" + "tailscale.com/util/usermetric" +) + +const MetricLabelWarning = "warning" + +type metricHealthMessageLabel struct { + // TODO: break down by warnable.severity as well? + Type string +} + +// SetMetricsRegistry sets up the metrics for the Tracker. It takes +// a usermetric.Registry and registers the metrics there. +func (t *Tracker) SetMetricsRegistry(reg *usermetric.Registry) { + if !buildfeatures.HasHealth { + return + } + + if reg == nil || t.metricHealthMessage != nil { + return + } + + m := usermetric.NewMultiLabelMapWithRegistry[metricHealthMessageLabel]( + reg, + "tailscaled_health_messages", + "gauge", + "Number of health messages broken down by type.", + ) + + m.Set(metricHealthMessageLabel{ + Type: MetricLabelWarning, + }, expvar.Func(func() any { + if t.nil() { + return 0 + } + t.mu.Lock() + defer t.mu.Unlock() + t.updateBuiltinWarnablesLocked() + return int64(len(t.stringsLocked())) + })) + t.metricHealthMessage = m +} diff --git a/vendor/tailscale.com/health/usermetrics_omit.go b/vendor/tailscale.com/health/usermetrics_omit.go new file mode 100644 index 0000000..9d5e35b --- /dev/null +++ b/vendor/tailscale.com/health/usermetrics_omit.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_health || ts_omit_usermetrics + +package health + +func (t *Tracker) SetMetricsRegistry(any) {} diff --git a/vendor/tailscale.com/health/warnings.go b/vendor/tailscale.com/health/warnings.go index 7a21f96..a9c4b34 100644 --- a/vendor/tailscale.com/health/warnings.go +++ b/vendor/tailscale.com/health/warnings.go @@ -8,244 +8,279 @@ import ( "runtime" "time" + "tailscale.com/feature/buildfeatures" + "tailscale.com/tsconst" "tailscale.com/version" ) +func condRegister(f func() *Warnable) *Warnable { + if !buildfeatures.HasHealth { + return nil + } + return f() +} + /** This file contains definitions for the Warnables maintained within this `health` package. */ // updateAvailableWarnable is a Warnable that warns the user that an update is available. -var updateAvailableWarnable = Register(&Warnable{ - Code: "update-available", - Title: "Update available", - Severity: SeverityLow, - Text: func(args Args) string { - if version.IsMacAppStore() || version.IsAppleTV() || version.IsMacSys() || version.IsWindowsGUI() || runtime.GOOS == "android" { - return fmt.Sprintf("An update from version %s to %s is available.", args[ArgCurrentVersion], args[ArgAvailableVersion]) - } else { - return fmt.Sprintf("An update from version %s to %s is available. Run `tailscale update` or `tailscale set --auto-update` to update now.", args[ArgCurrentVersion], args[ArgAvailableVersion]) - } - }, +var updateAvailableWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableUpdateAvailable, + Title: "Update available", + Severity: SeverityLow, + Text: func(args Args) string { + if version.IsMacAppStore() || version.IsAppleTV() || version.IsMacSys() || version.IsWindowsGUI() || runtime.GOOS == "android" { + return fmt.Sprintf("An update from version %s to %s is available.", args[ArgCurrentVersion], args[ArgAvailableVersion]) + } else { + return fmt.Sprintf("An update from version %s to %s is available. Run `tailscale update` or `tailscale set --auto-update` to update now.", args[ArgCurrentVersion], args[ArgAvailableVersion]) + } + }, + } }) // securityUpdateAvailableWarnable is a Warnable that warns the user that an important security update is available. -var securityUpdateAvailableWarnable = Register(&Warnable{ - Code: "security-update-available", - Title: "Security update available", - Severity: SeverityMedium, - Text: func(args Args) string { - if version.IsMacAppStore() || version.IsAppleTV() || version.IsMacSys() || version.IsWindowsGUI() || runtime.GOOS == "android" { - return fmt.Sprintf("A security update from version %s to %s is available.", args[ArgCurrentVersion], args[ArgAvailableVersion]) - } else { - return fmt.Sprintf("A security update from version %s to %s is available. Run `tailscale update` or `tailscale set --auto-update` to update now.", args[ArgCurrentVersion], args[ArgAvailableVersion]) - } - }, +var securityUpdateAvailableWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableSecurityUpdateAvailable, + Title: "Security update available", + Severity: SeverityMedium, + Text: func(args Args) string { + if version.IsMacAppStore() || version.IsAppleTV() || version.IsMacSys() || version.IsWindowsGUI() || runtime.GOOS == "android" { + return fmt.Sprintf("A security update from version %s to %s is available.", args[ArgCurrentVersion], args[ArgAvailableVersion]) + } else { + return fmt.Sprintf("A security update from version %s to %s is available. Run `tailscale update` or `tailscale set --auto-update` to update now.", args[ArgCurrentVersion], args[ArgAvailableVersion]) + } + }, + } }) // unstableWarnable is a Warnable that warns the user that they are using an unstable version of Tailscale // so they won't be surprised by all the issues that may arise. -var unstableWarnable = Register(&Warnable{ - Code: "is-using-unstable-version", - Title: "Using an unstable version", - Severity: SeverityLow, - Text: StaticMessage("This is an unstable version of Tailscale meant for testing and development purposes. Please report any issues to Tailscale."), +var unstableWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableIsUsingUnstableVersion, + Title: "Using an unstable version", + Severity: SeverityLow, + Text: StaticMessage("This is an unstable version of Tailscale meant for testing and development purposes. Please report any issues to Tailscale."), + } }) // NetworkStatusWarnable is a Warnable that warns the user that the network is down. -var NetworkStatusWarnable = Register(&Warnable{ - Code: "network-status", - Title: "Network down", - Severity: SeverityMedium, - Text: StaticMessage("Tailscale cannot connect because the network is down. Check your Internet connection."), - ImpactsConnectivity: true, - TimeToVisible: 5 * time.Second, +var NetworkStatusWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableNetworkStatus, + Title: "Network down", + Severity: SeverityMedium, + Text: StaticMessage("Tailscale cannot connect because the network is down. Check your Internet connection."), + ImpactsConnectivity: true, + TimeToVisible: 5 * time.Second, + } }) // IPNStateWarnable is a Warnable that warns the user that Tailscale is stopped. -var IPNStateWarnable = Register(&Warnable{ - Code: "wantrunning-false", - Title: "Tailscale off", - Severity: SeverityLow, - Text: StaticMessage("Tailscale is stopped."), +var IPNStateWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableWantRunningFalse, + Title: "Tailscale off", + Severity: SeverityLow, + Text: StaticMessage("Tailscale is stopped."), + } }) // localLogWarnable is a Warnable that warns the user that the local log is misconfigured. -var localLogWarnable = Register(&Warnable{ - Code: "local-log-config-error", - Title: "Local log misconfiguration", - Severity: SeverityLow, - Text: func(args Args) string { - return fmt.Sprintf("The local log is misconfigured: %v", args[ArgError]) - }, +var localLogWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableLocalLogConfigError, + Title: "Local log misconfiguration", + Severity: SeverityLow, + Text: func(args Args) string { + return fmt.Sprintf("The local log is misconfigured: %v", args[ArgError]) + }, + } }) // LoginStateWarnable is a Warnable that warns the user that they are logged out, // and provides the last login error if available. -var LoginStateWarnable = Register(&Warnable{ - Code: "login-state", - Title: "Logged out", - Severity: SeverityMedium, - Text: func(args Args) string { - if args[ArgError] != "" { - return fmt.Sprintf("You are logged out. The last login error was: %v", args[ArgError]) - } else { - return "You are logged out." - } - }, - DependsOn: []*Warnable{IPNStateWarnable}, +var LoginStateWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableLoginState, + Title: "Logged out", + Severity: SeverityMedium, + Text: func(args Args) string { + if args[ArgError] != "" { + return fmt.Sprintf("You are logged out. The last login error was: %v", args[ArgError]) + } else { + return "You are logged out." + } + }, + DependsOn: []*Warnable{IPNStateWarnable}, + } }) // notInMapPollWarnable is a Warnable that warns the user that we are using a stale network map. -var notInMapPollWarnable = Register(&Warnable{ - Code: "not-in-map-poll", - Title: "Out of sync", - Severity: SeverityMedium, - DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, - Text: StaticMessage("Unable to connect to the Tailscale coordination server to synchronize the state of your tailnet. Peer reachability might degrade over time."), - // 8 minutes reflects a maximum maintenance window for the coordination server. - TimeToVisible: 8 * time.Minute, +var notInMapPollWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableNotInMapPoll, + Title: "Out of sync", + Severity: SeverityMedium, + DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, + Text: StaticMessage("Unable to connect to the Tailscale coordination server to synchronize the state of your tailnet. Peer reachability might degrade over time."), + // 8 minutes reflects a maximum maintenance window for the coordination server. + TimeToVisible: 8 * time.Minute, + } }) // noDERPHomeWarnable is a Warnable that warns the user that Tailscale doesn't have a home DERP. -var noDERPHomeWarnable = Register(&Warnable{ - Code: "no-derp-home", - Title: "No home relay server", - Severity: SeverityMedium, - DependsOn: []*Warnable{NetworkStatusWarnable}, - Text: StaticMessage("Tailscale could not connect to any relay server. Check your Internet connection."), - ImpactsConnectivity: true, - TimeToVisible: 10 * time.Second, +var noDERPHomeWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableNoDERPHome, + Title: "No home relay server", + Severity: SeverityMedium, + DependsOn: []*Warnable{NetworkStatusWarnable}, + Text: StaticMessage("Tailscale could not connect to any relay server. Check your Internet connection."), + ImpactsConnectivity: true, + TimeToVisible: 10 * time.Second, + } }) // noDERPConnectionWarnable is a Warnable that warns the user that Tailscale couldn't connect to a specific DERP server. -var noDERPConnectionWarnable = Register(&Warnable{ - Code: "no-derp-connection", - Title: "Relay server unavailable", - Severity: SeverityMedium, - DependsOn: []*Warnable{ - NetworkStatusWarnable, +var noDERPConnectionWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableNoDERPConnection, + Title: "Relay server unavailable", + Severity: SeverityMedium, + DependsOn: []*Warnable{ + NetworkStatusWarnable, - // Technically noDERPConnectionWarnable could be used to warn about - // failure to connect to a specific DERP server (e.g. your home is derp1 - // but you're trying to connect to a peer's derp4 and are unable) but as - // of 2024-09-25 we only use this for connecting to your home DERP, so - // we depend on noDERPHomeWarnable which is the ability to figure out - // what your DERP home even is. - noDERPHomeWarnable, - }, - Text: func(args Args) string { - if n := args[ArgDERPRegionName]; n != "" { - return fmt.Sprintf("Tailscale could not connect to the '%s' relay server. Your Internet connection might be down, or the server might be temporarily unavailable.", n) - } else { - return fmt.Sprintf("Tailscale could not connect to the relay server with ID '%s'. Your Internet connection might be down, or the server might be temporarily unavailable.", args[ArgDERPRegionID]) - } - }, - ImpactsConnectivity: true, - TimeToVisible: 10 * time.Second, + // Technically noDERPConnectionWarnable could be used to warn about + // failure to connect to a specific DERP server (e.g. your home is derp1 + // but you're trying to connect to a peer's derp4 and are unable) but as + // of 2024-09-25 we only use this for connecting to your home DERP, so + // we depend on noDERPHomeWarnable which is the ability to figure out + // what your DERP home even is. + noDERPHomeWarnable, + }, + Text: func(args Args) string { + if n := args[ArgDERPRegionName]; n != "" { + return fmt.Sprintf("Tailscale could not connect to the '%s' relay server. Your Internet connection might be down, or the server might be temporarily unavailable.", n) + } else { + return fmt.Sprintf("Tailscale could not connect to the relay server with ID '%s'. Your Internet connection might be down, or the server might be temporarily unavailable.", args[ArgDERPRegionID]) + } + }, + ImpactsConnectivity: true, + TimeToVisible: 10 * time.Second, + } }) // derpTimeoutWarnable is a Warnable that warns the user that Tailscale hasn't // heard from the home DERP region for a while. -var derpTimeoutWarnable = Register(&Warnable{ - Code: "derp-timed-out", - Title: "Relay server timed out", - Severity: SeverityMedium, - DependsOn: []*Warnable{ - NetworkStatusWarnable, - noDERPConnectionWarnable, // don't warn about it being stalled if we're not connected - noDERPHomeWarnable, // same reason as noDERPConnectionWarnable's dependency - }, - Text: func(args Args) string { - if n := args[ArgDERPRegionName]; n != "" { - return fmt.Sprintf("Tailscale hasn't heard from the '%s' relay server in %v. The server might be temporarily unavailable, or your Internet connection might be down.", n, args[ArgDuration]) - } else { - return fmt.Sprintf("Tailscale hasn't heard from the home relay server (region ID '%v') in %v. The server might be temporarily unavailable, or your Internet connection might be down.", args[ArgDERPRegionID], args[ArgDuration]) - } - }, +var derpTimeoutWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableDERPTimedOut, + Title: "Relay server timed out", + Severity: SeverityMedium, + DependsOn: []*Warnable{ + NetworkStatusWarnable, + noDERPConnectionWarnable, // don't warn about it being stalled if we're not connected + noDERPHomeWarnable, // same reason as noDERPConnectionWarnable's dependency + }, + Text: func(args Args) string { + if n := args[ArgDERPRegionName]; n != "" { + return fmt.Sprintf("Tailscale hasn't heard from the '%s' relay server in %v. The server might be temporarily unavailable, or your Internet connection might be down.", n, args[ArgDuration]) + } else { + return fmt.Sprintf("Tailscale hasn't heard from the home relay server (region ID '%v') in %v. The server might be temporarily unavailable, or your Internet connection might be down.", args[ArgDERPRegionID], args[ArgDuration]) + } + }, + } }) // derpRegionErrorWarnable is a Warnable that warns the user that a DERP region is reporting an issue. -var derpRegionErrorWarnable = Register(&Warnable{ - Code: "derp-region-error", - Title: "Relay server error", - Severity: SeverityLow, - DependsOn: []*Warnable{NetworkStatusWarnable}, - Text: func(args Args) string { - return fmt.Sprintf("The relay server #%v is reporting an issue: %v", args[ArgDERPRegionID], args[ArgError]) - }, +var derpRegionErrorWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableDERPRegionError, + Title: "Relay server error", + Severity: SeverityLow, + DependsOn: []*Warnable{NetworkStatusWarnable}, + Text: func(args Args) string { + return fmt.Sprintf("The relay server #%v is reporting an issue: %v", args[ArgDERPRegionID], args[ArgError]) + }, + } }) // noUDP4BindWarnable is a Warnable that warns the user that Tailscale couldn't listen for incoming UDP connections. -var noUDP4BindWarnable = Register(&Warnable{ - Code: "no-udp4-bind", - Title: "NAT traversal setup failure", - Severity: SeverityMedium, - DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, - Text: StaticMessage("Tailscale couldn't listen for incoming UDP connections."), - ImpactsConnectivity: true, +var noUDP4BindWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableNoUDP4Bind, + Title: "NAT traversal setup failure", + Severity: SeverityMedium, + DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, + Text: StaticMessage("Tailscale couldn't listen for incoming UDP connections."), + ImpactsConnectivity: true, + } }) // mapResponseTimeoutWarnable is a Warnable that warns the user that Tailscale hasn't received a network map from the coordination server in a while. -var mapResponseTimeoutWarnable = Register(&Warnable{ - Code: "mapresponse-timeout", - Title: "Network map response timeout", - Severity: SeverityMedium, - DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, - Text: func(args Args) string { - return fmt.Sprintf("Tailscale hasn't received a network map from the coordination server in %s.", args[ArgDuration]) - }, +var mapResponseTimeoutWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableMapResponseTimeout, + Title: "Network map response timeout", + Severity: SeverityMedium, + DependsOn: []*Warnable{NetworkStatusWarnable, IPNStateWarnable}, + Text: func(args Args) string { + return fmt.Sprintf("Tailscale hasn't received a network map from the coordination server in %s.", args[ArgDuration]) + }, + } }) // tlsConnectionFailedWarnable is a Warnable that warns the user that Tailscale could not establish an encrypted connection with a server. -var tlsConnectionFailedWarnable = Register(&Warnable{ - Code: "tls-connection-failed", - Title: "Encrypted connection failed", - Severity: SeverityMedium, - DependsOn: []*Warnable{NetworkStatusWarnable}, - Text: func(args Args) string { - return fmt.Sprintf("Tailscale could not establish an encrypted connection with '%q': %v", args[ArgServerName], args[ArgError]) - }, +var tlsConnectionFailedWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableTLSConnectionFailed, + Title: "Encrypted connection failed", + Severity: SeverityMedium, + DependsOn: []*Warnable{NetworkStatusWarnable}, + Text: func(args Args) string { + return fmt.Sprintf("Tailscale could not establish an encrypted connection with '%q': %v", args[ArgServerName], args[ArgError]) + }, + } }) // magicsockReceiveFuncWarnable is a Warnable that warns the user that one of the Magicsock functions is not running. -var magicsockReceiveFuncWarnable = Register(&Warnable{ - Code: "magicsock-receive-func-error", - Title: "MagicSock function not running", - Severity: SeverityMedium, - Text: func(args Args) string { - return fmt.Sprintf("The MagicSock function %s is not running. You might experience connectivity issues.", args[ArgMagicsockFunctionName]) - }, +var magicsockReceiveFuncWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableMagicsockReceiveFuncError, + Title: "MagicSock function not running", + Severity: SeverityMedium, + Text: func(args Args) string { + return fmt.Sprintf("The MagicSock function %s is not running. You might experience connectivity issues.", args[ArgMagicsockFunctionName]) + }, + } }) // testWarnable is a Warnable that is used within this package for testing purposes only. -var testWarnable = Register(&Warnable{ - Code: "test-warnable", - Title: "Test warnable", - Severity: SeverityLow, - Text: func(args Args) string { - return args[ArgError] - }, +var testWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableTestWarnable, + Title: "Test warnable", + Severity: SeverityLow, + Text: func(args Args) string { + return args[ArgError] + }, + } }) // applyDiskConfigWarnable is a Warnable that warns the user that there was an error applying the envknob config stored on disk. -var applyDiskConfigWarnable = Register(&Warnable{ - Code: "apply-disk-config", - Title: "Could not apply configuration", - Severity: SeverityMedium, - Text: func(args Args) string { - return fmt.Sprintf("An error occurred applying the Tailscale envknob configuration stored on disk: %v", args[ArgError]) - }, -}) - -// controlHealthWarnable is a Warnable that warns the user that the coordination server is reporting an health issue. -var controlHealthWarnable = Register(&Warnable{ - Code: "control-health", - Title: "Coordination server reports an issue", - Severity: SeverityMedium, - Text: func(args Args) string { - return fmt.Sprintf("The coordination server is reporting an health issue: %v", args[ArgError]) - }, +var applyDiskConfigWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableApplyDiskConfig, + Title: "Could not apply configuration", + Severity: SeverityMedium, + Text: func(args Args) string { + return fmt.Sprintf("An error occurred applying the Tailscale envknob configuration stored on disk: %v", args[ArgError]) + }, + } }) // warmingUpWarnableDuration is the duration for which the warmingUpWarnable is reported by the backend after the user @@ -255,9 +290,11 @@ const warmingUpWarnableDuration = 5 * time.Second // warmingUpWarnable is a Warnable that is reported by the backend when it is starting up, for a maximum time of // warmingUpWarnableDuration. The GUIs use the presence of this Warnable to prevent showing any other warnings until // the backend is fully started. -var warmingUpWarnable = Register(&Warnable{ - Code: "warming-up", - Title: "Tailscale is starting", - Severity: SeverityLow, - Text: StaticMessage("Tailscale is starting. Please wait."), +var warmingUpWarnable = condRegister(func() *Warnable { + return &Warnable{ + Code: tsconst.HealthWarnableWarmingUp, + Title: "Tailscale is starting", + Severity: SeverityLow, + Text: StaticMessage("Tailscale is starting. Please wait."), + } }) diff --git a/vendor/tailscale.com/hostinfo/hostinfo.go b/vendor/tailscale.com/hostinfo/hostinfo.go index d952ce6..3e8f2f9 100644 --- a/vendor/tailscale.com/hostinfo/hostinfo.go +++ b/vendor/tailscale.com/hostinfo/hostinfo.go @@ -21,6 +21,7 @@ import ( "go4.org/mem" "tailscale.com/envknob" "tailscale.com/tailcfg" + "tailscale.com/types/lazy" "tailscale.com/types/opt" "tailscale.com/types/ptr" "tailscale.com/util/cloudenv" @@ -42,7 +43,7 @@ func RegisterHostinfoNewHook(f func(*tailcfg.Hostinfo)) { // New returns a partially populated Hostinfo for the current host. func New() *tailcfg.Hostinfo { - hostname, _ := os.Hostname() + hostname, _ := Hostname() hostname = dnsname.FirstLabel(hostname) hi := &tailcfg.Hostinfo{ IPNVersion: version.Long(), @@ -497,5 +498,32 @@ func IsNATLabGuestVM() bool { return false } -// NAT Lab VMs have a unique MAC address prefix. -// See +const copyV86DeviceModel = "copy-v86" + +var isV86Cache lazy.SyncValue[bool] + +// IsInVM86 reports whether we're running in the copy/v86 wasm emulator, +// https://github.com/copy/v86/. +func IsInVM86() bool { + return isV86Cache.Get(func() bool { + return New().DeviceModel == copyV86DeviceModel + }) +} + +type hostnameQuery func() (string, error) + +var hostnameFn atomic.Value // of func() (string, error) + +// SetHostNameFn sets a custom function for querying the system hostname. +func SetHostnameFn(fn hostnameQuery) { + hostnameFn.Store(fn) +} + +// Hostname returns the system hostname using the function +// set by SetHostNameFn. We will fallback to os.Hostname. +func Hostname() (string, error) { + if fn, ok := hostnameFn.Load().(hostnameQuery); ok && fn != nil { + return fn() + } + return os.Hostname() +} diff --git a/vendor/tailscale.com/hostinfo/hostinfo_plan9.go b/vendor/tailscale.com/hostinfo/hostinfo_plan9.go new file mode 100644 index 0000000..f9aa30e --- /dev/null +++ b/vendor/tailscale.com/hostinfo/hostinfo_plan9.go @@ -0,0 +1,39 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package hostinfo + +import ( + "bytes" + "os" + "strings" + + "tailscale.com/tailcfg" + "tailscale.com/types/lazy" +) + +func init() { + RegisterHostinfoNewHook(func(hi *tailcfg.Hostinfo) { + if isPlan9V86() { + hi.DeviceModel = copyV86DeviceModel + } + }) +} + +var isPlan9V86Cache lazy.SyncValue[bool] + +// isPlan9V86 reports whether we're running in the wasm +// environment (https://github.com/copy/v86/). +func isPlan9V86() bool { + return isPlan9V86Cache.Get(func() bool { + v, _ := os.ReadFile("/dev/cputype") + s, _, _ := strings.Cut(string(v), " ") + if s != "PentiumIV/Xeon" { + return false + } + + v, _ = os.ReadFile("/dev/config") + v, _, _ = bytes.Cut(v, []byte{'\n'}) + return string(v) == "# pcvm - small kernel used to run in vm" + }) +} diff --git a/vendor/tailscale.com/internal/client/tailscale/identityfederation.go b/vendor/tailscale.com/internal/client/tailscale/identityfederation.go new file mode 100644 index 0000000..3bb64b2 --- /dev/null +++ b/vendor/tailscale.com/internal/client/tailscale/identityfederation.go @@ -0,0 +1,29 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tailscale + +import ( + "context" + + "tailscale.com/feature" +) + +// HookResolveAuthKeyViaWIF resolves to [identityfederation.resolveAuthKey] when the +// corresponding feature tag is enabled in the build process. +// +// baseURL is the URL of the control server used for token exchange and authkey generation. +// clientID is the federated client ID used for token exchange +// idToken is the Identity token from the identity provider +// tags is the list of tags to be associated with the auth key +// audience is the federated audience acquired by configuring +// the trusted credential in the admin UI +var HookResolveAuthKeyViaWIF feature.Hook[func(ctx context.Context, baseURL, clientID, idToken, audience string, tags []string) (string, error)] + +// HookExchangeJWTForTokenViaWIF resolves to [identityfederation.exchangeJWTForToken] when the +// corresponding feature tag is enabled in the build process. +// +// baseURL is the URL of the control server used for token exchange +// clientID is the federated client ID used for token exchange +// idToken is the Identity token from the identity provider +var HookExchangeJWTForTokenViaWIF feature.Hook[func(ctx context.Context, baseURL, clientID, idToken string) (string, error)] diff --git a/vendor/tailscale.com/internal/client/tailscale/oauthkeys.go b/vendor/tailscale.com/internal/client/tailscale/oauthkeys.go new file mode 100644 index 0000000..21102ce --- /dev/null +++ b/vendor/tailscale.com/internal/client/tailscale/oauthkeys.go @@ -0,0 +1,20 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tailscale + +import ( + "context" + + "tailscale.com/feature" +) + +// HookResolveAuthKey resolves to [oauthkey.ResolveAuthKey] when the +// corresponding feature tag is enabled in the build process. +// +// authKey is a standard device auth key or an OAuth client secret to +// resolve into an auth key. +// tags is the list of tags being advertised by the client (required to be +// provided for the OAuth secret case, and required to be the same as the +// list of tags for which the OAuth secret is allowed to issue auth keys). +var HookResolveAuthKey feature.Hook[func(ctx context.Context, authKey string, tags []string) (string, error)] diff --git a/vendor/tailscale.com/internal/client/tailscale/tailscale.go b/vendor/tailscale.com/internal/client/tailscale/tailscale.go new file mode 100644 index 0000000..0e603bf --- /dev/null +++ b/vendor/tailscale.com/internal/client/tailscale/tailscale.go @@ -0,0 +1,86 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package tailscale provides a minimal control plane API client for internal +// use. A full client for 3rd party use is available at +// tailscale.com/client/tailscale/v2. The internal client is provided to avoid +// having to import that whole package. +package tailscale + +import ( + "errors" + "io" + "net/http" + + tsclient "tailscale.com/client/tailscale" +) + +// maxSize is the maximum read size (10MB) of responses from the server. +const maxReadSize = 10 << 20 + +func init() { + tsclient.I_Acknowledge_This_API_Is_Unstable = true +} + +// AuthMethod is an alias to tailscale.com/client/tailscale. +type AuthMethod = tsclient.AuthMethod + +// APIKey is an alias to tailscale.com/client/tailscale. +type APIKey = tsclient.APIKey + +// Device is an alias to tailscale.com/client/tailscale. +type Device = tsclient.Device + +// DeviceFieldsOpts is an alias to tailscale.com/client/tailscale. +type DeviceFieldsOpts = tsclient.DeviceFieldsOpts + +// Key is an alias to tailscale.com/client/tailscale. +type Key = tsclient.Key + +// KeyCapabilities is an alias to tailscale.com/client/tailscale. +type KeyCapabilities = tsclient.KeyCapabilities + +// KeyDeviceCapabilities is an alias to tailscale.com/client/tailscale. +type KeyDeviceCapabilities = tsclient.KeyDeviceCapabilities + +// KeyDeviceCreateCapabilities is an alias to tailscale.com/client/tailscale. +type KeyDeviceCreateCapabilities = tsclient.KeyDeviceCreateCapabilities + +// ErrResponse is an alias to tailscale.com/client/tailscale. +type ErrResponse = tsclient.ErrResponse + +// NewClient is an alias to tailscale.com/client/tailscale. +func NewClient(tailnet string, auth AuthMethod) *Client { + return &Client{ + Client: tsclient.NewClient(tailnet, auth), + } +} + +// Client is a wrapper of tailscale.com/client/tailscale. +type Client struct { + *tsclient.Client +} + +// HandleErrorResponse is an alias to tailscale.com/client/tailscale. +func HandleErrorResponse(b []byte, resp *http.Response) error { + return tsclient.HandleErrorResponse(b, resp) +} + +// SendRequest add the authentication key to the request and sends it. It +// receives the response and reads up to 10MB of it. +func SendRequest(c *Client, req *http.Request) ([]byte, *http.Response, error) { + resp, err := c.Do(req) + if err != nil { + return nil, resp, err + } + defer resp.Body.Close() + + // Read response. Limit the response to 10MB. + // This limit is carried over from client/tailscale/tailscale.go. + body := io.LimitReader(resp.Body, maxReadSize+1) + b, err := io.ReadAll(body) + if len(b) > maxReadSize { + err = errors.New("API response too large") + } + return b, resp, err +} diff --git a/vendor/tailscale.com/internal/client/tailscale/vip_service.go b/vendor/tailscale.com/internal/client/tailscale/vip_service.go new file mode 100644 index 0000000..48c59ce --- /dev/null +++ b/vendor/tailscale.com/internal/client/tailscale/vip_service.go @@ -0,0 +1,133 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tailscale + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + "tailscale.com/tailcfg" + "tailscale.com/util/httpm" +) + +// VIPService is a Tailscale VIPService with Tailscale API JSON representation. +type VIPService struct { + // Name is a VIPService name in form svc:. + Name tailcfg.ServiceName `json:"name,omitempty"` + // Addrs are the IP addresses of the VIP Service. There are two addresses: + // the first is IPv4 and the second is IPv6. + // When creating a new VIP Service, the IP addresses are optional: if no + // addresses are specified then they will be selected. If an IPv4 address is + // specified at index 0, then that address will attempt to be used. An IPv6 + // address can not be specified upon creation. + Addrs []string `json:"addrs,omitempty"` + // Comment is an optional text string for display in the admin panel. + Comment string `json:"comment,omitempty"` + // Annotations are optional key-value pairs that can be used to store arbitrary metadata. + Annotations map[string]string `json:"annotations,omitempty"` + // Ports are the ports of a VIPService that will be configured via Tailscale serve config. + // If set, any node wishing to advertise this VIPService must have this port configured via Tailscale serve. + Ports []string `json:"ports,omitempty"` + // Tags are optional ACL tags that will be applied to the VIPService. + Tags []string `json:"tags,omitempty"` +} + +// VIPServiceList represents the JSON response to the list VIP Services API. +type VIPServiceList struct { + VIPServices []VIPService `json:"vipServices"` +} + +// GetVIPService retrieves a VIPService by its name. It returns 404 if the VIPService is not found. +func (client *Client) GetVIPService(ctx context.Context, name tailcfg.ServiceName) (*VIPService, error) { + path := client.BuildTailnetURL("vip-services", name.String()) + req, err := http.NewRequestWithContext(ctx, httpm.GET, path, nil) + if err != nil { + return nil, fmt.Errorf("error creating new HTTP request: %w", err) + } + b, resp, err := SendRequest(client, req) + if err != nil { + return nil, fmt.Errorf("error making Tailsale API request: %w", err) + } + // If status code was not successful, return the error. + // TODO: Change the check for the StatusCode to include other 2XX success codes. + if resp.StatusCode != http.StatusOK { + return nil, HandleErrorResponse(b, resp) + } + svc := &VIPService{} + if err := json.Unmarshal(b, svc); err != nil { + return nil, err + } + return svc, nil +} + +// ListVIPServices retrieves all existing Services and returns them as a list. +func (client *Client) ListVIPServices(ctx context.Context) (*VIPServiceList, error) { + path := client.BuildTailnetURL("vip-services") + req, err := http.NewRequestWithContext(ctx, httpm.GET, path, nil) + if err != nil { + return nil, fmt.Errorf("error creating new HTTP request: %w", err) + } + b, resp, err := SendRequest(client, req) + if err != nil { + return nil, fmt.Errorf("error making Tailsale API request: %w", err) + } + // If status code was not successful, return the error. + // TODO: Change the check for the StatusCode to include other 2XX success codes. + if resp.StatusCode != http.StatusOK { + return nil, HandleErrorResponse(b, resp) + } + result := &VIPServiceList{} + if err := json.Unmarshal(b, result); err != nil { + return nil, err + } + return result, nil +} + +// CreateOrUpdateVIPService creates or updates a VIPService by its name. Caller must ensure that, if the +// VIPService already exists, the VIPService is fetched first to ensure that any auto-allocated IP addresses are not +// lost during the update. If the VIPService was created without any IP addresses explicitly set (so that they were +// auto-allocated by Tailscale) any subsequent request to this function that does not set any IP addresses will error. +func (client *Client) CreateOrUpdateVIPService(ctx context.Context, svc *VIPService) error { + data, err := json.Marshal(svc) + if err != nil { + return err + } + path := client.BuildTailnetURL("vip-services", svc.Name.String()) + req, err := http.NewRequestWithContext(ctx, httpm.PUT, path, bytes.NewBuffer(data)) + if err != nil { + return fmt.Errorf("error creating new HTTP request: %w", err) + } + b, resp, err := SendRequest(client, req) + if err != nil { + return fmt.Errorf("error making Tailscale API request: %w", err) + } + // If status code was not successful, return the error. + // TODO: Change the check for the StatusCode to include other 2XX success codes. + if resp.StatusCode != http.StatusOK { + return HandleErrorResponse(b, resp) + } + return nil +} + +// DeleteVIPService deletes a VIPService by its name. It returns an error if the VIPService +// does not exist or if the deletion fails. +func (client *Client) DeleteVIPService(ctx context.Context, name tailcfg.ServiceName) error { + path := client.BuildTailnetURL("vip-services", name.String()) + req, err := http.NewRequestWithContext(ctx, httpm.DELETE, path, nil) + if err != nil { + return fmt.Errorf("error creating new HTTP request: %w", err) + } + b, resp, err := SendRequest(client, req) + if err != nil { + return fmt.Errorf("error making Tailscale API request: %w", err) + } + // If status code was not successful, return the error. + if resp.StatusCode != http.StatusOK { + return HandleErrorResponse(b, resp) + } + return nil +} diff --git a/vendor/tailscale.com/ipn/auditlog/auditlog.go b/vendor/tailscale.com/ipn/auditlog/auditlog.go deleted file mode 100644 index 30f3921..0000000 --- a/vendor/tailscale.com/ipn/auditlog/auditlog.go +++ /dev/null @@ -1,466 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package auditlog provides a mechanism for logging audit events. -package auditlog - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "sort" - "sync" - "time" - - "tailscale.com/ipn" - "tailscale.com/tailcfg" - "tailscale.com/types/logger" - "tailscale.com/util/rands" - "tailscale.com/util/set" -) - -// transaction represents an audit log that has not yet been sent to the control plane. -type transaction struct { - // EventID is the unique identifier for the event being logged. - // This is used on the client side only and is not sent to control. - EventID string `json:",omitempty"` - // Retries is the number of times the logger has attempted to send this log. - // This is used on the client side only and is not sent to control. - Retries int `json:",omitempty"` - - // Action is the action to be logged. It must correspond to a known action in the control plane. - Action tailcfg.ClientAuditAction `json:",omitempty"` - // Details is an opaque string specific to the action being logged. Empty strings may not - // be valid depending on the action being logged. - Details string `json:",omitempty"` - // TimeStamp is the time at which the audit log was generated on the node. - TimeStamp time.Time `json:",omitzero"` -} - -// Transport provides a means for a client to send audit logs to a consumer (typically the control plane). -type Transport interface { - // SendAuditLog sends an audit log to a consumer of audit logs. - // Errors should be checked with [IsRetryableError] for retryability. - SendAuditLog(context.Context, tailcfg.AuditLogRequest) error -} - -// LogStore provides a means for a [Logger] to persist logs to disk or memory. -type LogStore interface { - // Save saves the given data to a persistent store. Save will overwrite existing data - // for the given key. - save(key ipn.ProfileID, txns []*transaction) error - - // Load retrieves the data from a persistent store. Returns a nil slice and - // no error if no data exists for the given key. - load(key ipn.ProfileID) ([]*transaction, error) -} - -// Opts contains the configuration options for a [Logger]. -type Opts struct { - // RetryLimit is the maximum number of attempts the logger will make to send a log before giving up. - RetryLimit int - // Store is the persistent store used to save logs to disk. Must be non-nil. - Store LogStore - // Logf is the logger used to log messages from the audit logger. Must be non-nil. - Logf logger.Logf -} - -// IsRetryableError returns true if the given error is retryable -// See [controlclient.apiResponseError]. Potentially retryable errors implement the Retryable() method. -func IsRetryableError(err error) bool { - var retryable interface{ Retryable() bool } - return errors.As(err, &retryable) && retryable.Retryable() -} - -type backoffOpts struct { - min, max time.Duration - multiplier float64 -} - -// .5, 1, 2, 4, 8, 10, 10, 10, 10, 10... -var defaultBackoffOpts = backoffOpts{ - min: time.Millisecond * 500, - max: 10 * time.Second, - multiplier: 2, -} - -// Logger provides a queue-based mechanism for submitting audit logs to the control plane - or -// another suitable consumer. Logs are stored to disk and retried until they are successfully sent, -// or until they permanently fail. -// -// Each individual profile/controlclient tuple should construct and manage a unique [Logger] instance. -type Logger struct { - logf logger.Logf - retryLimit int // the maximum number of attempts to send a log before giving up. - flusher chan struct{} // channel used to signal a flush operation. - done chan struct{} // closed when the flush worker exits. - ctx context.Context // canceled when the logger is stopped. - ctxCancel context.CancelFunc // cancels ctx. - backoffOpts // backoff settings for retry operations. - - // mu protects the fields below. - mu sync.Mutex - store LogStore // persistent storage for unsent logs. - profileID ipn.ProfileID // empty if [Logger.SetProfileID] has not been called. - transport Transport // nil until [Logger.Start] is called. -} - -// NewLogger creates a new [Logger] with the given options. -func NewLogger(opts Opts) *Logger { - ctx, cancel := context.WithCancel(context.Background()) - - al := &Logger{ - retryLimit: opts.RetryLimit, - logf: logger.WithPrefix(opts.Logf, "auditlog: "), - store: opts.Store, - flusher: make(chan struct{}, 1), - done: make(chan struct{}), - ctx: ctx, - ctxCancel: cancel, - backoffOpts: defaultBackoffOpts, - } - al.logf("created") - return al -} - -// FlushAndStop synchronously flushes all pending logs and stops the audit logger. -// This will block until a final flush operation completes or context is done. -// If the logger is already stopped, this will return immediately. All unsent -// logs will be persisted to the store. -func (al *Logger) FlushAndStop(ctx context.Context) { - al.stop() - al.flush(ctx) -} - -// SetProfileID sets the profileID for the logger. This must be called before any logs can be enqueued. -// The profileID of a logger cannot be changed once set. -func (al *Logger) SetProfileID(profileID ipn.ProfileID) error { - al.mu.Lock() - defer al.mu.Unlock() - if al.profileID != "" { - return errors.New("profileID already set") - } - - al.profileID = profileID - return nil -} - -// Start starts the audit logger with the given transport. -// It returns an error if the logger is already started. -func (al *Logger) Start(t Transport) error { - al.mu.Lock() - defer al.mu.Unlock() - - if al.transport != nil { - return errors.New("already started") - } - - al.transport = t - pending, err := al.storedCountLocked() - if err != nil { - al.logf("[unexpected] failed to restore logs: %v", err) - } - go al.flushWorker() - if pending > 0 { - al.flushAsync() - } - return nil -} - -// ErrAuditLogStorageFailure is returned when the logger fails to persist logs to the store. -var ErrAuditLogStorageFailure = errors.New("audit log storage failure") - -// Enqueue queues an audit log to be sent to the control plane (or another suitable consumer/transport). -// This will return an error if the underlying store fails to save the log or we fail to generate a unique -// eventID for the log. -func (al *Logger) Enqueue(action tailcfg.ClientAuditAction, details string) error { - txn := &transaction{ - Action: action, - Details: details, - TimeStamp: time.Now(), - } - // Generate a suitably random eventID for the transaction. - txn.EventID = fmt.Sprint(txn.TimeStamp, rands.HexString(16)) - return al.enqueue(txn) -} - -// flushAsync requests an asynchronous flush. -// It is a no-op if a flush is already pending. -func (al *Logger) flushAsync() { - select { - case al.flusher <- struct{}{}: - default: - } -} - -func (al *Logger) flushWorker() { - defer close(al.done) - - var retryDelay time.Duration - retry := time.NewTimer(0) - retry.Stop() - - for { - select { - case <-al.ctx.Done(): - return - case <-al.flusher: - err := al.flush(al.ctx) - switch { - case errors.Is(err, context.Canceled): - // The logger was stopped, no need to retry. - return - case err != nil: - retryDelay = max(al.backoffOpts.min, min(retryDelay*time.Duration(al.backoffOpts.multiplier), al.backoffOpts.max)) - al.logf("retrying after %v, %v", retryDelay, err) - retry.Reset(retryDelay) - default: - retryDelay = 0 - retry.Stop() - } - case <-retry.C: - al.flushAsync() - } - } -} - -// flush attempts to send all pending logs to the control plane. -// l.mu must not be held. -func (al *Logger) flush(ctx context.Context) error { - al.mu.Lock() - pending, err := al.store.load(al.profileID) - t := al.transport - al.mu.Unlock() - - if err != nil { - // This will catch nil profileIDs - return fmt.Errorf("failed to restore pending logs: %w", err) - } - if len(pending) == 0 { - return nil - } - if t == nil { - return errors.New("no transport") - } - - complete, unsent := al.sendToTransport(ctx, pending, t) - al.markTransactionsDone(complete) - - al.mu.Lock() - defer al.mu.Unlock() - if err = al.appendToStoreLocked(unsent); err != nil { - al.logf("[unexpected] failed to persist logs: %v", err) - } - - if len(unsent) != 0 { - return fmt.Errorf("failed to send %d logs", len(unsent)) - } - - if len(complete) != 0 { - al.logf("complete %d audit log transactions", len(complete)) - } - return nil -} - -// sendToTransport sends all pending logs to the control plane. Returns a pair of slices -// containing the logs that were successfully sent (or failed permanently) and those that were not. -// -// This may require multiple round trips to the control plane and can be a long running transaction. -func (al *Logger) sendToTransport(ctx context.Context, pending []*transaction, t Transport) (complete []*transaction, unsent []*transaction) { - for i, txn := range pending { - req := tailcfg.AuditLogRequest{ - Action: tailcfg.ClientAuditAction(txn.Action), - Details: txn.Details, - Timestamp: txn.TimeStamp, - } - - if err := t.SendAuditLog(ctx, req); err != nil { - switch { - case errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded): - // The contex is done. All further attempts will fail. - unsent = append(unsent, pending[i:]...) - return complete, unsent - case IsRetryableError(err) && txn.Retries+1 < al.retryLimit: - // We permit a maximum number of retries for each log. All retriable - // errors should be transient and we should be able to send the log eventually, but - // we don't want logs to be persisted indefinitely. - txn.Retries++ - unsent = append(unsent, txn) - default: - complete = append(complete, txn) - al.logf("failed permanently: %v", err) - } - } else { - // No error - we're done. - complete = append(complete, txn) - } - } - - return complete, unsent -} - -func (al *Logger) stop() { - al.mu.Lock() - t := al.transport - al.mu.Unlock() - - if t == nil { - // No transport means no worker goroutine and done will not be - // closed if we cancel the context. - return - } - - al.ctxCancel() - <-al.done - al.logf("stopped for profileID: %v", al.profileID) -} - -// appendToStoreLocked persists logs to the store. This will deduplicate -// logs so it is safe to call this with the same logs multiple time, to -// requeue failed transactions for example. -// -// l.mu must be held. -func (al *Logger) appendToStoreLocked(txns []*transaction) error { - if len(txns) == 0 { - return nil - } - - if al.profileID == "" { - return errors.New("no logId set") - } - - persisted, err := al.store.load(al.profileID) - if err != nil { - al.logf("[unexpected] append failed to restore logs: %v", err) - } - - // The order is important here. We want the latest transactions first, which will - // ensure when we dedup, the new transactions are seen and the older transactions - // are discarded. - txnsOut := append(txns, persisted...) - txnsOut = deduplicateAndSort(txnsOut) - - return al.store.save(al.profileID, txnsOut) -} - -// storedCountLocked returns the number of logs persisted to the store. -// al.mu must be held. -func (al *Logger) storedCountLocked() (int, error) { - persisted, err := al.store.load(al.profileID) - return len(persisted), err -} - -// markTransactionsDone removes logs from the store that are complete (sent or failed permanently). -// al.mu must not be held. -func (al *Logger) markTransactionsDone(sent []*transaction) { - al.mu.Lock() - defer al.mu.Unlock() - - ids := set.Set[string]{} - for _, txn := range sent { - ids.Add(txn.EventID) - } - - persisted, err := al.store.load(al.profileID) - if err != nil { - al.logf("[unexpected] markTransactionsDone failed to restore logs: %v", err) - } - var unsent []*transaction - for _, txn := range persisted { - if !ids.Contains(txn.EventID) { - unsent = append(unsent, txn) - } - } - al.store.save(al.profileID, unsent) -} - -// deduplicateAndSort removes duplicate logs from the given slice and sorts them by timestamp. -// The first log entry in the slice will be retained, subsequent logs with the same EventID will be discarded. -func deduplicateAndSort(txns []*transaction) []*transaction { - seen := set.Set[string]{} - deduped := make([]*transaction, 0, len(txns)) - for _, txn := range txns { - if !seen.Contains(txn.EventID) { - deduped = append(deduped, txn) - seen.Add(txn.EventID) - } - } - // Sort logs by timestamp - oldest to newest. This will put the oldest logs at - // the front of the queue. - sort.Slice(deduped, func(i, j int) bool { - return deduped[i].TimeStamp.Before(deduped[j].TimeStamp) - }) - return deduped -} - -func (al *Logger) enqueue(txn *transaction) error { - al.mu.Lock() - defer al.mu.Unlock() - - if err := al.appendToStoreLocked([]*transaction{txn}); err != nil { - return fmt.Errorf("%w: %w", ErrAuditLogStorageFailure, err) - } - - // If a.transport is nil if the logger is stopped. - if al.transport != nil { - al.flushAsync() - } - - return nil -} - -var _ LogStore = (*logStateStore)(nil) - -// logStateStore is a concrete implementation of [LogStore] -// using [ipn.StateStore] as the underlying storage. -type logStateStore struct { - store ipn.StateStore -} - -// NewLogStore creates a new LogStateStore with the given [ipn.StateStore]. -func NewLogStore(store ipn.StateStore) LogStore { - return &logStateStore{ - store: store, - } -} - -func (s *logStateStore) generateKey(key ipn.ProfileID) string { - return "auditlog-" + string(key) -} - -// Save saves the given logs to an [ipn.StateStore]. This overwrites -// any existing entries for the given key. -func (s *logStateStore) save(key ipn.ProfileID, txns []*transaction) error { - if key == "" { - return errors.New("empty key") - } - - data, err := json.Marshal(txns) - if err != nil { - return err - } - k := ipn.StateKey(s.generateKey(key)) - return s.store.WriteState(k, data) -} - -// Load retrieves the logs from an [ipn.StateStore]. -func (s *logStateStore) load(key ipn.ProfileID) ([]*transaction, error) { - if key == "" { - return nil, errors.New("empty key") - } - - k := ipn.StateKey(s.generateKey(key)) - data, err := s.store.ReadState(k) - - switch { - case errors.Is(err, ipn.ErrStateNotExist): - return nil, nil - case err != nil: - return nil, err - } - - var txns []*transaction - err = json.Unmarshal(data, &txns) - return txns, err -} diff --git a/vendor/tailscale.com/ipn/backend.go b/vendor/tailscale.com/ipn/backend.go index 3e956f4..b4ba958 100644 --- a/vendor/tailscale.com/ipn/backend.go +++ b/vendor/tailscale.com/ipn/backend.go @@ -74,13 +74,17 @@ const ( NotifyInitialPrefs NotifyWatchOpt = 1 << 2 // if set, the first Notify message (sent immediately) will contain the current Prefs NotifyInitialNetMap NotifyWatchOpt = 1 << 3 // if set, the first Notify message (sent immediately) will contain the current NetMap - NotifyNoPrivateKeys NotifyWatchOpt = 1 << 4 // if set, private keys that would normally be sent in updates are zeroed out + NotifyNoPrivateKeys NotifyWatchOpt = 1 << 4 // (no-op) it used to redact private keys; now they always are and this does nothing NotifyInitialDriveShares NotifyWatchOpt = 1 << 5 // if set, the first Notify message (sent immediately) will contain the current Taildrive Shares NotifyInitialOutgoingFiles NotifyWatchOpt = 1 << 6 // if set, the first Notify message (sent immediately) will contain the current Taildrop OutgoingFiles NotifyInitialHealthState NotifyWatchOpt = 1 << 7 // if set, the first Notify message (sent immediately) will contain the current health.State of the client NotifyRateLimit NotifyWatchOpt = 1 << 8 // if set, rate limit spammy netmap updates to every few seconds + + NotifyHealthActions NotifyWatchOpt = 1 << 9 // if set, include PrimaryActions in health.State. Otherwise append the action URL to the text + + NotifyInitialSuggestedExitNode NotifyWatchOpt = 1 << 10 // if set, the first Notify message (sent immediately) will contain the current SuggestedExitNode if available ) // Notify is a communication from a backend (e.g. tailscaled) to a frontend @@ -96,7 +100,7 @@ type Notify struct { // This field is only set in the first message when requesting // NotifyInitialState. Clients must store it on their side as // following notifications will not include this field. - SessionID string `json:",omitempty"` + SessionID string `json:",omitzero"` // ErrMessage, if non-nil, contains a critical error message. // For State InUseOtherUser, ErrMessage is not critical and just contains the details. @@ -114,7 +118,7 @@ type Notify struct { // user's preferred storage location. // // Deprecated: use LocalClient.AwaitWaitingFiles instead. - FilesWaiting *empty.Message `json:",omitempty"` + FilesWaiting *empty.Message `json:",omitzero"` // IncomingFiles, if non-nil, specifies which files are in the // process of being received. A nil IncomingFiles means this @@ -123,22 +127,22 @@ type Notify struct { // of being transferred. // // Deprecated: use LocalClient.AwaitWaitingFiles instead. - IncomingFiles []PartialFile `json:",omitempty"` + IncomingFiles []PartialFile `json:",omitzero"` // OutgoingFiles, if non-nil, tracks which files are in the process of // being sent via TailDrop, including files that finished, whether // successful or failed. This slice is sorted by Started time, then Name. - OutgoingFiles []*OutgoingFile `json:",omitempty"` + OutgoingFiles []*OutgoingFile `json:",omitzero"` // LocalTCPPort, if non-nil, informs the UI frontend which // (non-zero) localhost TCP port it's listening on. // This is currently only used by Tailscale when run in the // macOS Network Extension. - LocalTCPPort *uint16 `json:",omitempty"` + LocalTCPPort *uint16 `json:",omitzero"` // ClientVersion, if non-nil, describes whether a client version update // is available. - ClientVersion *tailcfg.ClientVersion `json:",omitempty"` + ClientVersion *tailcfg.ClientVersion `json:",omitzero"` // DriveShares tracks the full set of current DriveShares that we're // publishing. Some client applications, like the MacOS and Windows clients, @@ -151,7 +155,11 @@ type Notify struct { // Health is the last-known health state of the backend. When this field is // non-nil, a change in health verified, and the API client should surface // any changes to the user in the UI. - Health *health.State `json:",omitempty"` + Health *health.State `json:",omitzero"` + + // SuggestedExitNode, if non-nil, is the node that the backend has determined to + // be the best exit node for the current network conditions. + SuggestedExitNode *tailcfg.StableNodeID `json:",omitzero"` // type is mirrored in xcode/IPN/Core/LocalAPI/Model/LocalAPIModel.swift } @@ -192,8 +200,16 @@ func (n Notify) String() string { if n.Health != nil { sb.WriteString("Health{...} ") } + if n.SuggestedExitNode != nil { + fmt.Fprintf(&sb, "SuggestedExitNode=%v ", *n.SuggestedExitNode) + } + s := sb.String() - return s[0:len(s)-1] + "}" + if s == "Notify{" { + return "Notify{}" + } else { + return s[0:len(s)-1] + "}" + } } // PartialFile represents an in-progress incoming file transfer. diff --git a/vendor/tailscale.com/ipn/conffile/cloudconf.go b/vendor/tailscale.com/ipn/conffile/cloudconf.go index 650611c..4475a2d 100644 --- a/vendor/tailscale.com/ipn/conffile/cloudconf.go +++ b/vendor/tailscale.com/ipn/conffile/cloudconf.go @@ -10,6 +10,8 @@ import ( "net/http" "strings" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/omit" ) @@ -35,6 +37,9 @@ func getEC2MetadataToken() (string, error) { } func readVMUserData() ([]byte, error) { + if !buildfeatures.HasAWS { + return nil, feature.ErrUnavailable + } // TODO(bradfitz): support GCP, Azure, Proxmox/cloud-init // (NoCloud/ConfigDrive ISO), etc. diff --git a/vendor/tailscale.com/ipn/conffile/conffile.go b/vendor/tailscale.com/ipn/conffile/conffile.go index a2bafb8..3a2aeff 100644 --- a/vendor/tailscale.com/ipn/conffile/conffile.go +++ b/vendor/tailscale.com/ipn/conffile/conffile.go @@ -8,11 +8,11 @@ package conffile import ( "bytes" "encoding/json" - "errors" "fmt" "os" "runtime" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn" ) @@ -51,10 +51,6 @@ func Load(path string) (*Config, error) { // compile-time for deadcode elimination return nil, fmt.Errorf("config file loading not supported on %q", runtime.GOOS) } - if hujsonStandardize == nil { - // Build tags are wrong in conffile_hujson.go - return nil, errors.New("[unexpected] config file loading not wired up") - } var c Config c.Path = path var err error @@ -68,14 +64,21 @@ func Load(path string) (*Config, error) { if err != nil { return nil, err } - c.Std, err = hujsonStandardize(c.Raw) - if err != nil { - return nil, fmt.Errorf("error parsing config file %s HuJSON/JSON: %w", path, err) + if buildfeatures.HasHuJSONConf && hujsonStandardize != nil { + c.Std, err = hujsonStandardize(c.Raw) + if err != nil { + return nil, fmt.Errorf("error parsing config file %s HuJSON/JSON: %w", path, err) + } + } else { + c.Std = c.Raw // config file must be valid JSON with ts_omit_hujsonconf } var ver struct { Version string `json:"version"` } if err := json.Unmarshal(c.Std, &ver); err != nil { + if !buildfeatures.HasHuJSONConf { + return nil, fmt.Errorf("error parsing config file %s, which must be valid standard JSON: %w", path, err) + } return nil, fmt.Errorf("error parsing config file %s: %w", path, err) } switch ver.Version { diff --git a/vendor/tailscale.com/ipn/conffile/conffile_hujson.go b/vendor/tailscale.com/ipn/conffile/conffile_hujson.go index 6825a06..1e967f1 100644 --- a/vendor/tailscale.com/ipn/conffile/conffile_hujson.go +++ b/vendor/tailscale.com/ipn/conffile/conffile_hujson.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios && !android +//go:build !ios && !android && !ts_omit_hujsonconf package conffile diff --git a/vendor/tailscale.com/ipn/conffile/serveconf.go b/vendor/tailscale.com/ipn/conffile/serveconf.go new file mode 100644 index 0000000..bb63c1a --- /dev/null +++ b/vendor/tailscale.com/ipn/conffile/serveconf.go @@ -0,0 +1,239 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_serve + +package conffile + +import ( + "errors" + "fmt" + "net" + "os" + "path" + "strings" + + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" + "tailscale.com/tailcfg" + "tailscale.com/types/opt" + "tailscale.com/util/mak" +) + +// ServicesConfigFile is the config file format for services configuration. +type ServicesConfigFile struct { + // Version is always "0.0.1" and always present. + Version string `json:"version"` + + Services map[tailcfg.ServiceName]*ServiceDetailsFile `json:"services,omitzero"` +} + +// ServiceDetailsFile is the config syntax for an individual Tailscale Service. +type ServiceDetailsFile struct { + // Version is always "0.0.1", set if and only if this is not inside a + // [ServiceConfigFile]. + Version string `json:"version,omitzero"` + + // Endpoints are sets of reverse proxy mappings from ProtoPortRanges on a + // Service to Targets (proto+destination+port) on remote destinations (or + // localhost). + // For example, "tcp:443" -> "tcp://localhost:8000" is an endpoint definition + // mapping traffic on the TCP port 443 of the Service to port 8080 on localhost. + // The Proto in the key must be populated. + // As a special case, if the only mapping provided is "*" -> "TUN", that + // enables TUN/L3 mode, where packets are delivered to the Tailscale network + // interface with the understanding that the user will deal with them manually. + Endpoints map[*tailcfg.ProtoPortRange]*Target `json:"endpoints"` + + // Advertised is a flag that tells control whether or not the client thinks + // it is ready to host a particular Tailscale Service. If unset, it is + // assumed to be true. + Advertised opt.Bool `json:"advertised,omitzero"` +} + +// ServiceProtocol is the protocol of a Target. +type ServiceProtocol string + +const ( + ProtoHTTP ServiceProtocol = "http" + ProtoHTTPS ServiceProtocol = "https" + ProtoHTTPSInsecure ServiceProtocol = "https+insecure" + ProtoTCP ServiceProtocol = "tcp" + ProtoTLSTerminatedTCP ServiceProtocol = "tls-terminated-tcp" + ProtoFile ServiceProtocol = "file" + ProtoTUN ServiceProtocol = "TUN" +) + +// Target is a destination for traffic to go to when it arrives at a Tailscale +// Service host. +type Target struct { + // The protocol over which to communicate with the Destination. + // Protocol == ProtoTUN is a special case, activating "TUN mode" where + // packets are delivered to the Tailscale TUN interface and then manually + // handled by the user. + Protocol ServiceProtocol + + // If Protocol is ProtoFile, then Destination is a file path. + // If Protocol is ProtoTUN, then Destination is empty. + // Otherwise, it is a host. + Destination string + + // If Protocol is not ProtoFile or ProtoTUN, then DestinationPorts is the + // set of ports on which to connect to the host referred to by Destination. + DestinationPorts tailcfg.PortRange +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +func (t *Target) UnmarshalJSON(buf []byte) error { + return jsonv2.Unmarshal(buf, t) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (t *Target) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + var str string + if err := jsonv2.UnmarshalDecode(dec, &str); err != nil { + return err + } + + // The TUN case does not look like a standard :// arrangement, + // so handled separately. + if str == "TUN" { + t.Protocol = ProtoTUN + t.Destination = "" + t.DestinationPorts = tailcfg.PortRangeAny + return nil + } + + proto, rest, found := strings.Cut(str, "://") + if !found { + return errors.New("handler not of form ://") + } + + switch ServiceProtocol(proto) { + case ProtoFile: + target := path.Clean(rest) + t.Protocol = ProtoFile + t.Destination = target + t.DestinationPorts = tailcfg.PortRange{} + case ProtoHTTP, ProtoHTTPS, ProtoHTTPSInsecure, ProtoTCP, ProtoTLSTerminatedTCP: + host, portRange, err := tailcfg.ParseHostPortRange(rest) + if err != nil { + return err + } + t.Protocol = ServiceProtocol(proto) + t.Destination = host + t.DestinationPorts = portRange + default: + return errors.New("unsupported protocol") + } + + return nil +} + +func (t *Target) MarshalText() ([]byte, error) { + var out string + switch t.Protocol { + case ProtoFile: + out = fmt.Sprintf("%s://%s", t.Protocol, t.Destination) + case ProtoTUN: + out = "TUN" + case ProtoHTTP, ProtoHTTPS, ProtoHTTPSInsecure, ProtoTCP, ProtoTLSTerminatedTCP: + out = fmt.Sprintf("%s://%s", t.Protocol, net.JoinHostPort(t.Destination, t.DestinationPorts.String())) + default: + return nil, errors.New("unsupported protocol") + } + return []byte(out), nil +} + +func LoadServicesConfig(filename string, forService string) (*ServicesConfigFile, error) { + data, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + var json []byte + if hujsonStandardize != nil { + json, err = hujsonStandardize(data) + if err != nil { + return nil, err + } + } else { + json = data + } + var ver struct { + Version string `json:"version"` + } + if err = jsonv2.Unmarshal(json, &ver); err != nil { + return nil, fmt.Errorf("could not parse config file version: %w", err) + } + switch ver.Version { + case "": + return nil, errors.New("config file must have \"version\" field") + case "0.0.1": + return loadConfigV0(json, forService) + } + return nil, fmt.Errorf("unsupported config file version %q", ver.Version) +} + +func loadConfigV0(json []byte, forService string) (*ServicesConfigFile, error) { + var scf ServicesConfigFile + if svcName := tailcfg.AsServiceName(forService); svcName != "" { + var sdf ServiceDetailsFile + err := jsonv2.Unmarshal(json, &sdf, jsonv2.RejectUnknownMembers(true)) + if err != nil { + return nil, err + } + mak.Set(&scf.Services, svcName, &sdf) + + } else { + err := jsonv2.Unmarshal(json, &scf, jsonv2.RejectUnknownMembers(true)) + if err != nil { + return nil, err + } + } + for svcName, svc := range scf.Services { + if forService == "" && svc.Version != "" { + return nil, errors.New("services cannot be versioned separately from config file") + } + if err := svcName.Validate(); err != nil { + return nil, err + } + if svc.Endpoints == nil { + return nil, fmt.Errorf("service %q: missing \"endpoints\" field", svcName) + } + var sourcePorts []tailcfg.PortRange + foundTUN := false + foundNonTUN := false + for ppr, target := range svc.Endpoints { + if target.Protocol == "TUN" { + if ppr.Proto != 0 || ppr.Ports != tailcfg.PortRangeAny { + return nil, fmt.Errorf("service %q: destination \"TUN\" can only be used with source \"*\"", svcName) + } + foundTUN = true + } else { + if ppr.Ports.Last-ppr.Ports.First != target.DestinationPorts.Last-target.DestinationPorts.First { + return nil, fmt.Errorf("service %q: source and destination port ranges must be of equal size", svcName.String()) + } + foundNonTUN = true + } + if foundTUN && foundNonTUN { + return nil, fmt.Errorf("service %q: cannot mix TUN mode with non-TUN mode", svcName) + } + if pr := findOverlappingRange(sourcePorts, ppr.Ports); pr != nil { + return nil, fmt.Errorf("service %q: source port ranges %q and %q overlap", svcName, pr.String(), ppr.Ports.String()) + } + sourcePorts = append(sourcePorts, ppr.Ports) + } + } + return &scf, nil +} + +// findOverlappingRange finds and returns a reference to a [tailcfg.PortRange] +// in haystack that overlaps with needle. It returns nil if it doesn't find one. +func findOverlappingRange(haystack []tailcfg.PortRange, needle tailcfg.PortRange) *tailcfg.PortRange { + for _, pr := range haystack { + if pr.Contains(needle.First) || pr.Contains(needle.Last) || needle.Contains(pr.First) || needle.Contains(pr.Last) { + return &pr + } + } + return nil +} diff --git a/vendor/tailscale.com/ipn/desktop/doc.go b/vendor/tailscale.com/ipn/desktop/doc.go deleted file mode 100644 index 64a3327..0000000 --- a/vendor/tailscale.com/ipn/desktop/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package desktop facilitates interaction with the desktop environment -// and user sessions. As of 2025-02-06, it is only implemented for Windows. -package desktop diff --git a/vendor/tailscale.com/ipn/desktop/mksyscall.go b/vendor/tailscale.com/ipn/desktop/mksyscall.go deleted file mode 100644 index 3051384..0000000 --- a/vendor/tailscale.com/ipn/desktop/mksyscall.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package desktop - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go mksyscall.go -//go:generate go run golang.org/x/tools/cmd/goimports -w zsyscall_windows.go - -//sys setLastError(dwErrorCode uint32) = kernel32.SetLastError - -//sys registerClassEx(windowClass *_WNDCLASSEX) (atom uint16, err error) [atom==0] = user32.RegisterClassExW -//sys createWindowEx(dwExStyle uint32, lpClassName *uint16, lpWindowName *uint16, dwStyle uint32, x int32, y int32, nWidth int32, nHeight int32, hWndParent windows.HWND, hMenu windows.Handle, hInstance windows.Handle, lpParam unsafe.Pointer) (hWnd windows.HWND, err error) [hWnd==0] = user32.CreateWindowExW -//sys defWindowProc(hwnd windows.HWND, msg uint32, wparam uintptr, lparam uintptr) (res uintptr) = user32.DefWindowProcW -//sys setWindowLongPtr(hwnd windows.HWND, index int32, newLong uintptr) (res uintptr, err error) [res==0 && e1!=0] = user32.SetWindowLongPtrW -//sys getWindowLongPtr(hwnd windows.HWND, index int32) (res uintptr, err error) [res==0 && e1!=0] = user32.GetWindowLongPtrW -//sys sendMessage(hwnd windows.HWND, msg uint32, wparam uintptr, lparam uintptr) (res uintptr) = user32.SendMessageW -//sys getMessage(lpMsg *_MSG, hwnd windows.HWND, msgMin uint32, msgMax uint32) (ret int32) = user32.GetMessageW -//sys translateMessage(lpMsg *_MSG) (res bool) = user32.TranslateMessage -//sys dispatchMessage(lpMsg *_MSG) (res uintptr) = user32.DispatchMessageW -//sys destroyWindow(hwnd windows.HWND) (err error) [int32(failretval)==0] = user32.DestroyWindow -//sys postQuitMessage(exitCode int32) = user32.PostQuitMessage - -//sys registerSessionNotification(hServer windows.Handle, hwnd windows.HWND, flags uint32) (err error) [int32(failretval)==0] = wtsapi32.WTSRegisterSessionNotificationEx -//sys unregisterSessionNotification(hServer windows.Handle, hwnd windows.HWND) (err error) [int32(failretval)==0] = wtsapi32.WTSUnRegisterSessionNotificationEx diff --git a/vendor/tailscale.com/ipn/desktop/session.go b/vendor/tailscale.com/ipn/desktop/session.go deleted file mode 100644 index c953789..0000000 --- a/vendor/tailscale.com/ipn/desktop/session.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package desktop - -import ( - "fmt" - - "tailscale.com/ipn/ipnauth" -) - -// SessionID is a unique identifier of a desktop session. -type SessionID uint - -// SessionStatus is the status of a desktop session. -type SessionStatus int - -const ( - // ClosedSession is a session that does not exist, is not yet initialized by the OS, - // or has been terminated. - ClosedSession SessionStatus = iota - // ForegroundSession is a session that a user can interact with, - // such as when attached to a physical console or an active, - // unlocked RDP connection. - ForegroundSession - // BackgroundSession indicates that the session is locked, disconnected, - // or otherwise running without user presence or interaction. - BackgroundSession -) - -// String implements [fmt.Stringer]. -func (s SessionStatus) String() string { - switch s { - case ClosedSession: - return "Closed" - case ForegroundSession: - return "Foreground" - case BackgroundSession: - return "Background" - default: - panic("unreachable") - } -} - -// Session is a state of a desktop session at a given point in time. -type Session struct { - ID SessionID // Identifier of the session; can be reused after the session is closed. - Status SessionStatus // The status of the session, such as foreground or background. - User ipnauth.Actor // User logged into the session. -} - -// Description returns a human-readable description of the session. -func (s *Session) Description() string { - if maybeUsername, _ := s.User.Username(); maybeUsername != "" { // best effort - return fmt.Sprintf("Session %d - %q (%s)", s.ID, maybeUsername, s.Status) - } - return fmt.Sprintf("Session %d (%s)", s.ID, s.Status) -} diff --git a/vendor/tailscale.com/ipn/desktop/sessions.go b/vendor/tailscale.com/ipn/desktop/sessions.go deleted file mode 100644 index 8bf7a75..0000000 --- a/vendor/tailscale.com/ipn/desktop/sessions.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package desktop - -import ( - "errors" - "runtime" -) - -// ErrNotImplemented is returned by [NewSessionManager] when it is not -// implemented for the current GOOS. -var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS) - -// SessionInitCallback is a function that is called once per [Session]. -// It returns an optional cleanup function that is called when the session -// is about to be destroyed, or nil if no cleanup is needed. -// It is not safe to call SessionManager methods from within the callback. -type SessionInitCallback func(session *Session) (cleanup func()) - -// SessionStateCallback is a function that reports the initial or updated -// state of a [Session], such as when it transitions between foreground and background. -// It is guaranteed to be called after all registered [SessionInitCallback] functions -// have completed, and before any cleanup functions are called for the same session. -// It is not safe to call SessionManager methods from within the callback. -type SessionStateCallback func(session *Session) - -// SessionManager is an interface that provides access to desktop sessions on the current platform. -// It is safe for concurrent use. -type SessionManager interface { - // Init explicitly initializes the receiver. - // Unless the receiver is explicitly initialized, it will be lazily initialized - // on the first call to any other method. - // It is safe to call Init multiple times. - Init() error - - // Sessions returns a session snapshot taken at the time of the call. - // Since sessions can be created or destroyed at any time, it may become - // outdated as soon as it is returned. - // - // It is primarily intended for logging and debugging. - // Prefer registering a [SessionInitCallback] or [SessionStateCallback] - // in contexts requiring stronger guarantees. - Sessions() (map[SessionID]*Session, error) - - // RegisterInitCallback registers a [SessionInitCallback] that is called for each existing session - // and for each new session that is created, until the returned unregister function is called. - // If the specified [SessionInitCallback] returns a cleanup function, it is called when the session - // is about to be destroyed. The callback function is guaranteed to be called once and only once - // for each existing and new session. - RegisterInitCallback(cb SessionInitCallback) (unregister func(), err error) - - // RegisterStateCallback registers a [SessionStateCallback] that is called for each existing session - // and every time the state of a session changes, until the returned unregister function is called. - RegisterStateCallback(cb SessionStateCallback) (unregister func(), err error) - - // Close waits for all registered callbacks to complete - // and releases resources associated with the receiver. - Close() error -} diff --git a/vendor/tailscale.com/ipn/desktop/sessions_notwindows.go b/vendor/tailscale.com/ipn/desktop/sessions_notwindows.go deleted file mode 100644 index da3230a..0000000 --- a/vendor/tailscale.com/ipn/desktop/sessions_notwindows.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !windows - -package desktop - -import "tailscale.com/types/logger" - -// NewSessionManager returns a new [SessionManager] for the current platform, -// [ErrNotImplemented] if the platform is not supported, or an error if the -// session manager could not be created. -func NewSessionManager(logger.Logf) (SessionManager, error) { - return nil, ErrNotImplemented -} diff --git a/vendor/tailscale.com/ipn/desktop/sessions_windows.go b/vendor/tailscale.com/ipn/desktop/sessions_windows.go deleted file mode 100644 index b26172d..0000000 --- a/vendor/tailscale.com/ipn/desktop/sessions_windows.go +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package desktop - -import ( - "context" - "errors" - "fmt" - "runtime" - "sync" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" - "tailscale.com/ipn/ipnauth" - "tailscale.com/types/logger" - "tailscale.com/util/must" - "tailscale.com/util/set" -) - -// wtsManager is a [SessionManager] implementation for Windows. -type wtsManager struct { - logf logger.Logf - ctx context.Context // cancelled when the manager is closed - ctxCancel context.CancelFunc - - initOnce func() error - watcher *sessionWatcher - - mu sync.Mutex - sessions map[SessionID]*wtsSession - initCbs set.HandleSet[SessionInitCallback] - stateCbs set.HandleSet[SessionStateCallback] -} - -// NewSessionManager returns a new [SessionManager] for the current platform, -func NewSessionManager(logf logger.Logf) (SessionManager, error) { - ctx, ctxCancel := context.WithCancel(context.Background()) - m := &wtsManager{ - logf: logf, - ctx: ctx, - ctxCancel: ctxCancel, - sessions: make(map[SessionID]*wtsSession), - } - m.watcher = newSessionWatcher(m.ctx, m.logf, m.sessionEventHandler) - - m.initOnce = sync.OnceValue(func() error { - if err := waitUntilWTSReady(m.ctx); err != nil { - return fmt.Errorf("WTS is not ready: %w", err) - } - - m.mu.Lock() - defer m.mu.Unlock() - if err := m.watcher.Start(); err != nil { - return fmt.Errorf("failed to start session watcher: %w", err) - } - - var err error - m.sessions, err = enumerateSessions() - return err // may be nil or non-nil - }) - return m, nil -} - -// Init implements [SessionManager]. -func (m *wtsManager) Init() error { - return m.initOnce() -} - -// Sessions implements [SessionManager]. -func (m *wtsManager) Sessions() (map[SessionID]*Session, error) { - if err := m.initOnce(); err != nil { - return nil, err - } - - m.mu.Lock() - defer m.mu.Unlock() - sessions := make(map[SessionID]*Session, len(m.sessions)) - for _, s := range m.sessions { - sessions[s.id] = s.AsSession() - } - return sessions, nil -} - -// RegisterInitCallback implements [SessionManager]. -func (m *wtsManager) RegisterInitCallback(cb SessionInitCallback) (unregister func(), err error) { - if err := m.initOnce(); err != nil { - return nil, err - } - if cb == nil { - return nil, errors.New("nil callback") - } - - m.mu.Lock() - defer m.mu.Unlock() - handle := m.initCbs.Add(cb) - - // TODO(nickkhyl): enqueue callbacks in a separate goroutine? - for _, s := range m.sessions { - if cleanup := cb(s.AsSession()); cleanup != nil { - s.cleanup = append(s.cleanup, cleanup) - } - } - - return func() { - m.mu.Lock() - defer m.mu.Unlock() - delete(m.initCbs, handle) - }, nil -} - -// RegisterStateCallback implements [SessionManager]. -func (m *wtsManager) RegisterStateCallback(cb SessionStateCallback) (unregister func(), err error) { - if err := m.initOnce(); err != nil { - return nil, err - } - if cb == nil { - return nil, errors.New("nil callback") - } - - m.mu.Lock() - defer m.mu.Unlock() - handle := m.stateCbs.Add(cb) - - // TODO(nickkhyl): enqueue callbacks in a separate goroutine? - for _, s := range m.sessions { - cb(s.AsSession()) - } - - return func() { - m.mu.Lock() - defer m.mu.Unlock() - delete(m.stateCbs, handle) - }, nil -} - -func (m *wtsManager) sessionEventHandler(id SessionID, event uint32) { - m.mu.Lock() - defer m.mu.Unlock() - switch event { - case windows.WTS_SESSION_LOGON: - // The session may have been created after we started watching, - // but before the initial enumeration was performed. - // Do not create a new session if it already exists. - if _, _, err := m.getOrCreateSessionLocked(id); err != nil { - m.logf("[unexpected] getOrCreateSessionLocked(%d): %v", id, err) - } - case windows.WTS_SESSION_LOCK: - if err := m.setSessionStatusLocked(id, BackgroundSession); err != nil { - m.logf("[unexpected] setSessionStatusLocked(%d, BackgroundSession): %v", id, err) - } - case windows.WTS_SESSION_UNLOCK: - if err := m.setSessionStatusLocked(id, ForegroundSession); err != nil { - m.logf("[unexpected] setSessionStatusLocked(%d, ForegroundSession): %v", id, err) - } - case windows.WTS_SESSION_LOGOFF: - if err := m.deleteSessionLocked(id); err != nil { - m.logf("[unexpected] deleteSessionLocked(%d): %v", id, err) - } - } -} - -func (m *wtsManager) getOrCreateSessionLocked(id SessionID) (_ *wtsSession, created bool, err error) { - if s, ok := m.sessions[id]; ok { - return s, false, nil - } - - s, err := newWTSSession(id, ForegroundSession) - if err != nil { - return nil, false, err - } - m.sessions[id] = s - - session := s.AsSession() - // TODO(nickkhyl): enqueue callbacks in a separate goroutine? - for _, cb := range m.initCbs { - if cleanup := cb(session); cleanup != nil { - s.cleanup = append(s.cleanup, cleanup) - } - } - for _, cb := range m.stateCbs { - cb(session) - } - - return s, true, err -} - -func (m *wtsManager) setSessionStatusLocked(id SessionID, status SessionStatus) error { - s, _, err := m.getOrCreateSessionLocked(id) - if err != nil { - return err - } - if s.status == status { - return nil - } - - s.status = status - session := s.AsSession() - // TODO(nickkhyl): enqueue callbacks in a separate goroutine? - for _, cb := range m.stateCbs { - cb(session) - } - return nil -} - -func (m *wtsManager) deleteSessionLocked(id SessionID) error { - s, ok := m.sessions[id] - if !ok { - return nil - } - - s.status = ClosedSession - session := s.AsSession() - // TODO(nickkhyl): enqueue callbacks (and [wtsSession.close]!) in a separate goroutine? - for _, cb := range m.stateCbs { - cb(session) - } - - delete(m.sessions, id) - return s.close() -} - -func (m *wtsManager) Close() error { - m.ctxCancel() - - if m.watcher != nil { - err := m.watcher.Stop() - if err != nil { - return err - } - m.watcher = nil - } - - m.mu.Lock() - defer m.mu.Unlock() - m.initCbs = nil - m.stateCbs = nil - errs := make([]error, 0, len(m.sessions)) - for _, s := range m.sessions { - errs = append(errs, s.close()) - } - m.sessions = nil - return errors.Join(errs...) -} - -type wtsSession struct { - id SessionID - user *ipnauth.WindowsActor - - status SessionStatus - - cleanup []func() -} - -func newWTSSession(id SessionID, status SessionStatus) (*wtsSession, error) { - var token windows.Token - if err := windows.WTSQueryUserToken(uint32(id), &token); err != nil { - return nil, err - } - user, err := ipnauth.NewWindowsActorWithToken(token) - if err != nil { - return nil, err - } - return &wtsSession{id, user, status, nil}, nil -} - -// enumerateSessions returns a map of all active WTS sessions. -func enumerateSessions() (map[SessionID]*wtsSession, error) { - const reserved, version uint32 = 0, 1 - var numSessions uint32 - var sessionInfos *windows.WTS_SESSION_INFO - if err := windows.WTSEnumerateSessions(_WTS_CURRENT_SERVER_HANDLE, reserved, version, &sessionInfos, &numSessions); err != nil { - return nil, fmt.Errorf("WTSEnumerateSessions failed: %w", err) - } - defer windows.WTSFreeMemory(uintptr(unsafe.Pointer(sessionInfos))) - - sessions := make(map[SessionID]*wtsSession, numSessions) - for _, si := range unsafe.Slice(sessionInfos, numSessions) { - status := _WTS_CONNECTSTATE_CLASS(si.State).ToSessionStatus() - if status == ClosedSession { - // The session does not exist as far as we're concerned. - // It may be in the process of being created or destroyed, - // or be a special "listener" session, etc. - continue - } - id := SessionID(si.SessionID) - session, err := newWTSSession(id, status) - if err != nil { - continue - } - sessions[id] = session - } - return sessions, nil -} - -func (s *wtsSession) AsSession() *Session { - return &Session{ - ID: s.id, - Status: s.status, - // wtsSession owns the user; don't let the caller close it - User: ipnauth.WithoutClose(s.user), - } -} - -func (m *wtsSession) close() error { - for _, cleanup := range m.cleanup { - cleanup() - } - m.cleanup = nil - - if m.user != nil { - if err := m.user.Close(); err != nil { - return err - } - m.user = nil - } - return nil -} - -type sessionEventHandler func(id SessionID, event uint32) - -// TODO(nickkhyl): implement a sessionWatcher that does not use the message queue. -// One possible approach is to have the tailscaled service register a HandlerEx function -// and stream SERVICE_CONTROL_SESSIONCHANGE events to the tailscaled subprocess -// (the actual tailscaled backend), exposing these events via [sessionWatcher]/[wtsManager]. -// -// See tailscale/corp#26477 for details and tracking. -type sessionWatcher struct { - logf logger.Logf - ctx context.Context // canceled to stop the watcher - ctxCancel context.CancelFunc // cancels the watcher - hWnd windows.HWND // window handle for receiving session change notifications - handler sessionEventHandler // called on session events - - mu sync.Mutex - doneCh chan error // written to when the watcher exits; nil if not started -} - -func newSessionWatcher(ctx context.Context, logf logger.Logf, handler sessionEventHandler) *sessionWatcher { - ctx, cancel := context.WithCancel(ctx) - return &sessionWatcher{logf: logf, ctx: ctx, ctxCancel: cancel, handler: handler} -} - -func (sw *sessionWatcher) Start() error { - sw.mu.Lock() - defer sw.mu.Unlock() - - select { - case <-sw.ctx.Done(): - return fmt.Errorf("sessionWatcher already stopped: %w", sw.ctx.Err()) - default: - } - - if sw.doneCh != nil { - // Already started. - return nil - } - sw.doneCh = make(chan error, 1) - - startedCh := make(chan error, 1) - go sw.run(startedCh, sw.doneCh) - if err := <-startedCh; err != nil { - return err - } - - // Signal the window to unsubscribe from session notifications - // and shut down gracefully when the sessionWatcher is stopped. - context.AfterFunc(sw.ctx, func() { - sendMessage(sw.hWnd, _WM_CLOSE, 0, 0) - }) - return nil -} - -func (sw *sessionWatcher) run(started, done chan<- error) { - runtime.LockOSThread() - defer func() { - runtime.UnlockOSThread() - close(done) - }() - err := sw.createMessageWindow() - started <- err - if err != nil { - return - } - pumpThreadMessages() -} - -// Stop stops the session watcher and waits for it to exit. -func (sw *sessionWatcher) Stop() error { - sw.ctxCancel() - - sw.mu.Lock() - doneCh := sw.doneCh - sw.doneCh = nil - sw.mu.Unlock() - - if doneCh != nil { - return <-doneCh - } - return nil -} - -const watcherWindowClassName = "Tailscale-SessionManager" - -var watcherWindowClassName16 = sync.OnceValue(func() *uint16 { - return must.Get(syscall.UTF16PtrFromString(watcherWindowClassName)) -}) - -var registerSessionManagerWindowClass = sync.OnceValue(func() error { - var hInst windows.Handle - if err := windows.GetModuleHandleEx(0, nil, &hInst); err != nil { - return fmt.Errorf("GetModuleHandle: %w", err) - } - wc := _WNDCLASSEX{ - CbSize: uint32(unsafe.Sizeof(_WNDCLASSEX{})), - HInstance: hInst, - LpfnWndProc: syscall.NewCallback(sessionWatcherWndProc), - LpszClassName: watcherWindowClassName16(), - } - if _, err := registerClassEx(&wc); err != nil { - return fmt.Errorf("RegisterClassEx(%q): %w", watcherWindowClassName, err) - } - return nil -}) - -func (sw *sessionWatcher) createMessageWindow() error { - if err := registerSessionManagerWindowClass(); err != nil { - return err - } - _, err := createWindowEx( - 0, // dwExStyle - watcherWindowClassName16(), // lpClassName - nil, // lpWindowName - 0, // dwStyle - 0, // x - 0, // y - 0, // nWidth - 0, // nHeight - _HWND_MESSAGE, // hWndParent; message-only window - 0, // hMenu - 0, // hInstance - unsafe.Pointer(sw), // lpParam - ) - if err != nil { - return fmt.Errorf("CreateWindowEx: %w", err) - } - return nil -} - -func (sw *sessionWatcher) wndProc(hWnd windows.HWND, msg uint32, wParam, lParam uintptr) (result uintptr) { - switch msg { - case _WM_CREATE: - err := registerSessionNotification(_WTS_CURRENT_SERVER_HANDLE, hWnd, _NOTIFY_FOR_ALL_SESSIONS) - if err != nil { - sw.logf("[unexpected] failed to register for session notifications: %v", err) - return ^uintptr(0) - } - sw.logf("registered for session notifications") - case _WM_WTSSESSION_CHANGE: - sw.handler(SessionID(lParam), uint32(wParam)) - return 0 - case _WM_CLOSE: - if err := destroyWindow(hWnd); err != nil { - sw.logf("[unexpected] failed to destroy window: %v", err) - } - return 0 - case _WM_DESTROY: - err := unregisterSessionNotification(_WTS_CURRENT_SERVER_HANDLE, hWnd) - if err != nil { - sw.logf("[unexpected] failed to unregister session notifications callback: %v", err) - } - sw.logf("unregistered from session notifications") - return 0 - case _WM_NCDESTROY: - sw.hWnd = 0 - postQuitMessage(0) // quit the message loop for this thread - } - return defWindowProc(hWnd, msg, wParam, lParam) -} - -func (sw *sessionWatcher) setHandle(hwnd windows.HWND) error { - sw.hWnd = hwnd - setLastError(0) - _, err := setWindowLongPtr(sw.hWnd, _GWLP_USERDATA, uintptr(unsafe.Pointer(sw))) - return err // may be nil or non-nil -} - -func sessionWatcherByHandle(hwnd windows.HWND) *sessionWatcher { - val, _ := getWindowLongPtr(hwnd, _GWLP_USERDATA) - return (*sessionWatcher)(unsafe.Pointer(val)) -} - -func sessionWatcherWndProc(hWnd windows.HWND, msg uint32, wParam, lParam uintptr) (result uintptr) { - if msg == _WM_NCCREATE { - cs := (*_CREATESTRUCT)(unsafe.Pointer(lParam)) - sw := (*sessionWatcher)(unsafe.Pointer(cs.CreateParams)) - if sw == nil { - return 0 - } - if err := sw.setHandle(hWnd); err != nil { - return 0 - } - return defWindowProc(hWnd, msg, wParam, lParam) - } - if sw := sessionWatcherByHandle(hWnd); sw != nil { - return sw.wndProc(hWnd, msg, wParam, lParam) - } - return defWindowProc(hWnd, msg, wParam, lParam) -} - -func pumpThreadMessages() { - var msg _MSG - for getMessage(&msg, 0, 0, 0) != 0 { - translateMessage(&msg) - dispatchMessage(&msg) - } -} - -// waitUntilWTSReady waits until the Windows Terminal Services (WTS) is ready. -// This is necessary because the WTS API functions may fail if called before -// the WTS is ready. -// -// https://web.archive.org/web/20250207011738/https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsregistersessionnotificationex -func waitUntilWTSReady(ctx context.Context) error { - eventName16, err := windows.UTF16PtrFromString(`Global\TermSrvReadyEvent`) - if err != nil { - return err - } - event, err := windows.OpenEvent(windows.SYNCHRONIZE, false, eventName16) - if err != nil { - return err - } - defer windows.CloseHandle(event) - return waitForContextOrHandle(ctx, event) -} - -// waitForContextOrHandle waits for either the context to be done or a handle to be signaled. -func waitForContextOrHandle(ctx context.Context, handle windows.Handle) error { - contextDoneEvent, cleanup, err := channelToEvent(ctx.Done()) - if err != nil { - return err - } - defer cleanup() - - handles := []windows.Handle{contextDoneEvent, handle} - waitCode, err := windows.WaitForMultipleObjects(handles, false, windows.INFINITE) - if err != nil { - return err - } - - waitCode -= windows.WAIT_OBJECT_0 - if waitCode == 0 { // contextDoneEvent - return ctx.Err() - } - return nil -} - -// channelToEvent returns an auto-reset event that is set when the channel -// becomes receivable, including when the channel is closed. -func channelToEvent[T any](c <-chan T) (evt windows.Handle, cleanup func(), err error) { - evt, err = windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return 0, nil, err - } - - cancel := make(chan struct{}) - - go func() { - select { - case <-cancel: - return - case <-c: - } - windows.SetEvent(evt) - }() - - cleanup = func() { - close(cancel) - windows.CloseHandle(evt) - } - - return evt, cleanup, nil -} - -type _WNDCLASSEX struct { - CbSize uint32 - Style uint32 - LpfnWndProc uintptr - CbClsExtra int32 - CbWndExtra int32 - HInstance windows.Handle - HIcon windows.Handle - HCursor windows.Handle - HbrBackground windows.Handle - LpszMenuName *uint16 - LpszClassName *uint16 - HIconSm windows.Handle -} - -type _CREATESTRUCT struct { - CreateParams uintptr - Instance windows.Handle - Menu windows.Handle - Parent windows.HWND - Cy int32 - Cx int32 - Y int32 - X int32 - Style int32 - Name *uint16 - ClassName *uint16 - ExStyle uint32 -} - -type _POINT struct { - X, Y int32 -} - -type _MSG struct { - HWnd windows.HWND - Message uint32 - WParam uintptr - LParam uintptr - Time uint32 - Pt _POINT -} - -const ( - _WM_CREATE = 1 - _WM_DESTROY = 2 - _WM_CLOSE = 16 - _WM_NCCREATE = 129 - _WM_QUIT = 18 - _WM_NCDESTROY = 130 - - // _WM_WTSSESSION_CHANGE is a message sent to windows that have registered - // for session change notifications, informing them of changes in session state. - // - // https://web.archive.org/web/20250207012421/https://learn.microsoft.com/en-us/windows/win32/termserv/wm-wtssession-change - _WM_WTSSESSION_CHANGE = 0x02B1 -) - -const _GWLP_USERDATA = -21 - -const _HWND_MESSAGE = ^windows.HWND(2) - -// _NOTIFY_FOR_ALL_SESSIONS indicates that the window should receive -// session change notifications for all sessions on the specified server. -const _NOTIFY_FOR_ALL_SESSIONS = 1 - -// _WTS_CURRENT_SERVER_HANDLE indicates that the window should receive -// session change notifications for the host itself rather than a remote server. -const _WTS_CURRENT_SERVER_HANDLE = windows.Handle(0) - -// _WTS_CONNECTSTATE_CLASS represents the connection state of a session. -// -// https://web.archive.org/web/20250206082427/https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/ne-wtsapi32-wts_connectstate_class -type _WTS_CONNECTSTATE_CLASS int32 - -// ToSessionStatus converts cs to a [SessionStatus]. -func (cs _WTS_CONNECTSTATE_CLASS) ToSessionStatus() SessionStatus { - switch cs { - case windows.WTSActive: - return ForegroundSession - case windows.WTSDisconnected: - return BackgroundSession - default: - // The session does not exist as far as we're concerned. - return ClosedSession - } -} diff --git a/vendor/tailscale.com/ipn/desktop/zsyscall_windows.go b/vendor/tailscale.com/ipn/desktop/zsyscall_windows.go deleted file mode 100644 index 222ab49..0000000 --- a/vendor/tailscale.com/ipn/desktop/zsyscall_windows.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package desktop - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) - errERROR_EINVAL error = syscall.EINVAL -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return errERROR_EINVAL - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - moduser32 = windows.NewLazySystemDLL("user32.dll") - modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll") - - procSetLastError = modkernel32.NewProc("SetLastError") - procCreateWindowExW = moduser32.NewProc("CreateWindowExW") - procDefWindowProcW = moduser32.NewProc("DefWindowProcW") - procDestroyWindow = moduser32.NewProc("DestroyWindow") - procDispatchMessageW = moduser32.NewProc("DispatchMessageW") - procGetMessageW = moduser32.NewProc("GetMessageW") - procGetWindowLongPtrW = moduser32.NewProc("GetWindowLongPtrW") - procPostQuitMessage = moduser32.NewProc("PostQuitMessage") - procRegisterClassExW = moduser32.NewProc("RegisterClassExW") - procSendMessageW = moduser32.NewProc("SendMessageW") - procSetWindowLongPtrW = moduser32.NewProc("SetWindowLongPtrW") - procTranslateMessage = moduser32.NewProc("TranslateMessage") - procWTSRegisterSessionNotificationEx = modwtsapi32.NewProc("WTSRegisterSessionNotificationEx") - procWTSUnRegisterSessionNotificationEx = modwtsapi32.NewProc("WTSUnRegisterSessionNotificationEx") -) - -func setLastError(dwErrorCode uint32) { - syscall.Syscall(procSetLastError.Addr(), 1, uintptr(dwErrorCode), 0, 0) - return -} - -func createWindowEx(dwExStyle uint32, lpClassName *uint16, lpWindowName *uint16, dwStyle uint32, x int32, y int32, nWidth int32, nHeight int32, hWndParent windows.HWND, hMenu windows.Handle, hInstance windows.Handle, lpParam unsafe.Pointer) (hWnd windows.HWND, err error) { - r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(dwExStyle), uintptr(unsafe.Pointer(lpClassName)), uintptr(unsafe.Pointer(lpWindowName)), uintptr(dwStyle), uintptr(x), uintptr(y), uintptr(nWidth), uintptr(nHeight), uintptr(hWndParent), uintptr(hMenu), uintptr(hInstance), uintptr(lpParam)) - hWnd = windows.HWND(r0) - if hWnd == 0 { - err = errnoErr(e1) - } - return -} - -func defWindowProc(hwnd windows.HWND, msg uint32, wparam uintptr, lparam uintptr) (res uintptr) { - r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) - res = uintptr(r0) - return -} - -func destroyWindow(hwnd windows.HWND) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0) - if int32(r1) == 0 { - err = errnoErr(e1) - } - return -} - -func dispatchMessage(lpMsg *_MSG) (res uintptr) { - r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) - res = uintptr(r0) - return -} - -func getMessage(lpMsg *_MSG, hwnd windows.HWND, msgMin uint32, msgMax uint32) (ret int32) { - r0, _, _ := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(lpMsg)), uintptr(hwnd), uintptr(msgMin), uintptr(msgMax), 0, 0) - ret = int32(r0) - return -} - -func getWindowLongPtr(hwnd windows.HWND, index int32) (res uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowLongPtrW.Addr(), 2, uintptr(hwnd), uintptr(index), 0) - res = uintptr(r0) - if res == 0 && e1 != 0 { - err = errnoErr(e1) - } - return -} - -func postQuitMessage(exitCode int32) { - syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitCode), 0, 0) - return -} - -func registerClassEx(windowClass *_WNDCLASSEX) (atom uint16, err error) { - r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(windowClass)), 0, 0) - atom = uint16(r0) - if atom == 0 { - err = errnoErr(e1) - } - return -} - -func sendMessage(hwnd windows.HWND, msg uint32, wparam uintptr, lparam uintptr) (res uintptr) { - r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0) - res = uintptr(r0) - return -} - -func setWindowLongPtr(hwnd windows.HWND, index int32, newLong uintptr) (res uintptr, err error) { - r0, _, e1 := syscall.Syscall(procSetWindowLongPtrW.Addr(), 3, uintptr(hwnd), uintptr(index), uintptr(newLong)) - res = uintptr(r0) - if res == 0 && e1 != 0 { - err = errnoErr(e1) - } - return -} - -func translateMessage(lpMsg *_MSG) (res bool) { - r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) - res = r0 != 0 - return -} - -func registerSessionNotification(hServer windows.Handle, hwnd windows.HWND, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procWTSRegisterSessionNotificationEx.Addr(), 3, uintptr(hServer), uintptr(hwnd), uintptr(flags)) - if int32(r1) == 0 { - err = errnoErr(e1) - } - return -} - -func unregisterSessionNotification(hServer windows.Handle, hwnd windows.HWND) (err error) { - r1, _, e1 := syscall.Syscall(procWTSUnRegisterSessionNotificationEx.Addr(), 2, uintptr(hServer), uintptr(hwnd), 0) - if int32(r1) == 0 { - err = errnoErr(e1) - } - return -} diff --git a/vendor/tailscale.com/ipn/ipn_clone.go b/vendor/tailscale.com/ipn/ipn_clone.go index 4050fec..4bf78b4 100644 --- a/vendor/tailscale.com/ipn/ipn_clone.go +++ b/vendor/tailscale.com/ipn/ipn_clone.go @@ -61,43 +61,51 @@ func (src *Prefs) Clone() *Prefs { } } } + if dst.RelayServerPort != nil { + dst.RelayServerPort = ptr.To(*src.RelayServerPort) + } + dst.RelayServerStaticEndpoints = append(src.RelayServerStaticEndpoints[:0:0], src.RelayServerStaticEndpoints...) dst.Persist = src.Persist.Clone() return dst } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _PrefsCloneNeedsRegeneration = Prefs(struct { - ControlURL string - RouteAll bool - ExitNodeID tailcfg.StableNodeID - ExitNodeIP netip.Addr - InternalExitNodePrior tailcfg.StableNodeID - ExitNodeAllowLANAccess bool - CorpDNS bool - RunSSH bool - RunWebClient bool - WantRunning bool - LoggedOut bool - ShieldsUp bool - AdvertiseTags []string - Hostname string - NotepadURLs bool - ForceDaemon bool - Egg bool - AdvertiseRoutes []netip.Prefix - AdvertiseServices []string - NoSNAT bool - NoStatefulFiltering opt.Bool - NetfilterMode preftype.NetfilterMode - OperatorUser string - ProfileName string - AutoUpdate AutoUpdatePrefs - AppConnector AppConnectorPrefs - PostureChecking bool - NetfilterKind string - DriveShares []*drive.Share - AllowSingleHosts marshalAsTrueInJSON - Persist *persist.Persist + ControlURL string + RouteAll bool + ExitNodeID tailcfg.StableNodeID + ExitNodeIP netip.Addr + AutoExitNode ExitNodeExpression + InternalExitNodePrior tailcfg.StableNodeID + ExitNodeAllowLANAccess bool + CorpDNS bool + RunSSH bool + RunWebClient bool + WantRunning bool + LoggedOut bool + ShieldsUp bool + AdvertiseTags []string + Hostname string + NotepadURLs bool + ForceDaemon bool + Egg bool + AdvertiseRoutes []netip.Prefix + AdvertiseServices []string + Sync opt.Bool + NoSNAT bool + NoStatefulFiltering opt.Bool + NetfilterMode preftype.NetfilterMode + OperatorUser string + ProfileName string + AutoUpdate AutoUpdatePrefs + AppConnector AppConnectorPrefs + PostureChecking bool + NetfilterKind string + DriveShares []*drive.Share + RelayServerPort *uint16 + RelayServerStaticEndpoints []netip.AddrPort + AllowSingleHosts marshalAsTrueInJSON + Persist *persist.Persist }{}) // Clone makes a deep copy of ServeConfig. @@ -213,10 +221,11 @@ func (src *TCPPortHandler) Clone() *TCPPortHandler { // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _TCPPortHandlerCloneNeedsRegeneration = TCPPortHandler(struct { - HTTPS bool - HTTP bool - TCPForward string - TerminateTLS string + HTTPS bool + HTTP bool + TCPForward string + TerminateTLS string + ProxyProtocol int }{}) // Clone makes a deep copy of HTTPHandler. @@ -227,14 +236,17 @@ func (src *HTTPHandler) Clone() *HTTPHandler { } dst := new(HTTPHandler) *dst = *src + dst.AcceptAppCaps = append(src.AcceptAppCaps[:0:0], src.AcceptAppCaps...) return dst } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _HTTPHandlerCloneNeedsRegeneration = HTTPHandler(struct { - Path string - Proxy string - Text string + Path string + Proxy string + Text string + AcceptAppCaps []tailcfg.PeerCapability + Redirect string }{}) // Clone makes a deep copy of WebServerConfig. @@ -251,7 +263,7 @@ func (src *WebServerConfig) Clone() *WebServerConfig { if v == nil { dst.Handlers[k] = nil } else { - dst.Handlers[k] = ptr.To(*v) + dst.Handlers[k] = v.Clone() } } } diff --git a/vendor/tailscale.com/ipn/ipn_view.go b/vendor/tailscale.com/ipn/ipn_view.go index e633a26..4157ec7 100644 --- a/vendor/tailscale.com/ipn/ipn_view.go +++ b/vendor/tailscale.com/ipn/ipn_view.go @@ -6,10 +6,12 @@ package ipn import ( - "encoding/json" + jsonv1 "encoding/json" "errors" "net/netip" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "tailscale.com/drive" "tailscale.com/tailcfg" "tailscale.com/types/opt" @@ -48,8 +50,17 @@ func (v LoginProfileView) AsStruct() *LoginProfile { return v.ж.Clone() } -func (v LoginProfileView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v LoginProfileView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v LoginProfileView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *LoginProfileView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -58,21 +69,67 @@ func (v *LoginProfileView) UnmarshalJSON(b []byte) error { return nil } var x LoginProfile - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v LoginProfileView) ID() ProfileID { return v.ж.ID } -func (v LoginProfileView) Name() string { return v.ж.Name } -func (v LoginProfileView) NetworkProfile() NetworkProfile { return v.ж.NetworkProfile } -func (v LoginProfileView) Key() StateKey { return v.ж.Key } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *LoginProfileView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x LoginProfile + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// ID is a unique identifier for this profile. +// It is assigned on creation and never changes. +// It may seem redundant to have both ID and UserProfile.ID +// but they are different things. UserProfile.ID may change +// over time (e.g. if a device is tagged). +func (v LoginProfileView) ID() ProfileID { return v.ж.ID } + +// Name is the user-visible name of this profile. +// It is filled in from the UserProfile.LoginName field. +func (v LoginProfileView) Name() string { return v.ж.Name } + +// NetworkProfile is a subset of netmap.NetworkMap that we +// store to remember information about the tailnet that this +// profile was logged in with. +// +// This field was added on 2023-11-17. +func (v LoginProfileView) NetworkProfile() NetworkProfile { return v.ж.NetworkProfile } + +// Key is the StateKey under which the profile is stored. +// It is assigned once at profile creation time and never changes. +func (v LoginProfileView) Key() StateKey { return v.ж.Key } + +// UserProfile is the server provided UserProfile for this profile. +// This is updated whenever the server provides a new UserProfile. func (v LoginProfileView) UserProfile() tailcfg.UserProfile { return v.ж.UserProfile } -func (v LoginProfileView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID } -func (v LoginProfileView) LocalUserID() WindowsUserID { return v.ж.LocalUserID } -func (v LoginProfileView) ControlURL() string { return v.ж.ControlURL } + +// NodeID is the NodeID of the node that this profile is logged into. +// This should be stable across tagging and untagging nodes. +// It may seem redundant to check against both the UserProfile.UserID +// and the NodeID. However the NodeID can change if the node is deleted +// from the admin panel. +func (v LoginProfileView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID } + +// LocalUserID is the user ID of the user who created this profile. +// It is only relevant on Windows where we have a multi-user system. +// It is assigned once at profile creation time and never changes. +func (v LoginProfileView) LocalUserID() WindowsUserID { return v.ж.LocalUserID } + +// ControlURL is the URL of the control server that this profile is logged +// into. +func (v LoginProfileView) ControlURL() string { return v.ж.ControlURL } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _LoginProfileViewNeedsRegeneration = LoginProfile(struct { @@ -114,8 +171,17 @@ func (v PrefsView) AsStruct() *Prefs { return v.ж.Clone() } -func (v PrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v PrefsView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v PrefsView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *PrefsView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -124,84 +190,324 @@ func (v *PrefsView) UnmarshalJSON(b []byte) error { return nil } var x Prefs - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v PrefsView) ControlURL() string { return v.ж.ControlURL } -func (v PrefsView) RouteAll() bool { return v.ж.RouteAll } -func (v PrefsView) ExitNodeID() tailcfg.StableNodeID { return v.ж.ExitNodeID } -func (v PrefsView) ExitNodeIP() netip.Addr { return v.ж.ExitNodeIP } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *PrefsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Prefs + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// ControlURL is the URL of the control server to use. +// +// If empty, the default for new installs, DefaultControlURL +// is used. It's set non-empty once the daemon has been started +// for the first time. +// +// TODO(apenwarr): Make it safe to update this with EditPrefs(). +// Right now, you have to pass it in the initial prefs in Start(), +// which is the only code that actually uses the ControlURL value. +// It would be more consistent to restart controlclient +// automatically whenever this variable changes. +// +// Meanwhile, you have to provide this as part of +// Options.LegacyMigrationPrefs or Options.UpdatePrefs when +// calling Backend.Start(). +func (v PrefsView) ControlURL() string { return v.ж.ControlURL } + +// RouteAll specifies whether to accept subnets advertised by +// other nodes on the Tailscale network. Note that this does not +// include default routes (0.0.0.0/0 and ::/0), those are +// controlled by ExitNodeID/IP below. +func (v PrefsView) RouteAll() bool { return v.ж.RouteAll } + +// ExitNodeID and ExitNodeIP specify the node that should be used +// as an exit node for internet traffic. At most one of these +// should be non-zero. +// +// The preferred way to express the chosen node is ExitNodeID, but +// in some cases it's not possible to use that ID (e.g. in the +// linux CLI, before tailscaled has a netmap). For those +// situations, we allow specifying the exit node by IP, and +// ipnlocal.LocalBackend will translate the IP into an ID when the +// node is found in the netmap. +// +// If the selected exit node doesn't exist (e.g. it's not part of +// the current tailnet), or it doesn't offer exit node services, a +// blackhole route will be installed on the local system to +// prevent any traffic escaping to the local network. +func (v PrefsView) ExitNodeID() tailcfg.StableNodeID { return v.ж.ExitNodeID } +func (v PrefsView) ExitNodeIP() netip.Addr { return v.ж.ExitNodeIP } + +// AutoExitNode is an optional expression that specifies whether and how +// tailscaled should pick an exit node automatically. +// +// If specified, tailscaled will use an exit node based on the expression, +// and will re-evaluate the selection periodically as network conditions, +// available exit nodes, or policy settings change. A blackhole route will +// be installed to prevent traffic from escaping to the local network until +// an exit node is selected. It takes precedence over ExitNodeID and ExitNodeIP. +// +// If empty, tailscaled will not automatically select an exit node. +// +// If the specified expression is invalid or unsupported by the client, +// it falls back to the behavior of [AnyExitNode]. +// +// As of 2025-07-02, the only supported value is [AnyExitNode]. +// It's a string rather than a boolean to allow future extensibility +// (e.g., AutoExitNode = "mullvad" or AutoExitNode = "geo:us"). +func (v PrefsView) AutoExitNode() ExitNodeExpression { return v.ж.AutoExitNode } + +// InternalExitNodePrior is the most recently used ExitNodeID in string form. It is set by +// the backend on transition from exit node on to off and used by the +// backend. +// +// As an Internal field, it can't be set by LocalAPI clients, rather it is set indirectly +// when the ExitNodeID value is zero'd and via the set-use-exit-node-enabled endpoint. func (v PrefsView) InternalExitNodePrior() tailcfg.StableNodeID { return v.ж.InternalExitNodePrior } -func (v PrefsView) ExitNodeAllowLANAccess() bool { return v.ж.ExitNodeAllowLANAccess } -func (v PrefsView) CorpDNS() bool { return v.ж.CorpDNS } -func (v PrefsView) RunSSH() bool { return v.ж.RunSSH } -func (v PrefsView) RunWebClient() bool { return v.ж.RunWebClient } -func (v PrefsView) WantRunning() bool { return v.ж.WantRunning } -func (v PrefsView) LoggedOut() bool { return v.ж.LoggedOut } -func (v PrefsView) ShieldsUp() bool { return v.ж.ShieldsUp } -func (v PrefsView) AdvertiseTags() views.Slice[string] { return views.SliceOf(v.ж.AdvertiseTags) } -func (v PrefsView) Hostname() string { return v.ж.Hostname } -func (v PrefsView) NotepadURLs() bool { return v.ж.NotepadURLs } -func (v PrefsView) ForceDaemon() bool { return v.ж.ForceDaemon } -func (v PrefsView) Egg() bool { return v.ж.Egg } + +// ExitNodeAllowLANAccess indicates whether locally accessible subnets should be +// routed directly or via the exit node. +func (v PrefsView) ExitNodeAllowLANAccess() bool { return v.ж.ExitNodeAllowLANAccess } + +// CorpDNS specifies whether to install the Tailscale network's +// DNS configuration, if it exists. +func (v PrefsView) CorpDNS() bool { return v.ж.CorpDNS } + +// RunSSH bool is whether this node should run an SSH +// server, permitting access to peers according to the +// policies as configured by the Tailnet's admin(s). +func (v PrefsView) RunSSH() bool { return v.ж.RunSSH } + +// RunWebClient bool is whether this node should expose +// its web client over Tailscale at port 5252, +// permitting access to peers according to the +// policies as configured by the Tailnet's admin(s). +func (v PrefsView) RunWebClient() bool { return v.ж.RunWebClient } + +// WantRunning indicates whether networking should be active on +// this node. +func (v PrefsView) WantRunning() bool { return v.ж.WantRunning } + +// LoggedOut indicates whether the user intends to be logged out. +// There are other reasons we may be logged out, including no valid +// keys. +// We need to remember this state so that, on next startup, we can +// generate the "Login" vs "Connect" buttons correctly, without having +// to contact the server to confirm our nodekey status first. +func (v PrefsView) LoggedOut() bool { return v.ж.LoggedOut } + +// ShieldsUp indicates whether to block all incoming connections, +// regardless of the control-provided packet filter. If false, we +// use the packet filter as provided. If true, we block incoming +// connections. This overrides tailcfg.Hostinfo's ShieldsUp. +func (v PrefsView) ShieldsUp() bool { return v.ж.ShieldsUp } + +// AdvertiseTags specifies tags that should be applied to this node, for +// purposes of ACL enforcement. These can be referenced from the ACL policy +// document. Note that advertising a tag on the client doesn't guarantee +// that the control server will allow the node to adopt that tag. +func (v PrefsView) AdvertiseTags() views.Slice[string] { return views.SliceOf(v.ж.AdvertiseTags) } + +// Hostname is the hostname to use for identifying the node. If +// not set, os.Hostname is used. +func (v PrefsView) Hostname() string { return v.ж.Hostname } + +// NotepadURLs is a debugging setting that opens OAuth URLs in +// notepad.exe on Windows, rather than loading them in a browser. +// +// apenwarr 2020-04-29: Unfortunately this is still needed sometimes. +// Windows' default browser setting is sometimes screwy and this helps +// users narrow it down a bit. +func (v PrefsView) NotepadURLs() bool { return v.ж.NotepadURLs } + +// ForceDaemon specifies whether a platform that normally +// operates in "client mode" (that is, requires an active user +// logged in with the GUI app running) should keep running after the +// GUI ends and/or the user logs out. +// +// The only current applicable platform is Windows. This +// forced Windows to go into "server mode" where Tailscale is +// running even with no users logged in. This might also be +// used for macOS in the future. This setting has no effect +// for Linux/etc, which always operate in daemon mode. +func (v PrefsView) ForceDaemon() bool { return v.ж.ForceDaemon } + +// Egg is a optional debug flag. +func (v PrefsView) Egg() bool { return v.ж.Egg } + +// AdvertiseRoutes specifies CIDR prefixes to advertise into the +// Tailscale network as reachable through the current +// node. func (v PrefsView) AdvertiseRoutes() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.AdvertiseRoutes) } + +// AdvertiseServices specifies the list of services that this +// node can serve as a destination for. Note that an advertised +// service must still go through the approval process from the +// control server. func (v PrefsView) AdvertiseServices() views.Slice[string] { return views.SliceOf(v.ж.AdvertiseServices) } -func (v PrefsView) NoSNAT() bool { return v.ж.NoSNAT } -func (v PrefsView) NoStatefulFiltering() opt.Bool { return v.ж.NoStatefulFiltering } + +// Sync is whether this node should sync its configuration from +// the control plane. If unset, this defaults to true. +// This exists primarily for testing, to verify that netmap caching +// and offline operation work correctly. +func (v PrefsView) Sync() opt.Bool { return v.ж.Sync } + +// NoSNAT specifies whether to source NAT traffic going to +// destinations in AdvertiseRoutes. The default is to apply source +// NAT, which makes the traffic appear to come from the router +// machine rather than the peer's Tailscale IP. +// +// Disabling SNAT requires additional manual configuration in your +// network to route Tailscale traffic back to the subnet relay +// machine. +// +// Linux-only. +func (v PrefsView) NoSNAT() bool { return v.ж.NoSNAT } + +// NoStatefulFiltering specifies whether to apply stateful filtering when +// advertising routes in AdvertiseRoutes. The default is to not apply +// stateful filtering. +// +// To allow inbound connections from advertised routes, both NoSNAT and +// NoStatefulFiltering must be true. +// +// This is an opt.Bool because it was first added after NoSNAT, with a +// backfill based on the value of that parameter. The backfill has been +// removed since then, but the field remains an opt.Bool. +// +// Linux-only. +func (v PrefsView) NoStatefulFiltering() opt.Bool { return v.ж.NoStatefulFiltering } + +// NetfilterMode specifies how much to manage netfilter rules for +// Tailscale, if at all. func (v PrefsView) NetfilterMode() preftype.NetfilterMode { return v.ж.NetfilterMode } -func (v PrefsView) OperatorUser() string { return v.ж.OperatorUser } -func (v PrefsView) ProfileName() string { return v.ж.ProfileName } -func (v PrefsView) AutoUpdate() AutoUpdatePrefs { return v.ж.AutoUpdate } -func (v PrefsView) AppConnector() AppConnectorPrefs { return v.ж.AppConnector } -func (v PrefsView) PostureChecking() bool { return v.ж.PostureChecking } -func (v PrefsView) NetfilterKind() string { return v.ж.NetfilterKind } + +// OperatorUser is the local machine user name who is allowed to +// operate tailscaled without being root or using sudo. +func (v PrefsView) OperatorUser() string { return v.ж.OperatorUser } + +// ProfileName is the desired name of the profile. If empty, then the user's +// LoginName is used. It is only used for display purposes in the client UI +// and CLI. +func (v PrefsView) ProfileName() string { return v.ж.ProfileName } + +// AutoUpdate sets the auto-update preferences for the node agent. See +// AutoUpdatePrefs docs for more details. +func (v PrefsView) AutoUpdate() AutoUpdatePrefs { return v.ж.AutoUpdate } + +// AppConnector sets the app connector preferences for the node agent. See +// AppConnectorPrefs docs for more details. +func (v PrefsView) AppConnector() AppConnectorPrefs { return v.ж.AppConnector } + +// PostureChecking enables the collection of information used for device +// posture checks. +// +// Note: this should be named ReportPosture, but it was shipped as +// PostureChecking in some early releases and this JSON field is written to +// disk, so we just keep its old name. (akin to CorpDNS which is an internal +// pref name that doesn't match the public interface) +func (v PrefsView) PostureChecking() bool { return v.ж.PostureChecking } + +// NetfilterKind specifies what netfilter implementation to use. +// +// It can be "iptables", "nftables", or "" to auto-detect. +// +// Linux-only. +func (v PrefsView) NetfilterKind() string { return v.ж.NetfilterKind } + +// DriveShares are the configured DriveShares, stored in increasing order +// by name. func (v PrefsView) DriveShares() views.SliceView[*drive.Share, drive.ShareView] { return views.SliceOfViews[*drive.Share, drive.ShareView](v.ж.DriveShares) } + +// RelayServerPort is the UDP port number for the relay server to bind to, +// on all interfaces. A non-nil zero value signifies a random unused port +// should be used. A nil value signifies relay server functionality +// should be disabled. +func (v PrefsView) RelayServerPort() views.ValuePointer[uint16] { + return views.ValuePointerOf(v.ж.RelayServerPort) +} + +// RelayServerStaticEndpoints are static IP:port endpoints to advertise as +// candidates for relay connections. Only relevant when RelayServerPort is +// non-nil. +func (v PrefsView) RelayServerStaticEndpoints() views.Slice[netip.AddrPort] { + return views.SliceOf(v.ж.RelayServerStaticEndpoints) +} + +// AllowSingleHosts was a legacy field that was always true +// for the past 4.5 years. It controlled whether Tailscale +// peers got /32 or /128 routes for each other. +// As of 2024-05-17 we're starting to ignore it, but to let +// people still downgrade Tailscale versions and not break +// all peer-to-peer networking we still write it to disk (as JSON) +// so it can be loaded back by old versions. +// TODO(bradfitz): delete this in 2025 sometime. See #12058. func (v PrefsView) AllowSingleHosts() marshalAsTrueInJSON { return v.ж.AllowSingleHosts } -func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() } + +// The Persist field is named 'Config' in the file for backward +// compatibility with earlier versions. +// TODO(apenwarr): We should move this out of here, it's not a pref. +// +// We can maybe do that once we're sure which module should persist +// it (backend or frontend?) +func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _PrefsViewNeedsRegeneration = Prefs(struct { - ControlURL string - RouteAll bool - ExitNodeID tailcfg.StableNodeID - ExitNodeIP netip.Addr - InternalExitNodePrior tailcfg.StableNodeID - ExitNodeAllowLANAccess bool - CorpDNS bool - RunSSH bool - RunWebClient bool - WantRunning bool - LoggedOut bool - ShieldsUp bool - AdvertiseTags []string - Hostname string - NotepadURLs bool - ForceDaemon bool - Egg bool - AdvertiseRoutes []netip.Prefix - AdvertiseServices []string - NoSNAT bool - NoStatefulFiltering opt.Bool - NetfilterMode preftype.NetfilterMode - OperatorUser string - ProfileName string - AutoUpdate AutoUpdatePrefs - AppConnector AppConnectorPrefs - PostureChecking bool - NetfilterKind string - DriveShares []*drive.Share - AllowSingleHosts marshalAsTrueInJSON - Persist *persist.Persist + ControlURL string + RouteAll bool + ExitNodeID tailcfg.StableNodeID + ExitNodeIP netip.Addr + AutoExitNode ExitNodeExpression + InternalExitNodePrior tailcfg.StableNodeID + ExitNodeAllowLANAccess bool + CorpDNS bool + RunSSH bool + RunWebClient bool + WantRunning bool + LoggedOut bool + ShieldsUp bool + AdvertiseTags []string + Hostname string + NotepadURLs bool + ForceDaemon bool + Egg bool + AdvertiseRoutes []netip.Prefix + AdvertiseServices []string + Sync opt.Bool + NoSNAT bool + NoStatefulFiltering opt.Bool + NetfilterMode preftype.NetfilterMode + OperatorUser string + ProfileName string + AutoUpdate AutoUpdatePrefs + AppConnector AppConnectorPrefs + PostureChecking bool + NetfilterKind string + DriveShares []*drive.Share + RelayServerPort *uint16 + RelayServerStaticEndpoints []netip.AddrPort + AllowSingleHosts marshalAsTrueInJSON + Persist *persist.Persist }{}) // View returns a read-only view of ServeConfig. @@ -232,8 +538,17 @@ func (v ServeConfigView) AsStruct() *ServeConfig { return v.ж.Clone() } -func (v ServeConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ServeConfigView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ServeConfigView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *ServeConfigView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -242,40 +557,72 @@ func (v *ServeConfigView) UnmarshalJSON(b []byte) error { return nil } var x ServeConfig - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ServeConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x ServeConfig + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// TCP are the list of TCP port numbers that tailscaled should handle for +// the Tailscale IP addresses. (not subnet routers, etc) func (v ServeConfigView) TCP() views.MapFn[uint16, *TCPPortHandler, TCPPortHandlerView] { return views.MapFnOf(v.ж.TCP, func(t *TCPPortHandler) TCPPortHandlerView { return t.View() }) } +// Web maps from "$SNI_NAME:$PORT" to a set of HTTP handlers +// keyed by mount point ("/", "/foo", etc) func (v ServeConfigView) Web() views.MapFn[HostPort, *WebServerConfig, WebServerConfigView] { return views.MapFnOf(v.ж.Web, func(t *WebServerConfig) WebServerConfigView { return t.View() }) } +// Services maps from service name (in the form "svc:dns-label") to a ServiceConfig. +// Which describes the L3, L4, and L7 forwarding information for the service. func (v ServeConfigView) Services() views.MapFn[tailcfg.ServiceName, *ServiceConfig, ServiceConfigView] { return views.MapFnOf(v.ж.Services, func(t *ServiceConfig) ServiceConfigView { return t.View() }) } +// AllowFunnel is the set of SNI:port values for which funnel +// traffic is allowed, from trusted ingress peers. func (v ServeConfigView) AllowFunnel() views.Map[HostPort, bool] { return views.MapOf(v.ж.AllowFunnel) } +// Foreground is a map of an IPN Bus session ID to an alternate foreground serve config that's valid for the +// life of that WatchIPNBus session ID. This allows the config to specify ephemeral configs that are used +// in the CLI's foreground mode to ensure ungraceful shutdowns of either the client or the LocalBackend does not +// expose ports that users are not aware of. In practice this contains any serve config set via 'tailscale +// serve' command run without the '--bg' flag. ServeConfig contained by Foreground is not expected itself to contain +// another Foreground block. func (v ServeConfigView) Foreground() views.MapFn[string, *ServeConfig, ServeConfigView] { return views.MapFnOf(v.ж.Foreground, func(t *ServeConfig) ServeConfigView { return t.View() }) } + +// ETag is the checksum of the serve config that's populated +// by the LocalClient through the HTTP ETag header during a +// GetServeConfig request and is translated to an If-Match header +// during a SetServeConfig request. func (v ServeConfigView) ETag() string { return v.ж.ETag } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -316,8 +663,17 @@ func (v ServiceConfigView) AsStruct() *ServiceConfig { return v.ж.Clone() } -func (v ServiceConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ServiceConfigView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ServiceConfigView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *ServiceConfigView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -326,24 +682,43 @@ func (v *ServiceConfigView) UnmarshalJSON(b []byte) error { return nil } var x ServiceConfig - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ServiceConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x ServiceConfig + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// TCP are the list of TCP port numbers that tailscaled should handle for +// the Tailscale IP addresses. (not subnet routers, etc) func (v ServiceConfigView) TCP() views.MapFn[uint16, *TCPPortHandler, TCPPortHandlerView] { return views.MapFnOf(v.ж.TCP, func(t *TCPPortHandler) TCPPortHandlerView { return t.View() }) } +// Web maps from "$SNI_NAME:$PORT" to a set of HTTP handlers +// keyed by mount point ("/", "/foo", etc) func (v ServiceConfigView) Web() views.MapFn[HostPort, *WebServerConfig, WebServerConfigView] { return views.MapFnOf(v.ж.Web, func(t *WebServerConfig) WebServerConfigView { return t.View() }) } + +// Tun determines if the service should be using L3 forwarding (Tun mode). func (v ServiceConfigView) Tun() bool { return v.ж.Tun } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -381,8 +756,17 @@ func (v TCPPortHandlerView) AsStruct() *TCPPortHandler { return v.ж.Clone() } -func (v TCPPortHandlerView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v TCPPortHandlerView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v TCPPortHandlerView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *TCPPortHandlerView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -391,24 +775,64 @@ func (v *TCPPortHandlerView) UnmarshalJSON(b []byte) error { return nil } var x TCPPortHandler - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v TCPPortHandlerView) HTTPS() bool { return v.ж.HTTPS } -func (v TCPPortHandlerView) HTTP() bool { return v.ж.HTTP } -func (v TCPPortHandlerView) TCPForward() string { return v.ж.TCPForward } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *TCPPortHandlerView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x TCPPortHandler + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// HTTPS, if true, means that tailscaled should handle this connection as an +// HTTPS request as configured by ServeConfig.Web. +// +// It is mutually exclusive with TCPForward. +func (v TCPPortHandlerView) HTTPS() bool { return v.ж.HTTPS } + +// HTTP, if true, means that tailscaled should handle this connection as an +// HTTP request as configured by ServeConfig.Web. +// +// It is mutually exclusive with TCPForward. +func (v TCPPortHandlerView) HTTP() bool { return v.ж.HTTP } + +// TCPForward is the IP:port to forward TCP connections to. +// Whether or not TLS is terminated by tailscaled depends on +// TerminateTLS. +// +// It is mutually exclusive with HTTPS. +func (v TCPPortHandlerView) TCPForward() string { return v.ж.TCPForward } + +// TerminateTLS, if non-empty, means that tailscaled should terminate the +// TLS connections before forwarding them to TCPForward, permitting only the +// SNI name with this value. It is only used if TCPForward is non-empty. +// (the HTTPS mode uses ServeConfig.Web) func (v TCPPortHandlerView) TerminateTLS() string { return v.ж.TerminateTLS } +// ProxyProtocol indicates whether to send a PROXY protocol header +// before forwarding the connection to TCPForward. +// +// This is only valid if TCPForward is non-empty. +func (v TCPPortHandlerView) ProxyProtocol() int { return v.ж.ProxyProtocol } + // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _TCPPortHandlerViewNeedsRegeneration = TCPPortHandler(struct { - HTTPS bool - HTTP bool - TCPForward string - TerminateTLS string + HTTPS bool + HTTP bool + TCPForward string + TerminateTLS string + ProxyProtocol int }{}) // View returns a read-only view of HTTPHandler. @@ -439,8 +863,17 @@ func (v HTTPHandlerView) AsStruct() *HTTPHandler { return v.ж.Clone() } -func (v HTTPHandlerView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v HTTPHandlerView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v HTTPHandlerView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *HTTPHandlerView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -449,22 +882,56 @@ func (v *HTTPHandlerView) UnmarshalJSON(b []byte) error { return nil } var x HTTPHandler - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v HTTPHandlerView) Path() string { return v.ж.Path } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *HTTPHandlerView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x HTTPHandler + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// absolute path to directory or file to serve +func (v HTTPHandlerView) Path() string { return v.ж.Path } + +// http://localhost:3000/, localhost:3030, 3030 func (v HTTPHandlerView) Proxy() string { return v.ж.Proxy } -func (v HTTPHandlerView) Text() string { return v.ж.Text } + +// plaintext to serve (primarily for testing) +func (v HTTPHandlerView) Text() string { return v.ж.Text } + +// peer capabilities to forward in grant header, e.g. example.com/cap/mon +func (v HTTPHandlerView) AcceptAppCaps() views.Slice[tailcfg.PeerCapability] { + return views.SliceOf(v.ж.AcceptAppCaps) +} + +// Redirect, if not empty, is the target URL to redirect requests to. +// By default, we redirect with HTTP 302 (Found) status. +// If Redirect starts with ':', then we use that status instead. +// +// The target URL supports the following expansion variables: +// - ${HOST}: replaced with the request's Host header value +// - ${REQUEST_URI}: replaced with the request's full URI (path and query string) +func (v HTTPHandlerView) Redirect() string { return v.ж.Redirect } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _HTTPHandlerViewNeedsRegeneration = HTTPHandler(struct { - Path string - Proxy string - Text string + Path string + Proxy string + Text string + AcceptAppCaps []tailcfg.PeerCapability + Redirect string }{}) // View returns a read-only view of WebServerConfig. @@ -495,8 +962,17 @@ func (v WebServerConfigView) AsStruct() *WebServerConfig { return v.ж.Clone() } -func (v WebServerConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v WebServerConfigView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v WebServerConfigView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *WebServerConfigView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -505,13 +981,27 @@ func (v *WebServerConfigView) UnmarshalJSON(b []byte) error { return nil } var x WebServerConfig - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *WebServerConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x WebServerConfig + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// mountPoint => handler func (v WebServerConfigView) Handlers() views.MapFn[string, *HTTPHandler, HTTPHandlerView] { return views.MapFnOf(v.ж.Handlers, func(t *HTTPHandler) HTTPHandlerView { return t.View() diff --git a/vendor/tailscale.com/ipn/ipnauth/ipnauth.go b/vendor/tailscale.com/ipn/ipnauth/ipnauth.go index e656057..497f30f 100644 --- a/vendor/tailscale.com/ipn/ipnauth/ipnauth.go +++ b/vendor/tailscale.com/ipn/ipnauth/ipnauth.go @@ -14,8 +14,8 @@ import ( "runtime" "strconv" - "github.com/tailscale/peercred" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn" "tailscale.com/safesocket" "tailscale.com/types/logger" @@ -63,8 +63,8 @@ type ConnIdentity struct { notWindows bool // runtime.GOOS != "windows" // Fields used when NotWindows: - isUnixSock bool // Conn is a *net.UnixConn - creds *peercred.Creds // or nil + isUnixSock bool // Conn is a *net.UnixConn + creds PeerCreds // or nil if peercred.Get was not implemented on this OS // Used on Windows: // TODO(bradfitz): merge these into the peercreds package and @@ -78,6 +78,13 @@ type ConnIdentity struct { // It's suitable for passing to LookupUserFromID (os/user.LookupId) on any // operating system. func (ci *ConnIdentity) WindowsUserID() ipn.WindowsUserID { + if !buildfeatures.HasDebug && runtime.GOOS != "windows" { + // This function is only implemented on non-Windows for simulating + // Windows in tests. But that test (per comments below) is broken + // anyway. So disable this testing path in non-debug builds + // and just do the thing that optimizes away. + return "" + } if envknob.GOOS() != "windows" { return "" } @@ -97,9 +104,18 @@ func (ci *ConnIdentity) WindowsUserID() ipn.WindowsUserID { return "" } -func (ci *ConnIdentity) Pid() int { return ci.pid } -func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock } -func (ci *ConnIdentity) Creds() *peercred.Creds { return ci.creds } +func (ci *ConnIdentity) Pid() int { return ci.pid } +func (ci *ConnIdentity) IsUnixSock() bool { return ci.isUnixSock } +func (ci *ConnIdentity) Creds() PeerCreds { return ci.creds } + +// PeerCreds is the interface for a github.com/tailscale/peercred.Creds, +// if linked into the binary. +// +// (It's not used on some platforms, or if ts_omit_unixsocketidentity is set.) +type PeerCreds interface { + UserID() (uid string, ok bool) + PID() (pid int, ok bool) +} var metricIssue869Workaround = clientmetric.NewCounter("issue_869_workaround") diff --git a/vendor/tailscale.com/ipn/ipnauth/ipnauth_notwindows.go b/vendor/tailscale.com/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go similarity index 72% rename from vendor/tailscale.com/ipn/ipnauth/ipnauth_notwindows.go rename to vendor/tailscale.com/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go index d9d11bd..defe7d8 100644 --- a/vendor/tailscale.com/ipn/ipnauth/ipnauth_notwindows.go +++ b/vendor/tailscale.com/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go @@ -1,14 +1,13 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !windows +//go:build !windows && ts_omit_unixsocketidentity package ipnauth import ( "net" - "github.com/tailscale/peercred" "tailscale.com/types/logger" ) @@ -16,12 +15,7 @@ import ( // based on the user who owns the other end of the connection. // and couldn't. The returned connIdentity has NotWindows set to true. func GetConnIdentity(_ logger.Logf, c net.Conn) (ci *ConnIdentity, err error) { - ci = &ConnIdentity{conn: c, notWindows: true} - _, ci.isUnixSock = c.(*net.UnixConn) - if ci.creds, _ = peercred.Get(c); ci.creds != nil { - ci.pid, _ = ci.creds.PID() - } - return ci, nil + return &ConnIdentity{conn: c, notWindows: true}, nil } // WindowsToken is unsupported when GOOS != windows and always returns diff --git a/vendor/tailscale.com/ipn/ipnauth/ipnauth_unix_creds.go b/vendor/tailscale.com/ipn/ipnauth/ipnauth_unix_creds.go new file mode 100644 index 0000000..89a9cea --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnauth/ipnauth_unix_creds.go @@ -0,0 +1,37 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !windows && !ts_omit_unixsocketidentity + +package ipnauth + +import ( + "net" + + "github.com/tailscale/peercred" + "tailscale.com/types/logger" +) + +// GetConnIdentity extracts the identity information from the connection +// based on the user who owns the other end of the connection. +// and couldn't. The returned connIdentity has NotWindows set to true. +func GetConnIdentity(_ logger.Logf, c net.Conn) (ci *ConnIdentity, err error) { + ci = &ConnIdentity{conn: c, notWindows: true} + _, ci.isUnixSock = c.(*net.UnixConn) + if creds, err := peercred.Get(c); err == nil { + ci.creds = creds + ci.pid, _ = ci.creds.PID() + } else if err == peercred.ErrNotImplemented { + // peercred.Get is not implemented on this OS (such as OpenBSD) + // Just leave creds as nil, as documented. + } else { + return nil, err + } + return ci, nil +} + +// WindowsToken is unsupported when GOOS != windows and always returns +// ErrNotImplemented. +func (ci *ConnIdentity) WindowsToken() (WindowsToken, error) { + return nil, ErrNotImplemented +} diff --git a/vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go b/vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go index 1138bc2..e3ea448 100644 --- a/vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go +++ b/vendor/tailscale.com/ipn/ipnauth/ipnauth_windows.go @@ -25,6 +25,12 @@ func GetConnIdentity(logf logger.Logf, c net.Conn) (ci *ConnIdentity, err error) if !ok { return nil, fmt.Errorf("not a WindowsClientConn: %T", c) } + if err := wcc.CheckToken(); err != nil { + // Failure to obtain a token means the client cannot be authenticated. + // We don't care about the exact error, but it typically means the client + // attempted to connect at the Anonymous impersonation level. + return nil, fmt.Errorf("authentication failed: %w", err) + } ci.pid, err = wcc.ClientPID() if err != nil { return nil, err @@ -169,26 +175,13 @@ func (t *token) IsUID(uid ipn.WindowsUserID) bool { // WindowsToken returns the WindowsToken representing the security context // of the connection's client. func (ci *ConnIdentity) WindowsToken() (WindowsToken, error) { - var wcc *safesocket.WindowsClientConn - var ok bool - if wcc, ok = ci.conn.(*safesocket.WindowsClientConn); !ok { + wcc, ok := ci.conn.(*safesocket.WindowsClientConn) + if !ok { return nil, fmt.Errorf("not a WindowsClientConn: %T", ci.conn) } - - // We duplicate the token's handle so that the WindowsToken we return may have - // a lifetime independent from the original connection. - var h windows.Handle - if err := windows.DuplicateHandle( - windows.CurrentProcess(), - windows.Handle(wcc.Token()), - windows.CurrentProcess(), - &h, - 0, - false, - windows.DUPLICATE_SAME_ACCESS, - ); err != nil { + token, err := wcc.Token() + if err != nil { return nil, err } - - return newToken(windows.Token(h)), nil + return newToken(token), nil } diff --git a/vendor/tailscale.com/ipn/ipnauth/policy.go b/vendor/tailscale.com/ipn/ipnauth/policy.go index aa4ec41..eeee324 100644 --- a/vendor/tailscale.com/ipn/ipnauth/policy.go +++ b/vendor/tailscale.com/ipn/ipnauth/policy.go @@ -8,9 +8,11 @@ import ( "fmt" "tailscale.com/client/tailscale/apitype" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn" "tailscale.com/tailcfg" - "tailscale.com/util/syspolicy" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" ) type actorWithPolicyChecks struct{ Actor } @@ -50,10 +52,13 @@ func (a actorWithPolicyChecks) CheckProfileAccess(profile ipn.LoginProfileView, // TODO(nickkhyl): unexport it when we move [ipn.Actor] implementations from [ipnserver] // and corp to this package. func CheckDisconnectPolicy(actor Actor, profile ipn.LoginProfileView, reason string, auditFn AuditLogFunc) error { - if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); !alwaysOn { + if !buildfeatures.HasSystemPolicy { return nil } - if allowWithReason, _ := syspolicy.GetBoolean(syspolicy.AlwaysOnOverrideWithReason, false); !allowWithReason { + if alwaysOn, _ := policyclient.Get().GetBoolean(pkey.AlwaysOn, false); !alwaysOn { + return nil + } + if allowWithReason, _ := policyclient.Get().GetBoolean(pkey.AlwaysOnOverrideWithReason, false); !allowWithReason { return errors.New("disconnect not allowed: always-on mode is enabled") } if reason == "" { diff --git a/vendor/tailscale.com/ipn/ipnauth/self.go b/vendor/tailscale.com/ipn/ipnauth/self.go index 9b430dc..adee069 100644 --- a/vendor/tailscale.com/ipn/ipnauth/self.go +++ b/vendor/tailscale.com/ipn/ipnauth/self.go @@ -13,6 +13,11 @@ import ( // has unlimited access. var Self Actor = unrestricted{} +// TODO is a caller identity used when the operation is performed on behalf of a user, +// rather than by tailscaled itself, but the surrounding function is not yet extended +// to accept an [Actor] parameter. It grants the same unrestricted access as [Self]. +var TODO Actor = unrestricted{} + // unrestricted is an [Actor] that has unlimited access to the currently running // tailscaled instance. It's typically used for operations performed by tailscaled // on its own, or upon a request from the control plane, rather on behalf of a user. @@ -49,3 +54,10 @@ func (unrestricted) IsLocalSystem() bool { return false } // Deprecated: this method exists for compatibility with the current (as of 2025-01-28) // permission model and will be removed as we progress on tailscale/corp#18342. func (unrestricted) IsLocalAdmin(operatorUID string) bool { return false } + +// IsTailscaled reports whether the given Actor represents Tailscaled itself, +// such as [Self] or a [TODO] placeholder actor. +func IsTailscaled(a Actor) bool { + _, ok := a.(unrestricted) + return ok +} diff --git a/vendor/tailscale.com/ipn/ipnext/ipnext.go b/vendor/tailscale.com/ipn/ipnext/ipnext.go new file mode 100644 index 0000000..fc93cc8 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnext/ipnext.go @@ -0,0 +1,411 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package ipnext defines types and interfaces used for extending the core LocalBackend +// functionality with additional features and services. +package ipnext + +import ( + "errors" + "fmt" + "iter" + "net/netip" + + "tailscale.com/control/controlclient" + "tailscale.com/feature" + "tailscale.com/ipn" + "tailscale.com/ipn/ipnauth" + "tailscale.com/ipn/ipnstate" + "tailscale.com/tailcfg" + "tailscale.com/tsd" + "tailscale.com/tstime" + "tailscale.com/types/logger" + "tailscale.com/types/mapx" +) + +// Extension augments LocalBackend with additional functionality. +// +// An extension uses the provided [Host] to register callbacks +// and interact with the backend in a controlled, well-defined +// and thread-safe manner. +// +// Extensions are registered using [RegisterExtension]. +// +// They must be safe for concurrent use. +type Extension interface { + // Name is a unique name of the extension. + // It must be the same as the name used to register the extension. + Name() string + + // Init is called to initialize the extension when LocalBackend's + // Start method is called. Extensions are created but not initialized + // unless LocalBackend is started. + // + // If the extension cannot be initialized, it must return an error, + // and its Shutdown method will not be called on the host's shutdown. + // Returned errors are not fatal; they are used for logging. + // A [SkipExtension] error indicates an intentional decision rather than a failure. + Init(Host) error + + // Shutdown is called when LocalBackend is shutting down, + // provided the extension was initialized. For multiple extensions, + // Shutdown is called in the reverse order of Init. + // Returned errors are not fatal; they are used for logging. + // After a call to Shutdown, the extension will not be called again. + Shutdown() error +} + +// NewExtensionFn is a function that instantiates an [Extension]. +// If a registered extension cannot be instantiated, the function must return an error. +// If the extension should be skipped at runtime, it must return either [SkipExtension] +// or a wrapped [SkipExtension]. Any other error returned is fatal and will prevent +// the LocalBackend from starting. +type NewExtensionFn func(logger.Logf, SafeBackend) (Extension, error) + +// SkipExtension is an error returned by [NewExtensionFn] to indicate that the extension +// should be skipped rather than prevent the LocalBackend from starting. +// +// Skipping an extension should be reserved for cases where the extension is not supported +// on the current platform or configuration, or depends on a feature that is not available, +// or otherwise should be disabled permanently rather than temporarily. +// +// Specifically, it must not be returned if the extension is not required right now +// based on user preferences, policy settings, the current tailnet, or other factors +// that may change throughout the LocalBackend's lifetime. +var SkipExtension = errors.New("skipping extension") + +// Definition describes a registered [Extension]. +type Definition struct { + name string // name under which the extension is registered + newFn NewExtensionFn // function that creates a new instance of the extension +} + +// Name returns the name of the extension. +func (d *Definition) Name() string { + return d.name +} + +// MakeExtension instantiates the extension. +func (d *Definition) MakeExtension(logf logger.Logf, sb SafeBackend) (Extension, error) { + ext, err := d.newFn(logf, sb) + if err != nil { + return nil, err + } + if ext.Name() != d.name { + return nil, fmt.Errorf("extension name mismatch: registered %q; actual %q", d.name, ext.Name()) + } + return ext, nil +} + +// extensions is a map of registered extensions, +// where the key is the name of the extension. +var extensions mapx.OrderedMap[string, *Definition] + +// RegisterExtension registers a function that instantiates an [Extension]. +// The name must be the same as returned by the extension's [Extension.Name]. +// +// It must be called on the main goroutine before LocalBackend is created, +// such as from an init function of the package implementing the extension. +// +// It panics if newExt is nil or if an extension with the same name +// has already been registered. +func RegisterExtension(name string, newExt NewExtensionFn) { + if newExt == nil { + panic(fmt.Sprintf("ipnext: newExt is nil: %q", name)) + } + if extensions.Contains(name) { + panic(fmt.Sprintf("ipnext: duplicate extension name %q", name)) + } + extensions.Set(name, &Definition{name, newExt}) +} + +// Extensions iterates over the extensions in the order they were registered +// via [RegisterExtension]. +func Extensions() iter.Seq[*Definition] { + return extensions.Values() +} + +// DefinitionForTest returns a [Definition] for the specified [Extension]. +// It is primarily used for testing where the test code needs to instantiate +// and use an extension without registering it. +func DefinitionForTest(ext Extension) *Definition { + return &Definition{ + name: ext.Name(), + newFn: func(logger.Logf, SafeBackend) (Extension, error) { return ext, nil }, + } +} + +// DefinitionWithErrForTest returns a [Definition] with the specified extension name +// whose [Definition.MakeExtension] method returns the specified error. +// It is used for testing. +func DefinitionWithErrForTest(name string, err error) *Definition { + return &Definition{ + name: name, + newFn: func(logger.Logf, SafeBackend) (Extension, error) { return nil, err }, + } +} + +// Host is the API surface used by [Extension]s to interact with LocalBackend +// in a controlled manner. +// +// Extensions can register callbacks, request information, or perform actions +// via the [Host] interface. +// +// Typically, the host invokes registered callbacks when one of the following occurs: +// - LocalBackend notifies it of an event or state change that may be +// of interest to extensions, such as when switching [ipn.LoginProfile]. +// - LocalBackend needs to consult extensions for information, for example, +// determining the most appropriate profile for the current state of the system. +// - LocalBackend performs an extensible action, such as logging an auditable event, +// and delegates its execution to the extension. +// +// The callbacks are invoked synchronously, and the LocalBackend's state +// remains unchanged while callbacks execute. +// +// In contrast, actions initiated by extensions are generally asynchronous, +// as indicated by the "Async" suffix in their names. +// Performing actions may result in callbacks being invoked as described above. +// +// To prevent conflicts between extensions competing for shared state, +// such as the current profile or prefs, the host must not expose methods +// that directly modify that state. For example, instead of allowing extensions +// to switch profiles at-will, the host's [ProfileServices] provides a method +// to switch to the "best" profile. The host can then consult extensions +// to determine the appropriate profile to use and resolve any conflicts +// in a controlled manner. +// +// A host must be safe for concurrent use. +type Host interface { + // Extensions returns the host's [ExtensionServices]. + Extensions() ExtensionServices + + // Profiles returns the host's [ProfileServices]. + Profiles() ProfileServices + + // AuditLogger returns a function that calls all currently registered audit loggers. + // The function fails if any logger returns an error, indicating that the action + // cannot be logged and must not be performed. + // + // The returned function captures the current state (e.g., the current profile) at + // the time of the call and must not be persisted. + AuditLogger() ipnauth.AuditLogFunc + + // Hooks returns a non-nil pointer to a [Hooks] struct. + // Hooks must not be modified concurrently or after Tailscale has started. + Hooks() *Hooks + + // SendNotifyAsync sends a notification to the IPN bus, + // typically to the GUI client. + SendNotifyAsync(ipn.Notify) + + // NodeBackend returns the [NodeBackend] for the currently active node + // (which is approximately the same as the current profile). + NodeBackend() NodeBackend +} + +// SafeBackend is a subset of the [ipnlocal.LocalBackend] type's methods that +// are safe to call from extension hooks at any time (even hooks called while +// LocalBackend's internal mutex is held). +type SafeBackend interface { + Sys() *tsd.System + Clock() tstime.Clock + TailscaleVarRoot() string +} + +// ExtensionServices provides access to the [Host]'s extension management services, +// such as fetching active extensions. +type ExtensionServices interface { + // FindExtensionByName returns an active extension with the given name, + // or nil if no such extension exists. + FindExtensionByName(name string) any + + // FindMatchingExtension finds the first active extension that matches target, + // and if one is found, sets target to that extension and returns true. + // Otherwise, it returns false. + // + // It panics if target is not a non-nil pointer to either a type + // that implements [ipnext.Extension], or to any interface type. + FindMatchingExtension(target any) bool +} + +// ProfileServices provides access to the [Host]'s profile management services, +// such as switching profiles and registering profile change callbacks. +type ProfileServices interface { + // CurrentProfileState returns read-only views of the current profile + // and its preferences. The returned views are always valid, + // but the profile's [ipn.LoginProfileView.ID] returns "" + // if the profile is new and has not been persisted yet. + // + // The returned views are immutable snapshots of the current profile + // and prefs at the time of the call. The actual state is only guaranteed + // to remain unchanged and match these views for the duration + // of a callback invoked by the host, if used within that callback. + // + // Extensions that need the current profile or prefs at other times + // should typically subscribe to [ProfileStateChangeCallback] + // to be notified if the profile or prefs change after retrieval. + // CurrentProfileState returns both the profile and prefs + // to guarantee that they are consistent with each other. + CurrentProfileState() (ipn.LoginProfileView, ipn.PrefsView) + + // CurrentPrefs is like [CurrentProfileState] but only returns prefs. + CurrentPrefs() ipn.PrefsView + + // SwitchToBestProfileAsync asynchronously selects the best profile to use + // and switches to it, unless it is already the current profile. + // + // If an extension needs to know when a profile switch occurs, + // it must use [ProfileServices.RegisterProfileStateChangeCallback] + // to register a [ProfileStateChangeCallback]. + // + // The reason indicates why the profile is being switched, such as due + // to a client connecting or disconnecting or a change in the desktop + // session state. It is used for logging. + SwitchToBestProfileAsync(reason string) +} + +// ProfileStore provides read-only access to available login profiles and their preferences. +// It is not safe for concurrent use and can only be used from the callback it is passed to. +type ProfileStore interface { + // CurrentUserID returns the current user ID. It is only non-empty on + // Windows where we have a multi-user system. + // + // Deprecated: this method exists for compatibility with the current (as of 2024-08-27) + // permission model and will be removed as we progress on tailscale/corp#18342. + CurrentUserID() ipn.WindowsUserID + + // CurrentProfile returns a read-only [ipn.LoginProfileView] of the current profile. + // The returned view is always valid, but the profile's [ipn.LoginProfileView.ID] + // returns "" if the profile is new and has not been persisted yet. + CurrentProfile() ipn.LoginProfileView + + // CurrentPrefs returns a read-only view of the current prefs. + // The returned view is always valid. + CurrentPrefs() ipn.PrefsView + + // DefaultUserProfile returns a read-only view of the default (last used) profile for the specified user. + // It returns a read-only view of a new, non-persisted profile if the specified user does not have a default profile. + DefaultUserProfile(uid ipn.WindowsUserID) ipn.LoginProfileView +} + +// AuditLogProvider is a function that returns an [ipnauth.AuditLogFunc] for +// logging auditable actions. +type AuditLogProvider func() ipnauth.AuditLogFunc + +// ProfileResolver is a function that returns a read-only view of a login profile. +// An invalid view indicates no profile. A valid profile view with an empty [ipn.ProfileID] +// indicates that the profile is new and has not been persisted yet. +// The provided [ProfileStore] can only be used for the duration of the callback. +type ProfileResolver func(ProfileStore) ipn.LoginProfileView + +// ProfileStateChangeCallback is a function to be called when the current login profile +// or its preferences change. +// +// The sameNode parameter indicates whether the profile represents the same node as before, +// which is true when: +// - Only the profile's [ipn.Prefs] or metadata (e.g., [tailcfg.UserProfile]) have changed, +// but the node ID and [ipn.ProfileID] remain the same. +// - The profile has been persisted and assigned an [ipn.ProfileID] for the first time, +// so while its node ID and [ipn.ProfileID] have changed, it is still the same profile. +// +// It can be used to decide whether to reset state bound to the current profile or node identity. +// +// The profile and prefs are always valid, but the profile's [ipn.LoginProfileView.ID] +// returns "" if the profile is new and has not been persisted yet. +type ProfileStateChangeCallback func(_ ipn.LoginProfileView, _ ipn.PrefsView, sameNode bool) + +// NewControlClientCallback is a function to be called when a new [controlclient.Client] +// is created and before it is first used. The specified profile represents the node +// for which the cc is created and is always valid. Its [ipn.LoginProfileView.ID] +// returns "" if it is a new node whose profile has never been persisted. +// +// If the [controlclient.Client] is created due to a profile switch, any registered +// [ProfileStateChangeCallback]s are called first. +// +// It returns a function to be called when the cc is being shut down, +// or nil if no cleanup is needed. That cleanup function should not call +// back into LocalBackend, which may be locked during shutdown. +type NewControlClientCallback func(controlclient.Client, ipn.LoginProfileView) (cleanup func()) + +// Hooks is a collection of hooks that extensions can add to (non-concurrently) +// during program initialization and can be called by LocalBackend and others at +// runtime. +// +// Each hook has its own rules about when it's called and what environment it +// has access to and what it's allowed to do. +type Hooks struct { + // BackendStateChange is called when the backend state changes. + BackendStateChange feature.Hooks[func(ipn.State)] + + // ProfileStateChange contains callbacks that are invoked when the current login profile + // or its [ipn.Prefs] change, after those changes have been made. The current login profile + // may be changed either because of a profile switch, or because the profile information + // was updated by [LocalBackend.SetControlClientStatus], including when the profile + // is first populated and persisted. + ProfileStateChange feature.Hooks[ProfileStateChangeCallback] + + // BackgroundProfileResolvers are registered background profile resolvers. + // They're used to determine the profile to use when no GUI/CLI client is connected. + // + // TODO(nickkhyl): allow specifying some kind of priority/altitude for the resolver. + // TODO(nickkhyl): make it a "profile resolver" instead of a "background profile resolver". + // The concepts of the "current user", "foreground profile" and "background profile" + // only exist on Windows, and we're moving away from them anyway. + BackgroundProfileResolvers feature.Hooks[ProfileResolver] + + // AuditLoggers are registered [AuditLogProvider]s. + // Each provider is called to get an [ipnauth.AuditLogFunc] when an auditable action + // is about to be performed. If an audit logger returns an error, the action is denied. + AuditLoggers feature.Hooks[AuditLogProvider] + + // NewControlClient are the functions to be called when a new control client + // is created. It is called with the LocalBackend locked. + NewControlClient feature.Hooks[NewControlClientCallback] + + // OnSelfChange is called (with LocalBackend.mu held) when the self node + // changes, including changing to nothing (an invalid view). + OnSelfChange feature.Hooks[func(tailcfg.NodeView)] + + // MutateNotifyLocked is called to optionally mutate the provided Notify + // before sending it to the IPN bus. It is called with LocalBackend.mu held. + MutateNotifyLocked feature.Hooks[func(*ipn.Notify)] + + // SetPeerStatus is called to mutate PeerStatus. + // Callers must only use NodeBackend to read data. + SetPeerStatus feature.Hooks[func(*ipnstate.PeerStatus, tailcfg.NodeView, NodeBackend)] + + // ShouldUploadServices reports whether this node should include services + // in Hostinfo from the portlist extension. + ShouldUploadServices feature.Hook[func() bool] +} + +// NodeBackend is an interface to query the current node and its peers. +// +// It is not a snapshot in time but is locked to a particular node. +type NodeBackend interface { + // AppendMatchingPeers appends all peers that match the predicate + // to the base slice and returns it. + AppendMatchingPeers(base []tailcfg.NodeView, pred func(tailcfg.NodeView) bool) []tailcfg.NodeView + + // PeerCaps returns the capabilities that src has to this node. + PeerCaps(src netip.Addr) tailcfg.PeerCapMap + + // PeerHasCap reports whether the peer has the specified peer capability. + PeerHasCap(peer tailcfg.NodeView, cap tailcfg.PeerCapability) bool + + // PeerAPIBase returns the "http://ip:port" URL base to reach peer's + // PeerAPI, or the empty string if the peer is invalid or doesn't support + // PeerAPI. + PeerAPIBase(tailcfg.NodeView) string + + // PeerHasPeerAPI whether the provided peer supports PeerAPI. + // + // It effectively just reports whether PeerAPIBase(node) is non-empty, but + // potentially more efficiently. + PeerHasPeerAPI(tailcfg.NodeView) bool + + // CollectServices reports whether the control plane is telling this + // node that the portlist service collection is desirable, should it + // choose to report them. + CollectServices() bool +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/autoupdate.go b/vendor/tailscale.com/ipn/ipnlocal/autoupdate.go deleted file mode 100644 index b7d217a..0000000 --- a/vendor/tailscale.com/ipn/ipnlocal/autoupdate.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux || windows - -package ipnlocal - -import ( - "context" - "time" - - "tailscale.com/clientupdate" - "tailscale.com/ipn" - "tailscale.com/version" -) - -func (b *LocalBackend) stopOfflineAutoUpdate() { - if b.offlineAutoUpdateCancel != nil { - b.logf("offline auto-update: stopping update checks") - b.offlineAutoUpdateCancel() - b.offlineAutoUpdateCancel = nil - } -} - -func (b *LocalBackend) maybeStartOfflineAutoUpdate(prefs ipn.PrefsView) { - if !prefs.AutoUpdate().Apply.EqualBool(true) { - return - } - // AutoUpdate.Apply field in prefs can only be true for platforms that - // support auto-updates. But check it here again, just in case. - if !clientupdate.CanAutoUpdate() { - return - } - // On macsys, auto-updates are managed by Sparkle. - if version.IsMacSysExt() { - return - } - - if b.offlineAutoUpdateCancel != nil { - // Already running. - return - } - ctx, cancel := context.WithCancel(context.Background()) - b.offlineAutoUpdateCancel = cancel - - b.logf("offline auto-update: starting update checks") - go b.offlineAutoUpdate(ctx) -} - -const offlineAutoUpdateCheckPeriod = time.Hour - -func (b *LocalBackend) offlineAutoUpdate(ctx context.Context) { - t := time.NewTicker(offlineAutoUpdateCheckPeriod) - defer t.Stop() - for { - select { - case <-ctx.Done(): - return - case <-t.C: - } - if err := b.startAutoUpdate("offline auto-update"); err != nil { - b.logf("offline auto-update: failed: %v", err) - } - } -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/autoupdate_disabled.go b/vendor/tailscale.com/ipn/ipnlocal/autoupdate_disabled.go deleted file mode 100644 index 88ed68c..0000000 --- a/vendor/tailscale.com/ipn/ipnlocal/autoupdate_disabled.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !(linux || windows) - -package ipnlocal - -import ( - "tailscale.com/ipn" -) - -func (b *LocalBackend) stopOfflineAutoUpdate() { - // Not supported on this platform. -} - -func (b *LocalBackend) maybeStartOfflineAutoUpdate(prefs ipn.PrefsView) { - // Not supported on this platform. -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/bus.go b/vendor/tailscale.com/ipn/ipnlocal/bus.go index 111a877..910e4e7 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/bus.go +++ b/vendor/tailscale.com/ipn/ipnlocal/bus.go @@ -156,5 +156,6 @@ func isNotableNotify(n *ipn.Notify) bool { n.Health != nil || len(n.IncomingFiles) > 0 || len(n.OutgoingFiles) > 0 || - n.FilesWaiting != nil + n.FilesWaiting != nil || + n.SuggestedExitNode != nil } diff --git a/vendor/tailscale.com/ipn/ipnlocal/c2n.go b/vendor/tailscale.com/ipn/ipnlocal/c2n.go index e919215..b5e722b 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/c2n.go +++ b/vendor/tailscale.com/ipn/ipnlocal/c2n.go @@ -4,76 +4,71 @@ package ipnlocal import ( - "crypto/x509" "encoding/json" - "encoding/pem" - "errors" "fmt" "io" "net/http" - "os" - "os/exec" "path" - "path/filepath" + "reflect" "runtime" "strconv" "strings" "time" - "tailscale.com/clientupdate" - "tailscale.com/envknob" + "tailscale.com/control/controlclient" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" + "tailscale.com/health" "tailscale.com/ipn" "tailscale.com/net/sockstats" - "tailscale.com/posture" "tailscale.com/tailcfg" + "tailscale.com/types/netmap" "tailscale.com/util/clientmetric" "tailscale.com/util/goroutines" + "tailscale.com/util/httpm" "tailscale.com/util/set" - "tailscale.com/util/syspolicy" "tailscale.com/version" - "tailscale.com/version/distro" ) // c2nHandlers maps an HTTP method and URI path (without query parameters) to // its handler. The exact method+path match is preferred, but if no entry // exists for that, a map entry with an empty method is used as a fallback. -var c2nHandlers = map[methodAndPath]c2nHandler{ - // Debug. - req("/echo"): handleC2NEcho, - req("/debug/goroutines"): handleC2NDebugGoroutines, - req("/debug/prefs"): handleC2NDebugPrefs, - req("/debug/metrics"): handleC2NDebugMetrics, - req("/debug/component-logging"): handleC2NDebugComponentLogging, - req("/debug/logheap"): handleC2NDebugLogHeap, +var c2nHandlers map[methodAndPath]c2nHandler - // PPROF - We only expose a subset of typical pprof endpoints for security. - req("/debug/pprof/heap"): handleC2NPprof, - req("/debug/pprof/allocs"): handleC2NPprof, +func init() { + c2nHandlers = map[methodAndPath]c2nHandler{} + if buildfeatures.HasC2N { + // Echo is the basic "ping" handler as used by the control plane to probe + // whether a node is reachable. In particular, it's important for + // high-availability subnet routers for the control plane to probe which of + // several candidate nodes is reachable and actually alive. + RegisterC2N("/echo", handleC2NEcho) + } + if buildfeatures.HasSSH { + RegisterC2N("/ssh/usernames", handleC2NSSHUsernames) + } + if buildfeatures.HasLogTail { + RegisterC2N("POST /logtail/flush", handleC2NLogtailFlush) + } + if buildfeatures.HasDebug { + RegisterC2N("POST /sockstats", handleC2NSockStats) - req("POST /logtail/flush"): handleC2NLogtailFlush, - req("POST /sockstats"): handleC2NSockStats, + // pprof: + // we only expose a subset of typical pprof endpoints for security. + RegisterC2N("/debug/pprof/heap", handleC2NPprof) + RegisterC2N("/debug/pprof/allocs", handleC2NPprof) - // Check TLS certificate status. - req("GET /tls-cert-status"): handleC2NTLSCertStatus, - - // SSH - req("/ssh/usernames"): handleC2NSSHUsernames, - - // Auto-updates. - req("GET /update"): handleC2NUpdateGet, - req("POST /update"): handleC2NUpdatePost, - - // Device posture. - req("GET /posture/identity"): handleC2NPostureIdentityGet, - - // App Connectors. - req("GET /appconnector/routes"): handleC2NAppConnectorDomainRoutesGet, - - // Linux netfilter. - req("POST /netfilter-kind"): handleC2NSetNetfilterKind, - - // VIP services. - req("GET /vip-services"): handleC2NVIPServicesGet, + RegisterC2N("/debug/goroutines", handleC2NDebugGoroutines) + RegisterC2N("/debug/prefs", handleC2NDebugPrefs) + RegisterC2N("/debug/metrics", handleC2NDebugMetrics) + RegisterC2N("/debug/component-logging", handleC2NDebugComponentLogging) + RegisterC2N("/debug/logheap", handleC2NDebugLogHeap) + RegisterC2N("/debug/netmap", handleC2NDebugNetMap) + RegisterC2N("/debug/health", handleC2NDebugHealth) + } + if runtime.GOOS == "linux" && buildfeatures.HasOSRouter { + RegisterC2N("POST /netfilter-kind", handleC2NSetNetfilterKind) + } } // RegisterC2N registers a new c2n handler for the given pattern. @@ -81,6 +76,9 @@ var c2nHandlers = map[methodAndPath]c2nHandler{ // A pattern is like "GET /foo" (specific to an HTTP method) or "/foo" (all // methods). It panics if the pattern is already registered. func RegisterC2N(pattern string, h func(*LocalBackend, http.ResponseWriter, *http.Request)) { + if !buildfeatures.HasC2N { + return + } k := req(pattern) if _, ok := c2nHandlers[k]; ok { panic(fmt.Sprintf("c2n: duplicate handler for %q", pattern)) @@ -149,21 +147,108 @@ func handleC2NLogtailFlush(b *LocalBackend, w http.ResponseWriter, r *http.Reque } } +func handleC2NDebugHealth(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + var st *health.State + if buildfeatures.HasDebug && b.health != nil { + st = b.health.CurrentState() + } + writeJSON(w, st) +} + +func handleC2NDebugNetMap(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + ctx := r.Context() + if r.Method != httpm.POST && r.Method != httpm.GET { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + + b.logf("c2n: %s /debug/netmap received", r.Method) + + // redactAndMarshal redacts private keys from the given netmap, clears fields + // that should be omitted, and marshals it to JSON. + redactAndMarshal := func(nm *netmap.NetworkMap, omitFields []string) (json.RawMessage, error) { + for _, f := range omitFields { + field := reflect.ValueOf(nm).Elem().FieldByName(f) + if !field.IsValid() { + b.logf("c2n: /debug/netmap: unknown field %q in omitFields", f) + continue + } + field.SetZero() + } + return json.Marshal(nm) + } + + var omitFields []string + resp := &tailcfg.C2NDebugNetmapResponse{} + + if r.Method == httpm.POST { + var req tailcfg.C2NDebugNetmapRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, fmt.Sprintf("failed to decode request body: %v", err), http.StatusBadRequest) + return + } + omitFields = req.OmitFields + + if req.Candidate != nil { + cand, err := controlclient.NetmapFromMapResponseForDebug(ctx, b.unsanitizedPersist(), req.Candidate) + if err != nil { + http.Error(w, fmt.Sprintf("failed to convert candidate MapResponse: %v", err), http.StatusBadRequest) + return + } + candJSON, err := redactAndMarshal(cand, omitFields) + if err != nil { + http.Error(w, fmt.Sprintf("failed to marshal candidate netmap: %v", err), http.StatusInternalServerError) + return + } + resp.Candidate = candJSON + } + } + + var err error + resp.Current, err = redactAndMarshal(b.currentNode().netMapWithPeers(), omitFields) + if err != nil { + http.Error(w, fmt.Sprintf("failed to marshal current netmap: %v", err), http.StatusInternalServerError) + return + } + + writeJSON(w, resp) +} + func handleC2NDebugGoroutines(_ *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } w.Header().Set("Content-Type", "text/plain") w.Write(goroutines.ScrubbedGoroutineDump(true)) } func handleC2NDebugPrefs(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } writeJSON(w, b.Prefs()) } func handleC2NDebugMetrics(_ *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } w.Header().Set("Content-Type", "text/plain") clientmetric.WritePrometheusExpositionFormat(w) } func handleC2NDebugComponentLogging(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } component := r.FormValue("component") secs, _ := strconv.Atoi(r.FormValue("secs")) if secs == 0 { @@ -206,6 +291,10 @@ func handleC2NPprof(b *LocalBackend, w http.ResponseWriter, r *http.Request) { } func handleC2NSSHUsernames(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasSSH { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } var req tailcfg.C2NSSHUsernamesRequest if r.Method == "POST" { if err := json.NewDecoder(r.Body).Decode(&req); err != nil { @@ -232,26 +321,6 @@ func handleC2NSockStats(b *LocalBackend, w http.ResponseWriter, r *http.Request) fmt.Fprintf(w, "debug info: %v\n", sockstats.DebugInfo()) } -// handleC2NAppConnectorDomainRoutesGet handles returning the domains -// that the app connector is responsible for, as well as the resolved -// IP addresses for each domain. If the node is not configured as -// an app connector, an empty map is returned. -func handleC2NAppConnectorDomainRoutesGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - b.logf("c2n: GET /appconnector/routes received") - - var res tailcfg.C2NAppConnectorDomainRoutesResponse - if b.appConnector == nil { - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) - return - } - - res.Domains = b.appConnector.DomainRoutes() - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) -} - func handleC2NSetNetfilterKind(b *LocalBackend, w http.ResponseWriter, r *http.Request) { b.logf("c2n: POST /netfilter-kind received") @@ -277,285 +346,3 @@ func handleC2NSetNetfilterKind(b *LocalBackend, w http.ResponseWriter, r *http.R w.WriteHeader(http.StatusNoContent) } - -func handleC2NVIPServicesGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - b.logf("c2n: GET /vip-services received") - var res tailcfg.C2NVIPServicesResponse - res.VIPServices = b.VIPServices() - res.ServicesHash = b.vipServiceHash(res.VIPServices) - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) -} - -func handleC2NUpdateGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - b.logf("c2n: GET /update received") - - res := b.newC2NUpdateResponse() - res.Started = b.c2nUpdateStarted() - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) -} - -func handleC2NUpdatePost(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - b.logf("c2n: POST /update received") - res := b.newC2NUpdateResponse() - defer func() { - if res.Err != "" { - b.logf("c2n: POST /update failed: %s", res.Err) - } - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) - }() - - if !res.Enabled { - res.Err = "not enabled" - return - } - if !res.Supported { - res.Err = "not supported" - return - } - - // Do not update if we have active inbound SSH connections. Control can set - // force=true query parameter to override this. - if r.FormValue("force") != "true" && b.sshServer != nil && b.sshServer.NumActiveConns() > 0 { - res.Err = "not updating due to active SSH connections" - return - } - - if err := b.startAutoUpdate("c2n"); err != nil { - res.Err = err.Error() - return - } - res.Started = true -} - -func handleC2NPostureIdentityGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - b.logf("c2n: GET /posture/identity received") - - res := tailcfg.C2NPostureIdentityResponse{} - - // Only collect posture identity if enabled on the client, - // this will first check syspolicy, MDM settings like Registry - // on Windows or defaults on macOS. If they are not set, it falls - // back to the cli-flag, `--posture-checking`. - choice, err := syspolicy.GetPreferenceOption(syspolicy.PostureChecking) - if err != nil { - b.logf( - "c2n: failed to read PostureChecking from syspolicy, returning default from CLI: %s; got error: %s", - b.Prefs().PostureChecking(), - err, - ) - } - - if choice.ShouldEnable(b.Prefs().PostureChecking()) { - res.SerialNumbers, err = posture.GetSerialNumbers(b.logf) - if err != nil { - b.logf("c2n: GetSerialNumbers returned error: %v", err) - } - - // TODO(tailscale/corp#21371, 2024-07-10): once this has landed in a stable release - // and looks good in client metrics, remove this parameter and always report MAC - // addresses. - if r.FormValue("hwaddrs") == "true" { - res.IfaceHardwareAddrs, err = posture.GetHardwareAddrs() - if err != nil { - b.logf("c2n: GetHardwareAddrs returned error: %v", err) - } - } - } else { - res.PostureDisabled = true - } - - b.logf("c2n: posture identity disabled=%v reported %d serials %d hwaddrs", res.PostureDisabled, len(res.SerialNumbers), len(res.IfaceHardwareAddrs)) - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) -} - -func (b *LocalBackend) newC2NUpdateResponse() tailcfg.C2NUpdateResponse { - // If NewUpdater does not return an error, we can update the installation. - // - // Note that we create the Updater solely to check for errors; we do not - // invoke it here. For this purpose, it is ok to pass it a zero Arguments. - prefs := b.Prefs().AutoUpdate() - return tailcfg.C2NUpdateResponse{ - Enabled: envknob.AllowsRemoteUpdate() || prefs.Apply.EqualBool(true), - Supported: clientupdate.CanAutoUpdate() && !version.IsMacSysExt(), - } -} - -func (b *LocalBackend) c2nUpdateStarted() bool { - b.mu.Lock() - defer b.mu.Unlock() - return b.c2nUpdateStatus.started -} - -func (b *LocalBackend) setC2NUpdateStarted(v bool) { - b.mu.Lock() - defer b.mu.Unlock() - b.c2nUpdateStatus.started = v -} - -func (b *LocalBackend) trySetC2NUpdateStarted() bool { - b.mu.Lock() - defer b.mu.Unlock() - if b.c2nUpdateStatus.started { - return false - } - b.c2nUpdateStatus.started = true - return true -} - -// findCmdTailscale looks for the cmd/tailscale that corresponds to the -// currently running cmd/tailscaled. It's up to the caller to verify that the -// two match, but this function does its best to find the right one. Notably, it -// doesn't use $PATH for security reasons. -func findCmdTailscale() (string, error) { - self, err := os.Executable() - if err != nil { - return "", err - } - var ts string - switch runtime.GOOS { - case "linux": - if self == "/usr/sbin/tailscaled" || self == "/usr/bin/tailscaled" { - ts = "/usr/bin/tailscale" - } - if self == "/usr/local/sbin/tailscaled" || self == "/usr/local/bin/tailscaled" { - ts = "/usr/local/bin/tailscale" - } - switch distro.Get() { - case distro.QNAP: - // The volume under /share/ where qpkg are installed is not - // predictable. But the rest of the path is. - ok, err := filepath.Match("/share/*/.qpkg/Tailscale/tailscaled", self) - if err == nil && ok { - ts = filepath.Join(filepath.Dir(self), "tailscale") - } - case distro.Unraid: - if self == "/usr/local/emhttp/plugins/tailscale/bin/tailscaled" { - ts = "/usr/local/emhttp/plugins/tailscale/bin/tailscale" - } - } - case "windows": - ts = filepath.Join(filepath.Dir(self), "tailscale.exe") - case "freebsd": - if self == "/usr/local/bin/tailscaled" { - ts = "/usr/local/bin/tailscale" - } - default: - return "", fmt.Errorf("unsupported OS %v", runtime.GOOS) - } - if ts != "" && regularFileExists(ts) { - return ts, nil - } - return "", errors.New("tailscale executable not found in expected place") -} - -func tailscaleUpdateCmd(cmdTS string) *exec.Cmd { - defaultCmd := exec.Command(cmdTS, "update", "--yes") - if runtime.GOOS != "linux" { - return defaultCmd - } - if _, err := exec.LookPath("systemd-run"); err != nil { - return defaultCmd - } - - // When systemd-run is available, use it to run the update command. This - // creates a new temporary unit separate from the tailscaled unit. When - // tailscaled is restarted during the update, systemd won't kill this - // temporary update unit, which could cause unexpected breakage. - // - // We want to use a few optional flags: - // * --wait, to block the update command until completion (added in systemd 232) - // * --pipe, to collect stdout/stderr (added in systemd 235) - // * --collect, to clean up failed runs from memory (added in systemd 236) - // - // We need to check the version of systemd to figure out if those flags are - // available. - // - // The output will look like: - // - // systemd 255 (255.7-1-arch) - // +PAM +AUDIT ... other feature flags ... - systemdVerOut, err := exec.Command("systemd-run", "--version").Output() - if err != nil { - return defaultCmd - } - parts := strings.Fields(string(systemdVerOut)) - if len(parts) < 2 || parts[0] != "systemd" { - return defaultCmd - } - systemdVer, err := strconv.Atoi(parts[1]) - if err != nil { - return defaultCmd - } - if systemdVer >= 236 { - return exec.Command("systemd-run", "--wait", "--pipe", "--collect", cmdTS, "update", "--yes") - } else if systemdVer >= 235 { - return exec.Command("systemd-run", "--wait", "--pipe", cmdTS, "update", "--yes") - } else if systemdVer >= 232 { - return exec.Command("systemd-run", "--wait", cmdTS, "update", "--yes") - } else { - return exec.Command("systemd-run", cmdTS, "update", "--yes") - } -} - -func regularFileExists(path string) bool { - fi, err := os.Stat(path) - return err == nil && fi.Mode().IsRegular() -} - -// handleC2NTLSCertStatus returns info about the last TLS certificate issued for the -// provided domain. This can be called by the controlplane to clean up DNS TXT -// records when they're no longer needed by LetsEncrypt. -// -// It does not kick off a cert fetch or async refresh. It only reports anything -// that's already sitting on disk, and only reports metadata about the public -// cert (stuff that'd be the in CT logs anyway). -func handleC2NTLSCertStatus(b *LocalBackend, w http.ResponseWriter, r *http.Request) { - cs, err := b.getCertStore() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - domain := r.FormValue("domain") - if domain == "" { - http.Error(w, "no 'domain'", http.StatusBadRequest) - return - } - - ret := &tailcfg.C2NTLSCertInfo{} - pair, err := getCertPEMCached(cs, domain, b.clock.Now()) - ret.Valid = err == nil - if err != nil { - ret.Error = err.Error() - if errors.Is(err, errCertExpired) { - ret.Expired = true - } else if errors.Is(err, ipn.ErrStateNotExist) { - ret.Missing = true - ret.Error = "no certificate" - } - } else { - block, _ := pem.Decode(pair.CertPEM) - if block == nil { - ret.Error = "invalid PEM" - ret.Valid = false - } else { - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - ret.Error = fmt.Sprintf("invalid certificate: %v", err) - ret.Valid = false - } else { - ret.NotBefore = cert.NotBefore.UTC().Format(time.RFC3339) - ret.NotAfter = cert.NotAfter.UTC().Format(time.RFC3339) - } - } - } - - writeJSON(w, ret) -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/c2n_pprof.go b/vendor/tailscale.com/ipn/ipnlocal/c2n_pprof.go index b4bc357..13237cc 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/c2n_pprof.go +++ b/vendor/tailscale.com/ipn/ipnlocal/c2n_pprof.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !js && !wasm +//go:build !js && !wasm && !ts_omit_debug package ipnlocal diff --git a/vendor/tailscale.com/ipn/ipnlocal/captiveportal.go b/vendor/tailscale.com/ipn/ipnlocal/captiveportal.go new file mode 100644 index 0000000..14f8b79 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/captiveportal.go @@ -0,0 +1,186 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_captiveportal + +package ipnlocal + +import ( + "context" + "time" + + "tailscale.com/health" + "tailscale.com/net/captivedetection" + "tailscale.com/util/clientmetric" +) + +func init() { + hookCaptivePortalHealthChange.Set(captivePortalHealthChange) + hookCheckCaptivePortalLoop.Set(checkCaptivePortalLoop) +} + +var metricCaptivePortalDetected = clientmetric.NewCounter("captiveportal_detected") + +// captivePortalDetectionInterval is the duration to wait in an unhealthy state with connectivity broken +// before running captive portal detection. +const captivePortalDetectionInterval = 2 * time.Second + +func captivePortalHealthChange(b *LocalBackend, state *health.State) { + isConnectivityImpacted := false + for _, w := range state.Warnings { + // Ignore the captive portal warnable itself. + if w.ImpactsConnectivity && w.WarnableCode != captivePortalWarnable.Code { + isConnectivityImpacted = true + break + } + } + + // captiveCtx can be changed, and is protected with 'mu'; grab that + // before we start our select, below. + // + // It is guaranteed to be non-nil. + b.mu.Lock() + ctx := b.captiveCtx + b.mu.Unlock() + + // If the context is canceled, we don't need to do anything. + if ctx.Err() != nil { + return + } + + if isConnectivityImpacted { + b.logf("health: connectivity impacted; triggering captive portal detection") + + // Ensure that we select on captiveCtx so that we can time out + // triggering captive portal detection if the backend is shutdown. + select { + case b.needsCaptiveDetection <- true: + case <-ctx.Done(): + } + } else { + // If connectivity is not impacted, we know for sure we're not behind a captive portal, + // so drop any warning, and signal that we don't need captive portal detection. + b.health.SetHealthy(captivePortalWarnable) + select { + case b.needsCaptiveDetection <- false: + case <-ctx.Done(): + } + } +} + +// captivePortalWarnable is a Warnable which is set to an unhealthy state when a captive portal is detected. +var captivePortalWarnable = health.Register(&health.Warnable{ + Code: "captive-portal-detected", + Title: "Captive portal detected", + // High severity, because captive portals block all traffic and require user intervention. + Severity: health.SeverityHigh, + Text: health.StaticMessage("This network requires you to log in using your web browser."), + ImpactsConnectivity: true, +}) + +func checkCaptivePortalLoop(b *LocalBackend, ctx context.Context) { + var tmr *time.Timer + + maybeStartTimer := func() { + // If there's an existing timer, nothing to do; just continue + // waiting for it to expire. Otherwise, create a new timer. + if tmr == nil { + tmr = time.NewTimer(captivePortalDetectionInterval) + } + } + maybeStopTimer := func() { + if tmr == nil { + return + } + if !tmr.Stop() { + <-tmr.C + } + tmr = nil + } + + for { + if ctx.Err() != nil { + maybeStopTimer() + return + } + + // First, see if we have a signal on our "healthy" channel, which + // takes priority over an existing timer. Because a select is + // nondeterministic, we explicitly check this channel before + // entering the main select below, so that we're guaranteed to + // stop the timer before starting captive portal detection. + select { + case needsCaptiveDetection := <-b.needsCaptiveDetection: + if needsCaptiveDetection { + maybeStartTimer() + } else { + maybeStopTimer() + } + default: + } + + var timerChan <-chan time.Time + if tmr != nil { + timerChan = tmr.C + } + select { + case <-ctx.Done(): + // All done; stop the timer and then exit. + maybeStopTimer() + return + case <-timerChan: + // Kick off captive portal check + b.performCaptiveDetection() + // nil out timer to force recreation + tmr = nil + case needsCaptiveDetection := <-b.needsCaptiveDetection: + if needsCaptiveDetection { + maybeStartTimer() + } else { + // Healthy; cancel any existing timer + maybeStopTimer() + } + } + } +} + +// shouldRunCaptivePortalDetection reports whether captive portal detection +// should be run. It is enabled by default, but can be disabled via a control +// knob. It is also only run when the user explicitly wants the backend to be +// running. +func (b *LocalBackend) shouldRunCaptivePortalDetection() bool { + b.mu.Lock() + defer b.mu.Unlock() + return !b.ControlKnobs().DisableCaptivePortalDetection.Load() && b.pm.prefs.WantRunning() +} + +// performCaptiveDetection checks if captive portal detection is enabled via controlknob. If so, it runs +// the detection and updates the Warnable accordingly. +func (b *LocalBackend) performCaptiveDetection() { + if !b.shouldRunCaptivePortalDetection() { + return + } + + d := captivedetection.NewDetector(b.logf) + b.mu.Lock() // for b.hostinfo + cn := b.currentNode() + dm := cn.DERPMap() + preferredDERP := 0 + if b.hostinfo != nil { + if b.hostinfo.NetInfo != nil { + preferredDERP = b.hostinfo.NetInfo.PreferredDERP + } + } + ctx := b.ctx + netMon := b.NetMon() + b.mu.Unlock() + found := d.Detect(ctx, netMon, dm, preferredDERP) + if found { + if !b.health.IsUnhealthy(captivePortalWarnable) { + metricCaptivePortalDetected.Add(1) + } + b.health.SetUnhealthy(captivePortalWarnable, health.Args{}) + } else { + b.health.SetHealthy(captivePortalWarnable) + } +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/cert.go b/vendor/tailscale.com/ipn/ipnlocal/cert.go index 111dc5a..b389c93 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/cert.go +++ b/vendor/tailscale.com/ipn/ipnlocal/cert.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !js +//go:build !js && !ts_omit_acme package ipnlocal @@ -24,22 +24,25 @@ import ( "log" randv2 "math/rand/v2" "net" + "net/http" "os" "path/filepath" "runtime" "slices" "strings" - "sync" "time" "tailscale.com/atomicfile" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/hostinfo" "tailscale.com/ipn" "tailscale.com/ipn/ipnstate" "tailscale.com/ipn/store" "tailscale.com/ipn/store/mem" "tailscale.com/net/bakedroots" + "tailscale.com/syncs" + "tailscale.com/tailcfg" "tailscale.com/tempfork/acme" "tailscale.com/types/logger" "tailscale.com/util/testenv" @@ -47,15 +50,19 @@ import ( "tailscale.com/version/distro" ) +func init() { + RegisterC2N("GET /tls-cert-status", handleC2NTLSCertStatus) +} + // Process-wide cache. (A new *Handler is created per connection, // effectively per request) var ( // acmeMu guards all ACME operations, so concurrent requests // for certs don't slam ACME. The first will go through and // populate the on-disk cache and the rest should use that. - acmeMu sync.Mutex + acmeMu syncs.Mutex - renewMu sync.Mutex // lock order: acmeMu before renewMu + renewMu syncs.Mutex // lock order: acmeMu before renewMu renewCertAt = map[string]time.Time{} ) @@ -67,7 +74,7 @@ func (b *LocalBackend) certDir() (string, error) { // As a workaround for Synology DSM6 not having a "var" directory, use the // app's "etc" directory (on a small partition) to hold certs at least. // See https://github.com/tailscale/tailscale/issues/4060#issuecomment-1186592251 - if d == "" && runtime.GOOS == "linux" && distro.Get() == distro.Synology && distro.DSMVersion() == 6 { + if buildfeatures.HasSynology && d == "" && runtime.GOOS == "linux" && distro.Get() == distro.Synology && distro.DSMVersion() == 6 { d = "/var/packages/Tailscale/etc" // base; we append "certs" below } if d == "" { @@ -100,6 +107,15 @@ func (b *LocalBackend) GetCertPEM(ctx context.Context, domain string) (*TLSCertK // If a cert is expired, or expires sooner than minValidity, it will be renewed // synchronously. Otherwise it will be renewed asynchronously. func (b *LocalBackend) GetCertPEMWithValidity(ctx context.Context, domain string, minValidity time.Duration) (*TLSCertKeyPair, error) { + b.mu.Lock() + getCertForTest := b.getCertForTest + b.mu.Unlock() + + if getCertForTest != nil { + testenv.AssertInTest() + return getCertForTest(domain) + } + if !validLookingCertDomain(domain) { return nil, errors.New("invalid domain") } @@ -137,7 +153,11 @@ func (b *LocalBackend) GetCertPEMWithValidity(ctx context.Context, domain string if minValidity == 0 { logf("starting async renewal") // Start renewal in the background, return current valid cert. - b.goTracker.Go(func() { getCertPEM(context.Background(), b, cs, logf, traceACME, domain, now, minValidity) }) + b.goTracker.Go(func() { + if _, err := getCertPEM(context.Background(), b, cs, logf, traceACME, domain, now, minValidity); err != nil { + logf("async renewal failed: getCertPem: %v", err) + } + }) return pair, nil } // If the caller requested a specific validity duration, fall through @@ -292,6 +312,16 @@ func (b *LocalBackend) getCertStore() (certStore, error) { return certFileStore{dir: dir, testRoots: testX509Roots}, nil } +// ConfigureCertsForTest sets a certificate retrieval function to be used by +// this local backend, skipping the usual ACME certificate registration. Should +// only be used in tests. +func (b *LocalBackend) ConfigureCertsForTest(getCert func(hostname string) (*TLSCertKeyPair, error)) { + testenv.AssertInTest() + b.mu.Lock() + b.getCertForTest = getCert + b.mu.Unlock() +} + // certFileStore implements certStore by storing the cert & key files in the named directory. type certFileStore struct { dir string @@ -484,14 +514,15 @@ var getCertPEM = func(ctx context.Context, b *LocalBackend, cs certStore, logf l // In case this method was triggered multiple times in parallel (when // serving incoming requests), check whether one of the other goroutines // already renewed the cert before us. - if p, err := getCertPEMCached(cs, domain, now); err == nil { + previous, err := getCertPEMCached(cs, domain, now) + if err == nil { // shouldStartDomainRenewal caches its result so it's OK to call this // frequently. - shouldRenew, err := b.shouldStartDomainRenewal(cs, domain, now, p, minValidity) + shouldRenew, err := b.shouldStartDomainRenewal(cs, domain, now, previous, minValidity) if err != nil { logf("error checking for certificate renewal: %v", err) } else if !shouldRenew { - return p, nil + return previous, nil } } else if !errors.Is(err, ipn.ErrStateNotExist) && !errors.Is(err, errCertExpired) { return nil, err @@ -536,7 +567,20 @@ var getCertPEM = func(ctx context.Context, b *LocalBackend, cs certStore, logf l return nil, err } - order, err := ac.AuthorizeOrder(ctx, []acme.AuthzID{{Type: "dns", Value: domain}}) + // If we have a previous cert, include it in the order. Assuming we're + // within the ARI renewal window this should exclude us from LE rate + // limits. + // Note that this order extension will fail renewals if the ACME account key has changed + // since the last issuance, see + // https://github.com/tailscale/tailscale/issues/18251 + var opts []acme.OrderOption + if previous != nil && !envknob.Bool("TS_DEBUG_ACME_FORCE_RENEWAL") { + prevCrt, err := previous.parseCertificate() + if err == nil { + opts = append(opts, acme.WithOrderReplacesCert(prevCrt)) + } + } + order, err := ac.AuthorizeOrder(ctx, []acme.AuthzID{{Type: "dns", Value: domain}}, opts...) if err != nil { return nil, err } @@ -825,3 +869,54 @@ func checkCertDomain(st *ipnstate.Status, domain string) error { } return fmt.Errorf("invalid domain %q; must be one of %q", domain, st.CertDomains) } + +// handleC2NTLSCertStatus returns info about the last TLS certificate issued for the +// provided domain. This can be called by the controlplane to clean up DNS TXT +// records when they're no longer needed by LetsEncrypt. +// +// It does not kick off a cert fetch or async refresh. It only reports anything +// that's already sitting on disk, and only reports metadata about the public +// cert (stuff that'd be the in CT logs anyway). +func handleC2NTLSCertStatus(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + cs, err := b.getCertStore() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + domain := r.FormValue("domain") + if domain == "" { + http.Error(w, "no 'domain'", http.StatusBadRequest) + return + } + + ret := &tailcfg.C2NTLSCertInfo{} + pair, err := getCertPEMCached(cs, domain, b.clock.Now()) + ret.Valid = err == nil + if err != nil { + ret.Error = err.Error() + if errors.Is(err, errCertExpired) { + ret.Expired = true + } else if errors.Is(err, ipn.ErrStateNotExist) { + ret.Missing = true + ret.Error = "no certificate" + } + } else { + block, _ := pem.Decode(pair.CertPEM) + if block == nil { + ret.Error = "invalid PEM" + ret.Valid = false + } else { + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + ret.Error = fmt.Sprintf("invalid certificate: %v", err) + ret.Valid = false + } else { + ret.NotBefore = cert.NotBefore.UTC().Format(time.RFC3339) + ret.NotAfter = cert.NotAfter.UTC().Format(time.RFC3339) + } + } + } + + writeJSON(w, ret) +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/cert_js.go b/vendor/tailscale.com/ipn/ipnlocal/cert_disabled.go similarity index 51% rename from vendor/tailscale.com/ipn/ipnlocal/cert_js.go rename to vendor/tailscale.com/ipn/ipnlocal/cert_disabled.go index 6acc57a..17d446c 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/cert_js.go +++ b/vendor/tailscale.com/ipn/ipnlocal/cert_disabled.go @@ -1,20 +1,30 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build js || ts_omit_acme + package ipnlocal import ( "context" "errors" + "io" + "net/http" "time" ) +func init() { + RegisterC2N("GET /tls-cert-status", handleC2NTLSCertStatusDisabled) +} + +var errNoCerts = errors.New("cert support not compiled in this build") + type TLSCertKeyPair struct { CertPEM, KeyPEM []byte } func (b *LocalBackend) GetCertPEM(ctx context.Context, domain string) (*TLSCertKeyPair, error) { - return nil, errors.New("not implemented for js/wasm") + return nil, errNoCerts } var errCertExpired = errors.New("cert expired") @@ -22,9 +32,14 @@ var errCertExpired = errors.New("cert expired") type certStore interface{} func getCertPEMCached(cs certStore, domain string, now time.Time) (p *TLSCertKeyPair, err error) { - return nil, errors.New("not implemented for js/wasm") + return nil, errNoCerts } func (b *LocalBackend) getCertStore() (certStore, error) { - return nil, errors.New("not implemented for js/wasm") + return nil, errNoCerts +} + +func handleC2NTLSCertStatusDisabled(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, `{"Missing":true}`) // a minimal tailcfg.C2NTLSCertInfo } diff --git a/vendor/tailscale.com/ipn/ipnlocal/desktop_sessions.go b/vendor/tailscale.com/ipn/ipnlocal/desktop_sessions.go deleted file mode 100644 index 23307f6..0000000 --- a/vendor/tailscale.com/ipn/ipnlocal/desktop_sessions.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Both the desktop session manager and multi-user support -// are currently available only on Windows. -// This file does not need to be built for other platforms. - -//go:build windows && !ts_omit_desktop_sessions - -package ipnlocal - -import ( - "cmp" - "errors" - "fmt" - "sync" - - "tailscale.com/feature" - "tailscale.com/ipn" - "tailscale.com/ipn/desktop" - "tailscale.com/tsd" - "tailscale.com/types/logger" - "tailscale.com/util/syspolicy" -) - -func init() { - feature.Register("desktop-sessions") - RegisterExtension("desktop-sessions", newDesktopSessionsExt) -} - -// desktopSessionsExt implements [localBackendExtension]. -var _ localBackendExtension = (*desktopSessionsExt)(nil) - -// desktopSessionsExt extends [LocalBackend] with desktop session management. -// It keeps Tailscale running in the background if Always-On mode is enabled, -// and switches to an appropriate profile when a user signs in or out, -// locks their screen, or disconnects a remote session. -type desktopSessionsExt struct { - logf logger.Logf - sm desktop.SessionManager - - *LocalBackend // or nil, until Init is called - cleanup []func() // cleanup functions to call on shutdown - - // mu protects all following fields. - // When both mu and [LocalBackend.mu] need to be taken, - // [LocalBackend.mu] must be taken before mu. - mu sync.Mutex - id2sess map[desktop.SessionID]*desktop.Session -} - -// newDesktopSessionsExt returns a new [desktopSessionsExt], -// or an error if [desktop.SessionManager] is not available. -func newDesktopSessionsExt(logf logger.Logf, sys *tsd.System) (localBackendExtension, error) { - sm, ok := sys.SessionManager.GetOK() - if !ok { - return nil, errors.New("session manager is not available") - } - return &desktopSessionsExt{logf: logf, sm: sm, id2sess: make(map[desktop.SessionID]*desktop.Session)}, nil -} - -// Init implements [localBackendExtension]. -func (e *desktopSessionsExt) Init(lb *LocalBackend) (err error) { - e.LocalBackend = lb - unregisterResolver := lb.RegisterBackgroundProfileResolver(e.getBackgroundProfile) - unregisterSessionCb, err := e.sm.RegisterStateCallback(e.updateDesktopSessionState) - if err != nil { - unregisterResolver() - return fmt.Errorf("session callback registration failed: %w", err) - } - e.cleanup = []func(){unregisterResolver, unregisterSessionCb} - return nil -} - -// updateDesktopSessionState is a [desktop.SessionStateCallback] -// invoked by [desktop.SessionManager] once for each existing session -// and whenever the session state changes. It updates the session map -// and switches to the best profile if necessary. -func (e *desktopSessionsExt) updateDesktopSessionState(session *desktop.Session) { - e.mu.Lock() - if session.Status != desktop.ClosedSession { - e.id2sess[session.ID] = session - } else { - delete(e.id2sess, session.ID) - } - e.mu.Unlock() - - var action string - switch session.Status { - case desktop.ForegroundSession: - // The user has either signed in or unlocked their session. - // For remote sessions, this may also mean the user has connected. - // The distinction isn't important for our purposes, - // so let's always say "signed in". - action = "signed in to" - case desktop.BackgroundSession: - action = "locked" - case desktop.ClosedSession: - action = "signed out from" - default: - panic("unreachable") - } - maybeUsername, _ := session.User.Username() - userIdentifier := cmp.Or(maybeUsername, string(session.User.UserID()), "user") - reason := fmt.Sprintf("%s %s session %v", userIdentifier, action, session.ID) - - e.SwitchToBestProfile(reason) -} - -// getBackgroundProfile is a [profileResolver] that works as follows: -// -// If Always-On mode is disabled, it returns no profile ("","",false). -// -// If AlwaysOn mode is enabled, it returns the current profile unless: -// - The current user has signed out. -// - Another user has a foreground (i.e. active/unlocked) session. -// -// If the current user's session runs in the background and no other user -// has a foreground session, it returns the current profile. This applies -// when a locally signed-in user locks their screen or when a remote user -// disconnects without signing out. -// -// In all other cases, it returns no profile ("","",false). -// -// It is called with [LocalBackend.mu] locked. -func (e *desktopSessionsExt) getBackgroundProfile() (_ ipn.WindowsUserID, _ ipn.ProfileID, ok bool) { - e.mu.Lock() - defer e.mu.Unlock() - - if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); !alwaysOn { - return "", "", false - } - - isCurrentUserSingedIn := false - var foregroundUIDs []ipn.WindowsUserID - for _, s := range e.id2sess { - switch uid := s.User.UserID(); uid { - case e.pm.CurrentUserID(): - isCurrentUserSingedIn = true - if s.Status == desktop.ForegroundSession { - // Keep the current profile if the user has a foreground session. - return e.pm.CurrentUserID(), e.pm.CurrentProfile().ID(), true - } - default: - if s.Status == desktop.ForegroundSession { - foregroundUIDs = append(foregroundUIDs, uid) - } - } - } - - // If there's no current user (e.g., tailscaled just started), or if the current - // user has no foreground session, switch to the default profile of the first user - // with a foreground session, if any. - for _, uid := range foregroundUIDs { - if profileID := e.pm.DefaultUserProfileID(uid); profileID != "" { - return uid, profileID, true - } - } - - // If no user has a foreground session but the current user is still signed in, - // keep the current profile even if the session is not in the foreground, - // such as when the screen is locked or a remote session is disconnected. - if len(foregroundUIDs) == 0 && isCurrentUserSingedIn { - return e.pm.CurrentUserID(), e.pm.CurrentProfile().ID(), true - } - - return "", "", false -} - -// Shutdown implements [localBackendExtension]. -func (e *desktopSessionsExt) Shutdown() error { - for _, f := range e.cleanup { - f() - } - e.cleanup = nil - e.LocalBackend = nil - return nil -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/drive.go b/vendor/tailscale.com/ipn/ipnlocal/drive.go index 8ae813f..456cd45 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/drive.go +++ b/vendor/tailscale.com/ipn/ipnlocal/drive.go @@ -1,51 +1,35 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_drive + package ipnlocal import ( - "cmp" + "errors" "fmt" + "io" + "net/http" + "net/netip" "os" "slices" "tailscale.com/drive" "tailscale.com/ipn" "tailscale.com/tailcfg" + "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/types/views" + "tailscale.com/util/httpm" ) -const ( - // DriveLocalPort is the port on which the Taildrive listens for location - // connections on quad 100. - DriveLocalPort = 8080 -) - -// DriveSharingEnabled reports whether sharing to remote nodes via Taildrive is -// enabled. This is currently based on checking for the drive:share node -// attribute. -func (b *LocalBackend) DriveSharingEnabled() bool { - b.mu.Lock() - defer b.mu.Unlock() - return b.driveSharingEnabledLocked() +func init() { + hookSetNetMapLockedDrive.Set(setNetMapLockedDrive) } -func (b *LocalBackend) driveSharingEnabledLocked() bool { - return b.netMap != nil && b.netMap.SelfNode.HasCap(tailcfg.NodeAttrsTaildriveShare) -} - -// DriveAccessEnabled reports whether accessing Taildrive shares on remote nodes -// is enabled. This is currently based on checking for the drive:access node -// attribute. -func (b *LocalBackend) DriveAccessEnabled() bool { - b.mu.Lock() - defer b.mu.Unlock() - return b.driveAccessEnabledLocked() -} - -func (b *LocalBackend) driveAccessEnabledLocked() bool { - return b.netMap != nil && b.netMap.SelfNode.HasCap(tailcfg.NodeAttrsTaildriveAccess) +func setNetMapLockedDrive(b *LocalBackend, nm *netmap.NetworkMap) { + b.updateDrivePeersLocked(nm) + b.driveNotifyCurrentSharesLocked() } // DriveSetServerAddr tells Taildrive to use the given address for connecting @@ -266,7 +250,7 @@ func (b *LocalBackend) driveNotifyShares(shares views.SliceView[*drive.Share, dr // shares has changed since the last notification. func (b *LocalBackend) driveNotifyCurrentSharesLocked() { var shares views.SliceView[*drive.Share, drive.ShareView] - if b.driveSharingEnabledLocked() { + if b.DriveSharingEnabled() { // Only populate shares if sharing is enabled. shares = b.pm.prefs.DriveShares() } @@ -310,59 +294,206 @@ func (b *LocalBackend) updateDrivePeersLocked(nm *netmap.NetworkMap) { } var driveRemotes []*drive.Remote - if b.driveAccessEnabledLocked() { + if b.DriveAccessEnabled() { // Only populate peers if access is enabled, otherwise leave blank. driveRemotes = b.driveRemotesFromPeers(nm) } - fs.SetRemotes(b.netMap.Domain, driveRemotes, b.newDriveTransport()) + fs.SetRemotes(nm.Domain, driveRemotes, b.newDriveTransport()) } func (b *LocalBackend) driveRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Remote { + b.logf("[v1] taildrive: setting up drive remotes from peers") driveRemotes := make([]*drive.Remote, 0, len(nm.Peers)) for _, p := range nm.Peers { - peerID := p.ID() - url := fmt.Sprintf("%s/%s", peerAPIBase(nm, p), taildrivePrefix[1:]) + peer := p + peerID := peer.ID() + peerKey := peer.Key().ShortString() + b.logf("[v1] taildrive: appending remote for peer %s", peerKey) driveRemotes = append(driveRemotes, &drive.Remote{ Name: p.DisplayName(false), - URL: url, + URL: func() string { + url := fmt.Sprintf("%s/%s", b.currentNode().PeerAPIBase(peer), taildrivePrefix[1:]) + b.logf("[v2] taildrive: url for peer %s: %s", peerKey, url) + return url + }, Available: func() bool { // Peers are available to Taildrive if: // - They are online + // - Their PeerAPI is reachable // - They are allowed to share at least one folder with us - b.mu.Lock() - latestNetMap := b.netMap - b.mu.Unlock() - - idx, found := slices.BinarySearchFunc(latestNetMap.Peers, peerID, func(candidate tailcfg.NodeView, id tailcfg.NodeID) int { - return cmp.Compare(candidate.ID(), id) - }) - if !found { + cn := b.currentNode() + peer, ok := cn.NodeByID(peerID) + if !ok { + b.logf("[v2] taildrive: Available(): peer %s not found", peerKey) return false } - peer := latestNetMap.Peers[idx] - // Exclude offline peers. // TODO(oxtoacart): for some reason, this correctly // catches when a node goes from offline to online, // but not the other way around... + // TODO(oxtoacart,nickkhyl): the reason was probably + // that we were using netmap.Peers instead of b.peers. + // The netmap.Peers slice is not updated in all cases. + // It should be fixed now that we use PeerByIDOk. if !peer.Online().Get() { + b.logf("[v2] taildrive: Available(): peer %s offline", peerKey) + return false + } + + if b.currentNode().PeerAPIBase(peer) == "" { + b.logf("[v2] taildrive: Available(): peer %s PeerAPI unreachable", peerKey) return false } // Check that the peer is allowed to share with us. - addresses := peer.Addresses() - for _, p := range addresses.All() { - capsMap := b.PeerCaps(p.Addr()) - if capsMap.HasCapability(tailcfg.PeerCapabilityTaildriveSharer) { - return true - } + if cn.PeerHasCap(peer, tailcfg.PeerCapabilityTaildriveSharer) { + b.logf("[v2] taildrive: Available(): peer %s available", peerKey) + return true } + b.logf("[v2] taildrive: Available(): peer %s not allowed to share", peerKey) return false }, }) } return driveRemotes } + +// responseBodyWrapper wraps an io.ReadCloser and stores +// the number of bytesRead. +type responseBodyWrapper struct { + io.ReadCloser + logVerbose bool + bytesRx int64 + bytesTx int64 + log logger.Logf + method string + statusCode int + contentType string + fileExtension string + shareNodeKey string + selfNodeKey string + contentLength int64 +} + +// logAccess logs the taildrive: access: log line. If the logger is nil, +// the log will not be written. +func (rbw *responseBodyWrapper) logAccess(err string) { + if rbw.log == nil { + return + } + + // Some operating systems create and copy lots of 0 length hidden files for + // tracking various states. Omit these to keep logs from being too verbose. + if rbw.logVerbose || rbw.contentLength > 0 { + levelPrefix := "" + if rbw.logVerbose { + levelPrefix = "[v1] " + } + rbw.log( + "%staildrive: access: %s from %s to %s: status-code=%d ext=%q content-type=%q content-length=%.f tx=%.f rx=%.f err=%q", + levelPrefix, + rbw.method, + rbw.selfNodeKey, + rbw.shareNodeKey, + rbw.statusCode, + rbw.fileExtension, + rbw.contentType, + roundTraffic(rbw.contentLength), + roundTraffic(rbw.bytesTx), roundTraffic(rbw.bytesRx), err) + } +} + +// Read implements the io.Reader interface. +func (rbw *responseBodyWrapper) Read(b []byte) (int, error) { + n, err := rbw.ReadCloser.Read(b) + rbw.bytesRx += int64(n) + if err != nil && !errors.Is(err, io.EOF) { + rbw.logAccess(err.Error()) + } + + return n, err +} + +// Close implements the io.Close interface. +func (rbw *responseBodyWrapper) Close() error { + err := rbw.ReadCloser.Close() + var errStr string + if err != nil { + errStr = err.Error() + } + rbw.logAccess(errStr) + + return err +} + +// driveTransport is an http.RoundTripper that wraps +// b.Dialer().PeerAPITransport() with metrics tracking. +type driveTransport struct { + b *LocalBackend + tr http.RoundTripper +} + +func (b *LocalBackend) newDriveTransport() *driveTransport { + return &driveTransport{ + b: b, + tr: b.Dialer().PeerAPITransport(), + } +} + +func (dt *driveTransport) RoundTrip(req *http.Request) (*http.Response, error) { + // Some WebDAV clients include origin and refer headers, which peerapi does + // not like. Remove them. + req.Header.Del("origin") + req.Header.Del("referer") + + bw := &requestBodyWrapper{} + if req.Body != nil { + bw.ReadCloser = req.Body + req.Body = bw + } + + resp, err := dt.tr.RoundTrip(req) + if err != nil { + return nil, err + } + + contentType := "unknown" + if ct := req.Header.Get("Content-Type"); ct != "" { + contentType = ct + } + + dt.b.mu.Lock() + selfNodeKey := dt.b.currentNode().Self().Key().ShortString() + dt.b.mu.Unlock() + n, _, ok := dt.b.WhoIs("tcp", netip.MustParseAddrPort(req.URL.Host)) + shareNodeKey := "unknown" + if ok { + shareNodeKey = string(n.Key().ShortString()) + } + + rbw := responseBodyWrapper{ + log: dt.b.logf, + logVerbose: req.Method != httpm.GET && req.Method != httpm.PUT, // other requests like PROPFIND are quite chatty, so we log those at verbose level + method: req.Method, + bytesTx: int64(bw.bytesRead), + selfNodeKey: selfNodeKey, + shareNodeKey: shareNodeKey, + contentType: contentType, + contentLength: resp.ContentLength, + fileExtension: parseDriveFileExtensionForLog(req.URL.Path), + statusCode: resp.StatusCode, + ReadCloser: resp.Body, + } + + if resp.StatusCode >= 400 { + // in case of error response, just log immediately + rbw.logAccess("") + } else { + resp.Body = &rbw + } + + return resp, nil +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/drive_tomove.go b/vendor/tailscale.com/ipn/ipnlocal/drive_tomove.go new file mode 100644 index 0000000..290fe09 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/drive_tomove.go @@ -0,0 +1,30 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// This is the Taildrive stuff that should ideally be registered in init only when +// the ts_omit_drive is not set, but for transition reasons is currently (2025-09-08) +// always defined, as we work to pull it out of LocalBackend. + +package ipnlocal + +import "tailscale.com/tailcfg" + +const ( + // DriveLocalPort is the port on which the Taildrive listens for location + // connections on quad 100. + DriveLocalPort = 8080 +) + +// DriveSharingEnabled reports whether sharing to remote nodes via Taildrive is +// enabled. This is currently based on checking for the drive:share node +// attribute. +func (b *LocalBackend) DriveSharingEnabled() bool { + return b.currentNode().SelfHasCap(tailcfg.NodeAttrsTaildriveShare) +} + +// DriveAccessEnabled reports whether accessing Taildrive shares on remote nodes +// is enabled. This is currently based on checking for the drive:access node +// attribute. +func (b *LocalBackend) DriveAccessEnabled() bool { + return b.currentNode().SelfHasCap(tailcfg.NodeAttrsTaildriveAccess) +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/expiry.go b/vendor/tailscale.com/ipn/ipnlocal/expiry.go index d111998..8ea63d2 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/expiry.go +++ b/vendor/tailscale.com/ipn/ipnlocal/expiry.go @@ -6,12 +6,14 @@ package ipnlocal import ( "time" + "tailscale.com/control/controlclient" "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tstime" "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/netmap" + "tailscale.com/util/eventbus" ) // For extra defense-in-depth, when we're testing expired nodes we check @@ -40,14 +42,22 @@ type expiryManager struct { logf logger.Logf clock tstime.Clock + + eventClient *eventbus.Client } -func newExpiryManager(logf logger.Logf) *expiryManager { - return &expiryManager{ +func newExpiryManager(logf logger.Logf, bus *eventbus.Bus) *expiryManager { + em := &expiryManager{ previouslyExpired: map[tailcfg.StableNodeID]bool{}, logf: logf, clock: tstime.StdClock{}, } + + em.eventClient = bus.Client("ipnlocal.expiryManager") + eventbus.SubscribeFunc(em.eventClient, func(ct controlclient.ControlTime) { + em.onControlTime(ct.Value) + }) + return em } // onControlTime is called whenever we receive a new timestamp from the control @@ -218,6 +228,8 @@ func (em *expiryManager) nextPeerExpiry(nm *netmap.NetworkMap, localNow time.Tim return nextExpiry } +func (em *expiryManager) close() { em.eventClient.Close() } + // ControlNow estimates the current time on the control server, calculated as // localNow + the delta between local and control server clocks as recorded // when the LocalBackend last received a time message from the control server. diff --git a/vendor/tailscale.com/ipn/ipnlocal/extension_host.go b/vendor/tailscale.com/ipn/ipnlocal/extension_host.go new file mode 100644 index 0000000..ca802ab --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/extension_host.go @@ -0,0 +1,621 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package ipnlocal + +import ( + "context" + "errors" + "fmt" + "maps" + "reflect" + "slices" + "strings" + "sync" + "sync/atomic" + "time" + + "tailscale.com/control/controlclient" + "tailscale.com/ipn" + "tailscale.com/ipn/ipnauth" + "tailscale.com/ipn/ipnext" + "tailscale.com/tailcfg" + "tailscale.com/types/logger" + "tailscale.com/util/execqueue" + "tailscale.com/util/mak" + "tailscale.com/util/testenv" +) + +// ExtensionHost is a bridge between the [LocalBackend] and the registered [ipnext.Extension]s. +// It implements [ipnext.Host] and is safe for concurrent use. +// +// A nil pointer to [ExtensionHost] is a valid, no-op extension host which is primarily used in tests +// that instantiate [LocalBackend] directly without using [NewExtensionHost]. +// +// The [LocalBackend] is not required to hold its mutex when calling the host's methods, +// but it typically does so either to prevent changes to its state (for example, the current profile) +// while callbacks are executing, or because it calls the host's methods as part of a larger operation +// that requires the mutex to be held. +// +// Extensions might invoke the host's methods either from callbacks triggered by the [LocalBackend], +// or in a response to external events. Some methods can be called by both the extensions and the backend. +// +// As a general rule, the host cannot assume anything about the current state of the [LocalBackend]'s +// internal mutex on entry to its methods, and therefore cannot safely call [LocalBackend] methods directly. +// +// The following are typical and supported patterns: +// - LocalBackend notifies the host about an event, such as a change in the current profile. +// The host invokes callbacks registered by Extensions, forwarding the event arguments to them. +// If necessary, the host can also update its own state for future use. +// - LocalBackend requests information from the host, such as the effective [ipnauth.AuditLogFunc] +// or the [ipn.LoginProfile] to use when no GUI/CLI client is connected. Typically, [LocalBackend] +// provides the required context to the host, and the host returns the result to [LocalBackend] +// after forwarding the request to the extensions. +// - Extension invokes the host's method to perform an action, such as switching to the "best" profile +// in response to a change in the device's state. Since the host does not know whether the [LocalBackend]'s +// internal mutex is held, it cannot invoke any methods on the [LocalBackend] directly and must instead +// do so asynchronously, such as by using [ExtensionHost.enqueueBackendOperation]. +// - Extension requests information from the host, such as the effective [ipnauth.AuditLogFunc] +// or the current [ipn.LoginProfile]. Since the host cannot invoke any methods on the [LocalBackend] directly, +// it should maintain its own view of the current state, updating it when the [LocalBackend] notifies it +// about a change or event. +// +// To safeguard against adopting incorrect or risky patterns, the host does not store [LocalBackend] in its fields +// and instead provides [ExtensionHost.enqueueBackendOperation]. Additionally, to make it easier to test extensions +// and to further reduce the risk of accessing unexported methods or fields of [LocalBackend], the host interacts +// with it via the [Backend] interface. +type ExtensionHost struct { + b Backend + hooks ipnext.Hooks + logf logger.Logf // prefixed with "ipnext:" + + // allExtensions holds the extensions in the order they were registered, + // including those that have not yet attempted initialization or have failed to initialize. + allExtensions []ipnext.Extension + + // initOnce is used to ensure that the extensions are initialized only once, + // even if [extensionHost.Init] is called multiple times. + initOnce sync.Once + initDone atomic.Bool + // shutdownOnce is like initOnce, but for [ExtensionHost.Shutdown]. + shutdownOnce sync.Once + + // workQueue maintains execution order for asynchronous operations requested by extensions. + // It is always an [execqueue.ExecQueue] except in some tests. + workQueue execQueue + // doEnqueueBackendOperation adds an asynchronous [LocalBackend] operation to the workQueue. + doEnqueueBackendOperation func(func(Backend)) + + shuttingDown atomic.Bool + + extByType sync.Map // reflect.Type -> ipnext.Extension + + // mu protects the following fields. + // It must not be held when calling [LocalBackend] methods + // or when invoking callbacks registered by extensions. + mu sync.Mutex + // initialized is whether the host and extensions have been fully initialized. + initialized atomic.Bool + // activeExtensions is a subset of allExtensions that have been initialized and are ready to use. + activeExtensions []ipnext.Extension + // extensionsByName are the extensions indexed by their names. + // They are not necessarily initialized (in activeExtensions) yet. + extensionsByName map[string]ipnext.Extension + // postInitWorkQueue is a queue of functions to be executed + // by the workQueue after all extensions have been initialized. + postInitWorkQueue []func(Backend) + + // currentProfile is a read-only view of the currently used profile. + // The view is always Valid, but might be of an empty, non-persisted profile. + currentProfile ipn.LoginProfileView + // currentPrefs is a read-only view of the current profile's [ipn.Prefs] + // with any private keys stripped. It is always Valid. + currentPrefs ipn.PrefsView +} + +// Backend is a subset of [LocalBackend] methods that are used by [ExtensionHost]. +// It is primarily used for testing. +type Backend interface { + // SwitchToBestProfile switches to the best profile for the current state of the system. + // The reason indicates why the profile is being switched. + SwitchToBestProfile(reason string) + + SendNotify(ipn.Notify) + + NodeBackend() ipnext.NodeBackend + + ipnext.SafeBackend +} + +// NewExtensionHost returns a new [ExtensionHost] which manages registered extensions for the given backend. +// The extensions are instantiated, but are not initialized until [ExtensionHost.Init] is called. +// It returns an error if instantiating any extension fails. +func NewExtensionHost(logf logger.Logf, b Backend) (*ExtensionHost, error) { + return newExtensionHost(logf, b) +} + +func NewExtensionHostForTest(logf logger.Logf, b Backend, overrideExts ...*ipnext.Definition) (*ExtensionHost, error) { + if !testenv.InTest() { + panic("use outside of test") + } + return newExtensionHost(logf, b, overrideExts...) +} + +// newExtensionHost is the shared implementation of [NewExtensionHost] and +// [NewExtensionHostForTest]. +// +// If overrideExts is non-nil, the registered extensions are ignored and the +// provided extensions are used instead. Overriding extensions is primarily used +// for testing. +func newExtensionHost(logf logger.Logf, b Backend, overrideExts ...*ipnext.Definition) (_ *ExtensionHost, err error) { + host := &ExtensionHost{ + b: b, + logf: logger.WithPrefix(logf, "ipnext: "), + workQueue: &execqueue.ExecQueue{}, + // The host starts with an empty profile and default prefs. + // We'll update them once [profileManager] notifies us of the initial profile. + currentProfile: zeroProfile, + currentPrefs: defaultPrefs, + } + + // All operations on the backend must be executed asynchronously by the work queue. + // DO NOT retain a direct reference to the backend in the host. + // See the docstring for [ExtensionHost] for more details. + host.doEnqueueBackendOperation = func(f func(Backend)) { + if f == nil { + panic("nil backend operation") + } + host.workQueue.Add(func() { f(b) }) + } + + // Use registered extensions. + extDef := ipnext.Extensions() + if overrideExts != nil { + // Use the provided, potentially empty, overrideExts + // instead of the registered ones. + extDef = slices.Values(overrideExts) + } + + for d := range extDef { + ext, err := d.MakeExtension(logf, b) + if errors.Is(err, ipnext.SkipExtension) { + // The extension wants to be skipped. + host.logf("%q: %v", d.Name(), err) + continue + } else if err != nil { + return nil, fmt.Errorf("failed to create %q extension: %v", d.Name(), err) + } + host.allExtensions = append(host.allExtensions, ext) + + if d.Name() != ext.Name() { + return nil, fmt.Errorf("extension name %q does not match the registered name %q", ext.Name(), d.Name()) + } + + if _, ok := host.extensionsByName[ext.Name()]; ok { + return nil, fmt.Errorf("duplicate extension name %q", ext.Name()) + } else { + mak.Set(&host.extensionsByName, ext.Name(), ext) + } + + typ := reflect.TypeOf(ext) + if _, ok := host.extByType.Load(typ); ok { + if _, ok := ext.(interface{ PermitDoubleRegister() }); !ok { + return nil, fmt.Errorf("duplicate extension type %T", ext) + } + } + host.extByType.Store(typ, ext) + } + return host, nil +} + +func (h *ExtensionHost) NodeBackend() ipnext.NodeBackend { + if h == nil { + return nil + } + return h.b.NodeBackend() +} + +// Init initializes the host and the extensions it manages. +func (h *ExtensionHost) Init() { + if h != nil { + h.initOnce.Do(h.init) + } +} + +var zeroHooks ipnext.Hooks + +func (h *ExtensionHost) Hooks() *ipnext.Hooks { + if h == nil { + return &zeroHooks + } + return &h.hooks +} + +func (h *ExtensionHost) init() { + defer h.initDone.Store(true) + + // Initialize the extensions in the order they were registered. + for _, ext := range h.allExtensions { + // Do not hold the lock while calling [ipnext.Extension.Init]. + // Extensions call back into the host to register their callbacks, + // and that would cause a deadlock if the h.mu is already held. + if err := ext.Init(h); err != nil { + // As per the [ipnext.Extension] interface, failures to initialize + // an extension are never fatal. The extension is simply skipped. + // + // But we handle [ipnext.SkipExtension] differently for nicer logging + // if the extension wants to be skipped and not actually failing. + if errors.Is(err, ipnext.SkipExtension) { + h.logf("%q: %v", ext.Name(), err) + } else { + h.logf("%q init failed: %v", ext.Name(), err) + } + continue + } + // Update the initialized extensions lists as soon as the extension is initialized. + // We'd like to make them visible to other extensions that are initialized later. + h.mu.Lock() + h.activeExtensions = append(h.activeExtensions, ext) + h.mu.Unlock() + } + + // Report active extensions to the log. + // TODO(nickkhyl): update client metrics to include the active/failed/skipped extensions. + h.mu.Lock() + extensionNames := slices.Collect(maps.Keys(h.extensionsByName)) + h.mu.Unlock() + h.logf("active extensions: %v", strings.Join(extensionNames, ", ")) + + // Additional init steps that need to be performed after all extensions have been initialized. + h.mu.Lock() + wq := h.postInitWorkQueue + h.postInitWorkQueue = nil + h.initialized.Store(true) + h.mu.Unlock() + + // Enqueue work that was requested and deferred during initialization. + h.doEnqueueBackendOperation(func(b Backend) { + for _, f := range wq { + f(b) + } + }) +} + +// Extensions implements [ipnext.Host]. +func (h *ExtensionHost) Extensions() ipnext.ExtensionServices { + // Currently, [ExtensionHost] implements [ExtensionServices] directly. + // We might want to extract it to a separate type in the future. + return h +} + +// FindExtensionByName implements [ipnext.ExtensionServices] +// and is also used by the [LocalBackend]. +// It returns nil if the extension is not found. +func (h *ExtensionHost) FindExtensionByName(name string) any { + if h == nil { + return nil + } + h.mu.Lock() + defer h.mu.Unlock() + return h.extensionsByName[name] +} + +// extensionIfaceType is the runtime type of the [ipnext.Extension] interface. +var extensionIfaceType = reflect.TypeFor[ipnext.Extension]() + +// GetExt returns the extension of type T registered with lb. +// If lb is nil or the extension is not found, it returns zero, false. +func GetExt[T ipnext.Extension](lb *LocalBackend) (_ T, ok bool) { + var zero T + if lb == nil { + return zero, false + } + if ext, ok := lb.extHost.extensionOfType(reflect.TypeFor[T]()); ok { + return ext.(T), true + } + return zero, false +} + +func (h *ExtensionHost) extensionOfType(t reflect.Type) (_ ipnext.Extension, ok bool) { + if h == nil { + return nil, false + } + if v, ok := h.extByType.Load(t); ok { + return v.(ipnext.Extension), true + } + return nil, false +} + +// FindMatchingExtension implements [ipnext.ExtensionServices] +// and is also used by the [LocalBackend]. +func (h *ExtensionHost) FindMatchingExtension(target any) bool { + if h == nil { + return false + } + + if target == nil { + panic("ipnext: target cannot be nil") + } + + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + panic("ipnext: target must be a non-nil pointer") + } + targetType := typ.Elem() + if targetType.Kind() != reflect.Interface && !targetType.Implements(extensionIfaceType) { + panic("ipnext: *target must be interface or implement ipnext.Extension") + } + + h.mu.Lock() + defer h.mu.Unlock() + for _, ext := range h.activeExtensions { + if reflect.TypeOf(ext).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(ext)) + return true + } + } + return false +} + +// Profiles implements [ipnext.Host]. +func (h *ExtensionHost) Profiles() ipnext.ProfileServices { + // Currently, [ExtensionHost] implements [ipnext.ProfileServices] directly. + // We might want to extract it to a separate type in the future. + return h +} + +// CurrentProfileState implements [ipnext.ProfileServices]. +func (h *ExtensionHost) CurrentProfileState() (ipn.LoginProfileView, ipn.PrefsView) { + if h == nil { + return zeroProfile, defaultPrefs + } + h.mu.Lock() + defer h.mu.Unlock() + return h.currentProfile, h.currentPrefs +} + +// CurrentPrefs implements [ipnext.ProfileServices]. +func (h *ExtensionHost) CurrentPrefs() ipn.PrefsView { + _, prefs := h.CurrentProfileState() + return prefs +} + +// SwitchToBestProfileAsync implements [ipnext.ProfileServices]. +func (h *ExtensionHost) SwitchToBestProfileAsync(reason string) { + if h == nil { + return + } + h.enqueueBackendOperation(func(b Backend) { + b.SwitchToBestProfile(reason) + }) +} + +// SendNotifyAsync implements [ipnext.Host]. +func (h *ExtensionHost) SendNotifyAsync(n ipn.Notify) { + if h == nil { + return + } + h.enqueueBackendOperation(func(b Backend) { + b.SendNotify(n) + }) +} + +// NotifyProfileChange invokes registered profile state change callbacks +// and updates the current profile and prefs in the host. +// It strips private keys from the [ipn.Prefs] before preserving +// or passing them to the callbacks. +func (h *ExtensionHost) NotifyProfileChange(profile ipn.LoginProfileView, prefs ipn.PrefsView, sameNode bool) { + if !h.active() { + return + } + h.mu.Lock() + // Strip private keys from the prefs before preserving or passing them to the callbacks. + // Extensions should not need them (unless proven otherwise in the future), + // and this is a good way to ensure that they won't accidentally leak them. + prefs = stripKeysFromPrefs(prefs) + // Update the current profile and prefs in the host, + // so we can provide them to the extensions later if they ask. + h.currentPrefs = prefs + h.currentProfile = profile + h.mu.Unlock() + + for _, cb := range h.hooks.ProfileStateChange { + cb(profile, prefs, sameNode) + } +} + +// NotifyProfilePrefsChanged invokes registered profile state change callbacks, +// and updates the current profile and prefs in the host. +// It strips private keys from the [ipn.Prefs] before preserving or using them. +func (h *ExtensionHost) NotifyProfilePrefsChanged(profile ipn.LoginProfileView, oldPrefs, newPrefs ipn.PrefsView) { + if !h.active() { + return + } + h.mu.Lock() + // Strip private keys from the prefs before preserving or passing them to the callbacks. + // Extensions should not need them (unless proven otherwise in the future), + // and this is a good way to ensure that they won't accidentally leak them. + newPrefs = stripKeysFromPrefs(newPrefs) + // Update the current profile and prefs in the host, + // so we can provide them to the extensions later if they ask. + h.currentPrefs = newPrefs + h.currentProfile = profile + // Get the callbacks to be invoked. + h.mu.Unlock() + + for _, cb := range h.hooks.ProfileStateChange { + cb(profile, newPrefs, true) + } +} + +func (h *ExtensionHost) active() bool { + return h != nil && !h.shuttingDown.Load() +} + +// DetermineBackgroundProfile returns a read-only view of the profile +// used when no GUI/CLI client is connected, using background profile +// resolvers registered by extensions. +// +// It returns an invalid view if Tailscale should not run in the background +// and instead disconnect until a GUI/CLI client connects. +// +// As of 2025-02-07, this is only used on Windows. +func (h *ExtensionHost) DetermineBackgroundProfile(profiles ipnext.ProfileStore) ipn.LoginProfileView { + if !h.active() { + return ipn.LoginProfileView{} + } + // TODO(nickkhyl): check if the returned profile is allowed on the device, + // such as when [syspolicy.Tailnet] policy setting requires a specific Tailnet. + // See tailscale/corp#26249. + + // Attempt to resolve the background profile using the registered + // background profile resolvers (e.g., [ipn/desktop.desktopSessionsExt] on Windows). + for _, resolver := range h.hooks.BackgroundProfileResolvers { + if profile := resolver(profiles); profile.Valid() { + return profile + } + } + + // Otherwise, switch to an empty profile and disconnect Tailscale + // until a GUI or CLI client connects. + return ipn.LoginProfileView{} +} + +// NotifyNewControlClient invokes all registered control client callbacks. +// It returns callbacks to be executed when the control client shuts down. +func (h *ExtensionHost) NotifyNewControlClient(cc controlclient.Client, profile ipn.LoginProfileView) (ccShutdownCbs []func()) { + if !h.active() { + return nil + } + for _, cb := range h.hooks.NewControlClient { + if shutdown := cb(cc, profile); shutdown != nil { + ccShutdownCbs = append(ccShutdownCbs, shutdown) + } + } + return ccShutdownCbs +} + +// AuditLogger returns a function that reports an auditable action +// to all registered audit loggers. It fails if any of them returns an error, +// indicating that the action cannot be logged and must not be performed. +// +// It implements [ipnext.Host], but is also used by the [LocalBackend]. +// +// The returned function closes over the current state of the host and extensions, +// which typically includes the current profile and the audit loggers registered by extensions. +// It must not be persisted outside of the auditable action context. +func (h *ExtensionHost) AuditLogger() ipnauth.AuditLogFunc { + if !h.active() { + return func(tailcfg.ClientAuditAction, string) error { return nil } + } + loggers := make([]ipnauth.AuditLogFunc, 0, len(h.hooks.AuditLoggers)) + for _, provider := range h.hooks.AuditLoggers { + loggers = append(loggers, provider()) + } + return func(action tailcfg.ClientAuditAction, details string) error { + // Log auditable actions to the host's log regardless of whether + // the audit loggers are available or not. + h.logf("auditlog: %v: %v", action, details) + + // Invoke all registered audit loggers and collect errors. + // If any of them returns an error, the action is denied. + var errs []error + for _, logger := range loggers { + if err := logger(action, details); err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) + } +} + +// Shutdown shuts down the extension host and all initialized extensions. +func (h *ExtensionHost) Shutdown() { + if h == nil { + return + } + // Ensure that the init function has completed before shutting down, + // or prevent any further init calls from happening. + h.initOnce.Do(func() {}) + h.shutdownOnce.Do(h.shutdown) +} + +func (h *ExtensionHost) shutdown() { + h.shuttingDown.Store(true) + // Prevent any queued but not yet started operations from running, + // block new operations from being enqueued, and wait for the + // currently executing operation (if any) to finish. + h.shutdownWorkQueue() + // Invoke shutdown callbacks registered by extensions. + h.shutdownExtensions() +} + +func (h *ExtensionHost) shutdownWorkQueue() { + h.workQueue.Shutdown() + var ctx context.Context + if testenv.InTest() { + // In tests, we'd like to wait indefinitely for the current operation to finish, + // mostly to help avoid flaky tests. Test runners can be pretty slow. + ctx = context.Background() + } else { + // In prod, however, we want to avoid blocking indefinitely. + // The 5s timeout is somewhat arbitrary; LocalBackend operations + // should not take that long. + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + } + // Since callbacks are invoked synchronously, this will also wait + // for in-flight callbacks associated with those operations to finish. + if err := h.workQueue.Wait(ctx); err != nil { + h.logf("work queue shutdown failed: %v", err) + } +} + +func (h *ExtensionHost) shutdownExtensions() { + h.mu.Lock() + extensions := h.activeExtensions + h.mu.Unlock() + + // h.mu must not be held while shutting down extensions. + // Extensions might call back into the host and that would cause + // a deadlock if the h.mu is already held. + // + // Shutdown is called in the reverse order of Init. + for _, ext := range slices.Backward(extensions) { + if err := ext.Shutdown(); err != nil { + // Extension shutdown errors are never fatal, but we log them for debugging purposes. + h.logf("%q: shutdown callback failed: %v", ext.Name(), err) + } + } +} + +// enqueueBackendOperation enqueues a function to perform an operation on the [Backend]. +// If the host has not yet been initialized (e.g., when called from an extension's Init method), +// the operation is deferred until after the host and all extensions have completed initialization. +// It panics if the f is nil. +func (h *ExtensionHost) enqueueBackendOperation(f func(Backend)) { + if h == nil { + return + } + if f == nil { + panic("nil backend operation") + } + h.mu.Lock() // protects h.initialized and h.postInitWorkQueue + defer h.mu.Unlock() + if h.initialized.Load() { + h.doEnqueueBackendOperation(f) + } else { + h.postInitWorkQueue = append(h.postInitWorkQueue, f) + } +} + +// execQueue is an ordered asynchronous queue for executing functions. +// It is implemented by [execqueue.ExecQueue]. The interface is used +// to allow testing with a mock implementation. +type execQueue interface { + Add(func()) + Shutdown() + Wait(context.Context) error +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/hwattest.go b/vendor/tailscale.com/ipn/ipnlocal/hwattest.go new file mode 100644 index 0000000..2c93cad --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/hwattest.go @@ -0,0 +1,48 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_tpm + +package ipnlocal + +import ( + "errors" + + "tailscale.com/feature" + "tailscale.com/types/key" + "tailscale.com/types/logger" + "tailscale.com/types/persist" +) + +func init() { + feature.HookGenerateAttestationKeyIfEmpty.Set(generateAttestationKeyIfEmpty) +} + +// generateAttestationKeyIfEmpty generates a new hardware attestation key if +// none exists. It returns true if a new key was generated and stored in +// p.AttestationKey. +func generateAttestationKeyIfEmpty(p *persist.Persist, logf logger.Logf) (bool, error) { + // attempt to generate a new hardware attestation key if none exists + var ak key.HardwareAttestationKey + if p != nil { + ak = p.AttestationKey + } + + if ak == nil || ak.IsZero() { + var err error + ak, err = key.NewHardwareAttestationKey() + if err != nil { + if !errors.Is(err, key.ErrUnsupported) { + logf("failed to create hardware attestation key: %v", err) + } + } else if ak != nil { + logf("using new hardware attestation key: %v", ak.Public()) + if p == nil { + p = &persist.Persist{} + } + p.AttestationKey = ak + return true, nil + } + } + return false, nil +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/local.go b/vendor/tailscale.com/ipn/ipnlocal/local.go index 11da8c7..2f05a4d 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/local.go +++ b/vendor/tailscale.com/ipn/ipnlocal/local.go @@ -6,18 +6,14 @@ package ipnlocal import ( - "bytes" "cmp" "context" "crypto/sha256" - "encoding/base64" - "encoding/hex" + "encoding/binary" "encoding/json" "errors" "fmt" "io" - "log" - "maps" "math" "math/rand/v2" "net" @@ -25,12 +21,9 @@ import ( "net/netip" "net/url" "os" - "os/exec" - "path/filepath" "reflect" "runtime" "slices" - "sort" "strconv" "strings" "sync" @@ -40,32 +33,25 @@ import ( "go4.org/mem" "go4.org/netipx" "golang.org/x/net/dns/dnsmessage" - "gvisor.dev/gvisor/pkg/tcpip" "tailscale.com/appc" "tailscale.com/client/tailscale/apitype" - "tailscale.com/clientupdate" "tailscale.com/control/controlclient" "tailscale.com/control/controlknobs" - "tailscale.com/doctor" - "tailscale.com/doctor/ethtool" - "tailscale.com/doctor/permissions" - "tailscale.com/doctor/routetable" "tailscale.com/drive" "tailscale.com/envknob" "tailscale.com/envknob/featureknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/health/healthmsg" "tailscale.com/hostinfo" "tailscale.com/ipn" - "tailscale.com/ipn/auditlog" "tailscale.com/ipn/conffile" "tailscale.com/ipn/ipnauth" + "tailscale.com/ipn/ipnext" "tailscale.com/ipn/ipnstate" - "tailscale.com/ipn/policy" - memstore "tailscale.com/ipn/store/mem" "tailscale.com/log/sockstatlog" "tailscale.com/logpolicy" - "tailscale.com/net/captivedetection" "tailscale.com/net/dns" "tailscale.com/net/dnscache" "tailscale.com/net/dnsfallback" @@ -79,11 +65,8 @@ import ( "tailscale.com/net/tsaddr" "tailscale.com/net/tsdial" "tailscale.com/paths" - "tailscale.com/portlist" "tailscale.com/syncs" "tailscale.com/tailcfg" - "tailscale.com/taildrop" - "tailscale.com/tka" "tailscale.com/tsd" "tailscale.com/tstime" "tailscale.com/types/appctype" @@ -98,21 +81,20 @@ import ( "tailscale.com/types/preftype" "tailscale.com/types/ptr" "tailscale.com/types/views" + "tailscale.com/util/checkchange" "tailscale.com/util/clientmetric" - "tailscale.com/util/deephash" "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" + "tailscale.com/util/execqueue" "tailscale.com/util/goroutines" - "tailscale.com/util/httpm" "tailscale.com/util/mak" - "tailscale.com/util/multierr" - "tailscale.com/util/osshare" "tailscale.com/util/osuser" "tailscale.com/util/rands" "tailscale.com/util/set" "tailscale.com/util/slicesx" - "tailscale.com/util/syspolicy" - "tailscale.com/util/syspolicy/rsop" - "tailscale.com/util/systemd" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/util/syspolicy/ptype" "tailscale.com/util/testenv" "tailscale.com/util/usermetric" "tailscale.com/version" @@ -170,48 +152,20 @@ type watchSession struct { cancel context.CancelFunc // to shut down the session } -// localBackendExtension extends [LocalBackend] with additional functionality. -type localBackendExtension interface { - // Init is called to initialize the extension when the [LocalBackend] is created - // and before it starts running. If the extension cannot be initialized, - // it must return an error, and the Shutdown method will not be called. - // Any returned errors are not fatal; they are used for logging. - // TODO(nickkhyl): should we allow returning a fatal error? - Init(*LocalBackend) error +var ( + // errShutdown indicates that the [LocalBackend.Shutdown] was called. + errShutdown = errors.New("shutting down") - // Shutdown is called when the [LocalBackend] is shutting down, - // if the extension was initialized. Any returned errors are not fatal; - // they are used for logging. - Shutdown() error -} + // errNodeContextChanged indicates that [LocalBackend] has switched + // to a different [localNodeContext], usually due to a profile change. + // It is used as a context cancellation cause for the old context + // and can be returned when an operation is performed on it. + errNodeContextChanged = errors.New("profile changed") -// newLocalBackendExtension is a function that instantiates a [localBackendExtension]. -type newLocalBackendExtension func(logger.Logf, *tsd.System) (localBackendExtension, error) - -// registeredExtensions is a map of registered local backend extensions, -// where the key is the name of the extension and the value is the function -// that instantiates the extension. -var registeredExtensions map[string]newLocalBackendExtension - -// RegisterExtension registers a function that creates a [localBackendExtension]. -// It panics if newExt is nil or if an extension with the same name has already been registered. -func RegisterExtension(name string, newExt newLocalBackendExtension) { - if newExt == nil { - panic(fmt.Sprintf("lb: newExt is nil: %q", name)) - } - if _, ok := registeredExtensions[name]; ok { - panic(fmt.Sprintf("lb: duplicate extensions: %q", name)) - } - mak.Set(®isteredExtensions, name, newExt) -} - -// profileResolver is any function that returns user and profile IDs -// along with a flag indicating whether it succeeded. Since an empty -// profile ID ("") represents an empty profile, the ok return parameter -// distinguishes between an empty profile and no profile. -// -// It is called with [LocalBackend.mu] held. -type profileResolver func() (_ ipn.WindowsUserID, _ ipn.ProfileID, ok bool) + // errManagedByPolicy indicates the operation is blocked + // because the target state is managed by a GP/MDM policy. + errManagedByPolicy = errors.New("managed by policy") +) // LocalBackend is the glue between the major pieces of the Tailscale // network software: the cloud control plane (via controlclient), the @@ -225,35 +179,35 @@ type profileResolver func() (_ ipn.WindowsUserID, _ ipn.ProfileID, ok bool) // state machine generates events back out to zero or more components. type LocalBackend struct { // Elements that are thread-safe or constant after construction. - ctx context.Context // canceled by [LocalBackend.Shutdown] - ctxCancel context.CancelFunc // cancels ctx - logf logger.Logf // general logging - keyLogf logger.Logf // for printing list of peers on change - statsLogf logger.Logf // for printing peers stats on change - sys *tsd.System - health *health.Tracker // always non-nil + ctx context.Context // canceled by [LocalBackend.Shutdown] + ctxCancel context.CancelCauseFunc // cancels ctx + logf logger.Logf // general logging + keyLogf logger.Logf // for printing list of peers on change + statsLogf logger.Logf // for printing peers stats on change + sys *tsd.System + eventClient *eventbus.Client + appcTask execqueue.ExecQueue // handles updates from appc + + health *health.Tracker // always non-nil + polc policyclient.Client // always non-nil metrics metrics e wgengine.Engine // non-nil; TODO(bradfitz): remove; use sys store ipn.StateStore // non-nil; TODO(bradfitz): remove; use sys dialer *tsdial.Dialer // non-nil; TODO(bradfitz): remove; use sys pushDeviceToken syncs.AtomicValue[string] - backendLogID logid.PublicID - unregisterNetMon func() - unregisterHealthWatch func() + backendLogID logid.PublicID // or zero value if logging not in use unregisterSysPolicyWatch func() - portpoll *portlist.Poller // may be nil - portpollOnce sync.Once // guards starting readPoller - varRoot string // or empty if SetVarRoot never called - logFlushFunc func() // or nil if SetLogFlusher wasn't called - em *expiryManager // non-nil - sshAtomicBool atomic.Bool + varRoot string // or empty if SetVarRoot never called + logFlushFunc func() // or nil if SetLogFlusher wasn't called + em *expiryManager // non-nil; TODO(nickkhyl): move to nodeBackend + sshAtomicBool atomic.Bool // TODO(nickkhyl): move to nodeBackend // webClientAtomicBool controls whether the web client is running. This should // be true unless the disable-web-client node attribute has been set. - webClientAtomicBool atomic.Bool + webClientAtomicBool atomic.Bool // TODO(nickkhyl): move to nodeBackend // exposeRemoteWebClientAtomicBool controls whether the web client is exposed over // Tailscale on port 5252. - exposeRemoteWebClientAtomicBool atomic.Bool - shutdownCalled bool // if Shutdown has been called + exposeRemoteWebClientAtomicBool atomic.Bool // TODO(nickkhyl): move to nodeBackend + shutdownCalled bool // if Shutdown has been called debugSink packet.CaptureSink sockstatLogger *sockstatlog.Logger @@ -273,103 +227,92 @@ type LocalBackend struct { // is never called. getTCPHandlerForFunnelFlow func(srcAddr netip.AddrPort, dstPort uint16) (handler func(net.Conn)) - filterAtomic atomic.Pointer[filter.Filter] - containsViaIPFuncAtomic syncs.AtomicValue[func(netip.Addr) bool] - shouldInterceptTCPPortAtomic syncs.AtomicValue[func(uint16) bool] - shouldInterceptVIPServicesTCPPortAtomic syncs.AtomicValue[func(netip.AddrPort) bool] - numClientStatusCalls atomic.Uint32 + containsViaIPFuncAtomic syncs.AtomicValue[func(netip.Addr) bool] // TODO(nickkhyl): move to nodeBackend + shouldInterceptTCPPortAtomic syncs.AtomicValue[func(uint16) bool] // TODO(nickkhyl): move to nodeBackend + shouldInterceptVIPServicesTCPPortAtomic syncs.AtomicValue[func(netip.AddrPort) bool] // TODO(nickkhyl): move to nodeBackend + numClientStatusCalls atomic.Uint32 // TODO(nickkhyl): move to nodeBackend // goTracker accounts for all goroutines started by LocalBacked, primarily // for testing and graceful shutdown purposes. goTracker goroutines.Tracker + startOnce sync.Once // protects the one‑time initialization in [LocalBackend.Start] + + // extHost is the bridge between [LocalBackend] and the registered [ipnext.Extension]s. + // It may be nil in tests that use direct composite literal initialization of [LocalBackend] + // instead of calling [NewLocalBackend]. A nil pointer is a valid, no-op host. + // It can be used with or without b.mu held, but is typically used with it held + // to prevent state changes while invoking callbacks. + extHost *ExtensionHost + + peerAPIPorts syncs.AtomicValue[map[netip.Addr]int] // can be read without b.mu held; TODO(nickkhyl): remove or move to nodeBackend? + // The mutex protects the following elements. - mu sync.Mutex - conf *conffile.Config // latest parsed config, or nil if not in declarative mode - pm *profileManager // mu guards access - filterHash deephash.Sum - httpTestClient *http.Client // for controlclient. nil by default, used by tests. - ccGen clientGen // function for producing controlclient; lazily populated - sshServer SSHServer // or nil, initialized lazily. - appConnector *appc.AppConnector // or nil, initialized when configured. + mu syncs.Mutex + + // currentNodeAtomic is the current node context. It is always non-nil. + // It must be re-created when [LocalBackend] switches to a different profile/node + // (see tailscale/corp#28014 for a bug), but can be mutated in place (via its methods) + // while [LocalBackend] represents the same node. + // + // It is safe for reading with or without holding b.mu, but mutating it in place + // or creating a new one must be done with b.mu held. If both mutexes must be held, + // the LocalBackend's mutex must be acquired first before acquiring the nodeBackend's mutex. + // + // We intend to relax this in the future and only require holding b.mu when replacing it, + // but that requires a better (strictly ordered?) state machine and better management + // of [LocalBackend]'s own state that is not tied to the node context. + currentNodeAtomic atomic.Pointer[nodeBackend] + + conf *conffile.Config // latest parsed config, or nil if not in declarative mode + pm *profileManager // mu guards access + lastFilterInputs *filterInputs + httpTestClient *http.Client // for controlclient. nil by default, used by tests. + ccGen clientGen // function for producing controlclient; lazily populated + sshServer SSHServer // or nil, initialized lazily. + appConnector *appc.AppConnector // or nil, initialized when configured. // notifyCancel cancels notifications to the current SetNotifyCallback. - notifyCancel context.CancelFunc - cc controlclient.Client - ccAuto *controlclient.Auto // if cc is of type *controlclient.Auto + notifyCancel context.CancelFunc + cc controlclient.Client // TODO(nickkhyl): move to nodeBackend + ccAuto *controlclient.Auto // if cc is of type *controlclient.Auto; TODO(nickkhyl): move to nodeBackend + + // ignoreControlClientUpdates indicates whether we want to ignore SetControlClientStatus updates + // before acquiring b.mu. This is used during shutdown to avoid deadlocks. + ignoreControlClientUpdates atomic.Bool + machinePrivKey key.MachinePrivate - tka *tkaState - state ipn.State - capFileSharing bool // whether netMap contains the file sharing capability - capTailnetLock bool // whether netMap contains the tailnet lock capability + tka *tkaState // TODO(nickkhyl): move to nodeBackend + state ipn.State // TODO(nickkhyl): move to nodeBackend + capTailnetLock bool // whether netMap contains the tailnet lock capability // hostinfo is mutated in-place while mu is held. - hostinfo *tailcfg.Hostinfo - // netMap is the most recently set full netmap from the controlclient. - // It can't be mutated in place once set. Because it can't be mutated in place, - // delta updates from the control server don't apply to it. Instead, use - // the peers map to get up-to-date information on the state of peers. - // In general, avoid using the netMap.Peers slice. We'd like it to go away - // as of 2023-09-17. - netMap *netmap.NetworkMap - // peers is the set of current peers and their current values after applying - // delta node mutations as they come in (with mu held). The map values can - // be given out to callers, but the map itself must not escape the LocalBackend. - peers map[tailcfg.NodeID]tailcfg.NodeView - nodeByAddr map[netip.Addr]tailcfg.NodeID // by Node.Addresses only (not subnet routes) - nmExpiryTimer tstime.TimerController // for updating netMap on node expiry; can be nil - activeLogin string // last logged LoginName from netMap - engineStatus ipn.EngineStatus - endpoints []tailcfg.Endpoint - blocked bool - keyExpired bool - authURL string // non-empty if not Running - authURLTime time.Time // when the authURL was received from the control server - authActor ipnauth.Actor // an actor who called [LocalBackend.StartLoginInteractive] last, or nil - egg bool - prevIfState *netmon.State - peerAPIServer *peerAPIServer // or nil - peerAPIListeners []*peerAPIListener - loginFlags controlclient.LoginFlags - fileWaiters set.HandleSet[context.CancelFunc] // of wake-up funcs - notifyWatchers map[string]*watchSession // by session ID - lastStatusTime time.Time // status.AsOf value of the last processed status update - // directFileRoot, if non-empty, means to write received files - // directly to this directory, without staging them in an - // intermediate buffered directory for "pick-up" later. If - // empty, the files are received in a daemon-owned location - // and the localapi is used to enumerate, download, and delete - // them. This is used on macOS where the GUI lifetime is the - // same as the Network Extension lifetime and we can thus avoid - // double-copying files by writing them to the right location - // immediately. - // It's also used on several NAS platforms (Synology, TrueNAS, etc) - // but in that case DoFinalRename is also set true, which moves the - // *.partial file to its final name on completion. - directFileRoot string + hostinfo *tailcfg.Hostinfo // TODO(nickkhyl): move to nodeBackend + nmExpiryTimer tstime.TimerController // for updating netMap on node expiry; can be nil; TODO(nickkhyl): move to nodeBackend + activeLogin string // last logged LoginName from netMap; TODO(nickkhyl): move to nodeBackend (or remove? it's in [ipn.LoginProfile]). + engineStatus ipn.EngineStatus + endpoints []tailcfg.Endpoint + blocked bool + keyExpired bool // TODO(nickkhyl): move to nodeBackend + authURL string // non-empty if not Running; TODO(nickkhyl): move to nodeBackend + authURLTime time.Time // when the authURL was received from the control server; TODO(nickkhyl): move to nodeBackend + authActor ipnauth.Actor // an actor who called [LocalBackend.StartLoginInteractive] last, or nil; TODO(nickkhyl): move to nodeBackend + egg bool + interfaceState *netmon.State // latest network interface state or nil + peerAPIServer *peerAPIServer // or nil + peerAPIListeners []*peerAPIListener // TODO(nickkhyl): move to nodeBackend + loginFlags controlclient.LoginFlags + notifyWatchers map[string]*watchSession // by session ID + lastStatusTime time.Time // status.AsOf value of the last processed status update componentLogUntil map[string]componentLogState - // c2nUpdateStatus is the status of c2n-triggered client update. - c2nUpdateStatus updateStatus - currentUser ipnauth.Actor + currentUser ipnauth.Actor - // backgroundProfileResolvers are optional background profile resolvers. - backgroundProfileResolvers set.HandleSet[profileResolver] - - selfUpdateProgress []ipnstate.UpdateProgress - lastSelfUpdateState ipnstate.SelfUpdateStatus // capForcedNetfilter is the netfilter that control instructs Linux clients // to use, unless overridden locally. - capForcedNetfilter string - // offlineAutoUpdateCancel stops offline auto-updates when called. It - // should be used via stopOfflineAutoUpdate and - // maybeStartOfflineAutoUpdate. It is nil when offline auto-updates are - // note running. - // - //lint:ignore U1000 only used in Linux and Windows builds in autoupdate.go - offlineAutoUpdateCancel func() + capForcedNetfilter string // TODO(nickkhyl): move to nodeBackend // ServeConfig fields. (also guarded by mu) lastServeConfJSON mem.RO // last JSON that was parsed into serveConfig serveConfig ipn.ServeConfigView // or !Valid if none - ipVIPServiceMap netmap.IPServiceMappings // map of VIPService IPs to their corresponding service names + ipVIPServiceMap netmap.IPServiceMappings // map of VIPService IPs to their corresponding service names; TODO(nickkhyl): move to nodeBackend webClient webClient webClientListeners map[netip.AddrPort]*localListener // listeners for local web client traffic @@ -377,14 +320,9 @@ type LocalBackend struct { serveListeners map[netip.AddrPort]*localListener // listeners for local serve traffic serveProxyHandlers sync.Map // string (HTTPHandler.Proxy) => *reverseProxy - // statusLock must be held before calling statusChanged.Wait() or - // statusChanged.Broadcast(). - statusLock sync.Mutex - statusChanged *sync.Cond - // dialPlan is any dial plan that we've received from the control // server during a previous connection; it is cleared on logout. - dialPlan atomic.Pointer[tailcfg.ControlDialPlan] + dialPlan atomic.Pointer[tailcfg.ControlDialPlan] // TODO(nickkhyl): maybe move to nodeBackend? // tkaSyncLock is used to make tkaSyncIfNeeded an exclusive // section. This is needed to stop two map-responses in quick succession @@ -392,28 +330,25 @@ type LocalBackend struct { // // tkaSyncLock MUST be taken before mu (or inversely, mu must not be held // at the moment that tkaSyncLock is taken). - tkaSyncLock sync.Mutex + tkaSyncLock syncs.Mutex clock tstime.Clock // Last ClientVersion received in MapResponse, guarded by mu. lastClientVersion *tailcfg.ClientVersion // lastNotifiedDriveSharesMu guards lastNotifiedDriveShares - lastNotifiedDriveSharesMu sync.Mutex + lastNotifiedDriveSharesMu syncs.Mutex // lastNotifiedDriveShares keeps track of the last set of shares that we // notified about. lastNotifiedDriveShares *views.SliceView[*drive.Share, drive.ShareView] - // outgoingFiles keeps track of Taildrop outgoing files keyed to their OutgoingFile.ID - outgoingFiles map[string]*ipn.OutgoingFile - // lastSuggestedExitNode stores the last suggested exit node suggestion to // avoid unnecessary churn between multiple equally-good options. lastSuggestedExitNode tailcfg.StableNodeID // allowedSuggestedExitNodes is a set of exit nodes permitted by the most recent - // [syspolicy.AllowedSuggestedExitNodes] value. The allowedSuggestedExitNodesMu + // [pkey.AllowedSuggestedExitNodes] value. The allowedSuggestedExitNodesMu // mutex guards access to this set. allowedSuggestedExitNodesMu sync.Mutex allowedSuggestedExitNodes set.Set[tailcfg.StableNodeID] @@ -436,10 +371,10 @@ type LocalBackend struct { // (sending false). needsCaptiveDetection chan bool - // overrideAlwaysOn is whether [syspolicy.AlwaysOn] is overridden by the user + // overrideAlwaysOn is whether [pkey.AlwaysOn] is overridden by the user // and should have no impact on the WantRunning state until the policy changes, // or the user re-connects manually, switches to a different profile, etc. - // Notably, this is true when [syspolicy.AlwaysOnOverrideWithReason] is enabled, + // Notably, this is true when [pkey.AlwaysOnOverrideWithReason] is enabled, // and the user has disconnected with a reason. // See tailscale/corp#26146. overrideAlwaysOn bool @@ -448,22 +383,46 @@ type LocalBackend struct { // to true after a delay, or nil if no reconnect is scheduled. reconnectTimer tstime.TimerController - // shutdownCbs are the callbacks to be called when the backend is shutting down. - // Each callback is called exactly once in unspecified order and without b.mu held. - // Returned errors are logged but otherwise ignored and do not affect the shutdown process. - shutdownCbs set.HandleSet[func() error] - - // auditLogger, if non-nil, manages audit logging for the backend. + // overrideExitNodePolicy is whether the user has overridden the exit node policy + // by manually selecting an exit node, as allowed by [pkey.AllowExitNodeOverride]. // - // It queues, persists, and sends audit logs - // to the control client. auditLogger has the same lifespan as b.cc. - auditLogger *auditlog.Logger + // If true, the [pkey.ExitNodeID] and [pkey.ExitNodeIP] policy settings are ignored, + // and the suggested exit node is not applied automatically. + // + // It is cleared when the user switches back to the state required by policy (typically, auto:any), + // or when switching profiles, connecting/disconnecting Tailscale, restarting the client, + // or on similar events. + // + // See tailscale/corp#29969. + overrideExitNodePolicy bool + + // hardwareAttested is whether backend should use a hardware-backed key to + // bind the node identity to this device. + hardwareAttested atomic.Bool + + // getCertForTest is used to retrieve TLS certificates in tests. + // See [LocalBackend.ConfigureCertsForTest]. + getCertForTest func(hostname string) (*TLSCertKeyPair, error) +} + +// SetHardwareAttested enables hardware attestation key signatures in map +// requests, if supported on this platform. SetHardwareAttested should be called +// before Start. +func (b *LocalBackend) SetHardwareAttested() { + b.hardwareAttested.Store(true) +} + +// HardwareAttested reports whether hardware-backed attestation keys should be +// used to bind the node's identity to this device. +func (b *LocalBackend) HardwareAttested() bool { + return b.hardwareAttested.Load() } // HealthTracker returns the health tracker for the backend. -func (b *LocalBackend) HealthTracker() *health.Tracker { - return b.health -} +func (b *LocalBackend) HealthTracker() *health.Tracker { return b.health } + +// Logger returns the logger for the backend. +func (b *LocalBackend) Logger() logger.Logf { return b.logf } // UserMetricsRegistry returns the usermetrics registry for the backend func (b *LocalBackend) UserMetricsRegistry() *usermetric.Registry { @@ -475,9 +434,8 @@ func (b *LocalBackend) NetMon() *netmon.Monitor { return b.sys.NetMon.Get() } -type updateStatus struct { - started bool -} +// PolicyClient returns the policy client for the backend. +func (b *LocalBackend) PolicyClient() policyclient.Client { return b.polc } type metrics struct { // advertisedRoutes is a metric that reports the number of network routes that are advertised by the local node. @@ -497,6 +455,8 @@ type clientGen func(controlclient.Options) (controlclient.Client, error) // but is not actually running. // // If dialer is nil, a new one is made. +// +// The logID may be the zero value if logging is not in use. func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, loginFlags controlclient.LoginFlags) (_ *LocalBackend, err error) { e := sys.Engine.Get() store := sys.StateStore.Get() @@ -513,7 +473,7 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo if loginFlags&controlclient.LocalBackendStartKeyOSNeutral != 0 { goos = "" } - pm, err := newProfileManagerWithGOOS(store, logf, sys.HealthTracker(), goos) + pm, err := newProfileManagerWithGOOS(store, logf, sys.HealthTracker.Get(), goos) if err != nil { return nil, err } @@ -522,9 +482,8 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo } envknob.LogCurrent(logf) - osshare.SetFileSharingEnabled(false, logf) - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancelCause(context.Background()) clock := tstime.StdClock{} // Until we transition to a Running state, use a canceled context for @@ -546,7 +505,8 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo keyLogf: logger.LogOnChange(logf, 5*time.Minute, clock.Now), statsLogf: logger.LogOnChange(logf, 5*time.Minute, clock.Now), sys: sys, - health: sys.HealthTracker(), + polc: sys.PolicyClientOrDefault(), + health: sys.HealthTracker.Get(), metrics: m, e: e, dialer: dialer, @@ -554,17 +514,17 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo pm: pm, backendLogID: logID, state: ipn.NoState, - portpoll: new(portlist.Poller), - em: newExpiryManager(logf), + em: newExpiryManager(logf, sys.Bus.Get()), loginFlags: loginFlags, clock: clock, - selfUpdateProgress: make([]ipnstate.UpdateProgress, 0), - lastSelfUpdateState: ipnstate.UpdateFinished, captiveCtx: captiveCtx, captiveCancel: nil, // so that we start checkCaptivePortalLoop when Running needsCaptiveDetection: make(chan bool), } - mConn.SetNetInfoCallback(b.setNetInfo) + + nb := newNodeBackend(ctx, b.logf, b.sys.Bus.Get()) + b.currentNodeAtomic.Store(nb) + nb.ready() if sys.InitialConfig != nil { if err := b.initPrefsFromConfig(sys.InitialConfig); err != nil { @@ -572,6 +532,11 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo } } + if b.extHost, err = NewExtensionHost(logf, b); err != nil { + return nil, fmt.Errorf("failed to create extension host: %w", err) + } + b.pm.SetExtensionHost(b.extHost) + if b.unregisterSysPolicyWatch, err = b.registerSysPolicyWatch(); err != nil { return nil, err } @@ -582,9 +547,9 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo }() netMon := sys.NetMon.Get() - b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker()) + b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker.Get(), sys.Bus.Get()) if err != nil { - log.Printf("error setting up sockstat logger: %v", err) + logf("error setting up sockstat logger: %v", err) } // Enable sockstats logs only on non-mobile unstable builds if version.IsUnstableBuild() && !version.IsMobile() && b.sockstatLogger != nil { @@ -597,51 +562,123 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo b.e.SetJailedFilter(noneFilter) b.setTCPPortsIntercepted(nil) - b.setVIPServicesTCPPortsIntercepted(nil) - b.statusChanged = sync.NewCond(&b.statusLock) b.e.SetStatusCallback(b.setWgengineStatus) - b.prevIfState = netMon.InterfaceState() - // Call our linkChange code once with the current state, and - // then also whenever it changes: - b.linkChange(&netmon.ChangeDelta{New: netMon.InterfaceState()}) - b.unregisterNetMon = netMon.RegisterChangeCallback(b.linkChange) + b.interfaceState = netMon.InterfaceState() - b.unregisterHealthWatch = b.health.RegisterWatcher(b.onHealthChange) - - if tunWrap, ok := b.sys.Tun.GetOK(); ok { - tunWrap.PeerAPIPort = b.GetPeerAPIPort + // Call our linkChange code once with the current state. + // Following changes are triggered via the eventbus. + cd, err := netmon.NewChangeDelta(nil, b.interfaceState, false, false) + if err != nil { + b.logf("[unexpected] setting initial netmon state failed: %v", err) } else { - b.logf("[unexpected] failed to wire up PeerAPI port for engine %T", e) + b.linkChange(cd) } - for _, component := range ipn.DebuggableComponents { - key := componentStateKey(component) - if ut, err := ipn.ReadStoreInt(pm.Store(), key); err == nil { - if until := time.Unix(ut, 0); until.After(b.clock.Now()) { - // conditional to avoid log spam at start when off - b.SetComponentDebugLogging(component, until) + if buildfeatures.HasPeerAPIServer { + if tunWrap, ok := b.sys.Tun.GetOK(); ok { + tunWrap.PeerAPIPort = b.GetPeerAPIPort + } else { + b.logf("[unexpected] failed to wire up PeerAPI port for engine %T", e) + } + } + + if buildfeatures.HasDebug { + for _, component := range ipn.DebuggableComponents { + key := componentStateKey(component) + if ut, err := ipn.ReadStoreInt(pm.Store(), key); err == nil { + if until := time.Unix(ut, 0); until.After(b.clock.Now()) { + // conditional to avoid log spam at start when off + b.SetComponentDebugLogging(component, until) + } } } } - for name, newFn := range registeredExtensions { - ext, err := newFn(logf, sys) - if err != nil { - b.logf("lb: failed to create %q extension: %v", name, err) - continue - } - if err := ext.Init(b); err != nil { - b.logf("lb: failed to initialize %q extension: %v", name, err) - continue - } - b.shutdownCbs.Add(ext.Shutdown) + // Start the event bus late, once all the assignments above are done. + // (See previous race in tailscale/tailscale#17252) + ec := b.Sys().Bus.Get().Client("ipnlocal.LocalBackend") + b.eventClient = ec + eventbus.SubscribeFunc(ec, b.onClientVersion) + eventbus.SubscribeFunc(ec, func(au controlclient.AutoUpdate) { + b.onTailnetDefaultAutoUpdate(au.Value) + }) + eventbus.SubscribeFunc(ec, func(cd netmon.ChangeDelta) { b.linkChange(&cd) }) + if buildfeatures.HasHealth { + eventbus.SubscribeFunc(ec, b.onHealthChange) } + if buildfeatures.HasPortList { + eventbus.SubscribeFunc(ec, b.setPortlistServices) + } + eventbus.SubscribeFunc(ec, b.onAppConnectorRouteUpdate) + eventbus.SubscribeFunc(ec, b.onAppConnectorStoreRoutes) + mConn.SetNetInfoCallback(b.setNetInfo) // TODO(tailscale/tailscale#17887): move to eventbus return b, nil } +func (b *LocalBackend) onAppConnectorRouteUpdate(ru appctype.RouteUpdate) { + // TODO(creachadair, 2025-10-02): It is currently possible for updates produced under + // one profile to arrive and be applied after a switch to another profile. + // We need to find a way to ensure that changes to the backend state are applied + // consistently in the presnce of profile changes, which currently may not happen in + // a single atomic step. See: https://github.com/tailscale/tailscale/issues/17414 + b.appcTask.Add(func() { + if err := b.AdvertiseRoute(ru.Advertise...); err != nil { + b.logf("appc: failed to advertise routes: %v: %v", ru.Advertise, err) + } + if err := b.UnadvertiseRoute(ru.Unadvertise...); err != nil { + b.logf("appc: failed to unadvertise routes: %v: %v", ru.Unadvertise, err) + } + }) +} + +func (b *LocalBackend) onAppConnectorStoreRoutes(ri appctype.RouteInfo) { + // Whether or not routes should be stored can change over time. + shouldStoreRoutes := b.ControlKnobs().AppCStoreRoutes.Load() + if shouldStoreRoutes { + if err := b.storeRouteInfo(ri); err != nil { + b.logf("appc: failed to store route info: %v", err) + } + } +} + +func (b *LocalBackend) Clock() tstime.Clock { return b.clock } +func (b *LocalBackend) Sys() *tsd.System { return b.sys } + +// NodeBackend returns the current node's NodeBackend interface. +func (b *LocalBackend) NodeBackend() ipnext.NodeBackend { + return b.currentNode() +} + +func (b *LocalBackend) currentNode() *nodeBackend { + if v := b.currentNodeAtomic.Load(); v != nil || !testenv.InTest() { + return v + } + v := newNodeBackend(cmp.Or(b.ctx, context.Background()), b.logf, b.sys.Bus.Get()) + if b.currentNodeAtomic.CompareAndSwap(nil, v) { + v.ready() + } + return b.currentNodeAtomic.Load() +} + +// FindExtensionByName returns an active extension with the given name, +// or nil if no such extension exists. +func (b *LocalBackend) FindExtensionByName(name string) any { + return b.extHost.Extensions().FindExtensionByName(name) +} + +// FindMatchingExtension finds the first active extension that matches target, +// and if one is found, sets target to that extension and returns true. +// Otherwise, it returns false. +// +// It panics if target is not a non-nil pointer to either a type +// that implements [ipnext.Extension], or to any interface type. +func (b *LocalBackend) FindMatchingExtension(target any) bool { + return b.extHost.Extensions().FindMatchingExtension(target) +} + type componentLogState struct { until time.Time timer tstime.TimerController // if non-nil, the AfterFunc to disable it @@ -659,6 +696,9 @@ func componentStateKey(component string) ipn.StateKey { // - magicsock // - sockstats func (b *LocalBackend) SetComponentDebugLogging(component string, until time.Time) error { + if !buildfeatures.HasDebug { + return feature.ErrUnavailable + } b.mu.Lock() defer b.mu.Unlock() @@ -678,7 +718,7 @@ func (b *LocalBackend) SetComponentDebugLogging(component string, until time.Tim } } case "syspolicy": - setEnabled = syspolicy.SetDebugLoggingEnabled + setEnabled = b.polc.SetDebugLoggingEnabled } if setEnabled == nil || !slices.Contains(ipn.DebuggableComponents, component) { return fmt.Errorf("unknown component %q", component) @@ -722,6 +762,9 @@ func (b *LocalBackend) SetComponentDebugLogging(component string, until time.Tim // GetDNSOSConfig returns the base OS DNS configuration, as seen by the DNS manager. func (b *LocalBackend) GetDNSOSConfig() (dns.OSConfig, error) { + if !buildfeatures.HasDNS { + panic("unreachable") + } manager, ok := b.sys.DNSManager.GetOK() if !ok { return dns.OSConfig{}, errors.New("DNS manager not available") @@ -733,6 +776,9 @@ func (b *LocalBackend) GetDNSOSConfig() (dns.OSConfig, error) { // the raw DNS response and the resolvers that are were able to handle the query (the internal forwarder // may race multiple resolvers). func (b *LocalBackend) QueryDNS(name string, queryType dnsmessage.Type) (res []byte, resolvers []*dnstype.Resolver, err error) { + if !buildfeatures.HasDNS { + return nil, nil, feature.ErrUnavailable + } manager, ok := b.sys.DNSManager.GetOK() if !ok { return nil, nil, errors.New("DNS manager not available") @@ -777,6 +823,9 @@ func (b *LocalBackend) QueryDNS(name string, queryType dnsmessage.Type) (res []b // enabled until, or the zero time if component's time is not currently // enabled. func (b *LocalBackend) GetComponentDebugLogging(component string) time.Time { + if !buildfeatures.HasDebug { + return time.Time{} + } b.mu.Lock() defer b.mu.Unlock() @@ -794,24 +843,13 @@ func (b *LocalBackend) Dialer() *tsdial.Dialer { return b.dialer } -// SetDirectFileRoot sets the directory to download files to directly, -// without buffering them through an intermediate daemon-owned -// tailcfg.UserID-specific directory. -// -// This must be called before the LocalBackend starts being used. -func (b *LocalBackend) SetDirectFileRoot(dir string) { - b.mu.Lock() - defer b.mu.Unlock() - b.directFileRoot = dir -} - // ReloadConfig reloads the backend's config from disk. // // It returns (false, nil) if not running in declarative mode, (true, nil) on // success, or (false, error) on failure. func (b *LocalBackend) ReloadConfig() (ok bool, err error) { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() if b.conf == nil { return false, nil } @@ -819,7 +857,7 @@ func (b *LocalBackend) ReloadConfig() (ok bool, err error) { if err != nil { return false, err } - if err := b.setConfigLockedOnEntry(conf, unlock); err != nil { + if err := b.setConfigLocked(conf); err != nil { return false, fmt.Errorf("error setting config: %w", err) } @@ -843,12 +881,14 @@ func (b *LocalBackend) initPrefsFromConfig(conf *conffile.Config) error { if err := b.pm.SetPrefs(p.View(), ipn.NetworkProfile{}); err != nil { return err } + b.updateWarnSync(p.View()) b.setStaticEndpointsFromConfigLocked(conf) b.conf = conf return nil } func (b *LocalBackend) setStaticEndpointsFromConfigLocked(conf *conffile.Config) { + syncs.RequiresMutex(&b.mu) if conf.Parsed.StaticEndpoints == nil && (b.conf == nil || b.conf.Parsed.StaticEndpoints == nil) { return } @@ -866,10 +906,21 @@ func (b *LocalBackend) setStaticEndpointsFromConfigLocked(conf *conffile.Config) } } -// setConfigLockedOnEntry uses the provided config to update the backend's prefs +func (b *LocalBackend) setStateLocked(state ipn.State) { + syncs.RequiresMutex(&b.mu) + if b.state == state { + return + } + b.state = state + for _, f := range b.extHost.Hooks().BackendStateChange { + f(state) + } +} + +// setConfigLocked uses the provided config to update the backend's prefs // and other state. -func (b *LocalBackend) setConfigLockedOnEntry(conf *conffile.Config, unlock unlockOnce) error { - defer unlock() +func (b *LocalBackend) setConfigLocked(conf *conffile.Config) error { + syncs.RequiresMutex(&b.mu) p := b.pm.CurrentPrefs().AsStruct() mp, err := conf.Parsed.ToPrefs() if err != nil { @@ -877,7 +928,7 @@ func (b *LocalBackend) setConfigLockedOnEntry(conf *conffile.Config, unlock unlo } p.ApplyEdits(&mp) b.setStaticEndpointsFromConfigLocked(conf) - b.setPrefsLockedOnEntry(p, unlock) + b.setPrefsLocked(p) b.conf = conf return nil @@ -891,11 +942,17 @@ var assumeNetworkUpdateForTest = envknob.RegisterBool("TS_ASSUME_NETWORK_UP_FOR_ // // b.mu must be held. func (b *LocalBackend) pauseOrResumeControlClientLocked() { + syncs.RequiresMutex(&b.mu) if b.cc == nil { return } - networkUp := b.prevIfState.AnyInterfaceUp() - b.cc.SetPaused((b.state == ipn.Stopped && b.netMap != nil) || (!networkUp && !testenv.InTest() && !assumeNetworkUpdateForTest())) + networkUp := b.interfaceState.AnyInterfaceUp() + pauseForNetwork := (b.state == ipn.Stopped && b.NetMap() != nil) || (!networkUp && !testenv.InTest() && !assumeNetworkUpdateForTest()) + + prefs := b.pm.CurrentPrefs() + pauseForSyncPref := prefs.Valid() && prefs.Sync().EqualBool(false) + + b.cc.SetPaused(pauseForNetwork || pauseForSyncPref) } // DisconnectControl shuts down control client. This can be run before node shutdown to force control to consider this ndoe @@ -903,40 +960,36 @@ func (b *LocalBackend) pauseOrResumeControlClientLocked() { // down, clients switch over to other replicas whilst the existing connections are kept alive for some period of time. func (b *LocalBackend) DisconnectControl() { b.mu.Lock() - defer b.mu.Unlock() cc := b.resetControlClientLocked() - if cc == nil { - return - } - cc.Shutdown() -} + b.mu.Unlock() -// captivePortalDetectionInterval is the duration to wait in an unhealthy state with connectivity broken -// before running captive portal detection. -const captivePortalDetectionInterval = 2 * time.Second + if cc != nil { + cc.Shutdown() + } +} // linkChange is our network monitor callback, called whenever the network changes. func (b *LocalBackend) linkChange(delta *netmon.ChangeDelta) { b.mu.Lock() defer b.mu.Unlock() - ifst := delta.New - hadPAC := b.prevIfState.HasPAC() - b.prevIfState = ifst + b.interfaceState = delta.CurrentState() + b.pauseOrResumeControlClientLocked() - if delta.Major && shouldAutoExitNode() { + prefs := b.pm.CurrentPrefs() + if delta.RebindLikelyRequired && prefs.AutoExitNode().IsSet() { b.refreshAutoExitNode = true } var needReconfig bool // If the network changed and we're using an exit node and allowing LAN access, we may need to reconfigure. - if delta.Major && b.pm.CurrentPrefs().ExitNodeID() != "" && b.pm.CurrentPrefs().ExitNodeAllowLANAccess() { + if delta.RebindLikelyRequired && prefs.ExitNodeID() != "" && prefs.ExitNodeAllowLANAccess() { b.logf("linkChange: in state %v; updating LAN routes", b.state) needReconfig = true } // If the PAC-ness of the network changed, reconfig wireguard+route to add/remove subnets. - if hadPAC != ifst.HasPAC() { - b.logf("linkChange: in state %v; PAC changed from %v->%v", b.state, hadPAC, ifst.HasPAC()) + if delta.HasPACOrProxyConfigChanged { + b.logf("linkChange: in state %v; PAC or proxyConfig changed; updating routes", b.state) needReconfig = true } if needReconfig { @@ -953,25 +1006,42 @@ func (b *LocalBackend) linkChange(delta *netmon.ChangeDelta) { // If the local network configuration has changed, our filter may // need updating to tweak default routes. - b.updateFilterLocked(b.netMap, b.pm.CurrentPrefs()) - updateExitNodeUsageWarning(b.pm.CurrentPrefs(), delta.New, b.health) + b.updateFilterLocked(prefs) + updateExitNodeUsageWarning(prefs, delta.CurrentState(), b.health) - if peerAPIListenAsync && b.netMap != nil && b.state == ipn.Running { - want := b.netMap.GetAddresses().Len() - have := len(b.peerAPIListeners) - b.logf("[v1] linkChange: have %d peerAPIListeners, want %d", have, want) - if have < want { - b.logf("linkChange: peerAPIListeners too low; trying again") - b.goTracker.Go(b.initPeerAPIListener) + if buildfeatures.HasPeerAPIServer { + cn := b.currentNode() + nm := cn.NetMap() + if peerAPIListenAsync && nm != nil && b.state == ipn.Running { + want := nm.GetAddresses().Len() + have := len(b.peerAPIListeners) + b.logf("[v1] linkChange: have %d peerAPIListeners, want %d", have, want) + if have < want { + b.logf("linkChange: peerAPIListeners too low; trying again") + b.goTracker.Go(b.initPeerAPIListener) + } } } } -func (b *LocalBackend) onHealthChange(w *health.Warnable, us *health.UnhealthyState) { - if us == nil { - b.logf("health(warnable=%s): ok", w.Code) - } else { - b.logf("health(warnable=%s): error: %s", w.Code, us.Text) +// Captive portal detection hooks. +var ( + hookCaptivePortalHealthChange feature.Hook[func(*LocalBackend, *health.State)] + hookCheckCaptivePortalLoop feature.Hook[func(*LocalBackend, context.Context)] +) + +func (b *LocalBackend) onHealthChange(change health.Change) { + if !buildfeatures.HasHealth { + return + } + if change.WarnableChanged { + w := change.Warnable + us := change.UnhealthyState + if us == nil { + b.logf("health(warnable=%s): ok", w.Code) + } else { + b.logf("health(warnable=%s): error: %s", w.Code, us.Text) + } } // Whenever health changes, send the current health state to the frontend. @@ -980,51 +1050,17 @@ func (b *LocalBackend) onHealthChange(w *health.Warnable, us *health.UnhealthySt Health: state, }) - isConnectivityImpacted := false - for _, w := range state.Warnings { - // Ignore the captive portal warnable itself. - if w.ImpactsConnectivity && w.WarnableCode != captivePortalWarnable.Code { - isConnectivityImpacted = true - break - } - } - - // captiveCtx can be changed, and is protected with 'mu'; grab that - // before we start our select, below. - // - // It is guaranteed to be non-nil. - b.mu.Lock() - ctx := b.captiveCtx - b.mu.Unlock() - - // If the context is canceled, we don't need to do anything. - if ctx.Err() != nil { - return - } - - if isConnectivityImpacted { - b.logf("health: connectivity impacted; triggering captive portal detection") - - // Ensure that we select on captiveCtx so that we can time out - // triggering captive portal detection if the backend is shutdown. - select { - case b.needsCaptiveDetection <- true: - case <-ctx.Done(): - } - } else { - // If connectivity is not impacted, we know for sure we're not behind a captive portal, - // so drop any warning, and signal that we don't need captive portal detection. - b.health.SetHealthy(captivePortalWarnable) - select { - case b.needsCaptiveDetection <- false: - case <-ctx.Done(): - } + if f, ok := hookCaptivePortalHealthChange.GetOk(); ok { + f(b, state) } } // GetOrSetCaptureSink returns the current packet capture sink, creating it // with the provided newSink function if it does not already exist. func (b *LocalBackend) GetOrSetCaptureSink(newSink func() packet.CaptureSink) packet.CaptureSink { + if !buildfeatures.HasCapture { + return nil + } b.mu.Lock() defer b.mu.Unlock() @@ -1038,6 +1074,9 @@ func (b *LocalBackend) GetOrSetCaptureSink(newSink func() packet.CaptureSink) pa } func (b *LocalBackend) ClearCaptureSink() { + if !buildfeatures.HasCapture { + return + } // Shut down & uninstall the sink if there are no longer // any outputs on it. b.mu.Lock() @@ -1059,6 +1098,16 @@ func (b *LocalBackend) ClearCaptureSink() { // Shutdown halts the backend and all its sub-components. The backend // can no longer be used after Shutdown returns. func (b *LocalBackend) Shutdown() { + // Close the [eventbus.Client] to wait for subscribers to + // return before acquiring b.mu: + // 1. Event handlers also acquire b.mu, they can deadlock with c.Shutdown(). + // 2. Event handlers may not guard against undesirable post/in-progress + // LocalBackend.Shutdown() behaviors. + b.appcTask.Shutdown() + b.eventClient.Close() + + b.em.close() + b.mu.Lock() if b.shutdownCalled { b.mu.Unlock() @@ -1066,7 +1115,7 @@ func (b *LocalBackend) Shutdown() { } b.shutdownCalled = true - if b.captiveCancel != nil { + if buildfeatures.HasCaptivePortal && b.captiveCancel != nil { b.logf("canceling captive portal context") b.captiveCancel() } @@ -1078,7 +1127,7 @@ func (b *LocalBackend) Shutdown() { ctx, cancel := context.WithTimeout(b.ctx, 5*time.Second) defer cancel() t0 := time.Now() - err := b.Logout(ctx) // best effort + err := b.Logout(ctx, ipnauth.Self) // best effort td := time.Since(t0).Round(time.Millisecond) if err != nil { b.logf("failed to log out ephemeral node on shutdown after %v: %v", td, err) @@ -1101,41 +1150,30 @@ func (b *LocalBackend) Shutdown() { if b.notifyCancel != nil { b.notifyCancel() } - shutdownCbs := slices.Collect(maps.Values(b.shutdownCbs)) - b.shutdownCbs = nil + b.appConnector.Close() b.mu.Unlock() b.webClientShutdown() - for _, cb := range shutdownCbs { - if err := cb(); err != nil { - b.logf("shutdown callback failed: %v", err) - } - } - if b.sockstatLogger != nil { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() b.sockstatLogger.Shutdown(ctx) } - if b.peerAPIServer != nil { - b.peerAPIServer.taildrop.Shutdown() - } - b.stopOfflineAutoUpdate() - b.unregisterNetMon() - b.unregisterHealthWatch() b.unregisterSysPolicyWatch() if cc != nil { cc.Shutdown() } - b.ctxCancel() + b.ctxCancel(errShutdown) + b.currentNode().shutdown(errShutdown) + b.extHost.Shutdown() b.e.Close() <-b.e.Done() b.awaitNoGoroutinesInTest() } func (b *LocalBackend) awaitNoGoroutinesInTest() { - if !testenv.InTest() { + if !buildfeatures.HasDebug || !testenv.InTest() { return } ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) @@ -1169,6 +1207,7 @@ func stripKeysFromPrefs(p ipn.PrefsView) ipn.PrefsView { p2.Persist.PrivateNodeKey = key.NodePrivate{} p2.Persist.OldPrivateNodeKey = key.NodePrivate{} p2.Persist.NetworkLockKey = key.NLPrivate{} + p2.Persist.AttestationKey = nil return p2.View() } @@ -1180,9 +1219,17 @@ func (b *LocalBackend) Prefs() ipn.PrefsView { } func (b *LocalBackend) sanitizedPrefsLocked() ipn.PrefsView { + syncs.RequiresMutex(&b.mu) return stripKeysFromPrefs(b.pm.CurrentPrefs()) } +// unsanitizedPersist returns the current PersistView, including any private keys. +func (b *LocalBackend) unsanitizedPersist() persist.PersistView { + b.mu.Lock() + defer b.mu.Unlock() + return b.pm.CurrentPrefs().Persist() +} + // Status returns the latest status of the backend and its // sub-components. func (b *LocalBackend) Status() *ipnstate.Status { @@ -1206,6 +1253,8 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { b.mu.Lock() defer b.mu.Unlock() + cn := b.currentNode() + nm := cn.NetMap() sb.MutateStatus(func(s *ipnstate.Status) { s.Version = version.Long() s.TUN = !b.sys.IsNetstack() @@ -1222,21 +1271,21 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { if m := b.sshOnButUnusableHealthCheckMessageLocked(); m != "" { s.Health = append(s.Health, m) } - if b.netMap != nil { - s.CertDomains = append([]string(nil), b.netMap.DNS.CertDomains...) - s.MagicDNSSuffix = b.netMap.MagicDNSSuffix() + if nm != nil { + s.CertDomains = append([]string(nil), nm.DNS.CertDomains...) + s.MagicDNSSuffix = nm.MagicDNSSuffix() if s.CurrentTailnet == nil { s.CurrentTailnet = &ipnstate.TailnetStatus{} } - s.CurrentTailnet.MagicDNSSuffix = b.netMap.MagicDNSSuffix() - s.CurrentTailnet.MagicDNSEnabled = b.netMap.DNS.Proxied - s.CurrentTailnet.Name = b.netMap.Domain + s.CurrentTailnet.MagicDNSSuffix = nm.MagicDNSSuffix() + s.CurrentTailnet.MagicDNSEnabled = nm.DNS.Proxied + s.CurrentTailnet.Name = nm.Domain if prefs := b.pm.CurrentPrefs(); prefs.Valid() { - if !prefs.RouteAll() && b.netMap.AnyPeersAdvertiseRoutes() { + if !prefs.RouteAll() && nm.AnyPeersAdvertiseRoutes() { s.Health = append(s.Health, healthmsg.WarnAcceptRoutesOff) } if !prefs.ExitNodeID().IsZero() { - if exitPeer, ok := b.netMap.PeerWithStableID(prefs.ExitNodeID()); ok { + if exitPeer, ok := nm.PeerWithStableID(prefs.ExitNodeID()); ok { s.ExitNodeStatus = &ipnstate.ExitNodeStatus{ ID: prefs.ExitNodeID(), Online: exitPeer.Online().Get(), @@ -1249,8 +1298,8 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { }) var tailscaleIPs []netip.Addr - if b.netMap != nil { - addrs := b.netMap.GetAddresses() + if nm != nil { + addrs := nm.GetAddresses() for i := range addrs.Len() { if addr := addrs.At(i); addr.IsSingleIP() { sb.AddTailscaleIP(addr.Addr()) @@ -1262,14 +1311,14 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { sb.MutateSelfStatus(func(ss *ipnstate.PeerStatus) { ss.OS = version.OS() ss.Online = b.health.GetInPollNetMap() - if b.netMap != nil { + if nm != nil { ss.InNetworkMap = true - if hi := b.netMap.SelfNode.Hostinfo(); hi.Valid() { + if hi := nm.SelfNode.Hostinfo(); hi.Valid() { ss.HostName = hi.Hostname() } - ss.DNSName = b.netMap.Name - ss.UserID = b.netMap.User() - if sn := b.netMap.SelfNode; sn.Valid() { + ss.DNSName = nm.SelfName() + ss.UserID = nm.User() + if sn := nm.SelfNode; sn.Valid() { peerStatusFromNode(ss, sn) if cm := sn.CapMap(); cm.Len() > 0 { ss.Capabilities = make([]tailcfg.NodeCapability, 1, cm.Len()+1) @@ -1287,7 +1336,7 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { } } else { - ss.HostName, _ = os.Hostname() + ss.HostName, _ = hostinfo.Hostname() } for _, pln := range b.peerAPIListeners { ss.PeerAPIURL = append(ss.PeerAPIURL, pln.urlStr) @@ -1302,14 +1351,17 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { } func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) { - if b.netMap == nil { + syncs.RequiresMutex(&b.mu) + cn := b.currentNode() + nm := cn.NetMap() + if nm == nil { return } - for id, up := range b.netMap.UserProfiles { + for id, up := range nm.UserProfiles { sb.AddUser(id, up) } exitNodeID := b.pm.CurrentPrefs().ExitNodeID() - for _, p := range b.peers { + for _, p := range cn.Peers() { tailscaleIPs := make([]netip.Addr, 0, p.Addresses().Len()) for i := range p.Addresses().Len() { addr := p.Addresses().At(i) @@ -1332,7 +1384,9 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) { SSH_HostKeys: p.Hostinfo().SSH_HostKeys().AsSlice(), Location: p.Hostinfo().Location().AsStruct(), Capabilities: p.Capabilities().AsSlice(), - TaildropTarget: b.taildropTargetStatus(p), + } + for _, f := range b.extHost.Hooks().SetPeerStatus { + f(ps, p, cn) } if cm := p.CapMap(); cm.Len() > 0 { ps.CapMap = make(tailcfg.NodeCapMap, cm.Len()) @@ -1359,7 +1413,7 @@ func peerStatusFromNode(ps *ipnstate.PeerStatus, n tailcfg.NodeView) { ps.PublicKey = n.Key() ps.ID = n.StableID() ps.Created = n.Created() - ps.ExitNodeOption = tsaddr.ContainsExitRoutes(n.AllowedIPs()) + ps.ExitNodeOption = buildfeatures.HasUseExitNode && tsaddr.ContainsExitRoutes(n.AllowedIPs()) if n.Tags().Len() != 0 { v := n.Tags() ps.Tags = &v @@ -1396,18 +1450,10 @@ func profileFromView(v tailcfg.UserProfileView) tailcfg.UserProfile { // WhoIsNodeKey returns the peer info of given public key, if it exists. func (b *LocalBackend) WhoIsNodeKey(k key.NodePublic) (n tailcfg.NodeView, u tailcfg.UserProfile, ok bool) { - b.mu.Lock() - defer b.mu.Unlock() - // TODO(bradfitz): add nodeByKey like nodeByAddr instead of walking peers. - if b.netMap == nil { - return n, u, false - } - if self := b.netMap.SelfNode; self.Valid() && self.Key() == k { - return self, profileFromView(b.netMap.UserProfiles[self.User()]), true - } - for _, n := range b.peers { - if n.Key() == k { - up, ok := b.netMap.UserProfiles[n.User()] + cn := b.currentNode() + if nid, ok := cn.NodeByKey(k); ok { + if n, ok := cn.NodeByID(nid); ok { + up, ok := cn.NetMap().UserProfiles[n.User()] u = profileFromView(up) return n, u, ok } @@ -1440,8 +1486,9 @@ func (b *LocalBackend) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeVi return zero, u, false } - nid, ok := b.nodeByAddr[ipp.Addr()] - if !ok { + cn := b.currentNode() + nid, ok := cn.NodeByAddr(ipp.Addr()) + if !ok && buildfeatures.HasNetstack { var ip netip.Addr if ipp.Port() != 0 { var protos []string @@ -1462,23 +1509,20 @@ func (b *LocalBackend) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeVi if !ok { return failf("no IP found in ProxyMapper for %v", ipp) } - nid, ok = b.nodeByAddr[ip] + nid, ok = cn.NodeByAddr(ip) if !ok { return failf("no node for proxymapped IP %v", ip) } } - if b.netMap == nil { + nm := cn.NetMap() + if nm == nil { return failf("no netmap") } - n, ok = b.peers[nid] + n, ok = cn.NodeByID(nid) if !ok { - // Check if this the self-node, which would not appear in peers. - if !b.netMap.SelfNode.Valid() || nid != b.netMap.SelfNode.ID() { - return zero, u, false - } - n = b.netMap.SelfNode + return zero, u, false } - up, ok := b.netMap.UserProfiles[n.User()] + up, ok := cn.UserByID(n.User()) if !ok { return failf("no userprofile for node %v", n.Key()) } @@ -1488,50 +1532,46 @@ func (b *LocalBackend) WhoIs(proto string, ipp netip.AddrPort) (n tailcfg.NodeVi // PeerCaps returns the capabilities that remote src IP has to // ths current node. func (b *LocalBackend) PeerCaps(src netip.Addr) tailcfg.PeerCapMap { - b.mu.Lock() - defer b.mu.Unlock() - return b.peerCapsLocked(src) -} - -func (b *LocalBackend) peerCapsLocked(src netip.Addr) tailcfg.PeerCapMap { - if b.netMap == nil { - return nil - } - filt := b.filterAtomic.Load() - if filt == nil { - return nil - } - addrs := b.netMap.GetAddresses() - for i := range addrs.Len() { - a := addrs.At(i) - if !a.IsSingleIP() { - continue - } - dst := a.Addr() - if dst.BitLen() == src.BitLen() { // match on family - return filt.CapsWithValues(src, dst) - } - } - return nil + return b.currentNode().PeerCaps(src) } func (b *LocalBackend) GetFilterForTest() *filter.Filter { - return b.filterAtomic.Load() + testenv.AssertInTest() + nb := b.currentNode() + return nb.filterAtomic.Load() +} + +func (b *LocalBackend) settleEventBus() { + // The move to eventbus made some things racy that + // weren't before so we have to wait for it to all be settled + // before we call certain things. + // See https://github.com/tailscale/tailscale/issues/16369 + // But we can't do this while holding b.mu without deadlocks, + // (https://github.com/tailscale/tailscale/pull/17804#issuecomment-3514426485) so + // now we just do it in lots of places before acquiring b.mu. + // Is this winning?? + if b.sys != nil { + if ms, ok := b.sys.MagicSock.GetOK(); ok { + ms.Synchronize() + } + } } // SetControlClientStatus is the callback invoked by the control client whenever it posts a new status. // Among other things, this is where we update the netmap, packet filters, DNS and DERP maps. func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st controlclient.Status) { - unlock := b.lockAndGetUnlock() - defer unlock() + if b.ignoreControlClientUpdates.Load() { + b.logf("ignoring SetControlClientStatus during controlclient shutdown") + return + } + b.mu.Lock() + defer b.mu.Unlock() if b.cc != c { b.logf("Ignoring SetControlClientStatus from old client") return } if st.Err != nil { - // The following do not depend on any data for which we need b locked. - unlock.UnlockEarly() if errors.Is(st.Err, io.EOF) { b.logf("[v1] Received error: EOF") return @@ -1540,7 +1580,7 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control var uerr controlclient.UserVisibleError if errors.As(st.Err, &uerr) { s := uerr.UserVisibleError() - b.send(ipn.Notify{ErrMessage: &s}) + b.sendLocked(ipn.Notify{ErrMessage: &s}) } return } @@ -1589,38 +1629,35 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control } wasBlocked := b.blocked + authWasInProgress := b.authURL != "" keyExpiryExtended := false if st.NetMap != nil { wasExpired := b.keyExpired - isExpired := !st.NetMap.Expiry.IsZero() && st.NetMap.Expiry.Before(b.clock.Now()) + isExpired := !st.NetMap.SelfKeyExpiry().IsZero() && st.NetMap.SelfKeyExpiry().Before(b.clock.Now()) if wasExpired && !isExpired { keyExpiryExtended = true } b.keyExpired = isExpired } - unlock.UnlockEarly() - if keyExpiryExtended && wasBlocked { // Key extended, unblock the engine - b.blockEngineUpdates(false) + b.blockEngineUpdatesLocked(false) } - if st.LoginFinished() && (wasBlocked || b.seamlessRenewalEnabled()) { + if st.LoggedIn && (wasBlocked || authWasInProgress) { if wasBlocked { // Auth completed, unblock the engine - b.blockEngineUpdates(false) + b.blockEngineUpdatesLocked(false) } - b.authReconfig() - b.send(ipn.Notify{LoginFinished: &empty.Message{}}) + b.authReconfigLocked() + b.sendLocked(ipn.Notify{LoginFinished: &empty.Message{}}) } - // Lock b again and do only the things that require locking. - b.mu.Lock() - prefsChanged := false + cn := b.currentNode() prefs := b.pm.CurrentPrefs().AsStruct() - oldNetMap := b.netMap + oldNetMap := cn.NetMap() curNetMap := st.NetMap if curNetMap == nil { // The status didn't include a netmap update, so the old one is still @@ -1634,7 +1671,7 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control // future "tailscale up" to start checking for // implicit setting reverts, which it doesn't do when // ControlURL is blank. - prefs.ControlURL = prefs.ControlURLOrDefault() + prefs.ControlURL = prefs.ControlURLOrDefault(b.polc) prefsChanged = true } if st.Persist.Valid() { @@ -1643,8 +1680,8 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control prefs.Persist = st.Persist.AsStruct() } } - if st.LoginFinished() { - if b.authURL != "" { + if st.LoggedIn { + if authWasInProgress { b.resetAuthURLLocked() // Interactive login finished successfully (URL visited). // After an interactive login, the user always wants @@ -1659,17 +1696,11 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control prefsChanged = true } } - if shouldAutoExitNode() { - // Re-evaluate exit node suggestion in case circumstances have changed. - _, err := b.suggestExitNodeLocked(curNetMap) - if err != nil && !errors.Is(err, ErrNoPreferredDERP) { - b.logf("SetControlClientStatus failed to select auto exit node: %v", err) - } - } - if applySysPolicy(prefs, b.lastSuggestedExitNode, b.overrideAlwaysOn) { - prefsChanged = true - } - if setExitNodeID(prefs, curNetMap) { + // We primarily need this to apply syspolicy to the prefs if an implicit profile + // switch is about to happen. + // TODO(nickkhyl): remove this once we improve handling of implicit profile switching + // in tailscale/corp#28014 and we apply syspolicy when the switch actually happens. + if b.reconcilePrefsLocked(prefs) { prefsChanged = true } @@ -1679,23 +1710,23 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control prefsChanged = true } + // If the tailnet's display name has changed, update prefs. + if st.NetMap != nil && st.NetMap.TailnetDisplayName() != b.pm.CurrentProfile().NetworkProfile().DisplayName { + prefsChanged = true + } + // Perform all mutations of prefs based on the netmap here. if prefsChanged { // Prefs will be written out if stale; this is not safe unless locked or cloned. if err := b.pm.SetPrefs(prefs.View(), ipn.NetworkProfile{ MagicDNSName: curNetMap.MagicDNSSuffix(), DomainName: curNetMap.DomainName(), + DisplayName: curNetMap.TailnetDisplayName(), }); err != nil { b.logf("Failed to save new controlclient state: %v", err) } - } - // Update the audit logger with the current profile ID. - if b.auditLogger != nil && prefsChanged { - pid := b.pm.CurrentProfile().ID() - if err := b.auditLogger.SetProfileID(pid); err != nil { - b.logf("Failed to set profile ID in audit logger: %v", err) - } + b.sendToLocked(ipn.Notify{Prefs: ptr.To(prefs.View())}, allClients) } // initTKALocked is dependent on CurrentProfile.ID, which is initialized @@ -1733,31 +1764,26 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control b.tkaFilterNetmapLocked(st.NetMap) } b.setNetMapLocked(st.NetMap) - b.updateFilterLocked(st.NetMap, prefs.View()) + b.updateFilterLocked(prefs.View()) } - b.mu.Unlock() // Now complete the lock-free parts of what we started while locked. - if prefsChanged { - b.send(ipn.Notify{Prefs: ptr.To(prefs.View())}) - } - if st.NetMap != nil { if envknob.NoLogsNoSupport() && st.NetMap.HasCap(tailcfg.CapabilityDataPlaneAuditLogs) { msg := "tailnet requires logging to be enabled. Remove --no-logs-no-support from tailscaled command line." b.health.SetLocalLogConfigHealth(errors.New(msg)) - // Connecting to this tailnet without logging is forbidden; boot us outta here. - b.mu.Lock() + // Get the current prefs again, since we unlocked above. + prefs := b.pm.CurrentPrefs().AsStruct() prefs.WantRunning = false p := prefs.View() if err := b.pm.SetPrefs(p, ipn.NetworkProfile{ MagicDNSName: st.NetMap.MagicDNSSuffix(), DomainName: st.NetMap.DomainName(), + DisplayName: st.NetMap.TailnetDisplayName(), }); err != nil { b.logf("Failed to save new controlclient state: %v", err) } - b.mu.Unlock() - b.send(ipn.Notify{ErrMessage: &msg, Prefs: &p}) + b.sendLocked(ipn.Notify{ErrMessage: &msg, Prefs: &p}) return } if oldNetMap != nil { @@ -1779,79 +1805,100 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control // Update the DERP map in the health package, which uses it for health notifications b.health.SetDERPMap(st.NetMap.DERPMap) - b.send(ipn.Notify{NetMap: st.NetMap}) + b.sendLocked(ipn.Notify{NetMap: st.NetMap}) + + // The error here is unimportant as is the result. This will recalculate the suggested exit node + // cache the value and push any changes to the IPN bus. + b.suggestExitNodeLocked() + + // Check and update the exit node if needed, now that we have a new netmap. + // + // This must happen after the netmap change is sent via [ipn.Notify], + // so the GUI can correctly display the exit node if it has changed + // since the last netmap was sent. + // + // Otherwise, it might briefly show the exit node as offline and display a warning, + // if the node wasn't online or wasn't advertising default routes in the previous netmap. + b.refreshExitNodeLocked() } if st.URL != "" { b.logf("Received auth URL: %.20v...", st.URL) - b.setAuthURL(st.URL) + b.setAuthURLLocked(st.URL) } - b.stateMachine() + b.stateMachineLocked() // This is currently (2020-07-28) necessary; conditionally disabling it is fragile! // This is where netmap information gets propagated to router and magicsock. - b.authReconfig() + b.authReconfigLocked() } type preferencePolicyInfo struct { - key syspolicy.Key + key pkey.Key get func(ipn.PrefsView) bool set func(*ipn.Prefs, bool) } var preferencePolicies = []preferencePolicyInfo{ { - key: syspolicy.EnableIncomingConnections, + key: pkey.EnableIncomingConnections, // Allow Incoming (used by the UI) is the negation of ShieldsUp (used by the // backend), so this has to convert between the two conventions. get: func(p ipn.PrefsView) bool { return !p.ShieldsUp() }, set: func(p *ipn.Prefs, v bool) { p.ShieldsUp = !v }, }, { - key: syspolicy.EnableServerMode, + key: pkey.EnableServerMode, get: func(p ipn.PrefsView) bool { return p.ForceDaemon() }, set: func(p *ipn.Prefs, v bool) { p.ForceDaemon = v }, }, { - key: syspolicy.ExitNodeAllowLANAccess, + key: pkey.ExitNodeAllowLANAccess, get: func(p ipn.PrefsView) bool { return p.ExitNodeAllowLANAccess() }, set: func(p *ipn.Prefs, v bool) { p.ExitNodeAllowLANAccess = v }, }, { - key: syspolicy.EnableTailscaleDNS, + key: pkey.EnableTailscaleDNS, get: func(p ipn.PrefsView) bool { return p.CorpDNS() }, set: func(p *ipn.Prefs, v bool) { p.CorpDNS = v }, }, { - key: syspolicy.EnableTailscaleSubnets, + key: pkey.EnableTailscaleSubnets, get: func(p ipn.PrefsView) bool { return p.RouteAll() }, set: func(p *ipn.Prefs, v bool) { p.RouteAll = v }, }, { - key: syspolicy.CheckUpdates, + key: pkey.CheckUpdates, get: func(p ipn.PrefsView) bool { return p.AutoUpdate().Check }, set: func(p *ipn.Prefs, v bool) { p.AutoUpdate.Check = v }, }, { - key: syspolicy.ApplyUpdates, + key: pkey.ApplyUpdates, get: func(p ipn.PrefsView) bool { v, _ := p.AutoUpdate().Apply.Get(); return v }, set: func(p *ipn.Prefs, v bool) { p.AutoUpdate.Apply.Set(v) }, }, { - key: syspolicy.EnableRunExitNode, + key: pkey.EnableRunExitNode, get: func(p ipn.PrefsView) bool { return p.AdvertisesExitNode() }, set: func(p *ipn.Prefs, v bool) { p.SetAdvertiseExitNode(v) }, }, } -// applySysPolicy overwrites configured preferences with policies that may be +// applySysPolicyLocked overwrites configured preferences with policies that may be // configured by the system administrator in an OS-specific way. -func applySysPolicy(prefs *ipn.Prefs, lastSuggestedExitNode tailcfg.StableNodeID, overrideAlwaysOn bool) (anyChange bool) { - if controlURL, err := syspolicy.GetString(syspolicy.ControlURL, prefs.ControlURL); err == nil && prefs.ControlURL != controlURL { +// +// b.mu must be held. +func (b *LocalBackend) applySysPolicyLocked(prefs *ipn.Prefs) (anyChange bool) { + if !buildfeatures.HasSystemPolicy { + return false + } + syncs.RequiresMutex(&b.mu) + + if controlURL, err := b.polc.GetString(pkey.ControlURL, prefs.ControlURL); err == nil && prefs.ControlURL != controlURL { prefs.ControlURL = controlURL anyChange = true } const sentinel = "HostnameDefaultValue" - hostnameFromPolicy, _ := syspolicy.GetString(syspolicy.Hostname, sentinel) + hostnameFromPolicy, _ := b.polc.GetString(pkey.Hostname, sentinel) switch hostnameFromPolicy { case sentinel: // An empty string for this policy value means that the admin wants to delete @@ -1881,38 +1928,18 @@ func applySysPolicy(prefs *ipn.Prefs, lastSuggestedExitNode tailcfg.StableNodeID } } - if exitNodeIDStr, _ := syspolicy.GetString(syspolicy.ExitNodeID, ""); exitNodeIDStr != "" { - exitNodeID := tailcfg.StableNodeID(exitNodeIDStr) - if shouldAutoExitNode() && lastSuggestedExitNode != "" { - exitNodeID = lastSuggestedExitNode - } - // Note: when exitNodeIDStr == "auto" && lastSuggestedExitNode == "", - // then exitNodeID is now "auto" which will never match a peer's node ID. - // When there is no a peer matching the node ID, traffic will blackhole, - // preventing accidental non-exit-node usage when a policy is in effect that requires an exit node. - if prefs.ExitNodeID != exitNodeID || prefs.ExitNodeIP.IsValid() { - anyChange = true - } - prefs.ExitNodeID = exitNodeID - prefs.ExitNodeIP = netip.Addr{} - } else if exitNodeIPStr, _ := syspolicy.GetString(syspolicy.ExitNodeIP, ""); exitNodeIPStr != "" { - exitNodeIP, err := netip.ParseAddr(exitNodeIPStr) - if exitNodeIP.IsValid() && err == nil { - if prefs.ExitNodeID != "" || prefs.ExitNodeIP != exitNodeIP { - anyChange = true - } - prefs.ExitNodeID = "" - prefs.ExitNodeIP = exitNodeIP - } + // Only apply the exit node policy if the user hasn't overridden it. + if !b.overrideExitNodePolicy && b.applyExitNodeSysPolicyLocked(prefs) { + anyChange = true } - if alwaysOn, _ := syspolicy.GetBoolean(syspolicy.AlwaysOn, false); alwaysOn && !overrideAlwaysOn && !prefs.WantRunning { + if alwaysOn, _ := b.polc.GetBoolean(pkey.AlwaysOn, false); alwaysOn && !b.overrideAlwaysOn && !prefs.WantRunning { prefs.WantRunning = true anyChange = true } for _, opt := range preferencePolicies { - if po, err := syspolicy.GetPreferenceOption(opt.key); err == nil { + if po, err := b.polc.GetPreferenceOption(opt.key, ptype.ShowChoiceByPolicy); err == nil { curVal := opt.get(prefs.View()) newVal := po.ShouldEnable(curVal) if curVal != newVal { @@ -1925,37 +1952,106 @@ func applySysPolicy(prefs *ipn.Prefs, lastSuggestedExitNode tailcfg.StableNodeID return anyChange } +// applyExitNodeSysPolicyLocked applies the exit node policy settings to prefs +// and reports whether any change was made. +// +// b.mu must be held. +func (b *LocalBackend) applyExitNodeSysPolicyLocked(prefs *ipn.Prefs) (anyChange bool) { + if !buildfeatures.HasUseExitNode { + return false + } + syncs.RequiresMutex(&b.mu) + + if exitNodeIDStr, _ := b.polc.GetString(pkey.ExitNodeID, ""); exitNodeIDStr != "" { + exitNodeID := tailcfg.StableNodeID(exitNodeIDStr) + + // Try to parse the policy setting value as an "auto:"-prefixed [ipn.ExitNodeExpression], + // and update prefs if it differs from the current one. + // This includes cases where it was previously an expression but no longer is, + // or where it wasn't before but now is. + autoExitNode, useAutoExitNode := ipn.ParseAutoExitNodeString(exitNodeID) + if prefs.AutoExitNode != autoExitNode { + prefs.AutoExitNode = autoExitNode + anyChange = true + } + // Additionally, if the specified exit node ID is an expression, + // meaning an exit node is required but we don't yet have a valid exit node ID, + // we should set exitNodeID to a value that is never a valid [tailcfg.StableNodeID], + // to install a blackhole route and prevent accidental non-exit-node usage + // until the expression is evaluated and an actual exit node is selected. + // We use "auto:any" for this purpose, primarily for compatibility with + // older clients (in case a user downgrades to an earlier version) + // and GUIs/CLIs that have special handling for it. + if useAutoExitNode { + exitNodeID = unresolvedExitNodeID + } + + // If the current exit node ID doesn't match the one enforced by the policy setting, + // and the policy either requires a specific exit node ID, + // or requires an auto exit node ID and the current one isn't allowed, + // then update the exit node ID. + if prefs.ExitNodeID != exitNodeID { + if !useAutoExitNode || !isAllowedAutoExitNodeID(b.polc, prefs.ExitNodeID) { + prefs.ExitNodeID = exitNodeID + anyChange = true + } + } + + // If the exit node IP is set, clear it. When ExitNodeIP is set in the prefs, + // it takes precedence over the ExitNodeID. + if prefs.ExitNodeIP.IsValid() { + prefs.ExitNodeIP = netip.Addr{} + anyChange = true + } + } else if exitNodeIPStr, _ := b.polc.GetString(pkey.ExitNodeIP, ""); exitNodeIPStr != "" { + if prefs.AutoExitNode != "" { + prefs.AutoExitNode = "" // mutually exclusive with ExitNodeIP + anyChange = true + } + if exitNodeIP, err := netip.ParseAddr(exitNodeIPStr); err == nil { + if prefs.ExitNodeID != "" || prefs.ExitNodeIP != exitNodeIP { + anyChange = true + } + prefs.ExitNodeID = "" + prefs.ExitNodeIP = exitNodeIP + } + } + + return anyChange +} + // registerSysPolicyWatch subscribes to syspolicy change notifications // and immediately applies the effective syspolicy settings to the current profile. func (b *LocalBackend) registerSysPolicyWatch() (unregister func(), err error) { - if unregister, err = syspolicy.RegisterChangeCallback(b.sysPolicyChanged); err != nil { + if unregister, err = b.polc.RegisterChangeCallback(b.sysPolicyChanged); err != nil { return nil, fmt.Errorf("syspolicy: LocalBacked failed to register policy change callback: %v", err) } - if prefs, anyChange := b.applySysPolicy(); anyChange { + if prefs, anyChange := b.reconcilePrefs(); anyChange { b.logf("syspolicy: changed initial profile prefs: %v", prefs.Pretty()) } b.refreshAllowedSuggestions() return unregister, nil } -// applySysPolicy overwrites the current profile's preferences with policies +// reconcilePrefs overwrites the current profile's preferences with policies // that may be configured by the system administrator in an OS-specific way. // // b.mu must not be held. -func (b *LocalBackend) applySysPolicy() (_ ipn.PrefsView, anyChange bool) { - unlock := b.lockAndGetUnlock() +func (b *LocalBackend) reconcilePrefs() (_ ipn.PrefsView, anyChange bool) { + b.mu.Lock() + defer b.mu.Unlock() + prefs := b.pm.CurrentPrefs().AsStruct() - if !applySysPolicy(prefs, b.lastSuggestedExitNode, b.overrideAlwaysOn) { - unlock.UnlockEarly() + if !b.reconcilePrefsLocked(prefs) { return prefs.View(), false } - return b.setPrefsLockedOnEntry(prefs, unlock), true + return b.setPrefsLocked(prefs), true } // sysPolicyChanged is a callback triggered by syspolicy when it detects // a change in one or more syspolicy settings. -func (b *LocalBackend) sysPolicyChanged(policy *rsop.PolicyChange) { - if policy.HasChanged(syspolicy.AlwaysOn) || policy.HasChanged(syspolicy.AlwaysOnOverrideWithReason) { +func (b *LocalBackend) sysPolicyChanged(policy policyclient.PolicyChange) { + if policy.HasChangedAnyOf(pkey.AlwaysOn, pkey.AlwaysOnOverrideWithReason) { // If the AlwaysOn or the AlwaysOnOverrideWithReason policy has changed, // we should reset the overrideAlwaysOn flag, as the override might // no longer be valid. @@ -1964,20 +2060,25 @@ func (b *LocalBackend) sysPolicyChanged(policy *rsop.PolicyChange) { b.mu.Unlock() } - if policy.HasChanged(syspolicy.AllowedSuggestedExitNodes) { + if policy.HasChangedAnyOf(pkey.ExitNodeID, pkey.ExitNodeIP, pkey.AllowExitNodeOverride) { + // Reset the exit node override if a policy that enforces exit node usage + // or allows the user to override automatic exit node selection has changed. + b.mu.Lock() + b.overrideExitNodePolicy = false + b.mu.Unlock() + } + + if buildfeatures.HasUseExitNode && policy.HasChanged(pkey.AllowedSuggestedExitNodes) { b.refreshAllowedSuggestions() // Re-evaluate exit node suggestion now that the policy setting has changed. - b.mu.Lock() - _, err := b.suggestExitNodeLocked(nil) - b.mu.Unlock() - if err != nil && !errors.Is(err, ErrNoPreferredDERP) { + if _, err := b.SuggestExitNode(); err != nil && !errors.Is(err, ErrNoPreferredDERP) { b.logf("failed to select auto exit node: %v", err) } - // If [syspolicy.ExitNodeID] is set to `auto:any`, the suggested exit node ID + // If [pkey.ExitNodeID] is set to `auto:any`, the suggested exit node ID // will be used when [applySysPolicy] updates the current profile's prefs. } - if prefs, anyChange := b.applySysPolicy(); anyChange { + if prefs, anyChange := b.reconcilePrefs(); anyChange { b.logf("syspolicy: changed profile prefs: %v", prefs.Pretty()) } } @@ -1986,32 +2087,50 @@ var _ controlclient.NetmapDeltaUpdater = (*LocalBackend)(nil) // UpdateNetmapDelta implements controlclient.NetmapDeltaUpdater. func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) { - if !b.MagicConn().UpdateNetmapDelta(muts) { - return false - } - var notify *ipn.Notify // non-nil if we need to send a Notify defer func() { if notify != nil { b.send(*notify) } }() + + // Gross. See https://github.com/tailscale/tailscale/issues/16369 + b.settleEventBus() + defer b.settleEventBus() + b.mu.Lock() defer b.mu.Unlock() - if !b.updateNetmapDeltaLocked(muts) { - return false + cn := b.currentNode() + cn.UpdateNetmapDelta(muts) + + // If auto exit nodes are enabled and our exit node went offline, + // we need to schedule picking a new one. + // TODO(nickkhyl): move the auto exit node logic to a feature package. + if prefs := b.pm.CurrentPrefs(); prefs.AutoExitNode().IsSet() { + exitNodeID := prefs.ExitNodeID() + for _, m := range muts { + mo, ok := m.(netmap.NodeMutationOnline) + if !ok || mo.Online { + continue + } + n, ok := cn.NodeByID(m.NodeIDBeingMutated()) + if !ok || n.StableID() != exitNodeID { + continue + } + b.refreshExitNodeLocked() + break + } } - if b.netMap != nil && mutationsAreWorthyOfTellingIPNBus(muts) { - nm := ptr.To(*b.netMap) // shallow clone - nm.Peers = make([]tailcfg.NodeView, 0, len(b.peers)) - for _, p := range b.peers { - nm.Peers = append(nm.Peers, p) - } - slices.SortFunc(nm.Peers, func(a, b tailcfg.NodeView) int { - return cmp.Compare(a.ID(), b.ID()) - }) + if cn.NetMap() != nil && mutationsAreWorthyOfRecalculatingSuggestedExitNode(muts, cn, b.lastSuggestedExitNode) { + // Recompute the suggested exit node + b.suggestExitNodeLocked() + } + + if cn.NetMap() != nil && mutationsAreWorthyOfTellingIPNBus(muts) { + + nm := cn.netMapWithPeers() notify = &ipn.Notify{NetMap: nm} } else if testenv.InTest() { // In tests, send an empty Notify as a wake-up so end-to-end @@ -2022,6 +2141,44 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo return true } +// mustationsAreWorthyOfRecalculatingSuggestedExitNode reports whether any mutation type in muts is +// worthy of recalculating the suggested exit node. +func mutationsAreWorthyOfRecalculatingSuggestedExitNode(muts []netmap.NodeMutation, cn *nodeBackend, sid tailcfg.StableNodeID) bool { + if !buildfeatures.HasUseExitNode { + return false + } + for _, m := range muts { + n, ok := cn.NodeByID(m.NodeIDBeingMutated()) + if !ok { + // The node being mutated is not in the netmap. + continue + } + + // The previously suggested exit node itself is being mutated. + if sid != "" && n.StableID() == sid { + return true + } + + allowed := n.AllowedIPs().AsSlice() + isExitNode := slices.Contains(allowed, tsaddr.AllIPv4()) || slices.Contains(allowed, tsaddr.AllIPv6()) + // The node being mutated is not an exit node. We don't care about it - unless + // it was our previously suggested exit node which we catch above. + if !isExitNode { + continue + } + + // Some exit node is being mutated. We care about it if it's online + // or offline state has changed. We *might* eventually care about it for other reasons + // but for the sake of finding a "better" suggested exit node, this is probably + // sufficient. + switch m.(type) { + case netmap.NodeMutationOnline: + return true + } + } + return false +} + // mutationsAreWorthyOfTellingIPNBus reports whether any mutation type in muts is // worthy of spamming the IPN bus (the Windows & Mac GUIs, basically) to tell them // about the update. @@ -2038,65 +2195,64 @@ func mutationsAreWorthyOfTellingIPNBus(muts []netmap.NodeMutation) bool { return false } -// pickNewAutoExitNode picks a new automatic exit node if needed. -func (b *LocalBackend) pickNewAutoExitNode() { - unlock := b.lockAndGetUnlock() - defer unlock() - - newPrefs := b.setAutoExitNodeIDLockedOnEntry(unlock) - if !newPrefs.Valid() { - // Unchanged. - return - } - - b.send(ipn.Notify{Prefs: &newPrefs}) -} - -func (b *LocalBackend) updateNetmapDeltaLocked(muts []netmap.NodeMutation) (handled bool) { - if b.netMap == nil || len(b.peers) == 0 { +// resolveAutoExitNodeLocked computes a suggested exit node and updates prefs +// to use it if AutoExitNode is enabled, and reports whether prefs was mutated. +// +// b.mu must be held. +func (b *LocalBackend) resolveAutoExitNodeLocked(prefs *ipn.Prefs) (prefsChanged bool) { + if !buildfeatures.HasUseExitNode { return false } + syncs.RequiresMutex(&b.mu) - // Locally cloned mutable nodes, to avoid calling AsStruct (clone) - // multiple times on a node if it's mutated multiple times in this - // call (e.g. its endpoints + online status both change) - var mutableNodes map[tailcfg.NodeID]*tailcfg.Node - - for _, m := range muts { - n, ok := mutableNodes[m.NodeIDBeingMutated()] - if !ok { - nv, ok := b.peers[m.NodeIDBeingMutated()] - if !ok { - // TODO(bradfitz): unexpected metric? - return false - } - n = nv.AsStruct() - mak.Set(&mutableNodes, nv.ID(), n) - } - m.Apply(n) - - // If our exit node went offline, we need to schedule picking - // a new one. - if mo, ok := m.(netmap.NodeMutationOnline); ok && !mo.Online && n.StableID == b.pm.prefs.ExitNodeID() && shouldAutoExitNode() { - b.goTracker.Go(b.pickNewAutoExitNode) - } + // As of 2025-07-08, the only supported auto exit node expression is [ipn.AnyExitNode]. + // + // However, to maintain forward compatibility with future auto exit node expressions, + // we treat any non-empty AutoExitNode as [ipn.AnyExitNode]. + // + // If and when we support additional auto exit node expressions, this method should be updated + // to handle them appropriately, while still falling back to [ipn.AnyExitNode] or a more appropriate + // default for unknown (or partially supported) expressions. + if !prefs.AutoExitNode.IsSet() { + return false } - for nid, n := range mutableNodes { - b.peers[nid] = n.View() + if _, err := b.suggestExitNodeLocked(); err != nil && !errors.Is(err, ErrNoPreferredDERP) { + b.logf("failed to select auto exit node: %v", err) // non-fatal, see below } - return true + var newExitNodeID tailcfg.StableNodeID + if !b.lastSuggestedExitNode.IsZero() { + // If we have a suggested exit node, use it. + newExitNodeID = b.lastSuggestedExitNode + } else if isAllowedAutoExitNodeID(b.polc, prefs.ExitNodeID) { + // If we don't have a suggested exit node, but the prefs already + // specify an allowed auto exit node ID, retain it. + newExitNodeID = prefs.ExitNodeID + } else { + // Otherwise, use [unresolvedExitNodeID] to install a blackhole route, + // preventing traffic from leaking to the local network until an actual + // exit node is selected. + newExitNodeID = unresolvedExitNodeID + } + if prefs.ExitNodeID != newExitNodeID { + prefs.ExitNodeID = newExitNodeID + prefsChanged = true + } + if prefs.ExitNodeIP.IsValid() { + prefs.ExitNodeIP = netip.Addr{} + prefsChanged = true + } + return prefsChanged } -// setExitNodeID updates prefs to reference an exit node by ID, rather +// resolveExitNodeIPLocked updates prefs to reference an exit node by ID, rather // than by IP. It returns whether prefs was mutated. -func setExitNodeID(prefs *ipn.Prefs, nm *netmap.NetworkMap) (prefsChanged bool) { - if nm == nil { - // No netmap, can't resolve anything. +// +// b.mu must be held. +func (b *LocalBackend) resolveExitNodeIPLocked(prefs *ipn.Prefs) (prefsChanged bool) { + if !buildfeatures.HasUseExitNode { return false } - - // If we have a desired IP on file, try to find the corresponding - // node. + // If we have a desired IP on file, try to find the corresponding node. if !prefs.ExitNodeIP.IsValid() { return false } @@ -2107,20 +2263,19 @@ func setExitNodeID(prefs *ipn.Prefs, nm *netmap.NetworkMap) (prefsChanged bool) prefsChanged = true } - oldExitNodeID := prefs.ExitNodeID - for _, peer := range nm.Peers { - for _, addr := range peer.Addresses().All() { - if !addr.IsSingleIP() || addr.Addr() != prefs.ExitNodeIP { - continue - } + cn := b.currentNode() + if nid, ok := cn.NodeByAddr(prefs.ExitNodeIP); ok { + if node, ok := cn.NodeByID(nid); ok { // Found the node being referenced, upgrade prefs to // reference it directly for next time. - prefs.ExitNodeID = peer.StableID() + prefs.ExitNodeID = node.StableID() prefs.ExitNodeIP = netip.Addr{} - return prefsChanged || oldExitNodeID != prefs.ExitNodeID + // Cleared ExitNodeIP, so prefs changed + // even if the ID stayed the same. + prefsChanged = true + } } - return prefsChanged } @@ -2129,62 +2284,62 @@ func setExitNodeID(prefs *ipn.Prefs, nm *netmap.NetworkMap) (prefsChanged bool) func (b *LocalBackend) setWgengineStatus(s *wgengine.Status, err error) { if err != nil { b.logf("wgengine status error: %v", err) - b.broadcastStatusChanged() return } if s == nil { b.logf("[unexpected] non-error wgengine update with status=nil: %v", s) - b.broadcastStatusChanged() return } b.mu.Lock() + defer b.mu.Unlock() + + // For now, only check this in the callback, but don't check it in setWgengineStatusLocked if s.AsOf.Before(b.lastStatusTime) { // Don't process a status update that is older than the one we have // already processed. (corp#2579) - b.mu.Unlock() return } b.lastStatusTime = s.AsOf + + b.setWgengineStatusLocked(s) +} + +// setWgengineStatusLocked updates LocalBackend's view of the engine status and +// updates the endpoints both in the backend and in the control client. +// +// Unlike setWgengineStatus it does not discard out-of-order updates, so +// statuses sent here are always processed. This is useful for ensuring we don't +// miss a "we shut down" status during backend shutdown even if other statuses +// arrive out of order. +// +// TODO(zofrex): we should ensure updates actually do arrive in order and move +// the out-of-order check into this function. +// +// b.mu must be held. +func (b *LocalBackend) setWgengineStatusLocked(s *wgengine.Status) { + syncs.RequiresMutex(&b.mu) + es := b.parseWgStatusLocked(s) cc := b.cc + + // TODO(zofrex): the only reason we even write this is to transition from + // "Starting" to "Running" in the call to state machine a few lines below + // this. Maybe we don't even need to store it at all. b.engineStatus = es - needUpdateEndpoints := !endpointsEqual(s.LocalAddrs, b.endpoints) + + needUpdateEndpoints := !slices.Equal(s.LocalAddrs, b.endpoints) if needUpdateEndpoints { b.endpoints = append([]tailcfg.Endpoint{}, s.LocalAddrs...) } - b.mu.Unlock() if cc != nil { if needUpdateEndpoints { cc.UpdateEndpoints(s.LocalAddrs) } - b.stateMachine() + b.stateMachineLocked() } - b.broadcastStatusChanged() - b.send(ipn.Notify{Engine: &es}) -} - -func (b *LocalBackend) broadcastStatusChanged() { - // The sync.Cond docs say: "It is allowed but not required for the caller to hold c.L during the call." - // In this particular case, we must acquire b.statusLock. Otherwise we might broadcast before - // the waiter (in requestEngineStatusAndWait) starts to wait, in which case - // the waiter can get stuck indefinitely. See PR 2865. - b.statusLock.Lock() - b.statusChanged.Broadcast() - b.statusLock.Unlock() -} - -func endpointsEqual(x, y []tailcfg.Endpoint) bool { - if len(x) != len(y) { - return false - } - for i := range x { - if x[i] != y[i] { - return false - } - } - return true + b.sendLocked(ipn.Notify{Engine: &es}) } // SetNotifyCallback sets the function to call when the backend has something to @@ -2229,33 +2384,11 @@ func (b *LocalBackend) SetControlClientGetterForTesting(newControlClient func(co b.ccGen = newControlClient } -// NodeViewByIDForTest returns the state of the node with the given ID -// for integration tests in another repo. -func (b *LocalBackend) NodeViewByIDForTest(id tailcfg.NodeID) (_ tailcfg.NodeView, ok bool) { - b.mu.Lock() - defer b.mu.Unlock() - n, ok := b.peers[id] - return n, ok -} - -// DisablePortMapperForTest disables the portmapper for tests. -// It must be called before Start. -func (b *LocalBackend) DisablePortMapperForTest() { - b.mu.Lock() - defer b.mu.Unlock() - b.portpoll = nil -} - // PeersForTest returns all the current peers, sorted by Node.ID, // for integration tests in another repo. func (b *LocalBackend) PeersForTest() []tailcfg.NodeView { - b.mu.Lock() - defer b.mu.Unlock() - ret := slicesx.MapValues(b.peers) - slices.SortFunc(ret, func(a, b tailcfg.NodeView) int { - return cmp.Compare(a.ID(), b.ID()) - }) - return ret + testenv.AssertInTest() + return b.currentNode().PeersForTest() } func (b *LocalBackend) getNewControlClientFuncLocked() clientGen { @@ -2270,6 +2403,11 @@ func (b *LocalBackend) getNewControlClientFuncLocked() clientGen { return b.ccGen } +// initOnce is called on the first call to [LocalBackend.Start]. +func (b *LocalBackend) initOnce() { + b.extHost.Init() +} + // Start applies the configuration specified in opts, and starts the // state machine. // @@ -2281,16 +2419,24 @@ func (b *LocalBackend) getNewControlClientFuncLocked() clientGen { // actually a supported operation (it should be, but it's very unclear // from the following whether or not that is a safe transition). func (b *LocalBackend) Start(opts ipn.Options) error { + defer b.settleEventBus() // with b.mu unlocked + b.mu.Lock() + defer b.mu.Unlock() + return b.startLocked(opts) +} + +func (b *LocalBackend) startLocked(opts ipn.Options) error { b.logf("Start") + logf := logger.WithPrefix(b.logf, "Start: ") + b.startOnce.Do(b.initOnce) var clientToShutdown controlclient.Client defer func() { if clientToShutdown != nil { - clientToShutdown.Shutdown() + // Shutdown outside of b.mu to avoid deadlocks. + b.goTracker.Go(clientToShutdown.Shutdown) } }() - unlock := b.lockAndGetUnlock() - defer unlock() if opts.UpdatePrefs != nil { if err := b.checkPrefsLocked(opts.UpdatePrefs); err != nil { @@ -2310,9 +2456,9 @@ func (b *LocalBackend) Start(opts ipn.Options) error { } if b.state != ipn.Running && b.conf == nil && opts.AuthKey == "" { - sysak, _ := syspolicy.GetString(syspolicy.AuthKey, "") + sysak, _ := b.polc.GetString(pkey.AuthKey, "") if sysak != "" { - b.logf("Start: setting opts.AuthKey by syspolicy, len=%v", len(sysak)) + logf("setting opts.AuthKey by syspolicy, len=%v", len(sysak)) opts.AuthKey = strings.TrimSpace(sysak) } } @@ -2324,6 +2470,7 @@ func (b *LocalBackend) Start(opts ipn.Options) error { hostinfo.Userspace.Set(b.sys.IsNetstack()) hostinfo.UserspaceRouter.Set(b.sys.IsNetstackRouter()) hostinfo.AppConnector.Set(b.appConnector != nil) + hostinfo.StateEncrypted = b.stateEncrypted() b.logf.JSON(1, "Hostinfo", hostinfo) // TODO(apenwarr): avoid the need to reinit controlclient. @@ -2340,31 +2487,59 @@ func (b *LocalBackend) Start(opts ipn.Options) error { hostinfo.Services = b.hostinfo.Services // keep any previous services } b.hostinfo = hostinfo - b.state = ipn.NoState + b.setStateLocked(ipn.NoState) + cn := b.currentNode() + + var prefsChanged bool + var prefsChangedWhy []string + newPrefs := b.pm.CurrentPrefs().AsStruct() if opts.UpdatePrefs != nil { - oldPrefs := b.pm.CurrentPrefs() - newPrefs := opts.UpdatePrefs.Clone() - newPrefs.Persist = oldPrefs.Persist().AsStruct() - pv := newPrefs.View() - if err := b.pm.SetPrefs(pv, ipn.NetworkProfile{ - MagicDNSName: b.netMap.MagicDNSSuffix(), - DomainName: b.netMap.DomainName(), - }); err != nil { - b.logf("failed to save UpdatePrefs state: %v", err) + newPrefs = opts.UpdatePrefs.Clone() + prefsChanged = true + prefsChangedWhy = append(prefsChangedWhy, "opts.UpdatePrefs") + } + // Apply any syspolicy overrides, resolve exit node ID, etc. + // As of 2025-07-03, this is primarily needed in two cases: + // - when opts.UpdatePrefs is not nil + // - when Always Mode is enabled and we need to set WantRunning to true + if b.reconcilePrefsLocked(newPrefs) { + prefsChanged = true + prefsChangedWhy = append(prefsChangedWhy, "reconcilePrefsLocked") + } + + // neither UpdatePrefs or reconciliation should change Persist + newPrefs.Persist = b.pm.CurrentPrefs().Persist().AsStruct() + + if buildfeatures.HasTPM && b.HardwareAttested() { + if genKey, ok := feature.HookGenerateAttestationKeyIfEmpty.GetOk(); ok { + newKey, err := genKey(newPrefs.Persist, logf) + if err != nil { + logf("failed to populate attestation key from TPM: %v", err) + } + if newKey { + prefsChanged = true + prefsChangedWhy = append(prefsChangedWhy, "newKey") + } } } + // Remove any existing attestation key if HardwareAttested is false. + if !b.HardwareAttested() && newPrefs.Persist != nil && newPrefs.Persist.AttestationKey != nil && !newPrefs.Persist.AttestationKey.IsZero() { + newPrefs.Persist.AttestationKey = nil + prefsChanged = true + prefsChangedWhy = append(prefsChangedWhy, "removeAttestationKey") + } + + if prefsChanged { + logf("updated prefs: %v, reason: %v", newPrefs.Pretty(), prefsChangedWhy) + if err := b.pm.SetPrefs(newPrefs.View(), cn.NetworkProfile()); err != nil { + logf("failed to save updated and reconciled prefs (but still using updated prefs in memory): %v", err) + } + } + prefs := newPrefs.View() // Reset the always-on override whenever Start is called. b.resetAlwaysOnOverrideLocked() - // And also apply syspolicy settings to the current profile. - // This is important in two cases: when opts.UpdatePrefs is not nil, - // and when Always Mode is enabled and we need to set WantRunning to true. - if newp := b.pm.CurrentPrefs().AsStruct(); applySysPolicy(newp, b.lastSuggestedExitNode, b.overrideAlwaysOn) { - setExitNodeID(newp, b.netMap) - b.pm.setPrefsNoPermCheck(newp.View()) - } - prefs := b.pm.CurrentPrefs() b.setAtomicValuesFromPrefsLocked(prefs) wantRunning := prefs.WantRunning() @@ -2376,50 +2551,36 @@ func (b *LocalBackend) Start(opts ipn.Options) error { loggedOut := prefs.LoggedOut() - serverURL := prefs.ControlURLOrDefault() + serverURL := prefs.ControlURLOrDefault(b.polc) if inServerMode := prefs.ForceDaemon(); inServerMode || runtime.GOOS == "windows" { - b.logf("Start: serverMode=%v", inServerMode) + logf("serverMode=%v", inServerMode) } - b.applyPrefsToHostinfoLocked(hostinfo, prefs) + b.applyPrefsToHostinfoLocked(b.hostinfo, prefs) + b.updateWarnSync(prefs) persistv := prefs.Persist().AsStruct() if persistv == nil { persistv = new(persist.Persist) } - if b.portpoll != nil { - b.portpollOnce.Do(func() { - b.goTracker.Go(b.readPoller) - }) - } - discoPublic := b.MagicConn().DiscoPublicKey() - var err error - isNetstack := b.sys.IsNetstackRouter() debugFlags := controlDebugFlags if isNetstack { debugFlags = append([]string{"netstack"}, debugFlags...) } - var auditLogShutdown func() - store, ok := b.sys.AuditLogStore.GetOK() - if !ok { - // Use memory store by default if no explicit store is provided. - store = auditlog.NewLogStore(&memstore.Store{}) + var ccShutdownCbs []func() + ccShutdown := func() { + for _, cb := range ccShutdownCbs { + cb() + } } - al := auditlog.NewLogger(auditlog.Opts{ - Logf: b.logf, - RetryLimit: 32, - Store: store, - }) - b.auditLogger = al - auditLogShutdown = func() { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - al.FlushAndStop(ctx) + var c2nHandler http.Handler + if buildfeatures.HasC2N { + c2nHandler = http.HandlerFunc(b.handleC2N) } // TODO(apenwarr): The only way to change the ServerURL is to @@ -2427,27 +2588,27 @@ func (b *LocalBackend) Start(opts ipn.Options) error { // new controlclient. EditPrefs allows you to overwrite ServerURL, // but it won't take effect until the next Start. cc, err := b.getNewControlClientFuncLocked()(controlclient.Options{ - GetMachinePrivateKey: b.createGetMachinePrivateKeyFunc(), - Logf: logger.WithPrefix(b.logf, "control: "), - Persist: *persistv, - ServerURL: serverURL, - AuthKey: opts.AuthKey, - Hostinfo: hostinfo, - HTTPTestClient: httpTestClient, - DiscoPublicKey: discoPublic, - DebugFlags: debugFlags, - HealthTracker: b.health, - Pinger: b, - PopBrowserURL: b.tellClientToBrowseToURL, - OnClientVersion: b.onClientVersion, - OnTailnetDefaultAutoUpdate: b.onTailnetDefaultAutoUpdate, - OnControlTime: b.em.onControlTime, - Dialer: b.Dialer(), - Observer: b, - C2NHandler: http.HandlerFunc(b.handleC2N), - DialPlan: &b.dialPlan, // pointer because it can't be copied - ControlKnobs: b.sys.ControlKnobs(), - Shutdown: auditLogShutdown, + GetMachinePrivateKey: b.createGetMachinePrivateKeyFunc(), + Logf: logger.WithPrefix(b.logf, "control: "), + Persist: *persistv, + ServerURL: serverURL, + AuthKey: opts.AuthKey, + Hostinfo: b.hostInfoWithServicesLocked(), + HTTPTestClient: httpTestClient, + DiscoPublicKey: discoPublic, + DebugFlags: debugFlags, + HealthTracker: b.health, + PolicyClient: b.sys.PolicyClientOrDefault(), + Pinger: b, + PopBrowserURL: b.tellClientToBrowseToURL, + Dialer: b.Dialer(), + Observer: b, + C2NHandler: c2nHandler, + DialPlan: &b.dialPlan, // pointer because it can't be copied + ControlKnobs: b.sys.ControlKnobs(), + Shutdown: ccShutdown, + Bus: b.sys.Bus.Get(), + StartPaused: prefs.Sync().EqualBool(false), // Don't warn about broken Linux IP forwarding when // netstack is being used. @@ -2456,12 +2617,13 @@ func (b *LocalBackend) Start(opts ipn.Options) error { if err != nil { return err } + ccShutdownCbs = b.extHost.NotifyNewControlClient(cc, b.pm.CurrentProfile()) b.setControlClientLocked(cc) endpoints := b.endpoints if err := b.initTKALocked(); err != nil { - b.logf("initTKALocked: %v", err) + logf("initTKALocked: %v", err) } var tkaHead string if b.tka != nil { @@ -2502,7 +2664,7 @@ func (b *LocalBackend) Start(opts ipn.Options) error { // regress tsnet.Server restarts. cc.Login(controlclient.LoginDefault) } - b.stateMachineLockedOnEntry(unlock) + b.stateMachineLocked() return nil } @@ -2538,17 +2700,58 @@ var invalidPacketFilterWarnable = health.Register(&health.Warnable{ Text: health.StaticMessage("The coordination server sent an invalid packet filter permitting traffic to unlocked nodes; rejecting all packets for safety"), }) +// filterInputs holds the inputs to the packet filter. +// +// Any field changes or additions here should be accompanied by a change to +// [filterInputs.Equal] and [filterInputs.Clone] if necessary. (e.g. non-view +// and non-value fields) +type filterInputs struct { + HaveNetmap bool + Addrs views.Slice[netip.Prefix] + FilterMatch views.Slice[filter.Match] + LocalNets views.Slice[netipx.IPRange] + LogNets views.Slice[netipx.IPRange] + ShieldsUp bool + SSHPolicy tailcfg.SSHPolicyView +} + +func (fi *filterInputs) Equal(o *filterInputs) bool { + if fi == nil || o == nil { + return fi == o + } + return reflect.DeepEqual(fi, o) +} + +func (fi *filterInputs) Clone() *filterInputs { + if fi == nil { + return nil + } + v := *fi // all fields are shallow copyable + return &v +} + // updateFilterLocked updates the packet filter in wgengine based on the // given netMap and user preferences. // // b.mu must be held. -func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.PrefsView) { +func (b *LocalBackend) updateFilterLocked(prefs ipn.PrefsView) { + // TODO(nickkhyl) split this into two functions: + // - (*nodeBackend).RebuildFilters() (normalFilter, jailedFilter *filter.Filter, changed bool), + // which would return packet filters for the current state and whether they changed since the last call. + // - (*LocalBackend).updateFilters(), which would use the above to update the engine with the new filters, + // notify b.sshServer, etc. + // + // For this, we would need to plumb a few more things into the [nodeBackend]. Most importantly, + // the current [ipn.PrefsView]), but also maybe also a b.logf and a b.health? + // // NOTE(danderson): keep change detection as the first thing in // this function. Don't try to optimize by returning early, more // likely than not you'll just end up breaking the change // detection and end up with the wrong filter installed. This is // quite hard to debug, so save yourself the trouble. var ( + cn = b.currentNode() + netMap = cn.NetMap() haveNetmap = netMap != nil addrs views.Slice[netip.Prefix] packetFilter []filter.Match @@ -2567,7 +2770,7 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P } packetFilter = netMap.PacketFilter - if packetFilterPermitsUnlockedNodes(b.peers, packetFilter) { + if cn.unlockedNodesPermitted(packetFilter) { b.health.SetUnhealthy(invalidPacketFilterWarnable, nil) packetFilter = nil } else { @@ -2579,31 +2782,33 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P } } if prefs.Valid() { - for _, r := range prefs.AdvertiseRoutes().All() { - if r.Bits() == 0 { - // When offering a default route to the world, we - // filter out locally reachable LANs, so that the - // default route effectively appears to be a "guest - // wifi": you get internet access, but to additionally - // get LAN access the LAN(s) need to be offered - // explicitly as well. - localInterfaceRoutes, hostIPs, err := interfaceRoutes() - if err != nil { - b.logf("getting local interface routes: %v", err) - continue + if buildfeatures.HasAdvertiseRoutes { + for _, r := range prefs.AdvertiseRoutes().All() { + if r.Bits() == 0 { + // When offering a default route to the world, we + // filter out locally reachable LANs, so that the + // default route effectively appears to be a "guest + // wifi": you get internet access, but to additionally + // get LAN access the LAN(s) need to be offered + // explicitly as well. + localInterfaceRoutes, hostIPs, err := interfaceRoutes() + if err != nil { + b.logf("getting local interface routes: %v", err) + continue + } + s, err := shrinkDefaultRoute(r, localInterfaceRoutes, hostIPs) + if err != nil { + b.logf("computing default route filter: %v", err) + continue + } + localNetsB.AddSet(s) + } else { + localNetsB.AddPrefix(r) + // When advertising a non-default route, we assume + // this is a corporate subnet that should be present + // in the audit logs. + logNetsB.AddPrefix(r) } - s, err := shrinkDefaultRoute(r, localInterfaceRoutes, hostIPs) - if err != nil { - b.logf("computing default route filter: %v", err) - continue - } - localNetsB.AddSet(s) - } else { - localNetsB.AddPrefix(r) - // When advertising a non-default route, we assume - // this is a corporate subnet that should be present - // in the audit logs. - logNetsB.AddPrefix(r) } } @@ -2614,27 +2819,27 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P // The correct filter rules are synthesized by the coordination server // and sent down, but the address needs to be part of the 'local net' for the // filter package to even bother checking the filter rules, so we set them here. - if prefs.AppConnector().Advertise { + if buildfeatures.HasAppConnectors && prefs.AppConnector().Advertise { localNetsB.Add(netip.MustParseAddr("0.0.0.0")) localNetsB.Add(netip.MustParseAddr("::0")) } } localNets, _ := localNetsB.IPSet() logNets, _ := logNetsB.IPSet() - var sshPol tailcfg.SSHPolicy - if haveNetmap && netMap.SSHPolicy != nil { - sshPol = *netMap.SSHPolicy + var sshPol tailcfg.SSHPolicyView + if buildfeatures.HasSSH && haveNetmap && netMap.SSHPolicy != nil { + sshPol = netMap.SSHPolicy.View() } - changed := deephash.Update(&b.filterHash, &struct { - HaveNetmap bool - Addrs views.Slice[netip.Prefix] - FilterMatch []filter.Match - LocalNets []netipx.IPRange - LogNets []netipx.IPRange - ShieldsUp bool - SSHPolicy tailcfg.SSHPolicy - }{haveNetmap, addrs, packetFilter, localNets.Ranges(), logNets.Ranges(), shieldsUp, sshPol}) + changed := checkchange.Update(&b.lastFilterInputs, &filterInputs{ + HaveNetmap: haveNetmap, + Addrs: addrs, + FilterMatch: views.SliceOf(packetFilter), + LocalNets: views.SliceOf(localNets.Ranges()), + LogNets: views.SliceOf(logNets.Ranges()), + ShieldsUp: shieldsUp, + SSHPolicy: sshPol, + }) if !changed { return } @@ -2664,122 +2869,6 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P } } -// captivePortalWarnable is a Warnable which is set to an unhealthy state when a captive portal is detected. -var captivePortalWarnable = health.Register(&health.Warnable{ - Code: "captive-portal-detected", - Title: "Captive portal detected", - // High severity, because captive portals block all traffic and require user intervention. - Severity: health.SeverityHigh, - Text: health.StaticMessage("This network requires you to log in using your web browser."), - ImpactsConnectivity: true, -}) - -func (b *LocalBackend) checkCaptivePortalLoop(ctx context.Context) { - var tmr *time.Timer - - maybeStartTimer := func() { - // If there's an existing timer, nothing to do; just continue - // waiting for it to expire. Otherwise, create a new timer. - if tmr == nil { - tmr = time.NewTimer(captivePortalDetectionInterval) - } - } - maybeStopTimer := func() { - if tmr == nil { - return - } - if !tmr.Stop() { - <-tmr.C - } - tmr = nil - } - - for { - if ctx.Err() != nil { - maybeStopTimer() - return - } - - // First, see if we have a signal on our "healthy" channel, which - // takes priority over an existing timer. Because a select is - // nondeterministic, we explicitly check this channel before - // entering the main select below, so that we're guaranteed to - // stop the timer before starting captive portal detection. - select { - case needsCaptiveDetection := <-b.needsCaptiveDetection: - if needsCaptiveDetection { - maybeStartTimer() - } else { - maybeStopTimer() - } - default: - } - - var timerChan <-chan time.Time - if tmr != nil { - timerChan = tmr.C - } - select { - case <-ctx.Done(): - // All done; stop the timer and then exit. - maybeStopTimer() - return - case <-timerChan: - // Kick off captive portal check - b.performCaptiveDetection() - // nil out timer to force recreation - tmr = nil - case needsCaptiveDetection := <-b.needsCaptiveDetection: - if needsCaptiveDetection { - maybeStartTimer() - } else { - // Healthy; cancel any existing timer - maybeStopTimer() - } - } - } -} - -// performCaptiveDetection checks if captive portal detection is enabled via controlknob. If so, it runs -// the detection and updates the Warnable accordingly. -func (b *LocalBackend) performCaptiveDetection() { - if !b.shouldRunCaptivePortalDetection() { - return - } - - d := captivedetection.NewDetector(b.logf) - var dm *tailcfg.DERPMap - b.mu.Lock() - if b.netMap != nil { - dm = b.netMap.DERPMap - } - preferredDERP := 0 - if b.hostinfo != nil { - if b.hostinfo.NetInfo != nil { - preferredDERP = b.hostinfo.NetInfo.PreferredDERP - } - } - ctx := b.ctx - netMon := b.NetMon() - b.mu.Unlock() - found := d.Detect(ctx, netMon, dm, preferredDERP) - if found { - b.health.SetUnhealthy(captivePortalWarnable, health.Args{}) - } else { - b.health.SetHealthy(captivePortalWarnable) - } -} - -// shouldRunCaptivePortalDetection reports whether captive portal detection -// should be run. It is enabled by default, but can be disabled via a control -// knob. It is also only run when the user explicitly wants the backend to be -// running. -func (b *LocalBackend) shouldRunCaptivePortalDetection() bool { - b.mu.Lock() - defer b.mu.Unlock() - return !b.ControlKnobs().DisableCaptivePortalDetection.Load() && b.pm.prefs.WantRunning() -} - // packetFilterPermitsUnlockedNodes reports any peer in peers with the // UnsignedPeerAPIOnly bool set true has any of its allowed IPs in the packet // filter. @@ -2819,8 +2908,10 @@ func packetFilterPermitsUnlockedNodes(peers map[tailcfg.NodeID]tailcfg.NodeView, return false } +// TODO(nickkhyl): this should be non-existent with a proper [LocalBackend.updateFilterLocked]. +// See the comment in that function for more details. func (b *LocalBackend) setFilter(f *filter.Filter) { - b.filterAtomic.Store(f) + b.currentNode().setFilter(f) b.e.SetFilter(f) } @@ -2951,57 +3042,6 @@ func shrinkDefaultRoute(route netip.Prefix, localInterfaceRoutes *netipx.IPSet, return b.IPSet() } -// readPoller is a goroutine that receives service lists from -// b.portpoll and propagates them into the controlclient's HostInfo. -func (b *LocalBackend) readPoller() { - if !envknob.BoolDefaultTrue("TS_PORTLIST") { - return - } - - ticker, tickerChannel := b.clock.NewTicker(portlist.PollInterval()) - defer ticker.Stop() - for { - select { - case <-tickerChannel: - case <-b.ctx.Done(): - return - } - - if !b.shouldUploadServices() { - continue - } - - ports, changed, err := b.portpoll.Poll() - if err != nil { - b.logf("error polling for open ports: %v", err) - return - } - if !changed { - continue - } - sl := []tailcfg.Service{} - for _, p := range ports { - s := tailcfg.Service{ - Proto: tailcfg.ServiceProto(p.Proto), - Port: p.Port, - Description: p.Process, - } - if policy.IsInterestingService(s, version.OS()) { - sl = append(sl, s) - } - } - - b.mu.Lock() - if b.hostinfo == nil { - b.hostinfo = new(tailcfg.Hostinfo) - } - b.hostinfo.Services = sl - b.mu.Unlock() - - b.doSetHostinfoFilterServices() - } -} - // GetPushDeviceToken returns the push notification device token. func (b *LocalBackend) GetPushDeviceToken() string { return b.pushDeviceToken.Load() @@ -3045,36 +3085,25 @@ func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWa b.WatchNotificationsAs(ctx, nil, mask, onWatchAdded, fn) } -// WatchNotificationsAs is like WatchNotifications but takes an [ipnauth.Actor] +// WatchNotificationsAs is like [LocalBackend.WatchNotifications] but takes an [ipnauth.Actor] // as an additional parameter. If non-nil, the specified callback is invoked // only for notifications relevant to this actor. func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.Actor, mask ipn.NotifyWatchOpt, onWatchAdded func(), fn func(roNotify *ipn.Notify) (keepGoing bool)) { ch := make(chan *ipn.Notify, 128) sessionID := rands.HexString(16) - origFn := fn - if mask&ipn.NotifyNoPrivateKeys != 0 { - fn = func(n *ipn.Notify) bool { - if n.NetMap == nil || n.NetMap.PrivateKey.IsZero() { - return origFn(n) - } - - // The netmap in n is shared across all watchers, so to mutate it for a - // single watcher we have to clone the notify and the netmap. We can - // make shallow clones, at least. - nm2 := *n.NetMap - n2 := *n - n2.NetMap = &nm2 - n2.NetMap.PrivateKey = key.NodePrivate{} - return origFn(&n2) - } + if mask&ipn.NotifyHealthActions == 0 { + // if UI does not support PrimaryAction in health warnings, append + // action URLs to the warning text instead. + fn = appendHealthActions(fn) } var ini *ipn.Notify b.mu.Lock() - const initialBits = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap | ipn.NotifyInitialDriveShares + const initialBits = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap | ipn.NotifyInitialDriveShares | ipn.NotifyInitialSuggestedExitNode if mask&initialBits != 0 { + cn := b.currentNode() ini = &ipn.Notify{Version: version.Long()} if mask&ipn.NotifyInitialState != 0 { ini.SessionID = sessionID @@ -3087,14 +3116,19 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A ini.Prefs = ptr.To(b.sanitizedPrefsLocked()) } if mask&ipn.NotifyInitialNetMap != 0 { - ini.NetMap = b.netMap + ini.NetMap = cn.NetMap() } - if mask&ipn.NotifyInitialDriveShares != 0 && b.driveSharingEnabledLocked() { + if mask&ipn.NotifyInitialDriveShares != 0 && b.DriveSharingEnabled() { ini.DriveShares = b.pm.prefs.DriveShares() } if mask&ipn.NotifyInitialHealthState != 0 { ini.Health = b.HealthTracker().CurrentState() } + if mask&ipn.NotifyInitialSuggestedExitNode != 0 { + if en, err := b.suggestExitNodeLocked(); err == nil { + ini.SuggestedExitNode = &en.ID + } + } } ctx, cancel := context.WithCancel(ctx) @@ -3156,6 +3190,33 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A sender.Run(ctx, ch) } +// appendHealthActions returns an IPN listener func that wraps the supplied IPN +// listener func and transforms health messages passed to the wrapped listener. +// If health messages with PrimaryActions are present, it appends the label & +// url in the PrimaryAction to the text of the message. For use for clients that +// do not process the PrimaryAction. +func appendHealthActions(fn func(roNotify *ipn.Notify) (keepGoing bool)) func(*ipn.Notify) bool { + return func(n *ipn.Notify) bool { + if n.Health == nil || len(n.Health.Warnings) == 0 { + return fn(n) + } + + // Shallow clone the notify and health so we can mutate them + h2 := *n.Health + n2 := *n + n2.Health = &h2 + n2.Health.Warnings = make(map[health.WarnableCode]health.UnhealthyState, len(n.Health.Warnings)) + for k, v := range n.Health.Warnings { + if v.PrimaryAction != nil { + v.Text = fmt.Sprintf("%s %s: %s", v.Text, v.PrimaryAction.Label, v.PrimaryAction.URL) + v.PrimaryAction = nil + } + n2.Health.Warnings[k] = v + } + return fn(&n2) + } +} + // pollRequestEngineStatus calls b.e.RequestStatus every 2 seconds until ctx // is done. func (b *LocalBackend) pollRequestEngineStatus(ctx context.Context) { @@ -3183,11 +3244,7 @@ func (b *LocalBackend) DebugNotify(n ipn.Notify) { // // It should only be used via the LocalAPI's debug handler. func (b *LocalBackend) DebugNotifyLastNetMap() { - b.mu.Lock() - nm := b.netMap - b.mu.Unlock() - - if nm != nil { + if nm := b.currentNode().NetMap(); nm != nil { b.send(ipn.Notify{NetMap: nm}) } } @@ -3201,7 +3258,8 @@ func (b *LocalBackend) DebugNotifyLastNetMap() { func (b *LocalBackend) DebugForceNetmapUpdate() { b.mu.Lock() defer b.mu.Unlock() - nm := b.netMap + // TODO(nickkhyl): this all should be done in [LocalBackend.setNetMapLocked]. + nm := b.currentNode().NetMap() b.e.SetNetworkMap(nm) if nm != nil { b.MagicConn().SetDERPMap(nm.DERPMap) @@ -3234,6 +3292,16 @@ func (b *LocalBackend) send(n ipn.Notify) { b.sendTo(n, allClients) } +func (b *LocalBackend) sendLocked(n ipn.Notify) { + b.sendToLocked(n, allClients) +} + +// SendNotify sends a notification to the IPN bus, +// typically to the GUI client. +func (b *LocalBackend) SendNotify(n ipn.Notify) { + b.send(n) +} + // notificationTarget describes a notification recipient. // A zero value is valid and indicate that the notification // should be broadcast to all active [watchSession]s. @@ -3303,9 +3371,8 @@ func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget) n.Version = version.Long() } - apiSrv := b.peerAPIServer - if mayDeref(apiSrv).taildrop.HasFilesWaiting() { - n.FilesWaiting = &empty.Message{} + for _, f := range b.extHost.Hooks().MutateNotifyLocked { + f(&n) } for _, sess := range b.notifyWatchers { @@ -3319,47 +3386,22 @@ func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget) } } -func (b *LocalBackend) sendFileNotify() { - var n ipn.Notify - - b.mu.Lock() - for _, wakeWaiter := range b.fileWaiters { - wakeWaiter() - } - apiSrv := b.peerAPIServer - if apiSrv == nil { - b.mu.Unlock() - return - } - - // Make sure we always set n.IncomingFiles non-nil so it gets encoded - // in JSON to clients. They distinguish between empty and non-nil - // to know whether a Notify should be able about files. - n.IncomingFiles = apiSrv.taildrop.IncomingFiles() - b.mu.Unlock() - - sort.Slice(n.IncomingFiles, func(i, j int) bool { - return n.IncomingFiles[i].Started.Before(n.IncomingFiles[j].Started) - }) - - b.send(n) -} - -// setAuthURL sets the authURL and triggers [LocalBackend.popBrowserAuthNow] if the URL has changed. +// setAuthURLLocked sets the authURL and triggers [LocalBackend.popBrowserAuthNow] if the URL has changed. // This method is called when a new authURL is received from the control plane, meaning that either a user // has started a new interactive login (e.g., by running `tailscale login` or clicking Login in the GUI), // or the control plane was unable to authenticate this node non-interactively (e.g., due to key expiration). // A non-nil b.authActor indicates that an interactive login is in progress and was initiated by the specified actor. +// +// b.mu must be held. +// // If url is "", it is equivalent to calling [LocalBackend.resetAuthURLLocked] with b.mu held. -func (b *LocalBackend) setAuthURL(url string) { +func (b *LocalBackend) setAuthURLLocked(url string) { var popBrowser, keyExpired bool var recipient ipnauth.Actor - b.mu.Lock() switch { case url == "": b.resetAuthURLLocked() - b.mu.Unlock() return case b.authURL != url: b.authURL = url @@ -3376,32 +3418,33 @@ func (b *LocalBackend) setAuthURL(url string) { // Consume the StartLoginInteractive call, if any, that caused the control // plane to send us this URL. b.authActor = nil - b.mu.Unlock() if popBrowser { - b.popBrowserAuthNow(url, keyExpired, recipient) + b.popBrowserAuthNowLocked(url, keyExpired, recipient) } } -// popBrowserAuthNow shuts down the data plane and sends the URL to the recipient's +// popBrowserAuthNowLocked shuts down the data plane and sends the URL to the recipient's // [watchSession]s if the recipient is non-nil; otherwise, it sends the URL to all watchSessions. // keyExpired is the value of b.keyExpired upon entry and indicates // whether the node's key has expired. -// It must not be called with b.mu held. -func (b *LocalBackend) popBrowserAuthNow(url string, keyExpired bool, recipient ipnauth.Actor) { +// +// b.mu must be held. +func (b *LocalBackend) popBrowserAuthNowLocked(url string, keyExpired bool, recipient ipnauth.Actor) { b.logf("popBrowserAuthNow(%q): url=%v, key-expired=%v, seamless-key-renewal=%v", maybeUsernameOf(recipient), url != "", keyExpired, b.seamlessRenewalEnabled()) // Deconfigure the local network data plane if: // - seamless key renewal is not enabled; // - key is expired (in which case tailnet connectivity is down anyway). if !b.seamlessRenewalEnabled() || keyExpired { - b.blockEngineUpdates(true) - b.stopEngineAndWait() - } - b.tellRecipientToBrowseToURL(url, toNotificationTarget(recipient)) - if b.State() == ipn.Running { - b.enterState(ipn.Starting) + b.blockEngineUpdatesLocked(true) + b.stopEngineAndWaitLocked() + + if b.state == ipn.Running { + b.enterStateLocked(ipn.Starting) + } } + b.tellRecipientToBrowseToURLLocked(url, toNotificationTarget(recipient)) } // validPopBrowserURL reports whether urlStr is a valid value for a @@ -3409,6 +3452,16 @@ func (b *LocalBackend) popBrowserAuthNow(url string, keyExpired bool, recipient // // b.mu must *not* be held. func (b *LocalBackend) validPopBrowserURL(urlStr string) bool { + b.mu.Lock() + defer b.mu.Unlock() + return b.validPopBrowserURLLocked(urlStr) +} + +// validPopBrowserURLLocked reports whether urlStr is a valid value for a +// control server to send in a *URL field. +// +// b.mu must be held. +func (b *LocalBackend) validPopBrowserURLLocked(urlStr string) bool { if urlStr == "" { return false } @@ -3416,7 +3469,7 @@ func (b *LocalBackend) validPopBrowserURL(urlStr string) bool { if err != nil { return false } - serverURL := b.Prefs().ControlURLOrDefault() + serverURL := b.sanitizedPrefsLocked().ControlURLOrDefault(b.polc) if ipn.IsLoginServerSynonym(serverURL) { // When connected to the official Tailscale control plane, only allow // URLs from tailscale.com or its subdomains. @@ -3439,13 +3492,16 @@ func (b *LocalBackend) validPopBrowserURL(urlStr string) bool { } func (b *LocalBackend) tellClientToBrowseToURL(url string) { - b.tellRecipientToBrowseToURL(url, allClients) + b.mu.Lock() + defer b.mu.Unlock() + b.tellRecipientToBrowseToURLLocked(url, allClients) } -// tellRecipientToBrowseToURL is like tellClientToBrowseToURL but allows specifying a recipient. -func (b *LocalBackend) tellRecipientToBrowseToURL(url string, recipient notificationTarget) { - if b.validPopBrowserURL(url) { - b.sendTo(ipn.Notify{BrowseToURL: &url}, recipient) +// tellRecipientToBrowseToURLLocked is like tellClientToBrowseToURL but allows specifying a recipient +// and b.mu must be held. +func (b *LocalBackend) tellRecipientToBrowseToURLLocked(url string, recipient notificationTarget) { + if b.validPopBrowserURLLocked(url) { + b.sendToLocked(ipn.Notify{BrowseToURL: &url}, recipient) } } @@ -3460,8 +3516,8 @@ func (b *LocalBackend) onClientVersion(v *tailcfg.ClientVersion) { } func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() prefs := b.pm.CurrentPrefs() if !prefs.Valid() { @@ -3479,16 +3535,18 @@ func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) { // can still manually enable auto-updates on this node. return } - if clientupdate.CanAutoUpdate() { + if buildfeatures.HasClientUpdate && feature.CanAutoUpdate() { b.logf("using tailnet default auto-update setting: %v", au) prefsClone := prefs.AsStruct() prefsClone.AutoUpdate.Apply = opt.NewBool(au) - _, err := b.editPrefsLockedOnEntry(&ipn.MaskedPrefs{ - Prefs: *prefsClone, - AutoUpdateSet: ipn.AutoUpdatePrefsMask{ - ApplySet: true, - }, - }, unlock) + _, err := b.editPrefsLocked( + ipnauth.Self, + &ipn.MaskedPrefs{ + Prefs: *prefsClone, + AutoUpdateSet: ipn.AutoUpdatePrefsMask{ + ApplySet: true, + }, + }) if err != nil { b.logf("failed to apply tailnet-wide default for auto-updates (%v): %v", au, err) return @@ -3626,46 +3684,6 @@ func generateInterceptVIPServicesTCPPortFunc(svcAddrPorts map[netip.Addr]func(ui } } -// setVIPServicesTCPPortsIntercepted populates b.shouldInterceptVIPServicesTCPPortAtomic with an -// efficient func for ShouldInterceptTCPPort to use, which is called on every incoming packet. -func (b *LocalBackend) setVIPServicesTCPPortsIntercepted(svcPorts map[tailcfg.ServiceName][]uint16) { - b.mu.Lock() - defer b.mu.Unlock() - b.setVIPServicesTCPPortsInterceptedLocked(svcPorts) -} - -func (b *LocalBackend) setVIPServicesTCPPortsInterceptedLocked(svcPorts map[tailcfg.ServiceName][]uint16) { - if len(svcPorts) == 0 { - b.shouldInterceptVIPServicesTCPPortAtomic.Store(func(netip.AddrPort) bool { return false }) - return - } - nm := b.netMap - if nm == nil { - b.logf("can't set intercept function for Service TCP Ports, netMap is nil") - return - } - vipServiceIPMap := nm.GetVIPServiceIPMap() - if len(vipServiceIPMap) == 0 { - // No approved VIP Services - return - } - - svcAddrPorts := make(map[netip.Addr]func(uint16) bool) - // Only set the intercept function if the service has been assigned a VIP. - for svcName, ports := range svcPorts { - addrs, ok := vipServiceIPMap[svcName] - if !ok { - continue - } - interceptFn := generateInterceptTCPPortFunc(ports) - for _, addr := range addrs { - svcAddrPorts[addr] = interceptFn - } - } - - b.shouldInterceptVIPServicesTCPPortAtomic.Store(generateInterceptVIPServicesTCPPortFunc(svcAddrPorts)) -} - // setAtomicValuesFromPrefsLocked populates sshAtomicBool, containsViaIPFuncAtomic, // shouldInterceptTCPPortAtomic, and exposeRemoteWebClientAtomicBool from the prefs p, // which may be !Valid(). @@ -3676,7 +3694,9 @@ func (b *LocalBackend) setAtomicValuesFromPrefsLocked(p ipn.PrefsView) { if !p.Valid() { b.containsViaIPFuncAtomic.Store(ipset.FalseContainsIPFunc()) b.setTCPPortsIntercepted(nil) - b.setVIPServicesTCPPortsInterceptedLocked(nil) + if f, ok := hookServeClearVIPServicesTCPPortsInterceptedLocked.GetOk(); ok { + f(b) + } b.lastServeConfJSON = mem.B(nil) b.serveConfig = ipn.ServeConfigView{} } else { @@ -3758,7 +3778,11 @@ func (b *LocalBackend) StartLoginInteractive(ctx context.Context) error { // the control plane sends us one. Otherwise, the notification will be delivered to all // active [watchSession]s. func (b *LocalBackend) StartLoginInteractiveAs(ctx context.Context, user ipnauth.Actor) error { + if b.health.IsUnhealthy(ipn.StateStoreHealth) { + return errors.New("cannot log in when state store is unhealthy") + } b.mu.Lock() + defer b.mu.Unlock() if b.cc == nil { panic("LocalBackend.assertClient: b.cc == nil") } @@ -3776,12 +3800,11 @@ func (b *LocalBackend) StartLoginInteractiveAs(ctx context.Context, user ipnauth b.authActor = user } cc := b.cc - b.mu.Unlock() b.logf("StartLoginInteractiveAs(%q): url=%v", maybeUsernameOf(user), hasValidURL) if hasValidURL { - b.popBrowserAuthNow(url, keyExpired, user) + b.popBrowserAuthNowLocked(url, keyExpired, user) } else { cc.Login(b.loginFlags | controlclient.LoginInteractive) } @@ -3826,6 +3849,9 @@ func (b *LocalBackend) Ping(ctx context.Context, ip netip.Addr, pingType tailcfg } func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netip.Addr) (peer tailcfg.NodeView, peerBase string, err error) { + if !buildfeatures.HasPeerAPIClient { + return peer, peerBase, feature.ErrUnavailable + } var zero tailcfg.NodeView ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() @@ -3891,21 +3917,6 @@ func (b *LocalBackend) parseWgStatusLocked(s *wgengine.Status) (ret ipn.EngineSt return ret } -// shouldUploadServices reports whether this node should include services -// in Hostinfo. When the user preferences currently request "shields up" -// mode, all inbound connections are refused, so services are not reported. -// Otherwise, shouldUploadServices respects NetMap.CollectServices. -func (b *LocalBackend) shouldUploadServices() bool { - b.mu.Lock() - defer b.mu.Unlock() - - p := b.pm.CurrentPrefs() - if !p.Valid() || b.netMap == nil { - return false // default to safest setting - } - return !p.ShieldsUp() && b.netMap.CollectServices -} - // SetCurrentUser is used to implement support for multi-user systems (only // Windows 2022-11-25). On such systems, the actor is used to determine which // user's state should be used. The current user is maintained by active @@ -3923,8 +3934,8 @@ func (b *LocalBackend) shouldUploadServices() bool { // // On non-multi-user systems, the actor should be set to nil. func (b *LocalBackend) SetCurrentUser(actor ipnauth.Actor) { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() var userIdentifier string if user := cmp.Or(actor, b.currentUser); user != nil { @@ -3946,7 +3957,7 @@ func (b *LocalBackend) SetCurrentUser(actor ipnauth.Actor) { action = "connected" } reason := fmt.Sprintf("client %s (%s)", action, userIdentifier) - b.switchToBestProfileLockedOnEntry(reason, unlock) + b.switchToBestProfileLocked(reason) } // SwitchToBestProfile selects the best profile to use, @@ -3956,21 +3967,30 @@ func (b *LocalBackend) SetCurrentUser(actor ipnauth.Actor) { // or disconnecting, or a change in the desktop session state, and is used // for logging. func (b *LocalBackend) SwitchToBestProfile(reason string) { - b.switchToBestProfileLockedOnEntry(reason, b.lockAndGetUnlock()) + b.mu.Lock() + defer b.mu.Unlock() + b.switchToBestProfileLocked(reason) } -// switchToBestProfileLockedOnEntry is like [LocalBackend.SwitchToBestProfile], -// but b.mu must held on entry. It is released on exit. -func (b *LocalBackend) switchToBestProfileLockedOnEntry(reason string, unlock unlockOnce) { - defer unlock() - oldControlURL := b.pm.CurrentPrefs().ControlURLOrDefault() - uid, profileID, background := b.resolveBestProfileLocked() - cp, switched := b.pm.SetCurrentUserAndProfile(uid, profileID) +// switchToBestProfileLocked is like [LocalBackend.SwitchToBestProfile], +// but b.mu must held on entry. +func (b *LocalBackend) switchToBestProfileLocked(reason string) { + oldControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(b.polc) + profile, background := b.resolveBestProfileLocked() + cp, switched, err := b.pm.SwitchToProfile(profile) switch { case !switched && cp.ID() == "": - b.logf("%s: staying on empty profile", reason) + if err != nil { + b.logf("%s: an error occurred; staying on empty profile: %v", reason, err) + } else { + b.logf("%s: staying on empty profile", reason) + } case !switched: - b.logf("%s: staying on profile %q (%s)", reason, cp.UserProfile().LoginName, cp.ID()) + if err != nil { + b.logf("%s: an error occurred; staying on profile %q (%s): %v", reason, cp.UserProfile().LoginName, cp.ID(), err) + } else { + b.logf("%s: staying on profile %q (%s)", reason, cp.UserProfile().LoginName, cp.ID()) + } case cp.ID() == "": b.logf("%s: disconnecting Tailscale", reason) case background: @@ -3982,15 +4002,15 @@ func (b *LocalBackend) switchToBestProfileLockedOnEntry(reason string, unlock un return } // As an optimization, only reset the dialPlan if the control URL changed. - if newControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(); oldControlURL != newControlURL { + if newControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(b.polc); oldControlURL != newControlURL { b.resetDialPlan() } - if err := b.resetForProfileChangeLockedOnEntry(unlock); err != nil { + if err := b.resetForProfileChangeLocked(); err != nil { // TODO(nickkhyl): The actual reset cannot fail. However, // the TKA initialization or [LocalBackend.Start] can fail. // These errors are not critical as far as we're concerned. // But maybe we should post a notification to the API watchers? - b.logf("failed switching profile to %q: %v", profileID, err) + b.logf("failed switching profile to %q: %v", profile.ID(), err) } } @@ -3999,30 +4019,33 @@ func (b *LocalBackend) switchToBestProfileLockedOnEntry(reason string, unlock un // the unattended mode is enabled, the current state of the desktop sessions, // and other factors. // -// It returns the user ID, profile ID, and whether the returned profile is -// considered a background profile. A background profile is used when no OS user -// is actively using Tailscale, such as when no GUI/CLI client is connected -// and Unattended Mode is enabled (see also [LocalBackend.getBackgroundProfileLocked]). -// An empty profile ID indicates that Tailscale should switch to an empty profile. +// It returns a read-only view of the profile and whether it is considered +// a background profile. A background profile is used when no OS user is actively +// using Tailscale, such as when no GUI/CLI client is connected and Unattended Mode +// is enabled (see also [LocalBackend.getBackgroundProfileLocked]). +// +// An invalid view indicates no profile, meaning Tailscale should disconnect +// and remain idle until a GUI or CLI client connects. +// A valid profile view with an empty [ipn.ProfileID] indicates a new profile that +// has not been persisted yet. // // b.mu must be held. -func (b *LocalBackend) resolveBestProfileLocked() (userID ipn.WindowsUserID, profileID ipn.ProfileID, isBackground bool) { +func (b *LocalBackend) resolveBestProfileLocked() (_ ipn.LoginProfileView, isBackground bool) { + // TODO(nickkhyl): delegate all of this to the extensions and remove the distinction + // between "foreground" and "background" profiles as we migrate away from the concept + // of a single "current user" on Windows. See tailscale/corp#18342. + // // If a GUI/CLI client is connected, use the connected user's profile, which means // either the current profile if owned by the user, or their default profile. if b.currentUser != nil { - cp := b.pm.CurrentProfile() - uid := b.currentUser.UserID() - - var profileID ipn.ProfileID + profile := b.pm.CurrentProfile() // TODO(nickkhyl): check if the current profile is allowed on the device, - // such as when [syspolicy.Tailnet] policy setting requires a specific Tailnet. + // such as when [pkey.Tailnet] policy setting requires a specific Tailnet. // See tailscale/corp#26249. - if cp.LocalUserID() == uid { - profileID = cp.ID() - } else { - profileID = b.pm.DefaultUserProfileID(uid) + if uid := b.currentUser.UserID(); profile.LocalUserID() != uid { + profile = b.pm.DefaultUserProfile(uid) } - return uid, profileID, false + return profile, false } // Otherwise, if on Windows, use the background profile if one is set. @@ -4031,63 +4054,29 @@ func (b *LocalBackend) resolveBestProfileLocked() (userID ipn.WindowsUserID, pro // If the returned background profileID is "", Tailscale will disconnect // and remain idle until a GUI or CLI client connects. if goos := envknob.GOOS(); goos == "windows" { - uid, profileID := b.getBackgroundProfileLocked() - return uid, profileID, true + // If Unattended Mode is enabled for the current profile, keep using it. + if b.pm.CurrentPrefs().ForceDaemon() { + return b.pm.CurrentProfile(), true + } + // Otherwise, use the profile returned by the extension. + profile := b.extHost.DetermineBackgroundProfile(b.pm) + return profile, true } // On other platforms, however, Tailscale continues to run in the background // using the current profile. // // TODO(nickkhyl): check if the current profile is allowed on the device, - // such as when [syspolicy.Tailnet] policy setting requires a specific Tailnet. + // such as when [pkey.Tailnet] policy setting requires a specific Tailnet. // See tailscale/corp#26249. - return b.pm.CurrentUserID(), b.pm.CurrentProfile().ID(), false -} - -// RegisterBackgroundProfileResolver registers a function to be used when -// resolving the background profile, until the returned unregister function is called. -func (b *LocalBackend) RegisterBackgroundProfileResolver(resolver profileResolver) (unregister func()) { - // TODO(nickkhyl): should we allow specifying some kind of priority/altitude for the resolver? - b.mu.Lock() - defer b.mu.Unlock() - handle := b.backgroundProfileResolvers.Add(resolver) - return func() { - b.mu.Lock() - defer b.mu.Unlock() - delete(b.backgroundProfileResolvers, handle) - } -} - -// getBackgroundProfileLocked returns the user and profile ID to use when no GUI/CLI -// client is connected, or "","" if Tailscale should not run in the background. -// As of 2025-02-07, it is only used on Windows. -func (b *LocalBackend) getBackgroundProfileLocked() (ipn.WindowsUserID, ipn.ProfileID) { - // TODO(nickkhyl): check if the returned profile is allowed on the device, - // such as when [syspolicy.Tailnet] policy setting requires a specific Tailnet. - // See tailscale/corp#26249. - - // If Unattended Mode is enabled for the current profile, keep using it. - if b.pm.CurrentPrefs().ForceDaemon() { - return b.pm.CurrentProfile().LocalUserID(), b.pm.CurrentProfile().ID() - } - - // Otherwise, attempt to resolve the background profile using the background - // profile resolvers available on the current platform. - for _, resolver := range b.backgroundProfileResolvers { - if uid, profileID, ok := resolver(); ok { - return uid, profileID - } - } - - // Otherwise, switch to an empty profile and disconnect Tailscale - // until a GUI or CLI client connects. - return "", "" + return b.pm.CurrentProfile(), false } // CurrentUserForTest returns the current user and the associated WindowsUserID. // It is used for testing only, and will be removed along with the rest of the // "current user" functionality as we progress on the multi-user improvements (tailscale/corp#18342). func (b *LocalBackend) CurrentUserForTest() (ipn.WindowsUserID, ipnauth.Actor) { + testenv.AssertInTest() b.mu.Lock() defer b.mu.Unlock() return b.pm.CurrentUserID(), b.currentUser @@ -4132,7 +4121,7 @@ func (b *LocalBackend) checkPrefsLocked(p *ipn.Prefs) error { if err := b.checkAutoUpdatePrefsLocked(p); err != nil { errs = append(errs, err) } - return multierr.New(errs...) + return errors.Join(errs...) } func (b *LocalBackend) checkSSHPrefsLocked(p *ipn.Prefs) error { @@ -4148,13 +4137,12 @@ func (b *LocalBackend) checkSSHPrefsLocked(p *ipn.Prefs) error { if envknob.SSHIgnoreTailnetPolicy() || envknob.SSHPolicyFile() != "" { return nil } - if b.netMap != nil { - if !b.netMap.HasCap(tailcfg.CapabilitySSH) { - if b.isDefaultServerLocked() { - return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet. See https://tailscale.com/s/ssh") - } - return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet.") + // Assume that we do have the SSH capability if don't have a netmap yet. + if !b.currentNode().SelfHasCapOr(tailcfg.CapabilitySSH, true) { + if b.isDefaultServerLocked() { + return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet. See https://tailscale.com/s/ssh") } + return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet.") } return nil } @@ -4166,7 +4154,7 @@ func (b *LocalBackend) sshOnButUnusableHealthCheckMessageLocked() (healthMessage if envknob.SSHIgnoreTailnetPolicy() || envknob.SSHPolicyFile() != "" { return "development SSH policy in use" } - nm := b.netMap + nm := b.currentNode().NetMap() if nm == nil { return "" } @@ -4189,7 +4177,7 @@ func (b *LocalBackend) isDefaultServerLocked() bool { if !prefs.Valid() { return true // assume true until set otherwise } - return prefs.ControlURLOrDefault() == ipn.DefaultControlURL + return prefs.ControlURLOrDefault(b.polc) == ipn.DefaultControlURL } var exitNodeMisconfigurationWarnable = health.Register(&health.Warnable{ @@ -4204,12 +4192,14 @@ var exitNodeMisconfigurationWarnable = health.Register(&health.Warnable{ // updateExitNodeUsageWarning updates a warnable meant to notify users of // configuration issues that could break exit node usage. func updateExitNodeUsageWarning(p ipn.PrefsView, state *netmon.State, healthTracker *health.Tracker) { + if !buildfeatures.HasUseExitNode { + return + } var msg string if p.ExitNodeIP().IsValid() || p.ExitNodeID() != "" { warn, _ := netutil.CheckReversePathFiltering(state) - const comment = "please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310" if len(warn) > 0 { - msg = fmt.Sprintf("%s: %v, %s", healthmsg.WarnExitNodeUsage, warn, comment) + msg = fmt.Sprintf("%s: %v, %s", healthmsg.WarnExitNodeUsage, warn, healthmsg.DisableRPFilter) } } if len(msg) > 0 { @@ -4224,6 +4214,9 @@ func (b *LocalBackend) checkExitNodePrefsLocked(p *ipn.Prefs) error { if !tryingToUseExitNode { return nil } + if !buildfeatures.HasUseExitNode { + return feature.ErrUnavailable + } if err := featureknob.CanUseExitNode(); err != nil { return err @@ -4243,7 +4236,12 @@ func (b *LocalBackend) checkFunnelEnabledLocked(p *ipn.Prefs) error { } func (b *LocalBackend) checkAutoUpdatePrefsLocked(p *ipn.Prefs) error { - if p.AutoUpdate.Apply.EqualBool(true) && !clientupdate.CanAutoUpdate() { + if !buildfeatures.HasClientUpdate { + if p.AutoUpdate.Apply.EqualBool(true) { + return errors.New("Auto-update support is disabled in this build") + } + } + if p.AutoUpdate.Apply.EqualBool(true) && !feature.CanAutoUpdate() { return errors.New("Auto-updates are not supported on this platform.") } return nil @@ -4254,11 +4252,14 @@ func (b *LocalBackend) checkAutoUpdatePrefsLocked(p *ipn.Prefs) error { // On success, it returns the resulting prefs (or current prefs, in the case of no change). // Setting the value to false when use of an exit node is already false is not an error, // nor is true when the exit node is already in use. -func (b *LocalBackend) SetUseExitNodeEnabled(v bool) (ipn.PrefsView, error) { - unlock := b.lockAndGetUnlock() - defer unlock() +func (b *LocalBackend) SetUseExitNodeEnabled(actor ipnauth.Actor, v bool) (ipn.PrefsView, error) { + b.mu.Lock() + defer b.mu.Unlock() p0 := b.pm.CurrentPrefs() + if !buildfeatures.HasUseExitNode { + return p0, nil + } if v && p0.ExitNodeID() != "" { // Already on. return p0, nil @@ -4279,22 +4280,36 @@ func (b *LocalBackend) SetUseExitNodeEnabled(v bool) (ipn.PrefsView, error) { mp := &ipn.MaskedPrefs{} if v { mp.ExitNodeIDSet = true - mp.ExitNodeID = tailcfg.StableNodeID(p0.InternalExitNodePrior()) + mp.ExitNodeID = p0.InternalExitNodePrior() + if expr, ok := ipn.ParseAutoExitNodeString(mp.ExitNodeID); ok { + mp.AutoExitNodeSet = true + mp.AutoExitNode = expr + mp.ExitNodeID = unresolvedExitNodeID + } } else { mp.ExitNodeIDSet = true mp.ExitNodeID = "" + mp.AutoExitNodeSet = true + mp.AutoExitNode = "" mp.InternalExitNodePriorSet = true - mp.InternalExitNodePrior = p0.ExitNodeID() + if p0.AutoExitNode().IsSet() { + mp.InternalExitNodePrior = tailcfg.StableNodeID(ipn.AutoExitNodePrefix + p0.AutoExitNode()) + } else { + mp.InternalExitNodePrior = p0.ExitNodeID() + } } - return b.editPrefsLockedOnEntry(mp, unlock) + return b.editPrefsLocked(actor, mp) } // MaybeClearAppConnector clears the routes from any AppConnector if // AdvertiseRoutes has been set in the MaskedPrefs. func (b *LocalBackend) MaybeClearAppConnector(mp *ipn.MaskedPrefs) error { + if !buildfeatures.HasAppConnectors { + return nil + } var err error - if b.appConnector != nil && mp.AdvertiseRoutesSet { - err = b.appConnector.ClearRoutes() + if ac := b.AppConnector(); ac != nil && mp.AdvertiseRoutesSet { + err = ac.ClearRoutes() if err != nil { b.logf("appc: clear routes error: %v", err) } @@ -4302,21 +4317,6 @@ func (b *LocalBackend) MaybeClearAppConnector(mp *ipn.MaskedPrefs) error { return err } -var errNoAuditLogger = errors.New("no audit logger configured") - -func (b *LocalBackend) getAuditLoggerLocked() ipnauth.AuditLogFunc { - logger := b.auditLogger - return func(action tailcfg.ClientAuditAction, details string) error { - if logger == nil { - return errNoAuditLogger - } - if err := logger.Enqueue(action, details); err != nil { - return fmt.Errorf("failed to enqueue audit log %v %q: %w", action, details, err) - } - return nil - } -} - // EditPrefs applies the changes in mp to the current prefs, // acting as the tailscaled itself rather than a specific user. func (b *LocalBackend) EditPrefs(mp *ipn.MaskedPrefs) (ipn.PrefsView, error) { @@ -4329,41 +4329,192 @@ func (b *LocalBackend) EditPrefsAs(mp *ipn.MaskedPrefs, actor ipnauth.Actor) (ip if mp.SetsInternal() { return ipn.PrefsView{}, errors.New("can't set Internal fields") } + defer b.settleEventBus() - // Zeroing the ExitNodeId via localAPI must also zero the prior exit node. - if mp.ExitNodeIDSet && mp.ExitNodeID == "" { + b.mu.Lock() + defer b.mu.Unlock() + return b.editPrefsLocked(actor, mp) +} + +// checkEditPrefsAccessLocked checks whether the current user has access +// to apply the changes in mp to the given prefs. +// +// It returns an error if the user is not allowed, or nil otherwise. +// +// b.mu must be held. +func (b *LocalBackend) checkEditPrefsAccessLocked(actor ipnauth.Actor, prefs ipn.PrefsView, mp *ipn.MaskedPrefs) error { + syncs.RequiresMutex(&b.mu) + var errs []error + + if mp.RunSSHSet && mp.RunSSH && !envknob.CanSSHD() { + errs = append(errs, errors.New("Tailscale SSH server administratively disabled")) + } + + // Check if the user is allowed to disconnect Tailscale. + if mp.WantRunningSet && !mp.WantRunning && b.pm.CurrentPrefs().WantRunning() { + if err := actor.CheckProfileAccess(b.pm.CurrentProfile(), ipnauth.Disconnect, b.extHost.AuditLogger()); err != nil { + errs = append(errs, err) + } + } + + // Prevent users from changing exit node preferences + // when exit node usage is managed by policy. + if mp.ExitNodeIDSet || mp.ExitNodeIPSet || mp.AutoExitNodeSet { + isManaged, err := b.polc.HasAnyOf(pkey.ExitNodeID, pkey.ExitNodeIP) + if err != nil { + err = fmt.Errorf("policy check failed: %w", err) + } else if isManaged { + // Allow users to override ExitNode policy settings and select an exit node manually + // if permitted by [pkey.AllowExitNodeOverride]. + // + // Disabling exit node usage entirely is not allowed. + allowExitNodeOverride, _ := b.polc.GetBoolean(pkey.AllowExitNodeOverride, false) + if !allowExitNodeOverride || b.changeDisablesExitNodeLocked(prefs, mp) { + err = errManagedByPolicy + } + } + if err != nil { + errs = append(errs, fmt.Errorf("exit node cannot be changed: %w", err)) + } + } + + return errors.Join(errs...) +} + +// changeDisablesExitNodeLocked reports whether applying the change +// to the given prefs would disable exit node usage. +// +// In other words, it returns true if prefs.ExitNodeID is non-empty +// initially, but would become empty after applying the given change. +// +// It applies the same adjustments and resolves the exit node in the prefs +// as done during actual edits. While not optimal performance-wise, +// changing the exit node via LocalAPI isn't a hot path, and reusing +// the same logic ensures consistency and simplifies maintenance. +// +// b.mu must be held. +func (b *LocalBackend) changeDisablesExitNodeLocked(prefs ipn.PrefsView, change *ipn.MaskedPrefs) bool { + syncs.RequiresMutex(&b.mu) + if !buildfeatures.HasUseExitNode { + return false + } + if !change.AutoExitNodeSet && !change.ExitNodeIDSet && !change.ExitNodeIPSet { + // The change does not affect exit node usage. + return false + } + + if prefs.ExitNodeID() == "" { + // Exit node usage is already disabled. + // Note that we do not check for ExitNodeIP here. + // If ExitNodeIP hasn't been resolved to a node, + // it's not enabled yet. + return false + } + + // First, apply the adjustments to a copy of the changes, + // e.g., clear AutoExitNode if ExitNodeID is set. + tmpChange := ptr.To(*change) + tmpChange.Prefs = *change.Prefs.Clone() + b.adjustEditPrefsLocked(prefs, tmpChange) + + // Then apply the adjusted changes to a copy of the current prefs, + // and resolve the exit node in the prefs. + tmpPrefs := prefs.AsStruct() + tmpPrefs.ApplyEdits(tmpChange) + b.resolveExitNodeInPrefsLocked(tmpPrefs) + + // If ExitNodeID is empty after applying the changes, + // but wasn't empty before, then the change disables + // exit node usage. + return tmpPrefs.ExitNodeID == "" +} + +// adjustEditPrefsLocked applies additional changes to mp if necessary, +// such as zeroing out mutually exclusive fields. +// +// It must not assume that the changes in mp will actually be applied. +// +// b.mu must be held. +func (b *LocalBackend) adjustEditPrefsLocked(prefs ipn.PrefsView, mp *ipn.MaskedPrefs) { + syncs.RequiresMutex(&b.mu) + // Zeroing the ExitNodeID via localAPI must also zero the prior exit node. + if mp.ExitNodeIDSet && mp.ExitNodeID == "" && !mp.InternalExitNodePriorSet { mp.InternalExitNodePrior = "" mp.InternalExitNodePriorSet = true } - // Acquire the lock before checking the profile access to prevent - // TOCTOU issues caused by the current profile changing between the - // check and the actual edit. - unlock := b.lockAndGetUnlock() - defer unlock() - if mp.WantRunningSet && !mp.WantRunning && b.pm.CurrentPrefs().WantRunning() { - if err := actor.CheckProfileAccess(b.pm.CurrentProfile(), ipnauth.Disconnect, b.getAuditLoggerLocked()); err != nil { - b.logf("check profile access failed: %v", err) - return ipn.PrefsView{}, err - } + // Clear ExitNodeID if AutoExitNode is disabled and ExitNodeID is still unresolved. + if mp.AutoExitNodeSet && mp.AutoExitNode == "" && prefs.ExitNodeID() == unresolvedExitNodeID { + mp.ExitNodeIDSet = true + mp.ExitNodeID = "" + } - // If a user has enough rights to disconnect, such as when [syspolicy.AlwaysOn] - // is disabled, or [syspolicy.AlwaysOnOverrideWithReason] is also set and the user + // Disable automatic exit node selection if the user explicitly sets + // ExitNodeID or ExitNodeIP. + if (mp.ExitNodeIDSet || mp.ExitNodeIPSet) && !mp.AutoExitNodeSet { + mp.AutoExitNodeSet = true + mp.AutoExitNode = "" + } +} + +// onEditPrefsLocked is called when prefs are edited (typically, via LocalAPI), +// just before the changes in newPrefs are set for the current profile. +// +// The changes in mp have been allowed, but the resulting [ipn.Prefs] +// have not yet been applied and may be subject to reconciliation +// by [LocalBackend.reconcilePrefsLocked], either before or after being set. +// +// This method handles preference edits, typically initiated by the user, +// as opposed to reconfiguring the backend when the final prefs are set. +// +// b.mu must be held; mp must not be mutated by this method. +func (b *LocalBackend) onEditPrefsLocked(_ ipnauth.Actor, mp *ipn.MaskedPrefs, oldPrefs, newPrefs ipn.PrefsView) { + if mp.WantRunningSet && !mp.WantRunning && oldPrefs.WantRunning() { + // If a user has enough rights to disconnect, such as when [pkey.AlwaysOn] + // is disabled, or [pkey.AlwaysOnOverrideWithReason] is also set and the user // provides a reason for disconnecting, then we should not force the "always on" // mode on them until the policy changes, they switch to a different profile, etc. b.overrideAlwaysOn = true - if reconnectAfter, _ := syspolicy.GetDuration(syspolicy.ReconnectAfter, 0); reconnectAfter > 0 { + if reconnectAfter, _ := b.polc.GetDuration(pkey.ReconnectAfter, 0); reconnectAfter > 0 { b.startReconnectTimerLocked(reconnectAfter) } } - return b.editPrefsLockedOnEntry(mp, unlock) + if oldPrefs.WantRunning() != newPrefs.WantRunning() { + // Connecting to or disconnecting from Tailscale clears the override, + // unless the user is also explicitly changing the exit node (see below). + b.overrideExitNodePolicy = false + } + if mp.AutoExitNodeSet || mp.ExitNodeIDSet || mp.ExitNodeIPSet { + if allowExitNodeOverride, _ := b.polc.GetBoolean(pkey.AllowExitNodeOverride, false); allowExitNodeOverride { + // If applying exit node policy settings to the new prefs results in no change, + // the user is not overriding the policy. Otherwise, it is an override. + b.overrideExitNodePolicy = b.applyExitNodeSysPolicyLocked(newPrefs.AsStruct()) + } else { + // Overrides are not allowed; clear the override flag. + b.overrideExitNodePolicy = false + } + } + + // This is recorded here in the EditPrefs path, not the setPrefs path on purpose. + // recordForEdit records metrics related to edits and changes, not the final state. + // If, in the future, we want to record gauge-metrics related to the state of prefs, + // that should be done in the setPrefs path. + e := prefsMetricsEditEvent{ + change: mp, + pNew: newPrefs, + pOld: oldPrefs, + node: b.currentNode(), + lastSuggestedExitNode: b.lastSuggestedExitNode, + } + e.record() } // startReconnectTimerLocked sets a timer to automatically set WantRunning to true // after the specified duration. func (b *LocalBackend) startReconnectTimerLocked(d time.Duration) { + syncs.RequiresMutex(&b.mu) if b.reconnectTimer != nil { // Stop may return false if the timer has already fired, // and the function has been called in its own goroutine, @@ -4376,8 +4527,8 @@ func (b *LocalBackend) startReconnectTimerLocked(d time.Duration) { profileID := b.pm.CurrentProfile().ID() var reconnectTimer tstime.TimerController reconnectTimer = b.clock.AfterFunc(d, func() { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() if b.reconnectTimer != reconnectTimer { // We're either not the most recent timer, or we lost the race when @@ -4395,7 +4546,7 @@ func (b *LocalBackend) startReconnectTimerLocked(d time.Duration) { } mp := &ipn.MaskedPrefs{WantRunningSet: true, Prefs: ipn.Prefs{WantRunning: true}} - if _, err := b.editPrefsLockedOnEntry(mp, unlock); err != nil { + if _, err := b.editPrefsLocked(ipnauth.Self, mp); err != nil { b.logf("failed to automatically reconnect as %q after %v: %v", cp.Name(), d, err) } else { b.logf("automatically reconnected as %q after %v", cp.Name(), d) @@ -4406,11 +4557,13 @@ func (b *LocalBackend) startReconnectTimerLocked(d time.Duration) { } func (b *LocalBackend) resetAlwaysOnOverrideLocked() { + syncs.RequiresMutex(&b.mu) b.overrideAlwaysOn = false b.stopReconnectTimerLocked() } func (b *LocalBackend) stopReconnectTimerLocked() { + syncs.RequiresMutex(&b.mu) if b.reconnectTimer != nil { // Stop may return false if the timer has already fired, // and the function has been called in its own goroutine, @@ -4424,36 +4577,50 @@ func (b *LocalBackend) stopReconnectTimerLocked() { } } -// Warning: b.mu must be held on entry, but it unlocks it on the way out. -// TODO(bradfitz): redo the locking on all these weird methods like this. -func (b *LocalBackend) editPrefsLockedOnEntry(mp *ipn.MaskedPrefs, unlock unlockOnce) (ipn.PrefsView, error) { - defer unlock() // for error paths +// b.mu must be held. +func (b *LocalBackend) editPrefsLocked(actor ipnauth.Actor, mp *ipn.MaskedPrefs) (ipn.PrefsView, error) { + syncs.RequiresMutex(&b.mu) + p0 := b.pm.CurrentPrefs() + + // Check if the changes in mp are allowed. + if err := b.checkEditPrefsAccessLocked(actor, p0, mp); err != nil { + b.logf("EditPrefs(%v): %v", mp.Pretty(), err) + return ipn.PrefsView{}, err + } + + // Apply additional changes to mp if necessary, + // such as clearing mutually exclusive fields. + b.adjustEditPrefsLocked(p0, mp) if mp.EggSet { mp.EggSet = false b.egg = true b.goTracker.Go(b.doSetHostinfoFilterServices) } - p0 := b.pm.CurrentPrefs() + p1 := b.pm.CurrentPrefs().AsStruct() p1.ApplyEdits(mp) + if err := b.checkPrefsLocked(p1); err != nil { b.logf("EditPrefs check error: %v", err) return ipn.PrefsView{}, err } - if p1.RunSSH && !envknob.CanSSHD() { - b.logf("EditPrefs requests SSH, but disabled by envknob; returning error") - return ipn.PrefsView{}, errors.New("Tailscale SSH server administratively disabled.") - } + if p1.View().Equals(p0) { return stripKeysFromPrefs(p0), nil } + b.logf("EditPrefs: %v", mp.Pretty()) - newPrefs := b.setPrefsLockedOnEntry(p1, unlock) + + // Perform any actions required when prefs are edited (typically by a user), + // before the modified prefs are actually set for the current profile. + b.onEditPrefsLocked(actor, mp, p0, p1.View()) + + newPrefs := b.setPrefsLocked(p1) // Note: don't perform any actions for the new prefs here. Not // every prefs change goes through EditPrefs. Put your actions - // in setPrefsLocksOnEntry instead. + // in setPrefsLocked instead. // This should return the public prefs, not the private ones. return stripKeysFromPrefs(newPrefs), nil @@ -4476,51 +4643,24 @@ func (b *LocalBackend) checkProfileNameLocked(p *ipn.Prefs) error { return nil } -// wantIngressLocked reports whether this node has ingress configured. This bool -// is sent to the coordination server (in Hostinfo.WireIngress) as an -// optimization hint to know primarily which nodes are NOT using ingress, to -// avoid doing work for regular nodes. -// -// Even if the user's ServeConfig.AllowFunnel map was manually edited in raw -// mode and contains map entries with false values, sending true (from Len > 0) -// is still fine. This is only an optimization hint for the control plane and -// doesn't affect security or correctness. And we also don't expect people to -// modify their ServeConfig in raw mode. -func (b *LocalBackend) wantIngressLocked() bool { - return b.serveConfig.Valid() && b.serveConfig.HasAllowFunnel() -} - -// hasIngressEnabledLocked reports whether the node has any funnel endpoint enabled. This bool is sent to control (in -// Hostinfo.IngressEnabled) to determine whether 'Funnel' badge should be displayed on this node in the admin panel. -func (b *LocalBackend) hasIngressEnabledLocked() bool { - return b.serveConfig.Valid() && b.serveConfig.IsFunnelOn() -} - -// shouldWireInactiveIngressLocked reports whether the node is in a state where funnel is not actively enabled, but it -// seems that it is intended to be used with funnel. -func (b *LocalBackend) shouldWireInactiveIngressLocked() bool { - return b.serveConfig.Valid() && !b.hasIngressEnabledLocked() && b.wantIngressLocked() -} - -// setPrefsLockedOnEntry requires b.mu be held to call it, but it -// unlocks b.mu when done. newp ownership passes to this function. +// setPrefsLocked requires b.mu be held to call it. +// newp ownership passes to this function. // It returns a read-only copy of the new prefs. -func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce) ipn.PrefsView { - defer unlock() - - netMap := b.netMap +func (b *LocalBackend) setPrefsLocked(newp *ipn.Prefs) ipn.PrefsView { + cn := b.currentNode() + netMap := cn.NetMap() b.setAtomicValuesFromPrefsLocked(newp.View()) oldp := b.pm.CurrentPrefs() if oldp.Valid() { newp.Persist = oldp.Persist().AsStruct() // caller isn't allowed to override this } - // applySysPolicy returns whether it updated newp, - // but everything in this function treats b.prefs as completely new + // Apply reconciliation to the prefs, such as policy overrides, + // exit node resolution, and so on. The call returns whether it updated + // newp, but everything in this function treats newp as completely new // anyway, so its return value can be ignored here. - applySysPolicy(newp, b.lastSuggestedExitNode, b.overrideAlwaysOn) - // setExitNodeID does likewise. No-op if no exit node resolution is needed. - setExitNodeID(newp, netMap) + b.reconcilePrefsLocked(newp) + // We do this to avoid holding the lock while doing everything else. oldHi := b.hostinfo @@ -4533,9 +4673,9 @@ func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce) hostInfoChanged := !oldHi.Equal(newHi) cc := b.cc - b.updateFilterLocked(netMap, newp.View()) + b.updateFilterLocked(newp.View()) - if oldp.ShouldSSHBeRunning() && !newp.ShouldSSHBeRunning() { + if buildfeatures.HasSSH && oldp.ShouldSSHBeRunning() && !newp.ShouldSSHBeRunning() { if b.sshServer != nil { b.goTracker.Go(b.sshServer.Shutdown) b.sshServer = nil @@ -4557,13 +4697,7 @@ func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce) } prefs := newp.View() - np := b.pm.CurrentProfile().NetworkProfile() - if netMap != nil { - np = ipn.NetworkProfile{ - MagicDNSName: b.netMap.MagicDNSSuffix(), - DomainName: b.netMap.DomainName(), - } - } + np := cmp.Or(cn.NetworkProfile(), b.pm.CurrentProfile().NetworkProfile()) if err := b.pm.SetPrefs(prefs, np); err != nil { b.logf("failed to save new controlclient state: %v", err) } else if prefs.WantRunning() { @@ -4573,18 +4707,11 @@ func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce) b.resetAlwaysOnOverrideLocked() } - if newp.AutoUpdate.Apply.EqualBool(true) { - if b.state != ipn.Running { - b.maybeStartOfflineAutoUpdate(newp.View()) - } - } else { - b.stopOfflineAutoUpdate() - } - - unlock.UnlockEarly() + b.pauseOrResumeControlClientLocked() // for prefs.Sync changes + b.updateWarnSync(prefs) if oldp.ShieldsUp() != newp.ShieldsUp || hostInfoChanged { - b.doSetHostinfoFilterServices() + b.doSetHostinfoFilterServicesLocked() } if netMap != nil { @@ -4597,26 +4724,23 @@ func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce) } if oldp.WantRunning() != newp.WantRunning { - b.stateMachine() + b.stateMachineLocked() } else { - b.authReconfig() + b.authReconfigLocked() } - b.send(ipn.Notify{Prefs: &prefs}) + b.sendLocked(ipn.Notify{Prefs: &prefs}) return prefs } // GetPeerAPIPort returns the port number for the peerapi server // running on the provided IP. func (b *LocalBackend) GetPeerAPIPort(ip netip.Addr) (port uint16, ok bool) { - b.mu.Lock() - defer b.mu.Unlock() - for _, pln := range b.peerAPIListeners { - if pln.ip == ip { - return uint16(pln.port), true - } + if !buildfeatures.HasPeerAPIServer { + return 0, false } - return 0, false + portInt, ok := b.peerAPIPorts.Load()[ip] + return uint16(portInt), ok } // handlePeerAPIConn serves an already-accepted connection c. @@ -4650,62 +4774,15 @@ var ( magicDNSIPv6 = tsaddr.TailscaleServiceIPv6() ) -// TCPHandlerForDst returns a TCP handler for connections to dst, or nil if -// no handler is needed. It also returns a list of TCP socket options to -// apply to the socket before calling the handler. -// TCPHandlerForDst is called both for connections to our node's local IP -// as well as to the service IP (quad 100). -func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c net.Conn) error, opts []tcpip.SettableSocketOption) { - // First handle internal connections to the service IP - hittingServiceIP := dst.Addr() == magicDNSIP || dst.Addr() == magicDNSIPv6 - if hittingServiceIP { - switch dst.Port() { - case 80: - // TODO(mpminardi): do we want to show an error message if the web client - // has been disabled instead of the more "basic" web UI? - if b.ShouldRunWebClient() { - return b.handleWebClientConn, opts - } - return b.HandleQuad100Port80Conn, opts - case DriveLocalPort: - return b.handleDriveConn, opts - } - } +// Hook exclusively for serve. +var ( + hookServeTCPHandlerForVIPService feature.Hook[func(b *LocalBackend, dst netip.AddrPort, src netip.AddrPort) (handler func(c net.Conn) error)] + hookTCPHandlerForServe feature.Hook[func(b *LocalBackend, dport uint16, srcAddr netip.AddrPort, f *funnelFlow) (handler func(net.Conn) error)] + hookServeUpdateServeTCPPortNetMapAddrListenersLocked feature.Hook[func(b *LocalBackend, ports []uint16)] - // TODO(tailscale/corp#26001): Get handler for VIP services and Local IPs using - // the same function. - if handler := b.tcpHandlerForVIPService(dst, src); handler != nil { - return handler, opts - } - // Then handle external connections to the local IP. - if !b.isLocalIP(dst.Addr()) { - return nil, nil - } - if dst.Port() == 22 && b.ShouldRunSSH() { - // Use a higher keepalive idle time for SSH connections, as they are - // typically long lived and idle connections are more likely to be - // intentional. Ideally we would turn this off entirely, but we can't - // tell the difference between a long lived connection that is idle - // vs a connection that is dead because the peer has gone away. - // We pick 72h as that is typically sufficient for a long weekend. - opts = append(opts, ptr.To(tcpip.KeepaliveIdleOption(72*time.Hour))) - return b.handleSSHConn, opts - } - // TODO(will,sonia): allow customizing web client port ? - if dst.Port() == webClientPort && b.ShouldExposeRemoteWebClient() { - return b.handleWebClientConn, opts - } - if port, ok := b.GetPeerAPIPort(dst.Addr()); ok && dst.Port() == port { - return func(c net.Conn) error { - b.handlePeerAPIConn(src, dst, c) - return nil - }, opts - } - if handler := b.tcpHandlerForServe(dst.Port(), src, nil); handler != nil { - return handler, opts - } - return nil, nil -} + hookServeSetTCPPortsInterceptedFromNetmapAndPrefsLocked feature.Hook[func(b *LocalBackend, prefs ipn.PrefsView) (handlePorts []uint16)] + hookServeClearVIPServicesTCPPortsInterceptedLocked feature.Hook[func(*LocalBackend)] +) func (b *LocalBackend) handleDriveConn(conn net.Conn) error { fs, ok := b.sys.DriveForLocal.GetOK() @@ -4739,15 +4816,38 @@ func (b *LocalBackend) peerAPIServicesLocked() (ret []tailcfg.Service) { return ret } +// PortlistServices is an eventbus topic for the portlist extension +// to advertise the running services on the host. +type PortlistServices []tailcfg.Service + +func (b *LocalBackend) setPortlistServices(sl []tailcfg.Service) { + if !buildfeatures.HasPortList { // redundant, but explicit for linker deadcode and humans + return + } + + b.mu.Lock() + if b.hostinfo == nil { + b.hostinfo = new(tailcfg.Hostinfo) + } + b.hostinfo.Services = sl + b.mu.Unlock() + + b.doSetHostinfoFilterServices() +} + // doSetHostinfoFilterServices calls SetHostinfo on the controlclient, // possibly after mangling the given hostinfo. // // TODO(danderson): we shouldn't be mangling hostinfo here after // painstakingly constructing it in twelvety other places. func (b *LocalBackend) doSetHostinfoFilterServices() { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() + b.doSetHostinfoFilterServicesLocked() +} +// b.mu must be held +func (b *LocalBackend) doSetHostinfoFilterServicesLocked() { cc := b.cc if cc == nil { // Control client isn't up yet. @@ -4757,6 +4857,17 @@ func (b *LocalBackend) doSetHostinfoFilterServices() { b.logf("[unexpected] doSetHostinfoFilterServices with nil hostinfo") return } + + hi := b.hostInfoWithServicesLocked() + + cc.SetHostinfo(hi) +} + +// hostInfoWithServicesLocked returns a shallow clone of b.hostinfo with +// services added. +// +// b.mu must be held. +func (b *LocalBackend) hostInfoWithServicesLocked() *tailcfg.Hostinfo { peerAPIServices := b.peerAPIServicesLocked() if b.egg { peerAPIServices = append(peerAPIServices, tailcfg.Service{Proto: "egg", Port: 1}) @@ -4764,27 +4875,50 @@ func (b *LocalBackend) doSetHostinfoFilterServices() { // TODO(maisem,bradfitz): store hostinfo as a view, not as a mutable struct. hi := *b.hostinfo // shallow copy - unlock.UnlockEarly() // Make a shallow copy of hostinfo so we can mutate // at the Service field. - if !b.shouldUploadServices() { + if f, ok := b.extHost.Hooks().ShouldUploadServices.GetOk(); !ok || !f() { hi.Services = []tailcfg.Service{} } + // Don't mutate hi.Service's underlying array. Append to // the slice with no free capacity. c := len(hi.Services) hi.Services = append(hi.Services[:c:c], peerAPIServices...) hi.PushDeviceToken = b.pushDeviceToken.Load() - cc.SetHostinfo(&hi) + + // Compare the expected ports from peerAPIServices to the actual ports in hi.Services. + expectedPorts := extractPeerAPIPorts(peerAPIServices) + actualPorts := extractPeerAPIPorts(hi.Services) + if expectedPorts != actualPorts { + b.logf("Hostinfo peerAPI ports changed: expected %v, got %v", expectedPorts, actualPorts) + } + + return &hi +} + +type portPair struct { + v4, v6 uint16 +} + +func extractPeerAPIPorts(services []tailcfg.Service) portPair { + var p portPair + for _, s := range services { + switch s.Proto { + case "peerapi4": + p.v4 = s.Port + case "peerapi6": + p.v6 = s.Port + } + } + return p } // NetMap returns the latest cached network map received from // controlclient, or nil if no network map was received yet. func (b *LocalBackend) NetMap() *netmap.NetworkMap { - b.mu.Lock() - defer b.mu.Unlock() - return b.netMap + return b.currentNode().NetMap() } func (b *LocalBackend) isEngineBlocked() bool { @@ -4793,21 +4927,24 @@ func (b *LocalBackend) isEngineBlocked() bool { return b.blocked } -// blockEngineUpdate sets b.blocked to block, while holding b.mu. Its -// indirect effect is to turn b.authReconfig() into a no-op if block -// is true. -func (b *LocalBackend) blockEngineUpdates(block bool) { +// blockEngineUpdatesLocked sets b.blocked to block. +// +// Its indirect effect is to turn b.authReconfig() into a no-op if block is +// true. +// +// b.mu must be held. +func (b *LocalBackend) blockEngineUpdatesLocked(block bool) { b.logf("blockEngineUpdates(%v)", block) - - b.mu.Lock() b.blocked = block - b.mu.Unlock() } // reconfigAppConnectorLocked updates the app connector state based on the // current network map and preferences. // b.mu must be held. func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs ipn.PrefsView) { + if !buildfeatures.HasAppConnectors { + return + } const appConnectorCapName = "tailscale.com/app-connectors" defer func() { if b.hostinfo != nil { @@ -4815,27 +4952,28 @@ func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs i } }() + // App connectors have been disabled. if !prefs.AppConnector().Advertise { + b.appConnector.Close() // clean up a previous connector (safe on nil) b.appConnector = nil return } - shouldAppCStoreRoutes := b.ControlKnobs().AppCStoreRoutes.Load() - if b.appConnector == nil || b.appConnector.ShouldStoreRoutes() != shouldAppCStoreRoutes { - var ri *appc.RouteInfo - var storeFunc func(*appc.RouteInfo) error - if shouldAppCStoreRoutes { - var err error - ri, err = b.readRouteInfoLocked() - if err != nil { - ri = &appc.RouteInfo{} - if err != ipn.ErrStateNotExist { - b.logf("Unsuccessful Read RouteInfo: ", err) - } - } - storeFunc = b.storeRouteInfo + // We don't (yet) have an app connector configured, or the configured + // connector has a different route persistence setting. + shouldStoreRoutes := b.ControlKnobs().AppCStoreRoutes.Load() + if b.appConnector == nil || (shouldStoreRoutes != b.appConnector.ShouldStoreRoutes()) { + ri, err := b.readRouteInfoLocked() + if err != nil && err != ipn.ErrStateNotExist { + b.logf("Unsuccessful Read RouteInfo: %v", err) } - b.appConnector = appc.NewAppConnector(b.logf, b, ri, storeFunc) + b.appConnector.Close() // clean up a previous connector (safe on nil) + b.appConnector = appc.NewAppConnector(appc.Config{ + Logf: b.logf, + EventBus: b.sys.Bus.Get(), + RouteInfo: ri, + HasStoredRoutes: shouldStoreRoutes, + }) } if nm == nil { return @@ -4878,9 +5016,7 @@ func (b *LocalBackend) readvertiseAppConnectorRoutes() { // // Grab a copy of the field, since b.mu only guards access to the // b.appConnector field itself. - b.mu.Lock() - appConnector := b.appConnector - b.mu.Unlock() + appConnector := b.AppConnector() if appConnector == nil { return @@ -4911,32 +5047,40 @@ func (b *LocalBackend) readvertiseAppConnectorRoutes() { // user prefs. func (b *LocalBackend) authReconfig() { b.mu.Lock() - blocked := b.blocked - prefs := b.pm.CurrentPrefs() - nm := b.netMap - hasPAC := b.prevIfState.HasPAC() - disableSubnetsIfPAC := nm.HasCap(tailcfg.NodeAttrDisableSubnetsIfPAC) - userDialUseRoutes := nm.HasCap(tailcfg.NodeAttrUserDialUseRoutes) - dohURL, dohURLOK := exitNodeCanProxyDNS(nm, b.peers, prefs.ExitNodeID()) - dcfg := dnsConfigForNetmap(nm, b.peers, prefs, b.keyExpired, b.logf, version.OS()) - // If the current node is an app connector, ensure the app connector machine is started - b.reconfigAppConnectorLocked(nm, prefs) - closing := b.shutdownCalled - b.mu.Unlock() + defer b.mu.Unlock() + b.authReconfigLocked() +} - if closing { +// authReconfigLocked is the locked version of [LocalBackend.authReconfig]. +// +// b.mu must be held. +func (b *LocalBackend) authReconfigLocked() { + + if b.shutdownCalled { b.logf("[v1] authReconfig: skipping because in shutdown") return } - - if blocked { + if b.blocked { b.logf("[v1] authReconfig: blocked, skipping.") return } + + cn := b.currentNode() + + nm := cn.NetMap() if nm == nil { b.logf("[v1] authReconfig: netmap not yet valid. Skipping.") return } + + prefs := b.pm.CurrentPrefs() + hasPAC := b.interfaceState.HasPAC() + disableSubnetsIfPAC := cn.SelfHasCap(tailcfg.NodeAttrDisableSubnetsIfPAC) + dohURL, dohURLOK := cn.exitNodeCanProxyDNS(prefs.ExitNodeID()) + dcfg := cn.dnsConfigForNetmap(prefs, b.keyExpired, version.OS()) + // If the current node is an app connector, ensure the app connector machine is started + b.reconfigAppConnectorLocked(nm, prefs) + if !prefs.WantRunning() { b.logf("[v1] authReconfig: skipping because !WantRunning.") return @@ -4956,20 +5100,27 @@ func (b *LocalBackend) authReconfig() { // Keep the dialer updated about whether we're supposed to use // an exit node's DNS server (so SOCKS5/HTTP outgoing dials // can use it for name resolution) - if dohURLOK { - b.dialer.SetExitDNSDoH(dohURL) - } else { - b.dialer.SetExitDNSDoH("") + if buildfeatures.HasUseExitNode { + if dohURLOK { + b.dialer.SetExitDNSDoH(dohURL) + } else { + b.dialer.SetExitDNSDoH("") + } } - cfg, err := nmcfg.WGCfg(nm, b.logf, flags, prefs.ExitNodeID()) + priv := b.pm.CurrentPrefs().Persist().PrivateNodeKey() + if !priv.IsZero() && priv.Public() != nm.NodeKey { + priv = key.NodePrivate{} + } + + cfg, err := nmcfg.WGCfg(priv, nm, b.logf, flags, prefs.ExitNodeID()) if err != nil { b.logf("wgcfg: %v", err) return } oneCGNATRoute := shouldUseOneCGNATRoute(b.logf, b.sys.NetMon.Get(), b.sys.ControlKnobs(), version.OS()) - rcfg := b.routerConfig(cfg, prefs, oneCGNATRoute) + rcfg := b.routerConfigLocked(cfg, prefs, oneCGNATRoute) err = b.e.Reconfig(cfg, rcfg, dcfg) if err == wgengine.ErrNoChanges { @@ -4977,14 +5128,10 @@ func (b *LocalBackend) authReconfig() { } b.logf("[v1] authReconfig: ra=%v dns=%v 0x%02x: %v", prefs.RouteAll(), prefs.CorpDNS(), flags, err) - if userDialUseRoutes { - b.dialer.SetRoutes(rcfg.Routes, rcfg.LocalRoutes) - } else { - b.dialer.SetRoutes(nil, nil) + b.initPeerAPIListenerLocked() + if buildfeatures.HasAppConnectors { + go b.goTracker.Go(b.readvertiseAppConnectorRoutes) } - - b.initPeerAPIListener() - b.readvertiseAppConnectorRoutes() } // shouldUseOneCGNATRoute reports whether we should prefer to make one big @@ -5001,6 +5148,11 @@ func shouldUseOneCGNATRoute(logf logger.Logf, mon *netmon.Monitor, controlKnobs } } + if versionOS == "plan9" { + // Just temporarily during plan9 bringup to have fewer routes to debug. + return true + } + // Also prefer to do this on the Mac, so that we don't need to constantly // update the network extension configuration (which is disruptive to // Chrome, see https://github.com/tailscale/tailscale/issues/3102). Only @@ -5020,193 +5172,6 @@ func shouldUseOneCGNATRoute(logf logger.Logf, mon *netmon.Monitor, controlKnobs return false } -// dnsConfigForNetmap returns a *dns.Config for the given netmap, -// prefs, client OS version, and cloud hosting environment. -// -// The versionOS is a Tailscale-style version ("iOS", "macOS") and not -// a runtime.GOOS. -func dnsConfigForNetmap(nm *netmap.NetworkMap, peers map[tailcfg.NodeID]tailcfg.NodeView, prefs ipn.PrefsView, selfExpired bool, logf logger.Logf, versionOS string) *dns.Config { - if nm == nil { - return nil - } - - // If the current node's key is expired, then we don't program any DNS - // configuration into the operating system. This ensures that if the - // DNS configuration specifies a DNS server that is only reachable over - // Tailscale, we don't break connectivity for the user. - // - // TODO(andrew-d): this also stops returning anything from quad-100; we - // could do the same thing as having "CorpDNS: false" and keep that but - // not program the OS? - if selfExpired { - return &dns.Config{} - } - - dcfg := &dns.Config{ - Routes: map[dnsname.FQDN][]*dnstype.Resolver{}, - Hosts: map[dnsname.FQDN][]netip.Addr{}, - } - - // selfV6Only is whether we only have IPv6 addresses ourselves. - selfV6Only := nm.GetAddresses().ContainsFunc(tsaddr.PrefixIs6) && - !nm.GetAddresses().ContainsFunc(tsaddr.PrefixIs4) - dcfg.OnlyIPv6 = selfV6Only - - // Populate MagicDNS records. We do this unconditionally so that - // quad-100 can always respond to MagicDNS queries, even if the OS - // isn't configured to make MagicDNS resolution truly - // magic. Details in - // https://github.com/tailscale/tailscale/issues/1886. - set := func(name string, addrs views.Slice[netip.Prefix]) { - if addrs.Len() == 0 || name == "" { - return - } - fqdn, err := dnsname.ToFQDN(name) - if err != nil { - return // TODO: propagate error? - } - var have4 bool - for _, addr := range addrs.All() { - if addr.Addr().Is4() { - have4 = true - break - } - } - var ips []netip.Addr - for _, addr := range addrs.All() { - if selfV6Only { - if addr.Addr().Is6() { - ips = append(ips, addr.Addr()) - } - continue - } - // If this node has an IPv4 address, then - // remove peers' IPv6 addresses for now, as we - // don't guarantee that the peer node actually - // can speak IPv6 correctly. - // - // https://github.com/tailscale/tailscale/issues/1152 - // tracks adding the right capability reporting to - // enable AAAA in MagicDNS. - if addr.Addr().Is6() && have4 { - continue - } - ips = append(ips, addr.Addr()) - } - dcfg.Hosts[fqdn] = ips - } - set(nm.Name, nm.GetAddresses()) - for _, peer := range peers { - set(peer.Name(), peer.Addresses()) - } - for _, rec := range nm.DNS.ExtraRecords { - switch rec.Type { - case "", "A", "AAAA": - // Treat these all the same for now: infer from the value - default: - // TODO: more - continue - } - ip, err := netip.ParseAddr(rec.Value) - if err != nil { - // Ignore. - continue - } - fqdn, err := dnsname.ToFQDN(rec.Name) - if err != nil { - continue - } - dcfg.Hosts[fqdn] = append(dcfg.Hosts[fqdn], ip) - } - - if !prefs.CorpDNS() { - return dcfg - } - - for _, dom := range nm.DNS.Domains { - fqdn, err := dnsname.ToFQDN(dom) - if err != nil { - logf("[unexpected] non-FQDN search domain %q", dom) - } - dcfg.SearchDomains = append(dcfg.SearchDomains, fqdn) - } - if nm.DNS.Proxied { // actually means "enable MagicDNS" - for _, dom := range magicDNSRootDomains(nm) { - dcfg.Routes[dom] = nil // resolve internally with dcfg.Hosts - } - } - - addDefault := func(resolvers []*dnstype.Resolver) { - dcfg.DefaultResolvers = append(dcfg.DefaultResolvers, resolvers...) - } - - // If we're using an exit node and that exit node is new enough (1.19.x+) - // to run a DoH DNS proxy, then send all our DNS traffic through it. - if dohURL, ok := exitNodeCanProxyDNS(nm, peers, prefs.ExitNodeID()); ok { - addDefault([]*dnstype.Resolver{{Addr: dohURL}}) - return dcfg - } - - // If the user has set default resolvers ("override local DNS"), prefer to - // use those resolvers as the default, otherwise if there are WireGuard exit - // node resolvers, use those as the default. - if len(nm.DNS.Resolvers) > 0 { - addDefault(nm.DNS.Resolvers) - } else { - if resolvers, ok := wireguardExitNodeDNSResolvers(nm, peers, prefs.ExitNodeID()); ok { - addDefault(resolvers) - } - } - - for suffix, resolvers := range nm.DNS.Routes { - fqdn, err := dnsname.ToFQDN(suffix) - if err != nil { - logf("[unexpected] non-FQDN route suffix %q", suffix) - } - - // Create map entry even if len(resolvers) == 0; Issue 2706. - // This lets the control plane send ExtraRecords for which we - // can authoritatively answer "name not exists" for when the - // control plane also sends this explicit but empty route - // making it as something we handle. - // - // While we're already populating it, might as well size the - // slice appropriately. - // Per #9498 the exact requirements of nil vs empty slice remain - // unclear, this is a haunted graveyard to be resolved. - dcfg.Routes[fqdn] = make([]*dnstype.Resolver, 0, len(resolvers)) - dcfg.Routes[fqdn] = append(dcfg.Routes[fqdn], resolvers...) - } - - // Set FallbackResolvers as the default resolvers in the - // scenarios that can't handle a purely split-DNS config. See - // https://github.com/tailscale/tailscale/issues/1743 for - // details. - switch { - case len(dcfg.DefaultResolvers) != 0: - // Default resolvers already set. - case !prefs.ExitNodeID().IsZero(): - // When using an exit node, we send all DNS traffic to the exit node, so - // we don't need a fallback resolver. - // - // However, if the exit node is too old to run a DoH DNS proxy, then we - // need to use a fallback resolver as it's very likely the LAN resolvers - // will become unreachable. - // - // This is especially important on Apple OSes, where - // adding the default route to the tunnel interface makes - // it "primary", and we MUST provide VPN-sourced DNS - // settings or we break all DNS resolution. - // - // https://github.com/tailscale/tailscale/issues/1713 - addDefault(nm.DNS.FallbackResolvers) - case len(dcfg.Routes) == 0: - // No settings requiring split DNS, no problem. - } - - return dcfg -} - // SetTCPHandlerForFunnelFlow sets the TCP handler for Funnel flows. // It should only be called before the LocalBackend is used. func (b *LocalBackend) SetTCPHandlerForFunnelFlow(h func(src netip.AddrPort, dstPort uint16) (handler func(net.Conn))) { @@ -5225,6 +5190,9 @@ func (b *LocalBackend) SetVarRoot(dir string) { // // It should only be called before the LocalBackend is used. func (b *LocalBackend) SetLogFlusher(flushFunc func()) { + if !buildfeatures.HasLogTail { + return + } b.logFlushFunc = flushFunc } @@ -5233,7 +5201,7 @@ func (b *LocalBackend) SetLogFlusher(flushFunc func()) { // // TryFlushLogs should not block. func (b *LocalBackend) TryFlushLogs() bool { - if b.logFlushFunc == nil { + if !buildfeatures.HasLogTail || b.logFlushFunc == nil { return false } b.logFlushFunc() @@ -5260,26 +5228,6 @@ func (b *LocalBackend) TailscaleVarRoot() string { return "" } -func (b *LocalBackend) fileRootLocked(uid tailcfg.UserID) string { - if v := b.directFileRoot; v != "" { - return v - } - varRoot := b.TailscaleVarRoot() - if varRoot == "" { - b.logf("Taildrop disabled; no state directory") - return "" - } - baseDir := fmt.Sprintf("%s-uid-%d", - strings.ReplaceAll(b.activeLogin, "@", "-"), - uid) - dir := filepath.Join(varRoot, "files", baseDir) - if err := os.MkdirAll(dir, 0700); err != nil { - b.logf("Taildrop disabled; error making directory: %v", err) - return "" - } - return dir -} - // closePeerAPIListenersLocked closes any existing PeerAPI listeners // and clears out the PeerAPI server state. // @@ -5287,11 +5235,15 @@ func (b *LocalBackend) fileRootLocked(uid tailcfg.UserID) string { // // b.mu must be held. func (b *LocalBackend) closePeerAPIListenersLocked() { + if !buildfeatures.HasPeerAPIServer { + return + } b.peerAPIServer = nil for _, pln := range b.peerAPIListeners { pln.Close() } b.peerAPIListeners = nil + b.peerAPIPorts.Store(nil) } // peerAPIListenAsync is whether the operating system requires that we @@ -5304,20 +5256,34 @@ const peerAPIListenAsync = runtime.GOOS == "windows" || runtime.GOOS == "android func (b *LocalBackend) initPeerAPIListener() { b.mu.Lock() defer b.mu.Unlock() + b.initPeerAPIListenerLocked() +} + +// b.mu must be held. +func (b *LocalBackend) initPeerAPIListenerLocked() { + if !buildfeatures.HasPeerAPIServer { + return + } + b.logf("[v1] initPeerAPIListener: entered") + if b.shutdownCalled { + b.logf("[v1] initPeerAPIListener: shutting down") return } - if b.netMap == nil { + cn := b.currentNode() + nm := cn.NetMap() + if nm == nil { // We're called from authReconfig which checks that // netMap is non-nil, but if a concurrent Logout, // ResetForClientDisconnect, or Start happens when its // mutex was released, the netMap could be // nil'ed out (Issue 1996). Bail out early here if so. + b.logf("[v1] initPeerAPIListener: no netmap") return } - addrs := b.netMap.GetAddresses() + addrs := nm.GetAddresses() if addrs.Len() == len(b.peerAPIListeners) { allSame := true for i, pln := range b.peerAPIListeners { @@ -5328,32 +5294,24 @@ func (b *LocalBackend) initPeerAPIListener() { } if allSame { // Nothing to do. + b.logf("[v1] initPeerAPIListener: %d netmap addresses match existing listeners", addrs.Len()) + // TODO(zofrex): This is fragile. It doesn't check what's actually in hostinfo, and if + // peerAPIListeners gets out of sync with hostinfo.Services, we won't get back into a good + // state. E.G. see tailscale/corp#27173. return } } b.closePeerAPIListenersLocked() - selfNode := b.netMap.SelfNode - if !selfNode.Valid() || b.netMap.GetAddresses().Len() == 0 { + selfNode := nm.SelfNode + if !selfNode.Valid() || nm.GetAddresses().Len() == 0 { + b.logf("[v1] initPeerAPIListener: no addresses in netmap") return } - fileRoot := b.fileRootLocked(selfNode.User()) - if fileRoot == "" { - b.logf("peerapi starting without Taildrop directory configured") - } - ps := &peerAPIServer{ b: b, - taildrop: taildrop.ManagerOptions{ - Logf: b.logf, - Clock: tstime.DefaultClock{Clock: b.clock}, - State: b.store, - Dir: fileRoot, - DirectFileMode: b.directFileRoot != "", - SendFileNotify: b.sendFileNotify, - }.New(), } if dm, ok := b.sys.DNSManager.GetOK(); ok { ps.resolver = dm.Resolver() @@ -5361,19 +5319,29 @@ func (b *LocalBackend) initPeerAPIListener() { b.peerAPIServer = ps isNetstack := b.sys.IsNetstack() + peerAPIPorts := make(map[netip.Addr]int) for i, a := range addrs.All() { var ln net.Listener var err error skipListen := i > 0 && isNetstack if !skipListen { - ln, err = ps.listen(a.Addr(), b.prevIfState) + // We don't care about the error here. Not all platforms set this. + // If ps.listen needs it, it will check for zero values and error out. + tsIfIndex, _ := netmon.TailscaleInterfaceIndex() + + ln, err = ps.listen(a.Addr(), tsIfIndex) if err != nil { if peerAPIListenAsync { - b.logf("possibly transient peerapi listen(%q) error, will try again on linkChange: %v", a.Addr(), err) + b.logf("[v1] possibly transient peerapi listen(%q) error, will try again on linkChange: %v", a.Addr(), err) // Expected. But we fix it later in linkChange // ("peerAPIListeners too low"). continue } + // Sandboxed macOS specifically requires the interface index to be non-zero. + if version.IsSandboxedMacOS() && tsIfIndex == 0 { + b.logf("[v1] peerapi listen(%q) error: interface index is 0 on darwin; try restarting tailscaled", a.Addr()) + continue + } b.logf("[unexpected] peerapi listen(%q) error: %v", a.Addr(), err) continue } @@ -5393,7 +5361,9 @@ func (b *LocalBackend) initPeerAPIListener() { b.logf("peerapi: serving on %s", pln.urlStr) go pln.serve() b.peerAPIListeners = append(b.peerAPIListeners, pln) + peerAPIPorts[a.Addr()] = pln.port } + b.peerAPIPorts.Store(peerAPIPorts) b.goTracker.Go(b.doSetHostinfoFilterServices) } @@ -5426,7 +5396,7 @@ func magicDNSRootDomains(nm *netmap.NetworkMap) []dnsname.FQDN { // peerRoutes returns the routerConfig.Routes to access peers. // If there are over cgnatThreshold CGNAT routes, one big CGNAT route // is used instead. -func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (routes []netip.Prefix) { +func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int, routeAll bool) (routes []netip.Prefix) { tsULA := tsaddr.TailscaleULARange() cgNAT := tsaddr.CGNATRange() var didULA bool @@ -5456,7 +5426,7 @@ func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (route } if aip.IsSingleIP() && cgNAT.Contains(aip.Addr()) { cgNATIPs = append(cgNATIPs, aip) - } else { + } else if routeAll { routes = append(routes, aip) } } @@ -5473,15 +5443,15 @@ func peerRoutes(logf logger.Logf, peers []wgcfg.Peer, cgnatThreshold int) (route } // routerConfig produces a router.Config from a wireguard config and IPN prefs. -func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs ipn.PrefsView, oneCGNATRoute bool) *router.Config { +// +// b.mu must be held. +func (b *LocalBackend) routerConfigLocked(cfg *wgcfg.Config, prefs ipn.PrefsView, oneCGNATRoute bool) *router.Config { singleRouteThreshold := 10_000 if oneCGNATRoute { singleRouteThreshold = 1 } - b.mu.Lock() - netfilterKind := b.capForcedNetfilter // protected by b.mu - b.mu.Unlock() + netfilterKind := b.capForcedNetfilter // protected by b.mu (hence the Locked suffix) if prefs.NetfilterKind() != "" { if netfilterKind != "" { @@ -5504,11 +5474,11 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs ipn.PrefsView, oneC SNATSubnetRoutes: !prefs.NoSNAT(), StatefulFiltering: doStatefulFiltering, NetfilterMode: prefs.NetfilterMode(), - Routes: peerRoutes(b.logf, cfg.Peers, singleRouteThreshold), + Routes: peerRoutes(b.logf, cfg.Peers, singleRouteThreshold, prefs.RouteAll()), NetfilterKind: netfilterKind, } - if distro.Get() == distro.Synology { + if buildfeatures.HasSynology && distro.Get() == distro.Synology { // Issue 1995: we don't use iptables on Synology. rs.NetfilterMode = preftype.NetfilterOff } @@ -5519,7 +5489,7 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs ipn.PrefsView, oneC // likely to break some functionality, but if the user expressed a // preference for routing remotely, we want to avoid leaking // traffic at the expense of functionality. - if prefs.ExitNodeID() != "" || prefs.ExitNodeIP().IsValid() { + if buildfeatures.HasUseExitNode && (prefs.ExitNodeID() != "" || prefs.ExitNodeIP().IsValid()) { var default4, default6 bool for _, route := range rs.Routes { switch route { @@ -5591,12 +5561,14 @@ func (b *LocalBackend) applyPrefsToHostinfoLocked(hi *tailcfg.Hostinfo, prefs ip hi.RoutableIPs = prefs.AdvertiseRoutes().AsSlice() hi.RequestTags = prefs.AdvertiseTags().AsSlice() hi.ShieldsUp = prefs.ShieldsUp() - hi.AllowsUpdate = envknob.AllowsRemoteUpdate() || prefs.AutoUpdate().Apply.EqualBool(true) + hi.AllowsUpdate = buildfeatures.HasClientUpdate && (envknob.AllowsRemoteUpdate() || prefs.AutoUpdate().Apply.EqualBool(true)) - b.metrics.advertisedRoutes.Set(float64(tsaddr.WithoutExitRoute(prefs.AdvertiseRoutes()).Len())) + if buildfeatures.HasAdvertiseRoutes { + b.metrics.advertisedRoutes.Set(float64(tsaddr.WithoutExitRoute(prefs.AdvertiseRoutes()).Len())) + } var sshHostKeys []string - if prefs.RunSSH() && envknob.CanSSHD() { + if buildfeatures.HasSSH && prefs.RunSSH() && envknob.CanSSHD() { // TODO(bradfitz): this is called with b.mu held. Not ideal. // If the filesystem gets wedged or something we could block for // a long time. But probably fine. @@ -5608,69 +5580,86 @@ func (b *LocalBackend) applyPrefsToHostinfoLocked(hi *tailcfg.Hostinfo, prefs ip } hi.SSH_HostKeys = sshHostKeys - hi.ServicesHash = b.vipServiceHash(b.vipServicesFromPrefsLocked(prefs)) + for _, f := range hookMaybeMutateHostinfoLocked { + f(b, hi, prefs) + } - // The Hostinfo.IngressEnabled field is used to communicate to control whether - // the node has funnel enabled. - hi.IngressEnabled = b.hasIngressEnabledLocked() - // The Hostinfo.WantIngress field tells control whether the user intends - // to use funnel with this node even though it is not currently enabled. - // This is an optimization to control- Funnel requires creation of DNS - // records and because DNS propagation can take time, we want to ensure - // that the records exist for any node that intends to use funnel even - // if it's not enabled. If hi.IngressEnabled is true, control knows that - // DNS records are needed, so we can save bandwidth and not send - // WireIngress. - hi.WireIngress = b.shouldWireInactiveIngressLocked() - hi.AppConnector.Set(prefs.AppConnector().Advertise) + if buildfeatures.HasAppConnectors { + hi.AppConnector.Set(prefs.AppConnector().Advertise) + } + + // The [tailcfg.Hostinfo.ExitNodeID] field tells control which exit node + // was selected, if any. + // + // If auto exit node is enabled (via [ipn.Prefs.AutoExitNode] or + // [pkey.ExitNodeID]), or an exit node is specified by ExitNodeIP + // instead of ExitNodeID , and we don't yet have enough info to resolve + // it (usually due to missing netmap or net report), then ExitNodeID in + // the prefs may be invalid (typically, [unresolvedExitNodeID]) until + // the netmap is available. + // + // In this case, we shouldn't update the Hostinfo with the bogus + // ExitNodeID here; [LocalBackend.ResolveExitNode] will be called once + // the netmap and/or net report have been received to both pick the exit + // node and notify control of the change. + if buildfeatures.HasUseExitNode { + if sid := prefs.ExitNodeID(); sid != unresolvedExitNodeID { + hi.ExitNodeID = prefs.ExitNodeID() + } + } } -// enterState transitions the backend into newState, updating internal +// enterStateLocked transitions the backend into newState, updating internal // state and propagating events out as needed. // // TODO(danderson): while this isn't a lie, exactly, a ton of other // places twiddle IPN internal state without going through here, so // really this is more "one of several places in which random things // happen". -func (b *LocalBackend) enterState(newState ipn.State) { - unlock := b.lockAndGetUnlock() - b.enterStateLockedOnEntry(newState, unlock) -} - -// enterStateLockedOnEntry is like enterState but requires b.mu be held to call -// it, but it unlocks b.mu when done (via unlock, a once func). -func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlockOnce) { +// +// b.mu must be held. +func (b *LocalBackend) enterStateLocked(newState ipn.State) { + cn := b.currentNode() oldState := b.state - b.state = newState + b.setStateLocked(newState) prefs := b.pm.CurrentPrefs() // Some temporary (2024-05-05) debugging code to help us catch // https://github.com/tailscale/tailscale/issues/11962 in the act. if prefs.WantRunning() && - prefs.ControlURLOrDefault() == ipn.DefaultControlURL && + prefs.ControlURLOrDefault(b.polc) == ipn.DefaultControlURL && envknob.Bool("TS_PANIC_IF_HIT_MAIN_CONTROL") { panic("[unexpected] use of main control server in integration test") } - netMap := b.netMap + netMap := cn.NetMap() activeLogin := b.activeLogin authURL := b.authURL if newState == ipn.Running { - b.resetAuthURLLocked() + // TODO(zofrex): Is this needed? As of 2025-10-03 it doesn't seem to be + // necessary when logging in or authenticating. When do we need to reset it + // here, rather than the other places it is reset? We should test if it is + // necessary and add unit tests to cover those cases, or remove it. + if oldState != ipn.Running { + b.resetAuthURLLocked() + } // Start a captive portal detection loop if none has been // started. Create a new context if none is present, since it // can be shut down if we transition away from Running. - if b.captiveCancel == nil { - b.captiveCtx, b.captiveCancel = context.WithCancel(b.ctx) - b.goTracker.Go(func() { b.checkCaptivePortalLoop(b.captiveCtx) }) + if buildfeatures.HasCaptivePortal { + if b.captiveCancel == nil { + captiveCtx, captiveCancel := context.WithCancel(b.ctx) + b.captiveCtx, b.captiveCancel = captiveCtx, captiveCancel + b.goTracker.Go(func() { hookCheckCaptivePortalLoop.Get()(b, captiveCtx) }) + } } } else if oldState == ipn.Running { // Transitioning away from running. b.closePeerAPIListenersLocked() // Stop any existing captive portal detection loop. - if b.captiveCancel != nil { + if buildfeatures.HasCaptivePortal && b.captiveCancel != nil { b.captiveCancel() b.captiveCancel = nil @@ -5681,60 +5670,56 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock } b.pauseOrResumeControlClientLocked() - if newState == ipn.Running { - b.stopOfflineAutoUpdate() - } else { - b.maybeStartOfflineAutoUpdate(prefs) - } - - unlock.UnlockEarly() - // prefs may change irrespective of state; WantRunning should be explicitly // set before potential early return even if the state is unchanged. b.health.SetIPNState(newState.String(), prefs.Valid() && prefs.WantRunning()) if oldState == newState { return } + b.logf("Switching ipn state %v -> %v (WantRunning=%v, nm=%v)", oldState, newState, prefs.WantRunning(), netMap != nil) - b.send(ipn.Notify{State: &newState}) + b.sendLocked(ipn.Notify{State: &newState}) switch newState { case ipn.NeedsLogin: - systemd.Status("Needs login: %s", authURL) - if b.seamlessRenewalEnabled() { - break - } - b.blockEngineUpdates(true) + feature.SystemdStatus("Needs login: %s", authURL) + // always block updates on NeedsLogin even if seamless renewal is enabled, + // to prevent calls to authReconfig from reconfiguring the engine when our + // key has expired and we're waiting to authenticate to use the new key. + b.blockEngineUpdatesLocked(true) fallthrough - case ipn.Stopped: + case ipn.Stopped, ipn.NoState: + // Unconfigure the engine if it has stopped (WantRunning is set to false) + // or if we've switched to a different profile and the state is unknown. err := b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{}) if err != nil { b.logf("Reconfig(down): %v", err) } - if authURL == "" { - systemd.Status("Stopped; run 'tailscale up' to log in") + if newState == ipn.Stopped && authURL == "" { + feature.SystemdStatus("Stopped; run 'tailscale up' to log in") } case ipn.Starting, ipn.NeedsMachineAuth: - b.authReconfig() + b.authReconfigLocked() // Needed so that UpdateEndpoints can run - b.e.RequestStatus() + b.goTracker.Go(b.e.RequestStatus) case ipn.Running: - var addrStrs []string - addrs := netMap.GetAddresses() - for _, p := range addrs.All() { - addrStrs = append(addrStrs, p.Addr().String()) + if feature.CanSystemdStatus { + var addrStrs []string + addrs := netMap.GetAddresses() + for _, p := range addrs.All() { + addrStrs = append(addrStrs, p.Addr().String()) + } + feature.SystemdStatus("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " ")) } - systemd.Status("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " ")) - case ipn.NoState: - // Do nothing. default: b.logf("[unexpected] unknown newState %#v", newState) } } func (b *LocalBackend) hasNodeKeyLocked() bool { + syncs.RequiresMutex(&b.mu) // we can't use b.Prefs(), because it strips the keys, oops! p := b.pm.CurrentPrefs() return p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() @@ -5755,9 +5740,15 @@ func (b *LocalBackend) NodeKey() key.NodePublic { // // b.mu must be held func (b *LocalBackend) nextStateLocked() ipn.State { + syncs.RequiresMutex(&b.mu) + if b.health.IsUnhealthy(ipn.StateStoreHealth) { + return ipn.NoState + } + var ( cc = b.cc - netMap = b.netMap + cn = b.currentNode() + netMap = cn.NetMap() state = b.state blocked = b.blocked st = b.engineStatus @@ -5827,103 +5818,33 @@ func (b *LocalBackend) nextStateLocked() ipn.State { // that have happened. It is invoked from the various callbacks that // feed events into LocalBackend. // -// TODO(apenwarr): use a channel or something to prevent reentrancy? -// Or maybe just call the state machine from fewer places. -func (b *LocalBackend) stateMachine() { - unlock := b.lockAndGetUnlock() - b.stateMachineLockedOnEntry(unlock) -} +// requires b.mu to be held. +func (b *LocalBackend) stateMachineLocked() { + syncs.RequiresMutex(&b.mu) -// stateMachineLockedOnEntry is like stateMachine but requires b.mu be held to -// call it, but it unlocks b.mu when done (via unlock, a once func). -func (b *LocalBackend) stateMachineLockedOnEntry(unlock unlockOnce) { - b.enterStateLockedOnEntry(b.nextStateLocked(), unlock) -} - -// lockAndGetUnlock locks b.mu and returns a sync.OnceFunc function that will -// unlock it at most once. -// -// This is all very unfortunate but exists as a guardrail against the -// unfortunate "lockedOnEntry" methods in this package (primarily -// enterStateLockedOnEntry) that require b.mu held to be locked on entry to the -// function but unlock the mutex on their way out. As a stepping stone to -// cleaning things up (as of 2024-04-06), we at least pass the unlock func -// around now and defer unlock in the caller to avoid missing unlocks and double -// unlocks. TODO(bradfitz,maisem): make the locking in this package more -// traditional (simple). See https://github.com/tailscale/tailscale/issues/11649 -func (b *LocalBackend) lockAndGetUnlock() (unlock unlockOnce) { - b.mu.Lock() - var unlocked atomic.Bool - return func() bool { - if unlocked.CompareAndSwap(false, true) { - b.mu.Unlock() - return true - } - return false - } -} - -// unlockOnce is a func that unlocks only b.mu the first time it's called. -// Therefore it can be safely deferred to catch error paths, without worrying -// about double unlocks if a different point in the code later needs to explicitly -// unlock it first as well. It reports whether it was unlocked. -type unlockOnce func() bool - -// UnlockEarly unlocks the LocalBackend.mu. It panics if u returns false, -// indicating that this unlocker was already used. -// -// We're using this method to help us document & find the places that have -// atypical locking patterns. See -// https://github.com/tailscale/tailscale/issues/11649 for background. -// -// A normal unlock is a deferred one or an explicit b.mu.Unlock a few lines -// after the lock, without lots of control flow in-between. An "early" unlock is -// one that happens in weird places, like in various "LockedOnEntry" methods in -// this package that require the mutex to be locked on entry but unlock it -// somewhere in the middle (maybe several calls away) and then sometimes proceed -// to lock it again. -// -// The reason UnlockeEarly panics if already called is because these are the -// points at which it's assumed that the mutex is already held and it now needs -// to be released. If somebody already released it, that invariant was violated. -// On the other hand, simply calling u only returns false instead of panicking -// so you can defer it without care, confident you got all the error return -// paths which were previously done by hand. -func (u unlockOnce) UnlockEarly() { - if !u() { - panic("Unlock on already-called unlockOnce") - } + b.enterStateLocked(b.nextStateLocked()) } // stopEngineAndWait deconfigures the local network data plane, and -// waits for it to deliver a status update before returning. +// waits for it to deliver a status update indicating it has stopped +// before returning. // -// TODO(danderson): this may be racy. We could unblock upon receiving -// a status update that predates the "I've shut down" update. -func (b *LocalBackend) stopEngineAndWait() { +// b.mu must be held. +func (b *LocalBackend) stopEngineAndWaitLocked() { + syncs.RequiresMutex(&b.mu) b.logf("stopEngineAndWait...") - b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{}) - b.requestEngineStatusAndWait() + st, err := b.e.ResetAndStop() + if err != nil { + // TODO(braditz): our caller, popBrowserAuthNowLocked, probably + // should handle this somehow. For now, just log it. + // See tailscale/tailscale#18187 + b.logf("stopEngineAndWait: ResetAndStop error: %v", err) + return + } + b.setWgengineStatusLocked(st) b.logf("stopEngineAndWait: done.") } -// Requests the wgengine status, and does not return until the status -// was delivered (to the usual callback). -func (b *LocalBackend) requestEngineStatusAndWait() { - b.logf("requestEngineStatusAndWait") - - b.statusLock.Lock() - defer b.statusLock.Unlock() - - b.goTracker.Go(b.e.RequestStatus) - b.logf("requestEngineStatusAndWait: waiting...") - b.statusChanged.Wait() // temporarily releases lock while waiting - b.logf("requestEngineStatusAndWait: got status update.") -} - -// [controlclient.Auto] implements [auditlog.Transport]. -var _ auditlog.Transport = (*controlclient.Auto)(nil) - // setControlClientLocked sets the control client to cc, // which may be nil. // @@ -5931,21 +5852,14 @@ var _ auditlog.Transport = (*controlclient.Auto)(nil) func (b *LocalBackend) setControlClientLocked(cc controlclient.Client) { b.cc = cc b.ccAuto, _ = cc.(*controlclient.Auto) - if t, ok := b.cc.(auditlog.Transport); ok && b.auditLogger != nil { - if err := b.auditLogger.SetProfileID(b.pm.CurrentProfile().ID()); err != nil { - b.logf("audit logger set profile ID failure: %v", err) - } - - if err := b.auditLogger.Start(t); err != nil { - b.logf("audit logger start failure: %v", err) - } - } + b.ignoreControlClientUpdates.Store(cc == nil) } // resetControlClientLocked sets b.cc to nil and returns the old value. If the // returned value is non-nil, the caller must call Shutdown on it after // releasing b.mu. func (b *LocalBackend) resetControlClientLocked() controlclient.Client { + syncs.RequiresMutex(&b.mu) if b.cc == nil { return nil } @@ -5972,6 +5886,8 @@ func (b *LocalBackend) resetControlClientLocked() controlclient.Client { // resetAuthURLLocked resets authURL, canceling any pending interactive login. func (b *LocalBackend) resetAuthURLLocked() { + syncs.RequiresMutex(&b.mu) + b.authURL = "" b.authURLTime = time.Time{} b.authActor = nil @@ -6001,6 +5917,8 @@ func (b *LocalBackend) ShouldExposeRemoteWebClient() bool { // // b.mu must be held. func (b *LocalBackend) setWebClientAtomicBoolLocked(nm *netmap.NetworkMap) { + syncs.RequiresMutex(&b.mu) + shouldRun := !nm.HasCap(tailcfg.NodeAttrDisableWebClient) wasRunning := b.webClientAtomicBool.Swap(shouldRun) if wasRunning && !shouldRun { @@ -6013,6 +5931,11 @@ func (b *LocalBackend) setWebClientAtomicBoolLocked(nm *netmap.NetworkMap) { // // b.mu must be held. func (b *LocalBackend) setExposeRemoteWebClientAtomicBoolLocked(prefs ipn.PrefsView) { + syncs.RequiresMutex(&b.mu) + + if !buildfeatures.HasWebClient { + return + } shouldExpose := prefs.Valid() && prefs.RunWebClient() b.exposeRemoteWebClientAtomicBool.Store(shouldExpose) } @@ -6029,12 +5952,12 @@ func (b *LocalBackend) ShouldHandleViaIP(ip netip.Addr) bool { // Logout logs out the current profile, if any, and waits for the logout to // complete. -func (b *LocalBackend) Logout(ctx context.Context) error { - unlock := b.lockAndGetUnlock() - defer unlock() +func (b *LocalBackend) Logout(ctx context.Context, actor ipnauth.Actor) error { + b.mu.Lock() if !b.hasNodeKeyLocked() { // Already logged out. + b.mu.Unlock() return nil } cc := b.cc @@ -6043,15 +5966,17 @@ func (b *LocalBackend) Logout(ctx context.Context) error { // delete it later. profile := b.pm.CurrentProfile() - _, err := b.editPrefsLockedOnEntry(&ipn.MaskedPrefs{ - WantRunningSet: true, - LoggedOutSet: true, - Prefs: ipn.Prefs{WantRunning: false, LoggedOut: true}, - }, unlock) + _, err := b.editPrefsLocked( + actor, + &ipn.MaskedPrefs{ + WantRunningSet: true, + LoggedOutSet: true, + Prefs: ipn.Prefs{WantRunning: false, LoggedOut: true}, + }) + b.mu.Unlock() if err != nil { return err } - // b.mu is now unlocked, after editPrefsLockedOnEntry. // Clear any previous dial plan(s), if set. b.resetDialPlan() @@ -6071,14 +5996,14 @@ func (b *LocalBackend) Logout(ctx context.Context) error { return err } - unlock = b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() if err := b.pm.DeleteProfile(profile.ID()); err != nil { b.logf("error deleting profile: %v", err) return err } - return b.resetForProfileChangeLockedOnEntry(unlock) + return b.resetForProfileChangeLocked() } // setNetInfo sets b.hostinfo.NetInfo to ni, and passes ni along to the @@ -6119,46 +6044,122 @@ func (b *LocalBackend) setNetInfo(ni *tailcfg.NetInfo) { } cc.SetNetInfo(ni) if refresh { - unlock := b.lockAndGetUnlock() - defer unlock() - b.setAutoExitNodeIDLockedOnEntry(unlock) + b.RefreshExitNode() } } -func (b *LocalBackend) setAutoExitNodeIDLockedOnEntry(unlock unlockOnce) (newPrefs ipn.PrefsView) { - var zero ipn.PrefsView - defer unlock() +// RefreshExitNode determines which exit node to use based on the current +// prefs and netmap and switches to it if needed. +func (b *LocalBackend) RefreshExitNode() { + if !buildfeatures.HasUseExitNode { + return + } + b.mu.Lock() + defer b.mu.Unlock() + b.refreshExitNodeLocked() +} - prefs := b.pm.CurrentPrefs() - if !prefs.Valid() { - b.logf("[unexpected]: received tailnet exit node ID pref change callback but current prefs are nil") - return zero +// refreshExitNodeLocked is like RefreshExitNode but requires b.mu be held. +func (b *LocalBackend) refreshExitNodeLocked() { + syncs.RequiresMutex(&b.mu) + + if b.resolveExitNodeLocked() { + b.authReconfigLocked() } - prefsClone := prefs.AsStruct() - newSuggestion, err := b.suggestExitNodeLocked(nil) - if err != nil { - b.logf("setAutoExitNodeID: %v", err) - return zero +} + +// resolveExitNodeLocked determines which exit node to use based on the current prefs +// and netmap. It updates the exit node ID in the prefs if needed, updates the +// exit node ID in the hostinfo if needed, sends a notification to clients, and +// returns true if the exit node has changed. +// +// It is the caller's responsibility to reconfigure routes and actually +// start using the selected exit node, if needed. +// +// b.mu must be held. +func (b *LocalBackend) resolveExitNodeLocked() (changed bool) { + syncs.RequiresMutex(&b.mu) + + if !buildfeatures.HasUseExitNode { + return false } - if prefsClone.ExitNodeID == newSuggestion.ID { - return zero + + nm := b.currentNode().NetMap() + prefs := b.pm.CurrentPrefs().AsStruct() + if !b.resolveExitNodeInPrefsLocked(prefs) { + return } - prefsClone.ExitNodeID = newSuggestion.ID - newPrefs, err = b.editPrefsLockedOnEntry(&ipn.MaskedPrefs{ - Prefs: *prefsClone, - ExitNodeIDSet: true, - }, unlock) - if err != nil { - b.logf("setAutoExitNodeID: failed to apply exit node ID preference: %v", err) - return zero + + if err := b.pm.SetPrefs(prefs.View(), ipn.NetworkProfile{ + MagicDNSName: nm.MagicDNSSuffix(), + DomainName: nm.DomainName(), + DisplayName: nm.TailnetDisplayName(), + }); err != nil { + b.logf("failed to save exit node changes: %v", err) } - return newPrefs + + // Send the resolved exit node to control via [tailcfg.Hostinfo]. + // [LocalBackend.applyPrefsToHostinfoLocked] usually sets the Hostinfo, + // but it deferred until this point because there was a bogus ExitNodeID + // in the prefs. + // + // TODO(sfllaw): Mutating b.hostinfo here is undesirable, mutating + // in-place doubly so. + sid := prefs.ExitNodeID + if sid != unresolvedExitNodeID && b.hostinfo.ExitNodeID != sid { + b.hostinfo.ExitNodeID = sid + b.goTracker.Go(b.doSetHostinfoFilterServices) + } + + b.sendToLocked(ipn.Notify{Prefs: ptr.To(prefs.View())}, allClients) + return true +} + +// reconcilePrefsLocked applies policy overrides, exit node resolution, +// and other post-processing to the prefs, and reports whether the prefs +// were modified as a result. +// +// It must not perform any reconfiguration, as the prefs are not yet effective. +// +// b.mu must be held. +func (b *LocalBackend) reconcilePrefsLocked(prefs *ipn.Prefs) (changed bool) { + if buildfeatures.HasSystemPolicy && b.applySysPolicyLocked(prefs) { + changed = true + } + if buildfeatures.HasUseExitNode && b.resolveExitNodeInPrefsLocked(prefs) { + changed = true + } + if changed { + b.logf("prefs reconciled: %v", prefs.Pretty()) + } + return changed +} + +// resolveExitNodeInPrefsLocked determines which exit node to use +// based on the specified prefs and netmap. It updates the exit node ID +// in the prefs if needed, and returns true if the exit node has changed. +// +// b.mu must be held. +func (b *LocalBackend) resolveExitNodeInPrefsLocked(prefs *ipn.Prefs) (changed bool) { + syncs.RequiresMutex(&b.mu) + if !buildfeatures.HasUseExitNode { + return false + } + if b.resolveAutoExitNodeLocked(prefs) { + changed = true + } + if b.resolveExitNodeIPLocked(prefs) { + changed = true + } + return changed } // setNetMapLocked updates the LocalBackend state to reflect the newly // received nm. If nm is nil, it resets all configuration as though // Tailscale is turned off. func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) { + oldSelf := b.currentNode().NetMap().SelfNodeOrZero() + b.dialer.SetNetMap(nm) if ns, ok := b.sys.Netstack.GetOK(); ok { ns.UpdateNetstackIPs(nm) @@ -6167,8 +6168,7 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) { if nm != nil { login = cmp.Or(profileFromView(nm.UserProfiles[nm.User()]).LoginName, "") } - b.netMap = nm - b.updatePeersFromNetmapLocked(nm) + b.currentNode().SetNetMap(nm) if login != b.activeLogin { b.logf("active login: %v", login) b.activeLogin = login @@ -6176,236 +6176,75 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) { b.pauseOrResumeControlClientLocked() if nm != nil { - b.health.SetControlHealth(nm.ControlHealth) + messages := make(map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage) + for id, msg := range nm.DisplayMessages { + if msg.PrimaryAction != nil && !b.validPopBrowserURLLocked(msg.PrimaryAction.URL) { + msg.PrimaryAction = nil + } + messages[id] = msg + } + b.health.SetControlHealth(messages) } else { b.health.SetControlHealth(nil) } - // Determine if file sharing is enabled - fs := nm.HasCap(tailcfg.CapabilityFileSharing) - if fs != b.capFileSharing { - osshare.SetFileSharingEnabled(fs, b.logf) - } - b.capFileSharing = fs - - if nm.HasCap(tailcfg.NodeAttrLinuxMustUseIPTables) { - b.capForcedNetfilter = "iptables" - } else if nm.HasCap(tailcfg.NodeAttrLinuxMustUseNfTables) { - b.capForcedNetfilter = "nftables" - } else { - b.capForcedNetfilter = "" // empty string means client can auto-detect + if runtime.GOOS == "linux" && buildfeatures.HasOSRouter { + if nm.HasCap(tailcfg.NodeAttrLinuxMustUseIPTables) { + b.capForcedNetfilter = "iptables" + } else if nm.HasCap(tailcfg.NodeAttrLinuxMustUseNfTables) { + b.capForcedNetfilter = "nftables" + } else { + b.capForcedNetfilter = "" // empty string means client can auto-detect + } } b.MagicConn().SetSilentDisco(b.ControlKnobs().SilentDisco.Load()) b.MagicConn().SetProbeUDPLifetime(b.ControlKnobs().ProbeUDPLifetime.Load()) - b.setDebugLogsByCapabilityLocked(nm) + if buildfeatures.HasDebug { + b.setDebugLogsByCapabilityLocked(nm) + } - // See the netns package for documentation on what this capability does. - netns.SetBindToInterfaceByRoute(nm.HasCap(tailcfg.CapabilityBindToInterfaceByRoute)) - netns.SetDisableBindConnToInterface(nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterface)) + // See the netns package for documentation on what these capability do. + netns.SetBindToInterfaceByRoute(b.logf, nm.HasCap(tailcfg.CapabilityBindToInterfaceByRoute)) + netns.SetDisableBindConnToInterface(b.logf, nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterface)) + netns.SetDisableBindConnToInterfaceAppleExt(b.logf, nm.HasCap(tailcfg.CapabilityDebugDisableBindConnToInterfaceAppleExt)) b.setTCPPortsInterceptedFromNetmapAndPrefsLocked(b.pm.CurrentPrefs()) - b.ipVIPServiceMap = nm.GetIPVIPServiceMap() - if nm == nil { - b.nodeByAddr = nil - - // If there is no netmap, the client is going into a "turned off" - // state so reset the metrics. - b.metrics.approvedRoutes.Set(0) - return + if buildfeatures.HasServe { + b.ipVIPServiceMap = nm.GetIPVIPServiceMap() } - // Update the nodeByAddr index. - if b.nodeByAddr == nil { - b.nodeByAddr = map[netip.Addr]tailcfg.NodeID{} + if !oldSelf.Equal(nm.SelfNodeOrZero()) { + for _, f := range b.extHost.Hooks().OnSelfChange { + f(nm.SelfNode) + } } - // First pass, mark everything unwanted. - for k := range b.nodeByAddr { - b.nodeByAddr[k] = 0 - } - addNode := func(n tailcfg.NodeView) { - for _, ipp := range n.Addresses().All() { - if ipp.IsSingleIP() { - b.nodeByAddr[ipp.Addr()] = n.ID() + + if buildfeatures.HasAdvertiseRoutes { + if nm == nil { + // If there is no netmap, the client is going into a "turned off" + // state so reset the metrics. + b.metrics.approvedRoutes.Set(0) + } else if nm.SelfNode.Valid() { + var approved float64 + for _, route := range nm.SelfNode.AllowedIPs().All() { + if !views.SliceContains(nm.SelfNode.Addresses(), route) && !tsaddr.IsExitRoute(route) { + approved++ + } } - } - } - if nm.SelfNode.Valid() { - addNode(nm.SelfNode) - - var approved float64 - for _, route := range nm.SelfNode.AllowedIPs().All() { - if !views.SliceContains(nm.SelfNode.Addresses(), route) && !tsaddr.IsExitRoute(route) { - approved++ - } - } - b.metrics.approvedRoutes.Set(approved) - } - for _, p := range nm.Peers { - addNode(p) - } - // Third pass, actually delete the unwanted items. - for k, v := range b.nodeByAddr { - if v == 0 { - delete(b.nodeByAddr, k) + b.metrics.approvedRoutes.Set(approved) } } - b.updateDrivePeersLocked(nm) - b.driveNotifyCurrentSharesLocked() -} - -func (b *LocalBackend) updatePeersFromNetmapLocked(nm *netmap.NetworkMap) { - if nm == nil { - b.peers = nil - return - } - - // First pass, mark everything unwanted. - for k := range b.peers { - b.peers[k] = tailcfg.NodeView{} - } - - // Second pass, add everything wanted. - for _, p := range nm.Peers { - mak.Set(&b.peers, p.ID(), p) - } - - // Third pass, remove deleted things. - for k, v := range b.peers { - if !v.Valid() { - delete(b.peers, k) + if buildfeatures.HasDrive && nm != nil { + if f, ok := hookSetNetMapLockedDrive.GetOk(); ok { + f(b, nm) } } } -// responseBodyWrapper wraps an io.ReadCloser and stores -// the number of bytesRead. -type responseBodyWrapper struct { - io.ReadCloser - bytesRx int64 - bytesTx int64 - log logger.Logf - method string - statusCode int - contentType string - fileExtension string - shareNodeKey string - selfNodeKey string - contentLength int64 -} - -// logAccess logs the taildrive: access: log line. If the logger is nil, -// the log will not be written. -func (rbw *responseBodyWrapper) logAccess(err string) { - if rbw.log == nil { - return - } - - // Some operating systems create and copy lots of 0 length hidden files for - // tracking various states. Omit these to keep logs from being too verbose. - if rbw.contentLength > 0 { - rbw.log("taildrive: access: %s from %s to %s: status-code=%d ext=%q content-type=%q content-length=%.f tx=%.f rx=%.f err=%q", rbw.method, rbw.selfNodeKey, rbw.shareNodeKey, rbw.statusCode, rbw.fileExtension, rbw.contentType, roundTraffic(rbw.contentLength), roundTraffic(rbw.bytesTx), roundTraffic(rbw.bytesRx), err) - } -} - -// Read implements the io.Reader interface. -func (rbw *responseBodyWrapper) Read(b []byte) (int, error) { - n, err := rbw.ReadCloser.Read(b) - rbw.bytesRx += int64(n) - if err != nil && !errors.Is(err, io.EOF) { - rbw.logAccess(err.Error()) - } - - return n, err -} - -// Close implements the io.Close interface. -func (rbw *responseBodyWrapper) Close() error { - err := rbw.ReadCloser.Close() - var errStr string - if err != nil { - errStr = err.Error() - } - rbw.logAccess(errStr) - - return err -} - -// driveTransport is an http.RoundTripper that wraps -// b.Dialer().PeerAPITransport() with metrics tracking. -type driveTransport struct { - b *LocalBackend - tr *http.Transport -} - -func (b *LocalBackend) newDriveTransport() *driveTransport { - return &driveTransport{ - b: b, - tr: b.Dialer().PeerAPITransport(), - } -} - -func (dt *driveTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) { - // Some WebDAV clients include origin and refer headers, which peerapi does - // not like. Remove them. - req.Header.Del("origin") - req.Header.Del("referer") - - bw := &requestBodyWrapper{} - if req.Body != nil { - bw.ReadCloser = req.Body - req.Body = bw - } - - defer func() { - contentType := "unknown" - switch req.Method { - case httpm.PUT: - if ct := req.Header.Get("Content-Type"); ct != "" { - contentType = ct - } - case httpm.GET: - if ct := resp.Header.Get("Content-Type"); ct != "" { - contentType = ct - } - default: - return - } - - dt.b.mu.Lock() - selfNodeKey := dt.b.netMap.SelfNode.Key().ShortString() - dt.b.mu.Unlock() - n, _, ok := dt.b.WhoIs("tcp", netip.MustParseAddrPort(req.URL.Host)) - shareNodeKey := "unknown" - if ok { - shareNodeKey = string(n.Key().ShortString()) - } - - rbw := responseBodyWrapper{ - log: dt.b.logf, - method: req.Method, - bytesTx: int64(bw.bytesRead), - selfNodeKey: selfNodeKey, - shareNodeKey: shareNodeKey, - contentType: contentType, - contentLength: resp.ContentLength, - fileExtension: parseDriveFileExtensionForLog(req.URL.Path), - statusCode: resp.StatusCode, - ReadCloser: resp.Body, - } - - if resp.StatusCode >= 400 { - // in case of error response, just log immediately - rbw.logAccess("") - } else { - resp.Body = &rbw - } - }() - - return dt.tr.RoundTrip(req) -} +var hookSetNetMapLockedDrive feature.Hook[func(*LocalBackend, *netmap.NetworkMap)] // roundTraffic rounds bytes. This is used to preserve user privacy within logs. func roundTraffic(bytes int64) float64 { @@ -6445,55 +6284,12 @@ func (b *LocalBackend) setDebugLogsByCapabilityLocked(nm *netmap.NetworkMap) { } } -// reloadServeConfigLocked reloads the serve config from the store or resets the -// serve config to nil if not logged in. The "changed" parameter, when false, instructs -// the method to only run the reset-logic and not reload the store from memory to ensure -// foreground sessions are not removed if they are not saved on disk. -func (b *LocalBackend) reloadServeConfigLocked(prefs ipn.PrefsView) { - if b.netMap == nil || !b.netMap.SelfNode.Valid() || !prefs.Valid() || b.pm.CurrentProfile().ID() == "" { - // We're not logged in, so we don't have a profile. - // Don't try to load the serve config. - b.lastServeConfJSON = mem.B(nil) - b.serveConfig = ipn.ServeConfigView{} - return - } - - confKey := ipn.ServeConfigKey(b.pm.CurrentProfile().ID()) - // TODO(maisem,bradfitz): prevent reading the config from disk - // if the profile has not changed. - confj, err := b.store.ReadState(confKey) - if err != nil { - b.lastServeConfJSON = mem.B(nil) - b.serveConfig = ipn.ServeConfigView{} - return - } - if b.lastServeConfJSON.Equal(mem.B(confj)) { - return - } - b.lastServeConfJSON = mem.B(confj) - var conf ipn.ServeConfig - if err := json.Unmarshal(confj, &conf); err != nil { - b.logf("invalid ServeConfig %q in StateStore: %v", confKey, err) - b.serveConfig = ipn.ServeConfigView{} - return - } - - // remove inactive sessions - maps.DeleteFunc(conf.Foreground, func(sessionID string, sc *ipn.ServeConfig) bool { - _, ok := b.notifyWatchers[sessionID] - return !ok - }) - - b.serveConfig = conf.View() -} - // setTCPPortsInterceptedFromNetmapAndPrefsLocked calls setTCPPortsIntercepted with // the ports that tailscaled should handle as a function of b.netMap and b.prefs. // // b.mu must be held. func (b *LocalBackend) setTCPPortsInterceptedFromNetmapAndPrefsLocked(prefs ipn.PrefsView) { handlePorts := make([]uint16, 0, 4) - var vipServicesPorts map[tailcfg.ServiceName][]uint16 if prefs.Valid() && prefs.RunSSH() && envknob.CanSSHD() { handlePorts = append(handlePorts, 22) @@ -6507,114 +6303,44 @@ func (b *LocalBackend) setTCPPortsInterceptedFromNetmapAndPrefsLocked(prefs ipn. } } - b.reloadServeConfigLocked(prefs) - if b.serveConfig.Valid() { - servePorts := make([]uint16, 0, 3) - for port := range b.serveConfig.TCPs() { - if port > 0 { - servePorts = append(servePorts, uint16(port)) - } - } - handlePorts = append(handlePorts, servePorts...) - - for svc, cfg := range b.serveConfig.Services().All() { - servicePorts := make([]uint16, 0, 3) - for port := range cfg.TCP().All() { - if port > 0 { - servicePorts = append(servicePorts, uint16(port)) - } - } - if _, ok := vipServicesPorts[svc]; !ok { - mak.Set(&vipServicesPorts, svc, servicePorts) - } else { - mak.Set(&vipServicesPorts, svc, append(vipServicesPorts[svc], servicePorts...)) - } - } - - b.setServeProxyHandlersLocked() - - // don't listen on netmap addresses if we're in userspace mode - if !b.sys.IsNetstack() { - b.updateServeTCPPortNetMapAddrListenersLocked(servePorts) - } + if f, ok := hookServeSetTCPPortsInterceptedFromNetmapAndPrefsLocked.GetOk(); ok { + v := f(b, prefs) + handlePorts = append(handlePorts, v...) } - // Update funnel info in hostinfo and kick off control update if needed. - b.updateIngressLocked() + // Update funnel and service hash info in hostinfo and kick off control update if needed. + b.maybeSentHostinfoIfChangedLocked(prefs) b.setTCPPortsIntercepted(handlePorts) - b.setVIPServicesTCPPortsInterceptedLocked(vipServicesPorts) } -// updateIngressLocked updates the hostinfo.WireIngress and hostinfo.IngressEnabled fields and kicks off a Hostinfo -// update if the values have changed. +// hookMaybeMutateHostinfoLocked is a hook that allows conditional features +// to mutate the provided hostinfo before it is sent to control. +// +// The hook function should return true if it mutated the hostinfo. +// +// The LocalBackend's mutex is held while calling. +var hookMaybeMutateHostinfoLocked feature.Hooks[func(*LocalBackend, *tailcfg.Hostinfo, ipn.PrefsView) bool] + +// maybeSentHostinfoIfChangedLocked updates the hostinfo.ServicesHash, hostinfo.WireIngress and +// hostinfo.IngressEnabled fields and kicks off a Hostinfo update if the values have changed. // // b.mu must be held. -func (b *LocalBackend) updateIngressLocked() { +func (b *LocalBackend) maybeSentHostinfoIfChangedLocked(prefs ipn.PrefsView) { if b.hostinfo == nil { return } - hostInfoChanged := false - if ie := b.hasIngressEnabledLocked(); b.hostinfo.IngressEnabled != ie { - b.logf("Hostinfo.IngressEnabled changed to %v", ie) - b.hostinfo.IngressEnabled = ie - hostInfoChanged = true - } - if wire := b.shouldWireInactiveIngressLocked(); b.hostinfo.WireIngress != wire { - b.logf("Hostinfo.WireIngress changed to %v", wire) - b.hostinfo.WireIngress = wire - hostInfoChanged = true + changed := false + for _, f := range hookMaybeMutateHostinfoLocked { + if f(b, b.hostinfo, prefs) { + changed = true + } } // Kick off a Hostinfo update to control if ingress status has changed. - if hostInfoChanged { + if changed { b.goTracker.Go(b.doSetHostinfoFilterServices) } } -// setServeProxyHandlersLocked ensures there is an http proxy handler for each -// backend specified in serveConfig. It expects serveConfig to be valid and -// up-to-date, so should be called after reloadServeConfigLocked. -func (b *LocalBackend) setServeProxyHandlersLocked() { - if !b.serveConfig.Valid() { - return - } - var backends map[string]bool - for _, conf := range b.serveConfig.Webs() { - for _, h := range conf.Handlers().All() { - backend := h.Proxy() - if backend == "" { - // Only create proxy handlers for servers with a proxy backend. - continue - } - mak.Set(&backends, backend, true) - if _, ok := b.serveProxyHandlers.Load(backend); ok { - continue - } - - b.logf("serve: creating a new proxy handler for %s", backend) - p, err := b.proxyHandlerForBackend(backend) - if err != nil { - // The backend endpoint (h.Proxy) should have been validated by expandProxyTarget - // in the CLI, so just log the error here. - b.logf("[unexpected] could not create proxy for %v: %s", backend, err) - continue - } - b.serveProxyHandlers.Store(backend, p) - } - } - - // Clean up handlers for proxy backends that are no longer present - // in configuration. - b.serveProxyHandlers.Range(func(key, value any) bool { - backend := key.(string) - if !backends[backend] { - b.logf("serve: closing idle connections to %s", backend) - b.serveProxyHandlers.Delete(backend) - value.(*reverseProxy).close() - } - return true - }) -} - // operatorUserName returns the current pref's OperatorUser's name, or the // empty string if none. func (b *LocalBackend) operatorUserName() string { @@ -6660,176 +6386,6 @@ func (b *LocalBackend) TestOnlyPublicKeys() (machineKey key.MachinePublic, nodeK return mk, nk } -func (b *LocalBackend) removeFileWaiter(handle set.Handle) { - b.mu.Lock() - defer b.mu.Unlock() - delete(b.fileWaiters, handle) -} - -func (b *LocalBackend) addFileWaiter(wakeWaiter context.CancelFunc) set.Handle { - b.mu.Lock() - defer b.mu.Unlock() - return b.fileWaiters.Add(wakeWaiter) -} - -func (b *LocalBackend) WaitingFiles() ([]apitype.WaitingFile, error) { - b.mu.Lock() - apiSrv := b.peerAPIServer - b.mu.Unlock() - return mayDeref(apiSrv).taildrop.WaitingFiles() -} - -// AwaitWaitingFiles is like WaitingFiles but blocks while ctx is not done, -// waiting for any files to be available. -// -// On return, exactly one of the results will be non-empty or non-nil, -// respectively. -func (b *LocalBackend) AwaitWaitingFiles(ctx context.Context) ([]apitype.WaitingFile, error) { - if ff, err := b.WaitingFiles(); err != nil || len(ff) > 0 { - return ff, err - } - - for { - gotFile, gotFileCancel := context.WithCancel(context.Background()) - defer gotFileCancel() - - handle := b.addFileWaiter(gotFileCancel) - defer b.removeFileWaiter(handle) - - // Now that we've registered ourselves, check again, in case - // of race. Otherwise there's a small window where we could - // miss a file arrival and wait forever. - if ff, err := b.WaitingFiles(); err != nil || len(ff) > 0 { - return ff, err - } - - select { - case <-gotFile.Done(): - if ff, err := b.WaitingFiles(); err != nil || len(ff) > 0 { - return ff, err - } - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} - -func (b *LocalBackend) DeleteFile(name string) error { - b.mu.Lock() - apiSrv := b.peerAPIServer - b.mu.Unlock() - return mayDeref(apiSrv).taildrop.DeleteFile(name) -} - -func (b *LocalBackend) OpenFile(name string) (rc io.ReadCloser, size int64, err error) { - b.mu.Lock() - apiSrv := b.peerAPIServer - b.mu.Unlock() - return mayDeref(apiSrv).taildrop.OpenFile(name) -} - -// hasCapFileSharing reports whether the current node has the file -// sharing capability enabled. -func (b *LocalBackend) hasCapFileSharing() bool { - b.mu.Lock() - defer b.mu.Unlock() - return b.capFileSharing -} - -// FileTargets lists nodes that the current node can send files to. -func (b *LocalBackend) FileTargets() ([]*apitype.FileTarget, error) { - var ret []*apitype.FileTarget - - b.mu.Lock() - defer b.mu.Unlock() - nm := b.netMap - if b.state != ipn.Running || nm == nil { - return nil, errors.New("not connected to the tailnet") - } - if !b.capFileSharing { - return nil, errors.New("file sharing not enabled by Tailscale admin") - } - for _, p := range b.peers { - if !b.peerIsTaildropTargetLocked(p) { - continue - } - if p.Hostinfo().OS() == "tvOS" { - continue - } - peerAPI := peerAPIBase(b.netMap, p) - if peerAPI == "" { - continue - } - ret = append(ret, &apitype.FileTarget{ - Node: p.AsStruct(), - PeerAPIURL: peerAPI, - }) - } - slices.SortFunc(ret, func(a, b *apitype.FileTarget) int { - return cmp.Compare(a.Node.Name, b.Node.Name) - }) - return ret, nil -} - -func (b *LocalBackend) taildropTargetStatus(p tailcfg.NodeView) ipnstate.TaildropTargetStatus { - if b.state != ipn.Running { - return ipnstate.TaildropTargetIpnStateNotRunning - } - if b.netMap == nil { - return ipnstate.TaildropTargetNoNetmapAvailable - } - if !b.capFileSharing { - return ipnstate.TaildropTargetMissingCap - } - - if !p.Online().Get() { - return ipnstate.TaildropTargetOffline - } - - if !p.Valid() { - return ipnstate.TaildropTargetNoPeerInfo - } - if b.netMap.User() != p.User() { - // Different user must have the explicit file sharing target capability - if p.Addresses().Len() == 0 || - !b.peerHasCapLocked(p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) { - return ipnstate.TaildropTargetOwnedByOtherUser - } - } - - if p.Hostinfo().OS() == "tvOS" { - return ipnstate.TaildropTargetUnsupportedOS - } - if peerAPIBase(b.netMap, p) == "" { - return ipnstate.TaildropTargetNoPeerAPI - } - return ipnstate.TaildropTargetAvailable -} - -// peerIsTaildropTargetLocked reports whether p is a valid Taildrop file -// recipient from this node according to its ownership and the capabilities in -// the netmap. -// -// b.mu must be locked. -func (b *LocalBackend) peerIsTaildropTargetLocked(p tailcfg.NodeView) bool { - if b.netMap == nil || !p.Valid() { - return false - } - if b.netMap.User() == p.User() { - return true - } - if p.Addresses().Len() > 0 && - b.peerHasCapLocked(p.Addresses().At(0).Addr(), tailcfg.PeerCapabilityFileSharingTarget) { - // Explicitly noted in the netmap ACL caps as a target. - return true - } - return false -} - -func (b *LocalBackend) peerHasCapLocked(addr netip.Addr, wantCap tailcfg.PeerCapability) bool { - return b.peerCapsLocked(addr).HasCapability(wantCap) -} - // SetDNS adds a DNS record for the given domain name & TXT record // value. // @@ -6838,6 +6394,9 @@ func (b *LocalBackend) peerHasCapLocked(addr netip.Addr, wantCap tailcfg.PeerCap // This is the low-level interface. Other layers will provide more // friendly options to get HTTPS certs. func (b *LocalBackend) SetDNS(ctx context.Context, name, value string) error { + if !buildfeatures.HasACME { + return feature.ErrUnavailable + } req := &tailcfg.SetDNSRequest{ Version: 1, // TODO(bradfitz,maisem): use tailcfg.CurrentCapabilityVersion when using the Noise transport Type: "TXT", @@ -6879,58 +6438,10 @@ func peerAPIPorts(peer tailcfg.NodeView) (p4, p6 uint16) { return } -// peerAPIURL returns an HTTP URL for the peer's peerapi service, -// without a trailing slash. -// -// If ip or port is the zero value then it returns the empty string. -func peerAPIURL(ip netip.Addr, port uint16) string { - if port == 0 || !ip.IsValid() { - return "" - } - return fmt.Sprintf("http://%v", netip.AddrPortFrom(ip, port)) -} - -// peerAPIBase returns the "http://ip:port" URL base to reach peer's peerAPI. -// It returns the empty string if the peer doesn't support the peerapi -// or there's no matching address family based on the netmap's own addresses. -func peerAPIBase(nm *netmap.NetworkMap, peer tailcfg.NodeView) string { - if nm == nil || !peer.Valid() || !peer.Hostinfo().Valid() { - return "" - } - - var have4, have6 bool - addrs := nm.GetAddresses() - for _, a := range addrs.All() { - if !a.IsSingleIP() { - continue - } - switch { - case a.Addr().Is4(): - have4 = true - case a.Addr().Is6(): - have6 = true - } - } - p4, p6 := peerAPIPorts(peer) - switch { - case have4 && p4 != 0: - return peerAPIURL(nodeIP(peer, netip.Addr.Is4), p4) - case have6 && p6 != 0: - return peerAPIURL(nodeIP(peer, netip.Addr.Is6), p6) - } - return "" -} - -func nodeIP(n tailcfg.NodeView, pred func(netip.Addr) bool) netip.Addr { - for _, pfx := range n.Addresses().All() { - if pfx.IsSingleIP() && pred(pfx.Addr()) { - return pfx.Addr() - } - } - return netip.Addr{} -} - func (b *LocalBackend) CheckIPForwarding() error { + if !buildfeatures.HasAdvertiseRoutes { + return nil + } if b.sys.IsNetstackRouter() { return nil } @@ -7016,12 +6527,7 @@ func (b *LocalBackend) SetUDPGROForwarding() error { // DERPMap returns the current DERPMap in use, or nil if not connected. func (b *LocalBackend) DERPMap() *tailcfg.DERPMap { - b.mu.Lock() - defer b.mu.Unlock() - if b.netMap == nil { - return nil - } - return b.netMap.DERPMap + return b.currentNode().DERPMap() } // OfferingExitNode reports whether b is currently offering exit node @@ -7051,17 +6557,32 @@ func (b *LocalBackend) OfferingExitNode() bool { // OfferingAppConnector reports whether b is currently offering app // connector services. func (b *LocalBackend) OfferingAppConnector() bool { + if !buildfeatures.HasAppConnectors { + return false + } b.mu.Lock() defer b.mu.Unlock() return b.appConnector != nil } +// AppConnector returns the current AppConnector, or nil if not configured. +// +// TODO(nickkhyl): move app connectors to [nodeBackend], or perhaps a feature package? +func (b *LocalBackend) AppConnector() *appc.AppConnector { + if !buildfeatures.HasAppConnectors { + return nil + } + b.mu.Lock() + defer b.mu.Unlock() + return b.appConnector +} + // allowExitNodeDNSProxyToServeName reports whether the Exit Node DNS // proxy is allowed to serve responses for the provided DNS name. func (b *LocalBackend) allowExitNodeDNSProxyToServeName(name string) bool { b.mu.Lock() defer b.mu.Unlock() - nm := b.netMap + nm := b.NetMap() if nm == nil { return false } @@ -7121,6 +6642,9 @@ func (b *LocalBackend) SetDeviceAttrs(ctx context.Context, attrs tailcfg.AttrUpd // // If exitNodeID is the zero valid, it returns "", false. func exitNodeCanProxyDNS(nm *netmap.NetworkMap, peers map[tailcfg.NodeID]tailcfg.NodeView, exitNodeID tailcfg.StableNodeID) (dohURL string, ok bool) { + if !buildfeatures.HasUseExitNode { + return "", false + } if exitNodeID.IsZero() { return "", false } @@ -7186,72 +6710,49 @@ func (b *LocalBackend) DebugReSTUN() error { return nil } +func (b *LocalBackend) DebugRotateDiscoKey() error { + if !buildfeatures.HasDebug { + return nil + } + + mc := b.MagicConn() + mc.RotateDiscoKey() + + newDiscoKey := mc.DiscoPublicKey() + + if tunWrap, ok := b.sys.Tun.GetOK(); ok { + tunWrap.SetDiscoKey(newDiscoKey) + } + + b.mu.Lock() + cc := b.cc + b.mu.Unlock() + if cc != nil { + cc.SetDiscoPublicKey(newDiscoKey) + } + + return nil +} + +func (b *LocalBackend) DebugPeerRelayServers() set.Set[netip.Addr] { + return b.MagicConn().PeerRelays() +} + // ControlKnobs returns the node's control knobs. func (b *LocalBackend) ControlKnobs() *controlknobs.Knobs { return b.sys.ControlKnobs() } +// EventBus returns the node's event bus. +func (b *LocalBackend) EventBus() *eventbus.Bus { + return b.sys.Bus.Get() +} + // MagicConn returns the backend's *magicsock.Conn. func (b *LocalBackend) MagicConn() *magicsock.Conn { return b.sys.MagicSock.Get() } -type keyProvingNoiseRoundTripper struct { - b *LocalBackend -} - -func (n keyProvingNoiseRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - b := n.b - - var priv key.NodePrivate - - b.mu.Lock() - cc := b.ccAuto - if nm := b.netMap; nm != nil { - priv = nm.PrivateKey - } - b.mu.Unlock() - if cc == nil { - return nil, errors.New("no client") - } - if priv.IsZero() { - return nil, errors.New("no netmap or private key") - } - rt, ep, err := cc.GetSingleUseNoiseRoundTripper(req.Context()) - if err != nil { - return nil, err - } - if ep == nil || ep.NodeKeyChallenge.IsZero() { - go rt.RoundTrip(new(http.Request)) // return our reservation with a bogus request - return nil, errors.New("this coordination server does not support API calls over the Noise channel") - } - - // QueryEscape the node key since it has a colon in it. - nk := url.QueryEscape(priv.Public().String()) - req.SetBasicAuth(nk, "") - - // genNodeProofHeaderValue returns the Tailscale-Node-Proof header's value to prove - // to chalPub that we control claimedPrivate. - genNodeProofHeaderValue := func(claimedPrivate key.NodePrivate, chalPub key.ChallengePublic) string { - // TODO(bradfitz): cache this somewhere? - box := claimedPrivate.SealToChallenge(chalPub, []byte(chalPub.String())) - return claimedPrivate.Public().String() + " " + base64.StdEncoding.EncodeToString(box) - } - - // And prove we have the private key corresponding to the public key sent - // tin the basic auth username. - req.Header.Set("Tailscale-Node-Proof", genNodeProofHeaderValue(priv, ep.NodeKeyChallenge)) - - return rt.RoundTrip(req) -} - -// KeyProvingNoiseRoundTripper returns an http.RoundTripper that uses the LocalBackend's -// DoNoiseRequest method and mutates the request to add an authorization header -// to prove the client's nodekey. -func (b *LocalBackend) KeyProvingNoiseRoundTripper() http.RoundTripper { - return keyProvingNoiseRoundTripper{b} -} - // DoNoiseRequest sends a request to URL over the control plane // Noise connection. func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error) { @@ -7264,6 +6765,15 @@ func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error) return cc.DoNoiseRequest(req) } +// ActiveSSHConns returns the number of active SSH connections, +// or 0 if SSH is not linked into the binary or available on the platform. +func (b *LocalBackend) ActiveSSHConns() int { + if b.sshServer == nil { + return 0 + } + return b.sshServer.NumActiveConns() +} + func (b *LocalBackend) sshServerOrInit() (_ SSHServer, err error) { b.mu.Lock() defer b.mu.Unlock() @@ -7280,6 +6790,13 @@ func (b *LocalBackend) sshServerOrInit() (_ SSHServer, err error) { return b.sshServer, nil } +var warnSyncDisabled = health.Register(&health.Warnable{ + Code: "sync-disabled", + Title: "Tailscale Sync is Disabled", + Severity: health.SeverityHigh, + Text: health.StaticMessage("Tailscale control plane syncing is disabled; run `tailscale set --sync` to restore"), +}) + var warnSSHSELinuxWarnable = health.Register(&health.Warnable{ Code: "ssh-unavailable-selinux-enabled", Title: "Tailscale SSH and SELinux", @@ -7295,6 +6812,14 @@ func (b *LocalBackend) updateSELinuxHealthWarning() { } } +func (b *LocalBackend) updateWarnSync(prefs ipn.PrefsView) { + if prefs.Sync().EqualBool(false) { + b.health.SetUnhealthy(warnSyncDisabled, nil) + } else { + b.health.SetHealthy(warnSyncDisabled) + } +} + func (b *LocalBackend) handleSSHConn(c net.Conn) (err error) { s, err := b.sshServerOrInit() if err != nil { @@ -7339,11 +6864,12 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re defer b.mu.Unlock() io.WriteString(w, "

Tailscale

\n") - if b.netMap == nil { + nm := b.currentNode().NetMap() + if nm == nil { io.WriteString(w, "No netmap.\n") return } - addrs := b.netMap.GetAddresses() + addrs := nm.GetAddresses() if addrs.Len() == 0 { io.WriteString(w, "No local addresses.\n") return @@ -7355,56 +6881,8 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re io.WriteString(w, "\n") } -func (b *LocalBackend) Doctor(ctx context.Context, logf logger.Logf) { - // We can write logs too fast for logtail to handle, even when - // opting-out of rate limits. Limit ourselves to at most one message - // per 20ms and a burst of 60 log lines, which should be fast enough to - // not block for too long but slow enough that we can upload all lines. - logf = logger.SlowLoggerWithClock(ctx, logf, 20*time.Millisecond, 60, b.clock.Now) - - var checks []doctor.Check - checks = append(checks, - permissions.Check{}, - routetable.Check{}, - ethtool.Check{}, - ) - - // Print a log message if any of the global DNS resolvers are Tailscale - // IPs; this can interfere with our ability to connect to the Tailscale - // controlplane. - checks = append(checks, doctor.CheckFunc("dns-resolvers", func(_ context.Context, logf logger.Logf) error { - b.mu.Lock() - nm := b.netMap - b.mu.Unlock() - if nm == nil { - return nil - } - - for i, resolver := range nm.DNS.Resolvers { - ipp, ok := resolver.IPPort() - if ok && tsaddr.IsTailscaleIP(ipp.Addr()) { - logf("resolver %d is a Tailscale address: %v", i, resolver) - } - } - for i, resolver := range nm.DNS.FallbackResolvers { - ipp, ok := resolver.IPPort() - if ok && tsaddr.IsTailscaleIP(ipp.Addr()) { - logf("fallback resolver %d is a Tailscale address: %v", i, resolver) - } - } - return nil - })) - - // TODO(andrew): more - - numChecks := len(checks) - checks = append(checks, doctor.CheckFunc("numchecks", func(_ context.Context, log logger.Logf) error { - log("%d checks", numChecks) - return nil - })) - - doctor.RunChecks(ctx, logf, checks...) -} +// HookDoctor is an optional hook for the "doctor" problem diagnosis feature. +var HookDoctor feature.Hook[func(context.Context, *LocalBackend, logger.Logf)] // SetDevStateStore updates the LocalBackend's state storage to the provided values. // @@ -7437,78 +6915,34 @@ func (b *LocalBackend) ShouldInterceptTCPPort(port uint16) bool { // ShouldInterceptVIPServiceTCPPort reports whether the given TCP port number // to a VIP service should be intercepted by Tailscaled and handled in-process. func (b *LocalBackend) ShouldInterceptVIPServiceTCPPort(ap netip.AddrPort) bool { - return b.shouldInterceptVIPServicesTCPPortAtomic.Load()(ap) + if !buildfeatures.HasServe { + return false + } + f := b.shouldInterceptVIPServicesTCPPortAtomic.Load() + if f == nil { + return false + } + return f(ap) } // SwitchProfile switches to the profile with the given id. // It will restart the backend on success. // If the profile is not known, it returns an errProfileNotFound. func (b *LocalBackend) SwitchProfile(profile ipn.ProfileID) error { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() - if b.pm.CurrentProfile().ID() == profile { - return nil - } - - oldControlURL := b.pm.CurrentPrefs().ControlURLOrDefault() - if err := b.pm.SwitchProfile(profile); err != nil { - return err + oldControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(b.polc) + if _, changed, err := b.pm.SwitchToProfileByID(profile); !changed || err != nil { + return err // nil if we're already on the target profile } // As an optimization, only reset the dialPlan if the control URL changed. - if newControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(); oldControlURL != newControlURL { + if newControlURL := b.pm.CurrentPrefs().ControlURLOrDefault(b.polc); oldControlURL != newControlURL { b.resetDialPlan() } - return b.resetForProfileChangeLockedOnEntry(unlock) -} - -func (b *LocalBackend) initTKALocked() error { - cp := b.pm.CurrentProfile() - if cp.ID() == "" { - b.tka = nil - return nil - } - if b.tka != nil { - if b.tka.profile == cp.ID() { - // Already initialized. - return nil - } - // As we're switching profiles, we need to reset the TKA to nil. - b.tka = nil - } - root := b.TailscaleVarRoot() - if root == "" { - b.tka = nil - b.logf("network-lock unavailable; no state directory") - return nil - } - - chonkDir := b.chonkPathLocked() - if _, err := os.Stat(chonkDir); err == nil { - // The directory exists, which means network-lock has been initialized. - storage, err := tka.ChonkDir(chonkDir) - if err != nil { - return fmt.Errorf("opening tailchonk: %v", err) - } - authority, err := tka.Open(storage) - if err != nil { - return fmt.Errorf("initializing tka: %v", err) - } - if err := authority.Compact(storage, tkaCompactionDefaults); err != nil { - b.logf("tka compaction failed: %v", err) - } - - b.tka = &tkaState{ - profile: cp.ID(), - authority: authority, - storage: storage, - } - b.logf("tka initialized at head %x", authority.Head()) - } - - return nil + return b.resetForProfileChangeLocked() } // resetDialPlan resets the dialPlan for this LocalBackend. It will log if @@ -7522,25 +6956,28 @@ func (b *LocalBackend) resetDialPlan() { } } -// resetForProfileChangeLockedOnEntry resets the backend for a profile change. +// resetForProfileChangeLocked resets the backend for a profile change. // -// b.mu must held on entry. It is released on exit. -func (b *LocalBackend) resetForProfileChangeLockedOnEntry(unlock unlockOnce) error { - defer unlock() - +// b.mu must be held. +func (b *LocalBackend) resetForProfileChangeLocked() error { if b.shutdownCalled { // Prevent a call back to Start during Shutdown, which calls Logout for // ephemeral nodes, which can then call back here. But we're shutting // down, so no need to do any work. return nil } + newNode := newNodeBackend(b.ctx, b.logf, b.sys.Bus.Get()) + if oldNode := b.currentNodeAtomic.Swap(newNode); oldNode != nil { + oldNode.shutdown(errNodeContextChanged) + } + defer newNode.ready() b.setNetMapLocked(nil) // Reset netmap. - b.updateFilterLocked(nil, ipn.PrefsView{}) + b.updateFilterLocked(ipn.PrefsView{}) // Reset the NetworkMap in the engine b.e.SetNetworkMap(new(netmap.NetworkMap)) if prevCC := b.resetControlClientLocked(); prevCC != nil { - // Needs to happen without b.mu held. - defer prevCC.Shutdown() + // Shutdown outside of b.mu to avoid deadlocks. + b.goTracker.Go(prevCC.Shutdown) } // TKA errors should not prevent resetting the backend state. // However, we should still return the error to the caller. @@ -7549,21 +6986,23 @@ func (b *LocalBackend) resetForProfileChangeLockedOnEntry(unlock unlockOnce) err b.serveConfig = ipn.ServeConfigView{} b.lastSuggestedExitNode = "" b.keyExpired = false + b.overrideExitNodePolicy = false b.resetAlwaysOnOverrideLocked() + b.extHost.NotifyProfileChange(b.pm.CurrentProfile(), b.pm.CurrentPrefs(), false) b.setAtomicValuesFromPrefsLocked(b.pm.CurrentPrefs()) - b.enterStateLockedOnEntry(ipn.NoState, unlock) // Reset state; releases b.mu + b.enterStateLocked(ipn.NoState) b.health.SetLocalLogConfigHealth(nil) if tkaErr != nil { return tkaErr } - return b.Start(ipn.Options{}) + return b.startLocked(ipn.Options{}) } // DeleteProfile deletes a profile with the given ID. // If the profile is not known, it is a no-op. func (b *LocalBackend) DeleteProfile(p ipn.ProfileID) error { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() needToRestart := b.pm.CurrentProfile().ID() == p if err := b.pm.DeleteProfile(p); err != nil { @@ -7575,7 +7014,7 @@ func (b *LocalBackend) DeleteProfile(p ipn.ProfileID) error { if !needToRestart { return nil } - return b.resetForProfileChangeLockedOnEntry(unlock) + return b.resetForProfileChangeLocked() } // CurrentProfile returns the current LoginProfile. @@ -7588,16 +7027,19 @@ func (b *LocalBackend) CurrentProfile() ipn.LoginProfileView { // NewProfile creates and switches to the new profile. func (b *LocalBackend) NewProfile() error { - unlock := b.lockAndGetUnlock() - defer unlock() + if b.health.IsUnhealthy(ipn.StateStoreHealth) { + return errors.New("cannot log in when state store is unhealthy") + } + b.mu.Lock() + defer b.mu.Unlock() - b.pm.NewProfile() + b.pm.SwitchToNewProfile() // The new profile doesn't yet have a ControlURL because it hasn't been // set. Conservatively reset the dialPlan. b.resetDialPlan() - return b.resetForProfileChangeLockedOnEntry(unlock) + return b.resetForProfileChangeLocked() } // ListProfiles returns a list of all LoginProfiles. @@ -7612,12 +7054,12 @@ func (b *LocalBackend) ListProfiles() []ipn.LoginProfileView { // backend is left with a new profile, ready for StartLoginInterative to be // called to register it as new node. func (b *LocalBackend) ResetAuth() error { - unlock := b.lockAndGetUnlock() - defer unlock() + b.mu.Lock() + defer b.mu.Unlock() - prevCC := b.resetControlClientLocked() - if prevCC != nil { - defer prevCC.Shutdown() // call must happen after release b.mu + if prevCC := b.resetControlClientLocked(); prevCC != nil { + // Shutdown outside of b.mu to avoid deadlocks. + b.goTracker.Go(prevCC.Shutdown) } if err := b.clearMachineKeyLocked(); err != nil { return err @@ -7626,7 +7068,7 @@ func (b *LocalBackend) ResetAuth() error { return err } b.resetDialPlan() // always reset if we're removing everything - return b.resetForProfileChangeLockedOnEntry(unlock) + return b.resetForProfileChangeLocked() } func (b *LocalBackend) GetPeerEndpointChanges(ctx context.Context, ip netip.Addr) ([]magicsock.EndpointChange, error) { @@ -7659,57 +7101,12 @@ func (b *LocalBackend) DebugBreakDERPConns() error { return b.MagicConn().DebugBreakDERPConns() } -func (b *LocalBackend) pushSelfUpdateProgress(up ipnstate.UpdateProgress) { - b.mu.Lock() - defer b.mu.Unlock() - b.selfUpdateProgress = append(b.selfUpdateProgress, up) - b.lastSelfUpdateState = up.Status -} - -func (b *LocalBackend) clearSelfUpdateProgress() { - b.mu.Lock() - defer b.mu.Unlock() - b.selfUpdateProgress = make([]ipnstate.UpdateProgress, 0) - b.lastSelfUpdateState = ipnstate.UpdateFinished -} - -func (b *LocalBackend) GetSelfUpdateProgress() []ipnstate.UpdateProgress { - b.mu.Lock() - defer b.mu.Unlock() - res := make([]ipnstate.UpdateProgress, len(b.selfUpdateProgress)) - copy(res, b.selfUpdateProgress) - return res -} - -func (b *LocalBackend) DoSelfUpdate() { - b.mu.Lock() - updateState := b.lastSelfUpdateState - b.mu.Unlock() - // don't start an update if one is already in progress - if updateState == ipnstate.UpdateInProgress { - return - } - b.clearSelfUpdateProgress() - b.pushSelfUpdateProgress(ipnstate.NewUpdateProgress(ipnstate.UpdateInProgress, "")) - up, err := clientupdate.NewUpdater(clientupdate.Arguments{ - Logf: func(format string, args ...any) { - b.pushSelfUpdateProgress(ipnstate.NewUpdateProgress(ipnstate.UpdateInProgress, fmt.Sprintf(format, args...))) - }, - }) - if err != nil { - b.pushSelfUpdateProgress(ipnstate.NewUpdateProgress(ipnstate.UpdateFailed, err.Error())) - } - err = up.Update() - if err != nil { - b.pushSelfUpdateProgress(ipnstate.NewUpdateProgress(ipnstate.UpdateFailed, err.Error())) - } else { - b.pushSelfUpdateProgress(ipnstate.NewUpdateProgress(ipnstate.UpdateFinished, "tailscaled did not restart; please restart Tailscale manually.")) - } -} - // ObserveDNSResponse passes a DNS response from the PeerAPI DNS server to the // App Connector to enable route discovery. func (b *LocalBackend) ObserveDNSResponse(res []byte) error { + if !buildfeatures.HasAppConnectors { + return nil + } var appConnector *appc.AppConnector b.mu.Lock() if b.appConnector == nil { @@ -7725,9 +7122,9 @@ func (b *LocalBackend) ObserveDNSResponse(res []byte) error { // ErrDisallowedAutoRoute is returned by AdvertiseRoute when a route that is not allowed is requested. var ErrDisallowedAutoRoute = errors.New("route is not allowed") -// AdvertiseRoute implements the appc.RouteAdvertiser interface. It sets a new -// route advertisement if one is not already present in the existing routes. -// If the route is disallowed, ErrDisallowedAutoRoute is returned. +// AdvertiseRoute implements the appctype.RouteAdvertiser interface. It sets a +// new route advertisement if one is not already present in the existing +// routes. If the route is disallowed, ErrDisallowedAutoRoute is returned. func (b *LocalBackend) AdvertiseRoute(ipps ...netip.Prefix) error { finalRoutes := b.Prefs().AdvertiseRoutes().AsSlice() var newRoutes []netip.Prefix @@ -7783,8 +7180,8 @@ func coveredRouteRangeNoDefault(finalRoutes []netip.Prefix, ipp netip.Prefix) bo return false } -// UnadvertiseRoute implements the appc.RouteAdvertiser interface. It removes -// a route advertisement if one is present in the existing routes. +// UnadvertiseRoute implements the appctype.RouteAdvertiser interface. It +// removes a route advertisement if one is present in the existing routes. func (b *LocalBackend) UnadvertiseRoute(toRemove ...netip.Prefix) error { currentRoutes := b.Prefs().AdvertiseRoutes().AsSlice() finalRoutes := currentRoutes[:0] @@ -7812,7 +7209,10 @@ func namespaceKeyForCurrentProfile(pm *profileManager, key ipn.StateKey) ipn.Sta const routeInfoStateStoreKey ipn.StateKey = "_routeInfo" -func (b *LocalBackend) storeRouteInfo(ri *appc.RouteInfo) error { +func (b *LocalBackend) storeRouteInfo(ri appctype.RouteInfo) error { + if !buildfeatures.HasAppConnectors { + return feature.ErrUnavailable + } b.mu.Lock() defer b.mu.Unlock() if b.pm.CurrentProfile().ID() == "" { @@ -7826,13 +7226,16 @@ func (b *LocalBackend) storeRouteInfo(ri *appc.RouteInfo) error { return b.pm.WriteState(key, bs) } -func (b *LocalBackend) readRouteInfoLocked() (*appc.RouteInfo, error) { +func (b *LocalBackend) readRouteInfoLocked() (*appctype.RouteInfo, error) { + if !buildfeatures.HasAppConnectors { + return nil, feature.ErrUnavailable + } if b.pm.CurrentProfile().ID() == "" { - return &appc.RouteInfo{}, nil + return &appctype.RouteInfo{}, nil } key := namespaceKeyForCurrentProfile(b.pm, routeInfoStateStoreKey) bs, err := b.pm.Store().ReadState(key) - ri := &appc.RouteInfo{} + ri := &appctype.RouteInfo{} if err != nil { return nil, err } @@ -7842,10 +7245,19 @@ func (b *LocalBackend) readRouteInfoLocked() (*appc.RouteInfo, error) { return ri, nil } -// seamlessRenewalEnabled reports whether seamless key renewals are enabled -// (i.e. we saw our self node with the SeamlessKeyRenewal attr in a netmap). -// This enables beta functionality of renewing node keys without breaking -// connections. +// ReadRouteInfo returns the app connector route information that is +// stored in prefs to be consistent across restarts. It should be up +// to date with the RouteInfo in memory being used by appc. +func (b *LocalBackend) ReadRouteInfo() (*appctype.RouteInfo, error) { + b.mu.Lock() + defer b.mu.Unlock() + return b.readRouteInfoLocked() +} + +// seamlessRenewalEnabled reports whether seamless key renewals are enabled. +// +// As of 2025-09-11, this is the default behaviour unless nodes receive +// [tailcfg.NodeAttrDisableSeamlessKeyRenewal] in their netmap. func (b *LocalBackend) seamlessRenewalEnabled() bool { return b.ControlKnobs().SeamlessKeyRenewal.Load() } @@ -7880,52 +7292,45 @@ func allowedAutoRoute(ipp netip.Prefix) bool { return true } -// mayDeref dereferences p if non-nil, otherwise it returns the zero value. -func mayDeref[T any](p *T) (v T) { - if p == nil { - return v - } - return *p -} - var ErrNoPreferredDERP = errors.New("no preferred DERP, try again later") -// suggestExitNodeLocked computes a suggestion based on the current netmap and last netcheck report. If -// there are multiple equally good options, one is selected at random, so the result is not stable. To be -// eligible for consideration, the peer must have NodeAttrSuggestExitNode in its CapMap. +// suggestExitNodeLocked computes a suggestion based on the current netmap and +// other optional factors. If there are multiple equally good options, one may +// be selected at random, so the result is not stable. To be eligible for +// consideration, the peer must have NodeAttrSuggestExitNode in its CapMap. // -// Currently, peers with a DERP home are preferred over those without (typically this means Mullvad). -// Peers are selected based on having a DERP home that is the lowest latency to this device. For peers -// without a DERP home, we look for geographic proximity to this device's DERP home. -// -// netMap is an optional netmap to use that overrides b.netMap (needed for SetControlClientStatus before b.netMap is updated). -// If netMap is nil, then b.netMap is used. -// -// b.mu.lock() must be held. -func (b *LocalBackend) suggestExitNodeLocked(netMap *netmap.NetworkMap) (response apitype.ExitNodeSuggestionResponse, err error) { - // netMap is an optional netmap to use that overrides b.netMap (needed for SetControlClientStatus before b.netMap is updated). If netMap is nil, then b.netMap is used. - if netMap == nil { - netMap = b.netMap +// b.mu must be held. +func (b *LocalBackend) suggestExitNodeLocked() (response apitype.ExitNodeSuggestionResponse, err error) { + if !buildfeatures.HasUseExitNode { + return response, feature.ErrUnavailable } lastReport := b.MagicConn().GetLastNetcheckReport(b.ctx) prevSuggestion := b.lastSuggestedExitNode - res, err := suggestExitNode(lastReport, netMap, prevSuggestion, randomRegion, randomNode, b.getAllowedSuggestions()) + res, err := suggestExitNode(lastReport, b.currentNode(), prevSuggestion, randomRegion, randomNode, b.getAllowedSuggestions()) if err != nil { return res, err } + if prevSuggestion != res.ID { + // Notify the clients via the IPN bus if the exit node suggestion has changed. + b.sendToLocked(ipn.Notify{SuggestedExitNode: &res.ID}, allClients) + } b.lastSuggestedExitNode = res.ID + return res, err } func (b *LocalBackend) SuggestExitNode() (response apitype.ExitNodeSuggestionResponse, err error) { + if !buildfeatures.HasUseExitNode { + return response, feature.ErrUnavailable + } b.mu.Lock() defer b.mu.Unlock() - return b.suggestExitNodeLocked(nil) + return b.suggestExitNodeLocked() } // getAllowedSuggestions returns a set of exit nodes permitted by the most recent -// [syspolicy.AllowedSuggestedExitNodes] value. Callers must not mutate the returned set. +// [pkey.AllowedSuggestedExitNodes] value. Callers must not mutate the returned set. func (b *LocalBackend) getAllowedSuggestions() set.Set[tailcfg.StableNodeID] { b.allowedSuggestedExitNodesMu.Lock() defer b.allowedSuggestedExitNodesMu.Unlock() @@ -7933,11 +7338,19 @@ func (b *LocalBackend) getAllowedSuggestions() set.Set[tailcfg.StableNodeID] { } // refreshAllowedSuggestions rebuilds the set of permitted exit nodes -// from the current [syspolicy.AllowedSuggestedExitNodes] value. +// from the current [pkey.AllowedSuggestedExitNodes] value. func (b *LocalBackend) refreshAllowedSuggestions() { + if !buildfeatures.HasUseExitNode { + return + } b.allowedSuggestedExitNodesMu.Lock() defer b.allowedSuggestedExitNodesMu.Unlock() - b.allowedSuggestedExitNodes = fillAllowedSuggestions() + + var err error + b.allowedSuggestedExitNodes, err = fillAllowedSuggestions(b.polc) + if err != nil { + b.logf("error refreshing allowed suggestions: %v", err) + } } // selectRegionFunc returns a DERP region from the slice of candidate regions. @@ -7949,38 +7362,70 @@ type selectRegionFunc func(views.Slice[int]) int // choice. type selectNodeFunc func(nodes views.Slice[tailcfg.NodeView], last tailcfg.StableNodeID) tailcfg.NodeView -func fillAllowedSuggestions() set.Set[tailcfg.StableNodeID] { - nodes, err := syspolicy.GetStringArray(syspolicy.AllowedSuggestedExitNodes, nil) +func fillAllowedSuggestions(polc policyclient.Client) (set.Set[tailcfg.StableNodeID], error) { + nodes, err := polc.GetStringArray(pkey.AllowedSuggestedExitNodes, nil) if err != nil { - log.Printf("fillAllowedSuggestions: unable to look up %q policy: %v", syspolicy.AllowedSuggestedExitNodes, err) - return nil + return nil, fmt.Errorf("fillAllowedSuggestions: unable to look up %q policy: %w", pkey.AllowedSuggestedExitNodes, err) } if nodes == nil { - return nil + return nil, nil } s := make(set.Set[tailcfg.StableNodeID], len(nodes)) for _, n := range nodes { s.Add(tailcfg.StableNodeID(n)) } - return s + return s, nil } -func suggestExitNode(report *netcheck.Report, netMap *netmap.NetworkMap, prevSuggestion tailcfg.StableNodeID, selectRegion selectRegionFunc, selectNode selectNodeFunc, allowList set.Set[tailcfg.StableNodeID]) (res apitype.ExitNodeSuggestionResponse, err error) { +// suggestExitNode returns a suggestion for reasonably good exit node based on +// the current netmap and the previous suggestion. +func suggestExitNode(report *netcheck.Report, nb *nodeBackend, prevSuggestion tailcfg.StableNodeID, selectRegion selectRegionFunc, selectNode selectNodeFunc, allowList set.Set[tailcfg.StableNodeID]) (res apitype.ExitNodeSuggestionResponse, err error) { + switch { + case nb.SelfHasCap(tailcfg.NodeAttrTrafficSteering): + // The traffic-steering feature flag is enabled on this tailnet. + return suggestExitNodeUsingTrafficSteering(nb, allowList) + default: + // The control plane will always strip the `traffic-steering` + // node attribute if it isn’t enabled for this tailnet, even if + // it is set in the policy file: tailscale/corp#34401 + return suggestExitNodeUsingDERP(report, nb, prevSuggestion, selectRegion, selectNode, allowList) + } +} + +// suggestExitNodeUsingDERP is the classic algorithm used to suggest exit nodes, +// before traffic steering was implemented. This handles the plain failover +// case, in addition to the optional Regional Routing. +// +// It computes a suggestion based on the current netmap and last netcheck +// report. If there are multiple equally good options, one is selected at +// random, so the result is not stable. To be eligible for consideration, the +// peer must have NodeAttrSuggestExitNode in its CapMap. +// +// Currently, peers with a DERP home are preferred over those without (typically +// this means Mullvad). Peers are selected based on having a DERP home that is +// the lowest latency to this device. For peers without a DERP home, we look for +// geographic proximity to this device's DERP home. +func suggestExitNodeUsingDERP(report *netcheck.Report, nb *nodeBackend, prevSuggestion tailcfg.StableNodeID, selectRegion selectRegionFunc, selectNode selectNodeFunc, allowList set.Set[tailcfg.StableNodeID]) (res apitype.ExitNodeSuggestionResponse, err error) { + // TODO(sfllaw): Context needs to be plumbed down here to support + // reachability testing. + ctx := context.TODO() + + netMap := nb.NetMap() if report == nil || report.PreferredDERP == 0 || netMap == nil || netMap.DERPMap == nil { return res, ErrNoPreferredDERP } - candidates := make([]tailcfg.NodeView, 0, len(netMap.Peers)) - for _, peer := range netMap.Peers { - if !peer.Valid() { - continue + // Use [nodeBackend.AppendMatchingPeers] instead of the netmap directly, + // since the netmap doesn't include delta updates (e.g., home DERP or Online + // status changes) from the control plane since the last full update. + candidates := nb.AppendMatchingPeers(nil, func(peer tailcfg.NodeView) bool { + if !peer.Valid() || !nb.PeerIsReachable(ctx, peer) { + return false } if allowList != nil && !allowList.Contains(peer.StableID()) { - continue + return false } - if peer.CapMap().Contains(tailcfg.NodeAttrSuggestExitNode) && tsaddr.ContainsExitRoutes(peer.AllowedIPs()) { - candidates = append(candidates, peer) - } - } + return peer.CapMap().Contains(tailcfg.NodeAttrSuggestExitNode) && tsaddr.ContainsExitRoutes(peer.AllowedIPs()) + }) if len(candidates) == 0 { return res, nil } @@ -8071,6 +7516,16 @@ func suggestExitNode(report *netcheck.Report, netMap *netmap.NetworkMap, prevSug } } bestCandidates := pickWeighted(pickFrom) + + // We may have an empty list of candidates here, if none of the candidates + // have home DERP info. + // + // We know that candidates is non-empty or we'd already have returned, so if + // we've filtered everything out of bestCandidates, just use candidates. + if len(bestCandidates) == 0 { + bestCandidates = candidates + } + chosen := selectNode(views.SliceOf(bestCandidates), prevSuggestion) if !chosen.Valid() { return res, errors.New("chosen candidate invalid: this is a bug") @@ -8085,6 +7540,103 @@ func suggestExitNode(report *netcheck.Report, netMap *netmap.NetworkMap, prevSug return res, nil } +var ErrNoNetMap = errors.New("no network map, try again later") + +// suggestExitNodeUsingTrafficSteering uses traffic steering priority scores to +// pick one of the best exit nodes. These priorities are provided by Control in +// the node’s [tailcfg.Location]. To be eligible for consideration, the node +// must have NodeAttrSuggestExitNode in its CapMap. +func suggestExitNodeUsingTrafficSteering(nb *nodeBackend, allowed set.Set[tailcfg.StableNodeID]) (apitype.ExitNodeSuggestionResponse, error) { + // TODO(sfllaw): Context needs to be plumbed down here to support + // reachability testing. + ctx := context.TODO() + + nm := nb.NetMap() + if nm == nil { + return apitype.ExitNodeSuggestionResponse{}, ErrNoNetMap + } + + self := nb.Self() + if !self.Valid() { + return apitype.ExitNodeSuggestionResponse{}, ErrNoNetMap + } + + if !nb.SelfHasCap(tailcfg.NodeAttrTrafficSteering) { + panic("missing traffic-steering capability") + } + + nodes := nb.AppendMatchingPeers(nil, func(p tailcfg.NodeView) bool { + if !p.Valid() { + return false + } + if !nb.PeerIsReachable(ctx, p) { + return false + } + if allowed != nil && !allowed.Contains(p.StableID()) { + return false + } + if !p.CapMap().Contains(tailcfg.NodeAttrSuggestExitNode) { + return false + } + if !tsaddr.ContainsExitRoutes(p.AllowedIPs()) { + return false + } + return true + }) + + scores := make(map[tailcfg.NodeID]int, len(nodes)) + score := func(n tailcfg.NodeView) int { + id := n.ID() + s, ok := scores[id] + if !ok { + s = 0 // score of zero means incomparable + if hi := n.Hostinfo(); hi.Valid() { + if loc := hi.Location(); loc.Valid() { + s = loc.Priority() + } + } + scores[id] = s + } + return s + } + rdvHash := makeRendezvousHasher(self.ID()) + + var pick tailcfg.NodeView + if len(nodes) == 1 { + pick = nodes[0] + } + if len(nodes) > 1 { + // Find the highest scoring exit nodes. + slices.SortFunc(nodes, func(a, b tailcfg.NodeView) int { + c := cmp.Compare(score(b), score(a)) // Highest score first. + if c == 0 { + // Rendezvous hashing for reliably picking the + // same node from a list: tailscale/tailscale#16551. + return cmp.Compare(rdvHash(b.ID()), rdvHash(a.ID())) + } + return c + }) + + // TODO(sfllaw): add a temperature knob so that this client has + // a chance of picking the next best option. + pick = nodes[0] + } + + if !pick.Valid() { + return apitype.ExitNodeSuggestionResponse{}, nil + } + res := apitype.ExitNodeSuggestionResponse{ + ID: pick.StableID(), + Name: pick.Name(), + } + if hi := pick.Hostinfo(); hi.Valid() { + if loc := hi.Location(); loc.Valid() { + res.Location = loc + } + } + return res, nil +} + // pickWeighted chooses the node with highest priority given a list of mullvad nodes. func pickWeighted(candidates []tailcfg.NodeView) []tailcfg.NodeView { maxWeight := 0 @@ -8168,83 +7720,57 @@ func longLatDistance(fromLat, fromLong, toLat, toLong float64) float64 { return earthRadiusMeters * c } -// shouldAutoExitNode checks for the auto exit node MDM policy. -func shouldAutoExitNode() bool { - exitNodeIDStr, _ := syspolicy.GetString(syspolicy.ExitNodeID, "") - return exitNodeIDStr == "auto:any" +// makeRendezvousHasher returns a function that hashes a node ID to a uint64. +// https://en.wikipedia.org/wiki/Rendezvous_hashing +func makeRendezvousHasher(seed tailcfg.NodeID) func(tailcfg.NodeID) uint64 { + en := binary.BigEndian + return func(n tailcfg.NodeID) uint64 { + var b [16]byte + en.PutUint64(b[:], uint64(seed)) + en.PutUint64(b[8:], uint64(n)) + v := sha256.Sum256(b[:]) + return en.Uint64(v[:]) + } } -// startAutoUpdate triggers an auto-update attempt. The actual update happens -// asynchronously. If another update is in progress, an error is returned. -func (b *LocalBackend) startAutoUpdate(logPrefix string) (retErr error) { - // Check if update was already started, and mark as started. - if !b.trySetC2NUpdateStarted() { - return errors.New("update already started") - } - defer func() { - // Clear the started flag if something failed. - if retErr != nil { - b.setC2NUpdateStarted(false) - } - }() +const ( + // unresolvedExitNodeID is a special [tailcfg.StableNodeID] value + // used as an exit node ID to install a blackhole route, preventing + // accidental non-exit-node usage until the [ipn.ExitNodeExpression] + // is evaluated and an actual exit node is selected. + // + // We use "auto:any" for compatibility with older, pre-[ipn.ExitNodeExpression] + // clients that have been using "auto:any" for this purpose for a long time. + unresolvedExitNodeID tailcfg.StableNodeID = "auto:any" +) - cmdTS, err := findCmdTailscale() - if err != nil { - return fmt.Errorf("failed to find cmd/tailscale binary: %w", err) +func isAllowedAutoExitNodeID(polc policyclient.Client, exitNodeID tailcfg.StableNodeID) bool { + if exitNodeID == "" { + return false // an exit node is required } - var ver struct { - Long string `json:"long"` + if nodes, _ := polc.GetStringArray(pkey.AllowedSuggestedExitNodes, nil); nodes != nil { + return slices.Contains(nodes, string(exitNodeID)) } - out, err := exec.Command(cmdTS, "version", "--json").Output() - if err != nil { - return fmt.Errorf("failed to find cmd/tailscale binary: %w", err) - } - if err := json.Unmarshal(out, &ver); err != nil { - return fmt.Errorf("invalid JSON from cmd/tailscale version --json: %w", err) - } - if ver.Long != version.Long() { - return fmt.Errorf("cmd/tailscale version %q does not match tailscaled version %q", ver.Long, version.Long()) - } - - cmd := tailscaleUpdateCmd(cmdTS) - buf := new(bytes.Buffer) - cmd.Stdout = buf - cmd.Stderr = buf - b.logf("%s: running %q", logPrefix, strings.Join(cmd.Args, " ")) - if err := cmd.Start(); err != nil { - return fmt.Errorf("failed to start cmd/tailscale update: %w", err) - } - - go func() { - if err := cmd.Wait(); err != nil { - b.logf("%s: update command failed: %v, output: %s", logPrefix, err, buf) - } else { - b.logf("%s: update attempt complete", logPrefix) - } - b.setC2NUpdateStarted(false) - }() - return nil + return true // no policy configured; allow all exit nodes } // srcIPHasCapForFilter is called by the packet filter when evaluating firewall // rules that require a source IP to have a certain node capability. // // TODO(bradfitz): optimize this later if/when it matters. +// TODO(nickkhyl): move this into [nodeBackend] along with [LocalBackend.updateFilterLocked]. func (b *LocalBackend) srcIPHasCapForFilter(srcIP netip.Addr, cap tailcfg.NodeCapability) bool { if cap == "" { // Shouldn't happen, but just in case. // But the empty cap also shouldn't be found in Node.CapMap. return false } - - b.mu.Lock() - defer b.mu.Unlock() - - nodeID, ok := b.nodeByAddr[srcIP] + cn := b.currentNode() + nodeID, ok := cn.NodeByAddr(srcIP) if !ok { return false } - n, ok := b.peers[nodeID] + n, ok := cn.NodeByID(nodeID) if !ok { return false } @@ -8261,60 +7787,28 @@ func maybeUsernameOf(actor ipnauth.Actor) string { return username } -// VIPServices returns the list of tailnet services that this node -// is serving as a destination for. -// The returned memory is owned by the caller. -func (b *LocalBackend) VIPServices() []*tailcfg.VIPService { - b.mu.Lock() - defer b.mu.Unlock() - return b.vipServicesFromPrefsLocked(b.pm.CurrentPrefs()) -} - -func (b *LocalBackend) vipServiceHash(services []*tailcfg.VIPService) string { - if len(services) == 0 { - return "" - } - buf, err := json.Marshal(services) - if err != nil { - b.logf("vipServiceHashLocked: %v", err) - return "" - } - hash := sha256.Sum256(buf) - return hex.EncodeToString(hash[:]) -} - -func (b *LocalBackend) vipServicesFromPrefsLocked(prefs ipn.PrefsView) []*tailcfg.VIPService { - // keyed by service name - var services map[tailcfg.ServiceName]*tailcfg.VIPService - if b.serveConfig.Valid() { - for svc, config := range b.serveConfig.Services().All() { - mak.Set(&services, svc, &tailcfg.VIPService{ - Name: svc, - Ports: config.ServicePortRange(), - }) - } - } - - for _, s := range prefs.AdvertiseServices().All() { - sn := tailcfg.ServiceName(s) - if services == nil || services[sn] == nil { - mak.Set(&services, sn, &tailcfg.VIPService{ - Name: sn, - }) - } - services[sn].Active = true - } - - servicesList := slicesx.MapValues(services) - // [slicesx.MapValues] provides the values in an indeterminate order, but since we'll - // be hashing a representation of this list later we want it to be in a consistent - // order. - slices.SortFunc(servicesList, func(a, b *tailcfg.VIPService) int { - return strings.Compare(a.Name.String(), b.Name.String()) - }) - return servicesList -} - var ( metricCurrentWatchIPNBus = clientmetric.NewGauge("localbackend_current_watch_ipn_bus") ) + +func (b *LocalBackend) stateEncrypted() opt.Bool { + switch runtime.GOOS { + case "android", "ios": + return opt.NewBool(true) + case "darwin": + switch { + case version.IsMacAppStore(): + return opt.NewBool(true) + case version.IsMacSysExt(): + sp, _ := b.polc.GetBoolean(pkey.EncryptState, true) + return opt.NewBool(sp) + default: + // Probably self-compiled tailscaled, we don't use the Keychain + // there. + return opt.NewBool(false) + } + default: + _, ok := b.store.(ipn.EncryptedStateStore) + return opt.NewBool(ok) + } +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/netstack.go b/vendor/tailscale.com/ipn/ipnlocal/netstack.go new file mode 100644 index 0000000..f7ffd03 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/netstack.go @@ -0,0 +1,74 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_netstack + +package ipnlocal + +import ( + "net" + "net/netip" + "time" + + "gvisor.dev/gvisor/pkg/tcpip" + "tailscale.com/types/ptr" +) + +// TCPHandlerForDst returns a TCP handler for connections to dst, or nil if +// no handler is needed. It also returns a list of TCP socket options to +// apply to the socket before calling the handler. +// TCPHandlerForDst is called both for connections to our node's local IP +// as well as to the service IP (quad 100). +func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c net.Conn) error, opts []tcpip.SettableSocketOption) { + // First handle internal connections to the service IP + hittingServiceIP := dst.Addr() == magicDNSIP || dst.Addr() == magicDNSIPv6 + if hittingServiceIP { + switch dst.Port() { + case 80: + // TODO(mpminardi): do we want to show an error message if the web client + // has been disabled instead of the more "basic" web UI? + if b.ShouldRunWebClient() { + return b.handleWebClientConn, opts + } + return b.HandleQuad100Port80Conn, opts + case DriveLocalPort: + return b.handleDriveConn, opts + } + } + + if f, ok := hookServeTCPHandlerForVIPService.GetOk(); ok { + if handler := f(b, dst, src); handler != nil { + return handler, opts + } + } + // Then handle external connections to the local IP. + if !b.isLocalIP(dst.Addr()) { + return nil, nil + } + if dst.Port() == 22 && b.ShouldRunSSH() { + // Use a higher keepalive idle time for SSH connections, as they are + // typically long lived and idle connections are more likely to be + // intentional. Ideally we would turn this off entirely, but we can't + // tell the difference between a long lived connection that is idle + // vs a connection that is dead because the peer has gone away. + // We pick 72h as that is typically sufficient for a long weekend. + opts = append(opts, ptr.To(tcpip.KeepaliveIdleOption(72*time.Hour))) + return b.handleSSHConn, opts + } + // TODO(will,sonia): allow customizing web client port ? + if dst.Port() == webClientPort && b.ShouldExposeRemoteWebClient() { + return b.handleWebClientConn, opts + } + if port, ok := b.GetPeerAPIPort(dst.Addr()); ok && dst.Port() == port { + return func(c net.Conn) error { + b.handlePeerAPIConn(src, dst, c) + return nil + }, opts + } + if f, ok := hookTCPHandlerForServe.GetOk(); ok { + if handler := f(b, dst.Port(), src, nil); handler != nil { + return handler, opts + } + } + return nil, nil +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/network-lock.go b/vendor/tailscale.com/ipn/ipnlocal/network-lock.go index e1583da..246b264 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/network-lock.go +++ b/vendor/tailscale.com/ipn/ipnlocal/network-lock.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package ipnlocal import ( @@ -21,6 +23,7 @@ import ( "slices" "time" + "tailscale.com/health" "tailscale.com/health/healthmsg" "tailscale.com/ipn" "tailscale.com/ipn/ipnstate" @@ -52,10 +55,68 @@ var ( type tkaState struct { profile ipn.ProfileID authority *tka.Authority - storage *tka.FS + storage tka.CompactableChonk filtered []ipnstate.TKAPeer } +func (b *LocalBackend) initTKALocked() error { + cp := b.pm.CurrentProfile() + if cp.ID() == "" { + b.tka = nil + return nil + } + if b.tka != nil { + if b.tka.profile == cp.ID() { + // Already initialized. + return nil + } + // As we're switching profiles, we need to reset the TKA to nil. + b.tka = nil + } + root := b.TailscaleVarRoot() + if root == "" { + b.tka = nil + b.logf("cannot fetch existing TKA state; no state directory for network-lock") + return nil + } + + chonkDir := b.chonkPathLocked() + if _, err := os.Stat(chonkDir); err == nil { + // The directory exists, which means network-lock has been initialized. + storage, err := tka.ChonkDir(chonkDir) + if err != nil { + return fmt.Errorf("opening tailchonk: %v", err) + } + authority, err := tka.Open(storage) + if err != nil { + return fmt.Errorf("initializing tka: %v", err) + } + + if err := authority.Compact(storage, tkaCompactionDefaults); err != nil { + b.logf("tka compaction failed: %v", err) + } + + b.tka = &tkaState{ + profile: cp.ID(), + authority: authority, + storage: storage, + } + b.logf("tka initialized at head %x", authority.Head()) + } + + return nil +} + +// noNetworkLockStateDirWarnable is a Warnable to warn the user that Tailnet Lock data +// (in particular, the list of AUMs in the TKA state) is being stored in memory and will +// be lost when tailscaled restarts. +var noNetworkLockStateDirWarnable = health.Register(&health.Warnable{ + Code: "no-tailnet-lock-state-dir", + Title: "No statedir for Tailnet Lock", + Severity: health.SeverityMedium, + Text: health.StaticMessage(healthmsg.InMemoryTailnetLockState), +}) + // tkaFilterNetmapLocked checks the signatures on each node key, dropping // nodes from the netmap whose signature does not verify. // @@ -239,8 +300,11 @@ func (b *LocalBackend) tkaSyncIfNeeded(nm *netmap.NetworkMap, prefs ipn.PrefsVie return nil } - if b.tka != nil || nm.TKAEnabled { - b.logf("tkaSyncIfNeeded: enabled=%v, head=%v", nm.TKAEnabled, nm.TKAHead) + isEnabled := b.tka != nil + wantEnabled := nm.TKAEnabled + + if isEnabled || wantEnabled { + b.logf("tkaSyncIfNeeded: isEnabled=%t, wantEnabled=%t, head=%v", isEnabled, wantEnabled, nm.TKAHead) } ourNodeKey, ok := prefs.Persist().PublicNodeKeyOK() @@ -248,8 +312,6 @@ func (b *LocalBackend) tkaSyncIfNeeded(nm *netmap.NetworkMap, prefs ipn.PrefsVie return errors.New("tkaSyncIfNeeded: no node key in prefs") } - isEnabled := b.tka != nil - wantEnabled := nm.TKAEnabled didJustEnable := false if isEnabled != wantEnabled { var ourHead tka.AUMHash @@ -294,25 +356,18 @@ func (b *LocalBackend) tkaSyncIfNeeded(nm *netmap.NetworkMap, prefs ipn.PrefsVie if err := b.tkaSyncLocked(ourNodeKey); err != nil { return fmt.Errorf("tka sync: %w", err) } + // Try to compact the TKA state, to avoid unbounded storage on nodes. + // + // We run this on every sync so that clients compact consistently. In many + // cases this will be a no-op. + if err := b.tka.authority.Compact(b.tka.storage, tkaCompactionDefaults); err != nil { + return fmt.Errorf("tka compact: %w", err) + } } return nil } -func toSyncOffer(head string, ancestors []string) (tka.SyncOffer, error) { - var out tka.SyncOffer - if err := out.Head.UnmarshalText([]byte(head)); err != nil { - return tka.SyncOffer{}, fmt.Errorf("head.UnmarshalText: %v", err) - } - out.Ancestors = make([]tka.AUMHash, len(ancestors)) - for i, a := range ancestors { - if err := out.Ancestors[i].UnmarshalText([]byte(a)); err != nil { - return tka.SyncOffer{}, fmt.Errorf("ancestor[%d].UnmarshalText: %v", i, err) - } - } - return out, nil -} - // tkaSyncLocked synchronizes TKA state with control. b.mu must be held // and tka must be initialized. b.mu will be stepped out of (and back into) // during network RPCs. @@ -330,7 +385,7 @@ func (b *LocalBackend) tkaSyncLocked(ourNodeKey key.NodePublic) error { if err != nil { return fmt.Errorf("offer RPC: %w", err) } - controlOffer, err := toSyncOffer(offerResp.Head, offerResp.Ancestors) + controlOffer, err := tka.ToSyncOffer(offerResp.Head, offerResp.Ancestors) if err != nil { return fmt.Errorf("control offer: %v", err) } @@ -393,7 +448,7 @@ func (b *LocalBackend) tkaSyncLocked(ourNodeKey key.NodePublic) error { // b.mu must be held & TKA must be initialized. func (b *LocalBackend) tkaApplyDisablementLocked(secret []byte) error { if b.tka.authority.ValidDisablement(secret) { - if err := os.RemoveAll(b.chonkPathLocked()); err != nil { + if err := b.tka.storage.RemoveAll(); err != nil { return err } b.tka = nil @@ -415,10 +470,6 @@ func (b *LocalBackend) chonkPathLocked() string { // // b.mu must be held. func (b *LocalBackend) tkaBootstrapFromGenesisLocked(g tkatype.MarshaledAUM, persist persist.PersistView) error { - if err := b.CanSupportNetworkLock(); err != nil { - return err - } - var genesis tka.AUM if err := genesis.Unserialize(g); err != nil { return fmt.Errorf("reading genesis: %v", err) @@ -437,19 +488,21 @@ func (b *LocalBackend) tkaBootstrapFromGenesisLocked(g tkatype.MarshaledAUM, per } } - chonkDir := b.chonkPathLocked() - if err := os.Mkdir(filepath.Dir(chonkDir), 0755); err != nil && !os.IsExist(err) { - return fmt.Errorf("creating chonk root dir: %v", err) + root := b.TailscaleVarRoot() + var storage tka.CompactableChonk + if root == "" { + b.health.SetUnhealthy(noNetworkLockStateDirWarnable, nil) + b.logf("network-lock using in-memory storage; no state directory") + storage = tka.ChonkMem() + } else { + chonkDir := b.chonkPathLocked() + chonk, err := tka.ChonkDir(chonkDir) + if err != nil { + return fmt.Errorf("chonk: %v", err) + } + storage = chonk } - if err := os.Mkdir(chonkDir, 0755); err != nil && !os.IsExist(err) { - return fmt.Errorf("mkdir: %v", err) - } - - chonk, err := tka.ChonkDir(chonkDir) - if err != nil { - return fmt.Errorf("chonk: %v", err) - } - authority, err := tka.Bootstrap(chonk, genesis) + authority, err := tka.Bootstrap(storage, genesis) if err != nil { return fmt.Errorf("tka bootstrap: %v", err) } @@ -457,29 +510,11 @@ func (b *LocalBackend) tkaBootstrapFromGenesisLocked(g tkatype.MarshaledAUM, per b.tka = &tkaState{ profile: b.pm.CurrentProfile().ID(), authority: authority, - storage: chonk, + storage: storage, } return nil } -// CanSupportNetworkLock returns nil if tailscaled is able to operate -// a local tailnet key authority (and hence enforce network lock). -func (b *LocalBackend) CanSupportNetworkLock() error { - if b.tka != nil { - // If the TKA is being used, it is supported. - return nil - } - - if b.TailscaleVarRoot() == "" { - return errors.New("network-lock is not supported in this configuration, try setting --statedir") - } - - // There's a var root (aka --statedir), so if network lock gets - // initialized we have somewhere to store our AUMs. That's all - // we need. - return nil -} - // NetworkLockStatus returns a structure describing the state of the // tailnet key authority, if any. func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus { @@ -516,9 +551,10 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus { var selfAuthorized bool nodeKeySignature := &tka.NodeKeySignature{} - if b.netMap != nil { - selfAuthorized = b.tka.authority.NodeKeyAuthorized(b.netMap.SelfNode.Key(), b.netMap.SelfNode.KeySignature().AsSlice()) == nil - if err := nodeKeySignature.Unserialize(b.netMap.SelfNode.KeySignature().AsSlice()); err != nil { + nm := b.currentNode().NetMap() + if nm != nil { + selfAuthorized = b.tka.authority.NodeKeyAuthorized(nm.SelfNode.Key(), nm.SelfNode.KeySignature().AsSlice()) == nil + if err := nodeKeySignature.Unserialize(nm.SelfNode.KeySignature().AsSlice()); err != nil { b.logf("failed to decode self node key signature: %v", err) } } @@ -527,6 +563,7 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus { outKeys := make([]ipnstate.TKAKey, len(keys)) for i, k := range keys { outKeys[i] = ipnstate.TKAKey{ + Kind: k.Kind.String(), Key: key.NLPublicFromEd25519Unsafe(k.Public), Metadata: k.Meta, Votes: k.Votes, @@ -539,9 +576,9 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus { } var visible []*ipnstate.TKAPeer - if b.netMap != nil { - visible = make([]*ipnstate.TKAPeer, len(b.netMap.Peers)) - for i, p := range b.netMap.Peers { + if nm != nil { + visible = make([]*ipnstate.TKAPeer, len(nm.Peers)) + for i, p := range nm.Peers { s := tkaStateFromPeer(p) visible[i] = &s } @@ -593,24 +630,16 @@ func tkaStateFromPeer(p tailcfg.NodeView) ipnstate.TKAPeer { // The Finish RPC submits signatures for all these nodes, at which point // Control has everything it needs to atomically enable network lock. func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byte, supportDisablement []byte) error { - if err := b.CanSupportNetworkLock(); err != nil { - return err - } - var ourNodeKey key.NodePublic var nlPriv key.NLPrivate + b.mu.Lock() - - if !b.capTailnetLock { - b.mu.Unlock() - return errors.New("not permitted to enable tailnet lock") - } - if p := b.pm.CurrentPrefs(); p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() { ourNodeKey = p.Persist().PublicNodeKey() nlPriv = p.Persist().NetworkLockKey() } b.mu.Unlock() + if ourNodeKey.IsZero() || nlPriv.IsZero() { return errors.New("no node-key: is tailscale logged in?") } @@ -624,7 +653,7 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt // We use an in-memory tailchonk because we don't want to commit to // the filesystem until we've finished the initialization sequence, // just in case something goes wrong. - _, genesisAUM, err := tka.Create(&tka.Mem{}, tka.State{ + _, genesisAUM, err := tka.Create(tka.ChonkMem(), tka.State{ Keys: keys, // TODO(tom): s/tka.State.DisablementSecrets/tka.State.DisablementValues // This will center on consistent nomenclature: @@ -652,7 +681,7 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt // Our genesis AUM was accepted but before Control turns on enforcement of // node-key signatures, we need to sign keys for all the existing nodes. - // If we don't get these signatures ahead of time, everyone will loose + // If we don't get these signatures ahead of time, everyone will lose // connectivity because control won't have any signatures to send which // satisfy network-lock checks. sigs := make(map[tailcfg.NodeID]tkatype.MarshaledSignature, len(initResp.NeedSignatures)) @@ -670,6 +699,13 @@ func (b *LocalBackend) NetworkLockInit(keys []tka.Key, disablementValues [][]byt return err } +// NetworkLockAllowed reports whether the node is allowed to use Tailnet Lock. +func (b *LocalBackend) NetworkLockAllowed() bool { + b.mu.Lock() + defer b.mu.Unlock() + return b.capTailnetLock +} + // Only use is in tests. func (b *LocalBackend) NetworkLockVerifySignatureForTest(nks tkatype.MarshaledSignature, nodeKey key.NodePublic) error { b.mu.Lock() @@ -702,16 +738,14 @@ func (b *LocalBackend) NetworkLockForceLocalDisable() error { id1, id2 := b.tka.authority.StateIDs() stateID := fmt.Sprintf("%d:%d", id1, id2) + cn := b.currentNode() newPrefs := b.pm.CurrentPrefs().AsStruct().Clone() // .Persist should always be initialized here. newPrefs.Persist.DisallowedTKAStateIDs = append(newPrefs.Persist.DisallowedTKAStateIDs, stateID) - if err := b.pm.SetPrefs(newPrefs.View(), ipn.NetworkProfile{ - MagicDNSName: b.netMap.MagicDNSSuffix(), - DomainName: b.netMap.DomainName(), - }); err != nil { + if err := b.pm.SetPrefs(newPrefs.View(), cn.NetworkProfile()); err != nil { return fmt.Errorf("saving prefs: %w", err) } - if err := os.RemoveAll(b.chonkPathLocked()); err != nil { + if err := b.tka.storage.RemoveAll(); err != nil { return fmt.Errorf("deleting TKA state: %w", err) } b.tka = nil @@ -897,7 +931,7 @@ func (b *LocalBackend) NetworkLockLog(maxEntries int) ([]ipnstate.NetworkLockUpd if err == os.ErrNotExist { break } - return out, fmt.Errorf("reading AUM: %w", err) + return out, fmt.Errorf("reading AUM (%v): %w", cursor, err) } update := ipnstate.NetworkLockUpdate{ @@ -1247,27 +1281,10 @@ func (b *LocalBackend) tkaFetchBootstrap(ourNodeKey key.NodePublic, head tka.AUM return a, nil } -func fromSyncOffer(offer tka.SyncOffer) (head string, ancestors []string, err error) { - headBytes, err := offer.Head.MarshalText() - if err != nil { - return "", nil, fmt.Errorf("head.MarshalText: %v", err) - } - - ancestors = make([]string, len(offer.Ancestors)) - for i, ancestor := range offer.Ancestors { - hash, err := ancestor.MarshalText() - if err != nil { - return "", nil, fmt.Errorf("ancestor[%d].MarshalText: %v", i, err) - } - ancestors[i] = string(hash) - } - return string(headBytes), ancestors, nil -} - // tkaDoSyncOffer sends a /machine/tka/sync/offer RPC to the control plane // over noise. This is the first of two RPCs implementing tka synchronization. func (b *LocalBackend) tkaDoSyncOffer(ourNodeKey key.NodePublic, offer tka.SyncOffer) (*tailcfg.TKASyncOfferResponse, error) { - head, ancestors, err := fromSyncOffer(offer) + head, ancestors, err := tka.FromSyncOffer(offer) if err != nil { return nil, fmt.Errorf("encoding offer: %v", err) } diff --git a/vendor/tailscale.com/ipn/ipnlocal/node_backend.go b/vendor/tailscale.com/ipn/ipnlocal/node_backend.go new file mode 100644 index 0000000..efef57e --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/node_backend.go @@ -0,0 +1,872 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package ipnlocal + +import ( + "cmp" + "context" + "net/netip" + "slices" + "sync" + "sync/atomic" + + "go4.org/netipx" + "tailscale.com/feature/buildfeatures" + "tailscale.com/ipn" + "tailscale.com/net/dns" + "tailscale.com/net/tsaddr" + "tailscale.com/syncs" + "tailscale.com/tailcfg" + "tailscale.com/types/dnstype" + "tailscale.com/types/key" + "tailscale.com/types/logger" + "tailscale.com/types/netmap" + "tailscale.com/types/ptr" + "tailscale.com/types/views" + "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" + "tailscale.com/util/mak" + "tailscale.com/util/slicesx" + "tailscale.com/wgengine/filter" + "tailscale.com/wgengine/magicsock" +) + +// nodeBackend is node-specific [LocalBackend] state. It is usually the current node. +// +// Its exported methods are safe for concurrent use, but the struct is not a snapshot of state at a given moment; +// its state can change between calls. For example, asking for the same value (e.g., netmap or prefs) twice +// may return different results. Returned values are immutable and safe for concurrent use. +// +// If both the [LocalBackend]'s internal mutex and the [nodeBackend] mutex must be held at the same time, +// the [LocalBackend] mutex must be acquired first. See the comment on the [LocalBackend] field for more details. +// +// Two pointers to different [nodeBackend] instances represent different local nodes. +// However, there's currently a bug where a new [nodeBackend] might not be created +// during an implicit node switch (see tailscale/corp#28014). +// +// In the future, we might want to include at least the following in this struct (in addition to the current fields). +// However, not everything should be exported or otherwise made available to the outside world (e.g. [ipnext] extensions, +// peer API handlers, etc.). +// - [ipn.State]: when the LocalBackend switches to a different [nodeBackend], it can update the state of the old one. +// - [ipn.LoginProfileView] and [ipn.Prefs]: we should update them when the [profileManager] reports changes to them. +// In the future, [profileManager] (and the corresponding methods of the [LocalBackend]) can be made optional, +// and something else could be used to set them once or update them as needed. +// - [tailcfg.HostinfoView]: it includes certain fields that are tied to the current profile/node/prefs. We should also +// update to build it once instead of mutating it in twelvety different places. +// - [filter.Filter] (normal and jailed, along with the filterHash): the nodeBackend could have a method to (re-)build +// the filter for the current netmap/prefs (see [LocalBackend.updateFilterLocked]), and it needs to track the current +// filters and their hash. +// - Fields related to a requested or required (re-)auth: authURL, authURLTime, authActor, keyExpired, etc. +// - [controlclient.Client]/[*controlclient.Auto]: the current control client. It is ties to a node identity. +// - [tkaState]: it is tied to the current profile / node. +// - Fields related to scheduled node expiration: nmExpiryTimer, numClientStatusCalls, [expiryManager]. +// +// It should not include any fields used by specific features that don't belong in [LocalBackend]. +// Even if they're tied to the local node, instead of moving them here, we should extract the entire feature +// into a separate package and have it install proper hooks. +type nodeBackend struct { + logf logger.Logf + + ctx context.Context // canceled by [nodeBackend.shutdown] + ctxCancel context.CancelCauseFunc // cancels ctx + + // filterAtomic is a stateful packet filter. Immutable once created, but can be + // replaced with a new one. + filterAtomic atomic.Pointer[filter.Filter] + + // initialized once and immutable + eventClient *eventbus.Client + filterPub *eventbus.Publisher[magicsock.FilterUpdate] + nodeViewsPub *eventbus.Publisher[magicsock.NodeViewsUpdate] + nodeMutsPub *eventbus.Publisher[magicsock.NodeMutationsUpdate] + derpMapViewPub *eventbus.Publisher[tailcfg.DERPMapView] + + // TODO(nickkhyl): maybe use sync.RWMutex? + mu syncs.Mutex // protects the following fields + + shutdownOnce sync.Once // guards calling [nodeBackend.shutdown] + readyCh chan struct{} // closed by [nodeBackend.ready]; nil after shutdown + + // NetMap is the most recently set full netmap from the controlclient. + // It can't be mutated in place once set. Because it can't be mutated in place, + // delta updates from the control server don't apply to it. Instead, use + // the peers map to get up-to-date information on the state of peers. + // In general, avoid using the netMap.Peers slice. We'd like it to go away + // as of 2023-09-17. + // TODO(nickkhyl): make it an atomic pointer to avoid the need for a mutex? + netMap *netmap.NetworkMap + + // peers is the set of current peers and their current values after applying + // delta node mutations as they come in (with mu held). The map values can be + // given out to callers, but the map itself can be mutated in place (with mu held) + // and must not escape the [nodeBackend]. + peers map[tailcfg.NodeID]tailcfg.NodeView + + // nodeByAddr maps nodes' own addresses (excluding subnet routes) to node IDs. + // It is mutated in place (with mu held) and must not escape the [nodeBackend]. + nodeByAddr map[netip.Addr]tailcfg.NodeID +} + +func newNodeBackend(ctx context.Context, logf logger.Logf, bus *eventbus.Bus) *nodeBackend { + ctx, ctxCancel := context.WithCancelCause(ctx) + nb := &nodeBackend{ + logf: logf, + ctx: ctx, + ctxCancel: ctxCancel, + eventClient: bus.Client("ipnlocal.nodeBackend"), + readyCh: make(chan struct{}), + } + // Default filter blocks everything and logs nothing. + noneFilter := filter.NewAllowNone(logger.Discard, &netipx.IPSet{}) + nb.filterAtomic.Store(noneFilter) + nb.filterPub = eventbus.Publish[magicsock.FilterUpdate](nb.eventClient) + nb.nodeViewsPub = eventbus.Publish[magicsock.NodeViewsUpdate](nb.eventClient) + nb.nodeMutsPub = eventbus.Publish[magicsock.NodeMutationsUpdate](nb.eventClient) + nb.derpMapViewPub = eventbus.Publish[tailcfg.DERPMapView](nb.eventClient) + nb.filterPub.Publish(magicsock.FilterUpdate{Filter: nb.filterAtomic.Load()}) + return nb +} + +// Context returns a context that is canceled when the [nodeBackend] shuts down, +// either because [LocalBackend] is switching to a different [nodeBackend] +// or is shutting down itself. +func (nb *nodeBackend) Context() context.Context { + return nb.ctx +} + +func (nb *nodeBackend) Self() tailcfg.NodeView { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil { + return tailcfg.NodeView{} + } + return nb.netMap.SelfNode +} + +func (nb *nodeBackend) SelfUserID() tailcfg.UserID { + self := nb.Self() + if !self.Valid() { + return 0 + } + return self.User() +} + +// SelfHasCap reports whether the specified capability was granted to the self node in the most recent netmap. +func (nb *nodeBackend) SelfHasCap(wantCap tailcfg.NodeCapability) bool { + return nb.SelfHasCapOr(wantCap, false) +} + +// SelfHasCapOr is like [nodeBackend.SelfHasCap], but returns the specified default value +// if the netmap is not available yet. +func (nb *nodeBackend) SelfHasCapOr(wantCap tailcfg.NodeCapability, def bool) bool { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil { + return def + } + return nb.netMap.AllCaps.Contains(wantCap) +} + +func (nb *nodeBackend) NetworkProfile() ipn.NetworkProfile { + nb.mu.Lock() + defer nb.mu.Unlock() + return ipn.NetworkProfile{ + // These are ok to call with nil netMap. + MagicDNSName: nb.netMap.MagicDNSSuffix(), + DomainName: nb.netMap.DomainName(), + DisplayName: nb.netMap.TailnetDisplayName(), + } +} + +// TODO(nickkhyl): update it to return a [tailcfg.DERPMapView]? +func (nb *nodeBackend) DERPMap() *tailcfg.DERPMap { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil { + return nil + } + return nb.netMap.DERPMap +} + +func (nb *nodeBackend) NodeByAddr(ip netip.Addr) (_ tailcfg.NodeID, ok bool) { + nb.mu.Lock() + defer nb.mu.Unlock() + nid, ok := nb.nodeByAddr[ip] + return nid, ok +} + +func (nb *nodeBackend) NodeByKey(k key.NodePublic) (_ tailcfg.NodeID, ok bool) { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil { + return 0, false + } + if self := nb.netMap.SelfNode; self.Valid() && self.Key() == k { + return self.ID(), true + } + // TODO(bradfitz,nickkhyl): add nodeByKey like nodeByAddr instead of walking peers. + for _, n := range nb.peers { + if n.Key() == k { + return n.ID(), true + } + } + return 0, false +} + +func (nb *nodeBackend) NodeByID(id tailcfg.NodeID) (_ tailcfg.NodeView, ok bool) { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap != nil { + if self := nb.netMap.SelfNode; self.Valid() && self.ID() == id { + return self, true + } + } + n, ok := nb.peers[id] + return n, ok +} + +func (nb *nodeBackend) PeerByStableID(id tailcfg.StableNodeID) (_ tailcfg.NodeView, ok bool) { + nb.mu.Lock() + defer nb.mu.Unlock() + for _, n := range nb.peers { + if n.StableID() == id { + return n, true + } + } + return tailcfg.NodeView{}, false +} + +func (nb *nodeBackend) UserByID(id tailcfg.UserID) (_ tailcfg.UserProfileView, ok bool) { + nb.mu.Lock() + nm := nb.netMap + nb.mu.Unlock() + if nm == nil { + return tailcfg.UserProfileView{}, false + } + u, ok := nm.UserProfiles[id] + return u, ok +} + +// Peers returns all the current peers in an undefined order. +func (nb *nodeBackend) Peers() []tailcfg.NodeView { + nb.mu.Lock() + defer nb.mu.Unlock() + return slicesx.MapValues(nb.peers) +} + +func (nb *nodeBackend) PeersForTest() []tailcfg.NodeView { + nb.mu.Lock() + defer nb.mu.Unlock() + ret := slicesx.MapValues(nb.peers) + slices.SortFunc(ret, func(a, b tailcfg.NodeView) int { + return cmp.Compare(a.ID(), b.ID()) + }) + return ret +} + +func (nb *nodeBackend) CollectServices() bool { + nb.mu.Lock() + defer nb.mu.Unlock() + return nb.netMap != nil && nb.netMap.CollectServices +} + +// AppendMatchingPeers returns base with all peers that match pred appended. +// +// It acquires b.mu to read the netmap but releases it before calling pred. +func (nb *nodeBackend) AppendMatchingPeers(base []tailcfg.NodeView, pred func(tailcfg.NodeView) bool) []tailcfg.NodeView { + var peers []tailcfg.NodeView + + nb.mu.Lock() + if nb.netMap != nil { + // All fields on b.netMap are immutable, so this is + // safe to copy and use outside the lock. + peers = nb.netMap.Peers + } + nb.mu.Unlock() + + ret := base + for _, peer := range peers { + // The peers in b.netMap don't contain updates made via + // UpdateNetmapDelta. So only use PeerView in b.netMap for its NodeID, + // and then look up the latest copy in b.peers which is updated in + // response to UpdateNetmapDelta edits. + nb.mu.Lock() + peer, ok := nb.peers[peer.ID()] + nb.mu.Unlock() + if ok && pred(peer) { + ret = append(ret, peer) + } + } + return ret +} + +// PeerCaps returns the capabilities that remote src IP has to +// ths current node. +func (nb *nodeBackend) PeerCaps(src netip.Addr) tailcfg.PeerCapMap { + nb.mu.Lock() + defer nb.mu.Unlock() + return nb.peerCapsLocked(src) +} + +func (nb *nodeBackend) peerCapsLocked(src netip.Addr) tailcfg.PeerCapMap { + if nb.netMap == nil { + return nil + } + filt := nb.filterAtomic.Load() + if filt == nil { + return nil + } + addrs := nb.netMap.GetAddresses() + for i := range addrs.Len() { + a := addrs.At(i) + if !a.IsSingleIP() { + continue + } + dst := a.Addr() + if dst.BitLen() == src.BitLen() { // match on family + return filt.CapsWithValues(src, dst) + } + } + return nil +} + +// PeerHasCap reports whether the peer contains the given capability string, +// with any value(s). +func (nb *nodeBackend) PeerHasCap(peer tailcfg.NodeView, wantCap tailcfg.PeerCapability) bool { + if !peer.Valid() { + return false + } + + nb.mu.Lock() + defer nb.mu.Unlock() + for _, ap := range peer.Addresses().All() { + if nb.peerHasCapLocked(ap.Addr(), wantCap) { + return true + } + } + return false +} + +func (nb *nodeBackend) peerHasCapLocked(addr netip.Addr, wantCap tailcfg.PeerCapability) bool { + return nb.peerCapsLocked(addr).HasCapability(wantCap) +} + +func (nb *nodeBackend) PeerHasPeerAPI(p tailcfg.NodeView) bool { + return nb.PeerAPIBase(p) != "" +} + +// PeerAPIBase returns the "http://ip:port" URL base to reach peer's PeerAPI, +// or the empty string if the peer is invalid or doesn't support PeerAPI. +func (nb *nodeBackend) PeerAPIBase(p tailcfg.NodeView) string { + nb.mu.Lock() + nm := nb.netMap + nb.mu.Unlock() + return peerAPIBase(nm, p) +} + +// PeerIsReachable reports whether the current node can reach p. If the ctx is +// done, this function may return a result based on stale reachability data. +func (nb *nodeBackend) PeerIsReachable(ctx context.Context, p tailcfg.NodeView) bool { + if !nb.SelfHasCap(tailcfg.NodeAttrClientSideReachability) { + // Legacy behavior is to always trust the control plane, which + // isn’t always correct because the peer could be slow to check + // in so that control marks it as offline. + // See tailscale/corp#32686. + return p.Online().Get() + } + + nb.mu.Lock() + nm := nb.netMap + nb.mu.Unlock() + + if self := nm.SelfNode; self.Valid() && self.ID() == p.ID() { + // This node can always reach itself. + return true + } + return nb.peerIsReachable(ctx, p) +} + +func (nb *nodeBackend) peerIsReachable(ctx context.Context, p tailcfg.NodeView) bool { + // TODO(sfllaw): The following does not actually test for client-side + // reachability. This would require a mechanism that tracks whether the + // current node can actually reach this peer, either because they are + // already communicating or because they can ping each other. + // + // Instead, it makes the client ignore p.Online completely. + // + // See tailscale/corp#32686. + return true +} + +func nodeIP(n tailcfg.NodeView, pred func(netip.Addr) bool) netip.Addr { + for _, pfx := range n.Addresses().All() { + if pfx.IsSingleIP() && pred(pfx.Addr()) { + return pfx.Addr() + } + } + return netip.Addr{} +} + +func (nb *nodeBackend) NetMap() *netmap.NetworkMap { + nb.mu.Lock() + defer nb.mu.Unlock() + return nb.netMap +} + +func (nb *nodeBackend) netMapWithPeers() *netmap.NetworkMap { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil { + return nil + } + nm := ptr.To(*nb.netMap) // shallow clone + nm.Peers = slicesx.MapValues(nb.peers) + slices.SortFunc(nm.Peers, func(a, b tailcfg.NodeView) int { + return cmp.Compare(a.ID(), b.ID()) + }) + return nm +} + +func (nb *nodeBackend) SetNetMap(nm *netmap.NetworkMap) { + nb.mu.Lock() + defer nb.mu.Unlock() + nb.netMap = nm + nb.updateNodeByAddrLocked() + nb.updatePeersLocked() + nv := magicsock.NodeViewsUpdate{} + if nm != nil { + nv.SelfNode = nm.SelfNode + nv.Peers = nm.Peers + nb.derpMapViewPub.Publish(nm.DERPMap.View()) + } else { + nb.derpMapViewPub.Publish(tailcfg.DERPMapView{}) + } + nb.nodeViewsPub.Publish(nv) +} + +func (nb *nodeBackend) updateNodeByAddrLocked() { + nm := nb.netMap + if nm == nil { + nb.nodeByAddr = nil + return + } + + // Update the nodeByAddr index. + if nb.nodeByAddr == nil { + nb.nodeByAddr = map[netip.Addr]tailcfg.NodeID{} + } + // First pass, mark everything unwanted. + for k := range nb.nodeByAddr { + nb.nodeByAddr[k] = 0 + } + addNode := func(n tailcfg.NodeView) { + for _, ipp := range n.Addresses().All() { + if ipp.IsSingleIP() { + nb.nodeByAddr[ipp.Addr()] = n.ID() + } + } + } + if nm.SelfNode.Valid() { + addNode(nm.SelfNode) + } + for _, p := range nm.Peers { + addNode(p) + } + // Third pass, actually delete the unwanted items. + for k, v := range nb.nodeByAddr { + if v == 0 { + delete(nb.nodeByAddr, k) + } + } +} + +func (nb *nodeBackend) updatePeersLocked() { + nm := nb.netMap + if nm == nil { + nb.peers = nil + return + } + + // First pass, mark everything unwanted. + for k := range nb.peers { + nb.peers[k] = tailcfg.NodeView{} + } + + // Second pass, add everything wanted. + for _, p := range nm.Peers { + mak.Set(&nb.peers, p.ID(), p) + } + + // Third pass, remove deleted things. + for k, v := range nb.peers { + if !v.Valid() { + delete(nb.peers, k) + } + } +} + +func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.netMap == nil || len(nb.peers) == 0 { + return false + } + + // Locally cloned mutable nodes, to avoid calling AsStruct (clone) + // multiple times on a node if it's mutated multiple times in this + // call (e.g. its endpoints + online status both change) + var mutableNodes map[tailcfg.NodeID]*tailcfg.Node + + update := magicsock.NodeMutationsUpdate{ + Mutations: make([]netmap.NodeMutation, 0, len(muts)), + } + for _, m := range muts { + n, ok := mutableNodes[m.NodeIDBeingMutated()] + if !ok { + nv, ok := nb.peers[m.NodeIDBeingMutated()] + if !ok { + // TODO(bradfitz): unexpected metric? + return false + } + n = nv.AsStruct() + mak.Set(&mutableNodes, nv.ID(), n) + update.Mutations = append(update.Mutations, m) + } + m.Apply(n) + } + for nid, n := range mutableNodes { + nb.peers[nid] = n.View() + } + nb.nodeMutsPub.Publish(update) + return true +} + +// unlockedNodesPermitted reports whether any peer with theUnsignedPeerAPIOnly bool set true has any of its allowed IPs +// in the specified packet filter. +// +// TODO(nickkhyl): It is here temporarily until we can move the whole [LocalBackend.updateFilterLocked] here, +// but change it so it builds and returns a filter for the current netmap/prefs instead of re-configuring the engine filter. +// Something like (*nodeBackend).RebuildFilters() (filter, jailedFilter *filter.Filter, changed bool) perhaps? +func (nb *nodeBackend) unlockedNodesPermitted(packetFilter []filter.Match) bool { + nb.mu.Lock() + defer nb.mu.Unlock() + return packetFilterPermitsUnlockedNodes(nb.peers, packetFilter) +} + +func (nb *nodeBackend) filter() *filter.Filter { + return nb.filterAtomic.Load() +} + +func (nb *nodeBackend) setFilter(f *filter.Filter) { + nb.filterAtomic.Store(f) + nb.filterPub.Publish(magicsock.FilterUpdate{Filter: f}) +} + +func (nb *nodeBackend) dnsConfigForNetmap(prefs ipn.PrefsView, selfExpired bool, versionOS string) *dns.Config { + nb.mu.Lock() + defer nb.mu.Unlock() + return dnsConfigForNetmap(nb.netMap, nb.peers, prefs, selfExpired, nb.logf, versionOS) +} + +func (nb *nodeBackend) exitNodeCanProxyDNS(exitNodeID tailcfg.StableNodeID) (dohURL string, ok bool) { + if !buildfeatures.HasUseExitNode { + return "", false + } + nb.mu.Lock() + defer nb.mu.Unlock() + return exitNodeCanProxyDNS(nb.netMap, nb.peers, exitNodeID) +} + +// ready signals that [LocalBackend] has completed the switch to this [nodeBackend] +// and any pending calls to [nodeBackend.Wait] must be unblocked. +func (nb *nodeBackend) ready() { + nb.mu.Lock() + defer nb.mu.Unlock() + if nb.readyCh != nil { + close(nb.readyCh) + } +} + +// Wait blocks until [LocalBackend] completes the switch to this [nodeBackend] +// and calls [nodeBackend.ready]. It returns an error if the provided context +// is canceled or if the [nodeBackend] shuts down or is already shut down. +// +// It must not be called with the [LocalBackend]'s internal mutex held as [LocalBackend] +// may need to acquire it to complete the switch. +// +// TODO(nickkhyl): Relax this restriction once [LocalBackend]'s state machine +// runs in its own goroutine, or if we decide that waiting for the state machine +// restart to finish isn't necessary for [LocalBackend] to consider the switch complete. +// We mostly need this because of [LocalBackend.Start] acquiring b.mu and the fact that +// methods like [LocalBackend.SwitchProfile] must report any errors returned by it. +// Perhaps we could report those errors asynchronously as [health.Warnable]s? +func (nb *nodeBackend) Wait(ctx context.Context) error { + nb.mu.Lock() + readyCh := nb.readyCh + nb.mu.Unlock() + + select { + case <-ctx.Done(): + return ctx.Err() + case <-nb.ctx.Done(): + return context.Cause(nb.ctx) + case <-readyCh: + return nil + } +} + +// shutdown shuts down the [nodeBackend] and cancels its context +// with the provided cause. +func (nb *nodeBackend) shutdown(cause error) { + nb.shutdownOnce.Do(func() { + nb.doShutdown(cause) + }) +} + +func (nb *nodeBackend) doShutdown(cause error) { + nb.mu.Lock() + defer nb.mu.Unlock() + nb.ctxCancel(cause) + nb.readyCh = nil + nb.eventClient.Close() +} + +// useWithExitNodeResolvers filters out resolvers so the ones that remain +// are all the ones marked for use with exit nodes. +func useWithExitNodeResolvers(resolvers []*dnstype.Resolver) []*dnstype.Resolver { + var filtered []*dnstype.Resolver + for _, res := range resolvers { + if res.UseWithExitNode { + filtered = append(filtered, res) + } + } + return filtered +} + +// useWithExitNodeRoutes filters out routes so the ones that remain +// are either zero-length resolver lists, or lists containing only +// resolvers marked for use with exit nodes. +func useWithExitNodeRoutes(routes map[string][]*dnstype.Resolver) map[string][]*dnstype.Resolver { + var filtered map[string][]*dnstype.Resolver + for suffix, resolvers := range routes { + // Suffixes with no resolvers represent a valid configuration, + // and should persist regardless of exit node considerations. + if len(resolvers) == 0 { + mak.Set(&filtered, suffix, make([]*dnstype.Resolver, 0)) + continue + } + + // In exit node contexts, we filter out resolvers not configured for use with + // exit nodes. If there are no such configured resolvers, there should not be an entry for that suffix. + filteredResolvers := useWithExitNodeResolvers(resolvers) + if len(filteredResolvers) > 0 { + mak.Set(&filtered, suffix, filteredResolvers) + } + } + + return filtered +} + +// dnsConfigForNetmap returns a *dns.Config for the given netmap, +// prefs, client OS version, and cloud hosting environment. +// +// The versionOS is a Tailscale-style version ("iOS", "macOS") and not +// a runtime.GOOS. +func dnsConfigForNetmap(nm *netmap.NetworkMap, peers map[tailcfg.NodeID]tailcfg.NodeView, prefs ipn.PrefsView, selfExpired bool, logf logger.Logf, versionOS string) *dns.Config { + if nm == nil { + return nil + } + if !buildfeatures.HasDNS { + return &dns.Config{} + } + + // If the current node's key is expired, then we don't program any DNS + // configuration into the operating system. This ensures that if the + // DNS configuration specifies a DNS server that is only reachable over + // Tailscale, we don't break connectivity for the user. + // + // TODO(andrew-d): this also stops returning anything from quad-100; we + // could do the same thing as having "CorpDNS: false" and keep that but + // not program the OS? + if selfExpired { + return &dns.Config{} + } + + dcfg := &dns.Config{ + Routes: map[dnsname.FQDN][]*dnstype.Resolver{}, + Hosts: map[dnsname.FQDN][]netip.Addr{}, + } + + // selfV6Only is whether we only have IPv6 addresses ourselves. + selfV6Only := nm.GetAddresses().ContainsFunc(tsaddr.PrefixIs6) && + !nm.GetAddresses().ContainsFunc(tsaddr.PrefixIs4) + dcfg.OnlyIPv6 = selfV6Only + + wantAAAA := nm.AllCaps.Contains(tailcfg.NodeAttrMagicDNSPeerAAAA) + + // Populate MagicDNS records. We do this unconditionally so that + // quad-100 can always respond to MagicDNS queries, even if the OS + // isn't configured to make MagicDNS resolution truly + // magic. Details in + // https://github.com/tailscale/tailscale/issues/1886. + set := func(name string, addrs views.Slice[netip.Prefix]) { + if addrs.Len() == 0 || name == "" { + return + } + fqdn, err := dnsname.ToFQDN(name) + if err != nil { + return // TODO: propagate error? + } + var have4 bool + for _, addr := range addrs.All() { + if addr.Addr().Is4() { + have4 = true + break + } + } + var ips []netip.Addr + for _, addr := range addrs.All() { + if selfV6Only { + if addr.Addr().Is6() { + ips = append(ips, addr.Addr()) + } + continue + } + // If this node has an IPv4 address, then + // remove peers' IPv6 addresses for now, as we + // don't guarantee that the peer node actually + // can speak IPv6 correctly. + // + // https://github.com/tailscale/tailscale/issues/1152 + // tracks adding the right capability reporting to + // enable AAAA in MagicDNS. + if addr.Addr().Is6() && have4 && !wantAAAA { + continue + } + ips = append(ips, addr.Addr()) + } + dcfg.Hosts[fqdn] = ips + } + set(nm.SelfName(), nm.GetAddresses()) + for _, peer := range peers { + set(peer.Name(), peer.Addresses()) + } + for _, rec := range nm.DNS.ExtraRecords { + switch rec.Type { + case "", "A", "AAAA": + // Treat these all the same for now: infer from the value + default: + // TODO: more + continue + } + ip, err := netip.ParseAddr(rec.Value) + if err != nil { + // Ignore. + continue + } + fqdn, err := dnsname.ToFQDN(rec.Name) + if err != nil { + continue + } + dcfg.Hosts[fqdn] = append(dcfg.Hosts[fqdn], ip) + } + + if !prefs.CorpDNS() { + return dcfg + } + + for _, dom := range nm.DNS.Domains { + fqdn, err := dnsname.ToFQDN(dom) + if err != nil { + logf("[unexpected] non-FQDN search domain %q", dom) + } + dcfg.SearchDomains = append(dcfg.SearchDomains, fqdn) + } + if nm.DNS.Proxied { // actually means "enable MagicDNS" + for _, dom := range magicDNSRootDomains(nm) { + dcfg.Routes[dom] = nil // resolve internally with dcfg.Hosts + } + } + + addDefault := func(resolvers []*dnstype.Resolver) { + dcfg.DefaultResolvers = append(dcfg.DefaultResolvers, resolvers...) + } + + addSplitDNSRoutes := func(routes map[string][]*dnstype.Resolver) { + for suffix, resolvers := range routes { + fqdn, err := dnsname.ToFQDN(suffix) + if err != nil { + logf("[unexpected] non-FQDN route suffix %q", suffix) + } + + // Create map entry even if len(resolvers) == 0; Issue 2706. + // This lets the control plane send ExtraRecords for which we + // can authoritatively answer "name not exists" for when the + // control plane also sends this explicit but empty route + // making it as something we handle. + dcfg.Routes[fqdn] = slices.Clone(resolvers) + } + } + + // If we're using an exit node and that exit node is new enough (1.19.x+) + // to run a DoH DNS proxy, then send all our DNS traffic through it, + // unless we find resolvers with UseWithExitNode set, in which case we use that. + if buildfeatures.HasUseExitNode { + if dohURL, ok := exitNodeCanProxyDNS(nm, peers, prefs.ExitNodeID()); ok { + filtered := useWithExitNodeResolvers(nm.DNS.Resolvers) + if len(filtered) > 0 { + addDefault(filtered) + } else { + // If no default global resolvers with the override + // are configured, configure the exit node's resolver. + addDefault([]*dnstype.Resolver{{Addr: dohURL}}) + } + + addSplitDNSRoutes(useWithExitNodeRoutes(nm.DNS.Routes)) + return dcfg + } + } + + // If the user has set default resolvers ("override local DNS"), prefer to + // use those resolvers as the default, otherwise if there are WireGuard exit + // node resolvers, use those as the default. + if len(nm.DNS.Resolvers) > 0 { + addDefault(nm.DNS.Resolvers) + } else if buildfeatures.HasUseExitNode { + if resolvers, ok := wireguardExitNodeDNSResolvers(nm, peers, prefs.ExitNodeID()); ok { + addDefault(resolvers) + } + } + + // Add split DNS routes, with no regard to exit node configuration. + addSplitDNSRoutes(nm.DNS.Routes) + + // Set FallbackResolvers as the default resolvers in the + // scenarios that can't handle a purely split-DNS config. See + // https://github.com/tailscale/tailscale/issues/1743 for + // details. + switch { + case len(dcfg.DefaultResolvers) != 0: + // Default resolvers already set. + case !prefs.ExitNodeID().IsZero(): + // When using an exit node, we send all DNS traffic to the exit node, so + // we don't need a fallback resolver. + // + // However, if the exit node is too old to run a DoH DNS proxy, then we + // need to use a fallback resolver as it's very likely the LAN resolvers + // will become unreachable. + // + // This is especially important on Apple OSes, where + // adding the default route to the tunnel interface makes + // it "primary", and we MUST provide VPN-sourced DNS + // settings or we break all DNS resolution. + // + // https://github.com/tailscale/tailscale/issues/1713 + addDefault(nm.DNS.FallbackResolvers) + case len(dcfg.Routes) == 0: + // No settings requiring split DNS, no problem. + } + + return dcfg +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/peerapi.go b/vendor/tailscale.com/ipn/ipnlocal/peerapi.go index f20ea75..318d9bf 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/peerapi.go +++ b/vendor/tailscale.com/ipn/ipnlocal/peerapi.go @@ -15,9 +15,7 @@ import ( "net" "net/http" "net/netip" - "net/url" "os" - "path/filepath" "runtime" "slices" "strconv" @@ -27,33 +25,25 @@ import ( "golang.org/x/net/dns/dnsmessage" "golang.org/x/net/http/httpguts" - "tailscale.com/drive" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/hostinfo" - "tailscale.com/ipn" "tailscale.com/net/netaddr" "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/net/sockstats" "tailscale.com/tailcfg" - "tailscale.com/taildrop" + "tailscale.com/types/netmap" "tailscale.com/types/views" "tailscale.com/util/clientmetric" - "tailscale.com/util/httphdr" - "tailscale.com/util/httpm" "tailscale.com/wgengine/filter" ) -const ( - taildrivePrefix = "/v0/drive" -) - -var initListenConfig func(*net.ListenConfig, netip.Addr, *netmon.State, string) error - -// addH2C is non-nil on platforms where we want to add H2C -// ("cleartext" HTTP/2) support to the peerAPI. -var addH2C func(*http.Server) +// initListenConfig, if non-nil, is called during peerAPIListener setup. It is used only +// on iOS and macOS to set socket options to bind the listener to the Tailscale interface. +var initListenConfig func(config *net.ListenConfig, addr netip.Addr, tunIfIndex int) error // peerDNSQueryHandler is implemented by tsdns.Resolver. type peerDNSQueryHandler interface { @@ -63,11 +53,9 @@ type peerDNSQueryHandler interface { type peerAPIServer struct { b *LocalBackend resolver peerDNSQueryHandler - - taildrop *taildrop.Manager } -func (s *peerAPIServer) listen(ip netip.Addr, ifState *netmon.State) (ln net.Listener, err error) { +func (s *peerAPIServer) listen(ip netip.Addr, tunIfIndex int) (ln net.Listener, err error) { // Android for whatever reason often has problems creating the peerapi listener. // But since we started intercepting it with netstack, it's not even important that // we have a real kernel-level listener. So just create a dummy listener on Android @@ -83,7 +71,14 @@ func (s *peerAPIServer) listen(ip netip.Addr, ifState *netmon.State) (ln net.Lis // On iOS/macOS, this sets the lc.Control hook to // setsockopt the interface index to bind to, to get // out of the network sandbox. - if err := initListenConfig(&lc, ip, ifState, s.b.dialer.TUNName()); err != nil { + + // A zero tunIfIndex is invalid for peerapi. A zero value will not get us + // out of the network sandbox. Caller should log and retry. + if tunIfIndex == 0 { + return nil, fmt.Errorf("peerapi: cannot listen on %s with tunIfIndex 0", ipStr) + } + + if err := initListenConfig(&lc, ip, tunIfIndex); err != nil { return nil, err } if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { @@ -146,6 +141,9 @@ type peerAPIListener struct { } func (pln *peerAPIListener) Close() error { + if !buildfeatures.HasPeerAPIServer { + return nil + } if pln.ln != nil { return pln.ln.Close() } @@ -153,6 +151,9 @@ func (pln *peerAPIListener) Close() error { } func (pln *peerAPIListener) serve() { + if !buildfeatures.HasPeerAPIServer { + return + } if pln.ln == nil { return } @@ -206,11 +207,11 @@ func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) { peerUser: peerUser, } httpServer := &http.Server{ - Handler: h, - } - if addH2C != nil { - addH2C(httpServer) + Handler: h, + Protocols: new(http.Protocols), } + httpServer.Protocols.SetHTTP1(true) + httpServer.Protocols.SetUnencryptedHTTP2(true) // over WireGuard; "unencrypted" means no TLS go httpServer.Serve(netutil.NewOneConnListener(c, nil)) } @@ -229,9 +230,12 @@ type peerAPIHandler struct { type PeerAPIHandler interface { Peer() tailcfg.NodeView PeerCaps() tailcfg.PeerCapMap + CanDebug() bool // can remote node can debug this node (internal state, etc) Self() tailcfg.NodeView LocalBackend() *LocalBackend IsSelfUntagged() bool // whether the peer is untagged and the same as this user + RemoteAddr() netip.AddrPort + Logf(format string, a ...any) } func (h *peerAPIHandler) IsSelfUntagged() bool { @@ -239,12 +243,20 @@ func (h *peerAPIHandler) IsSelfUntagged() bool { } func (h *peerAPIHandler) Peer() tailcfg.NodeView { return h.peerNode } func (h *peerAPIHandler) Self() tailcfg.NodeView { return h.selfNode } +func (h *peerAPIHandler) RemoteAddr() netip.AddrPort { return h.remoteAddr } func (h *peerAPIHandler) LocalBackend() *LocalBackend { return h.ps.b } +func (h *peerAPIHandler) Logf(format string, a ...any) { + h.logf(format, a...) +} func (h *peerAPIHandler) logf(format string, a ...any) { h.ps.b.logf("peerapi: "+format, a...) } +func (h *peerAPIHandler) logfv1(format string, a ...any) { + h.ps.b.logf("[v1] peerapi: "+format, a...) +} + // isAddressValid reports whether addr is a valid destination address for this // node originating from the peer. func (h *peerAPIHandler) isAddressValid(addr netip.Addr) bool { @@ -323,15 +335,31 @@ func peerAPIRequestShouldGetSecurityHeaders(r *http.Request) bool { // // It panics if the path is already registered. func RegisterPeerAPIHandler(path string, f func(PeerAPIHandler, http.ResponseWriter, *http.Request)) { + if !buildfeatures.HasPeerAPIServer { + return + } if _, ok := peerAPIHandlers[path]; ok { panic(fmt.Sprintf("duplicate PeerAPI handler %q", path)) } peerAPIHandlers[path] = f + if strings.HasSuffix(path, "/") { + peerAPIHandlerPrefixes[path] = f + } } -var peerAPIHandlers = map[string]func(PeerAPIHandler, http.ResponseWriter, *http.Request){} // by URL.Path +var ( + peerAPIHandlers = map[string]func(PeerAPIHandler, http.ResponseWriter, *http.Request){} // by URL.Path + + // peerAPIHandlerPrefixes are the subset of peerAPIHandlers where + // the map key ends with a slash, indicating a prefix match. + peerAPIHandlerPrefixes = map[string]func(PeerAPIHandler, http.ResponseWriter, *http.Request){} +) func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasPeerAPIServer { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } if err := h.validatePeerAPIRequest(r); err != nil { metricInvalidRequests.Add(1) h.logf("invalid request from %v: %v", h.remoteAddr, err) @@ -343,56 +371,50 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("X-Content-Type-Options", "nosniff") } - if strings.HasPrefix(r.URL.Path, "/v0/put/") { - if r.Method == "PUT" { - metricPutCalls.Add(1) + for pfx, ph := range peerAPIHandlerPrefixes { + if strings.HasPrefix(r.URL.Path, pfx) { + ph(h, w, r) + return } - h.handlePeerPut(w, r) - return } - if strings.HasPrefix(r.URL.Path, "/dns-query") { + if buildfeatures.HasDNS && strings.HasPrefix(r.URL.Path, "/dns-query") { metricDNSCalls.Add(1) h.handleDNSQuery(w, r) return } - if strings.HasPrefix(r.URL.Path, taildrivePrefix) { - h.handleServeDrive(w, r) - return - } - switch r.URL.Path { - case "/v0/goroutines": - h.handleServeGoroutines(w, r) - return - case "/v0/env": - h.handleServeEnv(w, r) - return - case "/v0/metrics": - h.handleServeMetrics(w, r) - return - case "/v0/magicsock": - h.handleServeMagicsock(w, r) - return - case "/v0/dnsfwd": - h.handleServeDNSFwd(w, r) - return - case "/v0/interfaces": - h.handleServeInterfaces(w, r) - return - case "/v0/doctor": - h.handleServeDoctor(w, r) - return - case "/v0/sockstats": - h.handleServeSockStats(w, r) - return - case "/v0/ingress": - metricIngressCalls.Add(1) - h.handleServeIngress(w, r) - return + if buildfeatures.HasDebug { + switch r.URL.Path { + case "/v0/goroutines": + h.handleServeGoroutines(w, r) + return + case "/v0/env": + h.handleServeEnv(w, r) + return + case "/v0/metrics": + h.handleServeMetrics(w, r) + return + case "/v0/magicsock": + h.handleServeMagicsock(w, r) + return + case "/v0/dnsfwd": + h.handleServeDNSFwd(w, r) + return + case "/v0/interfaces": + h.handleServeInterfaces(w, r) + return + case "/v0/sockstats": + h.handleServeSockStats(w, r) + return + } } if ph, ok := peerAPIHandlers[r.URL.Path]; ok { ph(h, w, r) return } + if r.URL.Path != "/" { + http.Error(w, "unsupported peerapi path", http.StatusNotFound) + return + } who := h.peerUser.DisplayName fmt.Fprintf(w, ` @@ -406,67 +428,6 @@ This is my Tailscale device. Your device is %v. } } -func (h *peerAPIHandler) handleServeIngress(w http.ResponseWriter, r *http.Request) { - // http.Errors only useful if hitting endpoint manually - // otherwise rely on log lines when debugging ingress connections - // as connection is hijacked for bidi and is encrypted tls - if !h.canIngress() { - h.logf("ingress: denied; no ingress cap from %v", h.remoteAddr) - http.Error(w, "denied; no ingress cap", http.StatusForbidden) - return - } - logAndError := func(code int, publicMsg string) { - h.logf("ingress: bad request from %v: %s", h.remoteAddr, publicMsg) - http.Error(w, publicMsg, http.StatusMethodNotAllowed) - } - bad := func(publicMsg string) { - logAndError(http.StatusBadRequest, publicMsg) - } - if r.Method != "POST" { - logAndError(http.StatusMethodNotAllowed, "only POST allowed") - return - } - srcAddrStr := r.Header.Get("Tailscale-Ingress-Src") - if srcAddrStr == "" { - bad("Tailscale-Ingress-Src header not set") - return - } - srcAddr, err := netip.ParseAddrPort(srcAddrStr) - if err != nil { - bad("Tailscale-Ingress-Src header invalid; want ip:port") - return - } - target := ipn.HostPort(r.Header.Get("Tailscale-Ingress-Target")) - if target == "" { - bad("Tailscale-Ingress-Target header not set") - return - } - if _, _, err := net.SplitHostPort(string(target)); err != nil { - bad("Tailscale-Ingress-Target header invalid; want host:port") - return - } - - getConnOrReset := func() (net.Conn, bool) { - conn, _, err := w.(http.Hijacker).Hijack() - if err != nil { - h.logf("ingress: failed hijacking conn") - http.Error(w, "failed hijacking conn", http.StatusInternalServerError) - return nil, false - } - io.WriteString(conn, "HTTP/1.1 101 Switching Protocols\r\n\r\n") - return &ipn.FunnelConn{ - Conn: conn, - Src: srcAddr, - Target: target, - }, true - } - sendRST := func() { - http.Error(w, "denied", http.StatusForbidden) - } - - h.ps.b.HandleIngressTCPConn(h.peerNode, target, srcAddr, getConnOrReset, sendRST) -} - func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Request) { if !h.canDebug() { http.Error(w, "denied; no debug access", http.StatusForbidden) @@ -514,24 +475,6 @@ func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Re fmt.Fprintln(w, "") } -func (h *peerAPIHandler) handleServeDoctor(w http.ResponseWriter, r *http.Request) { - if !h.canDebug() { - http.Error(w, "denied; no debug access", http.StatusForbidden) - return - } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - fmt.Fprintln(w, "

Doctor Output

") - - fmt.Fprintln(w, "
")
-
-	h.ps.b.Doctor(r.Context(), func(format string, args ...any) {
-		line := fmt.Sprintf(format, args...)
-		fmt.Fprintln(w, html.EscapeString(line))
-	})
-
-	fmt.Fprintln(w, "
") -} - func (h *peerAPIHandler) handleServeSockStats(w http.ResponseWriter, r *http.Request) { if !h.canDebug() { http.Error(w, "denied; no debug access", http.StatusForbidden) @@ -630,14 +573,7 @@ func (h *peerAPIHandler) handleServeSockStats(w http.ResponseWriter, r *http.Req fmt.Fprintln(w, "") } -// canPutFile reports whether h can put a file ("Taildrop") to this node. -func (h *peerAPIHandler) canPutFile() bool { - if h.peerNode.UnsignedPeerAPIOnly() { - // Unsigned peers can't send files. - return false - } - return h.isSelf || h.peerHasCap(tailcfg.PeerCapabilityFileSharingSend) -} +func (h *peerAPIHandler) CanDebug() bool { return h.canDebug() } // canDebug reports whether h can debug this node (goroutines, metrics, // magicsock internal state, etc). @@ -668,110 +604,6 @@ func (h *peerAPIHandler) PeerCaps() tailcfg.PeerCapMap { return h.ps.b.PeerCaps(h.remoteAddr.Addr()) } -func (h *peerAPIHandler) handlePeerPut(w http.ResponseWriter, r *http.Request) { - if !h.canPutFile() { - http.Error(w, taildrop.ErrNoTaildrop.Error(), http.StatusForbidden) - return - } - if !h.ps.b.hasCapFileSharing() { - http.Error(w, taildrop.ErrNoTaildrop.Error(), http.StatusForbidden) - return - } - rawPath := r.URL.EscapedPath() - prefix, ok := strings.CutPrefix(rawPath, "/v0/put/") - if !ok { - http.Error(w, "misconfigured internals", http.StatusForbidden) - return - } - baseName, err := url.PathUnescape(prefix) - if err != nil { - http.Error(w, taildrop.ErrInvalidFileName.Error(), http.StatusBadRequest) - return - } - enc := json.NewEncoder(w) - switch r.Method { - case "GET": - id := taildrop.ClientID(h.peerNode.StableID()) - if prefix == "" { - // List all the partial files. - files, err := h.ps.taildrop.PartialFiles(id) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if err := enc.Encode(files); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - h.logf("json.Encoder.Encode error: %v", err) - return - } - } else { - // Stream all the block hashes for the specified file. - next, close, err := h.ps.taildrop.HashPartialFile(id, baseName) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer close() - for { - switch cs, err := next(); { - case err == io.EOF: - return - case err != nil: - http.Error(w, err.Error(), http.StatusInternalServerError) - h.logf("HashPartialFile.next error: %v", err) - return - default: - if err := enc.Encode(cs); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - h.logf("json.Encoder.Encode error: %v", err) - return - } - } - } - } - case "PUT": - t0 := h.ps.b.clock.Now() - id := taildrop.ClientID(h.peerNode.StableID()) - - var offset int64 - if rangeHdr := r.Header.Get("Range"); rangeHdr != "" { - ranges, ok := httphdr.ParseRange(rangeHdr) - if !ok || len(ranges) != 1 || ranges[0].Length != 0 { - http.Error(w, "invalid Range header", http.StatusBadRequest) - return - } - offset = ranges[0].Start - } - n, err := h.ps.taildrop.PutFile(taildrop.ClientID(fmt.Sprint(id)), baseName, r.Body, offset, r.ContentLength) - switch err { - case nil: - d := h.ps.b.clock.Since(t0).Round(time.Second / 10) - h.logf("got put of %s in %v from %v/%v", approxSize(n), d, h.remoteAddr.Addr(), h.peerNode.ComputedName) - io.WriteString(w, "{}\n") - case taildrop.ErrNoTaildrop: - http.Error(w, err.Error(), http.StatusForbidden) - case taildrop.ErrInvalidFileName: - http.Error(w, err.Error(), http.StatusBadRequest) - case taildrop.ErrFileExists: - http.Error(w, err.Error(), http.StatusConflict) - default: - http.Error(w, err.Error(), http.StatusInternalServerError) - } - default: - http.Error(w, "expected method GET or PUT", http.StatusMethodNotAllowed) - } -} - -func approxSize(n int64) string { - if n <= 1<<10 { - return "<=1KB" - } - if n <= 1<<20 { - return "<=1MB" - } - return fmt.Sprintf("~%dMB", n>>20) -} - func (h *peerAPIHandler) handleServeGoroutines(w http.ResponseWriter, r *http.Request) { if !h.canDebug() { http.Error(w, "denied; no debug access", http.StatusForbidden) @@ -826,6 +658,10 @@ func (h *peerAPIHandler) handleServeMetrics(w http.ResponseWriter, r *http.Reque } func (h *peerAPIHandler) handleServeDNSFwd(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDNS { + http.NotFound(w, r) + return + } if !h.canDebug() { http.Error(w, "denied; no debug access", http.StatusForbidden) return @@ -839,6 +675,9 @@ func (h *peerAPIHandler) handleServeDNSFwd(w http.ResponseWriter, r *http.Reques } func (h *peerAPIHandler) replyToDNSQueries() bool { + if !buildfeatures.HasDNS { + return false + } if h.isSelf { // If the peer is owned by the same user, just allow it // without further checks. @@ -868,7 +707,7 @@ func (h *peerAPIHandler) replyToDNSQueries() bool { // but an app connector explicitly adds 0.0.0.0/32 (and the // IPv6 equivalent) to make this work (see updateFilterLocked // in LocalBackend). - f := b.filterAtomic.Load() + f := b.currentNode().filter() if f == nil { return false } @@ -890,7 +729,7 @@ func (h *peerAPIHandler) replyToDNSQueries() bool { // handleDNSQuery implements a DoH server (RFC 8484) over the peerapi. // It's not over HTTPS as the spec dictates, but rather HTTP-over-WireGuard. func (h *peerAPIHandler) handleDNSQuery(w http.ResponseWriter, r *http.Request) { - if h.ps.resolver == nil { + if !buildfeatures.HasDNS || h.ps.resolver == nil { http.Error(w, "DNS not wired up", http.StatusNotImplemented) return } @@ -931,7 +770,7 @@ func (h *peerAPIHandler) handleDNSQuery(w http.ResponseWriter, r *http.Request) // TODO(raggi): consider pushing the integration down into the resolver // instead to avoid re-parsing the DNS response for improved performance in // the future. - if h.ps.b.OfferingAppConnector() { + if buildfeatures.HasAppConnectors && h.ps.b.OfferingAppConnector() { if err := h.ps.b.ObserveDNSResponse(res); err != nil { h.logf("ObserveDNSResponse error: %v", err) // This is not fatal, we probably just failed to parse the upstream @@ -958,7 +797,7 @@ func dohQuery(r *http.Request) (dnsQuery []byte, publicErr string) { case "GET": q64 := r.FormValue("dns") if q64 == "" { - return nil, "missing 'dns' parameter" + return nil, "missing ‘dns’ parameter; try '?dns=' (DoH standard) or use '?q=' for JSON debug mode" } if base64.RawURLEncoding.DecodedLen(len(q64)) > maxQueryLen { return nil, "query too large" @@ -1113,85 +952,46 @@ func (rbw *requestBodyWrapper) Read(b []byte) (int, error) { return n, err } -func (h *peerAPIHandler) handleServeDrive(w http.ResponseWriter, r *http.Request) { - if !h.ps.b.DriveSharingEnabled() { - h.logf("taildrive: not enabled") - http.Error(w, "taildrive not enabled", http.StatusNotFound) - return +// peerAPIURL returns an HTTP URL for the peer's peerapi service, +// without a trailing slash. +// +// If ip or port is the zero value then it returns the empty string. +func peerAPIURL(ip netip.Addr, port uint16) string { + if port == 0 || !ip.IsValid() { + return "" } - - capsMap := h.PeerCaps() - driveCaps, ok := capsMap[tailcfg.PeerCapabilityTaildrive] - if !ok { - h.logf("taildrive: not permitted") - http.Error(w, "taildrive not permitted", http.StatusForbidden) - return - } - - rawPerms := make([][]byte, 0, len(driveCaps)) - for _, cap := range driveCaps { - rawPerms = append(rawPerms, []byte(cap)) - } - - p, err := drive.ParsePermissions(rawPerms) - if err != nil { - h.logf("taildrive: error parsing permissions: %w", err.Error()) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - fs, ok := h.ps.b.sys.DriveForRemote.GetOK() - if !ok { - h.logf("taildrive: not supported on platform") - http.Error(w, "taildrive not supported on platform", http.StatusNotFound) - return - } - wr := &httpResponseWrapper{ - ResponseWriter: w, - } - bw := &requestBodyWrapper{ - ReadCloser: r.Body, - } - r.Body = bw - - if r.Method == httpm.PUT || r.Method == httpm.GET { - defer func() { - switch wr.statusCode { - case 304: - // 304s are particularly chatty so skip logging. - default: - contentType := "unknown" - if ct := wr.Header().Get("Content-Type"); ct != "" { - contentType = ct - } - - h.logf("taildrive: share: %s from %s to %s: status-code=%d ext=%q content-type=%q tx=%.f rx=%.f", r.Method, h.peerNode.Key().ShortString(), h.selfNode.Key().ShortString(), wr.statusCode, parseDriveFileExtensionForLog(r.URL.Path), contentType, roundTraffic(wr.contentLength), roundTraffic(bw.bytesRead)) - } - }() - } - - r.URL.Path = strings.TrimPrefix(r.URL.Path, taildrivePrefix) - fs.ServeHTTPWithPerms(p, wr, r) + return fmt.Sprintf("http://%v", netip.AddrPortFrom(ip, port)) } -// parseDriveFileExtensionForLog parses the file extension, if available. -// If a file extension is not present or parsable, the file extension is -// set to "unknown". If the file extension contains a double quote, it is -// replaced with "removed". -// All whitespace is removed from a parsed file extension. -// File extensions including the leading ., e.g. ".gif". -func parseDriveFileExtensionForLog(path string) string { - fileExt := "unknown" - if fe := filepath.Ext(path); fe != "" { - if strings.Contains(fe, "\"") { - // Do not log include file extensions with quotes within them. - return "removed" - } - // Remove white space from user defined inputs. - fileExt = strings.ReplaceAll(fe, " ", "") +// peerAPIBase returns the "http://ip:port" URL base to reach peer's peerAPI. +// It returns the empty string if the peer doesn't support the peerapi +// or there's no matching address family based on the netmap's own addresses. +func peerAPIBase(nm *netmap.NetworkMap, peer tailcfg.NodeView) string { + if nm == nil || !peer.Valid() || !peer.Hostinfo().Valid() { + return "" } - return fileExt + var have4, have6 bool + addrs := nm.GetAddresses() + for _, a := range addrs.All() { + if !a.IsSingleIP() { + continue + } + switch { + case a.Addr().Is4(): + have4 = true + case a.Addr().Is6(): + have6 = true + } + } + p4, p6 := peerAPIPorts(peer) + switch { + case have4 && p4 != 0: + return peerAPIURL(nodeIP(peer, netip.Addr.Is4), p4) + case have6 && p6 != 0: + return peerAPIURL(nodeIP(peer, netip.Addr.Is6), p6) + } + return "" } // newFakePeerAPIListener creates a new net.Listener that acts like @@ -1244,7 +1044,5 @@ var ( metricInvalidRequests = clientmetric.NewCounter("peerapi_invalid_requests") // Non-debug PeerAPI endpoints. - metricPutCalls = clientmetric.NewCounter("peerapi_put") - metricDNSCalls = clientmetric.NewCounter("peerapi_dns") - metricIngressCalls = clientmetric.NewCounter("peerapi_ingress") + metricDNSCalls = clientmetric.NewCounter("peerapi_dns") ) diff --git a/vendor/tailscale.com/ipn/ipnlocal/peerapi_drive.go b/vendor/tailscale.com/ipn/ipnlocal/peerapi_drive.go new file mode 100644 index 0000000..8dffacd --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/peerapi_drive.go @@ -0,0 +1,110 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_drive + +package ipnlocal + +import ( + "net/http" + "path/filepath" + "strings" + + "tailscale.com/drive" + "tailscale.com/tailcfg" + "tailscale.com/util/httpm" +) + +const ( + taildrivePrefix = "/v0/drive" +) + +func init() { + peerAPIHandlerPrefixes[taildrivePrefix] = handleServeDrive +} + +func handleServeDrive(hi PeerAPIHandler, w http.ResponseWriter, r *http.Request) { + h := hi.(*peerAPIHandler) + + h.logfv1("taildrive: got %s request from %s", r.Method, h.peerNode.Key().ShortString()) + if !h.ps.b.DriveSharingEnabled() { + h.logf("taildrive: not enabled") + http.Error(w, "taildrive not enabled", http.StatusNotFound) + return + } + + capsMap := h.PeerCaps() + driveCaps, ok := capsMap[tailcfg.PeerCapabilityTaildrive] + if !ok { + h.logf("taildrive: not permitted") + http.Error(w, "taildrive not permitted", http.StatusForbidden) + return + } + + rawPerms := make([][]byte, 0, len(driveCaps)) + for _, cap := range driveCaps { + rawPerms = append(rawPerms, []byte(cap)) + } + + p, err := drive.ParsePermissions(rawPerms) + if err != nil { + h.logf("taildrive: error parsing permissions: %v", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + fs, ok := h.ps.b.sys.DriveForRemote.GetOK() + if !ok { + h.logf("taildrive: not supported on platform") + http.Error(w, "taildrive not supported on platform", http.StatusNotFound) + return + } + wr := &httpResponseWrapper{ + ResponseWriter: w, + } + bw := &requestBodyWrapper{ + ReadCloser: r.Body, + } + r.Body = bw + + defer func() { + switch wr.statusCode { + case 304: + // 304s are particularly chatty so skip logging. + default: + log := h.logf + if r.Method != httpm.PUT && r.Method != httpm.GET { + log = h.logfv1 + } + contentType := "unknown" + if ct := wr.Header().Get("Content-Type"); ct != "" { + contentType = ct + } + + log("taildrive: share: %s from %s to %s: status-code=%d ext=%q content-type=%q tx=%.f rx=%.f", r.Method, h.peerNode.Key().ShortString(), h.selfNode.Key().ShortString(), wr.statusCode, parseDriveFileExtensionForLog(r.URL.Path), contentType, roundTraffic(wr.contentLength), roundTraffic(bw.bytesRead)) + } + }() + + r.URL.Path = strings.TrimPrefix(r.URL.Path, taildrivePrefix) + fs.ServeHTTPWithPerms(p, wr, r) +} + +// parseDriveFileExtensionForLog parses the file extension, if available. +// If a file extension is not present or parsable, the file extension is +// set to "unknown". If the file extension contains a double quote, it is +// replaced with "removed". +// All whitespace is removed from a parsed file extension. +// File extensions including the leading ., e.g. ".gif". +func parseDriveFileExtensionForLog(path string) string { + fileExt := "unknown" + if fe := filepath.Ext(path); fe != "" { + if strings.Contains(fe, "\"") { + // Do not log include file extensions with quotes within them. + return "removed" + } + // Remove white space from user defined inputs. + fileExt = strings.ReplaceAll(fe, " ", "") + } + + return fileExt +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/peerapi_h2c.go b/vendor/tailscale.com/ipn/ipnlocal/peerapi_h2c.go deleted file mode 100644 index fbfa863..0000000 --- a/vendor/tailscale.com/ipn/ipnlocal/peerapi_h2c.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !ios && !android && !js - -package ipnlocal - -import ( - "net/http" - - "golang.org/x/net/http2" - "golang.org/x/net/http2/h2c" -) - -func init() { - addH2C = func(s *http.Server) { - h2s := &http2.Server{} - s.Handler = h2c.NewHandler(s.Handler, h2s) - } -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/peerapi_macios_ext.go b/vendor/tailscale.com/ipn/ipnlocal/peerapi_macios_ext.go index 15932df..f23b877 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/peerapi_macios_ext.go +++ b/vendor/tailscale.com/ipn/ipnlocal/peerapi_macios_ext.go @@ -6,11 +6,9 @@ package ipnlocal import ( - "fmt" "net" "net/netip" - "tailscale.com/net/netmon" "tailscale.com/net/netns" ) @@ -21,10 +19,6 @@ func init() { // initListenConfigNetworkExtension configures nc for listening on IP // through the iOS/macOS Network/System Extension (Packet Tunnel // Provider) sandbox. -func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netip.Addr, st *netmon.State, tunIfName string) error { - tunIf, ok := st.Interface[tunIfName] - if !ok { - return fmt.Errorf("no interface with name %q", tunIfName) - } - return netns.SetListenConfigInterfaceIndex(nc, tunIf.Index) +func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netip.Addr, ifaceIndex int) error { + return netns.SetListenConfigInterfaceIndex(nc, ifaceIndex) } diff --git a/vendor/tailscale.com/ipn/ipnlocal/prefs_metrics.go b/vendor/tailscale.com/ipn/ipnlocal/prefs_metrics.go new file mode 100644 index 0000000..34c5f55 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/prefs_metrics.go @@ -0,0 +1,103 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package ipnlocal + +import ( + "errors" + + "tailscale.com/feature/buildfeatures" + "tailscale.com/ipn" + "tailscale.com/tailcfg" + "tailscale.com/util/clientmetric" +) + +// Counter metrics for edit/change events +var ( + // metricExitNodeEnabled is incremented when the user enables an exit node independent of the node's characteristics. + metricExitNodeEnabled = clientmetric.NewCounter("prefs_exit_node_enabled") + // metricExitNodeEnabledSuggested is incremented when the user enables the suggested exit node. + metricExitNodeEnabledSuggested = clientmetric.NewCounter("prefs_exit_node_enabled_suggested") + // metricExitNodeEnabledMullvad is incremented when the user enables a Mullvad exit node. + metricExitNodeEnabledMullvad = clientmetric.NewCounter("prefs_exit_node_enabled_mullvad") + // metricWantRunningEnabled is incremented when WantRunning transitions from false to true. + metricWantRunningEnabled = clientmetric.NewCounter("prefs_want_running_enabled") + // metricWantRunningDisabled is incremented when WantRunning transitions from true to false. + metricWantRunningDisabled = clientmetric.NewCounter("prefs_want_running_disabled") +) + +type exitNodeProperty string + +const ( + exitNodeTypePreferred exitNodeProperty = "suggested" // The exit node is the last suggested exit node + exitNodeTypeMullvad exitNodeProperty = "mullvad" // The exit node is a Mullvad exit node +) + +// prefsMetricsEditEvent encapsulates information needed to record metrics related +// to any changes to preferences. +type prefsMetricsEditEvent struct { + change *ipn.MaskedPrefs // the preference mask used to update the preferences + pNew ipn.PrefsView // new preferences (after ApplyUpdates) + pOld ipn.PrefsView // old preferences (before ApplyUpdates) + node *nodeBackend // the node the event is associated with + lastSuggestedExitNode tailcfg.StableNodeID // the last suggested exit node +} + +// record records changes to preferences as clientmetrics. +func (e *prefsMetricsEditEvent) record() error { + if e.change == nil || e.node == nil { + return errors.New("prefsMetricsEditEvent: missing required fields") + } + + // Record up/down events. + if e.change.WantRunningSet && (e.pNew.WantRunning() != e.pOld.WantRunning()) { + if e.pNew.WantRunning() { + metricWantRunningEnabled.Add(1) + } else { + metricWantRunningDisabled.Add(1) + } + } + + // Record any changes to exit node settings. + if e.change.ExitNodeIDSet || e.change.ExitNodeIPSet { + if exitNodeTypes, ok := e.exitNodeType(e.pNew.ExitNodeID()); ok { + // We have switched to a valid exit node if ok is true. + metricExitNodeEnabled.Add(1) + + // We may have some additional characteristics we should also record. + for _, t := range exitNodeTypes { + switch t { + case exitNodeTypePreferred: + metricExitNodeEnabledSuggested.Add(1) + case exitNodeTypeMullvad: + metricExitNodeEnabledMullvad.Add(1) + } + } + } + } + return nil +} + +// exitNodeTypesLocked returns type of exit node for the given stable ID. +// An exit node may have multiple type (can be both mullvad and preferred +// simultaneously for example). +// +// This will return ok as true if the supplied stable ID resolves to a known peer, +// false otherwise. The caller is responsible for ensuring that the id belongs to +// an exit node. +func (e *prefsMetricsEditEvent) exitNodeType(id tailcfg.StableNodeID) (props []exitNodeProperty, isNode bool) { + if !buildfeatures.HasUseExitNode { + return nil, false + } + var peer tailcfg.NodeView + + if peer, isNode = e.node.PeerByStableID(id); isNode { + if tailcfg.StableNodeID(id) == e.lastSuggestedExitNode { + props = append(props, exitNodeTypePreferred) + } + if peer.IsWireGuardOnly() { + props = append(props, exitNodeTypeMullvad) + } + } + return props, isNode +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/profiles.go b/vendor/tailscale.com/ipn/ipnlocal/profiles.go index 10a110e..7080e3c 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/profiles.go +++ b/vendor/tailscale.com/ipn/ipnlocal/profiles.go @@ -5,25 +5,35 @@ package ipnlocal import ( "cmp" + "crypto" "crypto/rand" "encoding/json" "errors" "fmt" + "io" "runtime" "slices" "strings" - "tailscale.com/clientupdate" "tailscale.com/envknob" + "tailscale.com/feature" "tailscale.com/health" "tailscale.com/ipn" + "tailscale.com/ipn/ipnext" "tailscale.com/tailcfg" + "tailscale.com/types/key" "tailscale.com/types/logger" + "tailscale.com/types/persist" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" + "tailscale.com/util/testenv" ) var debug = envknob.RegisterBool("TS_DEBUG_PROFILES") +// [profileManager] implements [ipnext.ProfileStore]. +var _ ipnext.ProfileStore = (*profileManager)(nil) + // profileManager is a wrapper around an [ipn.StateStore] that manages // multiple profiles and the current profile. // @@ -36,8 +46,33 @@ type profileManager struct { currentUserID ipn.WindowsUserID knownProfiles map[ipn.ProfileID]ipn.LoginProfileView // always non-nil - currentProfile ipn.LoginProfileView // always Valid. - prefs ipn.PrefsView // always Valid. + currentProfile ipn.LoginProfileView // always Valid (once [newProfileManager] returns). + prefs ipn.PrefsView // always Valid (once [newProfileManager] returns). + + // StateChangeHook is an optional hook that is called when the current profile or prefs change, + // such as due to a profile switch or a change in the profile's preferences. + // It is typically set by the [LocalBackend] to invert the dependency between + // the [profileManager] and the [LocalBackend], so that instead of [LocalBackend] + // asking [profileManager] for the state, we can have [profileManager] call + // [LocalBackend] when the state changes. See also: + // https://github.com/tailscale/tailscale/pull/15791#discussion_r2060838160 + StateChangeHook ipnext.ProfileStateChangeCallback + + // extHost is the bridge between [profileManager] and the registered [ipnext.Extension]s. + // It may be nil in tests. A nil pointer is a valid, no-op host. + extHost *ExtensionHost + + // Override for key.NewEmptyHardwareAttestationKey used for testing. + newEmptyHardwareAttestationKey func() (key.HardwareAttestationKey, error) +} + +// SetExtensionHost sets the [ExtensionHost] for the [profileManager]. +// The specified host will be notified about profile and prefs changes +// and will immediately be notified about the current profile and prefs. +// A nil host is a valid, no-op host. +func (pm *profileManager) SetExtensionHost(host *ExtensionHost) { + pm.extHost = host + host.NotifyProfileChange(pm.currentProfile, pm.prefs, false) } func (pm *profileManager) dlogf(format string, args ...any) { @@ -64,8 +99,7 @@ func (pm *profileManager) SetCurrentUserID(uid ipn.WindowsUserID) { if pm.currentUserID == uid { return } - pm.currentUserID = uid - if err := pm.SwitchToDefaultProfile(); err != nil { + if _, _, err := pm.SwitchToDefaultProfileForUser(uid); err != nil { // SetCurrentUserID should never fail and must always switch to the // user's default profile or create a new profile for the current user. // Until we implement multi-user support and the new permission model, @@ -73,79 +107,122 @@ func (pm *profileManager) SetCurrentUserID(uid ipn.WindowsUserID) { // that when SetCurrentUserID exits, the profile in pm.currentProfile // is either an existing profile owned by the user, or a new, empty profile. pm.logf("%q's default profile cannot be used; creating a new one: %v", uid, err) - pm.NewProfileForUser(uid) + pm.SwitchToNewProfileForUser(uid) } } -// SetCurrentUserAndProfile sets the current user ID and switches the specified -// profile, if it is accessible to the user. If the profile does not exist, -// or is not accessible, it switches to the user's default profile, -// creating a new one if necessary. +// SwitchToProfile switches to the specified profile and (temporarily, +// while the "current user" is still a thing on Windows; see tailscale/corp#18342) +// sets its owner as the current user. The profile must be a valid profile +// returned by the [profileManager], such as by [profileManager.Profiles], +// [profileManager.ProfileByID], or [profileManager.NewProfileForUser]. // // It is a shorthand for [profileManager.SetCurrentUserID] followed by -// [profileManager.SwitchProfile], but it is more efficient as it switches +// [profileManager.SwitchProfileByID], but it is more efficient as it switches // directly to the specified profile rather than switching to the user's -// default profile first. +// default profile first. It is a no-op if the specified profile is already +// the current profile. // -// As a special case, if the specified profile ID "", it creates a new -// profile for the user and switches to it, unless the current profile -// is already a new, empty profile owned by the user. +// As a special case, if the specified profile view is not valid, it resets +// both the current user and the profile to a new, empty profile not owned +// by any user. // -// It returns the current profile and whether the call resulted -// in a profile switch. -func (pm *profileManager) SetCurrentUserAndProfile(uid ipn.WindowsUserID, profileID ipn.ProfileID) (cp ipn.LoginProfileView, changed bool) { - pm.currentUserID = uid - - if profileID == "" { - if pm.currentProfile.ID() == "" && pm.currentProfile.LocalUserID() == uid { - return pm.currentProfile, false +// It returns the current profile and whether the call resulted in a profile change, +// or an error if the specified profile does not exist or its prefs could not be loaded. +// +// It may be called during [profileManager] initialization before [newProfileManager] returns +// and must check whether pm.currentProfile is Valid before using it. +func (pm *profileManager) SwitchToProfile(profile ipn.LoginProfileView) (cp ipn.LoginProfileView, changed bool, err error) { + prefs := defaultPrefs + switch { + case !profile.Valid(): + // Create a new profile that is not associated with any user. + profile = pm.NewProfileForUser("") + case profile == pm.currentProfile, + profile.ID() != "" && pm.currentProfile.Valid() && profile.ID() == pm.currentProfile.ID(), + profile.ID() == "" && profile.Equals(pm.currentProfile) && prefs.Equals(pm.prefs): + // The profile is already the current profile; no need to switch. + // + // It includes three cases: + // 1. The target profile and the current profile are aliases referencing the [ipn.LoginProfile]. + // The profile may be either a new (non-persisted) profile or an existing well-known profile. + // 2. The target profile is a well-known, persisted profile with the same ID as the current profile. + // 3. The target and the current profiles are both new (non-persisted) profiles and they are equal. + // At minimum, equality means that the profiles are owned by the same user on platforms that support it + // and the prefs are the same as well. + return pm.currentProfile, false, nil + case profile.ID() == "": + // Copy the specified profile to prevent accidental mutation. + profile = profile.AsStruct().View() + default: + // Find an existing profile by ID and load its prefs. + kp, ok := pm.knownProfiles[profile.ID()] + if !ok { + // The profile ID is not valid; it may have been deleted or never existed. + // As the target profile should have been returned by the [profileManager], + // this is unexpected and might indicate a bug in the code. + return pm.currentProfile, false, fmt.Errorf("[unexpected] %w: %s (%s)", errProfileNotFound, profile.Name(), profile.ID()) } - pm.NewProfileForUser(uid) - return pm.currentProfile, true - } - - if profile, err := pm.ProfileByID(profileID); err == nil { - if pm.CurrentProfile().ID() == profileID { - return pm.currentProfile, false - } - if err := pm.SwitchProfile(profile.ID()); err == nil { - return pm.currentProfile, true + profile = kp + if prefs, err = pm.loadSavedPrefs(profile.Key()); err != nil { + return pm.currentProfile, false, fmt.Errorf("failed to load profile prefs for %s (%s): %w", profile.Name(), profile.ID(), err) } } - if err := pm.SwitchToDefaultProfile(); err != nil { - pm.logf("%q's default profile cannot be used; creating a new one: %v", uid, err) - pm.NewProfile() + if profile.ID() == "" { // new profile that has never been persisted + metricNewProfile.Add(1) + } else { + metricSwitchProfile.Add(1) } - return pm.currentProfile, true + + pm.prefs = prefs + pm.updateHealth() + pm.currentProfile = profile + pm.currentUserID = profile.LocalUserID() + if err := pm.setProfileAsUserDefault(profile); err != nil { + // This is not a fatal error; we've already switched to the profile. + // But if updating the default profile fails, we should log it. + pm.logf("failed to set %s (%s) as the default profile: %v", profile.Name(), profile.ID(), err) + } + + if f := pm.StateChangeHook; f != nil { + f(pm.currentProfile, pm.prefs, false) + } + // Do not call pm.extHost.NotifyProfileChange here; it is invoked in + // [LocalBackend.resetForProfileChangeLockedOnEntry] after the netmap reset. + // TODO(nickkhyl): Consider moving it here (or into the stateChangeCb handler + // in [LocalBackend]) once the profile/node state, including the netmap, + // is actually tied to the current profile. + + return profile, true, nil } -// DefaultUserProfileID returns [ipn.ProfileID] of the default (last used) profile for the specified user, -// or an empty string if the specified user does not have a default profile. -func (pm *profileManager) DefaultUserProfileID(uid ipn.WindowsUserID) ipn.ProfileID { +// DefaultUserProfile returns a read-only view of the default (last used) profile for the specified user. +// It returns a read-only view of a new, non-persisted profile if the specified user does not have a default profile. +func (pm *profileManager) DefaultUserProfile(uid ipn.WindowsUserID) ipn.LoginProfileView { // Read the CurrentProfileKey from the store which stores // the selected profile for the specified user. b, err := pm.store.ReadState(ipn.CurrentProfileKey(string(uid))) - pm.dlogf("DefaultUserProfileID: ReadState(%q) = %v, %v", string(uid), len(b), err) + pm.dlogf("DefaultUserProfile: ReadState(%q) = %v, %v", string(uid), len(b), err) if err == ipn.ErrStateNotExist || len(b) == 0 { if runtime.GOOS == "windows" { - pm.dlogf("DefaultUserProfileID: windows: migrating from legacy preferences") - profile, err := pm.migrateFromLegacyPrefs(uid, false) + pm.dlogf("DefaultUserProfile: windows: migrating from legacy preferences") + profile, err := pm.migrateFromLegacyPrefs(uid) if err == nil { - return profile.ID() + return profile } pm.logf("failed to migrate from legacy preferences: %v", err) } - return "" + return pm.NewProfileForUser(uid) } pk := ipn.StateKey(string(b)) prof := pm.findProfileByKey(uid, pk) if !prof.Valid() { - pm.dlogf("DefaultUserProfileID: no profile found for key: %q", pk) - return "" + pm.dlogf("DefaultUserProfile: no profile found for key: %q", pk) + return pm.NewProfileForUser(uid) } - return prof.ID() + return prof } // checkProfileAccess returns an [errProfileAccessDenied] if the current user @@ -251,12 +328,6 @@ func (pm *profileManager) setUnattendedModeAsConfigured() error { } } -// Reset unloads the current profile, if any. -func (pm *profileManager) Reset() { - pm.currentUserID = "" - pm.NewProfile() -} - // SetPrefs sets the current profile's prefs to the provided value. // It also saves the prefs to the [ipn.StateStore]. It stores a copy of the // provided prefs, which may be accessed via [profileManager.CurrentPrefs]. @@ -288,13 +359,37 @@ func (pm *profileManager) SetPrefs(prefsIn ipn.PrefsView, np ipn.NetworkProfile) delete(pm.knownProfiles, p.ID()) } } - pm.currentProfile = cp + // TODO(nickkhyl): Revisit how we handle implicit switching to a different profile, + // which occurs when prefsIn represents a node/user different from that of the + // currentProfile. It happens when a login (either reauth or user-initiated login) + // is completed with a different node/user identity than the one currently in use. + // + // Currently, we overwrite the existing profile prefs with the ones from prefsIn, + // where prefsIn is the previous profile's prefs with an updated Persist, LoggedOut, + // WantRunning and possibly other fields. This may not be the desired behavior. + // + // Additionally, LocalBackend doesn't treat it as a proper profile switch, meaning that + // [LocalBackend.resetForProfileChangeLockedOnEntry] is not called and certain + // node/profile-specific state may not be reset as expected. + // + // However, [profileManager] notifies [ipnext.Extension]s about the profile change, + // so features migrated from LocalBackend to external packages should not be affected. + // + // See tailscale/corp#28014. + if !cp.Equals(pm.currentProfile) { + const sameNode = false // implicit profile switch + pm.currentProfile = cp + pm.prefs = prefsIn.AsStruct().View() + if f := pm.StateChangeHook; f != nil { + f(cp, prefsIn, sameNode) + } + pm.extHost.NotifyProfileChange(cp, prefsIn, sameNode) + } cp, err := pm.setProfilePrefs(nil, prefsIn, np) if err != nil { return err } return pm.setProfileAsUserDefault(cp) - } // setProfilePrefs is like [profileManager.SetPrefs], but sets prefs for the specified [ipn.LoginProfile], @@ -351,7 +446,20 @@ func (pm *profileManager) setProfilePrefs(lp *ipn.LoginProfile, prefsIn ipn.Pref // Update the current profile view to reflect the changes // if the specified profile is the current profile. if isCurrentProfile { - pm.currentProfile = lp.View() + // Always set pm.currentProfile to the new profile view for pointer equality. + // We check it further down the call stack. + lp := lp.View() + sameProfileInfo := lp.Equals(pm.currentProfile) + pm.currentProfile = lp + if !sameProfileInfo { + // But only invoke the callbacks if the profile info has actually changed. + const sameNode = true // just an info update; still the same node + pm.prefs = prefsIn.AsStruct().View() // suppress further callbacks for this change + if f := pm.StateChangeHook; f != nil { + f(lp, prefsIn, sameNode) + } + pm.extHost.NotifyProfileChange(lp, prefsIn, sameNode) + } } // An empty profile.ID indicates that the node info is not available yet, @@ -392,7 +500,33 @@ func newUnusedID(knownProfiles map[ipn.ProfileID]ipn.LoginProfileView) (ipn.Prof func (pm *profileManager) setProfilePrefsNoPermCheck(profile ipn.LoginProfileView, clonedPrefs ipn.PrefsView) error { isCurrentProfile := pm.currentProfile == profile if isCurrentProfile { + oldPrefs := pm.prefs pm.prefs = clonedPrefs + + // Sadly, profile prefs can be changed in multiple ways. + // It's pretty chaotic, and in many cases callers use + // unexported methods of the profile manager instead of + // going through [LocalBackend.setPrefsLockedOnEntry] + // or at least using [profileManager.SetPrefs]. + // + // While we should definitely clean this up to improve + // the overall structure of how prefs are set, which would + // also address current and future conflicts, such as + // competing features changing the same prefs, this method + // is currently the central place where we can detect all + // changes to the current profile's prefs. + // + // That said, regardless of the cleanup, we might want + // to keep the profileManager responsible for invoking + // profile- and prefs-related callbacks. + + if !clonedPrefs.Equals(oldPrefs) { + if f := pm.StateChangeHook; f != nil { + f(pm.currentProfile, clonedPrefs, true) + } + pm.extHost.NotifyProfilePrefsChanged(pm.currentProfile, oldPrefs, clonedPrefs) + } + pm.updateHealth() } if profile.Key() != "" { @@ -477,42 +611,32 @@ func (pm *profileManager) profilePrefs(p ipn.LoginProfileView) (ipn.PrefsView, e return pm.loadSavedPrefs(p.Key()) } -// SwitchProfile switches to the profile with the given id. +// SwitchToProfileByID switches to the profile with the given id. +// It returns the current profile and whether the call resulted in a profile change. // If the profile exists but is not accessible to the current user, it returns an [errProfileAccessDenied]. // If the profile does not exist, it returns an [errProfileNotFound]. -func (pm *profileManager) SwitchProfile(id ipn.ProfileID) error { - metricSwitchProfile.Add(1) - - kp, ok := pm.knownProfiles[id] - if !ok { - return errProfileNotFound +func (pm *profileManager) SwitchToProfileByID(id ipn.ProfileID) (_ ipn.LoginProfileView, changed bool, err error) { + if id == pm.currentProfile.ID() { + return pm.currentProfile, false, nil } - if pm.currentProfile.Valid() && kp.ID() == pm.currentProfile.ID() && pm.prefs.Valid() { - return nil - } - - if err := pm.checkProfileAccess(kp); err != nil { - return fmt.Errorf("%w: profile %q is not accessible to the current user", err, id) - } - prefs, err := pm.loadSavedPrefs(kp.Key()) + profile, err := pm.ProfileByID(id) if err != nil { - return err + return pm.currentProfile, false, err } - pm.prefs = prefs - pm.updateHealth() - pm.currentProfile = kp - return pm.setProfileAsUserDefault(kp) + return pm.SwitchToProfile(profile) } -// SwitchToDefaultProfile switches to the default (last used) profile for the current user. -// It creates a new one and switches to it if the current user does not have a default profile, +// SwitchToDefaultProfileForUser switches to the default (last used) profile for the specified user. +// It creates a new one and switches to it if the specified user does not have a default profile, // or returns an error if the default profile is inaccessible or could not be loaded. -func (pm *profileManager) SwitchToDefaultProfile() error { - if id := pm.DefaultUserProfileID(pm.currentUserID); id != "" { - return pm.SwitchProfile(id) - } - pm.NewProfileForUser(pm.currentUserID) - return nil +func (pm *profileManager) SwitchToDefaultProfileForUser(uid ipn.WindowsUserID) (_ ipn.LoginProfileView, changed bool, err error) { + return pm.SwitchToProfile(pm.DefaultUserProfile(uid)) +} + +// SwitchToDefaultProfile is like [profileManager.SwitchToDefaultProfileForUser], but switches +// to the default profile for the current user. +func (pm *profileManager) SwitchToDefaultProfile() (_ ipn.LoginProfileView, changed bool, err error) { + return pm.SwitchToDefaultProfileForUser(pm.currentUserID) } // setProfileAsUserDefault sets the specified profile as the default for the current user. @@ -529,8 +653,8 @@ func (pm *profileManager) setProfileAsUserDefault(profile ipn.LoginProfileView) return pm.WriteState(k, []byte(profile.Key())) } -func (pm *profileManager) loadSavedPrefs(key ipn.StateKey) (ipn.PrefsView, error) { - bs, err := pm.store.ReadState(key) +func (pm *profileManager) loadSavedPrefs(k ipn.StateKey) (ipn.PrefsView, error) { + bs, err := pm.store.ReadState(k) if err == ipn.ErrStateNotExist || len(bs) == 0 { return defaultPrefs, nil } @@ -538,10 +662,28 @@ func (pm *profileManager) loadSavedPrefs(key ipn.StateKey) (ipn.PrefsView, error return ipn.PrefsView{}, err } savedPrefs := ipn.NewPrefs() - if err := ipn.PrefsFromBytes(bs, savedPrefs); err != nil { - return ipn.PrefsView{}, fmt.Errorf("parsing saved prefs: %v", err) + + // if supported by the platform, create an empty hardware attestation key to use when deserializing + // to avoid type exceptions from json.Unmarshaling into an interface{}. + hw, _ := pm.newEmptyHardwareAttestationKey() + savedPrefs.Persist = &persist.Persist{ + AttestationKey: hw, } - pm.logf("using backend prefs for %q: %v", key, savedPrefs.Pretty()) + + if err := ipn.PrefsFromBytes(bs, savedPrefs); err != nil { + // Try loading again, this time ignoring the AttestationKey contents. + // If that succeeds, there's something wrong with the underlying + // attestation key mechanism (most likely the TPM changed), but we + // should at least proceed with client startup. + origErr := err + savedPrefs.Persist.AttestationKey = &noopAttestationKey{} + if err := ipn.PrefsFromBytes(bs, savedPrefs); err != nil { + return ipn.PrefsView{}, fmt.Errorf("parsing saved prefs: %w", err) + } else { + pm.logf("failed to parse savedPrefs with attestation key (error: %v) but parsing without the attestation key succeeded; will proceed without using the old attestation key", origErr) + } + } + pm.logf("using backend prefs for %q: %v", k, savedPrefs.Pretty()) // Ignore any old stored preferences for https://login.tailscale.com // as the control server that would override the new default of @@ -558,7 +700,7 @@ func (pm *profileManager) loadSavedPrefs(key ipn.StateKey) (ipn.PrefsView, error // cause any EditPrefs calls to fail (other than disabling auto-updates). // // Reset AutoUpdate.Apply if we detect such invalid prefs. - if savedPrefs.AutoUpdate.Apply.EqualBool(true) && !clientupdate.CanAutoUpdate() { + if savedPrefs.AutoUpdate.Apply.EqualBool(true) && !feature.CanAutoUpdate() { savedPrefs.AutoUpdate.Apply.Clear() } @@ -590,7 +732,6 @@ var errProfileAccessDenied = errors.New("profile access denied") // This is useful for deleting the last profile. In other cases, it is // recommended to call [profileManager.SwitchProfile] first. func (pm *profileManager) DeleteProfile(id ipn.ProfileID) error { - metricDeleteProfile.Add(1) if id == pm.currentProfile.ID() { return pm.deleteCurrentProfile() } @@ -610,7 +751,7 @@ func (pm *profileManager) deleteCurrentProfile() error { } if pm.currentProfile.ID() == "" { // Deleting the in-memory only new profile, just create a new one. - pm.NewProfile() + pm.SwitchToNewProfile() return nil } return pm.deleteProfileNoPermCheck(pm.currentProfile) @@ -620,12 +761,13 @@ func (pm *profileManager) deleteCurrentProfile() error { // but it doesn't check user's access rights to the profile. func (pm *profileManager) deleteProfileNoPermCheck(profile ipn.LoginProfileView) error { if profile.ID() == pm.currentProfile.ID() { - pm.NewProfile() + pm.SwitchToNewProfile() } if err := pm.WriteState(profile.Key(), nil); err != nil { return err } delete(pm.knownProfiles, profile.ID()) + metricDeleteProfile.Add(1) return pm.writeKnownProfiles() } @@ -637,7 +779,7 @@ func (pm *profileManager) DeleteAllProfilesForUser() error { currentProfileDeleted := false writeKnownProfiles := func() error { if currentProfileDeleted || pm.currentProfile.ID() == "" { - pm.NewProfile() + pm.SwitchToNewProfile() } return pm.writeKnownProfiles() } @@ -666,6 +808,7 @@ func (pm *profileManager) writeKnownProfiles() error { if err != nil { return err } + metricProfileCount.Set(int64(len(pm.knownProfiles))) return pm.WriteState(ipn.KnownProfilesStateKey, b) } @@ -676,45 +819,25 @@ func (pm *profileManager) updateHealth() { pm.health.SetAutoUpdatePrefs(pm.prefs.AutoUpdate().Check, pm.prefs.AutoUpdate().Apply) } -// NewProfile creates and switches to a new unnamed profile. The new profile is +// SwitchToNewProfile creates and switches to a new unnamed profile. The new profile is // not persisted until [profileManager.SetPrefs] is called with a logged-in user. -func (pm *profileManager) NewProfile() { - pm.NewProfileForUser(pm.currentUserID) +func (pm *profileManager) SwitchToNewProfile() { + pm.SwitchToNewProfileForUser(pm.currentUserID) } -// NewProfileForUser is like [profileManager.NewProfile], but it switches to the +// SwitchToNewProfileForUser is like [profileManager.SwitchToNewProfile], but it switches to the // specified user and sets that user as the profile owner for the new profile. -func (pm *profileManager) NewProfileForUser(uid ipn.WindowsUserID) { - pm.currentUserID = uid - - metricNewProfile.Add(1) - - pm.prefs = defaultPrefs - pm.updateHealth() - newProfile := &ipn.LoginProfile{LocalUserID: uid} - pm.currentProfile = newProfile.View() +func (pm *profileManager) SwitchToNewProfileForUser(uid ipn.WindowsUserID) { + pm.SwitchToProfile(pm.NewProfileForUser(uid)) } -// newProfileWithPrefs creates a new profile with the specified prefs and assigns -// the specified uid as the profile owner. If switchNow is true, it switches to the -// newly created profile immediately. It returns the newly created profile on success, -// or an error on failure. -func (pm *profileManager) newProfileWithPrefs(uid ipn.WindowsUserID, prefs ipn.PrefsView, switchNow bool) (ipn.LoginProfileView, error) { - metricNewProfile.Add(1) +// zeroProfile is a read-only view of a new, empty profile that is not persisted to the store. +var zeroProfile = (&ipn.LoginProfile{}).View() - profile, err := pm.setProfilePrefs(&ipn.LoginProfile{LocalUserID: uid}, prefs, ipn.NetworkProfile{}) - if err != nil { - return ipn.LoginProfileView{}, err - } - if switchNow { - pm.currentProfile = profile - pm.prefs = prefs.AsStruct().View() - pm.updateHealth() - if err := pm.setProfileAsUserDefault(profile); err != nil { - return ipn.LoginProfileView{}, err - } - } - return profile, nil +// NewProfileForUser creates a new profile for the specified user and returns a read-only view of it. +// It neither switches to the new profile nor persists it to the store. +func (pm *profileManager) NewProfileForUser(uid ipn.WindowsUserID) ipn.LoginProfileView { + return (&ipn.LoginProfile{LocalUserID: uid}).View() } // defaultPrefs is the default prefs for a new profile. This initializes before @@ -742,7 +865,10 @@ func (pm *profileManager) CurrentPrefs() ipn.PrefsView { // ReadStartupPrefsForTest reads the startup prefs from disk. It is only used for testing. func ReadStartupPrefsForTest(logf logger.Logf, store ipn.StateStore) (ipn.PrefsView, error) { - ht := new(health.Tracker) // in tests, don't care about the health status + testenv.AssertInTest() + bus := eventbus.New() + defer bus.Close() + ht := health.NewTracker(bus) // in tests, don't care about the health status pm, err := newProfileManager(store, logf, ht) if err != nil { return ipn.PrefsView{}, err @@ -798,35 +924,20 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, ht *healt return nil, err } + metricProfileCount.Set(int64(len(knownProfiles))) + pm := &profileManager{ - goos: goos, - store: store, - knownProfiles: knownProfiles, - logf: logf, - health: ht, + goos: goos, + store: store, + knownProfiles: knownProfiles, + logf: logf, + health: ht, + newEmptyHardwareAttestationKey: key.NewEmptyHardwareAttestationKey, } + var initialProfile ipn.LoginProfileView if stateKey != "" { - for _, v := range knownProfiles { - if v.Key() == stateKey { - pm.currentProfile = v - } - } - if !pm.currentProfile.Valid() { - if suf, ok := strings.CutPrefix(string(stateKey), "user-"); ok { - pm.currentUserID = ipn.WindowsUserID(suf) - } - pm.NewProfile() - } else { - pm.currentUserID = pm.currentProfile.LocalUserID() - } - prefs, err := pm.loadSavedPrefs(stateKey) - if err != nil { - return nil, err - } - if err := pm.setProfilePrefsNoPermCheck(pm.currentProfile, prefs); err != nil { - return nil, err - } + initialProfile = pm.findProfileByKey("", stateKey) // Most platform behavior is controlled by the goos parameter, however // some behavior is implied by build tag and fails when run on Windows, // so we explicitly avoid that behavior when running on Windows. @@ -837,17 +948,24 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, ht *healt } else if len(knownProfiles) == 0 && goos != "windows" && runtime.GOOS != "windows" { // No known profiles, try a migration. pm.dlogf("no known profiles; trying to migrate from legacy prefs") - if _, err := pm.migrateFromLegacyPrefs(pm.currentUserID, true); err != nil { - return nil, err - } - } else { - pm.NewProfile() - } + if initialProfile, err = pm.migrateFromLegacyPrefs(pm.currentUserID); err != nil { + } + } + if !initialProfile.Valid() { + var initialUserID ipn.WindowsUserID + if suf, ok := strings.CutPrefix(string(stateKey), "user-"); ok { + initialUserID = ipn.WindowsUserID(suf) + } + initialProfile = pm.NewProfileForUser(initialUserID) + } + if _, _, err := pm.SwitchToProfile(initialProfile); err != nil { + return nil, err + } return pm, nil } -func (pm *profileManager) migrateFromLegacyPrefs(uid ipn.WindowsUserID, switchNow bool) (ipn.LoginProfileView, error) { +func (pm *profileManager) migrateFromLegacyPrefs(uid ipn.WindowsUserID) (ipn.LoginProfileView, error) { metricMigration.Add(1) sentinel, prefs, err := pm.loadLegacyPrefs(uid) if err != nil { @@ -855,7 +973,7 @@ func (pm *profileManager) migrateFromLegacyPrefs(uid ipn.WindowsUserID, switchNo return ipn.LoginProfileView{}, fmt.Errorf("load legacy prefs: %w", err) } pm.dlogf("loaded legacy preferences; sentinel=%q", sentinel) - profile, err := pm.newProfileWithPrefs(uid, prefs, switchNow) + profile, err := pm.setProfilePrefs(&ipn.LoginProfile{LocalUserID: uid}, prefs, ipn.NetworkProfile{}) if err != nil { metricMigrationError.Add(1) return ipn.LoginProfileView{}, fmt.Errorf("migrating _daemon profile: %w", err) @@ -877,8 +995,27 @@ var ( metricSwitchProfile = clientmetric.NewCounter("profiles_switch") metricDeleteProfile = clientmetric.NewCounter("profiles_delete") metricDeleteAllProfile = clientmetric.NewCounter("profiles_delete_all") + metricProfileCount = clientmetric.NewGauge("profiles_count") metricMigration = clientmetric.NewCounter("profiles_migration") metricMigrationError = clientmetric.NewCounter("profiles_migration_error") metricMigrationSuccess = clientmetric.NewCounter("profiles_migration_success") ) + +// noopAttestationKey is a key.HardwareAttestationKey that always successfully +// unmarshals as a zero key. +type noopAttestationKey struct{} + +func (n noopAttestationKey) Public() crypto.PublicKey { + panic("noopAttestationKey.Public should not be called; missing IsZero check somewhere?") +} + +func (n noopAttestationKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + panic("noopAttestationKey.Sign should not be called; missing IsZero check somewhere?") +} + +func (n noopAttestationKey) MarshalJSON() ([]byte, error) { return nil, nil } +func (n noopAttestationKey) UnmarshalJSON([]byte) error { return nil } +func (n noopAttestationKey) Close() error { return nil } +func (n noopAttestationKey) Clone() key.HardwareAttestationKey { return n } +func (n noopAttestationKey) IsZero() bool { return true } diff --git a/vendor/tailscale.com/ipn/ipnlocal/serve.go b/vendor/tailscale.com/ipn/ipnlocal/serve.go index 638b26a..a857147 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/serve.go +++ b/vendor/tailscale.com/ipn/ipnlocal/serve.go @@ -1,6 +1,10 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_serve + +// TODO: move this whole file to its own package, out of ipnlocal. + package ipnlocal import ( @@ -12,6 +16,7 @@ import ( "errors" "fmt" "io" + "maps" "mime" "net" "net/http" @@ -28,19 +33,40 @@ import ( "time" "unicode/utf8" - "golang.org/x/net/http2" + "github.com/pires/go-proxyproto" + "go4.org/mem" "tailscale.com/ipn" - "tailscale.com/logtail/backoff" + "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/types/lazy" "tailscale.com/types/logger" + "tailscale.com/types/views" + "tailscale.com/util/backoff" + "tailscale.com/util/clientmetric" "tailscale.com/util/ctxkey" "tailscale.com/util/mak" + "tailscale.com/util/slicesx" "tailscale.com/version" ) +func init() { + hookServeTCPHandlerForVIPService.Set((*LocalBackend).tcpHandlerForVIPService) + hookTCPHandlerForServe.Set((*LocalBackend).tcpHandlerForServe) + hookServeUpdateServeTCPPortNetMapAddrListenersLocked.Set((*LocalBackend).updateServeTCPPortNetMapAddrListenersLocked) + + hookServeSetTCPPortsInterceptedFromNetmapAndPrefsLocked.Set(serveSetTCPPortsInterceptedFromNetmapAndPrefsLocked) + hookServeClearVIPServicesTCPPortsInterceptedLocked.Set(func(b *LocalBackend) { + b.setVIPServicesTCPPortsInterceptedLocked(nil) + }) + + hookMaybeMutateHostinfoLocked.Add(maybeUpdateHostinfoServicesHashLocked) + hookMaybeMutateHostinfoLocked.Add(maybeUpdateHostinfoFunnelLocked) + + RegisterC2N("GET /vip-services", handleC2NVIPServicesGet) +} + const ( contentTypeHeader = "Content-Type" grpcBaseContentType = "application/grpc" @@ -51,6 +77,10 @@ const ( // current etag of a resource. var ErrETagMismatch = errors.New("etag mismatch") +// ErrProxyToTailscaledSocket is returned when attempting to proxy +// to the tailscaled socket itself, which would create a loop. +var ErrProxyToTailscaledSocket = errors.New("cannot proxy to tailscaled socket") + var serveHTTPContextKey ctxkey.Key[*serveHTTPContext] type serveHTTPContext struct { @@ -60,6 +90,8 @@ type serveHTTPContext struct { // provides funnel-specific context, nil if not funneled Funnel *funnelFlow + // AppCapabilities lists all PeerCapabilities that should be forwarded by serve + AppCapabilities views.Slice[tailcfg.PeerCapability] } // funnelFlow represents a funneled connection initiated via IngressPeer @@ -135,16 +167,24 @@ func (s *localListener) Run() { var lc net.ListenConfig if initListenConfig != nil { + ifIndex, err := netmon.TailscaleInterfaceIndex() + if err != nil { + s.logf("localListener failed to get Tailscale interface index %v, backing off: %v", s.ap, err) + s.bo.BackOff(s.ctx, err) + continue + } + // On macOS, this sets the lc.Control hook to // setsockopt the interface index to bind to. This is - // required by the network sandbox to allow binding to - // a specific interface. Without this hook, the system - // chooses a default interface to bind to. - if err := initListenConfig(&lc, ip, s.b.prevIfState, s.b.dialer.TUNName()); err != nil { + // required by the network sandbox which will not automatically + // bind to the tailscale interface to prevent routing loops. + // Explicit binding allows us to bypass that restriction. + if err := initListenConfig(&lc, ip, ifIndex); err != nil { s.logf("localListener failed to init listen config %v, backing off: %v", s.ap, err) s.bo.BackOff(s.ctx, err) continue } + // On macOS (AppStore or macsys) and if we're binding to a privileged port, if version.IsSandboxedMacOS() && s.ap.Port() < 1024 { // On macOS, we need to bind to ""/all-interfaces due to @@ -222,6 +262,10 @@ func (s *localListener) handleListenersAccept(ln net.Listener) error { // // b.mu must be held. func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint16) { + if b.sys.IsNetstack() { + // don't listen on netmap addresses if we're in userspace mode + return + } // close existing listeners where port // is no longer in incoming ports list for ap, sl := range b.serveListeners { @@ -232,7 +276,7 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1 } } - nm := b.netMap + nm := b.NetMap() if nm == nil { b.logf("netMap is nil") return @@ -258,9 +302,22 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1 } } +func generateServeConfigETag(sc ipn.ServeConfigView) (string, error) { + j, err := json.Marshal(sc) + if err != nil { + return "", fmt.Errorf("encoding config: %w", err) + } + sum := sha256.Sum256(j) + return hex.EncodeToString(sum[:]), nil +} + // SetServeConfig establishes or replaces the current serve config. // ETag is an optional parameter to enforce Optimistic Concurrency Control. // If it is an empty string, then the config will be overwritten. +// +// New foreground config cannot override existing listeners--neither existing +// foreground listeners nor existing background listeners. Background config can +// change as long as the serve type (e.g. HTTP, TCP, etc.) remains the same. func (b *LocalBackend) SetServeConfig(config *ipn.ServeConfig, etag string) error { b.mu.Lock() defer b.mu.Unlock() @@ -276,13 +333,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string return errors.New("can't reconfigure tailscaled when using a config file; config file is locked") } - if config != nil { - if err := config.CheckValidServicesConfig(); err != nil { - return err - } - } - - nm := b.netMap + nm := b.NetMap() if nm == nil { return errors.New("netMap is nil") } @@ -294,21 +345,19 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string // not changed from the last config. prevConfig := b.serveConfig if etag != "" { - // Note that we marshal b.serveConfig - // and not use b.lastServeConfJSON as that might - // be a Go nil value, which produces a different - // checksum from a JSON "null" value. - prevBytes, err := json.Marshal(prevConfig) + prevETag, err := generateServeConfigETag(prevConfig) if err != nil { - return fmt.Errorf("error encoding previous config: %w", err) + return fmt.Errorf("generating ETag for previous config: %w", err) } - sum := sha256.Sum256(prevBytes) - previousEtag := hex.EncodeToString(sum[:]) - if etag != previousEtag { + if etag != prevETag { return ErrETagMismatch } } + if err := validateServeConfigUpdate(prevConfig, config.View()); err != nil { + return err + } + var bs []byte if config != nil { j, err := json.Marshal(config) @@ -355,6 +404,20 @@ func (b *LocalBackend) ServeConfig() ipn.ServeConfigView { return b.serveConfig } +// ServeConfigETag provides a view of the current serve mappings and an ETag, +// which can later be provided to [LocalBackend.SetServeConfig] to implement +// Optimistic Concurrency Control. +// +// If serving is not configured, the returned view is not Valid. +func (b *LocalBackend) ServeConfigETag() (scv ipn.ServeConfigView, etag string, err error) { + sc := b.ServeConfig() + etag, err = generateServeConfigETag(sc) + if err != nil { + return ipn.ServeConfigView{}, "", fmt.Errorf("generating ETag: %w", err) + } + return sc, etag, nil +} + // DeleteForegroundSession deletes a ServeConfig's foreground session // in the LocalBackend if it exists. It also ensures check, delete, and // set operations happen within the same mutex lock to avoid any races. @@ -439,6 +502,38 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target handler(c) } +func (b *LocalBackend) vipServicesFromPrefsLocked(prefs ipn.PrefsView) []*tailcfg.VIPService { + // keyed by service name + var services map[tailcfg.ServiceName]*tailcfg.VIPService + if b.serveConfig.Valid() { + for svc, config := range b.serveConfig.Services().All() { + mak.Set(&services, svc, &tailcfg.VIPService{ + Name: svc, + Ports: config.ServicePortRange(), + }) + } + } + + for _, s := range prefs.AdvertiseServices().All() { + sn := tailcfg.ServiceName(s) + if services == nil || services[sn] == nil { + mak.Set(&services, sn, &tailcfg.VIPService{ + Name: sn, + }) + } + services[sn].Active = true + } + + servicesList := slicesx.MapValues(services) + // [slicesx.MapValues] provides the values in an indeterminate order, but since we'll + // be hashing a representation of this list later we want it to be in a consistent + // order. + slices.SortFunc(servicesList, func(a, b *tailcfg.VIPService) int { + return strings.Compare(a.Name.String(), b.Name.String()) + }) + return servicesList +} + // tcpHandlerForVIPService returns a handler for a TCP connection to a VIP service // that is being served via the ipn.ServeConfig. It returns nil if the destination // address is not a VIP service or if the VIP service does not have a TCP handler set. @@ -522,16 +617,7 @@ func (b *LocalBackend) tcpHandlerForVIPService(dstAddr, srcAddr netip.AddrPort) }) } - errc := make(chan error, 1) - go func() { - _, err := io.Copy(backConn, conn) - errc <- err - }() - go func() { - _, err := io.Copy(conn, backConn) - errc <- err - }() - return <-errc + return b.forwardTCPWithProxyProtocol(conn, backConn, tcph.ProxyProtocol(), srcAddr, dport, backDst) } } @@ -611,28 +697,99 @@ func (b *LocalBackend) tcpHandlerForServe(dport uint16, srcAddr netip.AddrPort, // TODO(bradfitz): do the RegisterIPPortIdentity and // UnregisterIPPortIdentity stuff that netstack does - errc := make(chan error, 1) - go func() { - _, err := io.Copy(backConn, conn) - errc <- err - }() - go func() { - _, err := io.Copy(conn, backConn) - errc <- err - }() - return <-errc + return b.forwardTCPWithProxyProtocol(conn, backConn, tcph.ProxyProtocol(), srcAddr, dport, backDst) } } return nil } +// forwardTCPWithProxyProtocol forwards TCP traffic between conn and backConn, +// optionally prepending a PROXY protocol header if proxyProtoVer > 0. +// The srcAddr is the original client address used to build the PROXY header. +func (b *LocalBackend) forwardTCPWithProxyProtocol(conn, backConn net.Conn, proxyProtoVer int, srcAddr netip.AddrPort, dport uint16, backDst string) error { + var proxyHeader []byte + if proxyProtoVer > 0 { + backAddr := backConn.RemoteAddr().(*net.TCPAddr) + + // We always want to format the PROXY protocol header based on + // the IPv4 or IPv6-ness of the client. The SourceAddr and + // DestinationAddr need to match in type. + // If this is an IPv6-mapped IPv4 address, unmap it. + proxySrcAddr := srcAddr + if proxySrcAddr.Addr().Is4In6() { + proxySrcAddr = netip.AddrPortFrom( + proxySrcAddr.Addr().Unmap(), + proxySrcAddr.Port(), + ) + } + + is4 := proxySrcAddr.Addr().Is4() + + var destAddr netip.Addr + if self := b.currentNode().Self(); self.Valid() { + if is4 { + destAddr = nodeIP(self, netip.Addr.Is4) + } else { + destAddr = nodeIP(self, netip.Addr.Is6) + } + } + if !destAddr.IsValid() { + // Unexpected: we couldn't determine the node's IP address. + // Pick a best-effort destination address of localhost. + if is4 { + destAddr = netip.AddrFrom4([4]byte{127, 0, 0, 1}) + } else { + destAddr = netip.IPv6Loopback() + } + } + + header := &proxyproto.Header{ + Version: byte(proxyProtoVer), + Command: proxyproto.PROXY, + SourceAddr: net.TCPAddrFromAddrPort(proxySrcAddr), + DestinationAddr: &net.TCPAddr{ + IP: destAddr.AsSlice(), + Port: backAddr.Port, + }, + } + if is4 { + header.TransportProtocol = proxyproto.TCPv4 + } else { + header.TransportProtocol = proxyproto.TCPv6 + } + var err error + proxyHeader, err = header.Format() + if err != nil { + b.logf("localbackend: failed to format proxy protocol header for port %v (from %v) to %s: %v", dport, srcAddr, backDst, err) + } + } + + errc := make(chan error, 1) + go func() { + if len(proxyHeader) > 0 { + if _, err := backConn.Write(proxyHeader); err != nil { + errc <- err + backConn.Close() + return + } + } + _, err := io.Copy(backConn, conn) + errc <- err + }() + go func() { + _, err := io.Copy(conn, backConn) + errc <- err + }() + return <-errc +} + func (b *LocalBackend) getServeHandler(r *http.Request) (_ ipn.HTTPHandlerView, at string, ok bool) { var z ipn.HTTPHandlerView // zero value hostname := r.Host if r.TLS == nil { - tcd := "." + b.Status().CurrentTailnet.MagicDNSSuffix + tcd := "." + b.CurrentProfile().NetworkProfile().MagicDNSName if host, _, err := net.SplitHostPort(hostname); err == nil { hostname = host } @@ -676,6 +833,27 @@ func (b *LocalBackend) getServeHandler(r *http.Request) (_ ipn.HTTPHandlerView, // we serve requests for. `backend` is a HTTPHandler.Proxy string (url, hostport or just port). func (b *LocalBackend) proxyHandlerForBackend(backend string) (http.Handler, error) { targetURL, insecure := expandProxyArg(backend) + + // Handle unix: scheme specially + if strings.HasPrefix(targetURL, "unix:") { + socketPath := strings.TrimPrefix(targetURL, "unix:") + if socketPath == "" { + return nil, fmt.Errorf("empty unix socket path") + } + if b.isTailscaledSocket(socketPath) { + return nil, ErrProxyToTailscaledSocket + } + u, _ := url.Parse("http://localhost") + return &reverseProxy{ + logf: b.logf, + url: u, + insecure: false, + backend: backend, + lb: b, + socketPath: socketPath, + }, nil + } + u, err := url.Parse(targetURL) if err != nil { return nil, fmt.Errorf("invalid url %s: %w", targetURL, err) @@ -690,6 +868,22 @@ func (b *LocalBackend) proxyHandlerForBackend(backend string) (http.Handler, err return p, nil } +// isTailscaledSocket reports whether socketPath refers to the same file +// as the tailscaled socket. It uses os.SameFile to handle symlinks, +// bind mounts, and other path variations. +func (b *LocalBackend) isTailscaledSocket(socketPath string) bool { + tailscaledSocket := b.sys.SocketPath + if tailscaledSocket == "" { + return false + } + fi1, err1 := os.Stat(socketPath) + fi2, err2 := os.Stat(tailscaledSocket) + if err1 != nil || err2 != nil { + return false + } + return os.SameFile(fi1, fi2) +} + // reverseProxy is a proxy that forwards a request to a backend host // (preconfigured via ipn.ServeConfig). If the host is configured with // http+insecure prefix, connection between proxy and backend will be over @@ -704,8 +898,9 @@ type reverseProxy struct { insecure bool backend string lb *LocalBackend - httpTransport lazy.SyncValue[*http.Transport] // transport for non-h2c backends - h2cTransport lazy.SyncValue[*http2.Transport] // transport for h2c backends + socketPath string // path to unix socket, empty for TCP + httpTransport lazy.SyncValue[*http.Transport] // transport for non-h2c backends + h2cTransport lazy.SyncValue[*http.Transport] // transport for h2c backends // closed tracks whether proxy is closed/currently closing. closed atomic.Bool } @@ -713,9 +908,7 @@ type reverseProxy struct { // close ensures that any open backend connections get closed. func (rp *reverseProxy) close() { rp.closed.Store(true) - if h2cT := rp.h2cTransport.Get(func() *http2.Transport { - return nil - }); h2cT != nil { + if h2cT := rp.h2cTransport.Get(func() *http.Transport { return nil }); h2cT != nil { h2cT.CloseIdleConnections() } if httpTransport := rp.httpTransport.Get(func() *http.Transport { @@ -746,12 +939,19 @@ func (rp *reverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { r.Out.URL.RawPath = rp.url.RawPath } - r.Out.Host = r.In.Host + // For Unix sockets, use the URL's host (localhost) instead of the incoming host + if rp.socketPath != "" { + r.Out.Host = rp.url.Host + } else { + r.Out.Host = r.In.Host + } addProxyForwardedHeaders(r) rp.lb.addTailscaleIdentityHeaders(r) - }} - - // There is no way to autodetect h2c as per RFC 9113 + if err := rp.lb.addAppCapabilitiesHeader(r); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + }} // There is no way to autodetect h2c as per RFC 9113 // https://datatracker.ietf.org/doc/html/rfc9113#name-starting-http-2. // However, we assume that http:// proxy prefix in combination with the // protoccol being HTTP/2 is sufficient to detect h2c for our needs. Only use this for @@ -769,8 +969,16 @@ func (rp *reverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { // to the backend. The Transport gets created lazily, at most once. func (rp *reverseProxy) getTransport() *http.Transport { return rp.httpTransport.Get(func() *http.Transport { + dial := rp.lb.dialer.SystemDial + if rp.socketPath != "" { + dial = func(ctx context.Context, _, _ string) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, "unix", rp.socketPath) + } + } + return &http.Transport{ - DialContext: rp.lb.dialer.SystemDial, + DialContext: dial, TLSClientConfig: &tls.Config{ InsecureSkipVerify: rp.insecure, }, @@ -786,14 +994,21 @@ func (rp *reverseProxy) getTransport() *http.Transport { // getH2CTransport returns the Transport used for GRPC requests to the backend. // The Transport gets created lazily, at most once. -func (rp *reverseProxy) getH2CTransport() *http2.Transport { - return rp.h2cTransport.Get(func() *http2.Transport { - return &http2.Transport{ - AllowHTTP: true, - DialTLSContext: func(ctx context.Context, network string, addr string, _ *tls.Config) (net.Conn, error) { +func (rp *reverseProxy) getH2CTransport() http.RoundTripper { + return rp.h2cTransport.Get(func() *http.Transport { + var p http.Protocols + p.SetUnencryptedHTTP2(true) + tr := &http.Transport{ + Protocols: &p, + DialTLSContext: func(ctx context.Context, network string, addr string) (net.Conn, error) { + if rp.socketPath != "" { + var d net.Dialer + return d.DialContext(ctx, "unix", rp.socketPath) + } return rp.lb.dialer.SystemDial(ctx, "tcp", rp.url.Host) }, } + return tr }) } @@ -801,6 +1016,10 @@ func (rp *reverseProxy) getH2CTransport() *http2.Transport { // for a h2c server, but sufficient for our particular use case. func (rp *reverseProxy) shouldProxyViaH2C(r *http.Request) bool { contentType := r.Header.Get(contentTypeHeader) + // For unix sockets, check if it's gRPC content to determine h2c + if rp.socketPath != "" { + return r.ProtoMajor == 2 && isGRPCContentType(contentType) + } return r.ProtoMajor == 2 && strings.HasPrefix(rp.backend, "http://") && isGRPCContentType(contentType) } @@ -870,6 +1089,53 @@ func encTailscaleHeaderValue(v string) string { return mime.QEncoding.Encode("utf-8", v) } +func (b *LocalBackend) addAppCapabilitiesHeader(r *httputil.ProxyRequest) error { + const appCapabilitiesHeaderName = "Tailscale-App-Capabilities" + r.Out.Header.Del(appCapabilitiesHeaderName) + + c, ok := serveHTTPContextKey.ValueOk(r.Out.Context()) + if !ok || c.Funnel != nil { + return nil + } + acceptCaps := c.AppCapabilities + if acceptCaps.IsNil() { + return nil + } + peerCaps := b.PeerCaps(c.SrcAddr.Addr()) + if peerCaps == nil { + return nil + } + + peerCapsFiltered := make(map[tailcfg.PeerCapability][]tailcfg.RawMessage, acceptCaps.Len()) + for _, cap := range acceptCaps.AsSlice() { + if peerCaps.HasCapability(cap) { + peerCapsFiltered[cap] = peerCaps[cap] + } + } + + peerCapsSerialized, err := json.Marshal(peerCapsFiltered) + if err != nil { + b.logf("serve: failed to serialize filtered PeerCapMap: %v", err) + return fmt.Errorf("unable to process app capabilities") + } + + r.Out.Header.Set(appCapabilitiesHeaderName, encTailscaleHeaderValue(string(peerCapsSerialized))) + return nil +} + +// parseRedirectWithCode parses a redirect string that may optionally start with +// a HTTP redirect status code ("3xx:"). +// Returns the status code and the final redirect URL. +// If no code prefix is found, returns http.StatusFound (302). +func parseRedirectWithCode(redirect string) (code int, url string) { + if len(redirect) >= 4 && redirect[3] == ':' { + if statusCode, err := strconv.Atoi(redirect[:3]); err == nil && statusCode >= 300 && statusCode <= 399 { + return statusCode, redirect[4:] + } + } + return http.StatusFound, redirect +} + // serveWebHandler is an http.HandlerFunc that maps incoming requests to the // correct *http. func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) { @@ -883,6 +1149,13 @@ func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) { io.WriteString(w, s) return } + if v := h.Redirect(); v != "" { + code, v := parseRedirectWithCode(v) + v = strings.ReplaceAll(v, "${HOST}", r.Host) + v = strings.ReplaceAll(v, "${REQUEST_URI}", r.RequestURI) + http.Redirect(w, r, v, code) + return + } if v := h.Path(); v != "" { b.serveFileOrDirectory(w, r, v, mountPoint) return @@ -893,6 +1166,12 @@ func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "unknown proxy destination", http.StatusInternalServerError) return } + // Inject app capabilities to forward into the request context + c, ok := serveHTTPContextKey.ValueOk(r.Context()) + if !ok { + return + } + c.AppCapabilities = h.AcceptAppCaps() h := p.(http.Handler) // Trim the mount point from the URL path before proxying. (#6571) if r.URL.Path != "/" { @@ -985,6 +1264,10 @@ func expandProxyArg(s string) (targetURL string, insecureSkipVerify bool) { if s == "" { return "", false } + // Unix sockets - return as-is + if strings.HasPrefix(s, "unix:") { + return s, false + } if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") { return s, false } @@ -1007,8 +1290,6 @@ func allNumeric(s string) bool { } func (b *LocalBackend) webServerConfig(hostname string, forVIPService tailcfg.ServiceName, port uint16) (c ipn.WebServerConfigView, ok bool) { - key := ipn.HostPort(fmt.Sprintf("%s:%v", hostname, port)) - b.mu.Lock() defer b.mu.Unlock() @@ -1016,8 +1297,12 @@ func (b *LocalBackend) webServerConfig(hostname string, forVIPService tailcfg.Se return c, false } if forVIPService != "" { + magicDNSSuffix := b.currentNode().NetMap().MagicDNSSuffix() + fqdn := strings.Join([]string{forVIPService.WithoutPrefix(), magicDNSSuffix}, ".") + key := ipn.HostPort(net.JoinHostPort(fqdn, fmt.Sprintf("%d", port))) return b.serveConfig.FindServiceWeb(forVIPService, key) } + key := ipn.HostPort(net.JoinHostPort(hostname, fmt.Sprintf("%d", port))) return b.serveConfig.FindWeb(key) } @@ -1044,3 +1329,467 @@ func (b *LocalBackend) getTLSServeCertForPort(port uint16, forVIPService tailcfg return &cert, nil } } + +// setServeProxyHandlersLocked ensures there is an http proxy handler for each +// backend specified in serveConfig. It expects serveConfig to be valid and +// up-to-date, so should be called after reloadServeConfigLocked. +func (b *LocalBackend) setServeProxyHandlersLocked() { + if !b.serveConfig.Valid() { + return + } + var backends map[string]bool + for _, conf := range b.serveConfig.Webs() { + for _, h := range conf.Handlers().All() { + backend := h.Proxy() + if backend == "" { + // Only create proxy handlers for servers with a proxy backend. + continue + } + mak.Set(&backends, backend, true) + if _, ok := b.serveProxyHandlers.Load(backend); ok { + continue + } + + b.logf("serve: creating a new proxy handler for %s", backend) + p, err := b.proxyHandlerForBackend(backend) + if err != nil { + // The backend endpoint (h.Proxy) should have been validated by expandProxyTarget + // in the CLI, so just log the error here. + b.logf("[unexpected] could not create proxy for %v: %s", backend, err) + continue + } + b.serveProxyHandlers.Store(backend, p) + } + } + + // Clean up handlers for proxy backends that are no longer present + // in configuration. + b.serveProxyHandlers.Range(func(key, value any) bool { + backend := key.(string) + if !backends[backend] { + b.logf("serve: closing idle connections to %s", backend) + b.serveProxyHandlers.Delete(backend) + value.(*reverseProxy).close() + } + return true + }) +} + +// VIPServices returns the list of tailnet services that this node +// is serving as a destination for. +// The returned memory is owned by the caller. +func (b *LocalBackend) VIPServices() []*tailcfg.VIPService { + b.mu.Lock() + defer b.mu.Unlock() + return b.vipServicesFromPrefsLocked(b.pm.CurrentPrefs()) +} + +func handleC2NVIPServicesGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) { + b.logf("c2n: GET /vip-services received") + var res tailcfg.C2NVIPServicesResponse + res.VIPServices = b.VIPServices() + res.ServicesHash = vipServiceHash(b.logf, res.VIPServices) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(res) +} + +var metricIngressCalls = clientmetric.NewCounter("peerapi_ingress") + +func init() { + RegisterPeerAPIHandler("/v0/ingress", handleServeIngress) + +} + +func handleServeIngress(ph PeerAPIHandler, w http.ResponseWriter, r *http.Request) { + h := ph.(*peerAPIHandler) + metricIngressCalls.Add(1) + + // http.Errors only useful if hitting endpoint manually + // otherwise rely on log lines when debugging ingress connections + // as connection is hijacked for bidi and is encrypted tls + if !h.canIngress() { + h.logf("ingress: denied; no ingress cap from %v", h.remoteAddr) + http.Error(w, "denied; no ingress cap", http.StatusForbidden) + return + } + logAndError := func(code int, publicMsg string) { + h.logf("ingress: bad request from %v: %s", h.remoteAddr, publicMsg) + http.Error(w, publicMsg, code) + } + bad := func(publicMsg string) { + logAndError(http.StatusBadRequest, publicMsg) + } + if r.Method != "POST" { + logAndError(http.StatusMethodNotAllowed, "only POST allowed") + return + } + srcAddrStr := r.Header.Get("Tailscale-Ingress-Src") + if srcAddrStr == "" { + bad("Tailscale-Ingress-Src header not set") + return + } + srcAddr, err := netip.ParseAddrPort(srcAddrStr) + if err != nil { + bad("Tailscale-Ingress-Src header invalid; want ip:port") + return + } + target := ipn.HostPort(r.Header.Get("Tailscale-Ingress-Target")) + if target == "" { + bad("Tailscale-Ingress-Target header not set") + return + } + if _, _, err := net.SplitHostPort(string(target)); err != nil { + bad("Tailscale-Ingress-Target header invalid; want host:port") + return + } + + getConnOrReset := func() (net.Conn, bool) { + conn, _, err := w.(http.Hijacker).Hijack() + if err != nil { + h.logf("ingress: failed hijacking conn") + http.Error(w, "failed hijacking conn", http.StatusInternalServerError) + return nil, false + } + io.WriteString(conn, "HTTP/1.1 101 Switching Protocols\r\n\r\n") + return &ipn.FunnelConn{ + Conn: conn, + Src: srcAddr, + Target: target, + }, true + } + sendRST := func() { + http.Error(w, "denied", http.StatusForbidden) + } + + h.ps.b.HandleIngressTCPConn(h.peerNode, target, srcAddr, getConnOrReset, sendRST) +} + +// wantIngressLocked reports whether this node has ingress configured. This bool +// is sent to the coordination server (in Hostinfo.WireIngress) as an +// optimization hint to know primarily which nodes are NOT using ingress, to +// avoid doing work for regular nodes. +// +// Even if the user's ServeConfig.AllowFunnel map was manually edited in raw +// mode and contains map entries with false values, sending true (from Len > 0) +// is still fine. This is only an optimization hint for the control plane and +// doesn't affect security or correctness. And we also don't expect people to +// modify their ServeConfig in raw mode. +func (b *LocalBackend) wantIngressLocked() bool { + return b.serveConfig.Valid() && b.serveConfig.HasAllowFunnel() +} + +// hasIngressEnabledLocked reports whether the node has any funnel endpoint enabled. This bool is sent to control (in +// Hostinfo.IngressEnabled) to determine whether 'Funnel' badge should be displayed on this node in the admin panel. +func (b *LocalBackend) hasIngressEnabledLocked() bool { + return b.serveConfig.Valid() && b.serveConfig.IsFunnelOn() +} + +// shouldWireInactiveIngressLocked reports whether the node is in a state where funnel is not actively enabled, but it +// seems that it is intended to be used with funnel. +func (b *LocalBackend) shouldWireInactiveIngressLocked() bool { + return b.serveConfig.Valid() && !b.hasIngressEnabledLocked() && b.wantIngressLocked() +} + +func serveSetTCPPortsInterceptedFromNetmapAndPrefsLocked(b *LocalBackend, prefs ipn.PrefsView) (handlePorts []uint16) { + var vipServicesPorts map[tailcfg.ServiceName][]uint16 + + b.reloadServeConfigLocked(prefs) + if b.serveConfig.Valid() { + servePorts := make([]uint16, 0, 3) + for port := range b.serveConfig.TCPs() { + if port > 0 { + servePorts = append(servePorts, uint16(port)) + } + } + handlePorts = append(handlePorts, servePorts...) + + for svc, cfg := range b.serveConfig.Services().All() { + servicePorts := make([]uint16, 0, 3) + for port := range cfg.TCP().All() { + if port > 0 { + servicePorts = append(servicePorts, uint16(port)) + } + } + if _, ok := vipServicesPorts[svc]; !ok { + mak.Set(&vipServicesPorts, svc, servicePorts) + } else { + mak.Set(&vipServicesPorts, svc, append(vipServicesPorts[svc], servicePorts...)) + } + } + + b.setServeProxyHandlersLocked() + + // don't listen on netmap addresses if we're in userspace mode + if !b.sys.IsNetstack() { + b.updateServeTCPPortNetMapAddrListenersLocked(servePorts) + } + } + + b.setVIPServicesTCPPortsInterceptedLocked(vipServicesPorts) + + return handlePorts +} + +// reloadServeConfigLocked reloads the serve config from the store or resets the +// serve config to nil if not logged in. The "changed" parameter, when false, instructs +// the method to only run the reset-logic and not reload the store from memory to ensure +// foreground sessions are not removed if they are not saved on disk. +func (b *LocalBackend) reloadServeConfigLocked(prefs ipn.PrefsView) { + if !b.currentNode().Self().Valid() || !prefs.Valid() || b.pm.CurrentProfile().ID() == "" { + // We're not logged in, so we don't have a profile. + // Don't try to load the serve config. + b.lastServeConfJSON = mem.B(nil) + b.serveConfig = ipn.ServeConfigView{} + return + } + + confKey := ipn.ServeConfigKey(b.pm.CurrentProfile().ID()) + // TODO(maisem,bradfitz): prevent reading the config from disk + // if the profile has not changed. + confj, err := b.store.ReadState(confKey) + if err != nil { + b.lastServeConfJSON = mem.B(nil) + b.serveConfig = ipn.ServeConfigView{} + return + } + if b.lastServeConfJSON.Equal(mem.B(confj)) { + return + } + b.lastServeConfJSON = mem.B(confj) + var conf ipn.ServeConfig + if err := json.Unmarshal(confj, &conf); err != nil { + b.logf("invalid ServeConfig %q in StateStore: %v", confKey, err) + b.serveConfig = ipn.ServeConfigView{} + return + } + + // remove inactive sessions + maps.DeleteFunc(conf.Foreground, func(sessionID string, sc *ipn.ServeConfig) bool { + _, ok := b.notifyWatchers[sessionID] + return !ok + }) + + b.serveConfig = conf.View() +} + +func (b *LocalBackend) setVIPServicesTCPPortsInterceptedLocked(svcPorts map[tailcfg.ServiceName][]uint16) { + if len(svcPorts) == 0 { + b.shouldInterceptVIPServicesTCPPortAtomic.Store(func(netip.AddrPort) bool { return false }) + return + } + nm := b.currentNode().NetMap() + if nm == nil { + b.logf("can't set intercept function for Service TCP Ports, netMap is nil") + return + } + vipServiceIPMap := nm.GetVIPServiceIPMap() + if len(vipServiceIPMap) == 0 { + // No approved VIP Services + return + } + + svcAddrPorts := make(map[netip.Addr]func(uint16) bool) + // Only set the intercept function if the service has been assigned a VIP. + for svcName, ports := range svcPorts { + addrs, ok := vipServiceIPMap[svcName] + if !ok { + continue + } + interceptFn := generateInterceptTCPPortFunc(ports) + for _, addr := range addrs { + svcAddrPorts[addr] = interceptFn + } + } + + b.shouldInterceptVIPServicesTCPPortAtomic.Store(generateInterceptVIPServicesTCPPortFunc(svcAddrPorts)) +} + +func maybeUpdateHostinfoServicesHashLocked(b *LocalBackend, hi *tailcfg.Hostinfo, prefs ipn.PrefsView) bool { + latestHash := vipServiceHash(b.logf, b.vipServicesFromPrefsLocked(prefs)) + if hi.ServicesHash != latestHash { + hi.ServicesHash = latestHash + return true + } + return false +} + +func maybeUpdateHostinfoFunnelLocked(b *LocalBackend, hi *tailcfg.Hostinfo, prefs ipn.PrefsView) (changed bool) { + // The Hostinfo.IngressEnabled field is used to communicate to control whether + // the node has funnel enabled. + if ie := b.hasIngressEnabledLocked(); hi.IngressEnabled != ie { + b.logf("Hostinfo.IngressEnabled changed to %v", ie) + hi.IngressEnabled = ie + changed = true + } + // The Hostinfo.WireIngress field tells control whether the user intends + // to use funnel with this node even though it is not currently enabled. + // This is an optimization to control- Funnel requires creation of DNS + // records and because DNS propagation can take time, we want to ensure + // that the records exist for any node that intends to use funnel even + // if it's not enabled. If hi.IngressEnabled is true, control knows that + // DNS records are needed, so we can save bandwidth and not send + // WireIngress. + if wire := b.shouldWireInactiveIngressLocked(); hi.WireIngress != wire { + b.logf("Hostinfo.WireIngress changed to %v", wire) + hi.WireIngress = wire + changed = true + } + return changed +} + +func vipServiceHash(logf logger.Logf, services []*tailcfg.VIPService) string { + if len(services) == 0 { + return "" + } + h := sha256.New() + jh := json.NewEncoder(h) + if err := jh.Encode(services); err != nil { + logf("vipServiceHashLocked: %v", err) + return "" + } + var buf [sha256.Size]byte + h.Sum(buf[:0]) + return hex.EncodeToString(buf[:]) +} + +// validateServeConfigUpdate validates changes proposed by incoming serve +// configuration. +func validateServeConfigUpdate(existing, incoming ipn.ServeConfigView) error { + // Error messages returned by this function may be presented to end-users by + // frontends like the CLI. Thus these error messages should provide enough + // information for end-users to diagnose and resolve conflicts. + + if !incoming.Valid() { + return nil + } + + // For Services, TUN mode is mutually exclusive with L4 or L7 handlers. + for svcName, svcCfg := range incoming.Services().All() { + hasTCP := svcCfg.TCP().Len() > 0 + hasWeb := svcCfg.Web().Len() > 0 + if svcCfg.Tun() && (hasTCP || hasWeb) { + return fmt.Errorf("cannot configure TUN mode in combination with TCP or web handlers for %s", svcName) + } + } + + if !existing.Valid() { + return nil + } + + // New foreground listeners must be on open ports. + for sessionID, incomingFg := range incoming.Foreground().All() { + if !existing.Foreground().Has(sessionID) { + // This is a new session. + for port := range incomingFg.TCPs() { + if _, exists := existing.FindTCP(port); exists { + return fmt.Errorf("listener already exists for port %d", port) + } + } + } + } + + // New background listeners cannot overwrite existing foreground listeners. + for port := range incoming.TCP().All() { + if _, exists := existing.FindForegroundTCP(port); exists { + return fmt.Errorf("foreground listener already exists for port %d", port) + } + } + + // Incoming configuration cannot change the serve type in use by a port. + for port, incomingHandler := range incoming.TCP().All() { + existingHandler, exists := existing.FindTCP(port) + if !exists { + continue + } + + existingServeType := serveTypeFromPortHandler(existingHandler) + incomingServeType := serveTypeFromPortHandler(incomingHandler) + if incomingServeType != existingServeType { + return fmt.Errorf("want to serve %q, but port %d is already serving %q", incomingServeType, port, existingServeType) + } + } + + // Validations for Tailscale Services. + for svcName, incomingSvcCfg := range incoming.Services().All() { + existingSvcCfg, exists := existing.Services().GetOk(svcName) + if !exists { + continue + } + + // Incoming configuration cannot change the serve type in use by a port. + for port, incomingHandler := range incomingSvcCfg.TCP().All() { + existingHandler, exists := existingSvcCfg.TCP().GetOk(port) + if !exists { + continue + } + + existingServeType := serveTypeFromPortHandler(existingHandler) + incomingServeType := serveTypeFromPortHandler(incomingHandler) + if incomingServeType != existingServeType { + return fmt.Errorf("want to serve %q, but port %d is already serving %q for %s", incomingServeType, port, existingServeType, svcName) + } + } + + existingHasTCP := existingSvcCfg.TCP().Len() > 0 + existingHasWeb := existingSvcCfg.Web().Len() > 0 + + // A Service cannot turn on TUN mode if TCP or web handlers exist. + if incomingSvcCfg.Tun() && (existingHasTCP || existingHasWeb) { + return fmt.Errorf("cannot turn on TUN mode with existing TCP or web handlers for %s", svcName) + } + + incomingHasTCP := incomingSvcCfg.TCP().Len() > 0 + incomingHasWeb := incomingSvcCfg.Web().Len() > 0 + + // A Service cannot add TCP or web handlers if TUN mode is enabled. + if (incomingHasTCP || incomingHasWeb) && existingSvcCfg.Tun() { + return fmt.Errorf("cannot add TCP or web handlers as TUN mode is enabled for %s", svcName) + } + } + + return nil +} + +// serveType is a high-level descriptor of the kind of serve performed by a TCP +// port handler. +type serveType int + +const ( + serveTypeHTTPS serveType = iota + serveTypeHTTP + serveTypeTCP + serveTypeTLSTerminatedTCP +) + +func (s serveType) String() string { + switch s { + case serveTypeHTTP: + return "http" + case serveTypeHTTPS: + return "https" + case serveTypeTCP: + return "tcp" + case serveTypeTLSTerminatedTCP: + return "tls-terminated-tcp" + default: + return "unknownServeType" + } +} + +// serveTypeFromPortHandler is used to get a high-level descriptor of the kind +// of serve being performed by a port handler. +func serveTypeFromPortHandler(ph ipn.TCPPortHandlerView) serveType { + switch { + case ph.HTTP(): + return serveTypeHTTP + case ph.HTTPS(): + return serveTypeHTTPS + case ph.TerminateTLS() != "": + return serveTypeTLSTerminatedTCP + case ph.TCPForward() != "": + return serveTypeTCP + default: + return -1 + } +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/serve_disabled.go b/vendor/tailscale.com/ipn/ipnlocal/serve_disabled.go new file mode 100644 index 0000000..a971129 --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/serve_disabled.go @@ -0,0 +1,34 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_serve + +// These are temporary (2025-09-13) stubs for when tailscaled is built with the +// ts_omit_serve build tag, disabling serve. +// +// TODO: move serve to a separate package, out of ipnlocal, and delete this +// file. One step at a time. + +package ipnlocal + +import ( + "tailscale.com/ipn" + "tailscale.com/tailcfg" +) + +const serveEnabled = false + +type localListener = struct{} + +func (b *LocalBackend) DeleteForegroundSession(sessionID string) error { + return nil +} + +type funnelFlow = struct{} + +func (*LocalBackend) hasIngressEnabledLocked() bool { return false } +func (*LocalBackend) shouldWireInactiveIngressLocked() bool { return false } + +func (b *LocalBackend) vipServicesFromPrefsLocked(prefs ipn.PrefsView) []*tailcfg.VIPService { + return nil +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/ssh.go b/vendor/tailscale.com/ipn/ipnlocal/ssh.go index 47a74e2..e2c2f50 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/ssh.go +++ b/vendor/tailscale.com/ipn/ipnlocal/ssh.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux || (darwin && !ios) || freebsd || openbsd +//go:build ((linux && !android) || (darwin && !ios) || freebsd || openbsd || plan9) && !ts_omit_ssh package ipnlocal diff --git a/vendor/tailscale.com/ipn/ipnlocal/ssh_stub.go b/vendor/tailscale.com/ipn/ipnlocal/ssh_stub.go index 7875ae3..6b2e360 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/ssh_stub.go +++ b/vendor/tailscale.com/ipn/ipnlocal/ssh_stub.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build ios || (!linux && !darwin && !freebsd && !openbsd) +//go:build ts_omit_ssh || ios || android || (!linux && !darwin && !freebsd && !openbsd && !plan9) package ipnlocal diff --git a/vendor/tailscale.com/ipn/ipnlocal/taildrop.go b/vendor/tailscale.com/ipn/ipnlocal/taildrop.go deleted file mode 100644 index db7d8e1..0000000 --- a/vendor/tailscale.com/ipn/ipnlocal/taildrop.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package ipnlocal - -import ( - "maps" - "slices" - "strings" - - "tailscale.com/ipn" -) - -// UpdateOutgoingFiles updates b.outgoingFiles to reflect the given updates and -// sends an ipn.Notify with the full list of outgoingFiles. -func (b *LocalBackend) UpdateOutgoingFiles(updates map[string]*ipn.OutgoingFile) { - b.mu.Lock() - if b.outgoingFiles == nil { - b.outgoingFiles = make(map[string]*ipn.OutgoingFile, len(updates)) - } - maps.Copy(b.outgoingFiles, updates) - outgoingFiles := make([]*ipn.OutgoingFile, 0, len(b.outgoingFiles)) - for _, file := range b.outgoingFiles { - outgoingFiles = append(outgoingFiles, file) - } - b.mu.Unlock() - slices.SortFunc(outgoingFiles, func(a, b *ipn.OutgoingFile) int { - t := a.Started.Compare(b.Started) - if t != 0 { - return t - } - return strings.Compare(a.Name, b.Name) - }) - b.send(ipn.Notify{OutgoingFiles: outgoingFiles}) -} diff --git a/vendor/tailscale.com/ipn/ipnlocal/tailnetlock_disabled.go b/vendor/tailscale.com/ipn/ipnlocal/tailnetlock_disabled.go new file mode 100644 index 0000000..85cf4bd --- /dev/null +++ b/vendor/tailscale.com/ipn/ipnlocal/tailnetlock_disabled.go @@ -0,0 +1,31 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_tailnetlock + +package ipnlocal + +import ( + "tailscale.com/ipn" + "tailscale.com/ipn/ipnstate" + "tailscale.com/tka" + "tailscale.com/types/netmap" +) + +type tkaState struct { + authority *tka.Authority +} + +func (b *LocalBackend) initTKALocked() error { + return nil +} + +func (b *LocalBackend) tkaSyncIfNeeded(nm *netmap.NetworkMap, prefs ipn.PrefsView) error { + return nil +} + +func (b *LocalBackend) tkaFilterNetmapLocked(nm *netmap.NetworkMap) {} + +func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus { + return &ipnstate.NetworkLockStatus{Enabled: false} +} diff --git a/vendor/tailscale.com/ipn/ipnlocal/web_client.go b/vendor/tailscale.com/ipn/ipnlocal/web_client.go index 219a4c5..a3c9387 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/web_client.go +++ b/vendor/tailscale.com/ipn/ipnlocal/web_client.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios && !android +//go:build !ios && !android && !ts_omit_webclient package ipnlocal @@ -19,14 +19,15 @@ import ( "tailscale.com/client/local" "tailscale.com/client/web" - "tailscale.com/logtail/backoff" "tailscale.com/net/netutil" "tailscale.com/tailcfg" + "tailscale.com/tsconst" "tailscale.com/types/logger" + "tailscale.com/util/backoff" "tailscale.com/util/mak" ) -const webClientPort = web.ListenPort +const webClientPort = tsconst.WebListenPort // webClient holds state for the web interface for managing this // tailscale instance. The web interface is not used by default, @@ -116,11 +117,12 @@ func (b *LocalBackend) handleWebClientConn(c net.Conn) error { // for each of the local device's Tailscale IP addresses. This is needed to properly // route local traffic when using kernel networking mode. func (b *LocalBackend) updateWebClientListenersLocked() { - if b.netMap == nil { + nm := b.currentNode().NetMap() + if nm == nil { return } - addrs := b.netMap.GetAddresses() + addrs := nm.GetAddresses() for _, pfx := range addrs.All() { addrPort := netip.AddrPortFrom(pfx.Addr(), webClientPort) if _, ok := b.webClientListeners[addrPort]; ok { diff --git a/vendor/tailscale.com/ipn/ipnlocal/web_client_stub.go b/vendor/tailscale.com/ipn/ipnlocal/web_client_stub.go index 31735de..787867b 100644 --- a/vendor/tailscale.com/ipn/ipnlocal/web_client_stub.go +++ b/vendor/tailscale.com/ipn/ipnlocal/web_client_stub.go @@ -1,22 +1,20 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build ios || android +//go:build ios || android || ts_omit_webclient package ipnlocal import ( "errors" "net" - - "tailscale.com/client/local" ) const webClientPort = 5252 type webClient struct{} -func (b *LocalBackend) ConfigureWebClient(lc *local.Client) {} +func (b *LocalBackend) ConfigureWebClient(any) {} func (b *LocalBackend) webClientGetOrInit() error { return errors.New("not implemented") diff --git a/vendor/tailscale.com/ipn/ipnstate/ipnstate.go b/vendor/tailscale.com/ipn/ipnstate/ipnstate.go index 89c6d7e..213090b 100644 --- a/vendor/tailscale.com/ipn/ipnstate/ipnstate.go +++ b/vendor/tailscale.com/ipn/ipnstate/ipnstate.go @@ -89,6 +89,7 @@ type Status struct { // TKAKey describes a key trusted by network lock. type TKAKey struct { + Kind string Key key.NLPublic Metadata map[string]string Votes uint @@ -251,9 +252,10 @@ type PeerStatus struct { PrimaryRoutes *views.Slice[netip.Prefix] `json:",omitempty"` // Endpoints: - Addrs []string - CurAddr string // one of Addrs, or unique if roaming - Relay string // DERP region + Addrs []string + CurAddr string // one of Addrs, or unique if roaming + Relay string // DERP region + PeerRelay string // peer relay address (ip:port:vni) RxBytes int64 TxBytes int64 @@ -451,6 +453,9 @@ func (sb *StatusBuilder) AddPeer(peer key.NodePublic, st *PeerStatus) { if v := st.Relay; v != "" { e.Relay = v } + if v := st.PeerRelay; v != "" { + e.PeerRelay = v + } if v := st.UserID; v != 0 { e.UserID = v } @@ -697,10 +702,17 @@ type PingResult struct { Err string LatencySeconds float64 - // Endpoint is the ip:port if direct UDP was used. - // It is not currently set for TSMP pings. + // Endpoint is a string of the form "{ip}:{port}" if direct UDP was used. It + // is not currently set for TSMP. Endpoint string + // PeerRelay is a string of the form "{ip}:{port}:vni:{vni}" if a peer + // relay was used. It is not currently set for TSMP. Note that this field + // is not omitted during JSON encoding if it contains a zero value. This is + // done for consistency with the Endpoint field; this structure is exposed + // externally via localAPI, so we want to maintain the existing convention. + PeerRelay string + // DERPRegionID is non-zero DERP region ID if DERP was used. // It is not currently set for TSMP pings. DERPRegionID int @@ -735,6 +747,7 @@ func (pr *PingResult) ToPingResponse(pingType tailcfg.PingType) *tailcfg.PingRes Err: pr.Err, LatencySeconds: pr.LatencySeconds, Endpoint: pr.Endpoint, + PeerRelay: pr.PeerRelay, DERPRegionID: pr.DERPRegionID, DERPRegionCode: pr.DERPRegionCode, PeerAPIPort: pr.PeerAPIPort, diff --git a/vendor/tailscale.com/ipn/localapi/cert.go b/vendor/tailscale.com/ipn/localapi/cert.go index 323406f..2313631 100644 --- a/vendor/tailscale.com/ipn/localapi/cert.go +++ b/vendor/tailscale.com/ipn/localapi/cert.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios && !android && !js +//go:build !ios && !android && !js && !ts_omit_acme package localapi @@ -14,6 +14,10 @@ import ( "tailscale.com/ipn/ipnlocal" ) +func init() { + Register("cert/", (*Handler).serveCert) +} + func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) { if !h.PermitWrite && !h.PermitCert { http.Error(w, "cert access denied", http.StatusForbidden) diff --git a/vendor/tailscale.com/ipn/localapi/debug.go b/vendor/tailscale.com/ipn/localapi/debug.go new file mode 100644 index 0000000..ae9cb01 --- /dev/null +++ b/vendor/tailscale.com/ipn/localapi/debug.go @@ -0,0 +1,495 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_debug + +package localapi + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/netip" + "reflect" + "slices" + "strconv" + "sync" + "time" + + "tailscale.com/client/tailscale/apitype" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" + "tailscale.com/ipn" + "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/httpm" +) + +func init() { + Register("component-debug-logging", (*Handler).serveComponentDebugLogging) + Register("debug", (*Handler).serveDebug) + Register("debug-rotate-disco-key", (*Handler).serveDebugRotateDiscoKey) + Register("dev-set-state-store", (*Handler).serveDevSetStateStore) + Register("debug-bus-events", (*Handler).serveDebugBusEvents) + Register("debug-bus-graph", (*Handler).serveEventBusGraph) + Register("debug-derp-region", (*Handler).serveDebugDERPRegion) + Register("debug-dial-types", (*Handler).serveDebugDialTypes) + Register("debug-log", (*Handler).serveDebugLog) + Register("debug-packet-filter-matches", (*Handler).serveDebugPacketFilterMatches) + Register("debug-packet-filter-rules", (*Handler).serveDebugPacketFilterRules) + Register("debug-peer-endpoint-changes", (*Handler).serveDebugPeerEndpointChanges) + Register("debug-optional-features", (*Handler).serveDebugOptionalFeatures) +} + +func (h *Handler) serveDebugPeerEndpointChanges(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "status access denied", http.StatusForbidden) + return + } + + ipStr := r.FormValue("ip") + if ipStr == "" { + http.Error(w, "missing 'ip' parameter", http.StatusBadRequest) + return + } + ip, err := netip.ParseAddr(ipStr) + if err != nil { + http.Error(w, "invalid IP", http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", "application/json") + chs, err := h.b.GetPeerEndpointChanges(r.Context(), ip) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + e := json.NewEncoder(w) + e.SetIndent("", "\t") + e.Encode(chs) +} + +func (h *Handler) serveComponentDebugLogging(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + component := r.FormValue("component") + secs, _ := strconv.Atoi(r.FormValue("secs")) + err := h.b.SetComponentDebugLogging(component, h.clock.Now().Add(time.Duration(secs)*time.Second)) + var res struct { + Error string + } + if err != nil { + res.Error = err.Error() + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(res) +} + +func (h *Handler) serveDebugDialTypes(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug-dial-types access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) + return + } + + ip := r.FormValue("ip") + port := r.FormValue("port") + network := r.FormValue("network") + + addr := ip + ":" + port + if _, err := netip.ParseAddrPort(addr); err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprintf(w, "invalid address %q: %v", addr, err) + return + } + + ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + defer cancel() + + var bareDialer net.Dialer + + dialer := h.b.Dialer() + + var peerDialer net.Dialer + peerDialer.Control = dialer.PeerDialControlFunc() + + // Kick off a dial with each available dialer in parallel. + dialers := []struct { + name string + dial func(context.Context, string, string) (net.Conn, error) + }{ + {"SystemDial", dialer.SystemDial}, + {"UserDial", dialer.UserDial}, + {"PeerDial", peerDialer.DialContext}, + {"BareDial", bareDialer.DialContext}, + } + type result struct { + name string + conn net.Conn + err error + } + results := make(chan result, len(dialers)) + + var wg sync.WaitGroup + for _, dialer := range dialers { + dialer := dialer // loop capture + + wg.Add(1) + go func() { + defer wg.Done() + conn, err := dialer.dial(ctx, network, addr) + results <- result{dialer.name, conn, err} + }() + } + + wg.Wait() + for range len(dialers) { + res := <-results + fmt.Fprintf(w, "[%s] connected=%v err=%v\n", res.name, res.conn != nil, res.err) + if res.conn != nil { + res.conn.Close() + } + } +} + +func (h *Handler) serveDebug(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, "debug not supported in this build", http.StatusNotImplemented) + return + } + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "POST required", http.StatusMethodNotAllowed) + return + } + // The action is normally in a POST form parameter, but + // some actions (like "notify") want a full JSON body, so + // permit some to have their action in a header. + var action string + switch v := r.Header.Get("Debug-Action"); v { + case "notify": + action = v + default: + action = r.FormValue("action") + } + var err error + switch action { + case "derp-set-homeless": + h.b.MagicConn().SetHomeless(true) + case "derp-unset-homeless": + h.b.MagicConn().SetHomeless(false) + case "rebind": + err = h.b.DebugRebind() + case "restun": + err = h.b.DebugReSTUN() + case "notify": + var n ipn.Notify + err = json.NewDecoder(r.Body).Decode(&n) + if err != nil { + break + } + h.b.DebugNotify(n) + case "notify-last-netmap": + h.b.DebugNotifyLastNetMap() + case "break-tcp-conns": + err = h.b.DebugBreakTCPConns() + case "break-derp-conns": + err = h.b.DebugBreakDERPConns() + case "force-netmap-update": + h.b.DebugForceNetmapUpdate() + case "control-knobs": + k := h.b.ControlKnobs() + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(k.AsDebugJSON()) + if err == nil { + return + } + case "pick-new-derp": + err = h.b.DebugPickNewDERP() + case "force-prefer-derp": + var n int + err = json.NewDecoder(r.Body).Decode(&n) + if err != nil { + break + } + h.b.DebugForcePreferDERP(n) + case "peer-relay-servers": + servers := h.b.DebugPeerRelayServers().Slice() + slices.SortFunc(servers, func(a, b netip.Addr) int { + return a.Compare(b) + }) + err = json.NewEncoder(w).Encode(servers) + if err == nil { + return + } + case "rotate-disco-key": + err = h.b.DebugRotateDiscoKey() + case "": + err = fmt.Errorf("missing parameter 'action'") + default: + err = fmt.Errorf("unknown action %q", action) + } + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", "text/plain") + io.WriteString(w, "done\n") +} + +func (h *Handler) serveDevSetStateStore(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "POST required", http.StatusMethodNotAllowed) + return + } + if err := h.b.SetDevStateStore(r.FormValue("key"), r.FormValue("value")); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/plain") + io.WriteString(w, "done\n") +} + +func (h *Handler) serveDebugPacketFilterRules(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + nm := h.b.NetMap() + if nm == nil { + http.Error(w, "no netmap", http.StatusNotFound) + return + } + w.Header().Set("Content-Type", "application/json") + + enc := json.NewEncoder(w) + enc.SetIndent("", "\t") + enc.Encode(nm.PacketFilterRules) +} + +func (h *Handler) serveDebugPacketFilterMatches(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + nm := h.b.NetMap() + if nm == nil { + http.Error(w, "no netmap", http.StatusNotFound) + return + } + w.Header().Set("Content-Type", "application/json") + + enc := json.NewEncoder(w) + enc.SetIndent("", "\t") + enc.Encode(nm.PacketFilter) +} + +// debugEventError provides the JSON encoding of internal errors from event processing. +type debugEventError struct { + Error string +} + +// serveDebugBusEvents taps into the tailscaled/utils/eventbus and streams +// events to the client. +func (h *Handler) serveDebugBusEvents(w http.ResponseWriter, r *http.Request) { + // Require write access (~root) as the logs could contain something + // sensitive. + if !h.PermitWrite { + http.Error(w, "event bus access denied", http.StatusForbidden) + return + } + if r.Method != httpm.GET { + http.Error(w, "GET required", http.StatusMethodNotAllowed) + return + } + + bus, ok := h.LocalBackend().Sys().Bus.GetOK() + if !ok { + http.Error(w, "event bus not running", http.StatusNoContent) + return + } + + f, ok := w.(http.Flusher) + if !ok { + http.Error(w, "streaming unsupported", http.StatusInternalServerError) + return + } + + io.WriteString(w, `{"Event":"[event listener connected]\n"}`+"\n") + f.Flush() + + mon := bus.Debugger().WatchBus() + defer mon.Close() + + i := 0 + for { + select { + case <-r.Context().Done(): + fmt.Fprintf(w, `{"Event":"[event listener closed]\n"}`) + return + case <-mon.Done(): + return + case event := <-mon.Events(): + data := eventbus.DebugEvent{ + Count: i, + Type: reflect.TypeOf(event.Event).String(), + Event: event.Event, + From: event.From.Name(), + } + for _, client := range event.To { + data.To = append(data.To, client.Name()) + } + + if msg, err := json.Marshal(data); err != nil { + data.Event = debugEventError{Error: fmt.Sprintf( + "failed to marshal JSON for %T", event.Event, + )} + if errMsg, err := json.Marshal(data); err != nil { + fmt.Fprintf(w, + `{"Count": %d, "Event":"[ERROR] failed to marshal JSON for %T\n"}`, + i, event.Event) + } else { + w.Write(errMsg) + } + } else { + w.Write(msg) + } + f.Flush() + i++ + } + } +} + +// serveEventBusGraph taps into the event bus and dumps out the active graph of +// publishers and subscribers. It does not represent anything about the messages +// exchanged. +func (h *Handler) serveEventBusGraph(w http.ResponseWriter, r *http.Request) { + if r.Method != httpm.GET { + http.Error(w, "GET required", http.StatusMethodNotAllowed) + return + } + + bus, ok := h.LocalBackend().Sys().Bus.GetOK() + if !ok { + http.Error(w, "event bus not running", http.StatusPreconditionFailed) + return + } + + debugger := bus.Debugger() + clients := debugger.Clients() + + graph := map[string]eventbus.DebugTopic{} + + for _, client := range clients { + for _, pub := range debugger.PublishTypes(client) { + topic, ok := graph[pub.Name()] + if !ok { + topic = eventbus.DebugTopic{Name: pub.Name()} + } + topic.Publisher = client.Name() + graph[pub.Name()] = topic + } + for _, sub := range debugger.SubscribeTypes(client) { + topic, ok := graph[sub.Name()] + if !ok { + topic = eventbus.DebugTopic{Name: sub.Name()} + } + topic.Subscribers = append(topic.Subscribers, client.Name()) + graph[sub.Name()] = topic + } + } + + // The top level map is not really needed for the client, convert to a list. + topics := eventbus.DebugTopics{} + for _, v := range graph { + topics.Topics = append(topics.Topics, v) + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(topics) +} + +func (h *Handler) serveDebugLog(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasLogTail { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + if !h.PermitRead { + http.Error(w, "debug-log access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) + return + } + defer h.b.TryFlushLogs() // kick off upload after we're done logging + + type logRequestJSON struct { + Lines []string + Prefix string + } + + var logRequest logRequestJSON + if err := json.NewDecoder(r.Body).Decode(&logRequest); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + prefix := logRequest.Prefix + if prefix == "" { + prefix = "debug-log" + } + logf := logger.WithPrefix(h.logf, prefix+": ") + + // We can write logs too fast for logtail to handle, even when + // opting-out of rate limits. Limit ourselves to at most one message + // per 20ms and a burst of 60 log lines, which should be fast enough to + // not block for too long but slow enough that we can upload all lines. + logf = logger.SlowLoggerWithClock(r.Context(), logf, 20*time.Millisecond, 60, h.clock.Now) + + for _, line := range logRequest.Lines { + logf("%s", line) + } + + w.WriteHeader(http.StatusNoContent) +} + +func (h *Handler) serveDebugOptionalFeatures(w http.ResponseWriter, r *http.Request) { + of := &apitype.OptionalFeatures{ + Features: feature.Registered(), + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(of) +} + +func (h *Handler) serveDebugRotateDiscoKey(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "POST required", http.StatusMethodNotAllowed) + return + } + if err := h.b.DebugRotateDiscoKey(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/plain") + io.WriteString(w, "done\n") +} diff --git a/vendor/tailscale.com/ipn/localapi/debugderp.go b/vendor/tailscale.com/ipn/localapi/debugderp.go index 6636fd2..3edbc08 100644 --- a/vendor/tailscale.com/ipn/localapi/debugderp.go +++ b/vendor/tailscale.com/ipn/localapi/debugderp.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_debug + package localapi import ( @@ -228,55 +230,59 @@ func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) { // Start by checking whether we can establish a HTTP connection for _, derpNode := range reg.Nodes { - connSuccess := checkConn(derpNode) + if !derpNode.STUNOnly { + connSuccess := checkConn(derpNode) - // Verify that the /generate_204 endpoint works - captivePortalURL := fmt.Sprintf("http://%s/generate_204?t=%d", derpNode.HostName, time.Now().Unix()) - req, err := http.NewRequest("GET", captivePortalURL, nil) - if err != nil { - st.Warnings = append(st.Warnings, fmt.Sprintf("Internal error creating request for captive portal check: %v", err)) - continue - } - req.Header.Set("Cache-Control", "no-cache, no-store, must-revalidate, no-transform, max-age=0") - resp, err := client.Do(req) - if err != nil { - st.Warnings = append(st.Warnings, fmt.Sprintf("Error making request to the captive portal check %q; is port 80 blocked?", captivePortalURL)) - } else { - resp.Body.Close() - } + // Verify that the /generate_204 endpoint works + captivePortalURL := fmt.Sprintf("http://%s/generate_204?t=%d", derpNode.HostName, time.Now().Unix()) + req, err := http.NewRequest("GET", captivePortalURL, nil) + if err != nil { + st.Warnings = append(st.Warnings, fmt.Sprintf("Internal error creating request for captive portal check: %v", err)) + continue + } + req.Header.Set("Cache-Control", "no-cache, no-store, must-revalidate, no-transform, max-age=0") + resp, err := client.Do(req) + if err != nil { + st.Warnings = append(st.Warnings, fmt.Sprintf("Error making request to the captive portal check %q; is port 80 blocked?", captivePortalURL)) + } else { + resp.Body.Close() + } - if !connSuccess { - continue - } + if !connSuccess { + continue + } - fakePrivKey := key.NewNode() + fakePrivKey := key.NewNode() - // Next, repeatedly get the server key to see if the node is - // behind a load balancer (incorrectly). - serverPubKeys := make(map[key.NodePublic]bool) - for i := range 5 { - func() { - rc := derphttp.NewRegionClient(fakePrivKey, h.logf, h.b.NetMon(), func() *tailcfg.DERPRegion { - return &tailcfg.DERPRegion{ - RegionID: reg.RegionID, - RegionCode: reg.RegionCode, - RegionName: reg.RegionName, - Nodes: []*tailcfg.DERPNode{derpNode}, + // Next, repeatedly get the server key to see if the node is + // behind a load balancer (incorrectly). + serverPubKeys := make(map[key.NodePublic]bool) + for i := range 5 { + func() { + rc := derphttp.NewRegionClient(fakePrivKey, h.logf, h.b.NetMon(), func() *tailcfg.DERPRegion { + return &tailcfg.DERPRegion{ + RegionID: reg.RegionID, + RegionCode: reg.RegionCode, + RegionName: reg.RegionName, + Nodes: []*tailcfg.DERPNode{derpNode}, + } + }) + if err := rc.Connect(ctx); err != nil { + st.Errors = append(st.Errors, fmt.Sprintf("Error connecting to node %q @ try %d: %v", derpNode.HostName, i, err)) + return } - }) - if err := rc.Connect(ctx); err != nil { - st.Errors = append(st.Errors, fmt.Sprintf("Error connecting to node %q @ try %d: %v", derpNode.HostName, i, err)) - return - } - if len(serverPubKeys) == 0 { - st.Info = append(st.Info, fmt.Sprintf("Successfully established a DERP connection with node %q", derpNode.HostName)) - } - serverPubKeys[rc.ServerPublicKey()] = true - }() - } - if len(serverPubKeys) > 1 { - st.Errors = append(st.Errors, fmt.Sprintf("Received multiple server public keys (%d); is the DERP server behind a load balancer?", len(serverPubKeys))) + if len(serverPubKeys) == 0 { + st.Info = append(st.Info, fmt.Sprintf("Successfully established a DERP connection with node %q", derpNode.HostName)) + } + serverPubKeys[rc.ServerPublicKey()] = true + }() + } + if len(serverPubKeys) > 1 { + st.Errors = append(st.Errors, fmt.Sprintf("Received multiple server public keys (%d); is the DERP server behind a load balancer?", len(serverPubKeys))) + } + } else { + st.Info = append(st.Info, fmt.Sprintf("Node %q is marked STUNOnly; skipped non-STUN checks", derpNode.HostName)) } // Send a STUN query to this node to verify whether or not it diff --git a/vendor/tailscale.com/ipn/localapi/localapi.go b/vendor/tailscale.com/ipn/localapi/localapi.go index d1f07ea..4648b2c 100644 --- a/vendor/tailscale.com/ipn/localapi/localapi.go +++ b/vendor/tailscale.com/ipn/localapi/localapi.go @@ -7,23 +7,15 @@ package localapi import ( "bytes" "cmp" - "context" - "crypto/sha256" - "encoding/hex" + "crypto/subtle" "encoding/json" "errors" "fmt" "io" - "maps" - "mime" - "mime/multipart" "net" "net/http" - "net/http/httputil" "net/netip" "net/url" - "os" - "path" "runtime" "slices" "strconv" @@ -33,41 +25,43 @@ import ( "golang.org/x/net/dns/dnsmessage" "tailscale.com/client/tailscale/apitype" - "tailscale.com/clientupdate" - "tailscale.com/drive" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" + "tailscale.com/health/healthmsg" "tailscale.com/hostinfo" "tailscale.com/ipn" "tailscale.com/ipn/ipnauth" "tailscale.com/ipn/ipnlocal" "tailscale.com/ipn/ipnstate" "tailscale.com/logtail" - "tailscale.com/net/netmon" + "tailscale.com/net/netns" "tailscale.com/net/netutil" - "tailscale.com/net/portmapper" "tailscale.com/tailcfg" - "tailscale.com/taildrop" - "tailscale.com/tka" "tailscale.com/tstime" - "tailscale.com/types/dnstype" + "tailscale.com/types/appctype" "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/logid" "tailscale.com/types/ptr" - "tailscale.com/types/tkatype" "tailscale.com/util/clientmetric" - "tailscale.com/util/httphdr" + "tailscale.com/util/eventbus" "tailscale.com/util/httpm" "tailscale.com/util/mak" "tailscale.com/util/osdiag" - "tailscale.com/util/progresstracking" "tailscale.com/util/rands" - "tailscale.com/util/syspolicy/rsop" - "tailscale.com/util/syspolicy/setting" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/version" "tailscale.com/wgengine/magicsock" ) +var ( + metricInvalidRequests = clientmetric.NewCounter("localapi_invalid_requests") + metricDebugMetricsCalls = clientmetric.NewCounter("localapi_debugmetric_requests") + metricUserMetricsCalls = clientmetric.NewCounter("localapi_usermetric_requests") + metricBugReportRequests = clientmetric.NewCounter("localapi_bugreport_requests") +) + type LocalAPIHandler func(*Handler, http.ResponseWriter, *http.Request) // handler is the set of LocalAPI handlers, keyed by the part of the @@ -75,80 +69,96 @@ type LocalAPIHandler func(*Handler, http.ResponseWriter, *http.Request) // then it's a prefix match. var handler = map[string]LocalAPIHandler{ // The prefix match handlers end with a slash: - "cert/": (*Handler).serveCert, - "file-put/": (*Handler).serveFilePut, - "files/": (*Handler).serveFiles, - "policy/": (*Handler).servePolicy, "profiles/": (*Handler).serveProfiles, // The other /localapi/v0/NAME handlers are exact matches and contain only NAME // without a trailing slash: - "alpha-set-device-attrs": (*Handler).serveSetDeviceAttrs, // see tailscale/corp#24690 - "bugreport": (*Handler).serveBugReport, - "check-ip-forwarding": (*Handler).serveCheckIPForwarding, - "check-prefs": (*Handler).serveCheckPrefs, - "check-udp-gro-forwarding": (*Handler).serveCheckUDPGROForwarding, - "component-debug-logging": (*Handler).serveComponentDebugLogging, - "debug": (*Handler).serveDebug, - "debug-derp-region": (*Handler).serveDebugDERPRegion, - "debug-dial-types": (*Handler).serveDebugDialTypes, - "debug-log": (*Handler).serveDebugLog, - "debug-packet-filter-matches": (*Handler).serveDebugPacketFilterMatches, - "debug-packet-filter-rules": (*Handler).serveDebugPacketFilterRules, - "debug-peer-endpoint-changes": (*Handler).serveDebugPeerEndpointChanges, - "debug-portmap": (*Handler).serveDebugPortmap, - "derpmap": (*Handler).serveDERPMap, - "dev-set-state-store": (*Handler).serveDevSetStateStore, - "dial": (*Handler).serveDial, - "disconnect-control": (*Handler).disconnectControl, - "dns-osconfig": (*Handler).serveDNSOSConfig, - "dns-query": (*Handler).serveDNSQuery, - "drive/fileserver-address": (*Handler).serveDriveServerAddr, - "drive/shares": (*Handler).serveShares, - "file-targets": (*Handler).serveFileTargets, - "goroutines": (*Handler).serveGoroutines, - "handle-push-message": (*Handler).serveHandlePushMessage, - "id-token": (*Handler).serveIDToken, - "login-interactive": (*Handler).serveLoginInteractive, - "logout": (*Handler).serveLogout, - "logtap": (*Handler).serveLogTap, - "metrics": (*Handler).serveMetrics, - "ping": (*Handler).servePing, - "pprof": (*Handler).servePprof, - "prefs": (*Handler).servePrefs, - "query-feature": (*Handler).serveQueryFeature, - "reload-config": (*Handler).reloadConfig, - "reset-auth": (*Handler).serveResetAuth, - "serve-config": (*Handler).serveServeConfig, - "set-dns": (*Handler).serveSetDNS, - "set-expiry-sooner": (*Handler).serveSetExpirySooner, - "set-gui-visible": (*Handler).serveSetGUIVisible, - "set-push-device-token": (*Handler).serveSetPushDeviceToken, - "set-udp-gro-forwarding": (*Handler).serveSetUDPGROForwarding, - "set-use-exit-node-enabled": (*Handler).serveSetUseExitNodeEnabled, - "start": (*Handler).serveStart, - "status": (*Handler).serveStatus, - "suggest-exit-node": (*Handler).serveSuggestExitNode, - "tka/affected-sigs": (*Handler).serveTKAAffectedSigs, - "tka/cosign-recovery-aum": (*Handler).serveTKACosignRecoveryAUM, - "tka/disable": (*Handler).serveTKADisable, - "tka/force-local-disable": (*Handler).serveTKALocalDisable, - "tka/generate-recovery-aum": (*Handler).serveTKAGenerateRecoveryAUM, - "tka/init": (*Handler).serveTKAInit, - "tka/log": (*Handler).serveTKALog, - "tka/modify": (*Handler).serveTKAModify, - "tka/sign": (*Handler).serveTKASign, - "tka/status": (*Handler).serveTKAStatus, - "tka/submit-recovery-aum": (*Handler).serveTKASubmitRecoveryAUM, - "tka/verify-deeplink": (*Handler).serveTKAVerifySigningDeeplink, - "tka/wrap-preauth-key": (*Handler).serveTKAWrapPreauthKey, - "update/check": (*Handler).serveUpdateCheck, - "update/install": (*Handler).serveUpdateInstall, - "update/progress": (*Handler).serveUpdateProgress, - "upload-client-metrics": (*Handler).serveUploadClientMetrics, - "usermetrics": (*Handler).serveUserMetrics, - "watch-ipn-bus": (*Handler).serveWatchIPNBus, - "whois": (*Handler).serveWhoIs, + "check-prefs": (*Handler).serveCheckPrefs, + "check-so-mark-in-use": (*Handler).serveCheckSOMarkInUse, + "derpmap": (*Handler).serveDERPMap, + "goroutines": (*Handler).serveGoroutines, + "login-interactive": (*Handler).serveLoginInteractive, + "logout": (*Handler).serveLogout, + "ping": (*Handler).servePing, + "prefs": (*Handler).servePrefs, + "reload-config": (*Handler).reloadConfig, + "reset-auth": (*Handler).serveResetAuth, + "set-expiry-sooner": (*Handler).serveSetExpirySooner, + "shutdown": (*Handler).serveShutdown, + "start": (*Handler).serveStart, + "status": (*Handler).serveStatus, + "whois": (*Handler).serveWhoIs, +} + +func init() { + if buildfeatures.HasAppConnectors { + Register("appc-route-info", (*Handler).serveGetAppcRouteInfo) + } + if buildfeatures.HasAdvertiseRoutes { + Register("check-ip-forwarding", (*Handler).serveCheckIPForwarding) + Register("check-udp-gro-forwarding", (*Handler).serveCheckUDPGROForwarding) + Register("set-udp-gro-forwarding", (*Handler).serveSetUDPGROForwarding) + } + if buildfeatures.HasUseExitNode && runtime.GOOS == "linux" { + Register("check-reverse-path-filtering", (*Handler).serveCheckReversePathFiltering) + } + if buildfeatures.HasClientMetrics { + Register("upload-client-metrics", (*Handler).serveUploadClientMetrics) + } + if buildfeatures.HasClientUpdate { + Register("update/check", (*Handler).serveUpdateCheck) + } + if buildfeatures.HasUseExitNode { + Register("suggest-exit-node", (*Handler).serveSuggestExitNode) + Register("set-use-exit-node-enabled", (*Handler).serveSetUseExitNodeEnabled) + } + if buildfeatures.HasACME { + Register("set-dns", (*Handler).serveSetDNS) + } + if buildfeatures.HasDebug { + Register("bugreport", (*Handler).serveBugReport) + Register("pprof", (*Handler).servePprof) + } + if buildfeatures.HasDebug || buildfeatures.HasServe { + Register("watch-ipn-bus", (*Handler).serveWatchIPNBus) + } + if buildfeatures.HasDNS { + Register("dns-osconfig", (*Handler).serveDNSOSConfig) + Register("dns-query", (*Handler).serveDNSQuery) + } + if buildfeatures.HasUserMetrics { + Register("usermetrics", (*Handler).serveUserMetrics) + } + if buildfeatures.HasServe { + Register("query-feature", (*Handler).serveQueryFeature) + } + if buildfeatures.HasOutboundProxy || buildfeatures.HasSSH { + Register("dial", (*Handler).serveDial) + } + if buildfeatures.HasClientMetrics || buildfeatures.HasDebug { + Register("metrics", (*Handler).serveMetrics) + } + if buildfeatures.HasDebug || buildfeatures.HasAdvertiseRoutes { + Register("disconnect-control", (*Handler).disconnectControl) + } + // Alpha/experimental/debug features. These should be moved to + // their own features if/when they graduate. + if buildfeatures.HasDebug { + Register("id-token", (*Handler).serveIDToken) + Register("alpha-set-device-attrs", (*Handler).serveSetDeviceAttrs) // see tailscale/corp#24690 + Register("handle-push-message", (*Handler).serveHandlePushMessage) + Register("set-push-device-token", (*Handler).serveSetPushDeviceToken) + } + if buildfeatures.HasDebug || runtime.GOOS == "windows" || runtime.GOOS == "darwin" { + Register("set-gui-visible", (*Handler).serveSetGUIVisible) + } + if buildfeatures.HasLogTail { + // TODO(bradfitz): separate out logtail tap functionality from upload + // functionality to make this possible? But seems unlikely people would + // want just this. They could "tail -f" or "journalctl -f" their logs + // themselves. + Register("logtap", (*Handler).serveLogTap) + } } // Register registers a new LocalAPI handler for the given name. @@ -169,9 +179,26 @@ var ( metrics = map[string]*clientmetric.Metric{} ) -// NewHandler creates a new LocalAPI HTTP handler. All parameters are required. -func NewHandler(actor ipnauth.Actor, b *ipnlocal.LocalBackend, logf logger.Logf, logID logid.PublicID) *Handler { - return &Handler{Actor: actor, b: b, logf: logf, backendLogID: logID, clock: tstime.StdClock{}} +// NewHandler creates a new LocalAPI HTTP handler from the given config. +func NewHandler(cfg HandlerConfig) *Handler { + return &Handler{ + Actor: cfg.Actor, + b: cfg.Backend, + logf: cfg.Logf, + backendLogID: cfg.LogID, + clock: tstime.StdClock{}, + eventBus: cfg.EventBus, + } +} + +// HandlerConfig carries the settings for a local API handler. +// All fields are required. +type HandlerConfig struct { + Actor ipnauth.Actor + Backend *ipnlocal.LocalBackend + Logf logger.Logf + LogID logid.PublicID + EventBus *eventbus.Bus } type Handler struct { @@ -200,6 +227,11 @@ type Handler struct { logf logger.Logf backendLogID logid.PublicID clock tstime.Clock + eventBus *eventbus.Bus // read-only after initialization +} + +func (h *Handler) Logf(format string, args ...any) { + h.logf(format, args...) } func (h *Handler) LocalBackend() *ipnlocal.LocalBackend { @@ -228,13 +260,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "auth required", http.StatusUnauthorized) return } - if pass != h.RequiredPassword { + if subtle.ConstantTimeCompare([]byte(pass), []byte(h.RequiredPassword)) == 0 { metricInvalidRequests.Add(1) http.Error(w, "bad password", http.StatusForbidden) return } } - if fn, ok := handlerForPath(r.URL.Path); ok { + if fn, route, ok := handlerForPath(r.URL.Path); ok { + h.logRequest(r.Method, route) fn(h, w, r) } else { http.NotFound(w, r) @@ -270,9 +303,9 @@ func (h *Handler) validHost(hostname string) bool { // handlerForPath returns the LocalAPI handler for the provided Request.URI.Path. // (the path doesn't include any query parameters) -func handlerForPath(urlPath string) (h LocalAPIHandler, ok bool) { +func handlerForPath(urlPath string) (h LocalAPIHandler, route string, ok bool) { if urlPath == "/" { - return (*Handler).serveLocalAPIRoot, true + return (*Handler).serveLocalAPIRoot, "/", true } suff, ok := strings.CutPrefix(urlPath, "/localapi/v0/") if !ok { @@ -280,22 +313,31 @@ func handlerForPath(urlPath string) (h LocalAPIHandler, ok bool) { // to people that they're not necessarily stable APIs. In practice we'll // probably need to keep them pretty stable anyway, but for now treat // them as an internal implementation detail. - return nil, false + return nil, "", false } if fn, ok := handler[suff]; ok { // Here we match exact handler suffixes like "status" or ones with a // slash already in their name, like "tka/status". - return fn, true + return fn, "/localapi/v0/" + suff, true } // Otherwise, it might be a prefix match like "files/*" which we look up // by the prefix including first trailing slash. if i := strings.IndexByte(suff, '/'); i != -1 { suff = suff[:i+1] if fn, ok := handler[suff]; ok { - return fn, true + return fn, "/localapi/v0/" + suff, true } } - return nil, false + return nil, "", false +} + +func (h *Handler) logRequest(method, route string) { + switch method { + case httpm.GET, httpm.HEAD, httpm.OPTIONS: + // don't log safe methods + default: + h.Logf("localapi: [%s] %s", method, route) + } } func (*Handler) serveLocalAPIRoot(w http.ResponseWriter, r *http.Request) { @@ -328,7 +370,7 @@ func (h *Handler) serveIDToken(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - httpReq, err := http.NewRequest("POST", "https://unused/machine/id-token", bytes.NewReader(b)) + httpReq, err := http.NewRequest(httpm.POST, "https://unused/machine/id-token", bytes.NewReader(b)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -351,7 +393,7 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) { http.Error(w, "bugreport access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) return } @@ -395,8 +437,19 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) { // OS-specific details h.logf.JSON(1, "UserBugReportOS", osdiag.SupportInfo(osdiag.LogSupportInfoReasonBugReport)) + // Tailnet Lock details + st := h.b.NetworkLockStatus() + if st.Enabled { + h.logf.JSON(1, "UserBugReportTailnetLockStatus", st) + if st.NodeKeySignature != nil { + h.logf("user bugreport tailnet lock signature: %s", st.NodeKeySignature.String()) + } + } + if defBool(r.URL.Query().Get("diagnose"), false) { - h.b.Doctor(r.Context(), logger.WithPrefix(h.logf, "diag: ")) + if f, ok := ipnlocal.HookDoctor.GetOk(); ok { + f(r.Context(), h.b, logger.WithPrefix(h.logf, "diag: ")) + } } w.Header().Set("Content-Type", "text/plain") fmt.Fprintln(w, startMarker) @@ -429,6 +482,8 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) { // NOTE(andrew): if we have anything else we want to do while recording // a bugreport, we can add it here. + metricBugReportRequests.Add(1) + // Read from the client; this will also return when the client closes // the connection. var buf [1]byte @@ -467,7 +522,7 @@ func (h *Handler) serveSetDeviceAttrs(w http.ResponseWriter, r *http.Request) { http.Error(w, "set-device-attrs access denied", http.StatusForbidden) return } - if r.Method != "PATCH" { + if r.Method != httpm.PATCH { http.Error(w, "only PATCH allowed", http.StatusMethodNotAllowed) return } @@ -572,7 +627,7 @@ func (h *Handler) serveLogTap(w http.ResponseWriter, r *http.Request) { http.Error(w, "logtap access denied", http.StatusForbidden) return } - if r.Method != "GET" { + if r.Method != httpm.GET { http.Error(w, "GET required", http.StatusMethodNotAllowed) return } @@ -619,369 +674,6 @@ func (h *Handler) serveUserMetrics(w http.ResponseWriter, r *http.Request) { h.b.UserMetricsRegistry().Handler(w, r) } -func (h *Handler) serveDebug(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - if r.Method != "POST" { - http.Error(w, "POST required", http.StatusMethodNotAllowed) - return - } - // The action is normally in a POST form parameter, but - // some actions (like "notify") want a full JSON body, so - // permit some to have their action in a header. - var action string - switch v := r.Header.Get("Debug-Action"); v { - case "notify": - action = v - default: - action = r.FormValue("action") - } - var err error - switch action { - case "derp-set-homeless": - h.b.MagicConn().SetHomeless(true) - case "derp-unset-homeless": - h.b.MagicConn().SetHomeless(false) - case "rebind": - err = h.b.DebugRebind() - case "restun": - err = h.b.DebugReSTUN() - case "notify": - var n ipn.Notify - err = json.NewDecoder(r.Body).Decode(&n) - if err != nil { - break - } - h.b.DebugNotify(n) - case "notify-last-netmap": - h.b.DebugNotifyLastNetMap() - case "break-tcp-conns": - err = h.b.DebugBreakTCPConns() - case "break-derp-conns": - err = h.b.DebugBreakDERPConns() - case "force-netmap-update": - h.b.DebugForceNetmapUpdate() - case "control-knobs": - k := h.b.ControlKnobs() - w.Header().Set("Content-Type", "application/json") - err = json.NewEncoder(w).Encode(k.AsDebugJSON()) - if err == nil { - return - } - case "pick-new-derp": - err = h.b.DebugPickNewDERP() - case "force-prefer-derp": - var n int - err = json.NewDecoder(r.Body).Decode(&n) - if err != nil { - break - } - h.b.DebugForcePreferDERP(n) - case "": - err = fmt.Errorf("missing parameter 'action'") - default: - err = fmt.Errorf("unknown action %q", action) - } - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - w.Header().Set("Content-Type", "text/plain") - io.WriteString(w, "done\n") -} - -func (h *Handler) serveDevSetStateStore(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - if r.Method != "POST" { - http.Error(w, "POST required", http.StatusMethodNotAllowed) - return - } - if err := h.b.SetDevStateStore(r.FormValue("key"), r.FormValue("value")); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "text/plain") - io.WriteString(w, "done\n") -} - -func (h *Handler) serveDebugPacketFilterRules(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - nm := h.b.NetMap() - if nm == nil { - http.Error(w, "no netmap", http.StatusNotFound) - return - } - w.Header().Set("Content-Type", "application/json") - - enc := json.NewEncoder(w) - enc.SetIndent("", "\t") - enc.Encode(nm.PacketFilterRules) -} - -func (h *Handler) serveDebugPacketFilterMatches(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - nm := h.b.NetMap() - if nm == nil { - http.Error(w, "no netmap", http.StatusNotFound) - return - } - w.Header().Set("Content-Type", "application/json") - - enc := json.NewEncoder(w) - enc.SetIndent("", "\t") - enc.Encode(nm.PacketFilter) -} - -func (h *Handler) serveDebugPortmap(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - w.Header().Set("Content-Type", "text/plain") - - dur, err := time.ParseDuration(r.FormValue("duration")) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - gwSelf := r.FormValue("gateway_and_self") - - // Update portmapper debug flags - debugKnobs := &portmapper.DebugKnobs{VerboseLogs: true} - switch r.FormValue("type") { - case "": - case "pmp": - debugKnobs.DisablePCP = true - debugKnobs.DisableUPnP = true - case "pcp": - debugKnobs.DisablePMP = true - debugKnobs.DisableUPnP = true - case "upnp": - debugKnobs.DisablePCP = true - debugKnobs.DisablePMP = true - default: - http.Error(w, "unknown portmap debug type", http.StatusBadRequest) - return - } - - if defBool(r.FormValue("log_http"), false) { - debugKnobs.LogHTTP = true - } - - var ( - logLock sync.Mutex - handlerDone bool - ) - logf := func(format string, args ...any) { - if !strings.HasSuffix(format, "\n") { - format = format + "\n" - } - - logLock.Lock() - defer logLock.Unlock() - - // The portmapper can call this log function after the HTTP - // handler returns, which is not allowed and can cause a panic. - // If this happens, ignore the log lines since this typically - // occurs due to a client disconnect. - if handlerDone { - return - } - - // Write and flush each line to the client so that output is streamed - fmt.Fprintf(w, format, args...) - if f, ok := w.(http.Flusher); ok { - f.Flush() - } - } - defer func() { - logLock.Lock() - handlerDone = true - logLock.Unlock() - }() - - ctx, cancel := context.WithTimeout(r.Context(), dur) - defer cancel() - - done := make(chan bool, 1) - - var c *portmapper.Client - c = portmapper.NewClient(logger.WithPrefix(logf, "portmapper: "), h.b.NetMon(), debugKnobs, h.b.ControlKnobs(), func() { - logf("portmapping changed.") - logf("have mapping: %v", c.HaveMapping()) - - if ext, ok := c.GetCachedMappingOrStartCreatingOne(); ok { - logf("cb: mapping: %v", ext) - select { - case done <- true: - default: - } - return - } - logf("cb: no mapping") - }) - defer c.Close() - - netMon, err := netmon.New(logger.WithPrefix(logf, "monitor: ")) - if err != nil { - logf("error creating monitor: %v", err) - return - } - - gatewayAndSelfIP := func() (gw, self netip.Addr, ok bool) { - if a, b, ok := strings.Cut(gwSelf, "/"); ok { - gw = netip.MustParseAddr(a) - self = netip.MustParseAddr(b) - return gw, self, true - } - return netMon.GatewayAndSelfIP() - } - - c.SetGatewayLookupFunc(gatewayAndSelfIP) - - gw, selfIP, ok := gatewayAndSelfIP() - if !ok { - logf("no gateway or self IP; %v", netMon.InterfaceState()) - return - } - logf("gw=%v; self=%v", gw, selfIP) - - uc, err := net.ListenPacket("udp", "0.0.0.0:0") - if err != nil { - return - } - defer uc.Close() - c.SetLocalPort(uint16(uc.LocalAddr().(*net.UDPAddr).Port)) - - res, err := c.Probe(ctx) - if err != nil { - logf("error in Probe: %v", err) - return - } - logf("Probe: %+v", res) - - if !res.PCP && !res.PMP && !res.UPnP { - logf("no portmapping services available") - return - } - - if ext, ok := c.GetCachedMappingOrStartCreatingOne(); ok { - logf("mapping: %v", ext) - } else { - logf("no mapping") - } - - select { - case <-done: - case <-ctx.Done(): - if r.Context().Err() == nil { - logf("serveDebugPortmap: context done: %v", ctx.Err()) - } else { - h.logf("serveDebugPortmap: context done: %v", ctx.Err()) - } - } -} - -func (h *Handler) serveComponentDebugLogging(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug access denied", http.StatusForbidden) - return - } - component := r.FormValue("component") - secs, _ := strconv.Atoi(r.FormValue("secs")) - err := h.b.SetComponentDebugLogging(component, h.clock.Now().Add(time.Duration(secs)*time.Second)) - var res struct { - Error string - } - if err != nil { - res.Error = err.Error() - } - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(res) -} - -func (h *Handler) serveDebugDialTypes(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "debug-dial-types access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) - return - } - - ip := r.FormValue("ip") - port := r.FormValue("port") - network := r.FormValue("network") - - addr := ip + ":" + port - if _, err := netip.ParseAddrPort(addr); err != nil { - w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, "invalid address %q: %v", addr, err) - return - } - - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) - defer cancel() - - var bareDialer net.Dialer - - dialer := h.b.Dialer() - - var peerDialer net.Dialer - peerDialer.Control = dialer.PeerDialControlFunc() - - // Kick off a dial with each available dialer in parallel. - dialers := []struct { - name string - dial func(context.Context, string, string) (net.Conn, error) - }{ - {"SystemDial", dialer.SystemDial}, - {"UserDial", dialer.UserDial}, - {"PeerDial", peerDialer.DialContext}, - {"BareDial", bareDialer.DialContext}, - } - type result struct { - name string - conn net.Conn - err error - } - results := make(chan result, len(dialers)) - - var wg sync.WaitGroup - for _, dialer := range dialers { - dialer := dialer // loop capture - - wg.Add(1) - go func() { - defer wg.Done() - conn, err := dialer.dial(ctx, network, addr) - results <- result{dialer.name, conn, err} - }() - } - - wg.Wait() - for range len(dialers) { - res := <-results - fmt.Fprintf(w, "[%s] connected=%v err=%v\n", res.name, res.conn != nil, res.err) - if res.conn != nil { - res.conn.Close() - } - } -} - // servePprofFunc is the implementation of Handler.servePprof, after auth, // for platforms where we want to link it in. var servePprofFunc func(http.ResponseWriter, *http.Request) @@ -1002,7 +694,7 @@ func (h *Handler) servePprof(w http.ResponseWriter, r *http.Request) { // disconnectControl is the handler for local API /disconnect-control endpoint that shuts down control client, so that // node no longer communicates with control. Doing this makes control consider this node inactive. This can be used -// before shutting down a replica of HA subnet router or app connector deployments to ensure that control tells the +// before shutting down a replica of HA subnet router or app connector deployments to ensure that control tells the // peers to switch over to another replica whilst still maintaining th existing peer connections. func (h *Handler) disconnectControl(w http.ResponseWriter, r *http.Request) { if !h.PermitWrite { @@ -1053,90 +745,6 @@ func (h *Handler) serveResetAuth(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) } -func (h *Handler) serveServeConfig(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case "GET": - if !h.PermitRead { - http.Error(w, "serve config denied", http.StatusForbidden) - return - } - config := h.b.ServeConfig() - bts, err := json.Marshal(config) - if err != nil { - http.Error(w, "error encoding config: "+err.Error(), http.StatusInternalServerError) - return - } - sum := sha256.Sum256(bts) - etag := hex.EncodeToString(sum[:]) - w.Header().Set("Etag", etag) - w.Header().Set("Content-Type", "application/json") - w.Write(bts) - case "POST": - if !h.PermitWrite { - http.Error(w, "serve config denied", http.StatusForbidden) - return - } - configIn := new(ipn.ServeConfig) - if err := json.NewDecoder(r.Body).Decode(configIn); err != nil { - writeErrorJSON(w, fmt.Errorf("decoding config: %w", err)) - return - } - - // require a local admin when setting a path handler - // TODO: roll-up this Windows-specific check into either PermitWrite - // or a global admin escalation check. - if err := authorizeServeConfigForGOOSAndUserContext(runtime.GOOS, configIn, h); err != nil { - http.Error(w, err.Error(), http.StatusUnauthorized) - return - } - - etag := r.Header.Get("If-Match") - if err := h.b.SetServeConfig(configIn, etag); err != nil { - if errors.Is(err, ipnlocal.ErrETagMismatch) { - http.Error(w, err.Error(), http.StatusPreconditionFailed) - return - } - writeErrorJSON(w, fmt.Errorf("updating config: %w", err)) - return - } - w.WriteHeader(http.StatusOK) - default: - http.Error(w, "method not allowed", http.StatusMethodNotAllowed) - } -} - -func authorizeServeConfigForGOOSAndUserContext(goos string, configIn *ipn.ServeConfig, h *Handler) error { - switch goos { - case "windows", "linux", "darwin", "illumos", "solaris": - default: - return nil - } - // Only check for local admin on tailscaled-on-mac (based on "sudo" - // permissions). On sandboxed variants (MacSys and AppStore), tailscaled - // cannot serve files outside of the sandbox and this check is not - // relevant. - if goos == "darwin" && version.IsSandboxedMacOS() { - return nil - } - if !configIn.HasPathHandler() { - return nil - } - if h.Actor.IsLocalAdmin(h.b.OperatorUserID()) { - return nil - } - switch goos { - case "windows": - return errors.New("must be a Windows local admin to serve a path") - case "linux", "darwin", "illumos", "solaris": - return errors.New("must be root, or be an operator and able to run 'sudo tailscale' to serve a path") - default: - // We filter goos at the start of the func, this default case - // should never happen. - panic("unreachable") - } - -} - func (h *Handler) serveCheckIPForwarding(w http.ResponseWriter, r *http.Request) { if !h.PermitRead { http.Error(w, "IP forwarding check access denied", http.StatusForbidden) @@ -1154,6 +762,49 @@ func (h *Handler) serveCheckIPForwarding(w http.ResponseWriter, r *http.Request) }) } +// serveCheckSOMarkInUse reports whether SO_MARK is in use on the linux while +// running without TUN. For any other OS, it reports false. +func (h *Handler) serveCheckSOMarkInUse(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "SO_MARK check access denied", http.StatusForbidden) + return + } + usingSOMark := netns.UseSocketMark() + usingUserspaceNetworking := h.b.Sys().IsNetstack() + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(struct { + UseSOMark bool + }{ + UseSOMark: usingSOMark || usingUserspaceNetworking, + }) +} + +func (h *Handler) serveCheckReversePathFiltering(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "reverse path filtering check access denied", http.StatusForbidden) + return + } + var warning string + + state := h.b.Sys().NetMon.Get().InterfaceState() + warn, err := netutil.CheckReversePathFiltering(state) + if err == nil && len(warn) > 0 { + var msg strings.Builder + msg.WriteString(healthmsg.WarnExitNodeUsage + ":\n") + for _, w := range warn { + msg.WriteString("- " + w + "\n") + } + msg.WriteString(healthmsg.DisableRPFilter) + warning = msg.String() + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(struct { + Warning string + }{ + Warning: warning, + }) +} + func (h *Handler) serveCheckUDPGROForwarding(w http.ResponseWriter, r *http.Request) { if !h.PermitRead { http.Error(w, "UDP GRO forwarding check access denied", http.StatusForbidden) @@ -1172,6 +823,10 @@ func (h *Handler) serveCheckUDPGROForwarding(w http.ResponseWriter, r *http.Requ } func (h *Handler) serveSetUDPGROForwarding(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasGRO { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } if !h.PermitWrite { http.Error(w, "UDP GRO forwarding set access denied", http.StatusForbidden) return @@ -1205,34 +860,6 @@ func (h *Handler) serveStatus(w http.ResponseWriter, r *http.Request) { e.Encode(st) } -func (h *Handler) serveDebugPeerEndpointChanges(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "status access denied", http.StatusForbidden) - return - } - - ipStr := r.FormValue("ip") - if ipStr == "" { - http.Error(w, "missing 'ip' parameter", http.StatusBadRequest) - return - } - ip, err := netip.ParseAddr(ipStr) - if err != nil { - http.Error(w, "invalid IP", http.StatusBadRequest) - return - } - w.Header().Set("Content-Type", "application/json") - chs, err := h.b.GetPeerEndpointChanges(r.Context(), ip) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - e := json.NewEncoder(w) - e.SetIndent("", "\t") - e.Encode(chs) -} - // InUseOtherUserIPNStream reports whether r is a request for the watch-ipn-bus // handler. If so, it writes an ipn.Notify InUseOtherUser message to the user // and returns true. Otherwise it returns false, in which case it doesn't write @@ -1242,7 +869,7 @@ func (h *Handler) serveDebugPeerEndpointChanges(w http.ResponseWriter, r *http.R // (in ipnserver.Server) provides the blocking until the connection is no longer // in use. func InUseOtherUserIPNStream(w http.ResponseWriter, r *http.Request, err error) (handled bool) { - if r.Method != "GET" || r.URL.Path != "/localapi/v0/watch-ipn-bus" { + if r.Method != httpm.GET || r.URL.Path != "/localapi/v0/watch-ipn-bus" { return false } js, err := json.Marshal(&ipn.Notify{ @@ -1279,14 +906,6 @@ func (h *Handler) serveWatchIPNBus(w http.ResponseWriter, r *http.Request) { } mask = ipn.NotifyWatchOpt(v) } - // Users with only read access must request private key filtering. If they - // don't filter out private keys, require write access. - if (mask & ipn.NotifyNoPrivateKeys) == 0 { - if !h.PermitWrite { - http.Error(w, "watch IPN bus access denied, must set ipn.NotifyNoPrivateKeys when not running as admin/root or operator", http.StatusForbidden) - return - } - } w.Header().Set("Content-Type", "application/json") ctx := r.Context() @@ -1307,11 +926,14 @@ func (h *Handler) serveLoginInteractive(w http.ResponseWriter, r *http.Request) http.Error(w, "login access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "want POST", http.StatusBadRequest) return } - h.b.StartLoginInteractiveAs(r.Context(), h.Actor) + if err := h.b.StartLoginInteractiveAs(r.Context(), h.Actor); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } w.WriteHeader(http.StatusNoContent) return } @@ -1321,7 +943,7 @@ func (h *Handler) serveStart(w http.ResponseWriter, r *http.Request) { http.Error(w, "access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "want POST", http.StatusBadRequest) return } @@ -1330,6 +952,11 @@ func (h *Handler) serveStart(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } + + if h.b.HealthTracker().IsUnhealthy(ipn.StateStoreHealth) { + http.Error(w, "cannot start backend when state store is unhealthy", http.StatusInternalServerError) + return + } err := h.b.Start(o) if err != nil { // TODO(bradfitz): map error to a good HTTP error @@ -1344,11 +971,11 @@ func (h *Handler) serveLogout(w http.ResponseWriter, r *http.Request) { http.Error(w, "logout access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "want POST", http.StatusBadRequest) return } - err := h.b.Logout(r.Context()) + err := h.b.Logout(r.Context(), h.Actor) if err == nil { w.WriteHeader(http.StatusNoContent) return @@ -1363,7 +990,7 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { } var prefs ipn.PrefsView switch r.Method { - case "PATCH": + case httpm.PATCH: if !h.PermitWrite { http.Error(w, "prefs write access denied", http.StatusForbidden) return @@ -1373,11 +1000,13 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - if err := h.b.MaybeClearAppConnector(mp); err != nil { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusInternalServerError) - json.NewEncoder(w).Encode(resJSON{Error: err.Error()}) - return + if buildfeatures.HasAppConnectors { + if err := h.b.MaybeClearAppConnector(mp); err != nil { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(resJSON{Error: err.Error()}) + return + } } var err error prefs, err = h.b.EditPrefsAs(mp, h.Actor) @@ -1387,7 +1016,7 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(resJSON{Error: err.Error()}) return } - case "GET", "HEAD": + case httpm.GET, httpm.HEAD: prefs = h.b.Prefs() default: http.Error(w, "unsupported method", http.StatusMethodNotAllowed) @@ -1399,53 +1028,6 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { e.Encode(prefs) } -func (h *Handler) servePolicy(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "policy access denied", http.StatusForbidden) - return - } - - suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/policy/") - if !ok { - http.Error(w, "misconfigured", http.StatusInternalServerError) - return - } - - var scope setting.PolicyScope - if suffix == "" { - scope = setting.DefaultScope() - } else if err := scope.UnmarshalText([]byte(suffix)); err != nil { - http.Error(w, fmt.Sprintf("%q is not a valid scope", suffix), http.StatusBadRequest) - return - } - - policy, err := rsop.PolicyFor(scope) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - var effectivePolicy *setting.Snapshot - switch r.Method { - case "GET": - effectivePolicy = policy.Get() - case "POST": - effectivePolicy, err = policy.Reload() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - default: - http.Error(w, "unsupported method", http.StatusMethodNotAllowed) - return - } - - w.Header().Set("Content-Type", "application/json") - e := json.NewEncoder(w) - e.SetIndent("", "\t") - e.Encode(effectivePolicy) -} - type resJSON struct { Error string `json:",omitempty"` } @@ -1455,7 +1037,7 @@ func (h *Handler) serveCheckPrefs(w http.ResponseWriter, r *http.Request) { http.Error(w, "checkprefs access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "unsupported method", http.StatusMethodNotAllowed) return } @@ -1473,67 +1055,10 @@ func (h *Handler) serveCheckPrefs(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(res) } -func (h *Handler) serveFiles(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "file access denied", http.StatusForbidden) - return - } - suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/files/") - if !ok { - http.Error(w, "misconfigured", http.StatusInternalServerError) - return - } - if suffix == "" { - if r.Method != "GET" { - http.Error(w, "want GET to list files", http.StatusBadRequest) - return - } - ctx := r.Context() - if s := r.FormValue("waitsec"); s != "" && s != "0" { - d, err := strconv.Atoi(s) - if err != nil { - http.Error(w, "invalid waitsec", http.StatusBadRequest) - return - } - deadline := time.Now().Add(time.Duration(d) * time.Second) - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, deadline) - defer cancel() - } - wfs, err := h.b.AwaitWaitingFiles(ctx) - if err != nil && ctx.Err() == nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(wfs) - return - } - name, err := url.PathUnescape(suffix) - if err != nil { - http.Error(w, "bad filename", http.StatusBadRequest) - return - } - if r.Method == "DELETE" { - if err := h.b.DeleteFile(name); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusNoContent) - return - } - rc, size, err := h.b.OpenFile(name) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer rc.Close() - w.Header().Set("Content-Length", fmt.Sprint(size)) - w.Header().Set("Content-Type", "application/octet-stream") - io.Copy(w, rc) -} - -func writeErrorJSON(w http.ResponseWriter, err error) { +// WriteErrorJSON writes a JSON object (with a single "error" string field) to w +// with the given error. If err is nil, "unexpected nil error" is used for the +// stringification instead. +func WriteErrorJSON(w http.ResponseWriter, err error) { if err == nil { err = errors.New("unexpected nil error") } @@ -1545,342 +1070,19 @@ func writeErrorJSON(w http.ResponseWriter, err error) { json.NewEncoder(w).Encode(E{err.Error()}) } -func (h *Handler) serveFileTargets(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "access denied", http.StatusForbidden) - return - } - if r.Method != "GET" { - http.Error(w, "want GET to list targets", http.StatusBadRequest) - return - } - fts, err := h.b.FileTargets() - if err != nil { - writeErrorJSON(w, err) - return - } - mak.NonNilSliceForJSON(&fts) - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(fts) -} - -// serveFilePut sends a file to another node. -// -// It's sometimes possible for clients to do this themselves, without -// tailscaled, except in the case of tailscaled running in -// userspace-networking ("netstack") mode, in which case tailscaled -// needs to a do a netstack dial out. -// -// Instead, the CLI also goes through tailscaled so it doesn't need to be -// aware of the network mode in use. -// -// macOS/iOS have always used this localapi method to simplify the GUI -// clients. -// -// The Windows client currently (2021-11-30) uses the peerapi (/v0/put/) -// directly, as the Windows GUI always runs in tun mode anyway. -// -// In addition to single file PUTs, this endpoint accepts multipart file -// POSTS encoded as multipart/form-data.The first part should be an -// application/json file that contains a manifest consisting of a JSON array of -// OutgoingFiles which wecan use for tracking progress even before reading the -// file parts. -// -// URL format: -// -// - PUT /localapi/v0/file-put/:stableID/:escaped-filename -// - POST /localapi/v0/file-put/:stableID -func (h *Handler) serveFilePut(w http.ResponseWriter, r *http.Request) { - metricFilePutCalls.Add(1) - - if !h.PermitWrite { - http.Error(w, "file access denied", http.StatusForbidden) - return - } - - if r.Method != "PUT" && r.Method != "POST" { - http.Error(w, "want PUT to put file", http.StatusBadRequest) - return - } - - fts, err := h.b.FileTargets() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - upath, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/file-put/") - if !ok { - http.Error(w, "misconfigured", http.StatusInternalServerError) - return - } - var peerIDStr, filenameEscaped string - if r.Method == "PUT" { - ok := false - peerIDStr, filenameEscaped, ok = strings.Cut(upath, "/") - if !ok { - http.Error(w, "bogus URL", http.StatusBadRequest) - return - } - } else { - peerIDStr = upath - } - peerID := tailcfg.StableNodeID(peerIDStr) - - var ft *apitype.FileTarget - for _, x := range fts { - if x.Node.StableID == peerID { - ft = x - break - } - } - if ft == nil { - http.Error(w, "node not found", http.StatusNotFound) - return - } - dstURL, err := url.Parse(ft.PeerAPIURL) - if err != nil { - http.Error(w, "bogus peer URL", http.StatusInternalServerError) - return - } - - // Periodically report progress of outgoing files. - outgoingFiles := make(map[string]*ipn.OutgoingFile) - t := time.NewTicker(1 * time.Second) - progressUpdates := make(chan ipn.OutgoingFile) - defer close(progressUpdates) - - go func() { - defer t.Stop() - defer h.b.UpdateOutgoingFiles(outgoingFiles) - for { - select { - case u, ok := <-progressUpdates: - if !ok { - return - } - outgoingFiles[u.ID] = &u - case <-t.C: - h.b.UpdateOutgoingFiles(outgoingFiles) - } - } - }() - - switch r.Method { - case "PUT": - file := ipn.OutgoingFile{ - ID: rands.HexString(30), - PeerID: peerID, - Name: filenameEscaped, - DeclaredSize: r.ContentLength, - } - h.singleFilePut(r.Context(), progressUpdates, w, r.Body, dstURL, file) - case "POST": - h.multiFilePost(progressUpdates, w, r, peerID, dstURL) - default: - http.Error(w, "want PUT to put file", http.StatusBadRequest) - return - } -} - -func (h *Handler) multiFilePost(progressUpdates chan (ipn.OutgoingFile), w http.ResponseWriter, r *http.Request, peerID tailcfg.StableNodeID, dstURL *url.URL) { - _, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - if err != nil { - http.Error(w, fmt.Sprintf("invalid Content-Type for multipart POST: %s", err), http.StatusBadRequest) - return - } - - ww := &multiFilePostResponseWriter{} - defer func() { - if err := ww.Flush(w); err != nil { - h.logf("error: multiFilePostResponseWriter.Flush(): %s", err) - } - }() - - outgoingFilesByName := make(map[string]ipn.OutgoingFile) - first := true - mr := multipart.NewReader(r.Body, params["boundary"]) - for { - part, err := mr.NextPart() - if err == io.EOF { - // No more parts. - return - } else if err != nil { - http.Error(ww, fmt.Sprintf("failed to decode multipart/form-data: %s", err), http.StatusBadRequest) - return - } - - if first { - first = false - if part.Header.Get("Content-Type") != "application/json" { - http.Error(ww, "first MIME part must be a JSON map of filename -> size", http.StatusBadRequest) - return - } - - var manifest []ipn.OutgoingFile - err := json.NewDecoder(part).Decode(&manifest) - if err != nil { - http.Error(ww, fmt.Sprintf("invalid manifest: %s", err), http.StatusBadRequest) - return - } - - for _, file := range manifest { - outgoingFilesByName[file.Name] = file - progressUpdates <- file - } - - continue - } - - if !h.singleFilePut(r.Context(), progressUpdates, ww, part, dstURL, outgoingFilesByName[part.FileName()]) { - return - } - - if ww.statusCode >= 400 { - // put failed, stop immediately - h.logf("error: singleFilePut: failed with status %d", ww.statusCode) - return - } - } -} - -// multiFilePostResponseWriter is a buffering http.ResponseWriter that can be -// reused across multiple singleFilePut calls and then flushed to the client -// when all files have been PUT. -type multiFilePostResponseWriter struct { - header http.Header - statusCode int - body *bytes.Buffer -} - -func (ww *multiFilePostResponseWriter) Header() http.Header { - if ww.header == nil { - ww.header = make(http.Header) - } - return ww.header -} - -func (ww *multiFilePostResponseWriter) WriteHeader(statusCode int) { - ww.statusCode = statusCode -} - -func (ww *multiFilePostResponseWriter) Write(p []byte) (int, error) { - if ww.body == nil { - ww.body = bytes.NewBuffer(nil) - } - return ww.body.Write(p) -} - -func (ww *multiFilePostResponseWriter) Flush(w http.ResponseWriter) error { - if ww.header != nil { - maps.Copy(w.Header(), ww.header) - } - if ww.statusCode > 0 { - w.WriteHeader(ww.statusCode) - } - if ww.body != nil { - _, err := io.Copy(w, ww.body) - return err - } - return nil -} - -func (h *Handler) singleFilePut( - ctx context.Context, - progressUpdates chan (ipn.OutgoingFile), - w http.ResponseWriter, - body io.Reader, - dstURL *url.URL, - outgoingFile ipn.OutgoingFile, -) bool { - outgoingFile.Started = time.Now() - body = progresstracking.NewReader(body, 1*time.Second, func(n int, err error) { - outgoingFile.Sent = int64(n) - progressUpdates <- outgoingFile - }) - - fail := func() { - outgoingFile.Finished = true - outgoingFile.Succeeded = false - progressUpdates <- outgoingFile - } - - // Before we PUT a file we check to see if there are any existing partial file and if so, - // we resume the upload from where we left off by sending the remaining file instead of - // the full file. - var offset int64 - var resumeDuration time.Duration - remainingBody := io.Reader(body) - client := &http.Client{ - Transport: h.b.Dialer().PeerAPITransport(), - Timeout: 10 * time.Second, - } - req, err := http.NewRequestWithContext(ctx, "GET", dstURL.String()+"/v0/put/"+outgoingFile.Name, nil) - if err != nil { - http.Error(w, "bogus peer URL", http.StatusInternalServerError) - fail() - return false - } - switch resp, err := client.Do(req); { - case err != nil: - h.logf("could not fetch remote hashes: %v", err) - case resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotFound: - // noop; implies older peerapi without resume support - case resp.StatusCode != http.StatusOK: - h.logf("fetch remote hashes status code: %d", resp.StatusCode) - default: - resumeStart := time.Now() - dec := json.NewDecoder(resp.Body) - offset, remainingBody, err = taildrop.ResumeReader(body, func() (out taildrop.BlockChecksum, err error) { - err = dec.Decode(&out) - return out, err - }) - if err != nil { - h.logf("reader could not be fully resumed: %v", err) - } - resumeDuration = time.Since(resumeStart).Round(time.Millisecond) - } - - outReq, err := http.NewRequestWithContext(ctx, "PUT", "http://peer/v0/put/"+outgoingFile.Name, remainingBody) - if err != nil { - http.Error(w, "bogus outreq", http.StatusInternalServerError) - fail() - return false - } - outReq.ContentLength = outgoingFile.DeclaredSize - if offset > 0 { - h.logf("resuming put at offset %d after %v", offset, resumeDuration) - rangeHdr, _ := httphdr.FormatRange([]httphdr.Range{{Start: offset, Length: 0}}) - outReq.Header.Set("Range", rangeHdr) - if outReq.ContentLength >= 0 { - outReq.ContentLength -= offset - } - } - - rp := httputil.NewSingleHostReverseProxy(dstURL) - rp.Transport = h.b.Dialer().PeerAPITransport() - rp.ServeHTTP(w, outReq) - - outgoingFile.Finished = true - outgoingFile.Succeeded = true - progressUpdates <- outgoingFile - - return true -} - func (h *Handler) serveSetDNS(w http.ResponseWriter, r *http.Request) { if !h.PermitWrite { http.Error(w, "access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "want POST", http.StatusBadRequest) return } ctx := r.Context() err := h.b.SetDNS(ctx, r.FormValue("name"), r.FormValue("value")) if err != nil { - writeErrorJSON(w, err) + WriteErrorJSON(w, err) return } w.Header().Set("Content-Type", "application/json") @@ -1888,7 +1090,7 @@ func (h *Handler) serveSetDNS(w http.ResponseWriter, r *http.Request) { } func (h *Handler) serveDERPMap(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { + if r.Method != httpm.GET { http.Error(w, "want GET", http.StatusBadRequest) return } @@ -1905,7 +1107,7 @@ func (h *Handler) serveSetExpirySooner(w http.ResponseWriter, r *http.Request) { http.Error(w, "access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "POST required", http.StatusMethodNotAllowed) return } @@ -1933,7 +1135,7 @@ func (h *Handler) serveSetExpirySooner(w http.ResponseWriter, r *http.Request) { func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "want POST", http.StatusBadRequest) return } @@ -1971,7 +1173,7 @@ func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) { } res, err := h.b.Ping(ctx, ip, tailcfg.PingType(pingTypeStr), size) if err != nil { - writeErrorJSON(w, err) + WriteErrorJSON(w, err) return } w.Header().Set("Content-Type", "application/json") @@ -1979,7 +1181,7 @@ func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) { } func (h *Handler) serveDial(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "POST required", http.StatusMethodNotAllowed) return } @@ -2042,7 +1244,7 @@ func (h *Handler) serveSetPushDeviceToken(w http.ResponseWriter, r *http.Request http.Error(w, "set push device token access denied", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "unsupported method", http.StatusMethodNotAllowed) return } @@ -2060,7 +1262,7 @@ func (h *Handler) serveHandlePushMessage(w http.ResponseWriter, r *http.Request) http.Error(w, "handle push message not allowed", http.StatusForbidden) return } - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "unsupported method", http.StatusMethodNotAllowed) return } @@ -2077,17 +1279,12 @@ func (h *Handler) serveHandlePushMessage(w http.ResponseWriter, r *http.Request) } func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { + if r.Method != httpm.POST { http.Error(w, "unsupported method", http.StatusMethodNotAllowed) return } - type clientMetricJSON struct { - Name string `json:"name"` - Type string `json:"type"` // one of "counter" or "gauge" - Value int `json:"value"` // amount to increment metric by - } - var clientMetrics []clientMetricJSON + var clientMetrics []clientmetric.MetricUpdate if err := json.NewDecoder(r.Body).Decode(&clientMetrics); err != nil { http.Error(w, "invalid JSON body", http.StatusBadRequest) return @@ -2097,14 +1294,12 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques defer metricsMu.Unlock() for _, m := range clientMetrics { - if metric, ok := metrics[m.Name]; ok { - metric.Add(int64(m.Value)) - } else { + metric, ok := metrics[m.Name] + if !ok { if clientmetric.HasPublished(m.Name) { http.Error(w, "Already have a metric named "+m.Name, http.StatusBadRequest) return } - var metric *clientmetric.Metric switch m.Type { case "counter": metric = clientmetric.NewCounter(m.Name) @@ -2115,7 +1310,15 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques return } metrics[m.Name] = metric + } + switch m.Op { + case "add", "": metric.Add(int64(m.Value)) + case "set": + metric.Set(int64(m.Value)) + default: + http.Error(w, "Unknown metric op "+m.Op, http.StatusBadRequest) + return } } @@ -2123,25 +1326,6 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques json.NewEncoder(w).Encode(struct{}{}) } -func (h *Handler) serveTKAStatus(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "lock status access denied", http.StatusForbidden) - return - } - if r.Method != httpm.GET { - http.Error(w, "use GET", http.StatusMethodNotAllowed) - return - } - - j, err := json.MarshalIndent(h.b.NetworkLockStatus(), "", "\t") - if err != nil { - http.Error(w, "JSON encoding error", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(j) -} - func (h *Handler) serveSetGUIVisible(w http.ResponseWriter, r *http.Request) { if r.Method != httpm.POST { http.Error(w, "use POST", http.StatusMethodNotAllowed) @@ -2164,6 +1348,10 @@ func (h *Handler) serveSetGUIVisible(w http.ResponseWriter, r *http.Request) { } func (h *Handler) serveSetUseExitNodeEnabled(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasUseExitNode { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } if r.Method != httpm.POST { http.Error(w, "use POST", http.StatusMethodNotAllowed) return @@ -2178,7 +1366,7 @@ func (h *Handler) serveSetUseExitNodeEnabled(w http.ResponseWriter, r *http.Requ http.Error(w, "invalid 'enabled' parameter", http.StatusBadRequest) return } - prefs, err := h.b.SetUseExitNodeEnabled(v) + prefs, err := h.b.SetUseExitNodeEnabled(h.Actor, v) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -2189,361 +1377,6 @@ func (h *Handler) serveSetUseExitNodeEnabled(w http.ResponseWriter, r *http.Requ e.Encode(prefs) } -func (h *Handler) serveTKASign(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "lock sign access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type signRequest struct { - NodeKey key.NodePublic - RotationPublic []byte - } - var req signRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockSign(req.NodeKey, req.RotationPublic); err != nil { - http.Error(w, "signing failed: "+err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusOK) -} - -func (h *Handler) serveTKAInit(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "lock init access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type initRequest struct { - Keys []tka.Key - DisablementValues [][]byte - SupportDisablement []byte - } - var req initRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockInit(req.Keys, req.DisablementValues, req.SupportDisablement); err != nil { - http.Error(w, "initialization failed: "+err.Error(), http.StatusInternalServerError) - return - } - - j, err := json.MarshalIndent(h.b.NetworkLockStatus(), "", "\t") - if err != nil { - http.Error(w, "JSON encoding error", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(j) -} - -func (h *Handler) serveTKAModify(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "network-lock modify access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type modifyRequest struct { - AddKeys []tka.Key - RemoveKeys []tka.Key - } - var req modifyRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockModify(req.AddKeys, req.RemoveKeys); err != nil { - http.Error(w, "network-lock modify failed: "+err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(204) -} - -func (h *Handler) serveTKAWrapPreauthKey(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "network-lock modify access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type wrapRequest struct { - TSKey string - TKAKey string // key.NLPrivate.MarshalText - } - var req wrapRequest - if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 12*1024)).Decode(&req); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - var priv key.NLPrivate - if err := priv.UnmarshalText([]byte(req.TKAKey)); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - wrappedKey, err := h.b.NetworkLockWrapPreauthKey(req.TSKey, priv) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusOK) - w.Write([]byte(wrappedKey)) -} - -func (h *Handler) serveTKAVerifySigningDeeplink(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "signing deeplink verification access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type verifyRequest struct { - URL string - } - var req verifyRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON for verifyRequest body", http.StatusBadRequest) - return - } - - res := h.b.NetworkLockVerifySigningDeeplink(req.URL) - j, err := json.MarshalIndent(res, "", "\t") - if err != nil { - http.Error(w, "JSON encoding error", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(j) -} - -func (h *Handler) serveTKADisable(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "network-lock modify access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - body := io.LimitReader(r.Body, 1024*1024) - secret, err := io.ReadAll(body) - if err != nil { - http.Error(w, "reading secret", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockDisable(secret); err != nil { - http.Error(w, "network-lock disable failed: "+err.Error(), http.StatusBadRequest) - return - } - w.WriteHeader(http.StatusOK) -} - -func (h *Handler) serveTKALocalDisable(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "network-lock modify access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - // Require a JSON stanza for the body as an additional CSRF protection. - var req struct{} - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockForceLocalDisable(); err != nil { - http.Error(w, "network-lock local disable failed: "+err.Error(), http.StatusBadRequest) - return - } - w.WriteHeader(http.StatusOK) -} - -func (h *Handler) serveTKALog(w http.ResponseWriter, r *http.Request) { - if r.Method != httpm.GET { - http.Error(w, "use GET", http.StatusMethodNotAllowed) - return - } - - limit := 50 - if limitStr := r.FormValue("limit"); limitStr != "" { - l, err := strconv.Atoi(limitStr) - if err != nil { - http.Error(w, "parsing 'limit' parameter: "+err.Error(), http.StatusBadRequest) - return - } - limit = int(l) - } - - updates, err := h.b.NetworkLockLog(limit) - if err != nil { - http.Error(w, "reading log failed: "+err.Error(), http.StatusInternalServerError) - return - } - - j, err := json.MarshalIndent(updates, "", "\t") - if err != nil { - http.Error(w, "JSON encoding error", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(j) -} - -func (h *Handler) serveTKAAffectedSigs(w http.ResponseWriter, r *http.Request) { - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - keyID, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 2048)) - if err != nil { - http.Error(w, "reading body", http.StatusBadRequest) - return - } - - sigs, err := h.b.NetworkLockAffectedSigs(keyID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - j, err := json.MarshalIndent(sigs, "", "\t") - if err != nil { - http.Error(w, "JSON encoding error", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(j) -} - -func (h *Handler) serveTKAGenerateRecoveryAUM(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - type verifyRequest struct { - Keys []tkatype.KeyID - ForkFrom string - } - var req verifyRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - http.Error(w, "invalid JSON for verifyRequest body", http.StatusBadRequest) - return - } - - var forkFrom tka.AUMHash - if req.ForkFrom != "" { - if err := forkFrom.UnmarshalText([]byte(req.ForkFrom)); err != nil { - http.Error(w, "decoding fork-from: "+err.Error(), http.StatusBadRequest) - return - } - } - - res, err := h.b.NetworkLockGenerateRecoveryAUM(req.Keys, forkFrom) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/octet-stream") - w.Write(res.Serialize()) -} - -func (h *Handler) serveTKACosignRecoveryAUM(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - body := io.LimitReader(r.Body, 1024*1024) - aumBytes, err := io.ReadAll(body) - if err != nil { - http.Error(w, "reading AUM", http.StatusBadRequest) - return - } - var aum tka.AUM - if err := aum.Unserialize(aumBytes); err != nil { - http.Error(w, "decoding AUM", http.StatusBadRequest) - return - } - - res, err := h.b.NetworkLockCosignRecoveryAUM(&aum) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/octet-stream") - w.Write(res.Serialize()) -} - -func (h *Handler) serveTKASubmitRecoveryAUM(w http.ResponseWriter, r *http.Request) { - if !h.PermitWrite { - http.Error(w, "access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "use POST", http.StatusMethodNotAllowed) - return - } - - body := io.LimitReader(r.Body, 1024*1024) - aumBytes, err := io.ReadAll(body) - if err != nil { - http.Error(w, "reading AUM", http.StatusBadRequest) - return - } - var aum tka.AUM - if err := aum.Unserialize(aumBytes); err != nil { - http.Error(w, "decoding AUM", http.StatusBadRequest) - return - } - - if err := h.b.NetworkLockSubmitRecoveryAUM(&aum); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusOK) -} - // serveProfiles serves profile switching-related endpoints. Supported methods // and paths are: // - GET /profiles/: list all profiles (JSON-encoded array of ipn.LoginProfiles) @@ -2668,7 +1501,7 @@ func (h *Handler) serveQueryFeature(w http.ResponseWriter, r *http.Request) { } req, err := http.NewRequestWithContext(r.Context(), - "POST", "https://unused/machine/feature/query", bytes.NewReader(b)) + httpm.POST, "https://unused/machine/feature/query", bytes.NewReader(b)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -2699,47 +1532,6 @@ func defBool(a string, def bool) bool { return v } -func (h *Handler) serveDebugLog(w http.ResponseWriter, r *http.Request) { - if !h.PermitRead { - http.Error(w, "debug-log access denied", http.StatusForbidden) - return - } - if r.Method != httpm.POST { - http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) - return - } - defer h.b.TryFlushLogs() // kick off upload after we're done logging - - type logRequestJSON struct { - Lines []string - Prefix string - } - - var logRequest logRequestJSON - if err := json.NewDecoder(r.Body).Decode(&logRequest); err != nil { - http.Error(w, "invalid JSON body", http.StatusBadRequest) - return - } - - prefix := logRequest.Prefix - if prefix == "" { - prefix = "debug-log" - } - logf := logger.WithPrefix(h.logf, prefix+": ") - - // We can write logs too fast for logtail to handle, even when - // opting-out of rate limits. Limit ourselves to at most one message - // per 20ms and a burst of 60 log lines, which should be fast enough to - // not block for too long but slow enough that we can upload all lines. - logf = logger.SlowLoggerWithClock(r.Context(), logf, 20*time.Millisecond, 60, h.clock.Now) - - for _, line := range logRequest.Lines { - logf("%s", line) - } - - w.WriteHeader(http.StatusNoContent) -} - // serveUpdateCheck returns the ClientVersion from Status, which contains // information on whether an update is available, and if so, what version, // *if* we support auto-updates on this platform. If we don't, this endpoint @@ -2747,17 +1539,10 @@ func (h *Handler) serveDebugLog(w http.ResponseWriter, r *http.Request) { // Effectively, it tells us whether serveUpdateInstall will be able to install // an update for us. func (h *Handler) serveUpdateCheck(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { + if r.Method != httpm.GET { http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) return } - - if !clientupdate.CanAutoUpdate() { - // if we don't support auto-update, just say that we're up to date - json.NewEncoder(w).Encode(tailcfg.ClientVersion{RunningLatest: true}) - return - } - cv := h.b.StatusWithoutPeers().ClientVersion // ipnstate.Status documentation notes that ClientVersion may be nil on some // platforms where this information is unavailable. In that case, return a @@ -2770,40 +1555,13 @@ func (h *Handler) serveUpdateCheck(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(cv) } -// serveUpdateInstall sends a request to the LocalBackend to start a Tailscale -// self-update. A successful response does not indicate whether the update -// succeeded, only that the request was accepted. Clients should use -// serveUpdateProgress after pinging this endpoint to check how the update is -// going. -func (h *Handler) serveUpdateInstall(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) - return - } - - w.WriteHeader(http.StatusAccepted) - - go h.b.DoSelfUpdate() -} - -// serveUpdateProgress returns the status of an in-progress Tailscale self-update. -// This is provided as a slice of ipnstate.UpdateProgress structs with various -// log messages in order from oldest to newest. If an update is not in progress, -// the returned slice will be empty. -func (h *Handler) serveUpdateProgress(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) - return - } - - ups := h.b.GetSelfUpdateProgress() - - json.NewEncoder(w).Encode(ups) -} - // serveDNSOSConfig serves the current system DNS configuration as a JSON object, if // supported by the OS. func (h *Handler) serveDNSOSConfig(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDNS { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } if r.Method != httpm.GET { http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) return @@ -2847,7 +1605,11 @@ func (h *Handler) serveDNSOSConfig(w http.ResponseWriter, r *http.Request) { // // The response if successful is a DNSQueryResponse JSON object. func (h *Handler) serveDNSQuery(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { + if !buildfeatures.HasDNS { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + if r.Method != httpm.GET { http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) return } @@ -2861,7 +1623,7 @@ func (h *Handler) serveDNSQuery(w http.ResponseWriter, r *http.Request) { queryType := q.Get("type") qt := dnsmessage.TypeA if queryType != "" { - t, err := dnstype.DNSMessageTypeForString(queryType) + t, err := dnsMessageTypeForString(queryType) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return @@ -2882,144 +1644,115 @@ func (h *Handler) serveDNSQuery(w http.ResponseWriter, r *http.Request) { }) } -// serveDriveServerAddr handles updates of the Taildrive file server address. -func (h *Handler) serveDriveServerAddr(w http.ResponseWriter, r *http.Request) { - if r.Method != "PUT" { - http.Error(w, "only PUT allowed", http.StatusMethodNotAllowed) - return +// dnsMessageTypeForString returns the dnsmessage.Type for the given string. +// For example, DNSMessageTypeForString("A") returns dnsmessage.TypeA. +func dnsMessageTypeForString(s string) (t dnsmessage.Type, err error) { + s = strings.TrimSpace(strings.ToUpper(s)) + switch s { + case "AAAA": + return dnsmessage.TypeAAAA, nil + case "ALL": + return dnsmessage.TypeALL, nil + case "A": + return dnsmessage.TypeA, nil + case "CNAME": + return dnsmessage.TypeCNAME, nil + case "HINFO": + return dnsmessage.TypeHINFO, nil + case "MINFO": + return dnsmessage.TypeMINFO, nil + case "MX": + return dnsmessage.TypeMX, nil + case "NS": + return dnsmessage.TypeNS, nil + case "OPT": + return dnsmessage.TypeOPT, nil + case "PTR": + return dnsmessage.TypePTR, nil + case "SOA": + return dnsmessage.TypeSOA, nil + case "SRV": + return dnsmessage.TypeSRV, nil + case "TXT": + return dnsmessage.TypeTXT, nil + case "WKS": + return dnsmessage.TypeWKS, nil } - - b, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - h.b.DriveSetServerAddr(string(b)) - w.WriteHeader(http.StatusCreated) + return 0, errors.New("unknown DNS message type: " + s) } -// serveShares handles the management of Taildrive shares. -// -// PUT - adds or updates an existing share -// DELETE - removes a share -// GET - gets a list of all shares, sorted by name -// POST - renames an existing share -func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) { - if !h.b.DriveSharingEnabled() { - http.Error(w, `taildrive sharing not enabled, please add the attribute "drive:share" to this node in your ACLs' "nodeAttrs" section`, http.StatusForbidden) - return - } - switch r.Method { - case "PUT": - var share drive.Share - err := json.NewDecoder(r.Body).Decode(&share) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - share.Path = path.Clean(share.Path) - fi, err := os.Stat(share.Path) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - if !fi.IsDir() { - http.Error(w, "not a directory", http.StatusBadRequest) - return - } - if drive.AllowShareAs() { - // share as the connected user - username, err := h.Actor.Username() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - share.As = username - } - err = h.b.DriveSetShare(&share) - if err != nil { - if errors.Is(err, drive.ErrInvalidShareName) { - http.Error(w, "invalid share name", http.StatusBadRequest) - return - } - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusCreated) - case "DELETE": - b, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - err = h.b.DriveRemoveShare(string(b)) - if err != nil { - if os.IsNotExist(err) { - http.Error(w, "share not found", http.StatusNotFound) - return - } - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusNoContent) - case "POST": - var names [2]string - err := json.NewDecoder(r.Body).Decode(&names) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - err = h.b.DriveRenameShare(names[0], names[1]) - if err != nil { - if os.IsNotExist(err) { - http.Error(w, "share not found", http.StatusNotFound) - return - } - if os.IsExist(err) { - http.Error(w, "share name already used", http.StatusBadRequest) - return - } - if errors.Is(err, drive.ErrInvalidShareName) { - http.Error(w, "invalid share name", http.StatusBadRequest) - return - } - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusNoContent) - case "GET": - shares := h.b.DriveGetShares() - err := json.NewEncoder(w).Encode(shares) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - default: - http.Error(w, "unsupported method", http.StatusMethodNotAllowed) - } -} - -var ( - metricInvalidRequests = clientmetric.NewCounter("localapi_invalid_requests") - - // User-visible LocalAPI endpoints. - metricFilePutCalls = clientmetric.NewCounter("localapi_file_put") - metricDebugMetricsCalls = clientmetric.NewCounter("localapi_debugmetric_requests") - metricUserMetricsCalls = clientmetric.NewCounter("localapi_usermetric_requests") -) - // serveSuggestExitNode serves a POST endpoint for returning a suggested exit node. func (h *Handler) serveSuggestExitNode(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { + if !buildfeatures.HasUseExitNode { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + if r.Method != httpm.GET { http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) return } res, err := h.b.SuggestExitNode() if err != nil { - writeErrorJSON(w, err) + WriteErrorJSON(w, err) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(res) } + +// Shutdown is an eventbus value published when tailscaled shutdown +// is requested via LocalAPI. Its only consumer is [ipnserver.Server]. +type Shutdown struct{} + +// serveShutdown shuts down tailscaled. It requires write access +// and the [pkey.AllowTailscaledRestart] policy to be enabled. +// See tailscale/corp#32674. +func (h *Handler) serveShutdown(w http.ResponseWriter, r *http.Request) { + if r.Method != httpm.POST { + http.Error(w, "only POST allowed", http.StatusMethodNotAllowed) + return + } + + if !h.PermitWrite { + http.Error(w, "shutdown access denied", http.StatusForbidden) + return + } + + polc := h.b.Sys().PolicyClientOrDefault() + if permitShutdown, _ := polc.GetBoolean(pkey.AllowTailscaledRestart, false); !permitShutdown { + http.Error(w, "shutdown access denied by policy", http.StatusForbidden) + return + } + + ec := h.eventBus.Client("localapi.Handler") + defer ec.Close() + + w.WriteHeader(http.StatusOK) + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + eventbus.Publish[Shutdown](ec).Publish(Shutdown{}) +} + +func (h *Handler) serveGetAppcRouteInfo(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasAppConnectors { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + if r.Method != httpm.GET { + http.Error(w, "only GET allowed", http.StatusMethodNotAllowed) + return + } + res, err := h.b.ReadRouteInfo() + if err != nil { + if errors.Is(err, ipn.ErrStateNotExist) { + res = &appctype.RouteInfo{} + } else { + WriteErrorJSON(w, err) + return + } + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(res) +} diff --git a/vendor/tailscale.com/ipn/localapi/localapi_drive.go b/vendor/tailscale.com/ipn/localapi/localapi_drive.go new file mode 100644 index 0000000..eb765ec --- /dev/null +++ b/vendor/tailscale.com/ipn/localapi/localapi_drive.go @@ -0,0 +1,141 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_drive + +package localapi + +import ( + "encoding/json" + "errors" + "io" + "net/http" + "os" + "path" + + "tailscale.com/drive" + "tailscale.com/util/httpm" +) + +func init() { + Register("drive/fileserver-address", (*Handler).serveDriveServerAddr) + Register("drive/shares", (*Handler).serveShares) +} + +// serveDriveServerAddr handles updates of the Taildrive file server address. +func (h *Handler) serveDriveServerAddr(w http.ResponseWriter, r *http.Request) { + if r.Method != httpm.PUT { + http.Error(w, "only PUT allowed", http.StatusMethodNotAllowed) + return + } + + b, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + h.b.DriveSetServerAddr(string(b)) + w.WriteHeader(http.StatusCreated) +} + +// serveShares handles the management of Taildrive shares. +// +// PUT - adds or updates an existing share +// DELETE - removes a share +// GET - gets a list of all shares, sorted by name +// POST - renames an existing share +func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) { + if !h.b.DriveSharingEnabled() { + http.Error(w, `taildrive sharing not enabled, please add the attribute "drive:share" to this node in your ACLs' "nodeAttrs" section`, http.StatusForbidden) + return + } + switch r.Method { + case httpm.PUT: + var share drive.Share + err := json.NewDecoder(r.Body).Decode(&share) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + share.Path = path.Clean(share.Path) + fi, err := os.Stat(share.Path) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if !fi.IsDir() { + http.Error(w, "not a directory", http.StatusBadRequest) + return + } + if drive.AllowShareAs() { + // share as the connected user + username, err := h.Actor.Username() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + share.As = username + } + err = h.b.DriveSetShare(&share) + if err != nil { + if errors.Is(err, drive.ErrInvalidShareName) { + http.Error(w, "invalid share name", http.StatusBadRequest) + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusCreated) + case httpm.DELETE: + b, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + err = h.b.DriveRemoveShare(string(b)) + if err != nil { + if os.IsNotExist(err) { + http.Error(w, "share not found", http.StatusNotFound) + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusNoContent) + case httpm.POST: + var names [2]string + err := json.NewDecoder(r.Body).Decode(&names) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + err = h.b.DriveRenameShare(names[0], names[1]) + if err != nil { + if os.IsNotExist(err) { + http.Error(w, "share not found", http.StatusNotFound) + return + } + if os.IsExist(err) { + http.Error(w, "share name already used", http.StatusBadRequest) + return + } + if errors.Is(err, drive.ErrInvalidShareName) { + http.Error(w, "invalid share name", http.StatusBadRequest) + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusNoContent) + case httpm.GET: + shares := h.b.DriveGetShares() + err := json.NewEncoder(w).Encode(shares) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + default: + http.Error(w, "unsupported method", http.StatusMethodNotAllowed) + } +} diff --git a/vendor/tailscale.com/ipn/localapi/pprof.go b/vendor/tailscale.com/ipn/localapi/pprof.go index 8c9429b..9476f72 100644 --- a/vendor/tailscale.com/ipn/localapi/pprof.go +++ b/vendor/tailscale.com/ipn/localapi/pprof.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios && !android && !js +//go:build !ios && !android && !js && !ts_omit_debug // We don't include it on mobile where we're more memory constrained and // there's no CLI to get at the results anyway. diff --git a/vendor/tailscale.com/ipn/localapi/serve.go b/vendor/tailscale.com/ipn/localapi/serve.go new file mode 100644 index 0000000..efbbde0 --- /dev/null +++ b/vendor/tailscale.com/ipn/localapi/serve.go @@ -0,0 +1,108 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_serve + +package localapi + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "runtime" + + "tailscale.com/ipn" + "tailscale.com/ipn/ipnlocal" + "tailscale.com/util/httpm" + "tailscale.com/version" +) + +func init() { + Register("serve-config", (*Handler).serveServeConfig) +} + +func (h *Handler) serveServeConfig(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case httpm.GET: + if !h.PermitRead { + http.Error(w, "serve config denied", http.StatusForbidden) + return + } + config, etag, err := h.b.ServeConfigETag() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + bts, err := json.Marshal(config) + if err != nil { + http.Error(w, "error encoding config: "+err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Etag", etag) + w.Header().Set("Content-Type", "application/json") + w.Write(bts) + case httpm.POST: + if !h.PermitWrite { + http.Error(w, "serve config denied", http.StatusForbidden) + return + } + configIn := new(ipn.ServeConfig) + if err := json.NewDecoder(r.Body).Decode(configIn); err != nil { + WriteErrorJSON(w, fmt.Errorf("decoding config: %w", err)) + return + } + + // require a local admin when setting a path handler + // TODO: roll-up this Windows-specific check into either PermitWrite + // or a global admin escalation check. + if err := authorizeServeConfigForGOOSAndUserContext(runtime.GOOS, configIn, h); err != nil { + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + + etag := r.Header.Get("If-Match") + if err := h.b.SetServeConfig(configIn, etag); err != nil { + if errors.Is(err, ipnlocal.ErrETagMismatch) { + http.Error(w, err.Error(), http.StatusPreconditionFailed) + return + } + WriteErrorJSON(w, fmt.Errorf("updating config: %w", err)) + return + } + w.WriteHeader(http.StatusOK) + default: + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + } +} + +func authorizeServeConfigForGOOSAndUserContext(goos string, configIn *ipn.ServeConfig, h *Handler) error { + switch goos { + case "windows", "linux", "darwin", "illumos", "solaris": + default: + return nil + } + // Only check for local admin on tailscaled-on-mac (based on "sudo" + // permissions). On sandboxed variants (MacSys and AppStore), tailscaled + // cannot serve files outside of the sandbox and this check is not + // relevant. + if goos == "darwin" && version.IsSandboxedMacOS() { + return nil + } + if !configIn.HasPathHandler() { + return nil + } + if h.Actor.IsLocalAdmin(h.b.OperatorUserID()) { + return nil + } + switch goos { + case "windows": + return errors.New("must be a Windows local admin to serve a path") + case "linux", "darwin", "illumos", "solaris": + return errors.New("must be root, or be an operator and able to run 'sudo tailscale' to serve a path") + default: + // We filter goos at the start of the func, this default case + // should never happen. + panic("unreachable") + } +} diff --git a/vendor/tailscale.com/ipn/localapi/syspolicy_api.go b/vendor/tailscale.com/ipn/localapi/syspolicy_api.go new file mode 100644 index 0000000..edb82e0 --- /dev/null +++ b/vendor/tailscale.com/ipn/localapi/syspolicy_api.go @@ -0,0 +1,68 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_syspolicy + +package localapi + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "tailscale.com/util/httpm" + "tailscale.com/util/syspolicy/rsop" + "tailscale.com/util/syspolicy/setting" +) + +func init() { + Register("policy/", (*Handler).servePolicy) +} + +func (h *Handler) servePolicy(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "policy access denied", http.StatusForbidden) + return + } + + suffix, ok := strings.CutPrefix(r.URL.EscapedPath(), "/localapi/v0/policy/") + if !ok { + http.Error(w, "misconfigured", http.StatusInternalServerError) + return + } + + var scope setting.PolicyScope + if suffix == "" { + scope = setting.DefaultScope() + } else if err := scope.UnmarshalText([]byte(suffix)); err != nil { + http.Error(w, fmt.Sprintf("%q is not a valid scope", suffix), http.StatusBadRequest) + return + } + + policy, err := rsop.PolicyFor(scope) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + var effectivePolicy *setting.Snapshot + switch r.Method { + case httpm.GET: + effectivePolicy = policy.Get() + case httpm.POST: + effectivePolicy, err = policy.Reload() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + default: + http.Error(w, "unsupported method", http.StatusMethodNotAllowed) + return + } + + w.Header().Set("Content-Type", "application/json") + e := json.NewEncoder(w) + e.SetIndent("", "\t") + e.Encode(effectivePolicy) +} diff --git a/vendor/tailscale.com/ipn/localapi/tailnetlock.go b/vendor/tailscale.com/ipn/localapi/tailnetlock.go new file mode 100644 index 0000000..e5f999b --- /dev/null +++ b/vendor/tailscale.com/ipn/localapi/tailnetlock.go @@ -0,0 +1,413 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_tailnetlock + +package localapi + +import ( + "encoding/json" + "io" + "net/http" + "strconv" + + "tailscale.com/tka" + "tailscale.com/types/key" + "tailscale.com/types/tkatype" + "tailscale.com/util/httpm" +) + +func init() { + Register("tka/affected-sigs", (*Handler).serveTKAAffectedSigs) + Register("tka/cosign-recovery-aum", (*Handler).serveTKACosignRecoveryAUM) + Register("tka/disable", (*Handler).serveTKADisable) + Register("tka/force-local-disable", (*Handler).serveTKALocalDisable) + Register("tka/generate-recovery-aum", (*Handler).serveTKAGenerateRecoveryAUM) + Register("tka/init", (*Handler).serveTKAInit) + Register("tka/log", (*Handler).serveTKALog) + Register("tka/modify", (*Handler).serveTKAModify) + Register("tka/sign", (*Handler).serveTKASign) + Register("tka/status", (*Handler).serveTKAStatus) + Register("tka/submit-recovery-aum", (*Handler).serveTKASubmitRecoveryAUM) + Register("tka/verify-deeplink", (*Handler).serveTKAVerifySigningDeeplink) + Register("tka/wrap-preauth-key", (*Handler).serveTKAWrapPreauthKey) +} + +func (h *Handler) serveTKAStatus(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "lock status access denied", http.StatusForbidden) + return + } + if r.Method != httpm.GET { + http.Error(w, "use GET", http.StatusMethodNotAllowed) + return + } + + j, err := json.MarshalIndent(h.b.NetworkLockStatus(), "", "\t") + if err != nil { + http.Error(w, "JSON encoding error", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} + +func (h *Handler) serveTKASign(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "lock sign access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type signRequest struct { + NodeKey key.NodePublic + RotationPublic []byte + } + var req signRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + if err := h.b.NetworkLockSign(req.NodeKey, req.RotationPublic); err != nil { + http.Error(w, "signing failed: "+err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) +} + +func (h *Handler) serveTKAInit(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "lock init access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type initRequest struct { + Keys []tka.Key + DisablementValues [][]byte + SupportDisablement []byte + } + var req initRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + if !h.b.NetworkLockAllowed() { + http.Error(w, "Tailnet Lock is not supported on your pricing plan", http.StatusForbidden) + return + } + + if err := h.b.NetworkLockInit(req.Keys, req.DisablementValues, req.SupportDisablement); err != nil { + http.Error(w, "initialization failed: "+err.Error(), http.StatusInternalServerError) + return + } + + j, err := json.MarshalIndent(h.b.NetworkLockStatus(), "", "\t") + if err != nil { + http.Error(w, "JSON encoding error", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} + +func (h *Handler) serveTKAModify(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "network-lock modify access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type modifyRequest struct { + AddKeys []tka.Key + RemoveKeys []tka.Key + } + var req modifyRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + if err := h.b.NetworkLockModify(req.AddKeys, req.RemoveKeys); err != nil { + http.Error(w, "network-lock modify failed: "+err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(204) +} + +func (h *Handler) serveTKAWrapPreauthKey(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "network-lock modify access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type wrapRequest struct { + TSKey string + TKAKey string // key.NLPrivate.MarshalText + } + var req wrapRequest + if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 12*1024)).Decode(&req); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + var priv key.NLPrivate + if err := priv.UnmarshalText([]byte(req.TKAKey)); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + wrappedKey, err := h.b.NetworkLockWrapPreauthKey(req.TSKey, priv) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + w.Write([]byte(wrappedKey)) +} + +func (h *Handler) serveTKAVerifySigningDeeplink(w http.ResponseWriter, r *http.Request) { + if !h.PermitRead { + http.Error(w, "signing deeplink verification access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type verifyRequest struct { + URL string + } + var req verifyRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON for verifyRequest body", http.StatusBadRequest) + return + } + + res := h.b.NetworkLockVerifySigningDeeplink(req.URL) + j, err := json.MarshalIndent(res, "", "\t") + if err != nil { + http.Error(w, "JSON encoding error", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} + +func (h *Handler) serveTKADisable(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "network-lock modify access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + body := io.LimitReader(r.Body, 1024*1024) + secret, err := io.ReadAll(body) + if err != nil { + http.Error(w, "reading secret", http.StatusBadRequest) + return + } + + if err := h.b.NetworkLockDisable(secret); err != nil { + http.Error(w, "network-lock disable failed: "+err.Error(), http.StatusBadRequest) + return + } + w.WriteHeader(http.StatusOK) +} + +func (h *Handler) serveTKALocalDisable(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "network-lock modify access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + // Require a JSON stanza for the body as an additional CSRF protection. + var req struct{} + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON body", http.StatusBadRequest) + return + } + + if err := h.b.NetworkLockForceLocalDisable(); err != nil { + http.Error(w, "network-lock local disable failed: "+err.Error(), http.StatusBadRequest) + return + } + w.WriteHeader(http.StatusOK) +} + +func (h *Handler) serveTKALog(w http.ResponseWriter, r *http.Request) { + if r.Method != httpm.GET { + http.Error(w, "use GET", http.StatusMethodNotAllowed) + return + } + + limit := 50 + if limitStr := r.FormValue("limit"); limitStr != "" { + lm, err := strconv.Atoi(limitStr) + if err != nil { + http.Error(w, "parsing 'limit' parameter: "+err.Error(), http.StatusBadRequest) + return + } + limit = int(lm) + } + + updates, err := h.b.NetworkLockLog(limit) + if err != nil { + http.Error(w, "reading log failed: "+err.Error(), http.StatusInternalServerError) + return + } + + j, err := json.MarshalIndent(updates, "", "\t") + if err != nil { + http.Error(w, "JSON encoding error", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} + +func (h *Handler) serveTKAAffectedSigs(w http.ResponseWriter, r *http.Request) { + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + keyID, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 2048)) + if err != nil { + http.Error(w, "reading body", http.StatusBadRequest) + return + } + + sigs, err := h.b.NetworkLockAffectedSigs(keyID) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + j, err := json.MarshalIndent(sigs, "", "\t") + if err != nil { + http.Error(w, "JSON encoding error", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(j) +} + +func (h *Handler) serveTKAGenerateRecoveryAUM(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + type verifyRequest struct { + Keys []tkatype.KeyID + ForkFrom string + } + var req verifyRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid JSON for verifyRequest body", http.StatusBadRequest) + return + } + + var forkFrom tka.AUMHash + if req.ForkFrom != "" { + if err := forkFrom.UnmarshalText([]byte(req.ForkFrom)); err != nil { + http.Error(w, "decoding fork-from: "+err.Error(), http.StatusBadRequest) + return + } + } + + res, err := h.b.NetworkLockGenerateRecoveryAUM(req.Keys, forkFrom) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(res.Serialize()) +} + +func (h *Handler) serveTKACosignRecoveryAUM(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + body := io.LimitReader(r.Body, 1024*1024) + aumBytes, err := io.ReadAll(body) + if err != nil { + http.Error(w, "reading AUM", http.StatusBadRequest) + return + } + var aum tka.AUM + if err := aum.Unserialize(aumBytes); err != nil { + http.Error(w, "decoding AUM", http.StatusBadRequest) + return + } + + res, err := h.b.NetworkLockCosignRecoveryAUM(&aum) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(res.Serialize()) +} + +func (h *Handler) serveTKASubmitRecoveryAUM(w http.ResponseWriter, r *http.Request) { + if !h.PermitWrite { + http.Error(w, "access denied", http.StatusForbidden) + return + } + if r.Method != httpm.POST { + http.Error(w, "use POST", http.StatusMethodNotAllowed) + return + } + + body := io.LimitReader(r.Body, 1024*1024) + aumBytes, err := io.ReadAll(body) + if err != nil { + http.Error(w, "reading AUM", http.StatusBadRequest) + return + } + var aum tka.AUM + if err := aum.Unserialize(aumBytes); err != nil { + http.Error(w, "decoding AUM", http.StatusBadRequest) + return + } + + if err := h.b.NetworkLockSubmitRecoveryAUM(&aum); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) +} diff --git a/vendor/tailscale.com/ipn/policy/policy.go b/vendor/tailscale.com/ipn/policy/policy.go deleted file mode 100644 index 494a0dc..0000000 --- a/vendor/tailscale.com/ipn/policy/policy.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package policy contains various policy decisions that need to be -// shared between the node client & control server. -package policy - -import ( - "tailscale.com/tailcfg" -) - -// IsInterestingService reports whether service s on the given operating -// system (a version.OS value) is an interesting enough port to report -// to our peer nodes for discovery purposes. -func IsInterestingService(s tailcfg.Service, os string) bool { - switch s.Proto { - case tailcfg.PeerAPI4, tailcfg.PeerAPI6, tailcfg.PeerAPIDNS: - return true - } - if s.Proto != tailcfg.TCP { - return false - } - if os != "windows" { - // For non-Windows machines, assume all TCP listeners - // are interesting enough. We don't see listener spam - // there. - return true - } - // Windows has tons of TCP listeners. We need to move to a denylist - // model later, but for now we just allow some common ones: - switch s.Port { - case 22, // ssh - 80, // http - 443, // https (but no hostname, so little useless) - 3389, // rdp - 5900, // vnc - 32400, // plex - - // And now some arbitrary HTTP dev server ports: - // Eventually we'll remove this and make all ports - // work, once we nicely filter away noisy system - // ports. - 8000, 8080, 8443, 8888: - return true - } - return false -} diff --git a/vendor/tailscale.com/ipn/prefs.go b/vendor/tailscale.com/ipn/prefs.go index f5406f3..9f98465 100644 --- a/vendor/tailscale.com/ipn/prefs.go +++ b/vendor/tailscale.com/ipn/prefs.go @@ -5,6 +5,7 @@ package ipn import ( "bytes" + "cmp" "encoding/json" "errors" "fmt" @@ -19,6 +20,7 @@ import ( "tailscale.com/atomicfile" "tailscale.com/drive" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn/ipnstate" "tailscale.com/net/netaddr" "tailscale.com/net/tsaddr" @@ -28,7 +30,9 @@ import ( "tailscale.com/types/preftype" "tailscale.com/types/views" "tailscale.com/util/dnsname" - "tailscale.com/util/syspolicy" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/version" ) // DefaultControlURL is the URL base of the control plane @@ -93,6 +97,25 @@ type Prefs struct { ExitNodeID tailcfg.StableNodeID ExitNodeIP netip.Addr + // AutoExitNode is an optional expression that specifies whether and how + // tailscaled should pick an exit node automatically. + // + // If specified, tailscaled will use an exit node based on the expression, + // and will re-evaluate the selection periodically as network conditions, + // available exit nodes, or policy settings change. A blackhole route will + // be installed to prevent traffic from escaping to the local network until + // an exit node is selected. It takes precedence over ExitNodeID and ExitNodeIP. + // + // If empty, tailscaled will not automatically select an exit node. + // + // If the specified expression is invalid or unsupported by the client, + // it falls back to the behavior of [AnyExitNode]. + // + // As of 2025-07-02, the only supported value is [AnyExitNode]. + // It's a string rather than a boolean to allow future extensibility + // (e.g., AutoExitNode = "mullvad" or AutoExitNode = "geo:us"). + AutoExitNode ExitNodeExpression `json:",omitempty"` + // InternalExitNodePrior is the most recently used ExitNodeID in string form. It is set by // the backend on transition from exit node on to off and used by the // backend. @@ -138,11 +161,10 @@ type Prefs struct { // connections. This overrides tailcfg.Hostinfo's ShieldsUp. ShieldsUp bool - // AdvertiseTags specifies groups that this node wants to join, for - // purposes of ACL enforcement. These can be referenced from the ACL - // security policy. Note that advertising a tag doesn't guarantee that - // the control server will allow you to take on the rights for that - // tag. + // AdvertiseTags specifies tags that should be applied to this node, for + // purposes of ACL enforcement. These can be referenced from the ACL policy + // document. Note that advertising a tag on the client doesn't guarantee + // that the control server will allow the node to adopt that tag. AdvertiseTags []string // Hostname is the hostname to use for identifying the node. If @@ -185,6 +207,12 @@ type Prefs struct { // control server. AdvertiseServices []string + // Sync is whether this node should sync its configuration from + // the control plane. If unset, this defaults to true. + // This exists primarily for testing, to verify that netmap caching + // and offline operation work correctly. + Sync opt.Bool + // NoSNAT specifies whether to source NAT traffic going to // destinations in AdvertiseRoutes. The default is to apply source // NAT, which makes the traffic appear to come from the router @@ -234,10 +262,17 @@ type Prefs struct { // PostureChecking enables the collection of information used for device // posture checks. + // + // Note: this should be named ReportPosture, but it was shipped as + // PostureChecking in some early releases and this JSON field is written to + // disk, so we just keep its old name. (akin to CorpDNS which is an internal + // pref name that doesn't match the public interface) PostureChecking bool // NetfilterKind specifies what netfilter implementation to use. // + // It can be "iptables", "nftables", or "" to auto-detect. + // // Linux-only. NetfilterKind string @@ -245,9 +280,20 @@ type Prefs struct { // by name. DriveShares []*drive.Share + // RelayServerPort is the UDP port number for the relay server to bind to, + // on all interfaces. A non-nil zero value signifies a random unused port + // should be used. A nil value signifies relay server functionality + // should be disabled. + RelayServerPort *uint16 `json:",omitempty"` + + // RelayServerStaticEndpoints are static IP:port endpoints to advertise as + // candidates for relay connections. Only relevant when RelayServerPort is + // non-nil. + RelayServerStaticEndpoints []netip.AddrPort `json:",omitempty"` + // AllowSingleHosts was a legacy field that was always true // for the past 4.5 years. It controlled whether Tailscale - // peers got /32 or /127 routes for each other. + // peers got /32 or /128 routes for each other. // As of 2024-05-17 we're starting to ignore it, but to let // people still downgrade Tailscale versions and not break // all peer-to-peer networking we still write it to disk (as JSON) @@ -307,35 +353,39 @@ type AppConnectorPrefs struct { type MaskedPrefs struct { Prefs - ControlURLSet bool `json:",omitempty"` - RouteAllSet bool `json:",omitempty"` - ExitNodeIDSet bool `json:",omitempty"` - ExitNodeIPSet bool `json:",omitempty"` - InternalExitNodePriorSet bool `json:",omitempty"` // Internal; can't be set by LocalAPI clients - ExitNodeAllowLANAccessSet bool `json:",omitempty"` - CorpDNSSet bool `json:",omitempty"` - RunSSHSet bool `json:",omitempty"` - RunWebClientSet bool `json:",omitempty"` - WantRunningSet bool `json:",omitempty"` - LoggedOutSet bool `json:",omitempty"` - ShieldsUpSet bool `json:",omitempty"` - AdvertiseTagsSet bool `json:",omitempty"` - HostnameSet bool `json:",omitempty"` - NotepadURLsSet bool `json:",omitempty"` - ForceDaemonSet bool `json:",omitempty"` - EggSet bool `json:",omitempty"` - AdvertiseRoutesSet bool `json:",omitempty"` - AdvertiseServicesSet bool `json:",omitempty"` - NoSNATSet bool `json:",omitempty"` - NoStatefulFilteringSet bool `json:",omitempty"` - NetfilterModeSet bool `json:",omitempty"` - OperatorUserSet bool `json:",omitempty"` - ProfileNameSet bool `json:",omitempty"` - AutoUpdateSet AutoUpdatePrefsMask `json:",omitempty"` - AppConnectorSet bool `json:",omitempty"` - PostureCheckingSet bool `json:",omitempty"` - NetfilterKindSet bool `json:",omitempty"` - DriveSharesSet bool `json:",omitempty"` + ControlURLSet bool `json:",omitempty"` + RouteAllSet bool `json:",omitempty"` + ExitNodeIDSet bool `json:",omitempty"` + ExitNodeIPSet bool `json:",omitempty"` + AutoExitNodeSet bool `json:",omitempty"` + InternalExitNodePriorSet bool `json:",omitempty"` // Internal; can't be set by LocalAPI clients + ExitNodeAllowLANAccessSet bool `json:",omitempty"` + CorpDNSSet bool `json:",omitempty"` + RunSSHSet bool `json:",omitempty"` + RunWebClientSet bool `json:",omitempty"` + WantRunningSet bool `json:",omitempty"` + LoggedOutSet bool `json:",omitempty"` + ShieldsUpSet bool `json:",omitempty"` + AdvertiseTagsSet bool `json:",omitempty"` + HostnameSet bool `json:",omitempty"` + NotepadURLsSet bool `json:",omitempty"` + ForceDaemonSet bool `json:",omitempty"` + EggSet bool `json:",omitempty"` + AdvertiseRoutesSet bool `json:",omitempty"` + AdvertiseServicesSet bool `json:",omitempty"` + SyncSet bool `json:",omitzero"` + NoSNATSet bool `json:",omitempty"` + NoStatefulFilteringSet bool `json:",omitempty"` + NetfilterModeSet bool `json:",omitempty"` + OperatorUserSet bool `json:",omitempty"` + ProfileNameSet bool `json:",omitempty"` + AutoUpdateSet AutoUpdatePrefsMask `json:",omitzero"` + AppConnectorSet bool `json:",omitempty"` + PostureCheckingSet bool `json:",omitempty"` + NetfilterKindSet bool `json:",omitempty"` + DriveSharesSet bool `json:",omitempty"` + RelayServerPortSet bool `json:",omitempty"` + RelayServerStaticEndpointsSet bool `json:",omitzero"` } // SetsInternal reports whether mp has any of the Internal*Set field bools set @@ -493,17 +543,24 @@ func (p *Prefs) Pretty() string { return p.pretty(runtime.GOOS) } func (p *Prefs) pretty(goos string) string { var sb strings.Builder sb.WriteString("Prefs{") - fmt.Fprintf(&sb, "ra=%v ", p.RouteAll) - fmt.Fprintf(&sb, "dns=%v want=%v ", p.CorpDNS, p.WantRunning) - if p.RunSSH { + if buildfeatures.HasUseRoutes { + fmt.Fprintf(&sb, "ra=%v ", p.RouteAll) + } + if buildfeatures.HasDNS { + fmt.Fprintf(&sb, "dns=%v want=%v ", p.CorpDNS, p.WantRunning) + } + if buildfeatures.HasSSH && p.RunSSH { sb.WriteString("ssh=true ") } - if p.RunWebClient { + if buildfeatures.HasWebClient && p.RunWebClient { sb.WriteString("webclient=true ") } if p.LoggedOut { sb.WriteString("loggedout=true ") } + if p.Sync.EqualBool(false) { + sb.WriteString("sync=false ") + } if p.ForceDaemon { sb.WriteString("server=true ") } @@ -513,23 +570,30 @@ func (p *Prefs) pretty(goos string) string { if p.ShieldsUp { sb.WriteString("shields=true ") } - if p.ExitNodeIP.IsValid() { - fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeIP, p.ExitNodeAllowLANAccess) - } else if !p.ExitNodeID.IsZero() { - fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeID, p.ExitNodeAllowLANAccess) + if buildfeatures.HasUseExitNode { + if p.ExitNodeIP.IsValid() { + fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeIP, p.ExitNodeAllowLANAccess) + } else if !p.ExitNodeID.IsZero() { + fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeID, p.ExitNodeAllowLANAccess) + } + if p.AutoExitNode.IsSet() { + fmt.Fprintf(&sb, "auto=%v ", p.AutoExitNode) + } } - if len(p.AdvertiseRoutes) > 0 || goos == "linux" { - fmt.Fprintf(&sb, "routes=%v ", p.AdvertiseRoutes) - } - if len(p.AdvertiseRoutes) > 0 || p.NoSNAT { - fmt.Fprintf(&sb, "snat=%v ", !p.NoSNAT) - } - if len(p.AdvertiseRoutes) > 0 || p.NoStatefulFiltering.EqualBool(true) { - // Only print if we're advertising any routes, or the user has - // turned off stateful filtering (NoStatefulFiltering=true ⇒ - // StatefulFiltering=false). - bb, _ := p.NoStatefulFiltering.Get() - fmt.Fprintf(&sb, "statefulFiltering=%v ", !bb) + if buildfeatures.HasAdvertiseRoutes { + if len(p.AdvertiseRoutes) > 0 || goos == "linux" { + fmt.Fprintf(&sb, "routes=%v ", p.AdvertiseRoutes) + } + if len(p.AdvertiseRoutes) > 0 || p.NoSNAT { + fmt.Fprintf(&sb, "snat=%v ", !p.NoSNAT) + } + if len(p.AdvertiseRoutes) > 0 || p.NoStatefulFiltering.EqualBool(true) { + // Only print if we're advertising any routes, or the user has + // turned off stateful filtering (NoStatefulFiltering=true ⇒ + // StatefulFiltering=false). + bb, _ := p.NoStatefulFiltering.Get() + fmt.Fprintf(&sb, "statefulFiltering=%v ", !bb) + } } if len(p.AdvertiseTags) > 0 { fmt.Fprintf(&sb, "tags=%s ", strings.Join(p.AdvertiseTags, ",")) @@ -552,8 +616,18 @@ func (p *Prefs) pretty(goos string) string { if p.NetfilterKind != "" { fmt.Fprintf(&sb, "netfilterKind=%s ", p.NetfilterKind) } - sb.WriteString(p.AutoUpdate.Pretty()) - sb.WriteString(p.AppConnector.Pretty()) + if buildfeatures.HasClientUpdate { + sb.WriteString(p.AutoUpdate.Pretty()) + } + if buildfeatures.HasAppConnectors { + sb.WriteString(p.AppConnector.Pretty()) + } + if buildfeatures.HasRelayServer && p.RelayServerPort != nil { + fmt.Fprintf(&sb, "relayServerPort=%d ", *p.RelayServerPort) + } + if buildfeatures.HasRelayServer && len(p.RelayServerStaticEndpoints) > 0 { + fmt.Fprintf(&sb, "relayServerStaticEndpoints=%v ", p.RelayServerStaticEndpoints) + } if p.Persist != nil { sb.WriteString(p.Persist.Pretty()) } else { @@ -580,7 +654,7 @@ func (p PrefsView) Equals(p2 PrefsView) bool { } func (p *Prefs) Equals(p2 *Prefs) bool { - if p == nil && p2 == nil { + if p == p2 { return true } if p == nil || p2 == nil { @@ -591,10 +665,12 @@ func (p *Prefs) Equals(p2 *Prefs) bool { p.RouteAll == p2.RouteAll && p.ExitNodeID == p2.ExitNodeID && p.ExitNodeIP == p2.ExitNodeIP && + p.AutoExitNode == p2.AutoExitNode && p.InternalExitNodePrior == p2.InternalExitNodePrior && p.ExitNodeAllowLANAccess == p2.ExitNodeAllowLANAccess && p.CorpDNS == p2.CorpDNS && p.RunSSH == p2.RunSSH && + p.Sync.Normalized() == p2.Sync.Normalized() && p.RunWebClient == p2.RunWebClient && p.WantRunning == p2.WantRunning && p.LoggedOut == p2.LoggedOut && @@ -606,16 +682,18 @@ func (p *Prefs) Equals(p2 *Prefs) bool { p.OperatorUser == p2.OperatorUser && p.Hostname == p2.Hostname && p.ForceDaemon == p2.ForceDaemon && - compareIPNets(p.AdvertiseRoutes, p2.AdvertiseRoutes) && - compareStrings(p.AdvertiseTags, p2.AdvertiseTags) && - compareStrings(p.AdvertiseServices, p2.AdvertiseServices) && + slices.Equal(p.AdvertiseRoutes, p2.AdvertiseRoutes) && + slices.Equal(p.AdvertiseTags, p2.AdvertiseTags) && + slices.Equal(p.AdvertiseServices, p2.AdvertiseServices) && p.Persist.Equals(p2.Persist) && p.ProfileName == p2.ProfileName && p.AutoUpdate.Equals(p2.AutoUpdate) && p.AppConnector == p2.AppConnector && p.PostureChecking == p2.PostureChecking && slices.EqualFunc(p.DriveShares, p2.DriveShares, drive.SharesEqual) && - p.NetfilterKind == p2.NetfilterKind + p.NetfilterKind == p2.NetfilterKind && + compareUint16Ptrs(p.RelayServerPort, p2.RelayServerPort) && + slices.Equal(p.RelayServerStaticEndpoints, p2.RelayServerStaticEndpoints) } func (au AutoUpdatePrefs) Pretty() string { @@ -635,28 +713,14 @@ func (ap AppConnectorPrefs) Pretty() string { return "" } -func compareIPNets(a, b []netip.Prefix) bool { - if len(a) != len(b) { +func compareUint16Ptrs(a, b *uint16) bool { + if (a == nil) != (b == nil) { return false } - for i := range a { - if a[i] != b[i] { - return false - } + if a == nil { + return true } - return true -} - -func compareStrings(a, b []string) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true + return *a == *b } // NewPrefs returns the default preferences to use. @@ -664,7 +728,8 @@ func NewPrefs() *Prefs { // Provide default values for options which might be missing // from the json data for any reason. The json can still // override them to false. - return &Prefs{ + + p := &Prefs{ // ControlURL is explicitly not set to signal that // it's not yet configured, which relaxes the CLI "up" // safety net features. It will get set to DefaultControlURL @@ -672,7 +737,6 @@ func NewPrefs() *Prefs { // later anyway. ControlURL: "", - RouteAll: true, CorpDNS: true, WantRunning: false, NetfilterMode: preftype.NetfilterOn, @@ -682,22 +746,24 @@ func NewPrefs() *Prefs { Apply: opt.Bool("unset"), }, } + p.RouteAll = p.DefaultRouteAll(runtime.GOOS) + return p } // ControlURLOrDefault returns the coordination server's URL base. // // If not configured, or if the configured value is a legacy name equivalent to // the default, then DefaultControlURL is returned instead. -func (p PrefsView) ControlURLOrDefault() string { - return p.ж.ControlURLOrDefault() +func (p PrefsView) ControlURLOrDefault(polc policyclient.Client) string { + return p.ж.ControlURLOrDefault(polc) } // ControlURLOrDefault returns the coordination server's URL base. // // If not configured, or if the configured value is a legacy name equivalent to // the default, then DefaultControlURL is returned instead. -func (p *Prefs) ControlURLOrDefault() string { - controlURL, err := syspolicy.GetString(syspolicy.ControlURL, p.ControlURL) +func (p *Prefs) ControlURLOrDefault(polc policyclient.Client) string { + controlURL, err := polc.GetString(pkey.ControlURL, p.ControlURL) if err != nil { controlURL = p.ControlURL } @@ -711,12 +777,26 @@ func (p *Prefs) ControlURLOrDefault() string { return DefaultControlURL } -// AdminPageURL returns the admin web site URL for the current ControlURL. -func (p PrefsView) AdminPageURL() string { return p.ж.AdminPageURL() } +// DefaultRouteAll returns the default value of [Prefs.RouteAll] as a function +// of the platform it's running on. +func (p *Prefs) DefaultRouteAll(goos string) bool { + switch goos { + case "windows", "android", "ios": + return true + case "darwin": + // Only true for macAppStore and macsys, false for darwin tailscaled. + return version.IsSandboxedMacOS() + default: + return false + } +} // AdminPageURL returns the admin web site URL for the current ControlURL. -func (p *Prefs) AdminPageURL() string { - url := p.ControlURLOrDefault() +func (p PrefsView) AdminPageURL(polc policyclient.Client) string { return p.ж.AdminPageURL(polc) } + +// AdminPageURL returns the admin web site URL for the current ControlURL. +func (p *Prefs) AdminPageURL(polc policyclient.Client) string { + url := p.ControlURLOrDefault(polc) if IsLoginServerSynonym(url) { // TODO(crawshaw): In future release, make this https://console.tailscale.com url = "https://login.tailscale.com" @@ -740,6 +820,9 @@ func (p *Prefs) AdvertisesExitNode() bool { // SetAdvertiseExitNode mutates p (if non-nil) to add or remove the two // /0 exit node routes. func (p *Prefs) SetAdvertiseExitNode(runExit bool) { + if !buildfeatures.HasAdvertiseExitNode { + return + } if p == nil { return } @@ -784,6 +867,7 @@ func isRemoteIP(st *ipnstate.Status, ip netip.Addr) bool { func (p *Prefs) ClearExitNode() { p.ExitNodeID = "" p.ExitNodeIP = netip.Addr{} + p.AutoExitNode = "" } // ExitNodeLocalIPError is returned when the requested IP address for an exit @@ -802,6 +886,9 @@ func exitNodeIPOfArg(s string, st *ipnstate.Status) (ip netip.Addr, err error) { } ip, err = netip.ParseAddr(s) if err == nil { + if !isRemoteIP(st, ip) { + return ip, ExitNodeLocalIPError{s} + } // If we're online already and have a netmap, double check that the IP // address specified is valid. if st.BackendState == "Running" { @@ -813,9 +900,6 @@ func exitNodeIPOfArg(s string, st *ipnstate.Status) (ip netip.Addr, err error) { return ip, fmt.Errorf("node %v is not advertising an exit node", ip) } } - if !isRemoteIP(st, ip) { - return ip, ExitNodeLocalIPError{s} - } return ip, nil } match := 0 @@ -891,10 +975,15 @@ func PrefsFromBytes(b []byte, base *Prefs) error { if len(b) == 0 { return nil } - return json.Unmarshal(b, base) } +func (p *Prefs) normalizeOptBools() { + if p.Sync == opt.ExplicitlyUnset { + p.Sync = "" + } +} + var jsonEscapedZero = []byte(`\u0000`) // LoadPrefsWindows loads a legacy relaynode config file into Prefs with @@ -943,6 +1032,7 @@ type WindowsUserID string type NetworkProfile struct { MagicDNSName string DomainName string + DisplayName string } // RequiresBackfill returns whether this object does not have all the data @@ -955,6 +1045,13 @@ func (n NetworkProfile) RequiresBackfill() bool { return n == NetworkProfile{} } +// DisplayNameOrDefault will always return a non-empty string. +// If there is a defined display name, it will return that. +// If they did not it will default to their domain name. +func (n NetworkProfile) DisplayNameOrDefault() string { + return cmp.Or(n.DisplayName, n.DomainName) +} + // LoginProfile represents a single login profile as managed // by the ProfileManager. type LoginProfile struct { @@ -1000,3 +1097,68 @@ type LoginProfile struct { // into. ControlURL string } + +// Equals reports whether p and p2 are equal. +func (p LoginProfileView) Equals(p2 LoginProfileView) bool { + return p.ж.Equals(p2.ж) +} + +// Equals reports whether p and p2 are equal. +func (p *LoginProfile) Equals(p2 *LoginProfile) bool { + if p == p2 { + return true + } + if p == nil || p2 == nil { + return false + } + return p.ID == p2.ID && + p.Name == p2.Name && + p.NetworkProfile == p2.NetworkProfile && + p.Key == p2.Key && + p.UserProfile.Equal(&p2.UserProfile) && + p.NodeID == p2.NodeID && + p.LocalUserID == p2.LocalUserID && + p.ControlURL == p2.ControlURL +} + +// ExitNodeExpression is a string that specifies how an exit node +// should be selected. An empty string means that no exit node +// should be selected. +// +// As of 2025-07-02, the only supported value is [AnyExitNode]. +type ExitNodeExpression string + +// AnyExitNode indicates that the exit node should be automatically +// selected from the pool of available exit nodes, excluding any +// disallowed by policy (e.g., [syspolicy.AllowedSuggestedExitNodes]). +// The exact implementation is subject to change, but exit nodes +// offering the best performance will be preferred. +const AnyExitNode ExitNodeExpression = "any" + +// IsSet reports whether the expression is non-empty and can be used +// to select an exit node. +func (e ExitNodeExpression) IsSet() bool { + return e != "" +} + +const ( + // AutoExitNodePrefix is the prefix used in [syspolicy.ExitNodeID] values and CLI + // to indicate that the string following the prefix is an [ipn.ExitNodeExpression]. + AutoExitNodePrefix = "auto:" +) + +// ParseAutoExitNodeString attempts to parse the given string +// as an [ExitNodeExpression]. +// +// It returns the parsed expression and true on success, +// or an empty string and false if the input does not appear to be +// an [ExitNodeExpression] (i.e., it doesn't start with "auto:"). +// +// It is mainly used to parse the [syspolicy.ExitNodeID] value +// when it is set to "auto:" (e.g., auto:any). +func ParseAutoExitNodeString[T ~string](s T) (_ ExitNodeExpression, ok bool) { + if expr, ok := strings.CutPrefix(string(s), AutoExitNodePrefix); ok && expr != "" { + return ExitNodeExpression(expr), true + } + return "", false +} diff --git a/vendor/tailscale.com/ipn/serve.go b/vendor/tailscale.com/ipn/serve.go index ac92287..240308f 100644 --- a/vendor/tailscale.com/ipn/serve.go +++ b/vendor/tailscale.com/ipn/serve.go @@ -10,6 +10,7 @@ import ( "net" "net/netip" "net/url" + "runtime" "slices" "strconv" "strings" @@ -17,6 +18,7 @@ import ( "tailscale.com/ipn/ipnstate" "tailscale.com/tailcfg" "tailscale.com/types/ipproto" + "tailscale.com/util/dnsname" "tailscale.com/util/mak" "tailscale.com/util/set" ) @@ -149,6 +151,12 @@ type TCPPortHandler struct { // SNI name with this value. It is only used if TCPForward is non-empty. // (the HTTPS mode uses ServeConfig.Web) TerminateTLS string `json:",omitempty"` + + // ProxyProtocol indicates whether to send a PROXY protocol header + // before forwarding the connection to TCPForward. + // + // This is only valid if TCPForward is non-empty. + ProxyProtocol int `json:",omitzero"` } // HTTPHandler is either a path or a proxy to serve. @@ -160,32 +168,61 @@ type HTTPHandler struct { Text string `json:",omitempty"` // plaintext to serve (primarily for testing) + AcceptAppCaps []tailcfg.PeerCapability `json:",omitempty"` // peer capabilities to forward in grant header, e.g. example.com/cap/mon + + // Redirect, if not empty, is the target URL to redirect requests to. + // By default, we redirect with HTTP 302 (Found) status. + // If Redirect starts with ':', then we use that status instead. + // + // The target URL supports the following expansion variables: + // - ${HOST}: replaced with the request's Host header value + // - ${REQUEST_URI}: replaced with the request's full URI (path and query string) + Redirect string `json:",omitempty"` + // TODO(bradfitz): bool to not enumerate directories? TTL on mapping for - // temporary ones? Error codes? Redirects? + // temporary ones? Error codes? } // WebHandlerExists reports whether if the ServeConfig Web handler exists for // the given host:port and mount point. -func (sc *ServeConfig) WebHandlerExists(hp HostPort, mount string) bool { - h := sc.GetWebHandler(hp, mount) +func (sc *ServeConfig) WebHandlerExists(svcName tailcfg.ServiceName, hp HostPort, mount string) bool { + h := sc.GetWebHandler(svcName, hp, mount) return h != nil } // GetWebHandler returns the HTTPHandler for the given host:port and mount point. // Returns nil if the handler does not exist. -func (sc *ServeConfig) GetWebHandler(hp HostPort, mount string) *HTTPHandler { - if sc == nil || sc.Web[hp] == nil { +func (sc *ServeConfig) GetWebHandler(svcName tailcfg.ServiceName, hp HostPort, mount string) *HTTPHandler { + if sc == nil { + return nil + } + if svcName != "" { + if svc, ok := sc.Services[svcName]; ok && svc.Web != nil { + if webCfg, ok := svc.Web[hp]; ok { + return webCfg.Handlers[mount] + } + } + return nil + } + if sc.Web[hp] == nil { return nil } return sc.Web[hp].Handlers[mount] } -// GetTCPPortHandler returns the TCPPortHandler for the given port. -// If the port is not configured, nil is returned. -func (sc *ServeConfig) GetTCPPortHandler(port uint16) *TCPPortHandler { +// GetTCPPortHandler returns the TCPPortHandler for the given port. If the port +// is not configured, nil is returned. Parameter svcName can be tailcfg.NoService +// for local serve or a service name for a service hosted on node. +func (sc *ServeConfig) GetTCPPortHandler(port uint16, svcName tailcfg.ServiceName) *TCPPortHandler { if sc == nil { return nil } + if svcName != "" { + if svc, ok := sc.Services[svcName]; ok && svc != nil { + return svc.TCP[port] + } + return nil + } return sc.TCP[port] } @@ -202,6 +239,20 @@ func (sc *ServeConfig) HasPathHandler() bool { } } + if sc.Services != nil { + for _, serviceConfig := range sc.Services { + if serviceConfig.Web != nil { + for _, webServerConfig := range serviceConfig.Web { + for _, httpHandler := range webServerConfig.Handlers { + if httpHandler.Path != "" { + return true + } + } + } + } + } + } + if sc.Foreground != nil { for _, fgConfig := range sc.Foreground { if fgConfig.HasPathHandler() { @@ -227,34 +278,78 @@ func (sc *ServeConfig) IsTCPForwardingAny() bool { return false } -// IsTCPForwardingOnPort reports whether if ServeConfig is currently forwarding -// in TCPForward mode on the given port. This is exclusive of Web/HTTPS serving. -func (sc *ServeConfig) IsTCPForwardingOnPort(port uint16) bool { - if sc == nil || sc.TCP[port] == nil { +// IsTCPForwardingOnPort reports whether ServeConfig is currently forwarding +// in TCPForward mode on the given port for local or a service. svcName will +// either be noService (empty string) for local serve or a serviceName for service +// hosted on node. Notice TCPForwarding is exclusive with Web/HTTPS serving. +func (sc *ServeConfig) IsTCPForwardingOnPort(port uint16, svcName tailcfg.ServiceName) bool { + if sc == nil { return false } - return !sc.IsServingWeb(port) -} -// IsServingWeb reports whether if ServeConfig is currently serving Web -// (HTTP/HTTPS) on the given port. This is exclusive of TCPForwarding. -func (sc *ServeConfig) IsServingWeb(port uint16) bool { - return sc.IsServingHTTP(port) || sc.IsServingHTTPS(port) -} - -// IsServingHTTPS reports whether if ServeConfig is currently serving HTTPS on -// the given port. This is exclusive of HTTP and TCPForwarding. -func (sc *ServeConfig) IsServingHTTPS(port uint16) bool { - if sc == nil || sc.TCP[port] == nil { + if svcName != "" { + svc, ok := sc.Services[svcName] + if !ok || svc == nil { + return false + } + if svc.TCP[port] == nil { + return false + } + } else if sc.TCP[port] == nil { return false } - return sc.TCP[port].HTTPS + return !sc.IsServingWeb(port, svcName) } -// IsServingHTTP reports whether if ServeConfig is currently serving HTTP on the -// given port. This is exclusive of HTTPS and TCPForwarding. -func (sc *ServeConfig) IsServingHTTP(port uint16) bool { - if sc == nil || sc.TCP[port] == nil { +// IsServingWeb reports whether ServeConfig is currently serving Web (HTTP/HTTPS) +// on the given port for local or a service. svcName will be either tailcfg.NoService, +// or a serviceName for service hosted on node. This is exclusive with TCPForwarding. +func (sc *ServeConfig) IsServingWeb(port uint16, svcName tailcfg.ServiceName) bool { + return sc.IsServingHTTP(port, svcName) || sc.IsServingHTTPS(port, svcName) +} + +// IsServingHTTPS reports whether ServeConfig is currently serving HTTPS on +// the given port for local or a service. svcName will be either tailcfg.NoService +// for local serve, or a serviceName for service hosted on node. This is exclusive +// with HTTP and TCPForwarding. +func (sc *ServeConfig) IsServingHTTPS(port uint16, svcName tailcfg.ServiceName) bool { + if sc == nil { + return false + } + var tcpHandlers map[uint16]*TCPPortHandler + if svcName != "" { + if svc := sc.Services[svcName]; svc != nil { + tcpHandlers = svc.TCP + } + } else { + tcpHandlers = sc.TCP + } + + th := tcpHandlers[port] + if th == nil { + return false + } + return th.HTTPS +} + +// IsServingHTTP reports whether ServeConfig is currently serving HTTP on the +// given port for local or a service. svcName will be either tailcfg.NoService for +// local serve, or a serviceName for service hosted on node. This is exclusive +// with HTTPS and TCPForwarding. +func (sc *ServeConfig) IsServingHTTP(port uint16, svcName tailcfg.ServiceName) bool { + if sc == nil { + return false + } + if svcName != "" { + if svc := sc.Services[svcName]; svc != nil { + if svc.TCP[port] != nil { + return svc.TCP[port].HTTP + } + } + return false + } + + if sc.TCP[port] == nil { return false } return sc.TCP[port].HTTP @@ -280,21 +375,38 @@ func (sc *ServeConfig) FindConfig(port uint16) (*ServeConfig, bool) { // SetWebHandler sets the given HTTPHandler at the specified host, port, // and mount in the serve config. sc.TCP is also updated to reflect web -// serving usage of the given port. -func (sc *ServeConfig) SetWebHandler(handler *HTTPHandler, host string, port uint16, mount string, useTLS bool) { +// serving usage of the given port. The st argument is needed when setting +// a web handler for a service, otherwise it can be nil. mds is the Magic DNS +// suffix, which is used to recreate serve's host. +func (sc *ServeConfig) SetWebHandler(handler *HTTPHandler, host string, port uint16, mount string, useTLS bool, mds string) { if sc == nil { sc = new(ServeConfig) } - mak.Set(&sc.TCP, port, &TCPPortHandler{HTTPS: useTLS, HTTP: !useTLS}) - hp := HostPort(net.JoinHostPort(host, strconv.Itoa(int(port)))) - if _, ok := sc.Web[hp]; !ok { - mak.Set(&sc.Web, hp, new(WebServerConfig)) + tcpMap := &sc.TCP + webServerMap := &sc.Web + hostName := host + if svcName := tailcfg.AsServiceName(host); svcName != "" { + hostName = strings.Join([]string{svcName.WithoutPrefix(), mds}, ".") + svc, ok := sc.Services[svcName] + if !ok { + svc = new(ServiceConfig) + mak.Set(&sc.Services, svcName, svc) + } + tcpMap = &svc.TCP + webServerMap = &svc.Web } - mak.Set(&sc.Web[hp].Handlers, mount, handler) + mak.Set(tcpMap, port, &TCPPortHandler{HTTPS: useTLS, HTTP: !useTLS}) + hp := HostPort(net.JoinHostPort(hostName, strconv.Itoa(int(port)))) + webCfg, ok := (*webServerMap)[hp] + if !ok { + webCfg = new(WebServerConfig) + mak.Set(webServerMap, hp, webCfg) + } + mak.Set(&webCfg.Handlers, mount, handler) // TODO(tylersmalley): handle multiple web handlers from foreground mode - for k, v := range sc.Web[hp].Handlers { + for k, v := range webCfg.Handlers { if v == handler { continue } @@ -305,7 +417,7 @@ func (sc *ServeConfig) SetWebHandler(handler *HTTPHandler, host string, port uin m1 := strings.TrimSuffix(mount, "/") m2 := strings.TrimSuffix(k, "/") if m1 == m2 { - delete(sc.Web[hp].Handlers, k) + delete(webCfg.Handlers, k) } } } @@ -314,16 +426,46 @@ func (sc *ServeConfig) SetWebHandler(handler *HTTPHandler, host string, port uin // connections from the given port. If terminateTLS is true, TLS connections // are terminated with only the given host name permitted before passing them // to the fwdAddr. -func (sc *ServeConfig) SetTCPForwarding(port uint16, fwdAddr string, terminateTLS bool, host string) { +// +// If proxyProtocol is non-zero, the corresponding PROXY protocol version +// header is sent before forwarding the connection. +func (sc *ServeConfig) SetTCPForwarding(port uint16, fwdAddr string, terminateTLS bool, proxyProtocol int, host string) { if sc == nil { sc = new(ServeConfig) } - mak.Set(&sc.TCP, port, &TCPPortHandler{TCPForward: fwdAddr}) + mak.Set(&sc.TCP, port, &TCPPortHandler{ + TCPForward: fwdAddr, + ProxyProtocol: proxyProtocol, // can be 0 + }) + if terminateTLS { sc.TCP[port].TerminateTLS = host } } +// SetTCPForwardingForService sets the fwdAddr (IP:port form) to which to +// forward connections from the given port on the service. If terminateTLS +// is true, TLS connections are terminated, with only the FQDN that corresponds +// to the given service being permitted, before passing them to the fwdAddr. +func (sc *ServeConfig) SetTCPForwardingForService(port uint16, fwdAddr string, terminateTLS bool, svcName tailcfg.ServiceName, proxyProtocol int, magicDNSSuffix string) { + if sc == nil { + sc = new(ServeConfig) + } + svcConfig, ok := sc.Services[svcName] + if !ok { + svcConfig = new(ServiceConfig) + mak.Set(&sc.Services, svcName, svcConfig) + } + mak.Set(&svcConfig.TCP, port, &TCPPortHandler{ + TCPForward: fwdAddr, + ProxyProtocol: proxyProtocol, // can be 0 + }) + + if terminateTLS { + svcConfig.TCP[port].TerminateTLS = fmt.Sprintf("%s.%s", svcName.WithoutPrefix(), magicDNSSuffix) + } +} + // SetFunnel sets the sc.AllowFunnel value for the given host and port. func (sc *ServeConfig) SetFunnel(host string, port uint16, setOn bool) { if sc == nil { @@ -344,9 +486,9 @@ func (sc *ServeConfig) SetFunnel(host string, port uint16, setOn bool) { } } -// RemoveWebHandler deletes the web handlers at all of the given mount points -// for the provided host and port in the serve config. If cleanupFunnel is -// true, this also removes the funnel value for this port if no handlers remain. +// RemoveWebHandler deletes the web handlers at all of the given mount points for the +// provided host and port in the serve config for the node (as opposed to a service). +// If cleanupFunnel is true, this also removes the funnel value for this port if no handlers remain. func (sc *ServeConfig) RemoveWebHandler(host string, port uint16, mounts []string, cleanupFunnel bool) { hp := HostPort(net.JoinHostPort(host, strconv.Itoa(int(port)))) @@ -374,9 +516,50 @@ func (sc *ServeConfig) RemoveWebHandler(host string, port uint16, mounts []strin } } +// RemoveServiceWebHandler deletes the web handlers at all of the given mount points +// for the provided host and port in the serve config for the given service. +func (sc *ServeConfig) RemoveServiceWebHandler(svcName tailcfg.ServiceName, hostName string, port uint16, mounts []string) { + hp := HostPort(net.JoinHostPort(hostName, strconv.Itoa(int(port)))) + + svc, ok := sc.Services[svcName] + if !ok || svc == nil { + return + } + + // Delete existing handler, then cascade delete if empty. + for _, m := range mounts { + delete(svc.Web[hp].Handlers, m) + } + if len(svc.Web[hp].Handlers) == 0 { + delete(svc.Web, hp) + delete(svc.TCP, port) + } + if len(svc.Web) == 0 && len(svc.TCP) == 0 { + delete(sc.Services, svcName) + } + if len(sc.Services) == 0 { + sc.Services = nil + } +} + // RemoveTCPForwarding deletes the TCP forwarding configuration for the given // port from the serve config. -func (sc *ServeConfig) RemoveTCPForwarding(port uint16) { +func (sc *ServeConfig) RemoveTCPForwarding(svcName tailcfg.ServiceName, port uint16) { + if svcName != "" { + if svc := sc.Services[svcName]; svc != nil { + delete(svc.TCP, port) + if len(svc.TCP) == 0 { + svc.TCP = nil + } + if len(svc.Web) == 0 && len(svc.TCP) == 0 { + delete(sc.Services, svcName) + } + if len(sc.Services) == 0 { + sc.Services = nil + } + } + return + } delete(sc.TCP, port) if len(sc.TCP) == 0 { sc.TCP = nil @@ -519,7 +702,8 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error { // ExpandProxyTargetValue expands the supported target values to be proxied // allowing for input values to be a port number, a partial URL, or a full URL -// including a path. +// including a path. If it's for a service, remote addresses are allowed and +// there doesn't have to be a port specified. // // examples: // - 3000 @@ -529,17 +713,40 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error { // - https://localhost:3000 // - https-insecure://localhost:3000 // - https-insecure://localhost:3000/foo +// - https://tailscale.com func ExpandProxyTargetValue(target string, supportedSchemes []string, defaultScheme string) (string, error) { const host = "127.0.0.1" + // empty target is invalid + if target == "" { + return "", fmt.Errorf("empty target") + } + // support target being a port number if port, err := strconv.ParseUint(target, 10, 16); err == nil { return fmt.Sprintf("%s://%s:%d", defaultScheme, host, port), nil } + // handle unix: scheme specially - it doesn't use standard URL format + if strings.HasPrefix(target, "unix:") { + if !slices.Contains(supportedSchemes, "unix") { + return "", fmt.Errorf("unix sockets are not supported for this target type") + } + if runtime.GOOS == "windows" { + return "", fmt.Errorf("unix socket serve target is not supported on Windows") + } + path := strings.TrimPrefix(target, "unix:") + if path == "" { + return "", fmt.Errorf("unix socket path cannot be empty") + } + return target, nil + } + + hasScheme := true // prepend scheme if not present if !strings.Contains(target, "://") { target = defaultScheme + "://" + target + hasScheme = false } // make sure we can parse the target @@ -553,16 +760,28 @@ func ExpandProxyTargetValue(target string, supportedSchemes []string, defaultSch return "", fmt.Errorf("must be a URL starting with one of the supported schemes: %v", supportedSchemes) } - // validate the host. - switch u.Hostname() { - case "localhost", "127.0.0.1": - default: - return "", errors.New("only localhost or 127.0.0.1 proxies are currently supported") + // validate port according to host. + if u.Hostname() == "localhost" || u.Hostname() == "127.0.0.1" || u.Hostname() == "::1" { + // require port for localhost targets + if u.Port() == "" { + return "", fmt.Errorf("port required for localhost target %q", target) + } + } else { + validHN := dnsname.ValidHostname(u.Hostname()) == nil + validIP := net.ParseIP(u.Hostname()) != nil + if !validHN && !validIP { + return "", fmt.Errorf("invalid hostname or IP address %q", u.Hostname()) + } + // require scheme for non-localhost targets + if !hasScheme { + return "", fmt.Errorf("non-localhost target %q must include a scheme", target) + } } - - // validate the port port, err := strconv.ParseUint(u.Port(), 10, 16) if err != nil || port == 0 { + if u.Port() == "" { + return u.String(), nil // allow no port for remote destinations + } return "", fmt.Errorf("invalid port %q", u.Port()) } @@ -626,6 +845,7 @@ func (v ServeConfigView) FindServiceTCP(svcName tailcfg.ServiceName, port uint16 return svcCfg.TCP().GetOk(port) } +// FindServiceWeb returns the web handler for the service's host-port. func (v ServeConfigView) FindServiceWeb(svcName tailcfg.ServiceName, hp HostPort) (res WebServerConfigView, ok bool) { if svcCfg, ok := v.Services().GetOk(svcName); ok { if res, ok := svcCfg.Web().GetOk(hp); ok { @@ -639,10 +859,9 @@ func (v ServeConfigView) FindServiceWeb(svcName tailcfg.ServiceName, hp HostPort // prefers a foreground match first followed by a background search if none // existed. func (v ServeConfigView) FindTCP(port uint16) (res TCPPortHandlerView, ok bool) { - for _, conf := range v.Foreground().All() { - if res, ok := conf.TCP().GetOk(port); ok { - return res, ok - } + res, ok = v.FindForegroundTCP(port) + if ok { + return res, ok } return v.TCP().GetOk(port) } @@ -659,6 +878,17 @@ func (v ServeConfigView) FindWeb(hp HostPort) (res WebServerConfigView, ok bool) return v.Web().GetOk(hp) } +// FindForegroundTCP returns the first foreground TCP handler matching the input +// port. +func (v ServeConfigView) FindForegroundTCP(port uint16) (res TCPPortHandlerView, ok bool) { + for _, conf := range v.Foreground().All() { + if res, ok := conf.TCP().GetOk(port); ok { + return res, ok + } + } + return res, false +} + // HasAllowFunnel returns whether this config has at least one AllowFunnel // set in the background or foreground configs. func (v ServeConfigView) HasAllowFunnel() bool { @@ -687,17 +917,6 @@ func (v ServeConfigView) HasFunnelForTarget(target HostPort) bool { return false } -// CheckValidServicesConfig reports whether the ServeConfig has -// invalid service configurations. -func (sc *ServeConfig) CheckValidServicesConfig() error { - for svcName, service := range sc.Services { - if err := service.checkValidConfig(); err != nil { - return fmt.Errorf("invalid service configuration for %q: %w", svcName, err) - } - } - return nil -} - // ServicePortRange returns the list of tailcfg.ProtoPortRange that represents // the proto/ports pairs that are being served by the service. // @@ -735,17 +954,3 @@ func (v ServiceConfigView) ServicePortRange() []tailcfg.ProtoPortRange { } return ranges } - -// ErrServiceConfigHasBothTCPAndTun signals that a service -// in Tun mode cannot also has TCP or Web handlers set. -var ErrServiceConfigHasBothTCPAndTun = errors.New("the VIP Service configuration can not set TUN at the same time as TCP or Web") - -// checkValidConfig checks if the service configuration is valid. -// Currently, the only invalid configuration is when the service is in Tun mode -// and has TCP or Web handlers. -func (v *ServiceConfig) checkValidConfig() error { - if v.Tun && (len(v.TCP) > 0 || len(v.Web) > 0) { - return ErrServiceConfigHasBothTCPAndTun - } - return nil -} diff --git a/vendor/tailscale.com/ipn/store.go b/vendor/tailscale.com/ipn/store.go index 550aa8c..2034ae0 100644 --- a/vendor/tailscale.com/ipn/store.go +++ b/vendor/tailscale.com/ipn/store.go @@ -10,6 +10,8 @@ import ( "fmt" "net" "strconv" + + "tailscale.com/health" ) // ErrStateNotExist is returned by StateStore.ReadState when the @@ -60,6 +62,19 @@ const ( TaildropReceivedKey = StateKey("_taildrop-received") ) +// StateStoreHealth is a Warnable set when store.New fails at startup. If +// unhealthy, we block all login attempts and return a health message in status +// responses. +var StateStoreHealth = health.Register(&health.Warnable{ + Code: "state-store-health", + Severity: health.SeverityHigh, + Title: "Tailscale state store failed to initialize", + Text: func(args health.Args) string { + return fmt.Sprintf("State store failed to initialize, Tailscale will not work until this is resolved. See https://tailscale.com/s/state-store-init-error. Error: %s", args[health.ArgError]) + }, + ImpactsConnectivity: true, +}) + // CurrentProfileID returns the StateKey that stores the // current profile ID. The value is a JSON-encoded LoginProfile. // If the userID is empty, the key returned is CurrentProfileStateKey, @@ -113,3 +128,9 @@ func ReadStoreInt(store StateStore, id StateKey) (int64, error) { func PutStoreInt(store StateStore, id StateKey, val int64) error { return WriteState(store, id, fmt.Appendf(nil, "%d", val)) } + +// EncryptedStateStore is a marker interface implemented by StateStores that +// encrypt data at rest. +type EncryptedStateStore interface { + stateStoreIsEncrypted() +} diff --git a/vendor/tailscale.com/ipn/store/awsstore/store_aws.go b/vendor/tailscale.com/ipn/store/awsstore/store_aws.go deleted file mode 100644 index 40bbbf0..0000000 --- a/vendor/tailscale.com/ipn/store/awsstore/store_aws.go +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux && !ts_omit_aws - -// Package awsstore contains an ipn.StateStore implementation using AWS SSM. -package awsstore - -import ( - "context" - "errors" - "fmt" - "net/url" - "regexp" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/arn" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/ssm" - ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" - "tailscale.com/ipn" - "tailscale.com/ipn/store/mem" - "tailscale.com/types/logger" -) - -const ( - parameterNameRxStr = `^parameter(/.*)` -) - -var parameterNameRx = regexp.MustCompile(parameterNameRxStr) - -// Option defines a functional option type for configuring awsStore. -type Option func(*storeOptions) - -// storeOptions holds optional settings for creating a new awsStore. -type storeOptions struct { - kmsKey string -} - -// awsSSMClient is an interface allowing us to mock the couple of -// API calls we are leveraging with the AWSStore provider -type awsSSMClient interface { - GetParameter(ctx context.Context, - params *ssm.GetParameterInput, - optFns ...func(*ssm.Options)) (*ssm.GetParameterOutput, error) - - PutParameter(ctx context.Context, - params *ssm.PutParameterInput, - optFns ...func(*ssm.Options)) (*ssm.PutParameterOutput, error) -} - -// store is a store which leverages AWS SSM parameter store -// to persist the state -type awsStore struct { - ssmClient awsSSMClient - ssmARN arn.ARN - - // kmsKey is optional. If empty, the parameter is stored in plaintext. - // If non-empty, the parameter is encrypted with this KMS key. - kmsKey string - - memory mem.Store -} - -// New returns a new ipn.StateStore using the AWS SSM storage -// location given by ssmARN. -// -// Note that we store the entire store in a single parameter -// key, therefore if the state is above 8kb, it can cause -// Tailscaled to only only store new state in-memory and -// restarting Tailscaled can fail until you delete your state -// from the AWS Parameter Store. -// -// If you want to specify an optional KMS key, -// pass one or more Option objects, e.g. awsstore.WithKeyID("alias/my-key"). -func New(_ logger.Logf, ssmARN string, opts ...Option) (ipn.StateStore, error) { - // Apply all options to an empty storeOptions - var so storeOptions - for _, opt := range opts { - opt(&so) - } - - return newStore(ssmARN, so, nil) -} - -// WithKeyID sets the KMS key to be used for encryption. It can be -// a KeyID, an alias ("alias/my-key"), or a full ARN. -// -// If kmsKey is empty, the Option is a no-op. -func WithKeyID(kmsKey string) Option { - return func(o *storeOptions) { - o.kmsKey = kmsKey - } -} - -// ParseARNAndOpts parses an ARN and optional URL-encoded parameters -// from arg. -func ParseARNAndOpts(arg string) (ssmARN string, opts []Option, err error) { - ssmARN = arg - - // Support optional ?url-encoded-parameters. - if s, q, ok := strings.Cut(arg, "?"); ok { - ssmARN = s - q, err := url.ParseQuery(q) - if err != nil { - return "", nil, err - } - - for k := range q { - switch k { - default: - return "", nil, fmt.Errorf("unknown arn option parameter %q", k) - case "kmsKey": - // We allow an ARN, a key ID, or an alias name for kmsKeyID. - // If it doesn't look like an ARN and doesn't have a '/', - // prepend "alias/" for KMS alias references. - kmsKey := q.Get(k) - if kmsKey != "" && - !strings.Contains(kmsKey, "/") && - !strings.HasPrefix(kmsKey, "arn:") { - kmsKey = "alias/" + kmsKey - } - if kmsKey != "" { - opts = append(opts, WithKeyID(kmsKey)) - } - } - } - } - return ssmARN, opts, nil -} - -// newStore is NewStore, but for tests. If client is non-nil, it's -// used instead of making one. -func newStore(ssmARN string, so storeOptions, client awsSSMClient) (ipn.StateStore, error) { - s := &awsStore{ - ssmClient: client, - kmsKey: so.kmsKey, - } - - var err error - if s.ssmARN, err = arn.Parse(ssmARN); err != nil { - return nil, fmt.Errorf("unable to parse the ARN correctly: %v", err) - } - if s.ssmARN.Service != "ssm" { - return nil, fmt.Errorf("invalid service %q, expected 'ssm'", s.ssmARN.Service) - } - if !parameterNameRx.MatchString(s.ssmARN.Resource) { - return nil, fmt.Errorf("invalid resource %q, expected to match %v", s.ssmARN.Resource, parameterNameRxStr) - } - - if s.ssmClient == nil { - var cfg aws.Config - if cfg, err = config.LoadDefaultConfig( - context.TODO(), - config.WithRegion(s.ssmARN.Region), - ); err != nil { - return nil, err - } - s.ssmClient = ssm.NewFromConfig(cfg) - } - - // Preload existing state, if any - if err := s.LoadState(); err != nil { - return nil, err - } - return s, nil -} - -// LoadState attempts to read the state from AWS SSM parameter store key. -func (s *awsStore) LoadState() error { - param, err := s.ssmClient.GetParameter( - context.TODO(), - &ssm.GetParameterInput{ - Name: aws.String(s.ParameterName()), - WithDecryption: aws.Bool(true), - }, - ) - - if err != nil { - var pnf *ssmTypes.ParameterNotFound - if errors.As(err, &pnf) { - // Create the parameter as it does not exist yet - // and return directly as it is defacto empty - return s.persistState() - } - return err - } - - // Load the content in-memory - return s.memory.LoadFromJSON([]byte(*param.Parameter.Value)) -} - -// ParameterName returns the parameter name extracted from -// the provided ARN -func (s *awsStore) ParameterName() (name string) { - values := parameterNameRx.FindStringSubmatch(s.ssmARN.Resource) - if len(values) == 2 { - name = values[1] - } - return -} - -// String returns the awsStore and the ARN of the SSM parameter store -// configured to store the state -func (s *awsStore) String() string { return fmt.Sprintf("awsStore(%q)", s.ssmARN.String()) } - -// ReadState implements the Store interface. -func (s *awsStore) ReadState(id ipn.StateKey) (bs []byte, err error) { - return s.memory.ReadState(id) -} - -// WriteState implements the Store interface. -func (s *awsStore) WriteState(id ipn.StateKey, bs []byte) (err error) { - // Write the state in-memory - if err = s.memory.WriteState(id, bs); err != nil { - return - } - - // Persist the state in AWS SSM parameter store - return s.persistState() -} - -// PersistState saves the states into the AWS SSM parameter store -func (s *awsStore) persistState() error { - // Generate JSON from in-memory cache - bs, err := s.memory.ExportToJSON() - if err != nil { - return err - } - - // Store in AWS SSM parameter store. - // - // We use intelligent tiering so that when the state is below 4kb, it uses Standard tiering - // which is free. However, if it exceeds 4kb it switches the parameter to advanced tiering - // doubling the capacity to 8kb per the following docs: - // https://aws.amazon.com/about-aws/whats-new/2019/08/aws-systems-manager-parameter-store-announces-intelligent-tiering-to-enable-automatic-parameter-tier-selection/ - in := &ssm.PutParameterInput{ - Name: aws.String(s.ParameterName()), - Value: aws.String(string(bs)), - Overwrite: aws.Bool(true), - Tier: ssmTypes.ParameterTierIntelligentTiering, - Type: ssmTypes.ParameterTypeSecureString, - } - - // If kmsKey is specified, encrypt with that key - // NOTE: this input allows any alias, keyID or ARN - // If this isn't specified, AWS will use the default KMS key - if s.kmsKey != "" { - in.KeyId = aws.String(s.kmsKey) - } - - _, err = s.ssmClient.PutParameter(context.TODO(), in) - return err -} diff --git a/vendor/tailscale.com/ipn/store/kubestore/store_kube.go b/vendor/tailscale.com/ipn/store/kubestore/store_kube.go deleted file mode 100644 index 14025bb..0000000 --- a/vendor/tailscale.com/ipn/store/kubestore/store_kube.go +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package kubestore contains an ipn.StateStore implementation using Kubernetes Secrets. -package kubestore - -import ( - "context" - "fmt" - "log" - "net" - "os" - "strings" - "time" - - "tailscale.com/envknob" - "tailscale.com/ipn" - "tailscale.com/ipn/store/mem" - "tailscale.com/kube/kubeapi" - "tailscale.com/kube/kubeclient" - "tailscale.com/kube/kubetypes" - "tailscale.com/types/logger" - "tailscale.com/util/dnsname" - "tailscale.com/util/mak" -) - -const ( - // timeout is the timeout for a single state update that includes calls to the API server to write or read a - // state Secret and emit an Event. - timeout = 30 * time.Second - - reasonTailscaleStateUpdated = "TailscaledStateUpdated" - reasonTailscaleStateLoaded = "TailscaleStateLoaded" - reasonTailscaleStateUpdateFailed = "TailscaleStateUpdateFailed" - reasonTailscaleStateLoadFailed = "TailscaleStateLoadFailed" - eventTypeWarning = "Warning" - eventTypeNormal = "Normal" - - keyTLSCert = "tls.crt" - keyTLSKey = "tls.key" -) - -// Store is an ipn.StateStore that uses a Kubernetes Secret for persistence. -type Store struct { - client kubeclient.Client - canPatch bool - secretName string // state Secret - certShareMode string // 'ro', 'rw', or empty - podName string - - // memory holds the latest tailscale state. Writes write state to a kube - // Secret and memory, Reads read from memory. - memory mem.Store -} - -// New returns a new Store that persists state to Kubernets Secret(s). -// Tailscale state is stored in a Secret named by the secretName parameter. -// TLS certs are stored and retrieved from state Secret or separate Secrets -// named after TLS endpoints if running in cert share mode. -func New(logf logger.Logf, secretName string) (*Store, error) { - c, err := newClient() - if err != nil { - return nil, err - } - return newWithClient(logf, c, secretName) -} - -func newClient() (kubeclient.Client, error) { - c, err := kubeclient.New("tailscale-state-store") - if err != nil { - return nil, err - } - if os.Getenv("TS_KUBERNETES_READ_API_SERVER_ADDRESS_FROM_ENV") == "true" { - // Derive the API server address from the environment variables - c.SetURL(fmt.Sprintf("https://%s:%s", os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT_HTTPS"))) - } - return c, nil -} - -func newWithClient(logf logger.Logf, c kubeclient.Client, secretName string) (*Store, error) { - canPatch, _, err := c.CheckSecretPermissions(context.Background(), secretName) - if err != nil { - return nil, err - } - s := &Store{ - client: c, - canPatch: canPatch, - secretName: secretName, - podName: os.Getenv("POD_NAME"), - } - if envknob.IsCertShareReadWriteMode() { - s.certShareMode = "rw" - } else if envknob.IsCertShareReadOnlyMode() { - s.certShareMode = "ro" - } - - // Load latest state from kube Secret if it already exists. - if err := s.loadState(); err != nil && err != ipn.ErrStateNotExist { - return nil, fmt.Errorf("error loading state from kube Secret: %w", err) - } - // If we are in cert share mode, pre-load existing shared certs. - if s.certShareMode == "rw" || s.certShareMode == "ro" { - sel := s.certSecretSelector() - if err := s.loadCerts(context.Background(), sel); err != nil { - // We will attempt to again retrieve the certs from Secrets when a request for an HTTPS endpoint - // is received. - log.Printf("[unexpected] error loading TLS certs: %v", err) - } - } - if s.certShareMode == "ro" { - go s.runCertReload(context.Background(), logf) - } - return s, nil -} - -func (s *Store) SetDialer(d func(ctx context.Context, network, address string) (net.Conn, error)) { - s.client.SetDialer(d) -} - -func (s *Store) String() string { return "kube.Store" } - -// ReadState implements the StateStore interface. -func (s *Store) ReadState(id ipn.StateKey) ([]byte, error) { - return s.memory.ReadState(ipn.StateKey(sanitizeKey(id))) -} - -// WriteState implements the StateStore interface. -func (s *Store) WriteState(id ipn.StateKey, bs []byte) (err error) { - defer func() { - if err == nil { - s.memory.WriteState(ipn.StateKey(sanitizeKey(id)), bs) - } - }() - return s.updateSecret(map[string][]byte{string(id): bs}, s.secretName) -} - -// WriteTLSCertAndKey writes a TLS cert and key to domain.crt, domain.key fields -// of a Tailscale Kubernetes node's state Secret. -func (s *Store) WriteTLSCertAndKey(domain string, cert, key []byte) (err error) { - if s.certShareMode == "ro" { - log.Printf("[unexpected] TLS cert and key write in read-only mode") - } - if err := dnsname.ValidHostname(domain); err != nil { - return fmt.Errorf("invalid domain name %q: %w", domain, err) - } - secretName := s.secretName - data := map[string][]byte{ - domain + ".crt": cert, - domain + ".key": key, - } - // If we run in cert share mode, cert and key for a DNS name are written - // to a separate Secret. - if s.certShareMode == "rw" { - secretName = domain - data = map[string][]byte{ - keyTLSCert: cert, - keyTLSKey: key, - } - } - if err := s.updateSecret(data, secretName); err != nil { - return fmt.Errorf("error writing TLS cert and key to Secret: %w", err) - } - // TODO(irbekrm): certs for write replicas are currently not - // written to memory to avoid out of sync memory state after - // Ingress resources have been recreated. This means that TLS - // certs for write replicas are retrieved from the Secret on - // each HTTPS request. This is a temporary solution till we - // implement a Secret watch. - if s.certShareMode != "rw" { - s.memory.WriteState(ipn.StateKey(domain+".crt"), cert) - s.memory.WriteState(ipn.StateKey(domain+".key"), key) - } - return nil -} - -// ReadTLSCertAndKey reads a TLS cert and key from memory or from a -// domain-specific Secret. It first checks the in-memory store, if not found in -// memory and running cert store in read-only mode, looks up a Secret. -// Note that write replicas of HA Ingress always retrieve TLS certs from Secrets. -func (s *Store) ReadTLSCertAndKey(domain string) (cert, key []byte, err error) { - if err := dnsname.ValidHostname(domain); err != nil { - return nil, nil, fmt.Errorf("invalid domain name %q: %w", domain, err) - } - certKey := domain + ".crt" - keyKey := domain + ".key" - cert, err = s.memory.ReadState(ipn.StateKey(certKey)) - if err == nil { - key, err = s.memory.ReadState(ipn.StateKey(keyKey)) - if err == nil { - return cert, key, nil - } - } - if s.certShareMode == "" { - return nil, nil, ipn.ErrStateNotExist - } - - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - secret, err := s.client.GetSecret(ctx, domain) - if err != nil { - if kubeclient.IsNotFoundErr(err) { - // TODO(irbekrm): we should return a more specific error - // that wraps ipn.ErrStateNotExist here. - return nil, nil, ipn.ErrStateNotExist - } - return nil, nil, fmt.Errorf("getting TLS Secret %q: %w", domain, err) - } - cert = secret.Data[keyTLSCert] - key = secret.Data[keyTLSKey] - if len(cert) == 0 || len(key) == 0 { - return nil, nil, ipn.ErrStateNotExist - } - // TODO(irbekrm): a read between these two separate writes would - // get a mismatched cert and key. Allow writing both cert and - // key to the memory store in a single, lock-protected operation. - // - // TODO(irbekrm): currently certs for write replicas of HA Ingress get - // retrieved from the cluster Secret on each HTTPS request to avoid a - // situation when after Ingress recreation stale certs are read from - // memory. - // Fix this by watching Secrets to ensure that memory store gets updated - // when Secrets are deleted. - if s.certShareMode == "ro" { - s.memory.WriteState(ipn.StateKey(certKey), cert) - s.memory.WriteState(ipn.StateKey(keyKey), key) - } - return cert, key, nil -} - -func (s *Store) updateSecret(data map[string][]byte, secretName string) (err error) { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer func() { - if err != nil { - if err := s.client.Event(ctx, eventTypeWarning, reasonTailscaleStateUpdateFailed, err.Error()); err != nil { - log.Printf("kubestore: error creating tailscaled state update Event: %v", err) - } - } else { - if err := s.client.Event(ctx, eventTypeNormal, reasonTailscaleStateUpdated, "Successfully updated tailscaled state Secret"); err != nil { - log.Printf("kubestore: error creating tailscaled state Event: %v", err) - } - } - cancel() - }() - secret, err := s.client.GetSecret(ctx, secretName) - if err != nil { - // If the Secret does not exist, create it with the required data. - if kubeclient.IsNotFoundErr(err) && s.canCreateSecret(secretName) { - return s.client.CreateSecret(ctx, &kubeapi.Secret{ - TypeMeta: kubeapi.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: kubeapi.ObjectMeta{ - Name: secretName, - }, - Data: func(m map[string][]byte) map[string][]byte { - d := make(map[string][]byte, len(m)) - for key, val := range m { - d[sanitizeKey(key)] = val - } - return d - }(data), - }) - } - return fmt.Errorf("error getting Secret %s: %w", secretName, err) - } - if s.canPatchSecret(secretName) { - var m []kubeclient.JSONPatch - // If the user has pre-created a Secret with no data, we need to ensure the top level /data field. - if len(secret.Data) == 0 { - m = []kubeclient.JSONPatch{ - { - Op: "add", - Path: "/data", - Value: func(m map[string][]byte) map[string][]byte { - d := make(map[string][]byte, len(m)) - for key, val := range m { - d[sanitizeKey(key)] = val - } - return d - }(data), - }, - } - // If the Secret has data, patch it with the new data. - } else { - for key, val := range data { - m = append(m, kubeclient.JSONPatch{ - Op: "add", - Path: "/data/" + sanitizeKey(key), - Value: val, - }) - } - } - if err := s.client.JSONPatchResource(ctx, secretName, kubeclient.TypeSecrets, m); err != nil { - return fmt.Errorf("error patching Secret %s: %w", secretName, err) - } - return nil - } - // No patch permissions, use UPDATE instead. - for key, val := range data { - mak.Set(&secret.Data, sanitizeKey(key), val) - } - if err := s.client.UpdateSecret(ctx, secret); err != nil { - return fmt.Errorf("error updating Secret %s: %w", s.secretName, err) - } - return nil -} - -func (s *Store) loadState() (err error) { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - secret, err := s.client.GetSecret(ctx, s.secretName) - if err != nil { - if st, ok := err.(*kubeapi.Status); ok && st.Code == 404 { - return ipn.ErrStateNotExist - } - if err := s.client.Event(ctx, eventTypeWarning, reasonTailscaleStateLoadFailed, err.Error()); err != nil { - log.Printf("kubestore: error creating Event: %v", err) - } - return err - } - if err := s.client.Event(ctx, eventTypeNormal, reasonTailscaleStateLoaded, "Successfully loaded tailscaled state from Secret"); err != nil { - log.Printf("kubestore: error creating Event: %v", err) - } - s.memory.LoadFromMap(secret.Data) - return nil -} - -// runCertReload relists and reloads all TLS certs for endpoints shared by this -// node from Secrets other than the state Secret to ensure that renewed certs get eventually loaded. -// It is not critical to reload a cert immediately after -// renewal, so a daily check is acceptable. -// Currently (3/2025) this is only used for the shared HA Ingress certs on 'read' replicas. -// Note that if shared certs are not found in memory on an HTTPS request, we -// do a Secret lookup, so this mechanism does not need to ensure that newly -// added Ingresses' certs get loaded. -func (s *Store) runCertReload(ctx context.Context, logf logger.Logf) { - ticker := time.NewTicker(time.Hour * 24) - defer ticker.Stop() - for { - select { - case <-ctx.Done(): - return - case <-ticker.C: - sel := s.certSecretSelector() - if err := s.loadCerts(ctx, sel); err != nil { - logf("[unexpected] error reloading TLS certs: %v", err) - } - } - } -} - -// loadCerts lists all Secrets matching the provided selector and loads TLS -// certs and keys from those. -func (s *Store) loadCerts(ctx context.Context, sel map[string]string) error { - ss, err := s.client.ListSecrets(ctx, sel) - if err != nil { - return fmt.Errorf("error listing TLS Secrets: %w", err) - } - for _, secret := range ss.Items { - if !hasTLSData(&secret) { - continue - } - // Only load secrets that have valid domain names (ending in .ts.net) - if !strings.HasSuffix(secret.Name, ".ts.net") { - continue - } - s.memory.WriteState(ipn.StateKey(secret.Name)+".crt", secret.Data[keyTLSCert]) - s.memory.WriteState(ipn.StateKey(secret.Name)+".key", secret.Data[keyTLSKey]) - } - return nil -} - -// canCreateSecret returns true if this node should be allowed to create the given -// Secret in its namespace. -func (s *Store) canCreateSecret(secret string) bool { - // Only allow creating the state Secret (and not TLS Secrets). - return secret == s.secretName -} - -// canPatchSecret returns true if this node should be allowed to patch the given -// Secret. -func (s *Store) canPatchSecret(secret string) bool { - // For backwards compatibility reasons, setups where the proxies are not - // given PATCH permissions for state Secrets are allowed. For TLS - // Secrets, we should always have PATCH permissions. - if secret == s.secretName { - return s.canPatch - } - return true -} - -// certSecretSelector returns a label selector that can be used to list all -// Secrets that aren't Tailscale state Secrets and contain TLS certificates for -// HTTPS endpoints that this node serves. -// Currently (3/2025) this only applies to the Kubernetes Operator's ingress -// ProxyGroup. -func (s *Store) certSecretSelector() map[string]string { - if s.podName == "" { - return map[string]string{} - } - p := strings.LastIndex(s.podName, "-") - if p == -1 { - return map[string]string{} - } - pgName := s.podName[:p] - return map[string]string{ - kubetypes.LabelSecretType: "certs", - kubetypes.LabelManaged: "true", - "tailscale.com/proxy-group": pgName, - } -} - -// hasTLSData returns true if the provided Secret contains non-empty TLS cert and key. -func hasTLSData(s *kubeapi.Secret) bool { - return len(s.Data[keyTLSCert]) != 0 && len(s.Data[keyTLSKey]) != 0 -} - -// sanitizeKey converts any value that can be converted to a string into a valid Kubernetes Secret key. -// Valid characters are alphanumeric, -, _, and . -// https://kubernetes.io/docs/concepts/configuration/secret/#restriction-names-data. -func sanitizeKey[T ~string](k T) string { - return strings.Map(func(r rune) rune { - if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-' || r == '_' || r == '.' { - return r - } - return '_' - }, string(k)) -} diff --git a/vendor/tailscale.com/ipn/store/store_aws.go b/vendor/tailscale.com/ipn/store/store_aws.go deleted file mode 100644 index d39e843..0000000 --- a/vendor/tailscale.com/ipn/store/store_aws.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ts_aws || (linux && (arm64 || amd64))) && !ts_omit_aws - -package store - -import ( - "tailscale.com/ipn" - "tailscale.com/ipn/store/awsstore" - "tailscale.com/types/logger" -) - -func init() { - registerAvailableExternalStores = append(registerAvailableExternalStores, registerAWSStore) -} - -func registerAWSStore() { - Register("arn:", func(logf logger.Logf, arg string) (ipn.StateStore, error) { - ssmARN, opts, err := awsstore.ParseARNAndOpts(arg) - if err != nil { - return nil, err - } - return awsstore.New(logf, ssmARN, opts...) - }) -} diff --git a/vendor/tailscale.com/ipn/store/store_kube.go b/vendor/tailscale.com/ipn/store/store_kube.go deleted file mode 100644 index 8941620..0000000 --- a/vendor/tailscale.com/ipn/store/store_kube.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ts_kube || (linux && (arm64 || amd64))) && !ts_omit_kube - -package store - -import ( - "strings" - - "tailscale.com/ipn" - "tailscale.com/ipn/store/kubestore" - "tailscale.com/types/logger" -) - -func init() { - registerAvailableExternalStores = append(registerAvailableExternalStores, registerKubeStore) -} - -func registerKubeStore() { - Register("kube:", func(logf logger.Logf, path string) (ipn.StateStore, error) { - secretName := strings.TrimPrefix(path, "kube:") - return kubestore.New(logf, secretName) - }) -} diff --git a/vendor/tailscale.com/ipn/store/stores.go b/vendor/tailscale.com/ipn/store/stores.go index 1a87fc5..bf175da 100644 --- a/vendor/tailscale.com/ipn/store/stores.go +++ b/vendor/tailscale.com/ipn/store/stores.go @@ -7,10 +7,14 @@ package store import ( "bytes" "encoding/json" + "errors" "fmt" + "iter" + "maps" "os" "path/filepath" "runtime" + "slices" "strings" "sync" @@ -20,26 +24,22 @@ import ( "tailscale.com/paths" "tailscale.com/types/logger" "tailscale.com/util/mak" + "tailscale.com/util/testenv" ) // Provider returns a StateStore for the provided path. // The arg is of the form "prefix:rest", where prefix was previously registered with Register. type Provider func(logf logger.Logf, arg string) (ipn.StateStore, error) -var regOnce sync.Once - -var registerAvailableExternalStores []func() - -func registerDefaultStores() { +func init() { Register("mem:", mem.New) - - for _, f := range registerAvailableExternalStores { - f() - } } var knownStores map[string]Provider +// TPMPrefix is the path prefix used for TPM-encrypted StateStore. +const TPMPrefix = "tpmseal:" + // New returns a StateStore based on the provided arg // and registered stores. // The arg is of the form "prefix:rest", where prefix was previously @@ -53,19 +53,31 @@ var knownStores map[string]Provider // the suffix an AWS ARN for an SSM. // - (Linux-only) if the string begins with "kube:", // the suffix is a Kubernetes secret name +// - (Linux or Windows) if the string begins with "tpmseal:", the suffix is +// filepath that is sealed with the local TPM device. // - In all other cases, the path is treated as a filepath. func New(logf logger.Logf, path string) (ipn.StateStore, error) { - regOnce.Do(registerDefaultStores) for prefix, sf := range knownStores { if strings.HasPrefix(path, prefix) { // We can't strip the prefix here as some NewStoreFunc (like arn:) // expect the prefix. + if prefix == TPMPrefix { + if runtime.GOOS == "windows" { + path = TPMPrefix + TryWindowsAppDataMigration(logf, strings.TrimPrefix(path, TPMPrefix)) + } + if err := maybeMigrateLocalStateFile(logf, path); err != nil { + return nil, fmt.Errorf("failed to migrate existing state file to TPM-sealed format: %w", err) + } + } return sf(logf, path) } } if runtime.GOOS == "windows" { path = TryWindowsAppDataMigration(logf, path) } + if err := maybeMigrateLocalStateFile(logf, path); err != nil { + return nil, fmt.Errorf("failed to migrate existing TPM-sealed state file to plaintext format: %w", err) + } return NewFileStore(logf, path) } @@ -84,6 +96,29 @@ func Register(prefix string, fn Provider) { mak.Set(&knownStores, prefix, fn) } +// RegisterForTest registers a prefix to be used for NewStore in tests. An +// existing registered prefix will be replaced. +func RegisterForTest(t testenv.TB, prefix string, fn Provider) { + if len(prefix) == 0 { + panic("prefix is empty") + } + old := maps.Clone(knownStores) + t.Cleanup(func() { knownStores = old }) + + mak.Set(&knownStores, prefix, fn) +} + +// HasKnownProviderPrefix reports whether path uses one of the registered +// Provider prefixes. +func HasKnownProviderPrefix(path string) bool { + for prefix := range knownStores { + if strings.HasPrefix(path, prefix) { + return true + } + } + return false +} + // TryWindowsAppDataMigration attempts to copy the Windows state file // from its old location to the new location. (Issue 2856) // @@ -186,3 +221,123 @@ func (s *FileStore) WriteState(id ipn.StateKey, bs []byte) error { } return atomicfile.WriteFile(s.path, bs, 0600) } + +func (s *FileStore) All() iter.Seq2[ipn.StateKey, []byte] { + return func(yield func(ipn.StateKey, []byte) bool) { + s.mu.Lock() + defer s.mu.Unlock() + + for k, v := range s.cache { + if !yield(k, v) { + break + } + } + } +} + +// Ensure FileStore implements ExportableStore for migration to/from +// tpm.tpmStore. +var _ ExportableStore = (*FileStore)(nil) + +// ExportableStore is an ipn.StateStore that can export all of its contents. +// This interface is optional to implement, and used for migrating the state +// between different store implementations. +type ExportableStore interface { + ipn.StateStore + + // All returns an iterator over all store keys. Using ReadState or + // WriteState is not safe while iterating and can lead to a deadlock. The + // order of keys in the iterator is not specified and may change between + // runs. + All() iter.Seq2[ipn.StateKey, []byte] +} + +func maybeMigrateLocalStateFile(logf logger.Logf, path string) error { + path, toTPM := strings.CutPrefix(path, TPMPrefix) + + // Extract JSON keys from the file on disk and guess what kind it is. + bs, err := os.ReadFile(path) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil + } + return err + } + var content map[string]any + if err := json.Unmarshal(bs, &content); err != nil { + return fmt.Errorf("failed to unmarshal %q: %w", path, err) + } + keys := slices.Sorted(maps.Keys(content)) + tpmKeys := []string{"key", "nonce", "data"} + slices.Sort(tpmKeys) + // TPM-sealed files will have exactly these keys. + existingFileSealed := slices.Equal(keys, tpmKeys) + // Plaintext files for nodes that registered at least once will have this + // key, plus other dynamic ones. + _, existingFilePlaintext := content["_machinekey"] + isTPM := existingFileSealed && !existingFilePlaintext + + if isTPM == toTPM { + // No migration needed. + return nil + } + + newTPMStore, ok := knownStores[TPMPrefix] + if !ok { + return errors.New("this build does not support TPM integration") + } + + // Open from (old format) and to (new format) stores for migration. The + // "to" store will be at tmpPath. + var from, to ipn.StateStore + tmpPath := path + ".tmp" + if toTPM { + // Migrate plaintext file to be TPM-sealed. + from, err = NewFileStore(logf, path) + if err != nil { + return fmt.Errorf("NewFileStore(%q): %w", path, err) + } + to, err = newTPMStore(logf, TPMPrefix+tmpPath) + if err != nil { + return fmt.Errorf("newTPMStore(%q): %w", tmpPath, err) + } + } else { + // Migrate TPM-selaed file to plaintext. + from, err = newTPMStore(logf, TPMPrefix+path) + if err != nil { + return fmt.Errorf("newTPMStore(%q): %w", path, err) + } + to, err = NewFileStore(logf, tmpPath) + if err != nil { + return fmt.Errorf("NewFileStore(%q): %w", tmpPath, err) + } + } + defer os.Remove(tmpPath) + + fromExp, ok := from.(ExportableStore) + if !ok { + return fmt.Errorf("%T does not implement the exportableStore interface", from) + } + + // Copy all the items. This is pretty inefficient, because both stores + // write the file to disk for each WriteState, but that's ok for a one-time + // migration. + for k, v := range fromExp.All() { + if err := to.WriteState(k, v); err != nil { + return err + } + } + + // Finally, overwrite the state file with the new one we created at + // tmpPath. + if err := atomicfile.Rename(tmpPath, path); err != nil { + return err + } + + if toTPM { + logf("migrated %q from plaintext to TPM-sealed format", path) + } else { + logf("migrated %q from TPM-sealed to plaintext format", path) + } + return nil +} diff --git a/vendor/tailscale.com/kube/kubeapi/api.go b/vendor/tailscale.com/kube/kubeapi/api.go deleted file mode 100644 index e62bd6e..0000000 --- a/vendor/tailscale.com/kube/kubeapi/api.go +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package kubeapi contains Kubernetes API types for internal consumption. -// These types are split into a separate package for consumption of -// non-Kubernetes shared libraries and binaries. Be mindful of not increasing -// dependency size for those consumers when adding anything new here. -package kubeapi - -import ( - "time" -) - -// Note: The API types are copied from k8s.io/api{,machinery} to not introduce a -// module dependency on the Kubernetes API as it pulls in many more dependencies. - -// TypeMeta describes an individual object in an API response or request with -// strings representing the type of the object and its API schema version. -// Structures that are versioned or persisted should inline TypeMeta. -type TypeMeta struct { - // Kind is a string value representing the REST resource this object represents. - // Servers may infer this from the endpoint the client submits requests to. - // Cannot be updated. - // In CamelCase. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - // +optional - Kind string `json:"kind,omitempty"` - - // APIVersion defines the versioned schema of this representation of an object. - // Servers should convert recognized schemas to the latest internal value, and - // may reject unrecognized values. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - // +optional - APIVersion string `json:"apiVersion,omitempty"` -} - -// ObjectMeta is metadata that all persisted resources must have, which -// includes all objects users must create. -type ObjectMeta struct { - // Name must be unique within a namespace. Is required when creating resources, although - // some resources may allow a client to request the generation of an appropriate name - // automatically. Name is primarily intended for creation idempotence and configuration - // definition. - // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names - // +optional - Name string `json:"name"` - - // Namespace defines the space within which each name must be unique. An empty namespace is - // equivalent to the "default" namespace, but "default" is the canonical representation. - // Not all objects are required to be scoped to a namespace - the value of this field for - // those objects will be empty. - // - // Must be a DNS_LABEL. - // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/namespaces - // +optional - Namespace string `json:"namespace"` - - // UID is the unique in time and space value for this object. It is typically generated by - // the server on successful creation of a resource and is not allowed to change on PUT - // operations. - // - // Populated by the system. - // Read-only. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids - // +optional - UID string `json:"uid,omitempty"` - - // An opaque value that represents the internal version of this object that can - // be used by clients to determine when objects have changed. May be used for optimistic - // concurrency, change detection, and the watch operation on a resource or set of resources. - // Clients must treat these values as opaque and passed unmodified back to the server. - // They may only be valid for a particular resource or set of resources. - // - // Populated by the system. - // Read-only. - // Value must be treated as opaque by clients and . - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency - // +optional - ResourceVersion string `json:"resourceVersion,omitempty"` - - // A sequence number representing a specific generation of the desired state. - // Populated by the system. Read-only. - // +optional - Generation int64 `json:"generation,omitempty"` - - // CreationTimestamp is a timestamp representing the server time when this object was - // created. It is not guaranteed to be set in happens-before order across separate operations. - // Clients may not set this value. It is represented in RFC3339 form and is in UTC. - // - // Populated by the system. - // Read-only. - // Null for lists. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - CreationTimestamp time.Time `json:"creationTimestamp,omitempty"` - - // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This - // field is set by the server when a graceful deletion is requested by the user, and is not - // directly settable by a client. The resource is expected to be deleted (no longer visible - // from resource lists, and not reachable by name) after the time in this field, once the - // finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. - // Once the deletionTimestamp is set, this value may not be unset or be set further into the - // future, although it may be shortened or the resource may be deleted prior to this time. - // For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react - // by sending a graceful termination signal to the containers in the pod. After that 30 seconds, - // the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, - // remove the pod from the API. In the presence of network partitions, this object may still - // exist after this timestamp, until an administrator or automated process can determine the - // resource is fully terminated. - // If not set, graceful deletion of the object has not been requested. - // - // Populated by the system when a graceful deletion is requested. - // Read-only. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` - - // Number of seconds allowed for this object to gracefully terminate before - // it will be removed from the system. Only set when deletionTimestamp is also set. - // May only be shortened. - // Read-only. - // +optional - DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty"` - - // Map of string keys and values that can be used to organize and categorize - // (scope and select) objects. May match selectors of replication controllers - // and services. - // More info: http://kubernetes.io/docs/user-guide/labels - // +optional - Labels map[string]string `json:"labels,omitempty"` - - // Annotations is an unstructured key value map stored with a resource that may be - // set by external tools to store and retrieve arbitrary metadata. They are not - // queryable and should be preserved when modifying objects. - // More info: http://kubernetes.io/docs/user-guide/annotations - // +optional - Annotations map[string]string `json:"annotations,omitempty"` -} - -// Secret holds secret data of a certain type. The total bytes of the values -// in the Data field must be less than MaxSecretSize bytes. -type Secret struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata"` - - // Data contains the secret data. Each key must consist of alphanumeric - // characters, '-', '_' or '.'. The serialized form of the secret data is a - // base64 encoded string, representing the arbitrary (possibly non-string) - // data value here. Described in https://tools.ietf.org/html/rfc4648#section-4 - // +optional - Data map[string][]byte `json:"data,omitempty"` -} - -// SecretList is a list of Secret objects. -type SecretList struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata"` - - Items []Secret `json:"items,omitempty"` -} - -// Event contains a subset of fields from corev1.Event. -// https://github.com/kubernetes/api/blob/6cc44b8953ae704d6d9ec2adf32e7ae19199ea9f/core/v1/types.go#L7034 -// It is copied here to avoid having to import kube libraries. -type Event struct { - TypeMeta `json:",inline"` - ObjectMeta `json:"metadata"` - Message string `json:"message,omitempty"` - Reason string `json:"reason,omitempty"` - Source EventSource `json:"source,omitempty"` // who is emitting this Event - Type string `json:"type,omitempty"` // Normal or Warning - // InvolvedObject is the subject of the Event. `kubectl describe` will, for most object types, display any - // currently present cluster Events matching the object (but you probably want to set UID for this to work). - InvolvedObject ObjectReference `json:"involvedObject"` - Count int32 `json:"count,omitempty"` // how many times Event was observed - FirstTimestamp time.Time `json:"firstTimestamp,omitempty"` - LastTimestamp time.Time `json:"lastTimestamp,omitempty"` -} - -// EventSource includes a subset of fields from corev1.EventSource. -// https://github.com/kubernetes/api/blob/6cc44b8953ae704d6d9ec2adf32e7ae19199ea9f/core/v1/types.go#L7007 -// It is copied here to avoid having to import kube libraries. -type EventSource struct { - // Component is the name of the component that is emitting the Event. - Component string `json:"component,omitempty"` -} - -// ObjectReference contains a subset of fields from corev1.ObjectReference. -// https://github.com/kubernetes/api/blob/6cc44b8953ae704d6d9ec2adf32e7ae19199ea9f/core/v1/types.go#L6902 -// It is copied here to avoid having to import kube libraries. -type ObjectReference struct { - // Kind of the referent. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - // +optional - Kind string `json:"kind,omitempty"` - // Namespace of the referent. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ - // +optional - Namespace string `json:"namespace,omitempty"` - // Name of the referent. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - // +optional - Name string `json:"name,omitempty"` - // UID of the referent. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids - // +optional - UID string `json:"uid,omitempty"` - // API version of the referent. - // +optional - APIVersion string `json:"apiVersion,omitempty"` -} - -// Status is a return value for calls that don't return other objects. -type Status struct { - TypeMeta `json:",inline"` - // Status of the operation. - // One of: "Success" or "Failure". - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - Status string `json:"status,omitempty"` - - // A human-readable description of the status of this operation. - // +optional - Message string `json:"message,omitempty"` - - // A machine-readable description of why this operation is in the - // "Failure" status. If this value is empty there - // is no information available. A Reason clarifies an HTTP status - // code but does not override it. - // +optional - Reason string `json:"reason,omitempty"` - - // Extended data associated with the reason. Each reason may define its - // own extended details. This field is optional and the data returned - // is not guaranteed to conform to any schema except that defined by - // the reason type. - // +optional - Details *struct { - Name string `json:"name,omitempty"` - Kind string `json:"kind,omitempty"` - } `json:"details,omitempty"` - - // Suggested HTTP return code for this status, 0 if not set. - // +optional - Code int `json:"code,omitempty"` -} - -func (s Status) Error() string { - return s.Message -} diff --git a/vendor/tailscale.com/kube/kubeclient/client.go b/vendor/tailscale.com/kube/kubeclient/client.go deleted file mode 100644 index 332b211..0000000 --- a/vendor/tailscale.com/kube/kubeclient/client.go +++ /dev/null @@ -1,513 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package kubeclient provides a client to interact with Kubernetes. -// This package is Tailscale-internal and not meant for external consumption. -// Further, the API should not be considered stable. -// Client is split into a separate package for consumption of -// non-Kubernetes shared libraries and binaries. Be mindful of not increasing -// dependency size for those consumers when adding anything new here. -package kubeclient - -import ( - "bytes" - "context" - "crypto/tls" - "crypto/x509" - "encoding/json" - "fmt" - "io" - "log" - "net" - "net/http" - "net/url" - "os" - "path/filepath" - "strings" - "sync" - "time" - - "tailscale.com/kube/kubeapi" - "tailscale.com/tstime" - "tailscale.com/util/multierr" -) - -const ( - saPath = "/var/run/secrets/kubernetes.io/serviceaccount" - defaultURL = "https://kubernetes.default.svc" - - TypeSecrets = "secrets" - typeEvents = "events" -) - -// rootPathForTests is set by tests to override the root path to the -// service account directory. -var rootPathForTests string - -// SetRootPathForTesting sets the path to the service account directory. -func SetRootPathForTesting(p string) { - rootPathForTests = p -} - -func readFile(n string) ([]byte, error) { - if rootPathForTests != "" { - return os.ReadFile(filepath.Join(rootPathForTests, saPath, n)) - } - return os.ReadFile(filepath.Join(saPath, n)) -} - -// Client handles connections to Kubernetes. -// It expects to be run inside a cluster. -type Client interface { - GetSecret(context.Context, string) (*kubeapi.Secret, error) - ListSecrets(context.Context, map[string]string) (*kubeapi.SecretList, error) - UpdateSecret(context.Context, *kubeapi.Secret) error - CreateSecret(context.Context, *kubeapi.Secret) error - // Event attempts to ensure an event with the specified options associated with the Pod in which we are - // currently running. This is best effort - if the client is not able to create events, this operation will be a - // no-op. If there is already an Event with the given reason for the current Pod, it will get updated (only - // count and timestamp are expected to change), else a new event will be created. - Event(_ context.Context, typ, reason, msg string) error - StrategicMergePatchSecret(context.Context, string, *kubeapi.Secret, string) error - JSONPatchResource(_ context.Context, resourceName string, resourceType string, patches []JSONPatch) error - CheckSecretPermissions(context.Context, string) (bool, bool, error) - SetDialer(dialer func(context.Context, string, string) (net.Conn, error)) - SetURL(string) -} - -type client struct { - mu sync.Mutex - name string - url string - podName string - podUID string - ns string // Pod namespace - client *http.Client - token string - tokenExpiry time.Time - cl tstime.Clock - // hasEventsPerms is true if client can emit Events for the Pod in which it runs. If it is set to false any - // calls to Events() will be a no-op. - hasEventsPerms bool - // kubeAPIRequest sends a request to the kube API server. It can set to a fake in tests. - kubeAPIRequest kubeAPIRequestFunc -} - -// New returns a new client -func New(name string) (Client, error) { - ns, err := readFile("namespace") - if err != nil { - return nil, err - } - caCert, err := readFile("ca.crt") - if err != nil { - return nil, err - } - cp := x509.NewCertPool() - if ok := cp.AppendCertsFromPEM(caCert); !ok { - return nil, fmt.Errorf("kube: error in creating root cert pool") - } - c := &client{ - url: defaultURL, - ns: string(ns), - name: name, - cl: tstime.DefaultClock{}, - client: &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - RootCAs: cp, - }, - }, - }, - } - c.kubeAPIRequest = newKubeAPIRequest(c) - c.setEventPerms() - return c, nil -} - -// SetURL sets the URL to use for the Kubernetes API. -// This is used only for testing. -func (c *client) SetURL(url string) { - c.url = url -} - -// SetDialer sets the dialer to use when establishing a connection -// to the Kubernetes API server. -func (c *client) SetDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) { - c.client.Transport.(*http.Transport).DialContext = dialer -} - -func (c *client) expireToken() { - c.mu.Lock() - defer c.mu.Unlock() - c.tokenExpiry = c.cl.Now() -} - -func (c *client) getOrRenewToken() (string, error) { - c.mu.Lock() - defer c.mu.Unlock() - tk, te := c.token, c.tokenExpiry - if c.cl.Now().Before(te) { - return tk, nil - } - - tkb, err := readFile("token") - if err != nil { - return "", err - } - c.token = string(tkb) - c.tokenExpiry = c.cl.Now().Add(30 * time.Minute) - return c.token, nil -} - -func getError(resp *http.Response) error { - if resp.StatusCode == 200 || resp.StatusCode == 201 { - // These are the only success codes returned by the Kubernetes API. - // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#http-status-codes - return nil - } - st := &kubeapi.Status{} - if err := json.NewDecoder(resp.Body).Decode(st); err != nil { - return err - } - return st -} - -func setHeader(key, value string) func(*http.Request) { - return func(req *http.Request) { - req.Header.Set(key, value) - } -} - -type kubeAPIRequestFunc func(ctx context.Context, method, url string, in, out any, opts ...func(*http.Request)) error - -// newKubeAPIRequest returns a function that can perform an HTTP request to the Kubernetes API. -func newKubeAPIRequest(c *client) kubeAPIRequestFunc { - // If in is not nil, it is expected to be a JSON-encodable object and will be - // sent as the request body. - // If out is not nil, it is expected to be a pointer to an object that can be - // decoded from JSON. - // If the request fails with a 401, the token is expired and a new one is - // requested. - f := func(ctx context.Context, method, url string, in, out any, opts ...func(*http.Request)) error { - req, err := c.newRequest(ctx, method, url, in) - if err != nil { - return err - } - for _, opt := range opts { - opt(req) - } - resp, err := c.client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - if err := getError(resp); err != nil { - if st, ok := err.(*kubeapi.Status); ok && st.Code == 401 { - c.expireToken() - } - return err - } - if out != nil { - return json.NewDecoder(resp.Body).Decode(out) - } - return nil - } - return f -} - -func (c *client) newRequest(ctx context.Context, method, url string, in any) (*http.Request, error) { - tk, err := c.getOrRenewToken() - if err != nil { - return nil, err - } - var body io.Reader - if in != nil { - switch in := in.(type) { - case []byte: - body = bytes.NewReader(in) - default: - var b bytes.Buffer - if err := json.NewEncoder(&b).Encode(in); err != nil { - return nil, err - } - body = &b - } - } - req, err := http.NewRequestWithContext(ctx, method, url, body) - if err != nil { - return nil, err - } - if body != nil { - req.Header.Add("Content-Type", "application/json") - } - req.Header.Add("Accept", "application/json") - req.Header.Add("Authorization", "Bearer "+tk) - return req, nil -} - -// GetSecret fetches the secret from the Kubernetes API. -func (c *client) GetSecret(ctx context.Context, name string) (*kubeapi.Secret, error) { - s := &kubeapi.Secret{Data: make(map[string][]byte)} - if err := c.kubeAPIRequest(ctx, "GET", c.resourceURL(name, TypeSecrets, ""), nil, s); err != nil { - return nil, err - } - return s, nil -} - -// ListSecrets fetches the secret from the Kubernetes API. -func (c *client) ListSecrets(ctx context.Context, selector map[string]string) (*kubeapi.SecretList, error) { - sl := new(kubeapi.SecretList) - s := make([]string, 0, len(selector)) - for key, val := range selector { - s = append(s, key+"="+url.QueryEscape(val)) - } - ss := strings.Join(s, ",") - if err := c.kubeAPIRequest(ctx, "GET", c.resourceURL("", TypeSecrets, ss), nil, sl); err != nil { - return nil, err - } - return sl, nil -} - -// CreateSecret creates a secret in the Kubernetes API. -func (c *client) CreateSecret(ctx context.Context, s *kubeapi.Secret) error { - s.Namespace = c.ns - return c.kubeAPIRequest(ctx, "POST", c.resourceURL("", TypeSecrets, ""), s, nil) -} - -// UpdateSecret updates a secret in the Kubernetes API. -func (c *client) UpdateSecret(ctx context.Context, s *kubeapi.Secret) error { - return c.kubeAPIRequest(ctx, "PUT", c.resourceURL(s.Name, TypeSecrets, ""), s, nil) -} - -// JSONPatch is a JSON patch operation. -// It currently (2024-11-15) only supports "add", "remove" and "replace" operations. -// -// https://tools.ietf.org/html/rfc6902 -type JSONPatch struct { - Op string `json:"op"` - Path string `json:"path"` - Value any `json:"value,omitempty"` -} - -// JSONPatchResource updates a resource in the Kubernetes API using a JSON patch. -// It currently (2024-11-15) only supports "add", "remove" and "replace" operations. -func (c *client) JSONPatchResource(ctx context.Context, name, typ string, patches []JSONPatch) error { - for _, p := range patches { - if p.Op != "remove" && p.Op != "add" && p.Op != "replace" { - return fmt.Errorf("unsupported JSON patch operation: %q", p.Op) - } - } - return c.kubeAPIRequest(ctx, "PATCH", c.resourceURL(name, typ, ""), patches, nil, setHeader("Content-Type", "application/json-patch+json")) -} - -// StrategicMergePatchSecret updates a secret in the Kubernetes API using a -// strategic merge patch. -// If a fieldManager is provided, it will be used to track the patch. -func (c *client) StrategicMergePatchSecret(ctx context.Context, name string, s *kubeapi.Secret, fieldManager string) error { - surl := c.resourceURL(name, TypeSecrets, "") - if fieldManager != "" { - uv := url.Values{ - "fieldManager": {fieldManager}, - } - surl += "?" + uv.Encode() - } - s.Namespace = c.ns - s.Name = name - return c.kubeAPIRequest(ctx, "PATCH", surl, s, nil, setHeader("Content-Type", "application/strategic-merge-patch+json")) -} - -// Event tries to ensure an Event associated with the Pod in which we are running. It is best effort - the event will be -// created if the kube client on startup was able to determine the name and UID of this Pod from POD_NAME,POD_UID env -// vars and if permissions check for event creation succeeded. Events are keyed on opts.Reason- if an Event for the -// current Pod with that reason already exists, its count and first timestamp will be updated, else a new Event will be -// created. -func (c *client) Event(ctx context.Context, typ, reason, msg string) error { - if !c.hasEventsPerms { - return nil - } - name := c.nameForEvent(reason) - ev, err := c.getEvent(ctx, name) - now := c.cl.Now() - if err != nil { - if !IsNotFoundErr(err) { - return err - } - // Event not found - create it - ev := kubeapi.Event{ - ObjectMeta: kubeapi.ObjectMeta{ - Name: name, - Namespace: c.ns, - }, - Type: typ, - Reason: reason, - Message: msg, - Source: kubeapi.EventSource{ - Component: c.name, - }, - InvolvedObject: kubeapi.ObjectReference{ - Name: c.podName, - Namespace: c.ns, - UID: c.podUID, - Kind: "Pod", - APIVersion: "v1", - }, - - FirstTimestamp: now, - LastTimestamp: now, - Count: 1, - } - return c.kubeAPIRequest(ctx, "POST", c.resourceURL("", typeEvents, ""), &ev, nil) - } - // If the Event already exists, we patch its count and last timestamp. This ensures that when users run 'kubectl - // describe pod...', they see the event just once (but with a message of how many times it has appeared over - // last timestamp - first timestamp period of time). - count := ev.Count + 1 - countPatch := JSONPatch{ - Op: "replace", - Value: count, - Path: "/count", - } - tsPatch := JSONPatch{ - Op: "replace", - Value: now, - Path: "/lastTimestamp", - } - return c.JSONPatchResource(ctx, name, typeEvents, []JSONPatch{countPatch, tsPatch}) -} - -// CheckSecretPermissions checks the secret access permissions of the current -// pod. It returns an error if the basic permissions tailscale needs are -// missing, and reports whether the patch and create permissions are additionally present. -// -// Errors encountered during the access checking process are logged, but ignored -// so that the pod tries to fail alive if the permissions exist and there's just -// something wrong with SelfSubjectAccessReviews. There shouldn't be, pods -// should always be able to use SSARs to assess their own permissions, but since -// we didn't use to check permissions this way we'll be cautious in case some -// old version of k8s deviates from the current behavior. -func (c *client) CheckSecretPermissions(ctx context.Context, secretName string) (canPatch, canCreate bool, err error) { - var errs []error - for _, verb := range []string{"get", "update"} { - ok, err := c.checkPermission(ctx, verb, TypeSecrets, secretName) - if err != nil { - log.Printf("error checking %s permission on secret %s: %v", verb, secretName, err) - } else if !ok { - errs = append(errs, fmt.Errorf("missing %s permission on secret %q", verb, secretName)) - } - } - if len(errs) > 0 { - return false, false, multierr.New(errs...) - } - canPatch, err = c.checkPermission(ctx, "patch", TypeSecrets, secretName) - if err != nil { - log.Printf("error checking patch permission on secret %s: %v", secretName, err) - return false, false, nil - } - canCreate, err = c.checkPermission(ctx, "create", TypeSecrets, secretName) - if err != nil { - log.Printf("error checking create permission on secret %s: %v", secretName, err) - return false, false, nil - } - return canPatch, canCreate, nil -} - -func IsNotFoundErr(err error) bool { - if st, ok := err.(*kubeapi.Status); ok && st.Code == 404 { - return true - } - return false -} - -// setEventPerms checks whether this client will be able to write tailscaled Events to its Pod and updates the state -// accordingly. If it determines that the client can not write Events, any subsequent calls to client.Event will be a -// no-op. -func (c *client) setEventPerms() { - name := os.Getenv("POD_NAME") - uid := os.Getenv("POD_UID") - hasPerms := false - defer func() { - c.podName = name - c.podUID = uid - c.hasEventsPerms = hasPerms - if !hasPerms { - log.Printf(`kubeclient: this client is not able to write tailscaled Events to the Pod in which it is running. - To help with future debugging you can make it able write Events by giving it get,create,patch permissions for Events in the Pod namespace - and setting POD_NAME, POD_UID env vars for the Pod.`) - } - }() - if name == "" || uid == "" { - return - } - for _, verb := range []string{"get", "create", "patch"} { - can, err := c.checkPermission(context.Background(), verb, typeEvents, "") - if err != nil { - log.Printf("kubeclient: error checking Events permissions: %v", err) - return - } - if !can { - return - } - } - hasPerms = true - return -} - -// checkPermission reports whether the current pod has permission to use the given verb (e.g. get, update, patch, -// create) on the given resource type. If name is not an empty string, will check the check will be for resource with -// the given name only. -func (c *client) checkPermission(ctx context.Context, verb, typ, name string) (bool, error) { - ra := map[string]any{ - "namespace": c.ns, - "verb": verb, - "resource": typ, - } - if name != "" { - ra["name"] = name - } - sar := map[string]any{ - "apiVersion": "authorization.k8s.io/v1", - "kind": "SelfSubjectAccessReview", - "spec": map[string]any{ - "resourceAttributes": ra, - }, - } - var res struct { - Status struct { - Allowed bool `json:"allowed"` - } `json:"status"` - } - url := c.url + "/apis/authorization.k8s.io/v1/selfsubjectaccessreviews" - if err := c.kubeAPIRequest(ctx, "POST", url, sar, &res); err != nil { - return false, err - } - return res.Status.Allowed, nil -} - -// resourceURL returns a URL that can be used to interact with the given resource type and, if name is not empty string, -// the named resource of that type. -// Note that this only works for core/v1 resource types. -func (c *client) resourceURL(name, typ, sel string) string { - if name == "" { - url := fmt.Sprintf("%s/api/v1/namespaces/%s/%s", c.url, c.ns, typ) - if sel != "" { - url += "?labelSelector=" + sel - } - return url - } - return fmt.Sprintf("%s/api/v1/namespaces/%s/%s/%s", c.url, c.ns, typ, name) -} - -// nameForEvent returns a name for the Event that uniquely identifies Event with that reason for the current Pod. -func (c *client) nameForEvent(reason string) string { - return fmt.Sprintf("%s.%s.%s", c.podName, c.podUID, strings.ToLower(reason)) -} - -// getEvent fetches the event from the Kubernetes API. -func (c *client) getEvent(ctx context.Context, name string) (*kubeapi.Event, error) { - e := &kubeapi.Event{} - if err := c.kubeAPIRequest(ctx, "GET", c.resourceURL(name, typeEvents, ""), nil, e); err != nil { - return nil, err - } - return e, nil -} diff --git a/vendor/tailscale.com/kube/kubeclient/fake_client.go b/vendor/tailscale.com/kube/kubeclient/fake_client.go deleted file mode 100644 index c21dc2b..0000000 --- a/vendor/tailscale.com/kube/kubeclient/fake_client.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package kubeclient - -import ( - "context" - "net" - - "tailscale.com/kube/kubeapi" -) - -var _ Client = &FakeClient{} - -type FakeClient struct { - GetSecretImpl func(context.Context, string) (*kubeapi.Secret, error) - CheckSecretPermissionsImpl func(ctx context.Context, name string) (bool, bool, error) - CreateSecretImpl func(context.Context, *kubeapi.Secret) error - UpdateSecretImpl func(context.Context, *kubeapi.Secret) error - JSONPatchResourceImpl func(context.Context, string, string, []JSONPatch) error - ListSecretsImpl func(context.Context, map[string]string) (*kubeapi.SecretList, error) -} - -func (fc *FakeClient) CheckSecretPermissions(ctx context.Context, name string) (bool, bool, error) { - return fc.CheckSecretPermissionsImpl(ctx, name) -} -func (fc *FakeClient) GetSecret(ctx context.Context, name string) (*kubeapi.Secret, error) { - return fc.GetSecretImpl(ctx, name) -} -func (fc *FakeClient) SetURL(_ string) {} -func (fc *FakeClient) SetDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) { -} -func (fc *FakeClient) StrategicMergePatchSecret(context.Context, string, *kubeapi.Secret, string) error { - return nil -} -func (fc *FakeClient) Event(context.Context, string, string, string) error { - return nil -} - -func (fc *FakeClient) JSONPatchResource(ctx context.Context, resource, name string, patches []JSONPatch) error { - return fc.JSONPatchResourceImpl(ctx, resource, name, patches) -} -func (fc *FakeClient) UpdateSecret(ctx context.Context, secret *kubeapi.Secret) error { - return fc.UpdateSecretImpl(ctx, secret) -} -func (fc *FakeClient) CreateSecret(ctx context.Context, secret *kubeapi.Secret) error { - return fc.CreateSecretImpl(ctx, secret) -} -func (fc *FakeClient) ListSecrets(ctx context.Context, selector map[string]string) (*kubeapi.SecretList, error) { - if fc.ListSecretsImpl != nil { - return fc.ListSecretsImpl(ctx, selector) - } - return nil, nil -} diff --git a/vendor/tailscale.com/kube/kubetypes/grants.go b/vendor/tailscale.com/kube/kubetypes/grants.go index 4dc278f..50d7d76 100644 --- a/vendor/tailscale.com/kube/kubetypes/grants.go +++ b/vendor/tailscale.com/kube/kubetypes/grants.go @@ -38,8 +38,12 @@ type KubernetesCapRule struct { // Default is to fail open. // The field name matches `EnforceRecorder` field with equal semantics for Tailscale SSH // session recorder. - // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-acls + // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file EnforceRecorder bool `json:"enforceRecorder,omitempty"` + // EnableEvents defines whether kubectl API request events (beta) + // should be recorded or not. + // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file + EnableEvents bool `json:"enableEvents,omitempty"` } // ImpersonateRule defines how a request from the tailnet identity matching diff --git a/vendor/tailscale.com/kube/kubetypes/types.go b/vendor/tailscale.com/kube/kubetypes/types.go index e54e1c9..44b01fe 100644 --- a/vendor/tailscale.com/kube/kubetypes/types.go +++ b/vendor/tailscale.com/kube/kubetypes/types.go @@ -3,21 +3,25 @@ package kubetypes +import "fmt" + const ( // Hostinfo App values for the Tailscale Kubernetes Operator components. - AppOperator = "k8s-operator" - AppAPIServerProxy = "k8s-operator-proxy" - AppIngressProxy = "k8s-operator-ingress-proxy" - AppIngressResource = "k8s-operator-ingress-resource" - AppEgressProxy = "k8s-operator-egress-proxy" - AppConnector = "k8s-operator-connector-resource" - AppProxyGroupEgress = "k8s-operator-proxygroup-egress" - AppProxyGroupIngress = "k8s-operator-proxygroup-ingress" + AppOperator = "k8s-operator" + AppInProcessAPIServerProxy = "k8s-operator-proxy" + AppIngressProxy = "k8s-operator-ingress-proxy" + AppIngressResource = "k8s-operator-ingress-resource" + AppEgressProxy = "k8s-operator-egress-proxy" + AppConnector = "k8s-operator-connector-resource" + AppProxyGroupEgress = "k8s-operator-proxygroup-egress" + AppProxyGroupIngress = "k8s-operator-proxygroup-ingress" + AppProxyGroupKubeAPIServer = "k8s-operator-proxygroup-kube-apiserver" // Clientmetrics for Tailscale Kubernetes Operator components MetricIngressProxyCount = "k8s_ingress_proxies" // L3 MetricIngressResourceCount = "k8s_ingress_resources" // L7 MetricIngressPGResourceCount = "k8s_ingress_pg_resources" // L7 on ProxyGroup + MetricServicePGResourceCount = "k8s_service_pg_resources" // L3 on ProxyGroup MetricEgressProxyCount = "k8s_egress_proxies" MetricConnectorResourceCount = "k8s_connector_resources" MetricConnectorWithSubnetRouterCount = "k8s_connector_subnetrouter_resources" @@ -28,6 +32,7 @@ const ( MetricEgressServiceCount = "k8s_egress_service_resources" MetricProxyGroupEgressCount = "k8s_proxygroup_egress_resources" MetricProxyGroupIngressCount = "k8s_proxygroup_ingress_resources" + MetricProxyGroupAPIServerCount = "k8s_proxygroup_kube_apiserver_resources" // Keys that containerboot writes to state file that can be used to determine its state. // fields set in Tailscale state Secret. These are mostly used by the Tailscale Kubernetes operator to determine @@ -51,4 +56,29 @@ const ( LabelManaged = "tailscale.com/managed" LabelSecretType = "tailscale.com/secret-type" // "config", "state" "certs" + + LabelSecretTypeConfig = "config" + LabelSecretTypeState = "state" + LabelSecretTypeCerts = "certs" + + KubeAPIServerConfigFile = "config.hujson" + APIServerProxyModeAuth APIServerProxyMode = "auth" + APIServerProxyModeNoAuth APIServerProxyMode = "noauth" ) + +// APIServerProxyMode specifies whether the API server proxy will add +// impersonation headers to requests based on the caller's Tailscale identity. +// May be "auth" or "noauth". +type APIServerProxyMode string + +func (a *APIServerProxyMode) UnmarshalJSON(data []byte) error { + switch string(data) { + case `"auth"`: + *a = APIServerProxyModeAuth + case `"noauth"`: + *a = APIServerProxyModeNoAuth + default: + return fmt.Errorf("unknown APIServerProxyMode %q", data) + } + return nil +} diff --git a/vendor/tailscale.com/licenses/android.md b/vendor/tailscale.com/licenses/android.md index 37961b7..4dc8e6c 100644 --- a/vendor/tailscale.com/licenses/android.md +++ b/vendor/tailscale.com/licenses/android.md @@ -9,72 +9,43 @@ Client][]. See also the dependencies in the [Tailscale CLI][]. - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.1.0/LICENSE)) - - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.29.5/config/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.17.58/credentials/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.16.27/feature/ec2/imds/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.3.31/internal/configsources/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.6.31/internal/endpoints/v2/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/ini](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/ini) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/ini/v1.8.2/internal/ini/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/internal/sync/singleflight/LICENSE)) - - [github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/accept-encoding/v1.12.2/service/internal/accept-encoding/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/presigned-url/v1.12.12/service/internal/presigned-url/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/ssm](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssm) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.44.7/service/ssm/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sso](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sso) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sso/v1.24.14/service/sso/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssooidc) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssooidc/v1.28.13/service/ssooidc/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sts) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.33.13/service/sts/LICENSE.txt)) - - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.22.2/LICENSE)) - - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.22.2/internal/sync/singleflight/LICENSE)) - - [github.com/coreos/go-iptables/iptables](https://pkg.go.dev/github.com/coreos/go-iptables/iptables) ([Apache-2.0](https://github.com/coreos/go-iptables/blob/65c67c9f46e6/LICENSE)) + - [github.com/creachadair/msync/trigger](https://pkg.go.dev/github.com/creachadair/msync/trigger) ([BSD-3-Clause](https://github.com/creachadair/msync/blob/v0.7.1/LICENSE)) - [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.6.0/LICENSE)) - [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.7.0/LICENSE)) - [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.18.0/LICENSE)) - - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/d3c622f1b874/LICENSE)) - - [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/76236955d466/LICENSE)) + - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/ebf49471dced/LICENSE)) - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE)) - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.2/LICENSE)) - - [github.com/google/nftables](https://pkg.go.dev/github.com/google/nftables) ([Apache-2.0](https://github.com/google/nftables/blob/5e242ec57806/LICENSE)) + - [github.com/google/go-tpm](https://pkg.go.dev/github.com/google/go-tpm) ([Apache-2.0](https://github.com/google/go-tpm/blob/v0.9.4/LICENSE)) - [github.com/hdevalence/ed25519consensus](https://pkg.go.dev/github.com/hdevalence/ed25519consensus) ([BSD-3-Clause](https://github.com/hdevalence/ed25519consensus/blob/v0.2.0/LICENSE)) - - [github.com/illarion/gonotify/v3](https://pkg.go.dev/github.com/illarion/gonotify/v3) ([MIT](https://github.com/illarion/gonotify/blob/v3.0.2/LICENSE)) - [github.com/insomniacslk/dhcp](https://pkg.go.dev/github.com/insomniacslk/dhcp) ([BSD-3-Clause](https://github.com/insomniacslk/dhcp/blob/8c70d406f6d2/LICENSE)) - [github.com/jellydator/ttlcache/v3](https://pkg.go.dev/github.com/jellydator/ttlcache/v3) ([MIT](https://github.com/jellydator/ttlcache/blob/v3.1.0/LICENSE)) - - [github.com/jmespath/go-jmespath](https://pkg.go.dev/github.com/jmespath/go-jmespath) ([Apache-2.0](https://github.com/jmespath/go-jmespath/blob/v0.4.0/LICENSE)) - - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.17.11/LICENSE)) - - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.17.11/internal/snapref/LICENSE)) - - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.17.11/zstd/internal/xxhash/LICENSE.txt)) + - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.0/LICENSE)) + - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.0/internal/snapref/LICENSE)) + - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.0/zstd/internal/xxhash/LICENSE.txt)) - [github.com/kortschak/wol](https://pkg.go.dev/github.com/kortschak/wol) ([BSD-3-Clause](https://github.com/kortschak/wol/blob/da482cc4850a/LICENSE)) - - [github.com/mdlayher/genetlink](https://pkg.go.dev/github.com/mdlayher/genetlink) ([MIT](https://github.com/mdlayher/genetlink/blob/v1.3.2/LICENSE.md)) - - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/fbb4dce95f42/LICENSE.md)) - - [github.com/mdlayher/sdnotify](https://pkg.go.dev/github.com/mdlayher/sdnotify) ([MIT](https://github.com/mdlayher/sdnotify/blob/v1.0.0/LICENSE.md)) - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.5.0/LICENSE.md)) - - [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) ([BSD-3-Clause](https://github.com/miekg/dns/blob/v1.1.58/LICENSE)) - - [github.com/mitchellh/go-ps](https://pkg.go.dev/github.com/mitchellh/go-ps) ([MIT](https://github.com/mitchellh/go-ps/blob/v1.0.0/LICENSE.md)) - [github.com/pierrec/lz4/v4](https://pkg.go.dev/github.com/pierrec/lz4/v4) ([BSD-3-Clause](https://github.com/pierrec/lz4/blob/v4.1.21/LICENSE)) - - [github.com/safchain/ethtool](https://pkg.go.dev/github.com/safchain/ethtool) ([Apache-2.0](https://github.com/safchain/ethtool/blob/v0.3.0/LICENSE)) - - [github.com/tailscale/goupnp](https://pkg.go.dev/github.com/tailscale/goupnp) ([BSD-2-Clause](https://github.com/tailscale/goupnp/blob/c64d0f06ea05/LICENSE)) - - [github.com/tailscale/netlink](https://pkg.go.dev/github.com/tailscale/netlink) ([Apache-2.0](https://github.com/tailscale/netlink/blob/4d49adab4de7/LICENSE)) + - [github.com/pires/go-proxyproto](https://pkg.go.dev/github.com/pires/go-proxyproto) ([Apache-2.0](https://github.com/pires/go-proxyproto/blob/v0.8.1/LICENSE)) + - [github.com/huin/goupnp](https://pkg.go.dev/github.com/huin/goupnp) ([BSD-2-Clause](https://github.com/huin/goupnp/blob/v1.3.0/LICENSE)) - [github.com/tailscale/peercred](https://pkg.go.dev/github.com/tailscale/peercred) ([BSD-3-Clause](https://github.com/tailscale/peercred/blob/35a0c7bd7edc/LICENSE)) - [github.com/tailscale/tailscale-android/libtailscale](https://pkg.go.dev/github.com/tailscale/tailscale-android/libtailscale) ([BSD-3-Clause](https://github.com/tailscale/tailscale-android/blob/HEAD/LICENSE)) - - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/0b8b35511f19/LICENSE)) + - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/1d0488a3d7da/LICENSE)) - [github.com/tailscale/xnet/webdav](https://pkg.go.dev/github.com/tailscale/xnet/webdav) ([BSD-3-Clause](https://github.com/tailscale/xnet/blob/8497ac4dab2e/LICENSE)) - [github.com/u-root/uio](https://pkg.go.dev/github.com/u-root/uio) ([BSD-3-Clause](https://github.com/u-root/uio/blob/d2acac8f3701/LICENSE)) - - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.4/LICENSE)) - [github.com/x448/float16](https://pkg.go.dev/github.com/x448/float16) ([MIT](https://github.com/x448/float16/blob/v0.8.4/LICENSE)) - - [go4.org/intern](https://pkg.go.dev/go4.org/intern) ([BSD-3-Clause](https://github.com/go4org/intern/blob/ae77deb06f29/LICENSE)) - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/ae6ca9944745/LICENSE)) - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/fdeea329fbba/LICENSE)) - - [go4.org/unsafe/assume-no-moving-gc](https://pkg.go.dev/go4.org/unsafe/assume-no-moving-gc) ([BSD-3-Clause](https://github.com/go4org/unsafe-assume-no-moving-gc/blob/e7c30c78aeb2/LICENSE)) - - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.35.0:LICENSE)) - - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/939b2ce7:LICENSE)) + - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.45.0:LICENSE)) + - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/b7579e27:LICENSE)) - [golang.org/x/mobile](https://pkg.go.dev/golang.org/x/mobile) ([BSD-3-Clause](https://cs.opensource.google/go/x/mobile/+/81131f64:LICENSE)) - - [golang.org/x/mod/semver](https://pkg.go.dev/golang.org/x/mod/semver) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.23.0:LICENSE)) - - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.36.0:LICENSE)) - - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.11.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.30.0:LICENSE)) - - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.29.0:LICENSE)) - - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.22.0:LICENSE)) - - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.10.0:LICENSE)) - - [golang.org/x/tools](https://pkg.go.dev/golang.org/x/tools) ([BSD-3-Clause](https://cs.opensource.google/go/x/tools/+/v0.30.0:LICENSE)) + - [golang.org/x/mod/semver](https://pkg.go.dev/golang.org/x/mod/semver) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE)) + - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE)) + - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.18.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.38.0:LICENSE)) + - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.37.0:LICENSE)) + - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.31.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.11.0:LICENSE)) + - [golang.org/x/tools](https://pkg.go.dev/golang.org/x/tools) ([BSD-3-Clause](https://cs.opensource.google/go/x/tools/+/v0.39.0:LICENSE)) - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/9414b50a5633/LICENSE)) - - [inet.af/netaddr](https://pkg.go.dev/inet.af/netaddr) ([BSD-3-Clause](Unknown)) - [tailscale.com](https://pkg.go.dev/tailscale.com) ([BSD-3-Clause](https://github.com/tailscale/tailscale/blob/HEAD/LICENSE)) diff --git a/vendor/tailscale.com/licenses/apple.md b/vendor/tailscale.com/licenses/apple.md index 814df22..c3f2d3b 100644 --- a/vendor/tailscale.com/licenses/apple.md +++ b/vendor/tailscale.com/licenses/apple.md @@ -12,30 +12,31 @@ See also the dependencies in the [Tailscale CLI][]. - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.1.0/LICENSE)) - - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.39.6/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.29.5/config/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.17.58/credentials/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.16.27/feature/ec2/imds/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.3.31/internal/configsources/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.6.31/internal/endpoints/v2/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.4.13/internal/configsources/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.7.13/internal/endpoints/v2/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/internal/ini](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/ini) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/ini/v1.8.2/internal/ini/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/internal/sync/singleflight/LICENSE)) + - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.39.6/internal/sync/singleflight/LICENSE)) - [github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/accept-encoding/v1.12.2/service/internal/accept-encoding/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/presigned-url/v1.12.12/service/internal/presigned-url/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/service/ssm](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssm) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.45.0/service/ssm/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/service/sso](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sso) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sso/v1.24.14/service/sso/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssooidc) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssooidc/v1.28.13/service/ssooidc/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/service/sts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sts) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.33.13/service/sts/LICENSE.txt)) - - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.22.2/LICENSE)) - - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.22.2/internal/sync/singleflight/LICENSE)) + - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.23.2/LICENSE)) + - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.23.2/internal/sync/singleflight/LICENSE)) - [github.com/coreos/go-iptables/iptables](https://pkg.go.dev/github.com/coreos/go-iptables/iptables) ([Apache-2.0](https://github.com/coreos/go-iptables/blob/65c67c9f46e6/LICENSE)) + - [github.com/creachadair/msync/trigger](https://pkg.go.dev/github.com/creachadair/msync/trigger) ([BSD-3-Clause](https://github.com/creachadair/msync/blob/v0.7.1/LICENSE)) - [github.com/digitalocean/go-smbios/smbios](https://pkg.go.dev/github.com/digitalocean/go-smbios/smbios) ([Apache-2.0](https://github.com/digitalocean/go-smbios/blob/390a4f403a8e/LICENSE.md)) - [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.6.0/LICENSE)) - [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.7.0/LICENSE)) - [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.18.0/LICENSE)) - - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/d3c622f1b874/LICENSE)) + - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/cc2cfa0554c3/LICENSE)) - [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/76236955d466/LICENSE)) - - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE)) + - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE)) - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.2/LICENSE)) - [github.com/google/nftables](https://pkg.go.dev/github.com/google/nftables) ([Apache-2.0](https://github.com/google/nftables/blob/5e242ec57806/LICENSE)) - [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE)) @@ -45,37 +46,37 @@ See also the dependencies in the [Tailscale CLI][]. - [github.com/jellydator/ttlcache/v3](https://pkg.go.dev/github.com/jellydator/ttlcache/v3) ([MIT](https://github.com/jellydator/ttlcache/blob/v3.1.0/LICENSE)) - [github.com/jmespath/go-jmespath](https://pkg.go.dev/github.com/jmespath/go-jmespath) ([Apache-2.0](https://github.com/jmespath/go-jmespath/blob/v0.4.0/LICENSE)) - [github.com/jsimonetti/rtnetlink](https://pkg.go.dev/github.com/jsimonetti/rtnetlink) ([MIT](https://github.com/jsimonetti/rtnetlink/blob/v1.4.1/LICENSE.md)) - - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.17.11/LICENSE)) - - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.17.11/internal/snapref/LICENSE)) - - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.17.11/zstd/internal/xxhash/LICENSE.txt)) + - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.0/LICENSE)) + - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.0/internal/snapref/LICENSE)) + - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.0/zstd/internal/xxhash/LICENSE.txt)) - [github.com/kortschak/wol](https://pkg.go.dev/github.com/kortschak/wol) ([BSD-3-Clause](https://github.com/kortschak/wol/blob/da482cc4850a/LICENSE)) - [github.com/mdlayher/genetlink](https://pkg.go.dev/github.com/mdlayher/genetlink) ([MIT](https://github.com/mdlayher/genetlink/blob/v1.3.2/LICENSE.md)) - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/fbb4dce95f42/LICENSE.md)) - [github.com/mdlayher/sdnotify](https://pkg.go.dev/github.com/mdlayher/sdnotify) ([MIT](https://github.com/mdlayher/sdnotify/blob/v1.0.0/LICENSE.md)) - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.5.0/LICENSE.md)) - - [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) ([BSD-3-Clause](https://github.com/miekg/dns/blob/v1.1.58/LICENSE)) - [github.com/mitchellh/go-ps](https://pkg.go.dev/github.com/mitchellh/go-ps) ([MIT](https://github.com/mitchellh/go-ps/blob/v1.0.0/LICENSE.md)) - - [github.com/pierrec/lz4/v4](https://pkg.go.dev/github.com/pierrec/lz4/v4) ([BSD-3-Clause](https://github.com/pierrec/lz4/blob/v4.1.21/LICENSE)) + - [github.com/pierrec/lz4/v4](https://pkg.go.dev/github.com/pierrec/lz4/v4) ([BSD-3-Clause](https://github.com/pierrec/lz4/blob/v4.1.22/LICENSE)) + - [github.com/pires/go-proxyproto](https://pkg.go.dev/github.com/pires/go-proxyproto) ([Apache-2.0](https://github.com/pires/go-proxyproto/blob/v0.8.1/LICENSE)) - [github.com/prometheus-community/pro-bing](https://pkg.go.dev/github.com/prometheus-community/pro-bing) ([MIT](https://github.com/prometheus-community/pro-bing/blob/v0.4.0/LICENSE)) - [github.com/safchain/ethtool](https://pkg.go.dev/github.com/safchain/ethtool) ([Apache-2.0](https://github.com/safchain/ethtool/blob/v0.3.0/LICENSE)) - - [github.com/tailscale/goupnp](https://pkg.go.dev/github.com/tailscale/goupnp) ([BSD-2-Clause](https://github.com/tailscale/goupnp/blob/c64d0f06ea05/LICENSE)) + - [github.com/huin/goupnp](https://pkg.go.dev/github.com/huin/goupnp) ([BSD-2-Clause](https://github.com/huin/goupnp/blob/v1.3.0/LICENSE)) - [github.com/tailscale/netlink](https://pkg.go.dev/github.com/tailscale/netlink) ([Apache-2.0](https://github.com/tailscale/netlink/blob/4d49adab4de7/LICENSE)) - [github.com/tailscale/peercred](https://pkg.go.dev/github.com/tailscale/peercred) ([BSD-3-Clause](https://github.com/tailscale/peercred/blob/35a0c7bd7edc/LICENSE)) - - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/0b8b35511f19/LICENSE)) + - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/1d0488a3d7da/LICENSE)) - [github.com/tailscale/xnet/webdav](https://pkg.go.dev/github.com/tailscale/xnet/webdav) ([BSD-3-Clause](https://github.com/tailscale/xnet/blob/8497ac4dab2e/LICENSE)) - [github.com/u-root/uio](https://pkg.go.dev/github.com/u-root/uio) ([BSD-3-Clause](https://github.com/u-root/uio/blob/d2acac8f3701/LICENSE)) - - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.4/LICENSE)) + - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.5/LICENSE)) - [github.com/x448/float16](https://pkg.go.dev/github.com/x448/float16) ([MIT](https://github.com/x448/float16/blob/v0.8.4/LICENSE)) - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/ae6ca9944745/LICENSE)) - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/fdeea329fbba/LICENSE)) - - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.35.0:LICENSE)) - - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/939b2ce7:LICENSE)) - - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.36.0:LICENSE)) - - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.11.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.30.0:LICENSE)) - - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.29.0:LICENSE)) - - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.22.0:LICENSE)) - - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.10.0:LICENSE)) + - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.45.0:LICENSE)) + - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/df929982:LICENSE)) + - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE)) + - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.18.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.38.0:LICENSE)) + - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.37.0:LICENSE)) + - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.31.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.12.0:LICENSE)) - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/9414b50a5633/LICENSE)) - [tailscale.com](https://pkg.go.dev/tailscale.com) ([BSD-3-Clause](https://github.com/tailscale/tailscale/blob/HEAD/LICENSE)) diff --git a/vendor/tailscale.com/licenses/tailscale.md b/vendor/tailscale.com/licenses/tailscale.md index b3095f5..85c0f33 100644 --- a/vendor/tailscale.com/licenses/tailscale.md +++ b/vendor/tailscale.com/licenses/tailscale.md @@ -14,9 +14,12 @@ Some packages may only be included on certain architectures or operating systems - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.1.0/LICENSE)) + - [fyne.io/systray](https://pkg.go.dev/fyne.io/systray) ([Apache-2.0](https://github.com/fyne-io/systray/blob/4856ac3adc3c/LICENSE)) + - [github.com/Kodeworks/golang-image-ico](https://pkg.go.dev/github.com/Kodeworks/golang-image-ico) ([BSD-3-Clause](https://github.com/Kodeworks/golang-image-ico/blob/73f0f4cfade9/LICENSE)) - [github.com/akutz/memconn](https://pkg.go.dev/github.com/akutz/memconn) ([Apache-2.0](https://github.com/akutz/memconn/blob/v0.1.0/LICENSE)) - [github.com/alexbrainman/sspi](https://pkg.go.dev/github.com/alexbrainman/sspi) ([BSD-3-Clause](https://github.com/alexbrainman/sspi/blob/1a75b4708caa/LICENSE)) - [github.com/anmitsu/go-shlex](https://pkg.go.dev/github.com/anmitsu/go-shlex) ([MIT](https://github.com/anmitsu/go-shlex/blob/38f4b401e2be/LICENSE)) + - [github.com/atotto/clipboard](https://pkg.go.dev/github.com/atotto/clipboard) ([BSD-3-Clause](https://github.com/atotto/clipboard/blob/v0.1.4/LICENSE)) - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.29.5/config/LICENSE.txt)) - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.17.58/credentials/LICENSE.txt)) @@ -34,78 +37,70 @@ Some packages may only be included on certain architectures or operating systems - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.22.2/LICENSE)) - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.22.2/internal/sync/singleflight/LICENSE)) - [github.com/coder/websocket](https://pkg.go.dev/github.com/coder/websocket) ([ISC](https://github.com/coder/websocket/blob/v1.8.12/LICENSE.txt)) - - [github.com/coreos/go-iptables/iptables](https://pkg.go.dev/github.com/coreos/go-iptables/iptables) ([Apache-2.0](https://github.com/coreos/go-iptables/blob/65c67c9f46e6/LICENSE)) + - [github.com/creachadair/msync/trigger](https://pkg.go.dev/github.com/creachadair/msync/trigger) ([BSD-3-Clause](https://github.com/creachadair/msync/blob/v0.7.1/LICENSE)) - [github.com/creack/pty](https://pkg.go.dev/github.com/creack/pty) ([MIT](https://github.com/creack/pty/blob/v1.1.23/LICENSE)) - [github.com/dblohm7/wingoes](https://pkg.go.dev/github.com/dblohm7/wingoes) ([BSD-3-Clause](https://github.com/dblohm7/wingoes/blob/a09d6be7affa/LICENSE)) - [github.com/digitalocean/go-smbios/smbios](https://pkg.go.dev/github.com/digitalocean/go-smbios/smbios) ([Apache-2.0](https://github.com/digitalocean/go-smbios/blob/390a4f403a8e/LICENSE.md)) - [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.6.0/LICENSE)) + - [github.com/fogleman/gg](https://pkg.go.dev/github.com/fogleman/gg) ([MIT](https://github.com/fogleman/gg/blob/v1.3.0/LICENSE.md)) - [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.7.0/LICENSE)) - [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.18.0/LICENSE)) - - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/d3c622f1b874/LICENSE)) + - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/ebf49471dced/LICENSE)) - [github.com/go-ole/go-ole](https://pkg.go.dev/github.com/go-ole/go-ole) ([MIT](https://github.com/go-ole/go-ole/blob/v1.3.0/LICENSE)) - [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/76236955d466/LICENSE)) + - [github.com/golang/freetype/raster](https://pkg.go.dev/github.com/golang/freetype/raster) ([Unknown](Unknown)) + - [github.com/golang/freetype/truetype](https://pkg.go.dev/github.com/golang/freetype/truetype) ([Unknown](Unknown)) - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE)) - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.2/LICENSE)) - - [github.com/google/nftables](https://pkg.go.dev/github.com/google/nftables) ([Apache-2.0](https://github.com/google/nftables/blob/5e242ec57806/LICENSE)) - [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE)) - - [github.com/gorilla/csrf](https://pkg.go.dev/github.com/gorilla/csrf) ([BSD-3-Clause](https://github.com/gorilla/csrf/blob/9dd6af1f6d30/LICENSE)) - - [github.com/gorilla/securecookie](https://pkg.go.dev/github.com/gorilla/securecookie) ([BSD-3-Clause](https://github.com/gorilla/securecookie/blob/v1.1.2/LICENSE)) - [github.com/hdevalence/ed25519consensus](https://pkg.go.dev/github.com/hdevalence/ed25519consensus) ([BSD-3-Clause](https://github.com/hdevalence/ed25519consensus/blob/v0.2.0/LICENSE)) - - [github.com/illarion/gonotify/v3](https://pkg.go.dev/github.com/illarion/gonotify/v3) ([MIT](https://github.com/illarion/gonotify/blob/v3.0.2/LICENSE)) - [github.com/insomniacslk/dhcp](https://pkg.go.dev/github.com/insomniacslk/dhcp) ([BSD-3-Clause](https://github.com/insomniacslk/dhcp/blob/8c70d406f6d2/LICENSE)) - [github.com/jellydator/ttlcache/v3](https://pkg.go.dev/github.com/jellydator/ttlcache/v3) ([MIT](https://github.com/jellydator/ttlcache/blob/v3.1.0/LICENSE)) - [github.com/jmespath/go-jmespath](https://pkg.go.dev/github.com/jmespath/go-jmespath) ([Apache-2.0](https://github.com/jmespath/go-jmespath/blob/v0.4.0/LICENSE)) - [github.com/kballard/go-shellquote](https://pkg.go.dev/github.com/kballard/go-shellquote) ([MIT](https://github.com/kballard/go-shellquote/blob/95032a82bc51/LICENSE)) - - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.17.11/LICENSE)) - - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.17.11/internal/snapref/LICENSE)) - - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.17.11/zstd/internal/xxhash/LICENSE.txt)) + - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.0/LICENSE)) + - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.0/internal/snapref/LICENSE)) + - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.0/zstd/internal/xxhash/LICENSE.txt)) - [github.com/kortschak/wol](https://pkg.go.dev/github.com/kortschak/wol) ([BSD-3-Clause](https://github.com/kortschak/wol/blob/da482cc4850a/LICENSE)) - [github.com/kr/fs](https://pkg.go.dev/github.com/kr/fs) ([BSD-3-Clause](https://github.com/kr/fs/blob/v0.1.0/LICENSE)) - [github.com/mattn/go-colorable](https://pkg.go.dev/github.com/mattn/go-colorable) ([MIT](https://github.com/mattn/go-colorable/blob/v0.1.13/LICENSE)) - [github.com/mattn/go-isatty](https://pkg.go.dev/github.com/mattn/go-isatty) ([MIT](https://github.com/mattn/go-isatty/blob/v0.0.20/LICENSE)) - - [github.com/mdlayher/genetlink](https://pkg.go.dev/github.com/mdlayher/genetlink) ([MIT](https://github.com/mdlayher/genetlink/blob/v1.3.2/LICENSE.md)) - - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/fbb4dce95f42/LICENSE.md)) - - [github.com/mdlayher/sdnotify](https://pkg.go.dev/github.com/mdlayher/sdnotify) ([MIT](https://github.com/mdlayher/sdnotify/blob/v1.0.0/LICENSE.md)) - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.5.0/LICENSE.md)) - - [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) ([BSD-3-Clause](https://github.com/miekg/dns/blob/v1.1.58/LICENSE)) - [github.com/mitchellh/go-ps](https://pkg.go.dev/github.com/mitchellh/go-ps) ([MIT](https://github.com/mitchellh/go-ps/blob/v1.0.0/LICENSE.md)) - [github.com/peterbourgon/ff/v3](https://pkg.go.dev/github.com/peterbourgon/ff/v3) ([Apache-2.0](https://github.com/peterbourgon/ff/blob/v3.4.0/LICENSE)) - [github.com/pierrec/lz4/v4](https://pkg.go.dev/github.com/pierrec/lz4/v4) ([BSD-3-Clause](https://github.com/pierrec/lz4/blob/v4.1.21/LICENSE)) + - [github.com/pires/go-proxyproto](https://pkg.go.dev/github.com/pires/go-proxyproto) ([Apache-2.0](https://github.com/pires/go-proxyproto/blob/v0.8.1/LICENSE)) - [github.com/pkg/sftp](https://pkg.go.dev/github.com/pkg/sftp) ([BSD-2-Clause](https://github.com/pkg/sftp/blob/v1.13.6/LICENSE)) - [github.com/prometheus-community/pro-bing](https://pkg.go.dev/github.com/prometheus-community/pro-bing) ([MIT](https://github.com/prometheus-community/pro-bing/blob/v0.4.0/LICENSE)) - - [github.com/safchain/ethtool](https://pkg.go.dev/github.com/safchain/ethtool) ([Apache-2.0](https://github.com/safchain/ethtool/blob/v0.3.0/LICENSE)) - [github.com/skip2/go-qrcode](https://pkg.go.dev/github.com/skip2/go-qrcode) ([MIT](https://github.com/skip2/go-qrcode/blob/da1b6568686e/LICENSE)) - [github.com/tailscale/certstore](https://pkg.go.dev/github.com/tailscale/certstore) ([MIT](https://github.com/tailscale/certstore/blob/d3fa0460f47e/LICENSE.md)) - [github.com/tailscale/go-winio](https://pkg.go.dev/github.com/tailscale/go-winio) ([MIT](https://github.com/tailscale/go-winio/blob/c4f33415bf55/LICENSE)) - - [github.com/tailscale/netlink](https://pkg.go.dev/github.com/tailscale/netlink) ([Apache-2.0](https://github.com/tailscale/netlink/blob/4d49adab4de7/LICENSE)) - - [github.com/tailscale/peercred](https://pkg.go.dev/github.com/tailscale/peercred) ([BSD-3-Clause](https://github.com/tailscale/peercred/blob/35a0c7bd7edc/LICENSE)) - [github.com/tailscale/web-client-prebuilt](https://pkg.go.dev/github.com/tailscale/web-client-prebuilt) ([BSD-3-Clause](https://github.com/tailscale/web-client-prebuilt/blob/d4cd19a26976/LICENSE)) - [github.com/tailscale/wf](https://pkg.go.dev/github.com/tailscale/wf) ([BSD-3-Clause](https://github.com/tailscale/wf/blob/6fbb0a674ee6/LICENSE)) - - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/0b8b35511f19/LICENSE)) + - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/1d0488a3d7da/LICENSE)) - [github.com/tailscale/xnet/webdav](https://pkg.go.dev/github.com/tailscale/xnet/webdav) ([BSD-3-Clause](https://github.com/tailscale/xnet/blob/8497ac4dab2e/LICENSE)) - [github.com/toqueteos/webbrowser](https://pkg.go.dev/github.com/toqueteos/webbrowser) ([MIT](https://github.com/toqueteos/webbrowser/blob/v1.2.0/LICENSE.md)) - - [github.com/u-root/u-root/pkg/termios](https://pkg.go.dev/github.com/u-root/u-root/pkg/termios) ([BSD-3-Clause](https://github.com/u-root/u-root/blob/v0.12.0/LICENSE)) + - [github.com/u-root/u-root/pkg/termios](https://pkg.go.dev/github.com/u-root/u-root/pkg/termios) ([BSD-3-Clause](https://github.com/u-root/u-root/blob/v0.14.0/LICENSE)) - [github.com/u-root/uio](https://pkg.go.dev/github.com/u-root/uio) ([BSD-3-Clause](https://github.com/u-root/uio/blob/d2acac8f3701/LICENSE)) - - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.4/LICENSE)) - [github.com/x448/float16](https://pkg.go.dev/github.com/x448/float16) ([MIT](https://github.com/x448/float16/blob/v0.8.4/LICENSE)) - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/ae6ca9944745/LICENSE)) - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/fdeea329fbba/LICENSE)) - - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.35.0:LICENSE)) - - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/939b2ce7:LICENSE)) - - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.36.0:LICENSE)) - - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.26.0:LICENSE)) - - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.11.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.30.0:LICENSE)) - - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.29.0:LICENSE)) - - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.22.0:LICENSE)) - - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.10.0:LICENSE)) + - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.45.0:LICENSE)) + - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/b7579e27:LICENSE)) + - [golang.org/x/image](https://pkg.go.dev/golang.org/x/image) ([BSD-3-Clause](https://cs.opensource.google/go/x/image/+/v0.27.0:LICENSE)) + - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE)) + - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.30.0:LICENSE)) + - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.18.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.38.0:LICENSE)) + - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.37.0:LICENSE)) + - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.31.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.11.0:LICENSE)) - [golang.zx2c4.com/wintun](https://pkg.go.dev/golang.zx2c4.com/wintun) ([MIT](https://git.zx2c4.com/wintun-go/tree/LICENSE?id=0fa3db229ce2)) - [golang.zx2c4.com/wireguard/windows/tunnel/winipcfg](https://pkg.go.dev/golang.zx2c4.com/wireguard/windows/tunnel/winipcfg) ([MIT](https://git.zx2c4.com/wireguard-windows/tree/COPYING?h=v0.5.3)) - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/9414b50a5633/LICENSE)) - [k8s.io/client-go/util/homedir](https://pkg.go.dev/k8s.io/client-go/util/homedir) ([Apache-2.0](https://github.com/kubernetes/client-go/blob/v0.32.0/LICENSE)) - [sigs.k8s.io/yaml](https://pkg.go.dev/sigs.k8s.io/yaml) ([Apache-2.0](https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/LICENSE)) - [sigs.k8s.io/yaml/goyaml.v2](https://pkg.go.dev/sigs.k8s.io/yaml/goyaml.v2) ([Apache-2.0](https://github.com/kubernetes-sigs/yaml/blob/v1.4.0/goyaml.v2/LICENSE)) - - [software.sslmate.com/src/go-pkcs12](https://pkg.go.dev/software.sslmate.com/src/go-pkcs12) ([BSD-3-Clause](https://github.com/SSLMate/go-pkcs12/blob/v0.4.0/LICENSE)) - [tailscale.com](https://pkg.go.dev/tailscale.com) ([BSD-3-Clause](https://github.com/tailscale/tailscale/blob/HEAD/LICENSE)) - [tailscale.com/tempfork/gliderlabs/ssh](https://pkg.go.dev/tailscale.com/tempfork/gliderlabs/ssh) ([BSD-3-Clause](https://github.com/tailscale/tailscale/blob/HEAD/tempfork/gliderlabs/ssh/LICENSE)) - [tailscale.com/tempfork/spf13/cobra](https://pkg.go.dev/tailscale.com/tempfork/spf13/cobra) ([Apache-2.0](https://github.com/tailscale/tailscale/blob/HEAD/tempfork/spf13/cobra/LICENSE.txt)) diff --git a/vendor/tailscale.com/licenses/windows.md b/vendor/tailscale.com/licenses/windows.md index bdf9650..0b8344b 100644 --- a/vendor/tailscale.com/licenses/windows.md +++ b/vendor/tailscale.com/licenses/windows.md @@ -10,78 +10,58 @@ Windows][]. See also the dependencies in the [Tailscale CLI][]. - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.1.0/LICENSE)) - - [github.com/alexbrainman/sspi](https://pkg.go.dev/github.com/alexbrainman/sspi) ([BSD-3-Clause](https://github.com/alexbrainman/sspi/blob/1a75b4708caa/LICENSE)) - [github.com/apenwarr/fixconsole](https://pkg.go.dev/github.com/apenwarr/fixconsole) ([Apache-2.0](https://github.com/apenwarr/fixconsole/blob/5a9f6489cc29/LICENSE)) - [github.com/apenwarr/w32](https://pkg.go.dev/github.com/apenwarr/w32) ([BSD-3-Clause](https://github.com/apenwarr/w32/blob/aa00fece76ab/LICENSE)) - - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.29.5/config/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.17.58/credentials/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.16.27/feature/ec2/imds/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.3.31/internal/configsources/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.6.31/internal/endpoints/v2/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/ini](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/ini) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/ini/v1.8.2/internal/ini/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.36.0/internal/sync/singleflight/LICENSE)) - - [github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/accept-encoding/v1.12.2/service/internal/accept-encoding/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/presigned-url/v1.12.12/service/internal/presigned-url/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/ssm](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssm) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.45.0/service/ssm/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sso](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sso) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sso/v1.24.14/service/sso/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssooidc) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssooidc/v1.28.13/service/ssooidc/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sts) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.33.13/service/sts/LICENSE.txt)) - - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.22.2/LICENSE)) - - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.22.2/internal/sync/singleflight/LICENSE)) - [github.com/beorn7/perks/quantile](https://pkg.go.dev/github.com/beorn7/perks/quantile) ([MIT](https://github.com/beorn7/perks/blob/v1.0.1/LICENSE)) - [github.com/cespare/xxhash/v2](https://pkg.go.dev/github.com/cespare/xxhash/v2) ([MIT](https://github.com/cespare/xxhash/blob/v2.3.0/LICENSE.txt)) - - [github.com/coreos/go-iptables/iptables](https://pkg.go.dev/github.com/coreos/go-iptables/iptables) ([Apache-2.0](https://github.com/coreos/go-iptables/blob/65c67c9f46e6/LICENSE)) + - [github.com/coder/websocket](https://pkg.go.dev/github.com/coder/websocket) ([ISC](https://github.com/coder/websocket/blob/v1.8.12/LICENSE.txt)) + - [github.com/creachadair/msync/trigger](https://pkg.go.dev/github.com/creachadair/msync/trigger) ([BSD-3-Clause](https://github.com/creachadair/msync/blob/v0.7.1/LICENSE)) - [github.com/dblohm7/wingoes](https://pkg.go.dev/github.com/dblohm7/wingoes) ([BSD-3-Clause](https://github.com/dblohm7/wingoes/blob/b75a8a7d7eb0/LICENSE)) - [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.6.0/LICENSE)) - [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.7.0/LICENSE)) - - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/d3c622f1b874/LICENSE)) - - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE)) + - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/cc2cfa0554c3/LICENSE)) + - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE)) - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.2/LICENSE)) - - [github.com/google/nftables](https://pkg.go.dev/github.com/google/nftables) ([Apache-2.0](https://github.com/google/nftables/blob/5e242ec57806/LICENSE)) + - [github.com/google/go-cmp/cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) ([BSD-3-Clause](https://github.com/google/go-cmp/blob/v0.7.0/LICENSE)) - [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE)) - [github.com/gregjones/httpcache](https://pkg.go.dev/github.com/gregjones/httpcache) ([MIT](https://github.com/gregjones/httpcache/blob/901d90724c79/LICENSE.txt)) - [github.com/hdevalence/ed25519consensus](https://pkg.go.dev/github.com/hdevalence/ed25519consensus) ([BSD-3-Clause](https://github.com/hdevalence/ed25519consensus/blob/v0.2.0/LICENSE)) - [github.com/jellydator/ttlcache/v3](https://pkg.go.dev/github.com/jellydator/ttlcache/v3) ([MIT](https://github.com/jellydator/ttlcache/blob/v3.1.0/LICENSE)) - - [github.com/jmespath/go-jmespath](https://pkg.go.dev/github.com/jmespath/go-jmespath) ([Apache-2.0](https://github.com/jmespath/go-jmespath/blob/v0.4.0/LICENSE)) - [github.com/jsimonetti/rtnetlink](https://pkg.go.dev/github.com/jsimonetti/rtnetlink) ([MIT](https://github.com/jsimonetti/rtnetlink/blob/v1.4.1/LICENSE.md)) - - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.17.11/LICENSE)) - - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.17.11/internal/snapref/LICENSE)) - - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.17.11/zstd/internal/xxhash/LICENSE.txt)) + - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.0/LICENSE)) + - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.0/internal/snapref/LICENSE)) + - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.0/zstd/internal/xxhash/LICENSE.txt)) - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/fbb4dce95f42/LICENSE.md)) - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.5.0/LICENSE.md)) - - [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) ([BSD-3-Clause](https://github.com/miekg/dns/blob/v1.1.58/LICENSE)) - [github.com/mitchellh/go-ps](https://pkg.go.dev/github.com/mitchellh/go-ps) ([MIT](https://github.com/mitchellh/go-ps/blob/v1.0.0/LICENSE.md)) - [github.com/munnerz/goautoneg](https://pkg.go.dev/github.com/munnerz/goautoneg) ([BSD-3-Clause](https://github.com/munnerz/goautoneg/blob/a7dc8b61c822/LICENSE)) - [github.com/nfnt/resize](https://pkg.go.dev/github.com/nfnt/resize) ([ISC](https://github.com/nfnt/resize/blob/83c6a9932646/LICENSE)) - [github.com/peterbourgon/diskv](https://pkg.go.dev/github.com/peterbourgon/diskv) ([MIT](https://github.com/peterbourgon/diskv/blob/v2.0.1/LICENSE)) - - [github.com/prometheus/client_golang/prometheus](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus) ([Apache-2.0](https://github.com/prometheus/client_golang/blob/v1.19.1/LICENSE)) - - [github.com/prometheus/client_model/go](https://pkg.go.dev/github.com/prometheus/client_model/go) ([Apache-2.0](https://github.com/prometheus/client_model/blob/v0.6.1/LICENSE)) - - [github.com/prometheus/common](https://pkg.go.dev/github.com/prometheus/common) ([Apache-2.0](https://github.com/prometheus/common/blob/v0.55.0/LICENSE)) + - [github.com/prometheus/client_golang/prometheus](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus) ([Apache-2.0](https://github.com/prometheus/client_golang/blob/v1.23.2/LICENSE)) + - [github.com/prometheus/client_model/go](https://pkg.go.dev/github.com/prometheus/client_model/go) ([Apache-2.0](https://github.com/prometheus/client_model/blob/v0.6.2/LICENSE)) + - [github.com/prometheus/common](https://pkg.go.dev/github.com/prometheus/common) ([Apache-2.0](https://github.com/prometheus/common/blob/v0.66.1/LICENSE)) - [github.com/skip2/go-qrcode](https://pkg.go.dev/github.com/skip2/go-qrcode) ([MIT](https://github.com/skip2/go-qrcode/blob/da1b6568686e/LICENSE)) - [github.com/tailscale/go-winio](https://pkg.go.dev/github.com/tailscale/go-winio) ([MIT](https://github.com/tailscale/go-winio/blob/c4f33415bf55/LICENSE)) - - [github.com/tailscale/hujson](https://pkg.go.dev/github.com/tailscale/hujson) ([BSD-3-Clause](https://github.com/tailscale/hujson/blob/20486734a56a/LICENSE)) - - [github.com/tailscale/netlink](https://pkg.go.dev/github.com/tailscale/netlink) ([Apache-2.0](https://github.com/tailscale/netlink/blob/4d49adab4de7/LICENSE)) - - [github.com/tailscale/walk](https://pkg.go.dev/github.com/tailscale/walk) ([BSD-3-Clause](https://github.com/tailscale/walk/blob/b2c15a420186/LICENSE)) - - [github.com/tailscale/win](https://pkg.go.dev/github.com/tailscale/win) ([BSD-3-Clause](https://github.com/tailscale/win/blob/5992cb43ca35/LICENSE)) + - [github.com/tailscale/hujson](https://pkg.go.dev/github.com/tailscale/hujson) ([BSD-3-Clause](https://github.com/tailscale/hujson/blob/992244df8c5a/LICENSE)) + - [github.com/tailscale/walk](https://pkg.go.dev/github.com/tailscale/walk) ([BSD-3-Clause](https://github.com/tailscale/walk/blob/963e260a8227/LICENSE)) + - [github.com/tailscale/win](https://pkg.go.dev/github.com/tailscale/win) ([BSD-3-Clause](https://github.com/tailscale/win/blob/f4da2b8ee071/LICENSE)) - [github.com/tailscale/xnet/webdav](https://pkg.go.dev/github.com/tailscale/xnet/webdav) ([BSD-3-Clause](https://github.com/tailscale/xnet/blob/8497ac4dab2e/LICENSE)) - [github.com/tc-hib/winres](https://pkg.go.dev/github.com/tc-hib/winres) ([0BSD](https://github.com/tc-hib/winres/blob/v0.2.1/LICENSE)) - - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.4/LICENSE)) - [github.com/x448/float16](https://pkg.go.dev/github.com/x448/float16) ([MIT](https://github.com/x448/float16/blob/v0.8.4/LICENSE)) + - [go.yaml.in/yaml/v2](https://pkg.go.dev/go.yaml.in/yaml/v2) ([Apache-2.0](https://github.com/yaml/go-yaml/blob/v2.4.2/LICENSE)) - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/ae6ca9944745/LICENSE)) - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/fdeea329fbba/LICENSE)) - - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.35.0:LICENSE)) - - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/939b2ce7:LICENSE)) - - [golang.org/x/image/bmp](https://pkg.go.dev/golang.org/x/image/bmp) ([BSD-3-Clause](https://cs.opensource.google/go/x/image/+/v0.24.0:LICENSE)) - - [golang.org/x/mod](https://pkg.go.dev/golang.org/x/mod) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.23.0:LICENSE)) - - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.36.0:LICENSE)) - - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.11.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.30.0:LICENSE)) - - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.29.0:LICENSE)) - - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.22.0:LICENSE)) + - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.45.0:LICENSE)) + - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/df929982:LICENSE)) + - [golang.org/x/image/bmp](https://pkg.go.dev/golang.org/x/image/bmp) ([BSD-3-Clause](https://cs.opensource.google/go/x/image/+/v0.27.0:LICENSE)) + - [golang.org/x/mod](https://pkg.go.dev/golang.org/x/mod) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE)) + - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE)) + - [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.18.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.38.0:LICENSE)) + - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.37.0:LICENSE)) - [golang.zx2c4.com/wintun](https://pkg.go.dev/golang.zx2c4.com/wintun) ([MIT](https://git.zx2c4.com/wintun-go/tree/LICENSE?id=0fa3db229ce2)) - [golang.zx2c4.com/wireguard/windows/tunnel/winipcfg](https://pkg.go.dev/golang.zx2c4.com/wireguard/windows/tunnel/winipcfg) ([MIT](https://git.zx2c4.com/wireguard-windows/tree/COPYING?h=v0.5.3)) - - [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) ([BSD-3-Clause](https://github.com/protocolbuffers/protobuf-go/blob/v1.35.1/LICENSE)) + - [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) ([BSD-3-Clause](https://github.com/protocolbuffers/protobuf-go/blob/v1.36.8/LICENSE)) - [gopkg.in/Knetic/govaluate.v3](https://pkg.go.dev/gopkg.in/Knetic/govaluate.v3) ([MIT](https://github.com/Knetic/govaluate/blob/v3.0.0/LICENSE)) - [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) ([MIT](https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE)) - [tailscale.com](https://pkg.go.dev/tailscale.com) ([BSD-3-Clause](https://github.com/tailscale/tailscale/blob/HEAD/LICENSE)) diff --git a/vendor/tailscale.com/log/sockstatlog/logger.go b/vendor/tailscale.com/log/sockstatlog/logger.go index 3cc27c2..8ddfabb 100644 --- a/vendor/tailscale.com/log/sockstatlog/logger.go +++ b/vendor/tailscale.com/log/sockstatlog/logger.go @@ -17,6 +17,7 @@ import ( "sync/atomic" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/logpolicy" "tailscale.com/logtail" @@ -25,6 +26,7 @@ import ( "tailscale.com/net/sockstats" "tailscale.com/types/logger" "tailscale.com/types/logid" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" ) @@ -96,8 +98,8 @@ func SockstatLogID(logID logid.PublicID) logid.PrivateID { // // The netMon parameter is optional. It should be specified in environments where // Tailscaled is manipulating the routing table. -func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker) (*Logger, error) { - if !sockstats.IsAvailable { +func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus) (*Logger, error) { + if !sockstats.IsAvailable || !buildfeatures.HasLogTail { return nil, nil } if netMon == nil { @@ -126,6 +128,7 @@ func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *ne PrivateID: SockstatLogID(logID), Collection: "sockstats.log.tailscale.io", Buffer: filch, + Bus: bus, CompressLogs: true, FlushDelayFn: func() time.Duration { // set flush delay to 100 years so it never flushes automatically @@ -143,33 +146,33 @@ func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *ne // SetLoggingEnabled enables or disables logging. // When disabled, socket stats are not polled and no new logs are written to disk. // Existing logs can still be fetched via the C2N API. -func (l *Logger) SetLoggingEnabled(v bool) { - old := l.enabled.Load() - if old != v && l.enabled.CompareAndSwap(old, v) { +func (lg *Logger) SetLoggingEnabled(v bool) { + old := lg.enabled.Load() + if old != v && lg.enabled.CompareAndSwap(old, v) { if v { - if l.eventCh == nil { + if lg.eventCh == nil { // eventCh should be large enough for the number of events that will occur within logInterval. // Add an extra second's worth of events to ensure we don't drop any. - l.eventCh = make(chan event, (logInterval+time.Second)/pollInterval) + lg.eventCh = make(chan event, (logInterval+time.Second)/pollInterval) } - l.ctx, l.cancelFn = context.WithCancel(context.Background()) - go l.poll() - go l.logEvents() + lg.ctx, lg.cancelFn = context.WithCancel(context.Background()) + go lg.poll() + go lg.logEvents() } else { - l.cancelFn() + lg.cancelFn() } } } -func (l *Logger) Write(p []byte) (int, error) { - return l.logger.Write(p) +func (lg *Logger) Write(p []byte) (int, error) { + return lg.logger.Write(p) } // poll fetches the current socket stats at the configured time interval, // calculates the delta since the last poll, // and writes any non-zero values to the logger event channel. // This method does not return. -func (l *Logger) poll() { +func (lg *Logger) poll() { // last is the last set of socket stats we saw. var lastStats *sockstats.SockStats var lastTime time.Time @@ -177,7 +180,7 @@ func (l *Logger) poll() { ticker := time.NewTicker(pollInterval) for { select { - case <-l.ctx.Done(): + case <-lg.ctx.Done(): ticker.Stop() return case t := <-ticker.C: @@ -193,7 +196,7 @@ func (l *Logger) poll() { if stats.CurrentInterfaceCellular { e.IsCellularInterface = 1 } - l.eventCh <- e + lg.eventCh <- e } } lastTime = t @@ -204,14 +207,14 @@ func (l *Logger) poll() { // logEvents reads events from the event channel at logInterval and logs them to disk. // This method does not return. -func (l *Logger) logEvents() { - enc := json.NewEncoder(l) +func (lg *Logger) logEvents() { + enc := json.NewEncoder(lg) flush := func() { for { select { - case e := <-l.eventCh: + case e := <-lg.eventCh: if err := enc.Encode(e); err != nil { - l.logf("sockstatlog: error encoding log: %v", err) + lg.logf("sockstatlog: error encoding log: %v", err) } default: return @@ -221,7 +224,7 @@ func (l *Logger) logEvents() { ticker := time.NewTicker(logInterval) for { select { - case <-l.ctx.Done(): + case <-lg.ctx.Done(): ticker.Stop() return case <-ticker.C: @@ -230,29 +233,29 @@ func (l *Logger) logEvents() { } } -func (l *Logger) LogID() string { - if l.logger == nil { +func (lg *Logger) LogID() string { + if lg.logger == nil { return "" } - return l.logger.PrivateID().Public().String() + return lg.logger.PrivateID().Public().String() } // Flush sends pending logs to the log server and flushes them from the local buffer. -func (l *Logger) Flush() { - l.logger.StartFlush() +func (lg *Logger) Flush() { + lg.logger.StartFlush() } -func (l *Logger) Shutdown(ctx context.Context) { - if l.cancelFn != nil { - l.cancelFn() +func (lg *Logger) Shutdown(ctx context.Context) { + if lg.cancelFn != nil { + lg.cancelFn() } - l.filch.Close() - l.logger.Shutdown(ctx) + lg.filch.Close() + lg.logger.Shutdown(ctx) type closeIdler interface { CloseIdleConnections() } - if tr, ok := l.tr.(closeIdler); ok { + if tr, ok := lg.tr.(closeIdler); ok { tr.CloseIdleConnections() } } diff --git a/vendor/tailscale.com/logpolicy/logpolicy.go b/vendor/tailscale.com/logpolicy/logpolicy.go index 1419fff..f749178 100644 --- a/vendor/tailscale.com/logpolicy/logpolicy.go +++ b/vendor/tailscale.com/logpolicy/logpolicy.go @@ -9,7 +9,6 @@ package logpolicy import ( "bufio" "bytes" - "cmp" "context" "crypto/tls" "encoding/json" @@ -32,6 +31,8 @@ import ( "golang.org/x/term" "tailscale.com/atomicfile" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/hostinfo" "tailscale.com/log/filelogger" @@ -42,16 +43,18 @@ import ( "tailscale.com/net/netknob" "tailscale.com/net/netmon" "tailscale.com/net/netns" + "tailscale.com/net/netx" "tailscale.com/net/tlsdial" - "tailscale.com/net/tshttpproxy" "tailscale.com/paths" "tailscale.com/safesocket" "tailscale.com/types/logger" "tailscale.com/types/logid" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" "tailscale.com/util/must" "tailscale.com/util/racebuild" - "tailscale.com/util/syspolicy" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" "tailscale.com/util/testenv" "tailscale.com/version" "tailscale.com/version/distro" @@ -65,7 +68,7 @@ var getLogTargetOnce struct { func getLogTarget() string { getLogTargetOnce.Do(func() { envTarget, _ := os.LookupEnv("TS_LOG_TARGET") - getLogTargetOnce.v, _ = syspolicy.GetString(syspolicy.LogTarget, envTarget) + getLogTargetOnce.v, _ = policyclient.Get().GetString(pkey.LogTarget, envTarget) }) return getLogTargetOnce.v @@ -105,6 +108,7 @@ type Policy struct { // Logtail is the logger. Logtail *logtail.Logger // PublicID is the logger's instance identifier. + // It may be the zero value if logging is not in use. PublicID logid.PublicID // Logf is where to write informational messages about this Logger. Logf logger.Logf @@ -189,8 +193,8 @@ type logWriter struct { logger *log.Logger } -func (l logWriter) Write(buf []byte) (int, error) { - l.logger.Printf("%s", buf) +func (lg logWriter) Write(buf []byte) (int, error) { + lg.logger.Printf("%s", buf) return len(buf), nil } @@ -224,6 +228,9 @@ func LogsDir(logf logger.Logf) string { logf("logpolicy: using LocalAppData dir %v", dir) return dir case "linux": + if distro.Get() == distro.JetKVM { + return "/userdata/tailscale/var" + } // STATE_DIRECTORY is set by systemd 240+ but we support older // systems-d. For example, Ubuntu 18.04 (Bionic Beaver) is 237. systemdStateDir := os.Getenv("STATE_DIRECTORY") @@ -460,18 +467,6 @@ func New(collection string, netMon *netmon.Monitor, health *health.Tracker, logf }.New() } -// Deprecated: Use [Options.New] instead. -func NewWithConfigPath(collection, dir, cmdName string, netMon *netmon.Monitor, health *health.Tracker, logf logger.Logf) *Policy { - return Options{ - Collection: collection, - Dir: dir, - CmdName: cmdName, - NetMon: netMon, - Health: health, - Logf: logf, - }.New() -} - // Options is used to construct a [Policy]. type Options struct { // Collection is a required collection to upload logs under. @@ -495,6 +490,11 @@ type Options struct { // If non-nil, it's used to construct the default HTTP client. Health *health.Tracker + // Bus is an optional parameter for communication on the eventbus. + // If non-nil, it's passed to logtail for use in interface monitoring. + // TODO(cmol): Make this non-optional when it's plumbed in by the clients. + Bus *eventbus.Bus + // Logf is an optional logger to use. // If nil, [log.Printf] will be used instead. Logf logger.Logf @@ -517,8 +517,9 @@ type Options struct { MaxUploadSize int } -// New returns a new log policy (a logger and its instance ID). -func (opts Options) New() *Policy { +// init initializes the log policy and returns a logtail.Config and the +// Policy. +func (opts Options) init(disableLogging bool) (*logtail.Config, *Policy) { if hostinfo.IsNATLabGuestVM() { // In NATLab Gokrazy instances, tailscaled comes up concurently with // DHCP and the doesn't have DNS for a while. Wait for DHCP first. @@ -620,6 +621,7 @@ func (opts Options) New() *Policy { Stderr: logWriter{console}, CompressLogs: true, MaxUploadSize: opts.MaxUploadSize, + Bus: opts.Bus, } if opts.Collection == logtail.CollectionNode { conf.MetricsDelta = clientmetric.EncodeLogTailMetricsDelta @@ -627,7 +629,7 @@ func (opts Options) New() *Policy { conf.IncludeProcSequence = true } - if envknob.NoLogsNoSupport() || testenv.InTest() { + if disableLogging { opts.Logf("You have disabled logging. Tailscale will not be able to provide support.") conf.HTTPC = &http.Client{Transport: noopPretendSuccessTransport{}} } else { @@ -636,14 +638,21 @@ func (opts Options) New() *Policy { attachFilchBuffer(&conf, opts.Dir, opts.CmdName, opts.MaxBufferSize, opts.Logf) conf.HTTPC = opts.HTTPC - if conf.HTTPC == nil { - logHost := logtail.DefaultHost - if val := getLogTarget(); val != "" { + logHost := logtail.DefaultHost + if val := getLogTarget(); val != "" { + u, err := url.Parse(val) + if err != nil { + opts.Logf("logpolicy: invalid TS_LOG_TARGET %q: %v; using default log host", val, err) + } else if u.Host == "" { + opts.Logf("logpolicy: invalid TS_LOG_TARGET %q: missing host; using default log host", val) + } else { opts.Logf("You have enabled a non-default log target. Doing without being told to by Tailscale staff or your network administrator will make getting support difficult.") conf.BaseURL = val - u, _ := url.Parse(val) logHost = u.Host } + } + + if conf.HTTPC == nil { conf.HTTPC = &http.Client{Transport: TransportOptions{ Host: logHost, NetMon: opts.NetMon, @@ -679,13 +688,20 @@ func (opts Options) New() *Policy { opts.Logf("%s", earlyErrBuf.Bytes()) } - return &Policy{ + return &conf, &Policy{ Logtail: lw, PublicID: newc.PublicID, Logf: opts.Logf, } } +// New returns a new log policy (a logger and its instance ID). +func (opts Options) New() *Policy { + disableLogging := envknob.NoLogsNoSupport() || testenv.InTest() || runtime.GOOS == "plan9" || !buildfeatures.HasLogTail + _, policy := opts.init(disableLogging) + return policy +} + // attachFilchBuffer creates an on-disk ring buffer using filch and attaches // it to the logtail config. Note that this is optional; if no buffer is set, // logtail will use an in-memory buffer. @@ -769,7 +785,7 @@ func (p *Policy) Shutdown(ctx context.Context) error { // // The netMon parameter is optional. It should be specified in environments where // Tailscaled is manipulating the routing table. -func MakeDialFunc(netMon *netmon.Monitor, logf logger.Logf) func(ctx context.Context, netw, addr string) (net.Conn, error) { +func MakeDialFunc(netMon *netmon.Monitor, logf logger.Logf) netx.DialFunc { if netMon == nil { netMon = netmon.NewStatic() } @@ -855,7 +871,7 @@ type TransportOptions struct { // New returns an HTTP Transport particularly suited to uploading logs // to the given host name. See [DialContext] for details on how it works. func (opts TransportOptions) New() http.RoundTripper { - if testenv.InTest() { + if testenv.InTest() || envknob.NoLogsNoSupport() { return noopPretendSuccessTransport{} } if opts.NetMon == nil { @@ -867,8 +883,12 @@ func (opts TransportOptions) New() http.RoundTripper { tr.TLSClientConfig = opts.TLSClientConfig.Clone() } - tr.Proxy = tshttpproxy.ProxyFromEnvironment - tshttpproxy.SetTransportGetProxyConnectHeader(tr) + if buildfeatures.HasUseProxy { + tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil() + if set, ok := feature.HookProxySetTransportGetProxyConnectHeader.GetOk(); ok { + set(tr) + } + } // We do our own zstd compression on uploads, and responses never contain any payload, // so don't send "Accept-Encoding: gzip" to save a few bytes on the wire, since there @@ -901,8 +921,7 @@ func (opts TransportOptions) New() http.RoundTripper { tr.TLSNextProto = map[string]func(authority string, c *tls.Conn) http.RoundTripper{} } - host := cmp.Or(opts.Host, logtail.DefaultHost) - tr.TLSClientConfig = tlsdial.Config(host, opts.Health, tr.TLSClientConfig) + tr.TLSClientConfig = tlsdial.Config(opts.Health, tr.TLSClientConfig) // Force TLS 1.3 since we know log.tailscale.com supports it. tr.TLSClientConfig.MinVersion = tls.VersionTLS13 diff --git a/vendor/tailscale.com/logpolicy/maybe_syspolicy.go b/vendor/tailscale.com/logpolicy/maybe_syspolicy.go new file mode 100644 index 0000000..8b2836c --- /dev/null +++ b/vendor/tailscale.com/logpolicy/maybe_syspolicy.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_syspolicy + +package logpolicy + +import _ "tailscale.com/feature/syspolicy" diff --git a/vendor/tailscale.com/logtail/buffer.go b/vendor/tailscale.com/logtail/buffer.go index c9f2e1a..6efdbda 100644 --- a/vendor/tailscale.com/logtail/buffer.go +++ b/vendor/tailscale.com/logtail/buffer.go @@ -1,13 +1,18 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_logtail + package logtail import ( "bytes" "errors" + "expvar" "fmt" - "sync" + + "tailscale.com/metrics" + "tailscale.com/syncs" ) type Buffer interface { @@ -34,14 +39,44 @@ type memBuffer struct { next []byte pending chan qentry - dropMu sync.Mutex + dropMu syncs.Mutex dropCount int + + // Metrics (see [memBuffer.ExpVar] for details). + writeCalls expvar.Int + readCalls expvar.Int + writeBytes expvar.Int + readBytes expvar.Int + droppedBytes expvar.Int + storedBytes expvar.Int +} + +// ExpVar returns a [metrics.Set] with metrics about the buffer. +// +// - counter_write_calls: Total number of write calls. +// - counter_read_calls: Total number of read calls. +// - counter_write_bytes: Total number of bytes written. +// - counter_read_bytes: Total number of bytes read. +// - counter_dropped_bytes: Total number of bytes dropped. +// - gauge_stored_bytes: Current number of bytes stored in memory. +func (b *memBuffer) ExpVar() expvar.Var { + m := new(metrics.Set) + m.Set("counter_write_calls", &b.writeCalls) + m.Set("counter_read_calls", &b.readCalls) + m.Set("counter_write_bytes", &b.writeBytes) + m.Set("counter_read_bytes", &b.readBytes) + m.Set("counter_dropped_bytes", &b.droppedBytes) + m.Set("gauge_stored_bytes", &b.storedBytes) + return m } func (m *memBuffer) TryReadLine() ([]byte, error) { + m.readCalls.Add(1) if m.next != nil { msg := m.next m.next = nil + m.readBytes.Add(int64(len(msg))) + m.storedBytes.Add(-int64(len(msg))) return msg, nil } @@ -49,8 +84,13 @@ func (m *memBuffer) TryReadLine() ([]byte, error) { case ent := <-m.pending: if ent.dropCount > 0 { m.next = ent.msg - return fmt.Appendf(nil, "----------- %d logs dropped ----------", ent.dropCount), nil + b := fmt.Appendf(nil, "----------- %d logs dropped ----------", ent.dropCount) + m.writeBytes.Add(int64(len(b))) // indicate pseudo-injected log message + m.readBytes.Add(int64(len(b))) + return b, nil } + m.readBytes.Add(int64(len(ent.msg))) + m.storedBytes.Add(-int64(len(ent.msg))) return ent.msg, nil default: return nil, nil @@ -58,6 +98,7 @@ func (m *memBuffer) TryReadLine() ([]byte, error) { } func (m *memBuffer) Write(b []byte) (int, error) { + m.writeCalls.Add(1) m.dropMu.Lock() defer m.dropMu.Unlock() @@ -67,10 +108,13 @@ func (m *memBuffer) Write(b []byte) (int, error) { } select { case m.pending <- ent: + m.writeBytes.Add(int64(len(b))) + m.storedBytes.Add(+int64(len(b))) m.dropCount = 0 return len(b), nil default: m.dropCount++ + m.droppedBytes.Add(int64(len(b))) return 0, errBufferFull } } diff --git a/vendor/tailscale.com/logtail/config.go b/vendor/tailscale.com/logtail/config.go new file mode 100644 index 0000000..bf47dd8 --- /dev/null +++ b/vendor/tailscale.com/logtail/config.go @@ -0,0 +1,67 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package logtail + +import ( + "io" + "net/http" + "time" + + "tailscale.com/tstime" + "tailscale.com/types/logid" + "tailscale.com/util/eventbus" +) + +// DefaultHost is the default host name to upload logs to when +// Config.BaseURL isn't provided. +const DefaultHost = "log.tailscale.com" + +const defaultFlushDelay = 2 * time.Second + +const ( + // CollectionNode is the name of a logtail Config.Collection + // for tailscaled (or equivalent: IPNExtension, Android app). + CollectionNode = "tailnode.log.tailscale.io" +) + +type Config struct { + Collection string // collection name, a domain name + PrivateID logid.PrivateID // private ID for the primary log stream + CopyPrivateID logid.PrivateID // private ID for a log stream that is a superset of this log stream + BaseURL string // if empty defaults to "https://log.tailscale.com" + HTTPC *http.Client // if empty defaults to http.DefaultClient + SkipClientTime bool // if true, client_time is not written to logs + LowMemory bool // if true, logtail minimizes memory use + Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now + Stderr io.Writer // if set, logs are sent here instead of os.Stderr + Bus *eventbus.Bus // if set, uses the eventbus for awaitInternetUp instead of callback + StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only + Buffer Buffer // temp storage, if nil a MemoryBuffer + CompressLogs bool // whether to compress the log uploads + MaxUploadSize int // maximum upload size; 0 means using the default + + // MetricsDelta, if non-nil, is a func that returns an encoding + // delta in clientmetrics to upload alongside existing logs. + // It can return either an empty string (for nothing) or a string + // that's safe to embed in a JSON string literal without further escaping. + MetricsDelta func() string + + // FlushDelayFn, if non-nil is a func that returns how long to wait to + // accumulate logs before uploading them. 0 or negative means to upload + // immediately. + // + // If nil, a default value is used. (currently 2 seconds) + FlushDelayFn func() time.Duration + + // IncludeProcID, if true, results in an ephemeral process identifier being + // included in logs. The ID is random and not guaranteed to be globally + // unique, but it can be used to distinguish between different instances + // running with same PrivateID. + IncludeProcID bool + + // IncludeProcSequence, if true, results in an ephemeral sequence number + // being included in the logs. The sequence number is incremented for each + // log message sent, but is not persisted across process restarts. + IncludeProcSequence bool +} diff --git a/vendor/tailscale.com/logtail/filch/filch.go b/vendor/tailscale.com/logtail/filch/filch.go index d00206d..88c72f2 100644 --- a/vendor/tailscale.com/logtail/filch/filch.go +++ b/vendor/tailscale.com/logtail/filch/filch.go @@ -1,148 +1,421 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_logtail + // Package filch is a file system queue that pilfers your stderr. // (A FILe CHannel that filches.) package filch import ( - "bufio" "bytes" + "cmp" + "errors" + "expvar" "fmt" "io" "os" + "slices" "sync" + + "tailscale.com/metrics" + "tailscale.com/util/must" ) var stderrFD = 2 // a variable for testing -const defaultMaxFileSize = 50 << 20 +var errTooLong = errors.New("filch: line too long") +var errClosed = errors.New("filch: buffer is closed") + +const DefaultMaxLineSize = 64 << 10 +const DefaultMaxFileSize = 50 << 20 type Options struct { - ReplaceStderr bool // dup over fd 2 so everything written to stderr comes here - MaxFileSize int + // ReplaceStderr specifies whether to filch [os.Stderr] such that + // everything written there appears in the [Filch] buffer instead. + // In order to write to stderr instead of writing to [Filch], + // then use [Filch.OrigStderr]. + ReplaceStderr bool + + // MaxLineSize is the maximum line size that could be encountered, + // including the trailing newline. This is enforced as a hard limit. + // Writes larger than this will be rejected. Reads larger than this + // will report an error and skip over the long line. + // If zero, the [DefaultMaxLineSize] is used. + MaxLineSize int + + // MaxFileSize specifies the maximum space on disk to use for logs. + // This is not enforced as a hard limit, but rather a soft limit. + // If zero, then [DefaultMaxFileSize] is used. + MaxFileSize int } // A Filch uses two alternating files as a simplistic ring buffer. type Filch struct { + // OrigStderr is the original [os.Stderr] if [Options.ReplaceStderr] is specified. + // Writing directly to this avoids writing into the Filch buffer. + // Otherwise, it is nil. OrigStderr *os.File - mu sync.Mutex - cur *os.File - alt *os.File - altscan *bufio.Scanner - recovered int64 + // maxLineSize specifies the maximum line size to use. + maxLineSize int // immutable once set - maxFileSize int64 - writeCounter int + // maxFileSize specifies the max space either newer and older should use. + maxFileSize int64 // immutable once set - // buf is an initial buffer for altscan. - // As of August 2021, 99.96% of all log lines - // are below 4096 bytes in length. - // Since this cutoff is arbitrary, instead of using 4096, - // we subtract off the size of the rest of the struct - // so that the whole struct takes 4096 bytes - // (less on 32 bit platforms). - // This reduces allocation waste. - buf [4096 - 64]byte + mu sync.Mutex + newer *os.File // newer logs data; writes are appended to the end + older *os.File // older logs data; reads are consumed from the start + + newlyWrittenBytes int64 // bytes written directly to newer; reset upon rotation + newlyFilchedBytes int64 // bytes filched indirectly to newer; reset upon rotation + + wrBuf []byte // temporary buffer for writing; only used for writes without trailing newline + wrBufMaxLen int // maximum length of wrBuf; reduced upon every rotation + + rdBufIdx int // index into rdBuf for the next unread bytes + rdBuf []byte // temporary buffer for reading + rdBufMaxLen int // maximum length of rdBuf; reduced upon every rotation + + // Metrics (see [Filch.ExpVar] for details). + writeCalls expvar.Int + readCalls expvar.Int + rotateCalls expvar.Int + callErrors expvar.Int + writeBytes expvar.Int + readBytes expvar.Int + filchedBytes expvar.Int + droppedBytes expvar.Int + storedBytes expvar.Int +} + +// ExpVar returns a [metrics.Set] with metrics about the buffer. +// +// - counter_write_calls: Total number of calls to [Filch.Write] +// (excludes calls when file is closed). +// +// - counter_read_calls: Total number of calls to [Filch.TryReadLine] +// (excludes calls when file is closed or no bytes). +// +// - counter_rotate_calls: Total number of calls to rotate the log files +// (excludes calls when there is nothing to rotate to). +// +// - counter_call_errors: Total number of calls returning errors. +// +// - counter_write_bytes: Total number of bytes written +// (includes bytes filched from stderr). +// +// - counter_read_bytes: Total number of bytes read +// (includes bytes filched from stderr). +// +// - counter_filched_bytes: Total number of bytes filched from stderr. +// +// - counter_dropped_bytes: Total number of bytes dropped +// (includes bytes filched from stderr and lines too long to read). +// +// - gauge_stored_bytes: Current number of bytes stored on disk. +func (f *Filch) ExpVar() expvar.Var { + m := new(metrics.Set) + m.Set("counter_write_calls", &f.writeCalls) + m.Set("counter_read_calls", &f.readCalls) + m.Set("counter_rotate_calls", &f.rotateCalls) + m.Set("counter_call_errors", &f.callErrors) + m.Set("counter_write_bytes", &f.writeBytes) + m.Set("counter_read_bytes", &f.readBytes) + m.Set("counter_filched_bytes", &f.filchedBytes) + m.Set("counter_dropped_bytes", &f.droppedBytes) + m.Set("gauge_stored_bytes", &f.storedBytes) + return m +} + +func (f *Filch) unreadReadBuffer() []byte { + return f.rdBuf[f.rdBufIdx:] +} +func (f *Filch) availReadBuffer() []byte { + return f.rdBuf[len(f.rdBuf):cap(f.rdBuf)] +} +func (f *Filch) resetReadBuffer() { + f.rdBufIdx, f.rdBuf = 0, f.rdBuf[:0] +} +func (f *Filch) moveReadBufferToFront() { + f.rdBufIdx, f.rdBuf = 0, f.rdBuf[:copy(f.rdBuf, f.rdBuf[f.rdBufIdx:])] +} +func (f *Filch) growReadBuffer() { + f.rdBuf = slices.Grow(f.rdBuf, cap(f.rdBuf)+1) +} +func (f *Filch) consumeReadBuffer(n int) { + f.rdBufIdx += n +} +func (f *Filch) appendReadBuffer(n int) { + f.rdBuf = f.rdBuf[:len(f.rdBuf)+n] + f.rdBufMaxLen = max(f.rdBufMaxLen, len(f.rdBuf)) } // TryReadline implements the logtail.Buffer interface. -func (f *Filch) TryReadLine() ([]byte, error) { +func (f *Filch) TryReadLine() (b []byte, err error) { f.mu.Lock() defer f.mu.Unlock() - - if f.altscan != nil { - if b, err := f.scan(); b != nil || err != nil { - return b, err - } + if f.older == nil { + return nil, io.EOF } - f.cur, f.alt = f.alt, f.cur - if f.OrigStderr != nil { - if err := dup2Stderr(f.cur); err != nil { + var tooLong bool // whether we are in a line that is too long + defer func() { + f.consumeReadBuffer(len(b)) + if tooLong || len(b) > f.maxLineSize { + f.droppedBytes.Add(int64(len(b))) + b, err = nil, cmp.Or(err, errTooLong) + } else { + f.readBytes.Add(int64(len(b))) + } + if len(b) != 0 || err != nil { + f.readCalls.Add(1) + } + if err != nil { + f.callErrors.Add(1) + } + }() + + for { + // Check if unread buffer already has the next line. + unread := f.unreadReadBuffer() + if i := bytes.IndexByte(unread, '\n') + len("\n"); i > 0 { + return unread[:i], nil + } + + // Check whether to make space for more data to read. + avail := f.availReadBuffer() + if len(avail) == 0 { + switch { + case len(unread) > f.maxLineSize: + tooLong = true + f.droppedBytes.Add(int64(len(unread))) + f.resetReadBuffer() + case len(unread) < cap(f.rdBuf)/10: + f.moveReadBufferToFront() + default: + f.growReadBuffer() + } + avail = f.availReadBuffer() // invariant: len(avail) > 0 + } + + // Read data into the available buffer. + n, err := f.older.Read(avail) + f.appendReadBuffer(n) + if err != nil { + if err == io.EOF { + unread = f.unreadReadBuffer() + if len(unread) == 0 { + if err := f.rotateLocked(); err != nil { + return nil, err + } + if f.storedBytes.Value() == 0 { + return nil, nil + } + continue + } + return unread, nil + } return nil, err } } - if _, err := f.alt.Seek(0, io.SeekStart); err != nil { - return nil, err - } - f.altscan = bufio.NewScanner(f.alt) - f.altscan.Buffer(f.buf[:], bufio.MaxScanTokenSize) - f.altscan.Split(splitLines) - return f.scan() } -func (f *Filch) scan() ([]byte, error) { - if f.altscan.Scan() { - return f.altscan.Bytes(), nil - } - err := f.altscan.Err() - err2 := f.alt.Truncate(0) - _, err3 := f.alt.Seek(0, io.SeekStart) - f.altscan = nil - if err != nil { - return nil, err - } - if err2 != nil { - return nil, err2 - } - if err3 != nil { - return nil, err3 - } - return nil, nil -} +var alwaysStatForTests bool // Write implements the logtail.Buffer interface. -func (f *Filch) Write(b []byte) (int, error) { +func (f *Filch) Write(b []byte) (n int, err error) { f.mu.Lock() defer f.mu.Unlock() - if f.writeCounter == 100 { - // Check the file size every 100 writes. - f.writeCounter = 0 - fi, err := f.cur.Stat() + if f.newer == nil { + return 0, errClosed + } + + defer func() { + f.writeCalls.Add(1) if err != nil { - return 0, err + f.callErrors.Add(1) } - if fi.Size() >= f.maxFileSize { - // This most likely means we are not draining. - // To limit the amount of space we use, throw away the old logs. - if err := moveContents(f.alt, f.cur); err != nil { + }() + + // To make sure we do not write data to disk unbounded + // (in the event that we are not draining fast enough) + // check whether we exceeded maxFileSize. + // If so, then force a file rotation. + if f.newlyWrittenBytes+f.newlyFilchedBytes > f.maxFileSize || f.writeCalls.Value()%100 == 0 || alwaysStatForTests { + f.statAndUpdateBytes() + if f.newlyWrittenBytes+f.newlyFilchedBytes > f.maxFileSize { + if err := f.rotateLocked(); err != nil { return 0, err } } } - f.writeCounter++ + // Write the log entry (appending a newline character if needed). + var newline string if len(b) == 0 || b[len(b)-1] != '\n' { - bnl := make([]byte, len(b)+1) - copy(bnl, b) - bnl[len(bnl)-1] = '\n' - return f.cur.Write(bnl) + newline = "\n" + f.wrBuf = append(append(f.wrBuf[:0], b...), newline...) + f.wrBufMaxLen = max(f.wrBufMaxLen, len(f.wrBuf)) + b = f.wrBuf } - return f.cur.Write(b) + if len(b) > f.maxLineSize { + for line := range bytes.Lines(b) { + if len(line) > f.maxLineSize { + return 0, errTooLong + } + } + } + n, err = f.newer.Write(b) + f.writeBytes.Add(int64(n)) + f.storedBytes.Add(int64(n)) + f.newlyWrittenBytes += int64(n) + return n - len(newline), err // subtract possibly appended newline } -// Close closes the Filch, releasing all os resources. -func (f *Filch) Close() (err error) { +func (f *Filch) statAndUpdateBytes() { + if fi, err := f.newer.Stat(); err == nil { + prevSize := f.newlyWrittenBytes + f.newlyFilchedBytes + filchedBytes := max(0, fi.Size()-prevSize) + f.writeBytes.Add(filchedBytes) + f.filchedBytes.Add(filchedBytes) + f.storedBytes.Add(filchedBytes) + f.newlyFilchedBytes += filchedBytes + } +} + +func (f *Filch) storedBytesForTest() int64 { + return must.Get(f.newer.Stat()).Size() + must.Get(f.older.Stat()).Size() +} + +var activeStderrWriteForTest sync.RWMutex + +// stderrWriteForTest calls [os.Stderr.Write], but respects calls to [waitIdleStderrForTest]. +func stderrWriteForTest(b []byte) int { + activeStderrWriteForTest.RLock() + defer activeStderrWriteForTest.RUnlock() + return must.Get(os.Stderr.Write(b)) +} + +// waitIdleStderrForTest waits until there are no active stderrWriteForTest calls. +func waitIdleStderrForTest() { + activeStderrWriteForTest.Lock() + defer activeStderrWriteForTest.Unlock() +} + +// rotateLocked swaps f.newer and f.older such that: +// +// - f.newer will be truncated and future writes will be appended to the end. +// - if [Options.ReplaceStderr], then stderr writes will redirect to f.newer +// - f.older will contain historical data, reads will consume from the start. +// - f.older is guaranteed to be immutable. +// +// There are two reasons for rotating: +// +// - The reader finished reading f.older. +// No data should be lost under this condition. +// +// - The writer exceeded a limit for f.newer. +// Data may be lost under this cxondition. +func (f *Filch) rotateLocked() error { + f.rotateCalls.Add(1) + + // Truncate the older file. + if fi, err := f.older.Stat(); err != nil { + return err + } else if fi.Size() > 0 { + // Update dropped bytes. + if pos, err := f.older.Seek(0, io.SeekCurrent); err == nil { + rdPos := pos - int64(len(f.unreadReadBuffer())) // adjust for data already read into the read buffer + f.droppedBytes.Add(max(0, fi.Size()-rdPos)) + } + f.resetReadBuffer() + + // Truncate the older file and write relative to the start. + if err := f.older.Truncate(0); err != nil { + return err + } + if _, err := f.older.Seek(0, io.SeekStart); err != nil { + return err + } + } + + // Swap newer and older. + f.newer, f.older = f.older, f.newer + + // If necessary, filch stderr into newer instead of older. + // This must be done after truncation otherwise + // we might lose some stderr data asynchronously written + // right in the middle of a rotation. + // Note that mutex does not prevent stderr writes. + prevSize := f.newlyWrittenBytes + f.newlyFilchedBytes + f.newlyWrittenBytes, f.newlyFilchedBytes = 0, 0 + if f.OrigStderr != nil { + if err := dup2Stderr(f.newer); err != nil { + return err + } + } + + // Update filched bytes and stored bytes metrics. + // This must be done after filching to newer + // so that f.older.Stat is *mostly* stable. + // + // NOTE: Unfortunately, an asynchronous os.Stderr.Write call + // that is already in progress when we called dup2Stderr + // will still write to the previous FD and + // may not be immediately observable by this Stat call. + // This is fundamentally unsolvable with the current design + // as we cannot synchronize all other os.Stderr.Write calls. + // In rare cases, it is possible that [Filch.TryReadLine] consumes + // the entire older file before the write commits, + // leading to dropped stderr lines. + waitIdleStderrForTest() + if fi, err := f.older.Stat(); err != nil { + return err + } else { + filchedBytes := max(0, fi.Size()-prevSize) + f.writeBytes.Add(filchedBytes) + f.filchedBytes.Add(filchedBytes) + f.storedBytes.Set(fi.Size()) // newer has been truncated, so only older matters + } + + // Start reading from the start of older. + if _, err := f.older.Seek(0, io.SeekStart); err != nil { + return err + } + + // Garbage collect unnecessarily large buffers. + mayGarbageCollect := func(b []byte, maxLen int) ([]byte, int) { + if cap(b)/4 > maxLen { // if less than 25% utilized + b = slices.Grow([]byte(nil), 2*maxLen) + } + maxLen = 3 * (maxLen / 4) // reduce by 25% + return b, maxLen + } + f.wrBuf, f.wrBufMaxLen = mayGarbageCollect(f.wrBuf, f.wrBufMaxLen) + f.rdBuf, f.rdBufMaxLen = mayGarbageCollect(f.rdBuf, f.rdBufMaxLen) + + return nil +} + +// Close closes the Filch, releasing all resources. +func (f *Filch) Close() error { f.mu.Lock() defer f.mu.Unlock() - + var errUnsave, errCloseNew, errCloseOld error if f.OrigStderr != nil { - if err2 := unsaveStderr(f.OrigStderr); err == nil { - err = err2 - } + errUnsave = unsaveStderr(f.OrigStderr) f.OrigStderr = nil } - - if err2 := f.cur.Close(); err == nil { - err = err2 + if f.newer != nil { + errCloseNew = f.newer.Close() + f.newer = nil } - if err2 := f.alt.Close(); err == nil { - err = err2 + if f.older != nil { + errCloseOld = f.older.Close() + f.older = nil } - - return err + return errors.Join(errUnsave, errCloseNew, errCloseOld) } // New creates a new filch around two log files, each starting with filePrefix. @@ -181,14 +454,10 @@ func New(filePrefix string, opts Options) (f *Filch, err error) { return nil, err } - mfs := defaultMaxFileSize - if opts.MaxFileSize > 0 { - mfs = opts.MaxFileSize - } - f = &Filch{ - OrigStderr: os.Stderr, // temporary, for past logs recovery - maxFileSize: int64(mfs), - } + f = new(Filch) + f.maxLineSize = int(cmp.Or(max(0, opts.MaxLineSize), DefaultMaxLineSize)) + f.maxFileSize = int64(cmp.Or(max(0, opts.MaxFileSize), DefaultMaxFileSize)) + f.maxFileSize /= 2 // since there are two log files that combine to equal MaxFileSize // Neither, either, or both files may exist and contain logs from // the last time the process ran. The three cases are: @@ -198,35 +467,22 @@ func New(filePrefix string, opts Options) (f *Filch, err error) { // - both: the files were swapped and were starting to be // read out, while new logs streamed into the other // file, but the read out did not complete - if n := fi1.Size() + fi2.Size(); n > 0 { - f.recovered = n - } switch { case fi1.Size() > 0 && fi2.Size() == 0: - f.cur, f.alt = f2, f1 + f.newer, f.older = f2, f1 // use empty file as newer case fi2.Size() > 0 && fi1.Size() == 0: - f.cur, f.alt = f1, f2 - case fi1.Size() > 0 && fi2.Size() > 0: // both - // We need to pick one of the files to be the elder, - // which we do using the mtime. - var older, newer *os.File - if fi1.ModTime().Before(fi2.ModTime()) { - older, newer = f1, f2 - } else { - older, newer = f2, f1 - } - if err := moveContents(older, newer); err != nil { - fmt.Fprintf(f.OrigStderr, "filch: recover move failed: %v\n", err) - fmt.Fprintf(older, "filch: recover move failed: %v\n", err) - } - f.cur, f.alt = newer, older + f.newer, f.older = f1, f2 // use empty file as newer + case fi1.ModTime().Before(fi2.ModTime()): + f.newer, f.older = f2, f1 // use older file as older + case fi2.ModTime().Before(fi1.ModTime()): + f.newer, f.older = f1, f2 // use newer file as newer default: - f.cur, f.alt = f1, f2 // does not matter + f.newer, f.older = f1, f2 // does not matter } - if f.recovered > 0 { - f.altscan = bufio.NewScanner(f.alt) - f.altscan.Buffer(f.buf[:], bufio.MaxScanTokenSize) - f.altscan.Split(splitLines) + f.writeBytes.Set(fi1.Size() + fi2.Size()) + f.storedBytes.Set(fi1.Size() + fi2.Size()) + if fi, err := f.newer.Stat(); err == nil { + f.newlyWrittenBytes = fi.Size() } f.OrigStderr = nil @@ -235,50 +491,10 @@ func New(filePrefix string, opts Options) (f *Filch, err error) { if err != nil { return nil, err } - if err := dup2Stderr(f.cur); err != nil { + if err := dup2Stderr(f.newer); err != nil { return nil, err } } return f, nil } - -func moveContents(dst, src *os.File) (err error) { - defer func() { - _, err2 := src.Seek(0, io.SeekStart) - err3 := src.Truncate(0) - _, err4 := dst.Seek(0, io.SeekStart) - if err == nil { - err = err2 - } - if err == nil { - err = err3 - } - if err == nil { - err = err4 - } - }() - if _, err := src.Seek(0, io.SeekStart); err != nil { - return err - } - if _, err := dst.Seek(0, io.SeekStart); err != nil { - return err - } - if _, err := io.Copy(dst, src); err != nil { - return err - } - return nil -} - -func splitLines(data []byte, atEOF bool) (advance int, token []byte, err error) { - if atEOF && len(data) == 0 { - return 0, nil, nil - } - if i := bytes.IndexByte(data, '\n'); i >= 0 { - return i + 1, data[0 : i+1], nil - } - if atEOF { - return len(data), data, nil - } - return 0, nil, nil -} diff --git a/vendor/tailscale.com/logtail/filch/filch_omit.go b/vendor/tailscale.com/logtail/filch/filch_omit.go new file mode 100644 index 0000000..898978e --- /dev/null +++ b/vendor/tailscale.com/logtail/filch/filch_omit.go @@ -0,0 +1,34 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_logtail + +package filch + +import "os" + +type Options struct { + ReplaceStderr bool + MaxLineSize int + MaxFileSize int +} + +type Filch struct { + OrigStderr *os.File +} + +func (*Filch) TryReadLine() ([]byte, error) { + return nil, nil +} + +func (*Filch) Write(b []byte) (int, error) { + return len(b), nil +} + +func (f *Filch) Close() error { + return nil +} + +func New(string, Options) (*Filch, error) { + return new(Filch), nil +} diff --git a/vendor/tailscale.com/logtail/filch/filch_stub.go b/vendor/tailscale.com/logtail/filch/filch_stub.go index 3bb82b1..f2aeeb9 100644 --- a/vendor/tailscale.com/logtail/filch/filch_stub.go +++ b/vendor/tailscale.com/logtail/filch/filch_stub.go @@ -1,13 +1,13 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build wasm || plan9 || tamago +//go:build !ts_omit_logtail && (wasm || plan9 || tamago) package filch -import ( - "os" -) +import "os" + +const replaceStderrSupportedForTest = false func saveStderr() (*os.File, error) { return os.Stderr, nil diff --git a/vendor/tailscale.com/logtail/filch/filch_unix.go b/vendor/tailscale.com/logtail/filch/filch_unix.go index 2eae70a..27f1d02 100644 --- a/vendor/tailscale.com/logtail/filch/filch_unix.go +++ b/vendor/tailscale.com/logtail/filch/filch_unix.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !windows && !wasm && !plan9 && !tamago +//go:build !ts_omit_logtail && !windows && !wasm && !plan9 && !tamago package filch @@ -11,6 +11,8 @@ import ( "golang.org/x/sys/unix" ) +const replaceStderrSupportedForTest = true + func saveStderr() (*os.File, error) { fd, err := unix.Dup(stderrFD) if err != nil { diff --git a/vendor/tailscale.com/logtail/filch/filch_windows.go b/vendor/tailscale.com/logtail/filch/filch_windows.go index d60514b..b08b64d 100644 --- a/vendor/tailscale.com/logtail/filch/filch_windows.go +++ b/vendor/tailscale.com/logtail/filch/filch_windows.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_logtail && windows + package filch import ( @@ -9,6 +11,8 @@ import ( "syscall" ) +const replaceStderrSupportedForTest = true + var kernel32 = syscall.MustLoadDLL("kernel32.dll") var procSetStdHandle = kernel32.MustFindProc("SetStdHandle") diff --git a/vendor/tailscale.com/logtail/logtail.go b/vendor/tailscale.com/logtail/logtail.go index a617397..ce50c1c 100644 --- a/vendor/tailscale.com/logtail/logtail.go +++ b/vendor/tailscale.com/logtail/logtail.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_logtail + // Package logtail sends logs to log.tailscale.com. package logtail @@ -10,14 +12,13 @@ import ( "context" "crypto/rand" "encoding/binary" + "expvar" "fmt" "io" "log" mrand "math/rand/v2" "net/http" - "net/netip" "os" - "regexp" "runtime" "slices" "strconv" @@ -25,14 +26,16 @@ import ( "sync/atomic" "time" + "github.com/creachadair/msync/trigger" "github.com/go-json-experiment/json/jsontext" "tailscale.com/envknob" + "tailscale.com/metrics" "tailscale.com/net/netmon" "tailscale.com/net/sockstats" - "tailscale.com/net/tsaddr" "tailscale.com/tstime" tslogger "tailscale.com/types/logger" "tailscale.com/types/logid" + "tailscale.com/util/eventbus" "tailscale.com/util/set" "tailscale.com/util/truncate" "tailscale.com/util/zstdframe" @@ -54,58 +57,6 @@ const lowMemRatio = 4 // but not too large to be a notable waste of memory if retained forever. const bufferSize = 4 << 10 -// DefaultHost is the default host name to upload logs to when -// Config.BaseURL isn't provided. -const DefaultHost = "log.tailscale.com" - -const defaultFlushDelay = 2 * time.Second - -const ( - // CollectionNode is the name of a logtail Config.Collection - // for tailscaled (or equivalent: IPNExtension, Android app). - CollectionNode = "tailnode.log.tailscale.io" -) - -type Config struct { - Collection string // collection name, a domain name - PrivateID logid.PrivateID // private ID for the primary log stream - CopyPrivateID logid.PrivateID // private ID for a log stream that is a superset of this log stream - BaseURL string // if empty defaults to "https://log.tailscale.com" - HTTPC *http.Client // if empty defaults to http.DefaultClient - SkipClientTime bool // if true, client_time is not written to logs - LowMemory bool // if true, logtail minimizes memory use - Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now - Stderr io.Writer // if set, logs are sent here instead of os.Stderr - StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only - Buffer Buffer // temp storage, if nil a MemoryBuffer - CompressLogs bool // whether to compress the log uploads - MaxUploadSize int // maximum upload size; 0 means using the default - - // MetricsDelta, if non-nil, is a func that returns an encoding - // delta in clientmetrics to upload alongside existing logs. - // It can return either an empty string (for nothing) or a string - // that's safe to embed in a JSON string literal without further escaping. - MetricsDelta func() string - - // FlushDelayFn, if non-nil is a func that returns how long to wait to - // accumulate logs before uploading them. 0 or negative means to upload - // immediately. - // - // If nil, a default value is used. (currently 2 seconds) - FlushDelayFn func() time.Duration - - // IncludeProcID, if true, results in an ephemeral process identifier being - // included in logs. The ID is random and not guaranteed to be globally - // unique, but it can be used to distinguish between different instances - // running with same PrivateID. - IncludeProcID bool - - // IncludeProcSequence, if true, results in an ephemeral sequence number - // being included in the logs. The sequence number is incremented for each - // log message sent, but is not persisted across process restarts. - IncludeProcSequence bool -} - func NewLogger(cfg Config, logf tslogger.Logf) *Logger { if cfg.BaseURL == "" { cfg.BaseURL = "https://" + DefaultHost @@ -151,7 +102,7 @@ func NewLogger(cfg Config, logf tslogger.Logf) *Logger { if !cfg.CopyPrivateID.IsZero() { urlSuffix = "?copyId=" + cfg.CopyPrivateID.String() } - l := &Logger{ + logger := &Logger{ privateID: cfg.PrivateID, stderr: cfg.Stderr, stderrLevel: int64(cfg.StderrLevel), @@ -173,15 +124,21 @@ func NewLogger(cfg Config, logf tslogger.Logf) *Logger { shutdownStart: make(chan struct{}), shutdownDone: make(chan struct{}), } - l.SetSockstatsLabel(sockstats.LabelLogtailLogger) - l.compressLogs = cfg.CompressLogs + + if cfg.Bus != nil { + logger.eventClient = cfg.Bus.Client("logtail.Logger") + // Subscribe to change deltas from NetMon to detect when the network comes up. + eventbus.SubscribeFunc(logger.eventClient, logger.onChangeDelta) + } + logger.SetSockstatsLabel(sockstats.LabelLogtailLogger) + logger.compressLogs = cfg.CompressLogs ctx, cancel := context.WithCancel(context.Background()) - l.uploadCancel = cancel + logger.uploadCancel = cancel - go l.uploading(ctx) - l.Write([]byte("logtail started")) - return l + go logger.uploading(ctx) + logger.Write([]byte("logtail started")) + return logger } // Logger writes logs, splitting them as configured between local @@ -209,6 +166,8 @@ type Logger struct { privateID logid.PrivateID httpDoCalls atomic.Int32 sockstatsLabel atomicSocktatsLabel + eventClient *eventbus.Client + networkIsUp trigger.Cond // set/reset by netmon.ChangeDelta events procID uint32 includeProcSequence bool @@ -223,6 +182,12 @@ type Logger struct { shutdownStartMu sync.Mutex // guards the closing of shutdownStart shutdownStart chan struct{} // closed when shutdown begins shutdownDone chan struct{} // closed when shutdown complete + + // Metrics (see [Logger.ExpVar] for details). + uploadCalls expvar.Int + failedCalls expvar.Int + uploadedBytes expvar.Int + uploadingTime expvar.Int } type atomicSocktatsLabel struct{ p atomic.Uint32 } @@ -233,27 +198,27 @@ func (p *atomicSocktatsLabel) Store(label sockstats.Label) { p.p.Store(uint32(la // SetVerbosityLevel controls the verbosity level that should be // written to stderr. 0 is the default (not verbose). Levels 1 or higher // are increasingly verbose. -func (l *Logger) SetVerbosityLevel(level int) { - atomic.StoreInt64(&l.stderrLevel, int64(level)) +func (lg *Logger) SetVerbosityLevel(level int) { + atomic.StoreInt64(&lg.stderrLevel, int64(level)) } // SetNetMon sets the network monitor. // // It should not be changed concurrently with log writes and should // only be set once. -func (l *Logger) SetNetMon(lm *netmon.Monitor) { - l.netMonitor = lm +func (lg *Logger) SetNetMon(lm *netmon.Monitor) { + lg.netMonitor = lm } // SetSockstatsLabel sets the label used in sockstat logs to identify network traffic from this logger. -func (l *Logger) SetSockstatsLabel(label sockstats.Label) { - l.sockstatsLabel.Store(label) +func (lg *Logger) SetSockstatsLabel(label sockstats.Label) { + lg.sockstatsLabel.Store(label) } // PrivateID returns the logger's private log ID. // // It exists for internal use only. -func (l *Logger) PrivateID() logid.PrivateID { return l.privateID } +func (lg *Logger) PrivateID() logid.PrivateID { return lg.privateID } // Shutdown gracefully shuts down the logger while completing any // remaining uploads. @@ -261,30 +226,33 @@ func (l *Logger) PrivateID() logid.PrivateID { return l.privateID } // It will block, continuing to try and upload unless the passed // context object interrupts it by being done. // If the shutdown is interrupted, an error is returned. -func (l *Logger) Shutdown(ctx context.Context) error { +func (lg *Logger) Shutdown(ctx context.Context) error { done := make(chan struct{}) go func() { select { case <-ctx.Done(): - l.uploadCancel() - <-l.shutdownDone - case <-l.shutdownDone: + lg.uploadCancel() + <-lg.shutdownDone + case <-lg.shutdownDone: } close(done) - l.httpc.CloseIdleConnections() + lg.httpc.CloseIdleConnections() }() - l.shutdownStartMu.Lock() + if lg.eventClient != nil { + lg.eventClient.Close() + } + lg.shutdownStartMu.Lock() select { - case <-l.shutdownStart: - l.shutdownStartMu.Unlock() + case <-lg.shutdownStart: + lg.shutdownStartMu.Unlock() return nil default: } - close(l.shutdownStart) - l.shutdownStartMu.Unlock() + close(lg.shutdownStart) + lg.shutdownStartMu.Unlock() - io.WriteString(l, "logger closing down\n") + io.WriteString(lg, "logger closing down\n") <-done return nil @@ -294,8 +262,8 @@ func (l *Logger) Shutdown(ctx context.Context) error { // process, and any associated goroutines. // // Deprecated: use Shutdown -func (l *Logger) Close() { - l.Shutdown(context.Background()) +func (lg *Logger) Close() { + lg.Shutdown(context.Background()) } // drainBlock is called by drainPending when there are no logs to drain. @@ -305,11 +273,11 @@ func (l *Logger) Close() { // // If the caller specified FlushInterface, drainWake is only sent to // periodically. -func (l *Logger) drainBlock() (shuttingDown bool) { +func (lg *Logger) drainBlock() (shuttingDown bool) { select { - case <-l.shutdownStart: + case <-lg.shutdownStart: return true - case <-l.drainWake: + case <-lg.drainWake: } return false } @@ -317,20 +285,20 @@ func (l *Logger) drainBlock() (shuttingDown bool) { // drainPending drains and encodes a batch of logs from the buffer for upload. // If no logs are available, drainPending blocks until logs are available. // The returned buffer is only valid until the next call to drainPending. -func (l *Logger) drainPending() (b []byte) { - b = l.drainBuf[:0] +func (lg *Logger) drainPending() (b []byte) { + b = lg.drainBuf[:0] b = append(b, '[') defer func() { b = bytes.TrimRight(b, ",") b = append(b, ']') - l.drainBuf = b + lg.drainBuf = b if len(b) <= len("[]") { b = nil } }() - maxLen := cmp.Or(l.maxUploadSize, maxSize) - if l.lowMem { + maxLen := cmp.Or(lg.maxUploadSize, maxSize) + if lg.lowMem { // When operating in a low memory environment, it is better to upload // in multiple operations than it is to allocate a large body and OOM. // Even if maxLen is less than maxSize, we can still upload an entry @@ -338,13 +306,13 @@ func (l *Logger) drainPending() (b []byte) { maxLen /= lowMemRatio } for len(b) < maxLen { - line, err := l.buffer.TryReadLine() + line, err := lg.buffer.TryReadLine() switch { case err == io.EOF: return b case err != nil: b = append(b, '{') - b = l.appendMetadata(b, false, true, 0, 0, "reading ringbuffer: "+err.Error(), nil, 0) + b = lg.appendMetadata(b, false, true, 0, 0, "reading ringbuffer: "+err.Error(), nil, 0) b = bytes.TrimRight(b, ",") b = append(b, '}') return b @@ -358,10 +326,10 @@ func (l *Logger) drainPending() (b []byte) { // in our buffer from a previous large write, let it go. if cap(b) > bufferSize { b = bytes.Clone(b) - l.drainBuf = b + lg.drainBuf = b } - if shuttingDown := l.drainBlock(); shuttingDown { + if shuttingDown := lg.drainBlock(); shuttingDown { return b } continue @@ -378,18 +346,18 @@ func (l *Logger) drainPending() (b []byte) { default: // This is probably a log added to stderr by filch // outside of the logtail logger. Encode it. - if !l.explainedRaw { - fmt.Fprintf(l.stderr, "RAW-STDERR: ***\n") - fmt.Fprintf(l.stderr, "RAW-STDERR: *** Lines prefixed with RAW-STDERR below bypassed logtail and probably come from a previous run of the program\n") - fmt.Fprintf(l.stderr, "RAW-STDERR: ***\n") - fmt.Fprintf(l.stderr, "RAW-STDERR:\n") - l.explainedRaw = true + if !lg.explainedRaw { + fmt.Fprintf(lg.stderr, "RAW-STDERR: ***\n") + fmt.Fprintf(lg.stderr, "RAW-STDERR: *** Lines prefixed with RAW-STDERR below bypassed logtail and probably come from a previous run of the program\n") + fmt.Fprintf(lg.stderr, "RAW-STDERR: ***\n") + fmt.Fprintf(lg.stderr, "RAW-STDERR:\n") + lg.explainedRaw = true } - fmt.Fprintf(l.stderr, "RAW-STDERR: %s", b) + fmt.Fprintf(lg.stderr, "RAW-STDERR: %s", b) // Do not add a client time, as it could be really old. // Do not include instance key or ID either, // since this came from a different instance. - b = l.appendText(b, line, true, 0, 0, 0) + b = lg.appendText(b, line, true, 0, 0, 0) } b = append(b, ',') } @@ -397,14 +365,14 @@ func (l *Logger) drainPending() (b []byte) { } // This is the goroutine that repeatedly uploads logs in the background. -func (l *Logger) uploading(ctx context.Context) { - defer close(l.shutdownDone) +func (lg *Logger) uploading(ctx context.Context) { + defer close(lg.shutdownDone) for { - body := l.drainPending() + body := lg.drainPending() origlen := -1 // sentinel value: uncompressed // Don't attempt to compress tiny bodies; not worth the CPU cycles. - if l.compressLogs && len(body) > 256 { + if lg.compressLogs && len(body) > 256 { zbody := zstdframe.AppendEncode(nil, body, zstdframe.FastestCompression, zstdframe.LowMemory(true)) @@ -421,20 +389,20 @@ func (l *Logger) uploading(ctx context.Context) { var numFailures int var firstFailure time.Time for len(body) > 0 && ctx.Err() == nil { - retryAfter, err := l.upload(ctx, body, origlen) + retryAfter, err := lg.upload(ctx, body, origlen) if err != nil { numFailures++ - firstFailure = l.clock.Now() + firstFailure = lg.clock.Now() - if !l.internetUp() { - fmt.Fprintf(l.stderr, "logtail: internet down; waiting\n") - l.awaitInternetUp(ctx) + if !lg.internetUp() { + fmt.Fprintf(lg.stderr, "logtail: internet down; waiting\n") + lg.awaitInternetUp(ctx) continue } // Only print the same message once. if currError := err.Error(); lastError != currError { - fmt.Fprintf(l.stderr, "logtail: upload: %v\n", err) + fmt.Fprintf(lg.stderr, "logtail: upload: %v\n", err) lastError = currError } @@ -447,44 +415,68 @@ func (l *Logger) uploading(ctx context.Context) { } else { // Only print a success message after recovery. if numFailures > 0 { - fmt.Fprintf(l.stderr, "logtail: upload succeeded after %d failures and %s\n", numFailures, l.clock.Since(firstFailure).Round(time.Second)) + fmt.Fprintf(lg.stderr, "logtail: upload succeeded after %d failures and %s\n", numFailures, lg.clock.Since(firstFailure).Round(time.Second)) } break } } select { - case <-l.shutdownStart: + case <-lg.shutdownStart: return default: } } } -func (l *Logger) internetUp() bool { - if l.netMonitor == nil { - // No way to tell, so assume it is. +func (lg *Logger) internetUp() bool { + select { + case <-lg.networkIsUp.Ready(): return true + default: + if lg.netMonitor == nil { + return true // No way to tell, so assume it is. + } + return lg.netMonitor.InterfaceState().AnyInterfaceUp() } - return l.netMonitor.InterfaceState().AnyInterfaceUp() } -func (l *Logger) awaitInternetUp(ctx context.Context) { +// onChangeDelta is an eventbus subscriber function that handles +// [netmon.ChangeDelta] events to detect whether the Internet is expected to be +// reachable. +func (lg *Logger) onChangeDelta(delta *netmon.ChangeDelta) { + if delta.AnyInterfaceUp() { + fmt.Fprintf(lg.stderr, "logtail: internet back up\n") + lg.networkIsUp.Set() + } else { + fmt.Fprintf(lg.stderr, "logtail: network changed, but is not up\n") + lg.networkIsUp.Reset() + } +} + +func (lg *Logger) awaitInternetUp(ctx context.Context) { + if lg.eventClient != nil { + select { + case <-lg.networkIsUp.Ready(): + case <-ctx.Done(): + } + return + } upc := make(chan bool, 1) - defer l.netMonitor.RegisterChangeCallback(func(delta *netmon.ChangeDelta) { - if delta.New.AnyInterfaceUp() { + defer lg.netMonitor.RegisterChangeCallback(func(delta *netmon.ChangeDelta) { + if delta.AnyInterfaceUp() { select { case upc <- true: default: } } })() - if l.internetUp() { + if lg.internetUp() { return } select { case <-upc: - fmt.Fprintf(l.stderr, "logtail: internet back up\n") + fmt.Fprintf(lg.stderr, "logtail: internet back up\n") case <-ctx.Done(): } } @@ -492,13 +484,16 @@ func (l *Logger) awaitInternetUp(ctx context.Context) { // upload uploads body to the log server. // origlen indicates the pre-compression body length. // origlen of -1 indicates that the body is not compressed. -func (l *Logger) upload(ctx context.Context, body []byte, origlen int) (retryAfter time.Duration, err error) { +func (lg *Logger) upload(ctx context.Context, body []byte, origlen int) (retryAfter time.Duration, err error) { + lg.uploadCalls.Add(1) + startUpload := time.Now() + const maxUploadTime = 45 * time.Second - ctx = sockstats.WithSockStats(ctx, l.sockstatsLabel.Load(), l.Logf) + ctx = sockstats.WithSockStats(ctx, lg.sockstatsLabel.Load(), lg.Logf) ctx, cancel := context.WithTimeout(ctx, maxUploadTime) defer cancel() - req, err := http.NewRequestWithContext(ctx, "POST", l.url, bytes.NewReader(body)) + req, err := http.NewRequestWithContext(ctx, "POST", lg.url, bytes.NewReader(body)) if err != nil { // I know of no conditions under which this could fail. // Report it very loudly. @@ -529,18 +524,23 @@ func (l *Logger) upload(ctx context.Context, body []byte, origlen int) (retryAft compressedNote = "compressed" } - l.httpDoCalls.Add(1) - resp, err := l.httpc.Do(req) + lg.httpDoCalls.Add(1) + resp, err := lg.httpc.Do(req) if err != nil { + lg.failedCalls.Add(1) return 0, fmt.Errorf("log upload of %d bytes %s failed: %v", len(body), compressedNote, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { + lg.failedCalls.Add(1) n, _ := strconv.Atoi(resp.Header.Get("Retry-After")) b, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<10)) return time.Duration(n) * time.Second, fmt.Errorf("log upload of %d bytes %s failed %d: %s", len(body), compressedNote, resp.StatusCode, bytes.TrimSpace(b)) } + + lg.uploadedBytes.Add(int64(len(body))) + lg.uploadingTime.Add(int64(time.Since(startUpload))) return 0, nil } @@ -549,19 +549,43 @@ func (l *Logger) upload(ctx context.Context, body []byte, origlen int) (retryAft // // TODO(bradfitz): this apparently just returns nil, as of tailscale/corp@9c2ec35. // Finish cleaning this up. -func (l *Logger) Flush() error { +func (lg *Logger) Flush() error { return nil } // StartFlush starts a log upload, if anything is pending. // // If l is nil, StartFlush is a no-op. -func (l *Logger) StartFlush() { - if l != nil { - l.tryDrainWake() +func (lg *Logger) StartFlush() { + if lg != nil { + lg.tryDrainWake() } } +// ExpVar report metrics about the logger. +// +// - counter_upload_calls: Total number of upload attempts. +// +// - counter_upload_errors: Total number of upload attempts that failed. +// +// - counter_uploaded_bytes: Total number of bytes successfully uploaded +// (which is calculated after compression is applied). +// +// - counter_uploading_nsecs: Total number of nanoseconds spent uploading. +// +// - buffer: An optional [metrics.Set] with metrics for the [Buffer]. +func (lg *Logger) ExpVar() expvar.Var { + m := new(metrics.Set) + m.Set("counter_upload_calls", &lg.uploadCalls) + m.Set("counter_upload_errors", &lg.failedCalls) + m.Set("counter_uploaded_bytes", &lg.uploadedBytes) + m.Set("counter_uploading_nsecs", &lg.uploadingTime) + if v, ok := lg.buffer.(interface{ ExpVar() expvar.Var }); ok { + m.Set("buffer", v.ExpVar()) + } + return m +} + // logtailDisabled is whether logtail uploads to logcatcher are disabled. var logtailDisabled atomic.Bool @@ -574,41 +598,41 @@ var debugWakesAndUploads = envknob.RegisterBool("TS_DEBUG_LOGTAIL_WAKES") // tryDrainWake tries to send to lg.drainWake, to cause an uploading wakeup. // It does not block. -func (l *Logger) tryDrainWake() { - l.flushPending.Store(false) +func (lg *Logger) tryDrainWake() { + lg.flushPending.Store(false) if debugWakesAndUploads() { // Using println instead of log.Printf here to avoid recursing back into // ourselves. - println("logtail: try drain wake, numHTTP:", l.httpDoCalls.Load()) + println("logtail: try drain wake, numHTTP:", lg.httpDoCalls.Load()) } select { - case l.drainWake <- struct{}{}: + case lg.drainWake <- struct{}{}: default: } } -func (l *Logger) sendLocked(jsonBlob []byte) (int, error) { +func (lg *Logger) sendLocked(jsonBlob []byte) (int, error) { tapSend(jsonBlob) if logtailDisabled.Load() { return len(jsonBlob), nil } - n, err := l.buffer.Write(jsonBlob) + n, err := lg.buffer.Write(jsonBlob) flushDelay := defaultFlushDelay - if l.flushDelayFn != nil { - flushDelay = l.flushDelayFn() + if lg.flushDelayFn != nil { + flushDelay = lg.flushDelayFn() } if flushDelay > 0 { - if l.flushPending.CompareAndSwap(false, true) { - if l.flushTimer == nil { - l.flushTimer = l.clock.AfterFunc(flushDelay, l.tryDrainWake) + if lg.flushPending.CompareAndSwap(false, true) { + if lg.flushTimer == nil { + lg.flushTimer = lg.clock.AfterFunc(flushDelay, lg.tryDrainWake) } else { - l.flushTimer.Reset(flushDelay) + lg.flushTimer.Reset(flushDelay) } } } else { - l.tryDrainWake() + lg.tryDrainWake() } return n, err } @@ -616,13 +640,13 @@ func (l *Logger) sendLocked(jsonBlob []byte) (int, error) { // appendMetadata appends optional "logtail", "metrics", and "v" JSON members. // This assumes dst is already within a JSON object. // Each member is comma-terminated. -func (l *Logger) appendMetadata(dst []byte, skipClientTime, skipMetrics bool, procID uint32, procSequence uint64, errDetail string, errData jsontext.Value, level int) []byte { +func (lg *Logger) appendMetadata(dst []byte, skipClientTime, skipMetrics bool, procID uint32, procSequence uint64, errDetail string, errData jsontext.Value, level int) []byte { // Append optional logtail metadata. if !skipClientTime || procID != 0 || procSequence != 0 || errDetail != "" || errData != nil { dst = append(dst, `"logtail":{`...) if !skipClientTime { dst = append(dst, `"client_time":"`...) - dst = l.clock.Now().UTC().AppendFormat(dst, time.RFC3339Nano) + dst = lg.clock.Now().UTC().AppendFormat(dst, time.RFC3339Nano) dst = append(dst, '"', ',') } if procID != 0 { @@ -655,8 +679,8 @@ func (l *Logger) appendMetadata(dst []byte, skipClientTime, skipMetrics bool, pr } // Append optional metrics metadata. - if !skipMetrics && l.metricsDelta != nil { - if d := l.metricsDelta(); d != "" { + if !skipMetrics && lg.metricsDelta != nil { + if d := lg.metricsDelta(); d != "" { dst = append(dst, `"metrics":"`...) dst = append(dst, d...) dst = append(dst, '"', ',') @@ -676,10 +700,10 @@ func (l *Logger) appendMetadata(dst []byte, skipClientTime, skipMetrics bool, pr } // appendText appends a raw text message in the Tailscale JSON log entry format. -func (l *Logger) appendText(dst, src []byte, skipClientTime bool, procID uint32, procSequence uint64, level int) []byte { +func (lg *Logger) appendText(dst, src []byte, skipClientTime bool, procID uint32, procSequence uint64, level int) []byte { dst = slices.Grow(dst, len(src)) dst = append(dst, '{') - dst = l.appendMetadata(dst, skipClientTime, false, procID, procSequence, "", nil, level) + dst = lg.appendMetadata(dst, skipClientTime, false, procID, procSequence, "", nil, level) if len(src) == 0 { dst = bytes.TrimRight(dst, ",") return append(dst, "}\n"...) @@ -688,7 +712,7 @@ func (l *Logger) appendText(dst, src []byte, skipClientTime bool, procID uint32, // Append the text string, which may be truncated. // Invalid UTF-8 will be mangled with the Unicode replacement character. max := maxTextSize - if l.lowMem { + if lg.lowMem { max /= lowMemRatio } dst = append(dst, `"text":`...) @@ -711,19 +735,14 @@ func appendTruncatedString(dst, src []byte, n int) []byte { return dst } -func (l *Logger) AppendTextOrJSONLocked(dst, src []byte) []byte { - l.clock = tstime.StdClock{} - return l.appendTextOrJSONLocked(dst, src, 0) -} - // appendTextOrJSONLocked appends a raw text message or a raw JSON object // in the Tailscale JSON log format. -func (l *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { - if l.includeProcSequence { - l.procSequence++ +func (lg *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { + if lg.includeProcSequence { + lg.procSequence++ } if len(src) == 0 || src[0] != '{' { - return l.appendText(dst, src, l.skipClientTime, l.procID, l.procSequence, level) + return lg.appendText(dst, src, lg.skipClientTime, lg.procID, lg.procSequence, level) } // Check whether the input is a valid JSON object and @@ -735,11 +754,11 @@ func (l *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { // However, bytes.NewBuffer normally allocates unless // we immediately shallow copy it into a pre-allocated Buffer struct. // See https://go.dev/issue/67004. - l.bytesBuf = *bytes.NewBuffer(src) - defer func() { l.bytesBuf = bytes.Buffer{} }() // avoid pinning src + lg.bytesBuf = *bytes.NewBuffer(src) + defer func() { lg.bytesBuf = bytes.Buffer{} }() // avoid pinning src - dec := &l.jsonDec - dec.Reset(&l.bytesBuf) + dec := &lg.jsonDec + dec.Reset(&lg.bytesBuf) if tok, err := dec.ReadToken(); tok.Kind() != '{' || err != nil { return false } @@ -771,7 +790,7 @@ func (l *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { // Treat invalid JSON as a raw text message. if !validJSON { - return l.appendText(dst, src, l.skipClientTime, l.procID, l.procSequence, level) + return lg.appendText(dst, src, lg.skipClientTime, lg.procID, lg.procSequence, level) } // Check whether the JSON payload is too large. @@ -779,13 +798,13 @@ func (l *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { // That's okay as the Tailscale log service limit is actually 2*maxSize. // However, so long as logging applications aim to target the maxSize limit, // there should be no trouble eventually uploading logs. - maxLen := cmp.Or(l.maxUploadSize, maxSize) + maxLen := cmp.Or(lg.maxUploadSize, maxSize) if len(src) > maxLen { errDetail := fmt.Sprintf("entry too large: %d bytes", len(src)) errData := appendTruncatedString(nil, src, maxLen/len(`\uffff`)) // escaping could increase size dst = append(dst, '{') - dst = l.appendMetadata(dst, l.skipClientTime, true, l.procID, l.procSequence, errDetail, errData, level) + dst = lg.appendMetadata(dst, lg.skipClientTime, true, lg.procID, lg.procSequence, errDetail, errData, level) dst = bytes.TrimRight(dst, ",") return append(dst, "}\n"...) } @@ -802,7 +821,7 @@ func (l *Logger) appendTextOrJSONLocked(dst, src []byte, level int) []byte { } dst = slices.Grow(dst, len(src)) dst = append(dst, '{') - dst = l.appendMetadata(dst, l.skipClientTime, true, l.procID, l.procSequence, errDetail, errData, level) + dst = lg.appendMetadata(dst, lg.skipClientTime, true, lg.procID, lg.procSequence, errDetail, errData, level) if logtailValLength > 0 { // Exclude original logtail member from the message. dst = appendWithoutNewline(dst, src[len("{"):logtailKeyOffset]) @@ -829,82 +848,42 @@ func appendWithoutNewline(dst, src []byte) []byte { } // Logf logs to l using the provided fmt-style format and optional arguments. -func (l *Logger) Logf(format string, args ...any) { - fmt.Fprintf(l, format, args...) +func (lg *Logger) Logf(format string, args ...any) { + fmt.Fprintf(lg, format, args...) } -var obscureIPs = envknob.RegisterBool("TS_OBSCURE_LOGGED_IPS") - // Write logs an encoded JSON blob. // // If the []byte passed to Write is not an encoded JSON blob, // then contents is fit into a JSON blob and written. // // This is intended as an interface for the stdlib "log" package. -func (l *Logger) Write(buf []byte) (int, error) { +func (lg *Logger) Write(buf []byte) (int, error) { if len(buf) == 0 { return 0, nil } inLen := len(buf) // length as provided to us, before modifications to downstream writers level, buf := parseAndRemoveLogLevel(buf) - if l.stderr != nil && l.stderr != io.Discard && int64(level) <= atomic.LoadInt64(&l.stderrLevel) { + if lg.stderr != nil && lg.stderr != io.Discard && int64(level) <= atomic.LoadInt64(&lg.stderrLevel) { if buf[len(buf)-1] == '\n' { - l.stderr.Write(buf) + lg.stderr.Write(buf) } else { // The log package always line-terminates logs, // so this is an uncommon path. withNL := append(buf[:len(buf):len(buf)], '\n') - l.stderr.Write(withNL) + lg.stderr.Write(withNL) } } - if obscureIPs() { - buf = redactIPs(buf) - } + lg.writeLock.Lock() + defer lg.writeLock.Unlock() - l.writeLock.Lock() - defer l.writeLock.Unlock() - - b := l.appendTextOrJSONLocked(l.writeBuf[:0], buf, level) - _, err := l.sendLocked(b) + b := lg.appendTextOrJSONLocked(lg.writeBuf[:0], buf, level) + _, err := lg.sendLocked(b) return inLen, err } -var ( - regexMatchesIPv6 = regexp.MustCompile(`([0-9a-fA-F]{1,4}):([0-9a-fA-F]{1,4}):([0-9a-fA-F:]{1,4})*`) - regexMatchesIPv4 = regexp.MustCompile(`(\d{1,3})\.(\d{1,3})\.\d{1,3}\.\d{1,3}`) -) - -// redactIPs is a helper function used in Write() to redact IPs (other than tailscale IPs). -// This function takes a log line as a byte slice and -// uses regex matching to parse and find IP addresses. Based on if the IP address is IPv4 or -// IPv6, it parses and replaces the end of the addresses with an "x". This function returns the -// log line with the IPs redacted. -func redactIPs(buf []byte) []byte { - out := regexMatchesIPv6.ReplaceAllFunc(buf, func(b []byte) []byte { - ip, err := netip.ParseAddr(string(b)) - if err != nil || tsaddr.IsTailscaleIP(ip) { - return b // don't change this one - } - - prefix := bytes.Split(b, []byte(":")) - return bytes.Join(append(prefix[:2], []byte("x")), []byte(":")) - }) - - out = regexMatchesIPv4.ReplaceAllFunc(out, func(b []byte) []byte { - ip, err := netip.ParseAddr(string(b)) - if err != nil || tsaddr.IsTailscaleIP(ip) { - return b // don't change this one - } - - prefix := bytes.Split(b, []byte(".")) - return bytes.Join(append(prefix[:2], []byte("x.x")), []byte(".")) - }) - - return []byte(out) -} - var ( openBracketV = []byte("[v") v1 = []byte("[v1] ") diff --git a/vendor/tailscale.com/logtail/logtail_omit.go b/vendor/tailscale.com/logtail/logtail_omit.go new file mode 100644 index 0000000..814fd3b --- /dev/null +++ b/vendor/tailscale.com/logtail/logtail_omit.go @@ -0,0 +1,44 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_logtail + +package logtail + +import ( + "context" + + tslogger "tailscale.com/types/logger" + "tailscale.com/types/logid" +) + +// Noop implementations of everything when ts_omit_logtail is set. + +type Logger struct{} + +type Buffer any + +func Disable() {} + +func NewLogger(cfg Config, logf tslogger.Logf) *Logger { + return &Logger{} +} + +func (*Logger) Write(p []byte) (n int, err error) { + return len(p), nil +} + +func (*Logger) Logf(format string, args ...any) {} +func (*Logger) Shutdown(ctx context.Context) error { return nil } +func (*Logger) SetVerbosityLevel(level int) {} + +func (l *Logger) SetSockstatsLabel(label any) {} + +func (l *Logger) PrivateID() logid.PrivateID { return logid.PrivateID{} } +func (l *Logger) StartFlush() {} + +func RegisterLogTap(dst chan<- string) (unregister func()) { + return func() {} +} + +func (*Logger) SetNetMon(any) {} diff --git a/vendor/tailscale.com/metrics/metrics.go b/vendor/tailscale.com/metrics/metrics.go index d1b1c06..092b56c 100644 --- a/vendor/tailscale.com/metrics/metrics.go +++ b/vendor/tailscale.com/metrics/metrics.go @@ -11,7 +11,6 @@ import ( "io" "slices" "strings" - "sync" "tailscale.com/syncs" ) @@ -30,6 +29,21 @@ type Set struct { expvar.Map } +// NewSet creates and publishes a new Set with the given name. +func NewSet(name string) *Set { + s := &Set{} + expvar.Publish(name, s) + return s +} + +// NewLabelMap creates a new LabelMap metric with the given +// metric name and label name, and adds it to the Set. +func (s *Set) NewLabelMap(metric, label string) *LabelMap { + m := &LabelMap{Label: label} + s.Set(metric, m) + return m +} + // LabelMap is a string-to-Var map variable that satisfies the // expvar.Var interface. // @@ -41,7 +55,15 @@ type LabelMap struct { Label string expvar.Map // shardedIntMu orders the initialization of new shardedint keys - shardedIntMu sync.Mutex + shardedIntMu syncs.Mutex +} + +// NewLabelMap creates and publishes a new LabelMap metric with the given +// metric name and label name. +func NewLabelMap(metric, label string) *LabelMap { + m := &LabelMap{Label: label} + expvar.Publish(metric, m) + return m } // SetInt64 sets the *Int value stored under the given map key. diff --git a/vendor/tailscale.com/net/bakedroots/bakedroots.go b/vendor/tailscale.com/net/bakedroots/bakedroots.go index 42e70c0..b268b15 100644 --- a/vendor/tailscale.com/net/bakedroots/bakedroots.go +++ b/vendor/tailscale.com/net/bakedroots/bakedroots.go @@ -7,6 +7,7 @@ package bakedroots import ( "crypto/x509" + "fmt" "sync" "tailscale.com/util/testenv" @@ -14,7 +15,7 @@ import ( // Get returns the baked-in roots. // -// As of 2025-01-21, this includes only the LetsEncrypt ISRG Root X1 root. +// As of 2025-01-21, this includes only the LetsEncrypt ISRG Root X1 & X2 roots. func Get() *x509.CertPool { roots.once.Do(func() { roots.parsePEM(append( @@ -25,16 +26,9 @@ func Get() *x509.CertPool { return roots.p } -// testingTB is a subset of testing.TB needed -// to verify the caller isn't in a parallel test. -type testingTB interface { - // Setenv panics if it's in a parallel test. - Setenv(k, v string) -} - // ResetForTest resets the cached roots for testing, // optionally setting them to caPEM if non-nil. -func ResetForTest(tb testingTB, caPEM []byte) { +func ResetForTest(tb testenv.TB, caPEM []byte) { if !testenv.InTest() { panic("not in test") } @@ -43,6 +37,10 @@ func ResetForTest(tb testingTB, caPEM []byte) { roots = rootsOnce{} if caPEM != nil { roots.once.Do(func() { roots.parsePEM(caPEM) }) + tb.Cleanup(func() { + // Reset the roots to real roots for any following test. + roots = rootsOnce{} + }) } } @@ -56,7 +54,7 @@ type rootsOnce struct { func (r *rootsOnce) parsePEM(caPEM []byte) { p := x509.NewCertPool() if !p.AppendCertsFromPEM(caPEM) { - panic("bogus PEM") + panic(fmt.Sprintf("bogus PEM: %q", caPEM)) } r.p = p } diff --git a/vendor/tailscale.com/net/batching/conn.go b/vendor/tailscale.com/net/batching/conn.go new file mode 100644 index 0000000..77cdf8c --- /dev/null +++ b/vendor/tailscale.com/net/batching/conn.go @@ -0,0 +1,47 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package batching implements a socket optimized for increased throughput. +package batching + +import ( + "net/netip" + + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" + "tailscale.com/net/packet" + "tailscale.com/types/nettype" +) + +var ( + // This acts as a compile-time check for our usage of ipv6.Message in + // [Conn] for both IPv6 and IPv4 operations. + _ ipv6.Message = ipv4.Message{} +) + +// Conn is a nettype.PacketConn that provides batched i/o using +// platform-specific optimizations, e.g. {recv,send}mmsg & UDP GSO/GRO. +// +// Conn originated from (and is still used by) magicsock where its API was +// strongly influenced by [wireguard-go/conn.Bind] constraints, namely +// wireguard-go's ownership of packet memory. +type Conn interface { + nettype.PacketConn + // ReadBatch reads messages from [Conn] into msgs. It returns the number of + // messages the caller should evaluate for nonzero len, as a zero len + // message may fall on either side of a nonzero. + // + // Each [ipv6.Message.OOB] must be sized to at least MinControlMessageSize(). + ReadBatch(msgs []ipv6.Message, flags int) (n int, err error) + // WriteBatchTo writes buffs to addr. + // + // If geneve.VNI.IsSet(), then geneve is encoded into the space preceding + // offset, and offset must equal [packet.GeneveFixedHeaderLength]. If + // !geneve.VNI.IsSet() then the space preceding offset is ignored. + // + // len(buffs) must be <= batchSize supplied in TryUpgradeToConn(). + // + // WriteBatchTo may return a [neterror.ErrUDPGSODisabled] error if UDP GSO + // was disabled as a result of a send error. + WriteBatchTo(buffs [][]byte, addr netip.AddrPort, geneve packet.GeneveHeader, offset int) error +} diff --git a/vendor/tailscale.com/net/batching/conn_default.go b/vendor/tailscale.com/net/batching/conn_default.go new file mode 100644 index 0000000..37d644f --- /dev/null +++ b/vendor/tailscale.com/net/batching/conn_default.go @@ -0,0 +1,23 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !linux + +package batching + +import ( + "tailscale.com/types/nettype" +) + +// TryUpgradeToConn is no-op on all platforms except linux. +func TryUpgradeToConn(pconn nettype.PacketConn, _ string, _ int) nettype.PacketConn { + return pconn +} + +var controlMessageSize = 0 + +func MinControlMessageSize() int { + return controlMessageSize +} + +const IdealBatchSize = 1 diff --git a/vendor/tailscale.com/wgengine/magicsock/batching_conn_linux.go b/vendor/tailscale.com/net/batching/conn_linux.go similarity index 86% rename from vendor/tailscale.com/wgengine/magicsock/batching_conn_linux.go rename to vendor/tailscale.com/net/batching/conn_linux.go index 25bf974..bd7ac25 100644 --- a/vendor/tailscale.com/wgengine/magicsock/batching_conn_linux.go +++ b/vendor/tailscale.com/net/batching/conn_linux.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package magicsock +package batching import ( "encoding/binary" @@ -22,6 +22,7 @@ import ( "golang.org/x/sys/unix" "tailscale.com/hostinfo" "tailscale.com/net/neterror" + "tailscale.com/net/packet" "tailscale.com/types/nettype" ) @@ -42,10 +43,15 @@ type xnetBatchWriter interface { WriteBatch([]ipv6.Message, int) (int, error) } +var ( + // [linuxBatchingConn] implements [Conn]. + _ Conn = (*linuxBatchingConn)(nil) +) + // linuxBatchingConn is a UDP socket that provides batched i/o. It implements -// batchingConn. +// [Conn]. type linuxBatchingConn struct { - pc nettype.PacketConn + pc *net.UDPConn xpc xnetBatchReaderWriter rxOffload bool // supports UDP GRO or similar txOffload atomic.Bool // supports UDP GSO or similar @@ -92,9 +98,13 @@ const ( maxIPv6PayloadLen = 1<<16 - 1 - 8 ) -// coalesceMessages iterates msgs, coalescing them where possible while -// maintaining datagram order. All msgs have their Addr field set to addr. -func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, buffs [][]byte, msgs []ipv6.Message) int { +// coalesceMessages iterates 'buffs', setting and coalescing them in 'msgs' +// where possible while maintaining datagram order. +// +// All msgs have their Addr field set to addr. +// +// All msgs[i].Buffers[0] are preceded by a Geneve header (geneve) if geneve.VNI.IsSet(). +func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, geneve packet.GeneveHeader, buffs [][]byte, msgs []ipv6.Message, offset int) int { var ( base = -1 // index of msg we are currently coalescing into gsoSize int // segmentation size of msgs[base] @@ -105,7 +115,13 @@ func (c *linuxBatchingConn) coalesceMessages(addr *net.UDPAddr, buffs [][]byte, if addr.IP.To4() == nil { maxPayloadLen = maxIPv6PayloadLen } + vniIsSet := geneve.VNI.IsSet() for i, buff := range buffs { + if vniIsSet { + geneve.Encode(buff) + } else { + buff = buff[offset:] + } if i > 0 { msgLen := len(buff) baseLenBefore := len(msgs[base].Buffers[0]) @@ -162,7 +178,7 @@ func (c *linuxBatchingConn) putSendBatch(batch *sendBatch) { c.sendBatchPool.Put(batch) } -func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error { +func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort, geneve packet.GeneveHeader, offset int) error { batch := c.getSendBatch() defer c.putSendBatch(batch) if addr.Addr().Is6() { @@ -181,10 +197,17 @@ func (c *linuxBatchingConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) er ) retry: if c.txOffload.Load() { - n = c.coalesceMessages(batch.ua, buffs, batch.msgs) + n = c.coalesceMessages(batch.ua, geneve, buffs, batch.msgs, offset) } else { + vniIsSet := geneve.VNI.IsSet() + if vniIsSet { + offset -= packet.GeneveFixedHeaderLength + } for i := range buffs { - batch.msgs[i].Buffers[0] = buffs[i] + if vniIsSet { + geneve.Encode(buffs[i]) + } + batch.msgs[i].Buffers[0] = buffs[i][offset:] batch.msgs[i].Addr = batch.ua batch.msgs[i].OOB = batch.msgs[i].OOB[:0] } @@ -204,11 +227,7 @@ retry: } func (c *linuxBatchingConn) SyscallConn() (syscall.RawConn, error) { - sc, ok := c.pc.(syscall.Conn) - if !ok { - return nil, errUnsupportedConnType - } - return sc.SyscallConn() + return c.pc.SyscallConn() } func (c *linuxBatchingConn) writeBatch(msgs []ipv6.Message) error { @@ -334,7 +353,7 @@ func getGSOSizeFromControl(control []byte) (int, error) { ) for len(rem) > unix.SizeofCmsghdr { - hdr, data, rem, err = unix.ParseOneSocketControlMessage(control) + hdr, data, rem, err = unix.ParseOneSocketControlMessage(rem) if err != nil { return 0, fmt.Errorf("error parsing socket control message: %w", err) } @@ -364,9 +383,10 @@ func setGSOSizeInControl(control *[]byte, gsoSize uint16) { *control = (*control)[:unix.CmsgSpace(2)] } -// tryUpgradeToBatchingConn probes the capabilities of the OS and pconn, and -// upgrades pconn to a *linuxBatchingConn if appropriate. -func tryUpgradeToBatchingConn(pconn nettype.PacketConn, network string, batchSize int) nettype.PacketConn { +// TryUpgradeToConn probes the capabilities of the OS and pconn, and upgrades +// pconn to a [Conn] if appropriate. A batch size of [IdealBatchSize] is +// suggested for the best performance. +func TryUpgradeToConn(pconn nettype.PacketConn, network string, batchSize int) nettype.PacketConn { if runtime.GOOS != "linux" { // Exclude Android. return pconn @@ -388,7 +408,7 @@ func tryUpgradeToBatchingConn(pconn nettype.PacketConn, network string, batchSiz return pconn } b := &linuxBatchingConn{ - pc: pconn, + pc: uc, getGSOSizeFromControl: getGSOSizeFromControl, setGSOSizeInControl: setGSOSizeInControl, sendBatchPool: sync.Pool{ @@ -422,3 +442,19 @@ func tryUpgradeToBatchingConn(pconn nettype.PacketConn, network string, batchSiz b.txOffload.Store(txOffload) return b } + +var controlMessageSize = -1 // bomb if used for allocation before init + +func init() { + // controlMessageSize is set to hold a UDP_GRO or UDP_SEGMENT control + // message. These contain a single uint16 of data. + controlMessageSize = unix.CmsgSpace(2) +} + +// MinControlMessageSize returns the minimum control message size required to +// support read batching via [Conn.ReadBatch]. +func MinControlMessageSize() int { + return controlMessageSize +} + +const IdealBatchSize = 128 diff --git a/vendor/tailscale.com/net/captivedetection/captivedetection.go b/vendor/tailscale.com/net/captivedetection/captivedetection.go index a06362a..3ec820b 100644 --- a/vendor/tailscale.com/net/captivedetection/captivedetection.go +++ b/vendor/tailscale.com/net/captivedetection/captivedetection.go @@ -18,6 +18,7 @@ import ( "time" "tailscale.com/net/netmon" + "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/types/logger" ) @@ -32,7 +33,7 @@ type Detector struct { // currIfIndex is the index of the interface that is currently being used by the httpClient. currIfIndex int // mu guards currIfIndex. - mu sync.Mutex + mu syncs.Mutex // logf is the logger used for logging messages. If it is nil, log.Printf is used. logf logger.Logf } diff --git a/vendor/tailscale.com/net/connstats/stats.go b/vendor/tailscale.com/net/connstats/stats.go deleted file mode 100644 index 4e6d8e1..0000000 --- a/vendor/tailscale.com/net/connstats/stats.go +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package connstats maintains statistics about connections -// flowing through a TUN device (which operate at the IP layer). -package connstats - -import ( - "context" - "net/netip" - "sync" - "time" - - "golang.org/x/sync/errgroup" - "tailscale.com/net/packet" - "tailscale.com/net/tsaddr" - "tailscale.com/types/netlogtype" -) - -// Statistics maintains counters for every connection. -// All methods are safe for concurrent use. -// The zero value is ready for use. -type Statistics struct { - maxConns int // immutable once set - - mu sync.Mutex - connCnts - - connCntsCh chan connCnts - shutdownCtx context.Context - shutdown context.CancelFunc - group errgroup.Group -} - -type connCnts struct { - start time.Time - end time.Time - virtual map[netlogtype.Connection]netlogtype.Counts - physical map[netlogtype.Connection]netlogtype.Counts -} - -// NewStatistics creates a data structure for tracking connection statistics -// that periodically dumps the virtual and physical connection counts -// depending on whether the maxPeriod or maxConns is exceeded. -// The dump function is called from a single goroutine. -// Shutdown must be called to cleanup resources. -func NewStatistics(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts)) *Statistics { - s := &Statistics{maxConns: maxConns} - s.connCntsCh = make(chan connCnts, 256) - s.shutdownCtx, s.shutdown = context.WithCancel(context.Background()) - s.group.Go(func() error { - // TODO(joetsai): Using a ticker is problematic on mobile platforms - // where waking up a process every maxPeriod when there is no activity - // is a drain on battery life. Switch this instead to instead use - // a time.Timer that is triggered upon network activity. - ticker := new(time.Ticker) - if maxPeriod > 0 { - ticker = time.NewTicker(maxPeriod) - defer ticker.Stop() - } - - for { - var cc connCnts - select { - case cc = <-s.connCntsCh: - case <-ticker.C: - cc = s.extract() - case <-s.shutdownCtx.Done(): - cc = s.extract() - } - if len(cc.virtual)+len(cc.physical) > 0 && dump != nil { - dump(cc.start, cc.end, cc.virtual, cc.physical) - } - if s.shutdownCtx.Err() != nil { - return nil - } - } - }) - return s -} - -// UpdateTxVirtual updates the counters for a transmitted IP packet -// The source and destination of the packet directly correspond with -// the source and destination in netlogtype.Connection. -func (s *Statistics) UpdateTxVirtual(b []byte) { - s.updateVirtual(b, false) -} - -// UpdateRxVirtual updates the counters for a received IP packet. -// The source and destination of the packet are inverted with respect to -// the source and destination in netlogtype.Connection. -func (s *Statistics) UpdateRxVirtual(b []byte) { - s.updateVirtual(b, true) -} - -var ( - tailscaleServiceIPv4 = tsaddr.TailscaleServiceIP() - tailscaleServiceIPv6 = tsaddr.TailscaleServiceIPv6() -) - -func (s *Statistics) updateVirtual(b []byte, receive bool) { - var p packet.Parsed - p.Decode(b) - conn := netlogtype.Connection{Proto: p.IPProto, Src: p.Src, Dst: p.Dst} - if receive { - conn.Src, conn.Dst = conn.Dst, conn.Src - } - - // Network logging is defined as traffic between two Tailscale nodes. - // Traffic with the internal Tailscale service is not with another node - // and should not be logged. It also happens to be a high volume - // amount of discrete traffic flows (e.g., DNS lookups). - switch conn.Dst.Addr() { - case tailscaleServiceIPv4, tailscaleServiceIPv6: - return - } - - s.mu.Lock() - defer s.mu.Unlock() - cnts, found := s.virtual[conn] - if !found && !s.preInsertConn() { - return - } - if receive { - cnts.RxPackets++ - cnts.RxBytes += uint64(len(b)) - } else { - cnts.TxPackets++ - cnts.TxBytes += uint64(len(b)) - } - s.virtual[conn] = cnts -} - -// UpdateTxPhysical updates the counters for zero or more transmitted wireguard packets. -// The src is always a Tailscale IP address, representing some remote peer. -// The dst is a remote IP address and port that corresponds -// with some physical peer backing the Tailscale IP address. -func (s *Statistics) UpdateTxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) { - s.updatePhysical(src, dst, packets, bytes, false) -} - -// UpdateRxPhysical updates the counters for zero or more received wireguard packets. -// The src is always a Tailscale IP address, representing some remote peer. -// The dst is a remote IP address and port that corresponds -// with some physical peer backing the Tailscale IP address. -func (s *Statistics) UpdateRxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) { - s.updatePhysical(src, dst, packets, bytes, true) -} - -func (s *Statistics) updatePhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int, receive bool) { - conn := netlogtype.Connection{Src: netip.AddrPortFrom(src, 0), Dst: dst} - - s.mu.Lock() - defer s.mu.Unlock() - cnts, found := s.physical[conn] - if !found && !s.preInsertConn() { - return - } - if receive { - cnts.RxPackets += uint64(packets) - cnts.RxBytes += uint64(bytes) - } else { - cnts.TxPackets += uint64(packets) - cnts.TxBytes += uint64(bytes) - } - s.physical[conn] = cnts -} - -// preInsertConn updates the maps to handle insertion of a new connection. -// It reports false if insertion is not allowed (i.e., after shutdown). -func (s *Statistics) preInsertConn() bool { - // Check whether insertion of a new connection will exceed maxConns. - if len(s.virtual)+len(s.physical) == s.maxConns && s.maxConns > 0 { - // Extract the current statistics and send it to the serializer. - // Avoid blocking the network packet handling path. - select { - case s.connCntsCh <- s.extractLocked(): - default: - // TODO(joetsai): Log that we are dropping an entire connCounts. - } - } - - // Initialize the maps if nil. - if s.virtual == nil && s.physical == nil { - s.start = time.Now().UTC() - s.virtual = make(map[netlogtype.Connection]netlogtype.Counts) - s.physical = make(map[netlogtype.Connection]netlogtype.Counts) - } - - return s.shutdownCtx.Err() == nil -} - -func (s *Statistics) extract() connCnts { - s.mu.Lock() - defer s.mu.Unlock() - return s.extractLocked() -} - -func (s *Statistics) extractLocked() connCnts { - if len(s.virtual)+len(s.physical) == 0 { - return connCnts{} - } - s.end = time.Now().UTC() - cc := s.connCnts - s.connCnts = connCnts{} - return cc -} - -// TestExtract synchronously extracts the current network statistics map -// and resets the counters. This should only be used for testing purposes. -func (s *Statistics) TestExtract() (virtual, physical map[netlogtype.Connection]netlogtype.Counts) { - cc := s.extract() - return cc.virtual, cc.physical -} - -// Shutdown performs a final flush of statistics. -// Statistics for any subsequent calls to Update will be dropped. -// It is safe to call Shutdown concurrently and repeatedly. -func (s *Statistics) Shutdown(context.Context) error { - s.shutdown() - return s.group.Wait() -} diff --git a/vendor/tailscale.com/net/dns/config.go b/vendor/tailscale.com/net/dns/config.go index 67d3d75..2425b30 100644 --- a/vendor/tailscale.com/net/dns/config.go +++ b/vendor/tailscale.com/net/dns/config.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:generate go run tailscale.com/cmd/viewer --type=Config --clonefunc + // Package dns contains code to configure and manage DNS settings. package dns @@ -8,8 +10,12 @@ import ( "bufio" "fmt" "net/netip" + "reflect" + "slices" "sort" + "tailscale.com/control/controlknobs" + "tailscale.com/envknob" "tailscale.com/net/dns/publicdns" "tailscale.com/net/dns/resolver" "tailscale.com/net/tsaddr" @@ -47,11 +53,28 @@ type Config struct { OnlyIPv6 bool } -func (c *Config) serviceIP() netip.Addr { +var magicDNSDualStack = envknob.RegisterBool("TS_DEBUG_MAGIC_DNS_DUAL_STACK") + +// serviceIPs returns the list of service IPs where MagicDNS is reachable. +// +// The provided knobs may be nil. +func (c *Config) serviceIPs(knobs *controlknobs.Knobs) []netip.Addr { if c.OnlyIPv6 { - return tsaddr.TailscaleServiceIPv6() + return []netip.Addr{tsaddr.TailscaleServiceIPv6()} } - return tsaddr.TailscaleServiceIP() + + // TODO(bradfitz,mikeodr,raggi): include IPv6 here too; tailscale/tailscale#15404 + // And add a controlknobs knob to disable dual stack. + // + // For now, opt-in for testing. + if magicDNSDualStack() { + return []netip.Addr{ + tsaddr.TailscaleServiceIP(), + tsaddr.TailscaleServiceIPv6(), + } + } + + return []netip.Addr{tsaddr.TailscaleServiceIP()} } // WriteToBufioWriter write a debug version of c for logs to w, omitting @@ -162,21 +185,16 @@ func sameResolverNames(a, b []*dnstype.Resolver) bool { if a[i].Addr != b[i].Addr { return false } - if !sameIPs(a[i].BootstrapResolution, b[i].BootstrapResolution) { + if !slices.Equal(a[i].BootstrapResolution, b[i].BootstrapResolution) { return false } } return true } -func sameIPs(a, b []netip.Addr) bool { - if len(a) != len(b) { - return false +func (c *Config) Equal(o *Config) bool { + if c == nil || o == nil { + return c == o } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true + return reflect.DeepEqual(c, o) } diff --git a/vendor/tailscale.com/net/dns/dbus.go b/vendor/tailscale.com/net/dns/dbus.go new file mode 100644 index 0000000..c53e8b7 --- /dev/null +++ b/vendor/tailscale.com/net/dns/dbus.go @@ -0,0 +1,59 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build linux && !android && !ts_omit_dbus + +package dns + +import ( + "context" + "time" + + "github.com/godbus/dbus/v5" +) + +func init() { + optDBusPing.Set(dbusPing) + optDBusReadString.Set(dbusReadString) +} + +func dbusPing(name, objectPath string) error { + conn, err := dbus.SystemBus() + if err != nil { + // DBus probably not running. + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + obj := conn.Object(name, dbus.ObjectPath(objectPath)) + call := obj.CallWithContext(ctx, "org.freedesktop.DBus.Peer.Ping", 0) + return call.Err +} + +// dbusReadString reads a string property from the provided name and object +// path. property must be in "interface.member" notation. +func dbusReadString(name, objectPath, iface, member string) (string, error) { + conn, err := dbus.SystemBus() + if err != nil { + // DBus probably not running. + return "", err + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + obj := conn.Object(name, dbus.ObjectPath(objectPath)) + + var result dbus.Variant + err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, iface, member).Store(&result) + if err != nil { + return "", err + } + + if s, ok := result.Value().(string); ok { + return s, nil + } + return result.String(), nil +} diff --git a/vendor/tailscale.com/net/dns/debian_resolvconf.go b/vendor/tailscale.com/net/dns/debian_resolvconf.go index 3ffc796..63fd80c 100644 --- a/vendor/tailscale.com/net/dns/debian_resolvconf.go +++ b/vendor/tailscale.com/net/dns/debian_resolvconf.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux || freebsd || openbsd +//go:build (linux && !android) || freebsd || openbsd package dns diff --git a/vendor/tailscale.com/net/dns/direct.go b/vendor/tailscale.com/net/dns/direct.go index aaff18f..78495d4 100644 --- a/vendor/tailscale.com/net/dns/direct.go +++ b/vendor/tailscale.com/net/dns/direct.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !android && !ios + package dns import ( @@ -19,13 +21,16 @@ import ( "slices" "strings" "sync" + "sync/atomic" "time" + "tailscale.com/feature" "tailscale.com/health" "tailscale.com/net/dns/resolvconffile" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" "tailscale.com/version/distro" ) @@ -132,6 +137,11 @@ type directManager struct { // but is better than having non-functioning DNS. renameBroken bool + trampleCount atomic.Int64 + trampleTimer *time.Timer + eventClient *eventbus.Client + trampleDNSPub *eventbus.Publisher[TrampleDNS] + ctx context.Context // valid until Close ctxClose context.CancelFunc // closes ctx @@ -142,11 +152,13 @@ type directManager struct { } //lint:ignore U1000 used in manager_{freebsd,openbsd}.go -func newDirectManager(logf logger.Logf, health *health.Tracker) *directManager { - return newDirectManagerOnFS(logf, health, directFS{}) +func newDirectManager(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus) *directManager { + return newDirectManagerOnFS(logf, health, bus, directFS{}) } -func newDirectManagerOnFS(logf logger.Logf, health *health.Tracker, fs wholeFileFS) *directManager { +var trampleWatchDuration = 5 * time.Second + +func newDirectManagerOnFS(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, fs wholeFileFS) *directManager { ctx, cancel := context.WithCancel(context.Background()) m := &directManager{ logf: logf, @@ -155,6 +167,13 @@ func newDirectManagerOnFS(logf logger.Logf, health *health.Tracker, fs wholeFile ctx: ctx, ctxClose: cancel, } + if bus != nil { + m.eventClient = bus.Client("dns.directManager") + m.trampleDNSPub = eventbus.Publish[TrampleDNS](m.eventClient) + } + m.trampleTimer = time.AfterFunc(trampleWatchDuration, func() { + m.trampleCount.Store(0) + }) go m.runFileWatcher() return m } @@ -413,8 +432,91 @@ func (m *directManager) GetBaseConfig() (OSConfig, error) { return oscfg, nil } +// HookWatchFile is a hook for watching file changes, for platforms that support it. +// The function is called with a directory and filename to watch, and a callback +// to call when the file changes. It returns an error if the watch could not be set up. +var HookWatchFile feature.Hook[func(ctx context.Context, dir, filename string, cb func()) error] + +func (m *directManager) runFileWatcher() { + watchFile, ok := HookWatchFile.GetOk() + if !ok { + return + } + if err := watchFile(m.ctx, "/etc/", resolvConf, m.checkForFileTrample); err != nil { + // This is all best effort for now, so surface warnings to users. + m.logf("dns: inotify: %s", err) + } +} + +var resolvTrampleWarnable = health.Register(&health.Warnable{ + Code: "resolv-conf-overwritten", + Severity: health.SeverityMedium, + Title: "DNS configuration issue", + Text: health.StaticMessage("System DNS config not ideal. /etc/resolv.conf overwritten. See https://tailscale.com/s/dns-fight"), +}) + +// checkForFileTrample checks whether /etc/resolv.conf has been trampled +// by another program on the system. (e.g. a DHCP client) +func (m *directManager) checkForFileTrample() { + m.mu.Lock() + want := m.wantResolvConf + lastWarn := m.lastWarnContents + m.mu.Unlock() + + if want == nil { + return + } + + cur, err := m.fs.ReadFile(resolvConf) + if err != nil { + m.logf("trample: read error: %v", err) + return + } + if bytes.Equal(cur, want) { + m.health.SetHealthy(resolvTrampleWarnable) + if lastWarn != nil { + m.mu.Lock() + m.lastWarnContents = nil + m.mu.Unlock() + m.logf("trample: resolv.conf again matches expected content") + } + return + } + if bytes.Equal(cur, lastWarn) { + // We already logged about this, so not worth doing it again. + return + } + + m.mu.Lock() + m.lastWarnContents = cur + m.mu.Unlock() + + show := cur + if len(show) > 1024 { + show = show[:1024] + } + m.logf("trample: resolv.conf changed from what we expected. did some other program interfere? current contents: %q", show) + m.health.SetUnhealthy(resolvTrampleWarnable, nil) + if m.trampleDNSPub != nil { + n := m.trampleCount.Add(1) + + if n < 10 { + m.trampleDNSPub.Publish(TrampleDNS{ + LastTrample: time.Now(), + TramplesInTimeout: n, + }) + m.trampleTimer.Reset(trampleWatchDuration) + } else { + m.logf("trample: resolv.conf overwritten %d times, no longer attempting to replace it.", n) + } + } +} + func (m *directManager) Close() error { m.ctxClose() + if m.eventClient != nil { + m.eventClient.Close() + } // We used to keep a file for the tailscale config and symlinked // to it, but then we stopped because /etc/resolv.conf being a diff --git a/vendor/tailscale.com/net/dns/direct_linux.go b/vendor/tailscale.com/net/dns/direct_linux.go deleted file mode 100644 index 8dccc5b..0000000 --- a/vendor/tailscale.com/net/dns/direct_linux.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package dns - -import ( - "bytes" - "context" - "fmt" - - "github.com/illarion/gonotify/v3" - "tailscale.com/health" -) - -func (m *directManager) runFileWatcher() { - if err := watchFile(m.ctx, "/etc/", resolvConf, m.checkForFileTrample); err != nil { - // This is all best effort for now, so surface warnings to users. - m.logf("dns: inotify: %s", err) - } -} - -// watchFile sets up an inotify watch for a given directory and -// calls the callback function every time a particular file is changed. -// The filename should be located in the provided directory. -func watchFile(ctx context.Context, dir, filename string, cb func()) error { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - const events = gonotify.IN_ATTRIB | - gonotify.IN_CLOSE_WRITE | - gonotify.IN_CREATE | - gonotify.IN_DELETE | - gonotify.IN_MODIFY | - gonotify.IN_MOVE - - watcher, err := gonotify.NewDirWatcher(ctx, events, dir) - if err != nil { - return fmt.Errorf("NewDirWatcher: %w", err) - } - - for { - select { - case event := <-watcher.C: - if event.Name == filename { - cb() - } - case <-ctx.Done(): - return ctx.Err() - } - } -} - -var resolvTrampleWarnable = health.Register(&health.Warnable{ - Code: "resolv-conf-overwritten", - Severity: health.SeverityMedium, - Title: "Linux DNS configuration issue", - Text: health.StaticMessage("Linux DNS config not ideal. /etc/resolv.conf overwritten. See https://tailscale.com/s/dns-fight"), -}) - -// checkForFileTrample checks whether /etc/resolv.conf has been trampled -// by another program on the system. (e.g. a DHCP client) -func (m *directManager) checkForFileTrample() { - m.mu.Lock() - want := m.wantResolvConf - lastWarn := m.lastWarnContents - m.mu.Unlock() - - if want == nil { - return - } - - cur, err := m.fs.ReadFile(resolvConf) - if err != nil { - m.logf("trample: read error: %v", err) - return - } - if bytes.Equal(cur, want) { - m.health.SetHealthy(resolvTrampleWarnable) - if lastWarn != nil { - m.mu.Lock() - m.lastWarnContents = nil - m.mu.Unlock() - m.logf("trample: resolv.conf again matches expected content") - } - return - } - if bytes.Equal(cur, lastWarn) { - // We already logged about this, so not worth doing it again. - return - } - - m.mu.Lock() - m.lastWarnContents = cur - m.mu.Unlock() - - show := cur - if len(show) > 1024 { - show = show[:1024] - } - m.logf("trample: resolv.conf changed from what we expected. did some other program interfere? current contents: %q", show) - m.health.SetUnhealthy(resolvTrampleWarnable, nil) -} diff --git a/vendor/tailscale.com/net/dns/direct_notlinux.go b/vendor/tailscale.com/net/dns/direct_notlinux.go deleted file mode 100644 index c221ca1..0000000 --- a/vendor/tailscale.com/net/dns/direct_notlinux.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package dns - -func (m *directManager) runFileWatcher() { - // Not implemented on other platforms. Maybe it could resort to polling. -} diff --git a/vendor/tailscale.com/net/dns/dns_clone.go b/vendor/tailscale.com/net/dns/dns_clone.go new file mode 100644 index 0000000..807bfce --- /dev/null +++ b/vendor/tailscale.com/net/dns/dns_clone.go @@ -0,0 +1,74 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT. + +package dns + +import ( + "net/netip" + + "tailscale.com/types/dnstype" + "tailscale.com/util/dnsname" +) + +// Clone makes a deep copy of Config. +// The result aliases no memory with the original. +func (src *Config) Clone() *Config { + if src == nil { + return nil + } + dst := new(Config) + *dst = *src + if src.DefaultResolvers != nil { + dst.DefaultResolvers = make([]*dnstype.Resolver, len(src.DefaultResolvers)) + for i := range dst.DefaultResolvers { + if src.DefaultResolvers[i] == nil { + dst.DefaultResolvers[i] = nil + } else { + dst.DefaultResolvers[i] = src.DefaultResolvers[i].Clone() + } + } + } + if dst.Routes != nil { + dst.Routes = map[dnsname.FQDN][]*dnstype.Resolver{} + for k := range src.Routes { + dst.Routes[k] = append([]*dnstype.Resolver{}, src.Routes[k]...) + } + } + dst.SearchDomains = append(src.SearchDomains[:0:0], src.SearchDomains...) + if dst.Hosts != nil { + dst.Hosts = map[dnsname.FQDN][]netip.Addr{} + for k := range src.Hosts { + dst.Hosts[k] = append([]netip.Addr{}, src.Hosts[k]...) + } + } + return dst +} + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _ConfigCloneNeedsRegeneration = Config(struct { + DefaultResolvers []*dnstype.Resolver + Routes map[dnsname.FQDN][]*dnstype.Resolver + SearchDomains []dnsname.FQDN + Hosts map[dnsname.FQDN][]netip.Addr + OnlyIPv6 bool +}{}) + +// Clone duplicates src into dst and reports whether it succeeded. +// To succeed, must be of types <*T, *T> or <*T, **T>, +// where T is one of Config. +func Clone(dst, src any) bool { + switch src := src.(type) { + case *Config: + switch dst := dst.(type) { + case *Config: + *dst = *src.Clone() + return true + case **Config: + *dst = src.Clone() + return true + } + } + return false +} diff --git a/vendor/tailscale.com/net/dns/dns_view.go b/vendor/tailscale.com/net/dns/dns_view.go new file mode 100644 index 0000000..c7ce376 --- /dev/null +++ b/vendor/tailscale.com/net/dns/dns_view.go @@ -0,0 +1,138 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Code generated by tailscale/cmd/viewer; DO NOT EDIT. + +package dns + +import ( + jsonv1 "encoding/json" + "errors" + "net/netip" + + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" + "tailscale.com/types/dnstype" + "tailscale.com/types/views" + "tailscale.com/util/dnsname" +) + +//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=Config + +// View returns a read-only view of Config. +func (p *Config) View() ConfigView { + return ConfigView{ж: p} +} + +// ConfigView provides a read-only view over Config. +// +// Its methods should only be called if `Valid()` returns true. +type ConfigView struct { + // ж is the underlying mutable value, named with a hard-to-type + // character that looks pointy like a pointer. + // It is named distinctively to make you think of how dangerous it is to escape + // to callers. You must not let callers be able to mutate it. + ж *Config +} + +// Valid reports whether v's underlying value is non-nil. +func (v ConfigView) Valid() bool { return v.ж != nil } + +// AsStruct returns a clone of the underlying value which aliases no memory with +// the original. +func (v ConfigView) AsStruct() *Config { + if v.ж == nil { + return nil + } + return v.ж.Clone() +} + +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ConfigView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} + +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ConfigView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +func (v *ConfigView) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } + if len(b) == 0 { + return nil + } + var x Config + if err := jsonv1.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Config + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// DefaultResolvers are the DNS resolvers to use for DNS names +// which aren't covered by more specific per-domain routes below. +// If empty, the OS's default resolvers (the ones that predate +// Tailscale altering the configuration) are used. +func (v ConfigView) DefaultResolvers() views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { + return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](v.ж.DefaultResolvers) +} + +// Routes maps a DNS suffix to the resolvers that should be used +// for queries that fall within that suffix. +// If a query doesn't match any entry in Routes, the +// DefaultResolvers are used. +// A Routes entry with no resolvers means the route should be +// authoritatively answered using the contents of Hosts. +func (v ConfigView) Routes() views.MapFn[dnsname.FQDN, []*dnstype.Resolver, views.SliceView[*dnstype.Resolver, dnstype.ResolverView]] { + return views.MapFnOf(v.ж.Routes, func(t []*dnstype.Resolver) views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { + return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](t) + }) +} + +// SearchDomains are DNS suffixes to try when expanding +// single-label queries. +func (v ConfigView) SearchDomains() views.Slice[dnsname.FQDN] { + return views.SliceOf(v.ж.SearchDomains) +} + +// Hosts maps DNS FQDNs to their IPs, which can be a mix of IPv4 +// and IPv6. +// Queries matching entries in Hosts are resolved locally by +// 100.100.100.100 without leaving the machine. +// Adding an entry to Hosts merely creates the record. If you want +// it to resolve, you also need to add appropriate routes to +// Routes. +func (v ConfigView) Hosts() views.MapSlice[dnsname.FQDN, netip.Addr] { + return views.MapSliceOf(v.ж.Hosts) +} + +// OnlyIPv6, if true, uses the IPv6 service IP (for MagicDNS) +// instead of the IPv4 version (100.100.100.100). +func (v ConfigView) OnlyIPv6() bool { return v.ж.OnlyIPv6 } +func (v ConfigView) Equal(v2 ConfigView) bool { return v.ж.Equal(v2.ж) } + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _ConfigViewNeedsRegeneration = Config(struct { + DefaultResolvers []*dnstype.Resolver + Routes map[dnsname.FQDN][]*dnstype.Resolver + SearchDomains []dnsname.FQDN + Hosts map[dnsname.FQDN][]netip.Addr + OnlyIPv6 bool +}{}) diff --git a/vendor/tailscale.com/net/dns/manager.go b/vendor/tailscale.com/net/dns/manager.go index 1e9eb7f..4441c4f 100644 --- a/vendor/tailscale.com/net/dns/manager.go +++ b/vendor/tailscale.com/net/dns/manager.go @@ -20,17 +20,19 @@ import ( "time" "tailscale.com/control/controlknobs" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/dns/resolver" "tailscale.com/net/netmon" "tailscale.com/net/tsdial" "tailscale.com/syncs" - "tailscale.com/tstime/rate" "tailscale.com/types/dnstype" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" "tailscale.com/util/slicesx" + "tailscale.com/util/syspolicy/policyclient" ) var ( @@ -53,6 +55,8 @@ type Manager struct { logf logger.Logf health *health.Tracker + eventClient *eventbus.Client + activeQueriesAtomic int32 ctx context.Context // good until Down @@ -63,16 +67,17 @@ type Manager struct { knobs *controlknobs.Knobs // or nil goos string // if empty, gets set to runtime.GOOS - mu sync.Mutex // guards following - // config is the last configuration we successfully compiled or nil if there - // was any failure applying the last configuration. - config *Config + mu sync.Mutex // guards following + config *Config // Tracks the last viable DNS configuration set by Set. nil on failures other than compilation failures or if set has never been called. } -// NewManagers created a new manager from the given config. +// NewManager created a new manager from the given config. // // knobs may be nil. -func NewManager(logf logger.Logf, oscfg OSConfigurator, health *health.Tracker, dialer *tsdial.Dialer, linkSel resolver.ForwardLinkSelector, knobs *controlknobs.Knobs, goos string) *Manager { +func NewManager(logf logger.Logf, oscfg OSConfigurator, health *health.Tracker, dialer *tsdial.Dialer, linkSel resolver.ForwardLinkSelector, knobs *controlknobs.Knobs, goos string, bus *eventbus.Bus) *Manager { + if !buildfeatures.HasDNS { + return nil + } if dialer == nil { panic("nil Dialer") } @@ -93,19 +98,17 @@ func NewManager(logf logger.Logf, oscfg OSConfigurator, health *health.Tracker, goos: goos, } - // Rate limit our attempts to correct our DNS configuration. - // This is done on incoming queries, we don't want to spam it. - limiter := rate.NewLimiter(1.0/5.0, 1) - - // This will recompile the DNS config, which in turn will requery the system - // DNS settings. The recovery func should triggered only when we are missing - // upstream nameservers and require them to forward a query. - m.resolver.SetMissingUpstreamRecovery(func() { - if limiter.Allow() { - m.logf("resolution failed due to missing upstream nameservers. Recompiling DNS configuration.") - if err := m.RecompileDNSConfig(); err != nil { - m.logf("config recompilation failed: %v", err) - } + m.eventClient = bus.Client("dns.Manager") + eventbus.SubscribeFunc(m.eventClient, func(trample TrampleDNS) { + m.mu.Lock() + defer m.mu.Unlock() + if m.config == nil { + m.logf("resolve.conf was trampled, but there is no DNS config") + return + } + m.logf("resolve.conf was trampled, setting existing config again") + if err := m.setLocked(*m.config); err != nil { + m.logf("error setting DNS config: %s", err) } }) @@ -115,9 +118,14 @@ func NewManager(logf logger.Logf, oscfg OSConfigurator, health *health.Tracker, } // Resolver returns the Manager's DNS Resolver. -func (m *Manager) Resolver() *resolver.Resolver { return m.resolver } +func (m *Manager) Resolver() *resolver.Resolver { + if !buildfeatures.HasDNS { + return nil + } + return m.resolver +} -// RecompileDNSConfig sets the DNS config to the current value, which has +// RecompileDNSConfig recompiles the last attempted DNS configuration, which has // the side effect of re-querying the OS's interface nameservers. This should be used // on platforms where the interface nameservers can change. Darwin, for example, // where the nameservers aren't always available when we process a major interface @@ -127,17 +135,23 @@ func (m *Manager) Resolver() *resolver.Resolver { return m.resolver } // give a better or different result than when [Manager.Set] was last called. The // logic for making that determination is up to the caller. // -// It returns [ErrNoDNSConfig] if the [Manager] has no existing DNS configuration. +// It returns [ErrNoDNSConfig] if [Manager.Set] has never been called. func (m *Manager) RecompileDNSConfig() error { + if !buildfeatures.HasDNS { + return nil + } m.mu.Lock() defer m.mu.Unlock() - if m.config == nil { - return ErrNoDNSConfig + if m.config != nil { + return m.setLocked(*m.config) } - return m.setLocked(*m.config) + return ErrNoDNSConfig } func (m *Manager) Set(cfg Config) error { + if !buildfeatures.HasDNS { + return nil + } m.mu.Lock() defer m.mu.Unlock() return m.setLocked(cfg) @@ -145,6 +159,9 @@ func (m *Manager) Set(cfg Config) error { // GetBaseConfig returns the current base OS DNS configuration as provided by the OSConfigurator. func (m *Manager) GetBaseConfig() (OSConfig, error) { + if !buildfeatures.HasDNS { + panic("unreachable") + } return m.os.GetBaseConfig() } @@ -154,15 +171,15 @@ func (m *Manager) GetBaseConfig() (OSConfig, error) { func (m *Manager) setLocked(cfg Config) error { syncs.AssertLocked(&m.mu) - // On errors, the 'set' config is cleared. - m.config = nil - m.logf("Set: %v", logger.ArgWriter(func(w *bufio.Writer) { cfg.WriteToBufioWriter(w) })) rcfg, ocfg, err := m.compileConfig(cfg) if err != nil { + // On a compilation failure, set m.config set for later reuse by + // [Manager.RecompileDNSConfig] and return the error. + m.config = &cfg return err } @@ -174,10 +191,10 @@ func (m *Manager) setLocked(cfg Config) error { })) if err := m.resolver.SetConfig(rcfg); err != nil { + m.config = nil return err } - if err := m.os.SetDNS(ocfg); err != nil { - m.health.SetUnhealthy(osConfigurationSetWarnable, health.Args{health.ArgError: err.Error()}) + if err := m.setDNSLocked(ocfg); err != nil { return err } @@ -187,6 +204,15 @@ func (m *Manager) setLocked(cfg Config) error { return nil } +func (m *Manager) setDNSLocked(ocfg OSConfig) error { + if err := m.os.SetDNS(ocfg); err != nil { + m.config = nil + m.health.SetUnhealthy(osConfigurationSetWarnable, health.Args{health.ArgError: err.Error()}) + return err + } + return nil +} + // compileHostEntries creates a list of single-label resolutions possible // from the configured hosts and search domains. // The entries are compiled in the order of the search domains, then the hosts. @@ -284,7 +310,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig // Deal with trivial configs first. switch { - case !cfg.needsOSResolver(): + case !cfg.needsOSResolver() || runtime.GOOS == "plan9": // Set search domains, but nothing else. This also covers the // case where cfg is entirely zero, in which case these // configs clear all Tailscale DNS settings. @@ -307,7 +333,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig // through quad-100. rcfg.Routes = routes rcfg.Routes["."] = cfg.DefaultResolvers - ocfg.Nameservers = []netip.Addr{cfg.serviceIP()} + ocfg.Nameservers = cfg.serviceIPs(m.knobs) return rcfg, ocfg, nil } @@ -345,7 +371,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig // or routes + MagicDNS, or just MagicDNS, or on an OS that cannot // split-DNS. Install a split config pointing at quad-100. rcfg.Routes = routes - ocfg.Nameservers = []netip.Addr{cfg.serviceIP()} + ocfg.Nameservers = cfg.serviceIPs(m.knobs) var baseCfg *OSConfig // base config; non-nil if/when known @@ -355,7 +381,10 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig // that as the forwarder for all DNS traffic that quad-100 doesn't handle. if isApple || !m.os.SupportsSplitDNS() { // If the OS can't do native split-dns, read out the underlying - // resolver config and blend it into our config. + // resolver config and blend it into our config. On apple platforms, [OSConfigurator.GetBaseConfig] + // has a tendency to temporarily fail if called immediately following + // an interface change. These failures should be retried if/when the OS + // indicates that the DNS configuration has changed via [RecompileDNSConfig]. cfg, err := m.os.GetBaseConfig() if err == nil { baseCfg = &cfg @@ -451,6 +480,13 @@ const ( maxReqSizeTCP = 4096 ) +// TrampleDNS is an an event indicating we detected that DNS config was +// overwritten by another process. +type TrampleDNS struct { + LastTrample time.Time + TramplesInTimeout int64 +} + // dnsTCPSession services DNS requests sent over TCP. type dnsTCPSession struct { m *Manager @@ -572,15 +608,22 @@ func (m *Manager) HandleTCPConn(conn net.Conn, srcAddr netip.AddrPort) { } func (m *Manager) Down() error { + if !buildfeatures.HasDNS { + return nil + } m.ctxCancel() if err := m.os.Close(); err != nil { return err } + m.eventClient.Close() m.resolver.Close() return nil } func (m *Manager) FlushCaches() error { + if !buildfeatures.HasDNS { + return nil + } return flushCaches() } @@ -589,20 +632,22 @@ func (m *Manager) FlushCaches() error { // No other state needs to be instantiated before this runs. // // health must not be nil -func CleanUp(logf logger.Logf, netMon *netmon.Monitor, health *health.Tracker, interfaceName string) { - oscfg, err := NewOSConfigurator(logf, nil, nil, interfaceName) +func CleanUp(logf logger.Logf, netMon *netmon.Monitor, bus *eventbus.Bus, health *health.Tracker, interfaceName string) { + if !buildfeatures.HasDNS { + return + } + oscfg, err := NewOSConfigurator(logf, health, bus, policyclient.Get(), nil, interfaceName) if err != nil { logf("creating dns cleanup: %v", err) return } d := &tsdial.Dialer{Logf: logf} d.SetNetMon(netMon) - dns := NewManager(logf, oscfg, health, d, nil, nil, runtime.GOOS) + d.SetBus(bus) + dns := NewManager(logf, oscfg, health, d, nil, nil, runtime.GOOS, bus) if err := dns.Down(); err != nil { logf("dns down: %v", err) } } -var ( - metricDNSQueryErrorQueue = clientmetric.NewCounter("dns_query_local_error_queue") -) +var metricDNSQueryErrorQueue = clientmetric.NewCounter("dns_query_local_error_queue") diff --git a/vendor/tailscale.com/net/dns/manager_darwin.go b/vendor/tailscale.com/net/dns/manager_darwin.go index ccfafaa..01c9206 100644 --- a/vendor/tailscale.com/net/dns/manager_darwin.go +++ b/vendor/tailscale.com/net/dns/manager_darwin.go @@ -13,13 +13,15 @@ import ( "tailscale.com/net/dns/resolvconffile" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" + "tailscale.com/util/syspolicy/policyclient" ) // NewOSConfigurator creates a new OS configurator. // -// The health tracker and the knobs may be nil and are ignored on this platform. -func NewOSConfigurator(logf logger.Logf, _ *health.Tracker, _ *controlknobs.Knobs, ifName string) (OSConfigurator, error) { +// The health tracker, bus and the knobs may be nil and are ignored on this platform. +func NewOSConfigurator(logf logger.Logf, _ *health.Tracker, _ *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, ifName string) (OSConfigurator, error) { return &darwinConfigurator{logf: logf, ifName: ifName}, nil } diff --git a/vendor/tailscale.com/net/dns/manager_default.go b/vendor/tailscale.com/net/dns/manager_default.go index 99ff017..42e7d29 100644 --- a/vendor/tailscale.com/net/dns/manager_default.go +++ b/vendor/tailscale.com/net/dns/manager_default.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !linux && !freebsd && !openbsd && !windows && !darwin && !illumos && !solaris +//go:build (!linux || android) && !freebsd && !openbsd && !windows && !darwin && !illumos && !solaris && !plan9 package dns @@ -9,11 +9,13 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/health" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" ) // NewOSConfigurator creates a new OS configurator. // // The health tracker and the knobs may be nil and are ignored on this platform. -func NewOSConfigurator(logger.Logf, *health.Tracker, *controlknobs.Knobs, string) (OSConfigurator, error) { +func NewOSConfigurator(logger.Logf, *health.Tracker, *eventbus.Bus, policyclient.Client, *controlknobs.Knobs, string) (OSConfigurator, error) { return NewNoopManager() } diff --git a/vendor/tailscale.com/net/dns/manager_freebsd.go b/vendor/tailscale.com/net/dns/manager_freebsd.go index 1ec9ea8..da3a821 100644 --- a/vendor/tailscale.com/net/dns/manager_freebsd.go +++ b/vendor/tailscale.com/net/dns/manager_freebsd.go @@ -10,15 +10,17 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/health" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" ) // NewOSConfigurator creates a new OS configurator. // // The health tracker may be nil; the knobs may be nil and are ignored on this platform. -func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs.Knobs, _ string) (OSConfigurator, error) { +func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, _ string) (OSConfigurator, error) { bs, err := os.ReadFile("/etc/resolv.conf") if os.IsNotExist(err) { - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil } if err != nil { return nil, fmt.Errorf("reading /etc/resolv.conf: %w", err) @@ -28,16 +30,16 @@ func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs case "resolvconf": switch resolvconfStyle() { case "": - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil case "debian": return newDebianResolvconfManager(logf) case "openresolv": return newOpenresolvManager(logf) default: logf("[unexpected] got unknown flavor of resolvconf %q, falling back to direct manager", resolvconfStyle()) - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil } default: - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil } } diff --git a/vendor/tailscale.com/net/dns/manager_linux.go b/vendor/tailscale.com/net/dns/manager_linux.go index 3ba3022..4fbf6a8 100644 --- a/vendor/tailscale.com/net/dns/manager_linux.go +++ b/vendor/tailscale.com/net/dns/manager_linux.go @@ -1,11 +1,12 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build linux && !android + package dns import ( "bytes" - "context" "errors" "fmt" "os" @@ -13,13 +14,16 @@ import ( "sync" "time" - "github.com/godbus/dbus/v5" "tailscale.com/control/controlknobs" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/netaddr" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" - "tailscale.com/util/cmpver" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/version/distro" ) type kv struct { @@ -32,18 +36,59 @@ func (kv kv) String() string { var publishOnce sync.Once +// reconfigTimeout is the time interval within which Manager.{Up,Down} should complete. +// +// This is particularly useful because certain conditions can cause indefinite hangs +// (such as improper dbus auth followed by contextless dbus.Object.Call). +// Such operations should be wrapped in a timeout context. +const reconfigTimeout = time.Second + +// Set unless ts_omit_networkmanager +var ( + optNewNMManager feature.Hook[func(ifName string) (OSConfigurator, error)] + optNMIsUsingResolved feature.Hook[func() error] + optNMVersionBetween feature.Hook[func(v1, v2 string) (bool, error)] +) + +// Set unless ts_omit_resolved +var ( + optNewResolvedManager feature.Hook[func(logf logger.Logf, health *health.Tracker, interfaceName string) (OSConfigurator, error)] +) + +// Set unless ts_omit_dbus +var ( + optDBusPing feature.Hook[func(name, objectPath string) error] + optDBusReadString feature.Hook[func(name, objectPath, iface, member string) (string, error)] +) + // NewOSConfigurator created a new OS configurator. // // The health tracker may be nil; the knobs may be nil and are ignored on this platform. -func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs.Knobs, interfaceName string) (ret OSConfigurator, err error) { - env := newOSConfigEnv{ - fs: directFS{}, - dbusPing: dbusPing, - dbusReadString: dbusReadString, - nmIsUsingResolved: nmIsUsingResolved, - nmVersionBetween: nmVersionBetween, - resolvconfStyle: resolvconfStyle, +func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, interfaceName string) (ret OSConfigurator, err error) { + if !buildfeatures.HasDNS || distro.Get() == distro.JetKVM { + return NewNoopManager() } + + env := newOSConfigEnv{ + fs: directFS{}, + resolvconfStyle: resolvconfStyle, + } + if f, ok := optDBusPing.GetOk(); ok { + env.dbusPing = f + } else { + env.dbusPing = func(_, _ string) error { return errors.ErrUnsupported } + } + if f, ok := optDBusReadString.GetOk(); ok { + env.dbusReadString = f + } else { + env.dbusReadString = func(_, _, _, _ string) (string, error) { return "", errors.ErrUnsupported } + } + if f, ok := optNMIsUsingResolved.GetOk(); ok { + env.nmIsUsingResolved = f + } else { + env.nmIsUsingResolved = func() error { return errors.ErrUnsupported } + } + env.nmVersionBetween, _ = optNMVersionBetween.GetOk() // GetOk to not panic if nil; unused if optNMIsUsingResolved returns an error mode, err := dnsMode(logf, health, env) if err != nil { return nil, err @@ -56,19 +101,26 @@ func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs logf("dns: using %q mode", mode) switch mode { case "direct": - return newDirectManagerOnFS(logf, health, env.fs), nil + return newDirectManagerOnFS(logf, health, bus, env.fs), nil case "systemd-resolved": - return newResolvedManager(logf, health, interfaceName) + if f, ok := optNewResolvedManager.GetOk(); ok { + return f(logf, health, interfaceName) + } + return nil, fmt.Errorf("tailscaled was built without DNS %q support", mode) case "network-manager": - return newNMManager(interfaceName) + if f, ok := optNewNMManager.GetOk(); ok { + return f(interfaceName) + } + return nil, fmt.Errorf("tailscaled was built without DNS %q support", mode) case "debian-resolvconf": return newDebianResolvconfManager(logf) case "openresolv": return newOpenresolvManager(logf) default: logf("[unexpected] detected unknown DNS mode %q, using direct manager as last resort", mode) - return newDirectManagerOnFS(logf, health, env.fs), nil } + + return newDirectManagerOnFS(logf, health, bus, env.fs), nil } // newOSConfigEnv are the funcs newOSConfigurator needs, pulled out for testing. @@ -284,50 +336,6 @@ func dnsMode(logf logger.Logf, health *health.Tracker, env newOSConfigEnv) (ret } } -func nmVersionBetween(first, last string) (bool, error) { - conn, err := dbus.SystemBus() - if err != nil { - // DBus probably not running. - return false, err - } - - nm := conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager")) - v, err := nm.GetProperty("org.freedesktop.NetworkManager.Version") - if err != nil { - return false, err - } - - version, ok := v.Value().(string) - if !ok { - return false, fmt.Errorf("unexpected type %T for NM version", v.Value()) - } - - outside := cmpver.Compare(version, first) < 0 || cmpver.Compare(version, last) > 0 - return !outside, nil -} - -func nmIsUsingResolved() error { - conn, err := dbus.SystemBus() - if err != nil { - // DBus probably not running. - return err - } - - nm := conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager/DnsManager")) - v, err := nm.GetProperty("org.freedesktop.NetworkManager.DnsManager.Mode") - if err != nil { - return fmt.Errorf("getting NM mode: %w", err) - } - mode, ok := v.Value().(string) - if !ok { - return fmt.Errorf("unexpected type %T for NM DNS mode", v.Value()) - } - if mode != "systemd-resolved" { - return errors.New("NetworkManager is not using systemd-resolved for DNS") - } - return nil -} - // resolvedIsActuallyResolver reports whether the system is using // systemd-resolved as the resolver. There are two different ways to // use systemd-resolved: @@ -388,44 +396,3 @@ func isLibnssResolveUsed(env newOSConfigEnv) error { } return fmt.Errorf("libnss_resolve not used") } - -func dbusPing(name, objectPath string) error { - conn, err := dbus.SystemBus() - if err != nil { - // DBus probably not running. - return err - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - obj := conn.Object(name, dbus.ObjectPath(objectPath)) - call := obj.CallWithContext(ctx, "org.freedesktop.DBus.Peer.Ping", 0) - return call.Err -} - -// dbusReadString reads a string property from the provided name and object -// path. property must be in "interface.member" notation. -func dbusReadString(name, objectPath, iface, member string) (string, error) { - conn, err := dbus.SystemBus() - if err != nil { - // DBus probably not running. - return "", err - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - obj := conn.Object(name, dbus.ObjectPath(objectPath)) - - var result dbus.Variant - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, iface, member).Store(&result) - if err != nil { - return "", err - } - - if s, ok := result.Value().(string); ok { - return s, nil - } - return result.String(), nil -} diff --git a/vendor/tailscale.com/net/dns/manager_openbsd.go b/vendor/tailscale.com/net/dns/manager_openbsd.go index 1a1c439..766c82f 100644 --- a/vendor/tailscale.com/net/dns/manager_openbsd.go +++ b/vendor/tailscale.com/net/dns/manager_openbsd.go @@ -11,6 +11,8 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/health" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" ) type kv struct { @@ -24,8 +26,8 @@ func (kv kv) String() string { // NewOSConfigurator created a new OS configurator. // // The health tracker may be nil; the knobs may be nil and are ignored on this platform. -func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) { - return newOSConfigurator(logf, health, interfaceName, +func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) { + return newOSConfigurator(logf, health, bus, interfaceName, newOSConfigEnv{ rcIsResolvd: rcIsResolvd, fs: directFS{}, @@ -38,7 +40,7 @@ type newOSConfigEnv struct { rcIsResolvd func(resolvConfContents []byte) bool } -func newOSConfigurator(logf logger.Logf, health *health.Tracker, interfaceName string, env newOSConfigEnv) (ret OSConfigurator, err error) { +func newOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, interfaceName string, env newOSConfigEnv) (ret OSConfigurator, err error) { var debug []kv dbg := func(k, v string) { debug = append(debug, kv{k, v}) @@ -53,7 +55,7 @@ func newOSConfigurator(logf logger.Logf, health *health.Tracker, interfaceName s bs, err := env.fs.ReadFile(resolvConf) if os.IsNotExist(err) { dbg("rc", "missing") - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil } if err != nil { return nil, fmt.Errorf("reading /etc/resolv.conf: %w", err) @@ -65,7 +67,7 @@ func newOSConfigurator(logf logger.Logf, health *health.Tracker, interfaceName s } dbg("resolvd", "missing") - return newDirectManager(logf, health), nil + return newDirectManager(logf, health, bus), nil } func rcIsResolvd(resolvConfContents []byte) bool { diff --git a/vendor/tailscale.com/net/dns/manager_plan9.go b/vendor/tailscale.com/net/dns/manager_plan9.go new file mode 100644 index 0000000..47c996d --- /dev/null +++ b/vendor/tailscale.com/net/dns/manager_plan9.go @@ -0,0 +1,183 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// TODO: man 6 ndb | grep -e 'suffix.*same line' +// to detect Russ's https://9fans.topicbox.com/groups/9fans/T9c9d81b5801a0820/ndb-suffix-specific-dns-changes + +package dns + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net/netip" + "os" + "regexp" + "strings" + "unicode" + + "tailscale.com/control/controlknobs" + "tailscale.com/health" + "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/set" + "tailscale.com/util/syspolicy/policyclient" +) + +func NewOSConfigurator(logf logger.Logf, ht *health.Tracker, _ *eventbus.Bus, _ policyclient.Client, knobs *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) { + return &plan9DNSManager{ + logf: logf, + ht: ht, + knobs: knobs, + }, nil +} + +type plan9DNSManager struct { + logf logger.Logf + ht *health.Tracker + knobs *controlknobs.Knobs +} + +// netNDBBytesWithoutTailscale returns raw (the contents of /net/ndb) with any +// Tailscale bits removed. +func netNDBBytesWithoutTailscale(raw []byte) ([]byte, error) { + var ret bytes.Buffer + bs := bufio.NewScanner(bytes.NewReader(raw)) + removeLine := set.Set[string]{} + for bs.Scan() { + t := bs.Text() + if rest, ok := strings.CutPrefix(t, "#tailscaled-added-line:"); ok { + removeLine.Add(strings.TrimSpace(rest)) + continue + } + trimmed := strings.TrimSpace(t) + if removeLine.Contains(trimmed) { + removeLine.Delete(trimmed) + continue + } + + // Also remove any DNS line referencing *.ts.net. This is + // Tailscale-specific (and won't work with, say, Headscale), but + // the Headscale case will be covered by the #tailscaled-added-line + // logic above, assuming the user didn't delete those comments. + if (strings.HasPrefix(trimmed, "dns=") || strings.Contains(trimmed, "dnsdomain=")) && + strings.HasSuffix(trimmed, ".ts.net") { + continue + } + + ret.WriteString(t) + ret.WriteByte('\n') + } + return ret.Bytes(), bs.Err() +} + +// setNDBSuffix adds lines to tsFree (the contents of /net/ndb already cleaned +// of Tailscale-added lines) to add the optional DNS search domain (e.g. +// "foo.ts.net") and DNS server to it. +func setNDBSuffix(tsFree []byte, suffix string) []byte { + suffix = strings.TrimSuffix(suffix, ".") + if suffix == "" { + return tsFree + } + var buf bytes.Buffer + bs := bufio.NewScanner(bytes.NewReader(tsFree)) + var added []string + addLine := func(s string) { + added = append(added, strings.TrimSpace(s)) + buf.WriteString(s) + } + for bs.Scan() { + buf.Write(bs.Bytes()) + buf.WriteByte('\n') + + t := bs.Text() + if suffix != "" && len(added) == 0 && strings.HasPrefix(t, "\tdns=") { + addLine(fmt.Sprintf("\tdns=100.100.100.100 suffix=%s\n", suffix)) + addLine(fmt.Sprintf("\tdnsdomain=%s\n", suffix)) + } + } + bufTrim := bytes.TrimLeftFunc(buf.Bytes(), unicode.IsSpace) + if len(added) == 0 { + return bufTrim + } + var ret bytes.Buffer + for _, s := range added { + ret.WriteString("#tailscaled-added-line: ") + ret.WriteString(s) + ret.WriteString("\n") + } + ret.WriteString("\n") + ret.Write(bufTrim) + return ret.Bytes() +} + +func (m *plan9DNSManager) SetDNS(c OSConfig) error { + ndbOnDisk, err := os.ReadFile("/net/ndb") + if err != nil { + return err + } + + tsFree, err := netNDBBytesWithoutTailscale(ndbOnDisk) + if err != nil { + return err + } + + var suffix string + if len(c.SearchDomains) > 0 { + suffix = string(c.SearchDomains[0]) + } + + newBuf := setNDBSuffix(tsFree, suffix) + if !bytes.Equal(newBuf, ndbOnDisk) { + if err := os.WriteFile("/net/ndb", newBuf, 0644); err != nil { + return fmt.Errorf("writing /net/ndb: %w", err) + } + if f, err := os.OpenFile("/net/dns", os.O_RDWR, 0); err == nil { + if _, err := io.WriteString(f, "refresh\n"); err != nil { + f.Close() + return fmt.Errorf("/net/dns refresh write: %w", err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("/net/dns refresh close: %w", err) + } + } + } + + return nil +} + +func (m *plan9DNSManager) SupportsSplitDNS() bool { return false } + +func (m *plan9DNSManager) Close() error { + // TODO(bradfitz): remove the Tailscale bits from /net/ndb ideally + return nil +} + +var dnsRegex = regexp.MustCompile(`\bdns=(\d+\.\d+\.\d+\.\d+)\b`) + +func (m *plan9DNSManager) GetBaseConfig() (OSConfig, error) { + var oc OSConfig + f, err := os.Open("/net/ndb") + if err != nil { + return oc, err + } + defer f.Close() + bs := bufio.NewScanner(f) + for bs.Scan() { + m := dnsRegex.FindSubmatch(bs.Bytes()) + if m == nil { + continue + } + addr, err := netip.ParseAddr(string(m[1])) + if err != nil { + continue + } + oc.Nameservers = append(oc.Nameservers, addr) + } + if err := bs.Err(); err != nil { + return oc, err + } + + return oc, nil +} diff --git a/vendor/tailscale.com/net/dns/manager_solaris.go b/vendor/tailscale.com/net/dns/manager_solaris.go index 1f48efb..dcd8b1f 100644 --- a/vendor/tailscale.com/net/dns/manager_solaris.go +++ b/vendor/tailscale.com/net/dns/manager_solaris.go @@ -7,8 +7,10 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/health" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" ) -func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs.Knobs, iface string) (OSConfigurator, error) { - return newDirectManager(logf, health), nil +func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, iface string) (OSConfigurator, error) { + return newDirectManager(logf, health, bus), nil } diff --git a/vendor/tailscale.com/net/dns/manager_windows.go b/vendor/tailscale.com/net/dns/manager_windows.go index effdf23..1eccb9a 100644 --- a/vendor/tailscale.com/net/dns/manager_windows.go +++ b/vendor/tailscale.com/net/dns/manager_windows.go @@ -16,7 +16,6 @@ import ( "slices" "sort" "strings" - "sync" "syscall" "time" @@ -27,8 +26,13 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/envknob" "tailscale.com/health" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/util/dnsname" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/util/syspolicy/ptype" "tailscale.com/util/winutil" ) @@ -44,19 +48,26 @@ type windowsManager struct { knobs *controlknobs.Knobs // or nil nrptDB *nrptRuleDatabase wslManager *wslManager + polc policyclient.Client - mu sync.Mutex + unregisterPolicyChangeCb func() // called when the manager is closing + + mu syncs.Mutex closing bool } // NewOSConfigurator created a new OS configurator. // -// The health tracker and the knobs may be nil. -func NewOSConfigurator(logf logger.Logf, health *health.Tracker, knobs *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) { +// The health tracker, eventbus and the knobs may be nil. +func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, polc policyclient.Client, knobs *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) { + if polc == nil { + panic("nil policyclient.Client") + } ret := &windowsManager{ logf: logf, guid: interfaceName, knobs: knobs, + polc: polc, wslManager: newWSLManager(logf, health), } @@ -64,6 +75,11 @@ func NewOSConfigurator(logf logger.Logf, health *health.Tracker, knobs *controlk ret.nrptDB = newNRPTRuleDatabase(logf) } + var err error + if ret.unregisterPolicyChangeCb, err = polc.RegisterChangeCallback(ret.sysPolicyChanged); err != nil { + logf("error registering policy change callback: %v", err) // non-fatal + } + go func() { // Log WSL status once at startup. if distros, err := wslDistros(); err != nil { @@ -148,7 +164,7 @@ func setTailscaleHosts(logf logger.Logf, prevHostsFile []byte, hosts []*HostEntr header = "# TailscaleHostsSectionStart" footer = "# TailscaleHostsSectionEnd" ) - var comments = []string{ + comments := []string{ "# This section contains MagicDNS entries for Tailscale.", "# Do not edit this section manually.", } @@ -362,11 +378,9 @@ func (m *windowsManager) SetDNS(cfg OSConfig) error { // configuration only, routing one set of things to the "split" // resolver and the rest to the primary. - // Unconditionally disable dynamic DNS updates and NetBIOS on our - // interfaces. - if err := m.disableDynamicUpdates(); err != nil { - m.logf("disableDynamicUpdates error: %v\n", err) - } + // Reconfigure DNS registration according to the [syspolicy.DNSRegistration] + // policy setting, and unconditionally disable NetBIOS on our interfaces. + m.reconfigureDNSRegistration() if err := m.disableNetBIOS(); err != nil { m.logf("disableNetBIOS error: %v\n", err) } @@ -485,6 +499,10 @@ func (m *windowsManager) Close() error { m.closing = true m.mu.Unlock() + if m.unregisterPolicyChangeCb != nil { + m.unregisterPolicyChangeCb() + } + err := m.SetDNS(OSConfig{}) if m.nrptDB != nil { m.nrptDB.Close() @@ -493,15 +511,62 @@ func (m *windowsManager) Close() error { return err } -// disableDynamicUpdates sets the appropriate registry values to prevent the -// Windows DHCP client from sending dynamic DNS updates for our interface to -// AD domain controllers. -func (m *windowsManager) disableDynamicUpdates() error { +// sysPolicyChanged is a callback triggered by [syspolicy] when it detects +// a change in one or more syspolicy settings. +func (m *windowsManager) sysPolicyChanged(policy policyclient.PolicyChange) { + if policy.HasChanged(pkey.EnableDNSRegistration) { + m.reconfigureDNSRegistration() + } +} + +// reconfigureDNSRegistration configures the DNS registration settings +// using the [syspolicy.DNSRegistration] policy setting, if it is set. +// If the policy is not configured, it disables DNS registration. +func (m *windowsManager) reconfigureDNSRegistration() { + // Disable DNS registration by default (if the policy setting is not configured). + // This is primarily for historical reasons and to avoid breaking existing + // setups that rely on this behavior. + enableDNSRegistration, err := m.polc.GetPreferenceOption(pkey.EnableDNSRegistration, ptype.NeverByPolicy) + if err != nil { + m.logf("error getting DNSRegistration policy setting: %v", err) // non-fatal; we'll use the default + } + + if enableDNSRegistration.Show() { + // "Show" reports whether the policy setting is configured as "user-decides". + // The name is a bit unfortunate in this context, as we don't actually "show" anything. + // Still, if the admin configured the policy as "user-decides", we shouldn't modify + // the adapter's settings and should leave them up to the user (admin rights required) + // or the system defaults. + return + } + + // Otherwise, if the policy setting is configured as "always" or "never", + // we should configure the adapter accordingly. + if err := m.configureDNSRegistration(enableDNSRegistration.IsAlways()); err != nil { + m.logf("error configuring DNS registration: %v", err) + } +} + +// configureDNSRegistration sets the appropriate registry values to allow or prevent +// the Windows DHCP client from registering Tailscale IP addresses with DNS +// and sending dynamic updates for our interface to AD domain controllers. +func (m *windowsManager) configureDNSRegistration(enabled bool) error { prefixen := []winutil.RegistryPathPrefix{ winutil.IPv4TCPIPInterfacePrefix, winutil.IPv6TCPIPInterfacePrefix, } + var ( + registrationEnabled = uint32(0) + disableDynamicUpdate = uint32(1) + maxNumberOfAddressesToRegister = uint32(0) + ) + if enabled { + registrationEnabled = 1 + disableDynamicUpdate = 0 + maxNumberOfAddressesToRegister = 1 + } + for _, prefix := range prefixen { k, err := m.openInterfaceKey(prefix) if err != nil { @@ -509,13 +574,13 @@ func (m *windowsManager) disableDynamicUpdates() error { } defer k.Close() - if err := k.SetDWordValue("RegistrationEnabled", 0); err != nil { + if err := k.SetDWordValue("RegistrationEnabled", registrationEnabled); err != nil { return err } - if err := k.SetDWordValue("DisableDynamicUpdate", 1); err != nil { + if err := k.SetDWordValue("DisableDynamicUpdate", disableDynamicUpdate); err != nil { return err } - if err := k.SetDWordValue("MaxNumberOfAddressesToRegister", 0); err != nil { + if err := k.SetDWordValue("MaxNumberOfAddressesToRegister", maxNumberOfAddressesToRegister); err != nil { return err } } diff --git a/vendor/tailscale.com/net/dns/nm.go b/vendor/tailscale.com/net/dns/nm.go index ef07a90..a88d29b 100644 --- a/vendor/tailscale.com/net/dns/nm.go +++ b/vendor/tailscale.com/net/dns/nm.go @@ -1,13 +1,14 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux +//go:build linux && !android && !ts_omit_networkmanager package dns import ( "context" "encoding/binary" + "errors" "fmt" "net" "net/netip" @@ -16,6 +17,7 @@ import ( "github.com/godbus/dbus/v5" "tailscale.com/net/tsaddr" + "tailscale.com/util/cmpver" "tailscale.com/util/dnsname" ) @@ -25,13 +27,6 @@ const ( lowerPriority = int32(200) // lower than all builtin auto priorities ) -// reconfigTimeout is the time interval within which Manager.{Up,Down} should complete. -// -// This is particularly useful because certain conditions can cause indefinite hangs -// (such as improper dbus auth followed by contextless dbus.Object.Call). -// Such operations should be wrapped in a timeout context. -const reconfigTimeout = time.Second - // nmManager uses the NetworkManager DBus API. type nmManager struct { interfaceName string @@ -39,7 +34,13 @@ type nmManager struct { dnsManager dbus.BusObject } -func newNMManager(interfaceName string) (*nmManager, error) { +func init() { + optNewNMManager.Set(newNMManager) + optNMIsUsingResolved.Set(nmIsUsingResolved) + optNMVersionBetween.Set(nmVersionBetween) +} + +func newNMManager(interfaceName string) (OSConfigurator, error) { conn, err := dbus.SystemBus() if err != nil { return nil, err @@ -389,3 +390,47 @@ func (m *nmManager) Close() error { // settings when the tailscale interface goes away. return nil } + +func nmVersionBetween(first, last string) (bool, error) { + conn, err := dbus.SystemBus() + if err != nil { + // DBus probably not running. + return false, err + } + + nm := conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager")) + v, err := nm.GetProperty("org.freedesktop.NetworkManager.Version") + if err != nil { + return false, err + } + + version, ok := v.Value().(string) + if !ok { + return false, fmt.Errorf("unexpected type %T for NM version", v.Value()) + } + + outside := cmpver.Compare(version, first) < 0 || cmpver.Compare(version, last) > 0 + return !outside, nil +} + +func nmIsUsingResolved() error { + conn, err := dbus.SystemBus() + if err != nil { + // DBus probably not running. + return err + } + + nm := conn.Object("org.freedesktop.NetworkManager", dbus.ObjectPath("/org/freedesktop/NetworkManager/DnsManager")) + v, err := nm.GetProperty("org.freedesktop.NetworkManager.DnsManager.Mode") + if err != nil { + return fmt.Errorf("getting NM mode: %w", err) + } + mode, ok := v.Value().(string) + if !ok { + return fmt.Errorf("unexpected type %T for NM DNS mode", v.Value()) + } + if mode != "systemd-resolved" { + return errors.New("NetworkManager is not using systemd-resolved for DNS") + } + return nil +} diff --git a/vendor/tailscale.com/net/dns/openresolv.go b/vendor/tailscale.com/net/dns/openresolv.go index 0b5c87a..c9562b6 100644 --- a/vendor/tailscale.com/net/dns/openresolv.go +++ b/vendor/tailscale.com/net/dns/openresolv.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux || freebsd || openbsd +//go:build (linux && !android) || freebsd || openbsd package dns diff --git a/vendor/tailscale.com/net/dns/osconfig.go b/vendor/tailscale.com/net/dns/osconfig.go index 842c5ac..af4c0f0 100644 --- a/vendor/tailscale.com/net/dns/osconfig.go +++ b/vendor/tailscale.com/net/dns/osconfig.go @@ -11,6 +11,7 @@ import ( "slices" "strings" + "tailscale.com/feature/buildfeatures" "tailscale.com/types/logger" "tailscale.com/util/dnsname" ) @@ -158,6 +159,10 @@ func (a OSConfig) Equal(b OSConfig) bool { // Fixes https://github.com/tailscale/tailscale/issues/5669 func (a OSConfig) Format(f fmt.State, verb rune) { logger.ArgWriter(func(w *bufio.Writer) { + if !buildfeatures.HasDNS { + w.WriteString(`{DNS-unlinked}`) + return + } w.WriteString(`{Nameservers:[`) for i, ns := range a.Nameservers { if i != 0 { diff --git a/vendor/tailscale.com/net/dns/publicdns/publicdns.go b/vendor/tailscale.com/net/dns/publicdns/publicdns.go index 0dbd3ab..b8a7f88 100644 --- a/vendor/tailscale.com/net/dns/publicdns/publicdns.go +++ b/vendor/tailscale.com/net/dns/publicdns/publicdns.go @@ -17,6 +17,8 @@ import ( "strconv" "strings" "sync" + + "tailscale.com/feature/buildfeatures" ) // dohOfIP maps from public DNS IPs to their DoH base URL. @@ -163,6 +165,9 @@ const ( // populate is called once to initialize the knownDoH and dohIPsOfBase maps. func populate() { + if !buildfeatures.HasDNS { + return + } // Cloudflare // https://developers.cloudflare.com/1.1.1.1/ip-addresses/ addDoH("1.1.1.1", "https://cloudflare-dns.com/dns-query") diff --git a/vendor/tailscale.com/net/dns/recursive/recursive.go b/vendor/tailscale.com/net/dns/recursive/recursive.go deleted file mode 100644 index eb23004..0000000 --- a/vendor/tailscale.com/net/dns/recursive/recursive.go +++ /dev/null @@ -1,621 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package recursive implements a simple recursive DNS resolver. -package recursive - -import ( - "context" - "errors" - "fmt" - "net" - "net/netip" - "slices" - "strings" - "time" - - "github.com/miekg/dns" - "tailscale.com/envknob" - "tailscale.com/net/netns" - "tailscale.com/types/logger" - "tailscale.com/util/dnsname" - "tailscale.com/util/mak" - "tailscale.com/util/multierr" - "tailscale.com/util/slicesx" -) - -const ( - // maxDepth is how deep from the root nameservers we'll recurse when - // resolving; passing this limit will instead return an error. - // - // maxDepth must be at least 20 to resolve "console.aws.amazon.com", - // which is a domain with a moderately complicated DNS setup. The - // current value of 30 was chosen semi-arbitrarily to ensure that we - // have about 50% headroom. - maxDepth = 30 - // numStartingServers is the number of root nameservers that we use as - // initial candidates for our recursion. - numStartingServers = 3 - // udpQueryTimeout is the amount of time we wait for a UDP response - // from a nameserver before falling back to a TCP connection. - udpQueryTimeout = 5 * time.Second - - // These constants aren't typed in the DNS package, so we create typed - // versions here to avoid having to do repeated type casts. - qtypeA dns.Type = dns.Type(dns.TypeA) - qtypeAAAA dns.Type = dns.Type(dns.TypeAAAA) -) - -var ( - // ErrMaxDepth is returned when recursive resolving exceeds the maximum - // depth limit for this package. - ErrMaxDepth = fmt.Errorf("exceeded max depth %d when resolving", maxDepth) - - // ErrAuthoritativeNoResponses is the error returned when an - // authoritative nameserver indicates that there are no responses to - // the given query. - ErrAuthoritativeNoResponses = errors.New("authoritative server returned no responses") - - // ErrNoResponses is returned when our resolution process completes - // with no valid responses from any nameserver, but no authoritative - // server explicitly returned NXDOMAIN. - ErrNoResponses = errors.New("no responses to query") -) - -var rootServersV4 = []netip.Addr{ - netip.MustParseAddr("198.41.0.4"), // a.root-servers.net - netip.MustParseAddr("170.247.170.2"), // b.root-servers.net - netip.MustParseAddr("192.33.4.12"), // c.root-servers.net - netip.MustParseAddr("199.7.91.13"), // d.root-servers.net - netip.MustParseAddr("192.203.230.10"), // e.root-servers.net - netip.MustParseAddr("192.5.5.241"), // f.root-servers.net - netip.MustParseAddr("192.112.36.4"), // g.root-servers.net - netip.MustParseAddr("198.97.190.53"), // h.root-servers.net - netip.MustParseAddr("192.36.148.17"), // i.root-servers.net - netip.MustParseAddr("192.58.128.30"), // j.root-servers.net - netip.MustParseAddr("193.0.14.129"), // k.root-servers.net - netip.MustParseAddr("199.7.83.42"), // l.root-servers.net - netip.MustParseAddr("202.12.27.33"), // m.root-servers.net -} - -var rootServersV6 = []netip.Addr{ - netip.MustParseAddr("2001:503:ba3e::2:30"), // a.root-servers.net - netip.MustParseAddr("2801:1b8:10::b"), // b.root-servers.net - netip.MustParseAddr("2001:500:2::c"), // c.root-servers.net - netip.MustParseAddr("2001:500:2d::d"), // d.root-servers.net - netip.MustParseAddr("2001:500:a8::e"), // e.root-servers.net - netip.MustParseAddr("2001:500:2f::f"), // f.root-servers.net - netip.MustParseAddr("2001:500:12::d0d"), // g.root-servers.net - netip.MustParseAddr("2001:500:1::53"), // h.root-servers.net - netip.MustParseAddr("2001:7fe::53"), // i.root-servers.net - netip.MustParseAddr("2001:503:c27::2:30"), // j.root-servers.net - netip.MustParseAddr("2001:7fd::1"), // k.root-servers.net - netip.MustParseAddr("2001:500:9f::42"), // l.root-servers.net - netip.MustParseAddr("2001:dc3::35"), // m.root-servers.net -} - -var debug = envknob.RegisterBool("TS_DEBUG_RECURSIVE_DNS") - -// Resolver is a recursive DNS resolver that is designed for looking up A and AAAA records. -type Resolver struct { - // Dialer is used to create outbound connections. If nil, a zero - // net.Dialer will be used instead. - Dialer netns.Dialer - - // Logf is the logging function to use; if none is specified, then logs - // will be dropped. - Logf logger.Logf - - // NoIPv6, if set, will prevent this package from querying for AAAA - // records and will avoid contacting nameservers over IPv6. - NoIPv6 bool - - // Test mocks - testQueryHook func(name dnsname.FQDN, nameserver netip.Addr, protocol string, qtype dns.Type) (*dns.Msg, error) - testExchangeHook func(nameserver netip.Addr, network string, msg *dns.Msg) (*dns.Msg, error) - rootServers []netip.Addr - timeNow func() time.Time - - // Caching - // NOTE(andrew): if we make resolution parallel, this needs a mutex - queryCache map[dnsQuery]dnsMsgWithExpiry - - // Possible future additions: - // - Additional nameservers? From the system maybe? - // - NoIPv4 for IPv4 - // - DNS-over-HTTPS or DNS-over-TLS support -} - -// queryState stores all state during the course of a single query -type queryState struct { - // rootServers are the root nameservers to start from - rootServers []netip.Addr - - // TODO: metrics? -} - -type dnsQuery struct { - nameserver netip.Addr - name dnsname.FQDN - qtype dns.Type -} - -func (q dnsQuery) String() string { - return fmt.Sprintf("dnsQuery{nameserver:%q,name:%q,qtype:%v}", q.nameserver.String(), q.name, q.qtype) -} - -type dnsMsgWithExpiry struct { - *dns.Msg - expiresAt time.Time -} - -func (r *Resolver) now() time.Time { - if r.timeNow != nil { - return r.timeNow() - } - return time.Now() -} - -func (r *Resolver) logf(format string, args ...any) { - if r.Logf == nil { - return - } - r.Logf(format, args...) -} - -func (r *Resolver) depthlogf(depth int, format string, args ...any) { - if r.Logf == nil || !debug() { - return - } - prefix := fmt.Sprintf("[%d] %s", depth, strings.Repeat(" ", depth)) - r.Logf(prefix+format, args...) -} - -var defaultDialer net.Dialer - -func (r *Resolver) dialer() netns.Dialer { - if r.Dialer != nil { - return r.Dialer - } - - return &defaultDialer -} - -func (r *Resolver) newState() *queryState { - var rootServers []netip.Addr - if len(r.rootServers) > 0 { - rootServers = r.rootServers - } else { - // Select a random subset of root nameservers to start from, since if - // we don't get responses from those, something else has probably gone - // horribly wrong. - roots4 := slices.Clone(rootServersV4) - slicesx.Shuffle(roots4) - roots4 = roots4[:numStartingServers] - - var roots6 []netip.Addr - if !r.NoIPv6 { - roots6 = slices.Clone(rootServersV6) - slicesx.Shuffle(roots6) - roots6 = roots6[:numStartingServers] - } - - // Interleave the root servers so that we try to contact them over - // IPv4, then IPv6, IPv4, IPv6, etc. - rootServers = slicesx.Interleave(roots4, roots6) - } - - return &queryState{ - rootServers: rootServers, - } -} - -// Resolve will perform a recursive DNS resolution for the provided name, -// starting at a randomly-chosen root DNS server, and return the A and AAAA -// responses as a slice of netip.Addrs along with the minimum TTL for the -// returned records. -func (r *Resolver) Resolve(ctx context.Context, name string) (addrs []netip.Addr, minTTL time.Duration, err error) { - dnsName, err := dnsname.ToFQDN(name) - if err != nil { - return nil, 0, err - } - - qstate := r.newState() - - r.logf("querying IPv4 addresses for: %q", name) - addrs4, minTTL4, err4 := r.resolveRecursiveFromRoot(ctx, qstate, 0, dnsName, qtypeA) - - var ( - addrs6 []netip.Addr - minTTL6 time.Duration - err6 error - ) - if !r.NoIPv6 { - r.logf("querying IPv6 addresses for: %q", name) - addrs6, minTTL6, err6 = r.resolveRecursiveFromRoot(ctx, qstate, 0, dnsName, qtypeAAAA) - } - - if err4 != nil && err6 != nil { - if err4 == err6 { - return nil, 0, err4 - } - - return nil, 0, multierr.New(err4, err6) - } - if err4 != nil { - return addrs6, minTTL6, nil - } else if err6 != nil { - return addrs4, minTTL4, nil - } - - minTTL = minTTL4 - if minTTL6 < minTTL { - minTTL = minTTL6 - } - - addrs = append(addrs4, addrs6...) - if len(addrs) == 0 { - return nil, 0, ErrNoResponses - } - - slicesx.Shuffle(addrs) - return addrs, minTTL, nil -} - -func (r *Resolver) resolveRecursiveFromRoot( - ctx context.Context, - qstate *queryState, - depth int, - name dnsname.FQDN, // what we're querying - qtype dns.Type, -) ([]netip.Addr, time.Duration, error) { - r.depthlogf(depth, "resolving %q from root (type: %v)", name, qtype) - - var depthError bool - for _, server := range qstate.rootServers { - addrs, minTTL, err := r.resolveRecursive(ctx, qstate, depth, name, server, qtype) - if err == nil { - return addrs, minTTL, err - } else if errors.Is(err, ErrAuthoritativeNoResponses) { - return nil, 0, ErrAuthoritativeNoResponses - } else if errors.Is(err, ErrMaxDepth) { - depthError = true - } - } - - if depthError { - return nil, 0, ErrMaxDepth - } - return nil, 0, ErrNoResponses -} - -func (r *Resolver) resolveRecursive( - ctx context.Context, - qstate *queryState, - depth int, - name dnsname.FQDN, // what we're querying - nameserver netip.Addr, - qtype dns.Type, -) ([]netip.Addr, time.Duration, error) { - if depth == maxDepth { - r.depthlogf(depth, "not recursing past maximum depth") - return nil, 0, ErrMaxDepth - } - - // Ask this nameserver for an answer. - resp, err := r.queryNameserver(ctx, depth, name, nameserver, qtype) - if err != nil { - return nil, 0, err - } - - // If we get an actual answer from the nameserver, then return it. - var ( - answers []netip.Addr - cnames []dnsname.FQDN - minTTL = 24 * 60 * 60 // 24 hours in seconds - ) - for _, answer := range resp.Answer { - if crec, ok := answer.(*dns.CNAME); ok { - cnameFQDN, err := dnsname.ToFQDN(crec.Target) - if err != nil { - r.logf("bad CNAME %q returned: %v", crec.Target, err) - continue - } - - cnames = append(cnames, cnameFQDN) - continue - } - - addr := addrFromRecord(answer) - if !addr.IsValid() { - r.logf("[unexpected] invalid record in %T answer", answer) - } else if addr.Is4() && qtype != qtypeA { - r.logf("[unexpected] got IPv4 answer but qtype=%v", qtype) - } else if addr.Is6() && qtype != qtypeAAAA { - r.logf("[unexpected] got IPv6 answer but qtype=%v", qtype) - } else { - answers = append(answers, addr) - minTTL = min(minTTL, int(answer.Header().Ttl)) - } - } - - if len(answers) > 0 { - r.depthlogf(depth, "got answers for %q: %v", name, answers) - return answers, time.Duration(minTTL) * time.Second, nil - } - - r.depthlogf(depth, "no answers for %q", name) - - // If we have a non-zero number of CNAMEs, then try resolving those - // (from the root again) and return the first one that succeeds. - // - // TODO: return the union of all responses? - // TODO: parallelism? - if len(cnames) > 0 { - r.depthlogf(depth, "got CNAME responses for %q: %v", name, cnames) - } - var cnameDepthError bool - for _, cname := range cnames { - answers, minTTL, err := r.resolveRecursiveFromRoot(ctx, qstate, depth+1, cname, qtype) - if err == nil { - return answers, minTTL, nil - } else if errors.Is(err, ErrAuthoritativeNoResponses) { - return nil, 0, ErrAuthoritativeNoResponses - } else if errors.Is(err, ErrMaxDepth) { - cnameDepthError = true - } - } - - // If this is an authoritative response, then we know that continuing - // to look further is not going to result in any answers and we should - // bail out. - if resp.MsgHdr.Authoritative { - // If we failed to recurse into a CNAME due to a depth limit, - // propagate that here. - if cnameDepthError { - return nil, 0, ErrMaxDepth - } - - r.depthlogf(depth, "got authoritative response with no answers; stopping") - return nil, 0, ErrAuthoritativeNoResponses - } - - r.depthlogf(depth, "got %d NS responses and %d ADDITIONAL responses for %q", len(resp.Ns), len(resp.Extra), name) - - // No CNAMEs and no answers; see if we got any AUTHORITY responses, - // which indicate which nameservers to query next. - var authorities []dnsname.FQDN - for _, rr := range resp.Ns { - ns, ok := rr.(*dns.NS) - if !ok { - continue - } - - nsName, err := dnsname.ToFQDN(ns.Ns) - if err != nil { - r.logf("unexpected bad NS name %q: %v", ns.Ns, err) - continue - } - - authorities = append(authorities, nsName) - } - - // Also check for "glue" records, which are IP addresses provided by - // the DNS server for authority responses; these are required when the - // authority server is a subdomain of what's being resolved. - glueRecords := make(map[dnsname.FQDN][]netip.Addr) - for _, rr := range resp.Extra { - name, err := dnsname.ToFQDN(rr.Header().Name) - if err != nil { - r.logf("unexpected bad Name %q in Extra addr: %v", rr.Header().Name, err) - continue - } - - if addr := addrFromRecord(rr); addr.IsValid() { - glueRecords[name] = append(glueRecords[name], addr) - } else { - r.logf("unexpected bad Extra %T addr", rr) - } - } - - // Try authorities with glue records first, to minimize the number of - // additional DNS queries that we need to make. - authoritiesGlue, authoritiesNoGlue := slicesx.Partition(authorities, func(aa dnsname.FQDN) bool { - return len(glueRecords[aa]) > 0 - }) - - authorityDepthError := false - - r.depthlogf(depth, "authorities with glue records for recursion: %v", authoritiesGlue) - for _, authority := range authoritiesGlue { - for _, nameserver := range glueRecords[authority] { - answers, minTTL, err := r.resolveRecursive(ctx, qstate, depth+1, name, nameserver, qtype) - if err == nil { - return answers, minTTL, nil - } else if errors.Is(err, ErrAuthoritativeNoResponses) { - return nil, 0, ErrAuthoritativeNoResponses - } else if errors.Is(err, ErrMaxDepth) { - authorityDepthError = true - } - } - } - - r.depthlogf(depth, "authorities with no glue records for recursion: %v", authoritiesNoGlue) - for _, authority := range authoritiesNoGlue { - // First, resolve the IP for the authority server from the - // root, querying for both IPv4 and IPv6 addresses regardless - // of what the current question type is. - // - // TODO: check for infinite recursion; it'll get caught by our - // recursion depth, but we want to bail early. - for _, authorityQtype := range []dns.Type{qtypeAAAA, qtypeA} { - answers, _, err := r.resolveRecursiveFromRoot(ctx, qstate, depth+1, authority, authorityQtype) - if err != nil { - r.depthlogf(depth, "error querying authority %q: %v", authority, err) - continue - } - r.depthlogf(depth, "resolved authority %q (type %v) to: %v", authority, authorityQtype, answers) - - // Now, query this authority for the final address. - for _, nameserver := range answers { - answers, minTTL, err := r.resolveRecursive(ctx, qstate, depth+1, name, nameserver, qtype) - if err == nil { - return answers, minTTL, nil - } else if errors.Is(err, ErrAuthoritativeNoResponses) { - return nil, 0, ErrAuthoritativeNoResponses - } else if errors.Is(err, ErrMaxDepth) { - authorityDepthError = true - } - } - } - } - - if authorityDepthError { - return nil, 0, ErrMaxDepth - } - return nil, 0, ErrNoResponses -} - -// queryNameserver sends a query for "name" to the nameserver "nameserver" for -// records of type "qtype", trying both UDP and TCP connections as -// appropriate. -func (r *Resolver) queryNameserver( - ctx context.Context, - depth int, - name dnsname.FQDN, // what we're querying - nameserver netip.Addr, // destination of query - qtype dns.Type, -) (*dns.Msg, error) { - // TODO(andrew): we should QNAME minimisation here to avoid sending the - // full name to intermediate/root nameservers. See: - // https://www.rfc-editor.org/rfc/rfc7816 - - // Handle the case where UDP is blocked by adding an explicit timeout - // for the UDP portion of this query. - udpCtx, udpCtxCancel := context.WithTimeout(ctx, udpQueryTimeout) - defer udpCtxCancel() - - msg, err := r.queryNameserverProto(udpCtx, depth, name, nameserver, "udp", qtype) - if err == nil { - return msg, nil - } - - msg, err2 := r.queryNameserverProto(ctx, depth, name, nameserver, "tcp", qtype) - if err2 == nil { - return msg, nil - } - - return nil, multierr.New(err, err2) -} - -// queryNameserverProto sends a query for "name" to the nameserver "nameserver" -// for records of type "qtype" over the provided protocol (either "udp" -// or "tcp"), and returns the DNS response or an error. -func (r *Resolver) queryNameserverProto( - ctx context.Context, - depth int, - name dnsname.FQDN, // what we're querying - nameserver netip.Addr, // destination of query - protocol string, - qtype dns.Type, -) (resp *dns.Msg, err error) { - if r.testQueryHook != nil { - return r.testQueryHook(name, nameserver, protocol, qtype) - } - - now := r.now() - nameserverStr := nameserver.String() - - cacheKey := dnsQuery{ - nameserver: nameserver, - name: name, - qtype: qtype, - } - cacheEntry, ok := r.queryCache[cacheKey] - if ok && cacheEntry.expiresAt.Before(now) { - r.depthlogf(depth, "using cached response from %s about %q (type: %v)", nameserverStr, name, qtype) - return cacheEntry.Msg, nil - } - - var network string - if nameserver.Is4() { - network = protocol + "4" - } else { - network = protocol + "6" - } - - // Prepare a message asking for an appropriately-typed record - // for the name we're querying. - m := new(dns.Msg) - m.SetQuestion(name.WithTrailingDot(), uint16(qtype)) - - // Allow mocking out the network components with our exchange hook. - if r.testExchangeHook != nil { - resp, err = r.testExchangeHook(nameserver, network, m) - } else { - // Dial the current nameserver using our dialer. - var nconn net.Conn - nconn, err = r.dialer().DialContext(ctx, network, net.JoinHostPort(nameserverStr, "53")) - if err != nil { - return nil, err - } - - var c dns.Client // TODO: share? - conn := &dns.Conn{ - Conn: nconn, - UDPSize: c.UDPSize, - } - - // Send the DNS request to the current nameserver. - r.depthlogf(depth, "asking %s over %s about %q (type: %v)", nameserverStr, protocol, name, qtype) - resp, _, err = c.ExchangeWithConnContext(ctx, m, conn) - } - if err != nil { - return nil, err - } - - // If the message was truncated and we're using UDP, re-run with TCP. - if resp.MsgHdr.Truncated && protocol == "udp" { - r.depthlogf(depth, "response message truncated; re-running query with TCP") - resp, err = r.queryNameserverProto(ctx, depth, name, nameserver, "tcp", qtype) - if err != nil { - return nil, err - } - } - - // Find minimum expiry for all records in this message. - var minTTL int - for _, rr := range resp.Answer { - minTTL = min(minTTL, int(rr.Header().Ttl)) - } - for _, rr := range resp.Ns { - minTTL = min(minTTL, int(rr.Header().Ttl)) - } - for _, rr := range resp.Extra { - minTTL = min(minTTL, int(rr.Header().Ttl)) - } - - mak.Set(&r.queryCache, cacheKey, dnsMsgWithExpiry{ - Msg: resp, - expiresAt: now.Add(time.Duration(minTTL) * time.Second), - }) - return resp, nil -} - -func addrFromRecord(rr dns.RR) netip.Addr { - switch v := rr.(type) { - case *dns.A: - ip, ok := netip.AddrFromSlice(v.A) - if !ok || !ip.Is4() { - return netip.Addr{} - } - return ip - case *dns.AAAA: - ip, ok := netip.AddrFromSlice(v.AAAA) - if !ok || !ip.Is6() { - return netip.Addr{} - } - return ip - } - return netip.Addr{} -} diff --git a/vendor/tailscale.com/net/dns/resolved.go b/vendor/tailscale.com/net/dns/resolved.go index 1a7c860..d8f63c9 100644 --- a/vendor/tailscale.com/net/dns/resolved.go +++ b/vendor/tailscale.com/net/dns/resolved.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux +//go:build linux && !android && !ts_omit_resolved package dns @@ -15,8 +15,8 @@ import ( "github.com/godbus/dbus/v5" "golang.org/x/sys/unix" "tailscale.com/health" - "tailscale.com/logtail/backoff" "tailscale.com/types/logger" + "tailscale.com/util/backoff" "tailscale.com/util/dnsname" ) @@ -70,7 +70,11 @@ type resolvedManager struct { configCR chan changeRequest // tracks OSConfigs changes and error responses } -func newResolvedManager(logf logger.Logf, health *health.Tracker, interfaceName string) (*resolvedManager, error) { +func init() { + optNewResolvedManager.Set(newResolvedManager) +} + +func newResolvedManager(logf logger.Logf, health *health.Tracker, interfaceName string) (OSConfigurator, error) { iface, err := net.InterfaceByName(interfaceName) if err != nil { return nil, err diff --git a/vendor/tailscale.com/net/dns/resolver/debug.go b/vendor/tailscale.com/net/dns/resolver/debug.go index da195d4..a41462e 100644 --- a/vendor/tailscale.com/net/dns/resolver/debug.go +++ b/vendor/tailscale.com/net/dns/resolver/debug.go @@ -8,14 +8,18 @@ import ( "html" "net/http" "strconv" - "sync" "sync/atomic" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" + "tailscale.com/syncs" ) func init() { + if !buildfeatures.HasDNS { + return + } health.RegisterDebugHandler("dnsfwd", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { n, _ := strconv.Atoi(r.FormValue("n")) if n <= 0 { @@ -35,7 +39,7 @@ func init() { var fwdLogAtomic atomic.Pointer[fwdLog] type fwdLog struct { - mu sync.Mutex + mu syncs.Mutex pos int // ent[pos] is next entry ent []fwdLogEntry } diff --git a/vendor/tailscale.com/net/dns/resolver/forwarder.go b/vendor/tailscale.com/net/dns/resolver/forwarder.go index c00dea1..797c527 100644 --- a/vendor/tailscale.com/net/dns/resolver/forwarder.go +++ b/vendor/tailscale.com/net/dns/resolver/forwarder.go @@ -17,6 +17,7 @@ import ( "net/http" "net/netip" "net/url" + "runtime" "sort" "strings" "sync" @@ -26,13 +27,17 @@ import ( dns "golang.org/x/net/dns/dnsmessage" "tailscale.com/control/controlknobs" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/dns/publicdns" "tailscale.com/net/dnscache" "tailscale.com/net/neterror" "tailscale.com/net/netmon" + "tailscale.com/net/netx" "tailscale.com/net/sockstats" "tailscale.com/net/tsdial" + "tailscale.com/syncs" "tailscale.com/types/dnstype" "tailscale.com/types/logger" "tailscale.com/types/nettype" @@ -215,18 +220,19 @@ type resolverAndDelay struct { // forwarder forwards DNS packets to a number of upstream nameservers. type forwarder struct { - logf logger.Logf - netMon *netmon.Monitor // always non-nil - linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absorbs it - dialer *tsdial.Dialer - health *health.Tracker // always non-nil + logf logger.Logf + netMon *netmon.Monitor // always non-nil + linkSel ForwardLinkSelector // TODO(bradfitz): remove this when tsdial.Dialer absorbs it + dialer *tsdial.Dialer + health *health.Tracker // always non-nil + verboseFwd bool // if true, log all DNS forwarding controlKnobs *controlknobs.Knobs // or nil ctx context.Context // good until Close ctxCancel context.CancelFunc // closes ctx - mu sync.Mutex // guards following + mu syncs.Mutex // guards following dohClient map[string]*http.Client // urlBase -> client @@ -243,26 +249,23 @@ type forwarder struct { // /etc/resolv.conf is missing/corrupt, and the peerapi ExitDNS stub // resolver lookup. cloudHostFallback []resolverAndDelay - - // missingUpstreamRecovery, if non-nil, is set called when a SERVFAIL is - // returned due to missing upstream resolvers. - // - // This should attempt to properly (re)set the upstream resolvers. - missingUpstreamRecovery func() } func newForwarder(logf logger.Logf, netMon *netmon.Monitor, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, health *health.Tracker, knobs *controlknobs.Knobs) *forwarder { + if !buildfeatures.HasDNS { + return nil + } if netMon == nil { panic("nil netMon") } f := &forwarder{ - logf: logger.WithPrefix(logf, "forward: "), - netMon: netMon, - linkSel: linkSel, - dialer: dialer, - health: health, - controlKnobs: knobs, - missingUpstreamRecovery: func() {}, + logf: logger.WithPrefix(logf, "forward: "), + netMon: netMon, + linkSel: linkSel, + dialer: dialer, + health: health, + controlKnobs: knobs, + verboseFwd: verboseDNSForward(), } f.ctx, f.ctxCancel = context.WithCancel(context.Background()) return f @@ -520,15 +523,18 @@ var ( // // send expects the reply to have the same txid as txidOut. func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDelay) (ret []byte, err error) { - if verboseDNSForward() { + if f.verboseFwd { id := forwarderCount.Add(1) domain, typ, _ := nameFromQuery(fq.packet) - f.logf("forwarder.send(%q, %d, %v, %d) [%d] ...", rr.name.Addr, fq.txid, typ, len(domain), id) + f.logf("forwarder.send(%q, %d, %v, %d) from %v [%d] ...", rr.name.Addr, fq.txid, typ, len(domain), fq.src, id) defer func() { - f.logf("forwarder.send(%q, %d, %v, %d) [%d] = %v, %v", rr.name.Addr, fq.txid, typ, len(domain), id, len(ret), err) + f.logf("forwarder.send(%q, %d, %v, %d) from %v [%d] = %v, %v", rr.name.Addr, fq.txid, typ, len(domain), fq.src, id, len(ret), err) }() } if strings.HasPrefix(rr.name.Addr, "http://") { + if !buildfeatures.HasPeerAPIClient { + return nil, feature.ErrUnavailable + } return f.sendDoH(ctx, rr.name.Addr, f.dialer.PeerAPIHTTPClient(), fq.packet) } if strings.HasPrefix(rr.name.Addr, "https://") { @@ -739,18 +745,38 @@ func (f *forwarder) sendUDP(ctx context.Context, fq *forwardQuery, rr resolverAn return out, nil } -func (f *forwarder) getDialerType() dnscache.DialContextFunc { - if f.controlKnobs != nil && f.controlKnobs.UserDialUseRoutes.Load() { - // It is safe to use UserDial as it dials external servers without going through Tailscale - // and closes connections on interface change in the same way as SystemDial does, - // thus preventing DNS resolution issues when switching between WiFi and cellular, - // but can also dial an internal DNS server on the Tailnet or via a subnet router. - // - // TODO(nickkhyl): Update tsdial.Dialer to reuse the bart.Table we create in net/tstun.Wrapper - // to avoid having two bart tables in memory, especially on iOS. Once that's done, - // we can get rid of the nodeAttr/control knob and always use UserDial for DNS. - // - // See https://github.com/tailscale/tailscale/issues/12027. +var optDNSForwardUseRoutes = envknob.RegisterOptBool("TS_DEBUG_DNS_FORWARD_USE_ROUTES") + +// ShouldUseRoutes reports whether the DNS resolver should consider routes when dialing +// upstream nameservers via TCP. +// +// If true, routes should be considered ([tsdial.Dialer.UserDial]), otherwise defer +// to the system routes ([tsdial.Dialer.SystemDial]). +// +// TODO(nickkhyl): Update [tsdial.Dialer] to reuse the bart.Table we create in net/tstun.Wrapper +// to avoid having two bart tables in memory, especially on iOS. Once that's done, +// we can get rid of the nodeAttr/control knob and always use UserDial for DNS. +// +// See tailscale/tailscale#12027. +func ShouldUseRoutes(knobs *controlknobs.Knobs) bool { + if !buildfeatures.HasDNS { + return false + } + switch runtime.GOOS { + case "android", "ios": + // On mobile platforms with lower memory limits (e.g., 50MB on iOS), + // this behavior is still gated by the "user-dial-routes" nodeAttr. + return knobs != nil && knobs.UserDialUseRoutes.Load() + default: + // On all other platforms, it is the default behavior, + // but it can be overridden with the "TS_DEBUG_DNS_FORWARD_USE_ROUTES" env var. + doNotUseRoutes := optDNSForwardUseRoutes().EqualBool(false) + return !doNotUseRoutes + } +} + +func (f *forwarder) getDialerType() netx.DialFunc { + if ShouldUseRoutes(f.controlKnobs) { return f.dialer.UserDial } return f.dialer.SystemDial @@ -878,6 +904,7 @@ type forwardQuery struct { txid txid packet []byte family string // "tcp" or "udp" + src netip.AddrPort // closeOnCtxDone lets send register values to Close if the // caller's ctx expires. This avoids send from allocating its @@ -943,13 +970,6 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo f.health.SetUnhealthy(dnsForwarderFailing, health.Args{health.ArgDNSServers: ""}) f.logf("no upstream resolvers set, returning SERVFAIL") - // Attempt to recompile the DNS configuration - // If we are being asked to forward queries and we have no - // nameservers, the network is in a bad state. - if f.missingUpstreamRecovery != nil { - f.missingUpstreamRecovery() - } - res, err := servfailResponse(query) if err != nil { return err @@ -969,11 +989,12 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo txid: getTxID(query.bs), packet: query.bs, family: query.family, + src: query.addr, closeOnCtxDone: new(closePool), } defer fq.closeOnCtxDone.Close() - if verboseDNSForward() { + if f.verboseFwd { domainSha256 := sha256.Sum256([]byte(domain)) domainSig := base64.RawStdEncoding.EncodeToString(domainSha256[:3]) f.logf("request(%d, %v, %d, %s) %d...", fq.txid, typ, len(domain), domainSig, len(fq.packet)) @@ -1018,7 +1039,7 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo metricDNSFwdErrorContext.Add(1) return fmt.Errorf("waiting to send response: %w", ctx.Err()) case responseChan <- packet{v, query.family, query.addr}: - if verboseDNSForward() { + if f.verboseFwd { f.logf("response(%d, %v, %d) = %d, nil", fq.txid, typ, len(domain), len(v)) } metricDNSFwdSuccess.Add(1) @@ -1048,7 +1069,7 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo } f.health.SetUnhealthy(dnsForwarderFailing, health.Args{health.ArgDNSServers: strings.Join(resolverAddrs, ",")}) case responseChan <- res: - if verboseDNSForward() { + if f.verboseFwd { f.logf("forwarder response(%d, %v, %d) = %d, %v", fq.txid, typ, len(domain), len(res.bs), firstErr) } return nil diff --git a/vendor/tailscale.com/net/dns/resolver/tsdns.go b/vendor/tailscale.com/net/dns/resolver/tsdns.go index 107740b..3185cbe 100644 --- a/vendor/tailscale.com/net/dns/resolver/tsdns.go +++ b/vendor/tailscale.com/net/dns/resolver/tsdns.go @@ -25,6 +25,8 @@ import ( dns "golang.org/x/net/dns/dnsmessage" "tailscale.com/control/controlknobs" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/dns/resolvconffile" "tailscale.com/net/netaddr" @@ -212,7 +214,7 @@ type Resolver struct { closed chan struct{} // mu guards the following fields from being updated while used. - mu sync.Mutex + mu syncs.Mutex localDomains []dnsname.FQDN hostToIP map[dnsname.FQDN][]netip.Addr ipToHost map[netip.Addr]dnsname.FQDN @@ -251,18 +253,12 @@ func New(logf logger.Logf, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, h return r } -// SetMissingUpstreamRecovery sets a callback to be called upon encountering -// a SERVFAIL due to missing upstream resolvers. -// -// This call should only happen before the resolver is used. It is not safe -// for concurrent use. -func (r *Resolver) SetMissingUpstreamRecovery(f func()) { - r.forwarder.missingUpstreamRecovery = f -} - func (r *Resolver) TestOnlySetHook(hook func(Config)) { r.saveConfigForTests = hook } func (r *Resolver) SetConfig(cfg Config) error { + if !buildfeatures.HasDNS { + return nil + } if r.saveConfigForTests != nil { r.saveConfigForTests(cfg) } @@ -288,6 +284,9 @@ func (r *Resolver) SetConfig(cfg Config) error { // Close shuts down the resolver and ensures poll goroutines have exited. // The Resolver cannot be used again after Close is called. func (r *Resolver) Close() { + if !buildfeatures.HasDNS { + return + } select { case <-r.closed: return @@ -305,6 +304,9 @@ func (r *Resolver) Close() { const dnsQueryTimeout = 10 * time.Second func (r *Resolver) Query(ctx context.Context, bs []byte, family string, from netip.AddrPort) ([]byte, error) { + if !buildfeatures.HasDNS { + return nil, feature.ErrUnavailable + } metricDNSQueryLocal.Add(1) select { case <-r.closed: @@ -332,6 +334,9 @@ func (r *Resolver) Query(ctx context.Context, bs []byte, family string, from net // GetUpstreamResolvers returns the resolvers that would be used to resolve // the given FQDN. func (r *Resolver) GetUpstreamResolvers(name dnsname.FQDN) []*dnstype.Resolver { + if !buildfeatures.HasDNS { + return nil + } return r.forwarder.GetUpstreamResolvers(name) } @@ -360,6 +365,9 @@ func parseExitNodeQuery(q []byte) *response { // and a nil error. // TODO: figure out if we even need an error result. func (r *Resolver) HandlePeerDNSQuery(ctx context.Context, q []byte, from netip.AddrPort, allowName func(name string) bool) (res []byte, err error) { + if !buildfeatures.HasDNS { + return nil, feature.ErrUnavailable + } metricDNSExitProxyQuery.Add(1) ch := make(chan packet, 1) @@ -436,6 +444,9 @@ var debugExitNodeDNSNetPkg = envknob.RegisterBool("TS_DEBUG_EXIT_NODE_DNS_NET_PK // response contains the pre-serialized response, which notably // includes the original question and its header. func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, logf logger.Logf, resolver *net.Resolver, resp *response) (res []byte, err error) { + if !buildfeatures.HasDNS { + return nil, feature.ErrUnavailable + } logf = logger.WithPrefix(logf, "exitNodeDNSQueryWithNetPkg: ") if resp.Question.Class != dns.ClassINET { return nil, errors.New("unsupported class") @@ -1256,6 +1267,9 @@ func (r *Resolver) respondReverse(query []byte, name dnsname.FQDN, resp *respons // respond returns a DNS response to query if it can be resolved locally. // Otherwise, it returns errNotOurName. func (r *Resolver) respond(query []byte) ([]byte, error) { + if !buildfeatures.HasDNS { + return nil, feature.ErrUnavailable + } parser := dnsParserPool.Get().(*dnsParser) defer dnsParserPool.Put(parser) diff --git a/vendor/tailscale.com/net/dns/wsl_windows.go b/vendor/tailscale.com/net/dns/wsl_windows.go index 8b0780f..81e8593 100644 --- a/vendor/tailscale.com/net/dns/wsl_windows.go +++ b/vendor/tailscale.com/net/dns/wsl_windows.go @@ -76,7 +76,7 @@ func (wm *wslManager) SetDNS(cfg OSConfig) error { } managers := make(map[string]*directManager) for _, distro := range distros { - managers[distro] = newDirectManagerOnFS(wm.logf, wm.health, wslFS{ + managers[distro] = newDirectManagerOnFS(wm.logf, wm.health, nil, wslFS{ user: "root", distro: distro, }) diff --git a/vendor/tailscale.com/net/dnscache/dnscache.go b/vendor/tailscale.com/net/dnscache/dnscache.go index 2cbea6c..e222b98 100644 --- a/vendor/tailscale.com/net/dnscache/dnscache.go +++ b/vendor/tailscale.com/net/dnscache/dnscache.go @@ -19,10 +19,13 @@ import ( "time" "tailscale.com/envknob" + "tailscale.com/net/netx" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/util/cloudenv" "tailscale.com/util/singleflight" "tailscale.com/util/slicesx" + "tailscale.com/util/testenv" ) var zaddr netip.Addr @@ -62,6 +65,10 @@ type Resolver struct { // If nil, net.DefaultResolver is used. Forward *net.Resolver + // LookupIPForTest, if non-nil and in tests, handles requests instead + // of the usual mechanisms. + LookupIPForTest func(ctx context.Context, host string) ([]netip.Addr, error) + // LookupIPFallback optionally provides a backup DNS mechanism // to use if Forward returns an error or no results. LookupIPFallback func(ctx context.Context, host string) ([]netip.Addr, error) @@ -91,7 +98,7 @@ type Resolver struct { sf singleflight.Group[string, ipRes] - mu sync.Mutex + mu syncs.Mutex ipCache map[string]ipCacheEntry } @@ -199,6 +206,9 @@ func (r *Resolver) LookupIP(ctx context.Context, host string) (ip, v6 netip.Addr } allIPs = append(allIPs, naIP) } + if !ip.IsValid() && v6.IsValid() { + ip = v6 + } r.dlogf("returning %d static results", len(allIPs)) return } @@ -283,7 +293,13 @@ func (r *Resolver) lookupIP(ctx context.Context, host string) (ip, ip6 netip.Add lookupCtx, lookupCancel := context.WithTimeout(ctx, r.lookupTimeoutForHost(host)) defer lookupCancel() - ips, err := r.fwd().LookupNetIP(lookupCtx, "ip", host) + + var ips []netip.Addr + if r.LookupIPForTest != nil && testenv.InTest() { + ips, err = r.LookupIPForTest(ctx, host) + } else { + ips, err = r.fwd().LookupNetIP(lookupCtx, "ip", host) + } if err != nil || len(ips) == 0 { if resolver, ok := r.cloudHostResolver(); ok { r.dlogf("resolving %q via cloud resolver", host) @@ -355,10 +371,8 @@ func (r *Resolver) addIPCache(host string, ip, ip6 netip.Addr, allIPs []netip.Ad } } -type DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error) - // Dialer returns a wrapped DialContext func that uses the provided dnsCache. -func Dialer(fwd DialContextFunc, dnsCache *Resolver) DialContextFunc { +func Dialer(fwd netx.DialFunc, dnsCache *Resolver) netx.DialFunc { d := &dialer{ fwd: fwd, dnsCache: dnsCache, @@ -369,7 +383,7 @@ func Dialer(fwd DialContextFunc, dnsCache *Resolver) DialContextFunc { // dialer is the config and accumulated state for a dial func returned by Dialer. type dialer struct { - fwd DialContextFunc + fwd netx.DialFunc dnsCache *Resolver mu sync.Mutex @@ -461,7 +475,7 @@ type dialCall struct { d *dialer network, address, host, port string - mu sync.Mutex // lock ordering: dialer.mu, then dialCall.mu + mu syncs.Mutex // lock ordering: dialer.mu, then dialCall.mu fails map[netip.Addr]error // set of IPs that failed to dial thus far } @@ -653,7 +667,7 @@ func v6addrs(aa []netip.Addr) (ret []netip.Addr) { // TLSDialer is like Dialer but returns a func suitable for using with net/http.Transport.DialTLSContext. // It returns a *tls.Conn type on success. // On TLS cert validation failure, it can invoke a backup DNS resolution strategy. -func TLSDialer(fwd DialContextFunc, dnsCache *Resolver, tlsConfigBase *tls.Config) DialContextFunc { +func TLSDialer(fwd netx.DialFunc, dnsCache *Resolver, tlsConfigBase *tls.Config) netx.DialFunc { tcpDialer := Dialer(fwd, dnsCache) return func(ctx context.Context, network, address string) (net.Conn, error) { host, _, err := net.SplitHostPort(address) diff --git a/vendor/tailscale.com/net/dnsfallback/dnsfallback.go b/vendor/tailscale.com/net/dnsfallback/dnsfallback.go index 4c5d5fa..74b6259 100644 --- a/vendor/tailscale.com/net/dnsfallback/dnsfallback.go +++ b/vendor/tailscale.com/net/dnsfallback/dnsfallback.go @@ -22,35 +22,20 @@ import ( "net/url" "os" "reflect" - "slices" "sync/atomic" "time" "tailscale.com/atomicfile" - "tailscale.com/envknob" + "tailscale.com/feature" "tailscale.com/health" - "tailscale.com/net/dns/recursive" "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/tlsdial" - "tailscale.com/net/tshttpproxy" "tailscale.com/tailcfg" "tailscale.com/types/logger" - "tailscale.com/util/clientmetric" - "tailscale.com/util/singleflight" "tailscale.com/util/slicesx" ) -var ( - optRecursiveResolver = envknob.RegisterOptBool("TS_DNSFALLBACK_RECURSIVE_RESOLVER") - disableRecursiveResolver = envknob.RegisterBool("TS_DNSFALLBACK_DISABLE_RECURSIVE_RESOLVER") // legacy pre-1.52 env knob name -) - -type resolveResult struct { - addrs []netip.Addr - minTTL time.Duration -} - // MakeLookupFunc creates a function that can be used to resolve hostnames // (e.g. as a LookupIPFallback from dnscache.Resolver). // The netMon parameter is optional; if non-nil it's used to do faster interface lookups. @@ -68,145 +53,13 @@ type fallbackResolver struct { logf logger.Logf netMon *netmon.Monitor // or nil healthTracker *health.Tracker // or nil - sf singleflight.Group[string, resolveResult] // for tests waitForCompare bool } func (fr *fallbackResolver) Lookup(ctx context.Context, host string) ([]netip.Addr, error) { - // If they've explicitly disabled the recursive resolver with the legacy - // TS_DNSFALLBACK_DISABLE_RECURSIVE_RESOLVER envknob or not set the - // newer TS_DNSFALLBACK_RECURSIVE_RESOLVER to true, then don't use the - // recursive resolver. (tailscale/corp#15261) In the future, we might - // change the default (the opt.Bool being unset) to mean enabled. - if disableRecursiveResolver() || !optRecursiveResolver().EqualBool(true) { - return lookup(ctx, host, fr.logf, fr.healthTracker, fr.netMon) - } - - addrsCh := make(chan []netip.Addr, 1) - - // Run the recursive resolver in the background so we can - // compare the results. For tests, we also allow waiting for the - // comparison to complete; normally, we do this entirely asynchronously - // so as not to block the caller. - var done chan struct{} - if fr.waitForCompare { - done = make(chan struct{}) - go func() { - defer close(done) - fr.compareWithRecursive(ctx, addrsCh, host) - }() - } else { - go fr.compareWithRecursive(ctx, addrsCh, host) - } - - addrs, err := lookup(ctx, host, fr.logf, fr.healthTracker, fr.netMon) - if err != nil { - addrsCh <- nil - return nil, err - } - - addrsCh <- slices.Clone(addrs) - if fr.waitForCompare { - select { - case <-done: - case <-ctx.Done(): - } - } - return addrs, nil -} - -// compareWithRecursive is responsible for comparing the DNS resolution -// performed via the "normal" path (bootstrap DNS requests to the DERP servers) -// with DNS resolution performed with our in-process recursive DNS resolver. -// -// It will select on addrsCh to read exactly one set of addrs (returned by the -// "normal" path) and compare against the results returned by the recursive -// resolver. If ctx is canceled, then it will abort. -func (fr *fallbackResolver) compareWithRecursive( - ctx context.Context, - addrsCh <-chan []netip.Addr, - host string, -) { - logf := logger.WithPrefix(fr.logf, "recursive: ") - - // Ensure that we catch panics while we're testing this - // code path; this should never panic, but we don't - // want to take down the process by having the panic - // propagate to the top of the goroutine's stack and - // then terminate. - defer func() { - if r := recover(); r != nil { - logf("bootstrap DNS: recovered panic: %v", r) - metricRecursiveErrors.Add(1) - } - }() - - // Don't resolve the same host multiple times - // concurrently; if we end up in a tight loop, this can - // take up a lot of CPU. - var didRun bool - result, err, _ := fr.sf.Do(host, func() (resolveResult, error) { - didRun = true - resolver := &recursive.Resolver{ - Dialer: netns.NewDialer(logf, fr.netMon), - Logf: logf, - } - addrs, minTTL, err := resolver.Resolve(ctx, host) - if err != nil { - logf("error using recursive resolver: %v", err) - metricRecursiveErrors.Add(1) - return resolveResult{}, err - } - return resolveResult{addrs, minTTL}, nil - }) - - // The singleflight function handled errors; return if - // there was one. Additionally, don't bother doing the - // comparison if we waited on another singleflight - // caller; the results are likely to be the same, so - // rather than spam the logs we can just exit and let - // the singleflight call that did execute do the - // comparison. - // - // Returning here is safe because the addrsCh channel - // is buffered, so the main function won't block even - // if we never read from it. - if err != nil || !didRun { - return - } - - addrs, minTTL := result.addrs, result.minTTL - compareAddr := func(a, b netip.Addr) int { return a.Compare(b) } - slices.SortFunc(addrs, compareAddr) - - // Wait for a response from the main function; try this once before we - // check whether the context is canceled since selects are - // nondeterministic. - var oldAddrs []netip.Addr - select { - case oldAddrs = <-addrsCh: - // All good; continue - default: - // Now block. - select { - case oldAddrs = <-addrsCh: - case <-ctx.Done(): - return - } - } - slices.SortFunc(oldAddrs, compareAddr) - - matches := slices.Equal(addrs, oldAddrs) - - logf("bootstrap DNS comparison: matches=%v oldAddrs=%v addrs=%v minTTL=%v", matches, oldAddrs, addrs, minTTL) - - if matches { - metricRecursiveMatches.Add(1) - } else { - metricRecursiveMismatches.Add(1) - } + return lookup(ctx, host, fr.logf, fr.healthTracker, fr.netMon) } func lookup(ctx context.Context, host string, logf logger.Logf, ht *health.Tracker, netMon *netmon.Monitor) ([]netip.Addr, error) { @@ -282,11 +135,11 @@ func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netip.Addr dialer := netns.NewDialer(logf, netMon) tr := http.DefaultTransport.(*http.Transport).Clone() tr.DisableKeepAlives = true // This transport is meant to be used once. - tr.Proxy = tshttpproxy.ProxyFromEnvironment + tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil() tr.DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) { return dialer.DialContext(ctx, "tcp", net.JoinHostPort(serverIP.String(), "443")) } - tr.TLSClientConfig = tlsdial.Config(serverName, ht, tr.TLSClientConfig) + tr.TLSClientConfig = tlsdial.Config(ht, tr.TLSClientConfig) c := &http.Client{Transport: tr} req, err := http.NewRequestWithContext(ctx, "GET", "https://"+serverName+"/bootstrap-dns?q="+url.QueryEscape(queryName), nil) if err != nil { @@ -428,9 +281,3 @@ func SetCachePath(path string, logf logger.Logf) { cachedDERPMap.Store(dm) logf("[v2] dnsfallback: SetCachePath loaded cached DERP map") } - -var ( - metricRecursiveMatches = clientmetric.NewCounter("dnsfallback_recursive_matches") - metricRecursiveMismatches = clientmetric.NewCounter("dnsfallback_recursive_mismatches") - metricRecursiveErrors = clientmetric.NewCounter("dnsfallback_recursive_errors") -) diff --git a/vendor/tailscale.com/net/memnet/listener.go b/vendor/tailscale.com/net/memnet/listener.go index d84a2e4..dded979 100644 --- a/vendor/tailscale.com/net/memnet/listener.go +++ b/vendor/tailscale.com/net/memnet/listener.go @@ -22,6 +22,7 @@ type Listener struct { ch chan Conn closeOnce sync.Once closed chan struct{} + onClose func() // or nil // NewConn, if non-nil, is called to create a new pair of connections // when dialing. If nil, NewConn is used. @@ -38,24 +39,29 @@ func Listen(addr string) *Listener { } // Addr implements net.Listener.Addr. -func (l *Listener) Addr() net.Addr { - return l.addr +func (ln *Listener) Addr() net.Addr { + return ln.addr } // Close closes the pipe listener. -func (l *Listener) Close() error { - l.closeOnce.Do(func() { - close(l.closed) +func (ln *Listener) Close() error { + var cleanup func() + ln.closeOnce.Do(func() { + cleanup = ln.onClose + close(ln.closed) }) + if cleanup != nil { + cleanup() + } return nil } // Accept blocks until a new connection is available or the listener is closed. -func (l *Listener) Accept() (net.Conn, error) { +func (ln *Listener) Accept() (net.Conn, error) { select { - case c := <-l.ch: + case c := <-ln.ch: return c, nil - case <-l.closed: + case <-ln.closed: return nil, net.ErrClosed } } @@ -64,18 +70,18 @@ func (l *Listener) Accept() (net.Conn, error) { // The provided Context must be non-nil. If the context expires before the // connection is complete, an error is returned. Once successfully connected // any expiration of the context will not affect the connection. -func (l *Listener) Dial(ctx context.Context, network, addr string) (_ net.Conn, err error) { +func (ln *Listener) Dial(ctx context.Context, network, addr string) (_ net.Conn, err error) { if !strings.HasSuffix(network, "tcp") { return nil, net.UnknownNetworkError(network) } - if connAddr(addr) != l.addr { + if connAddr(addr) != ln.addr { return nil, &net.AddrError{ Err: "invalid address", Addr: addr, } } - newConn := l.NewConn + newConn := ln.NewConn if newConn == nil { newConn = func(network, addr string, maxBuf int) (Conn, Conn) { return NewConn(addr, maxBuf) @@ -92,9 +98,9 @@ func (l *Listener) Dial(ctx context.Context, network, addr string) (_ net.Conn, select { case <-ctx.Done(): return nil, ctx.Err() - case <-l.closed: + case <-ln.closed: return nil, net.ErrClosed - case l.ch <- s: + case ln.ch <- s: return c, nil } } diff --git a/vendor/tailscale.com/net/memnet/memnet.go b/vendor/tailscale.com/net/memnet/memnet.go index c8799bc..db9e387 100644 --- a/vendor/tailscale.com/net/memnet/memnet.go +++ b/vendor/tailscale.com/net/memnet/memnet.go @@ -6,3 +6,87 @@ // in tests and other situations where you don't want to use the // network. package memnet + +import ( + "context" + "fmt" + "net" + "net/netip" + + "tailscale.com/net/netx" + "tailscale.com/syncs" +) + +var _ netx.Network = (*Network)(nil) + +// Network implements [Network] using an in-memory network, usually +// used for testing. +// +// As of 2025-04-08, it only supports TCP. +// +// Its zero value is a valid [netx.Network] implementation. +type Network struct { + mu syncs.Mutex + lns map[string]*Listener // address -> listener +} + +func (m *Network) Listen(network, address string) (net.Listener, error) { + if network != "tcp" && network != "tcp4" && network != "tcp6" { + return nil, fmt.Errorf("memNetwork: Listen called with unsupported network %q", network) + } + ap, err := netip.ParseAddrPort(address) + if err != nil { + return nil, fmt.Errorf("memNetwork: Listen called with invalid address %q: %w", address, err) + } + + m.mu.Lock() + defer m.mu.Unlock() + + if m.lns == nil { + m.lns = make(map[string]*Listener) + } + port := ap.Port() + for { + if port == 0 { + port = 33000 + } + key := net.JoinHostPort(ap.Addr().String(), fmt.Sprint(port)) + _, ok := m.lns[key] + if ok { + if ap.Port() != 0 { + return nil, fmt.Errorf("memNetwork: Listen called with duplicate address %q", address) + } + port++ + continue + } + ln := Listen(key) + m.lns[key] = ln + ln.onClose = func() { + m.mu.Lock() + delete(m.lns, key) + m.mu.Unlock() + } + return ln, nil + } +} + +func (m *Network) NewLocalTCPListener() net.Listener { + ln, err := m.Listen("tcp", "127.0.0.1:0") + if err != nil { + panic(fmt.Sprintf("memNetwork: failed to create local TCP listener: %v", err)) + } + return ln +} + +func (m *Network) Dial(ctx context.Context, network, address string) (net.Conn, error) { + if network != "tcp" && network != "tcp4" && network != "tcp6" { + return nil, fmt.Errorf("memNetwork: Dial called with unsupported network %q", network) + } + m.mu.Lock() + ln, ok := m.lns[address] + m.mu.Unlock() + if !ok { + return nil, fmt.Errorf("memNetwork: Dial called on unknown address %q", address) + } + return ln.Dial(ctx, network, address) +} diff --git a/vendor/tailscale.com/net/netaddr/netaddr.go b/vendor/tailscale.com/net/netaddr/netaddr.go index 1ab6c05..a04acd5 100644 --- a/vendor/tailscale.com/net/netaddr/netaddr.go +++ b/vendor/tailscale.com/net/netaddr/netaddr.go @@ -34,7 +34,7 @@ func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) { } ip = ip.Unmap() - if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len { + if ln := len(std.Mask); ln != net.IPv4len && ln != net.IPv6len { // Invalid mask. return netip.Prefix{}, false } diff --git a/vendor/tailscale.com/net/netcheck/captiveportal.go b/vendor/tailscale.com/net/netcheck/captiveportal.go new file mode 100644 index 0000000..ad11f19 --- /dev/null +++ b/vendor/tailscale.com/net/netcheck/captiveportal.go @@ -0,0 +1,55 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_captiveportal + +package netcheck + +import ( + "context" + "time" + + "tailscale.com/net/captivedetection" + "tailscale.com/tailcfg" +) + +func init() { + hookStartCaptivePortalDetection.Set(startCaptivePortalDetection) +} + +func startCaptivePortalDetection(ctx context.Context, rs *reportState, dm *tailcfg.DERPMap, preferredDERP int) (done <-chan struct{}, stop func()) { + c := rs.c + + // NOTE(andrew): we can't simply add this goroutine to the + // `NewWaitGroupChan` below, since we don't wait for that + // waitgroup to finish when exiting this function and thus get + // a data race. + ch := make(chan struct{}) + + tmr := time.AfterFunc(c.captivePortalDelay(), func() { + defer close(ch) + d := captivedetection.NewDetector(c.logf) + found := d.Detect(ctx, c.NetMon, dm, preferredDERP) + rs.report.CaptivePortal.Set(found) + }) + + stop = func() { + // Don't cancel our captive portal check if we're + // explicitly doing a verbose netcheck. + if c.Verbose { + return + } + + if tmr.Stop() { + // Stopped successfully; need to close the + // signal channel ourselves. + close(ch) + return + } + + // Did not stop; do nothing and it'll finish by itself + // and close the signal channel. + } + + return ch, stop +} diff --git a/vendor/tailscale.com/net/netcheck/netcheck.go b/vendor/tailscale.com/net/netcheck/netcheck.go index a33ca22..c5a3d23 100644 --- a/vendor/tailscale.com/net/netcheck/netcheck.go +++ b/vendor/tailscale.com/net/netcheck/netcheck.go @@ -23,15 +23,18 @@ import ( "syscall" "time" + "tailscale.com/derp" "tailscale.com/derp/derphttp" "tailscale.com/envknob" - "tailscale.com/net/captivedetection" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" + "tailscale.com/hostinfo" "tailscale.com/net/dnscache" "tailscale.com/net/neterror" "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/ping" - "tailscale.com/net/portmapper" + "tailscale.com/net/portmapper/portmappertype" "tailscale.com/net/sockstats" "tailscale.com/net/stun" "tailscale.com/syncs" @@ -213,7 +216,7 @@ type Client struct { // PortMapper, if non-nil, is used for portmap queries. // If nil, portmap discovery is not done. - PortMapper *portmapper.Client // lazily initialized on first use + PortMapper portmappertype.Client // UseDNSCache controls whether this client should use a // *dnscache.Resolver to resolve DERP hostnames, when no IP address is @@ -232,7 +235,7 @@ type Client struct { testEnoughRegions int testCaptivePortalDelay time.Duration - mu sync.Mutex // guards following + mu syncs.Mutex // guards following nextFull bool // do a full region scan, even if last != nil prev map[time.Time]*Report // some previous reports last *Report // most recent report @@ -448,7 +451,7 @@ func makeProbePlan(dm *tailcfg.DERPMap, ifState *netmon.State, last *Report, pre // restoration back to the home DERP on the next full netcheck ~5 minutes later // - which is highly disruptive when it causes shifts in geo routed subnet // routers. By always including the home DERP in the incremental netcheck, we - // ensure that the home DERP is always probed, even if it observed a recenet + // ensure that the home DERP is always probed, even if it observed a recent // poor latency sample. This inclusion enables the latency history checks in // home DERP selection to still take effect. // planContainsHome indicates whether the home DERP has been added to the probePlan, @@ -594,7 +597,7 @@ type reportState struct { stopProbeCh chan struct{} waitPortMap sync.WaitGroup - mu sync.Mutex + mu syncs.Mutex report *Report // to be returned by GetReport inFlight map[stun.TxID]func(netip.AddrPort) // called without c.mu held gotEP4 netip.AddrPort @@ -728,7 +731,7 @@ func (rs *reportState) probePortMapServices() { res, err := rs.c.PortMapper.Probe(context.Background()) if err != nil { - if !errors.Is(err, portmapper.ErrGatewayRange) { + if !errors.Is(err, portmappertype.ErrGatewayRange) { // "skipping portmap; gateway range likely lacks support" // is not very useful, and too spammy on cloud systems. // If there are other errors, we want to log those. @@ -752,6 +755,7 @@ func newReport() *Report { // GetReportOpts contains options that can be passed to GetReport. Unless // specified, all fields are optional and can be left as their zero value. +// At most one of OnlyTCP443 or OnlySTUN may be set. type GetReportOpts struct { // GetLastDERPActivity is a callback that, if provided, should return // the absolute time that the calling code last communicated with a @@ -764,6 +768,8 @@ type GetReportOpts struct { // OnlyTCP443 constrains netcheck reporting to measurements over TCP port // 443. OnlyTCP443 bool + // OnlySTUN constrains netcheck reporting to STUN measurements over UDP. + OnlySTUN bool } // getLastDERPActivity calls o.GetLastDERPActivity if both o and @@ -781,6 +787,8 @@ func (c *Client) SetForcePreferredDERP(region int) { c.ForcePreferredDERP = region } +var hookStartCaptivePortalDetection feature.Hook[func(ctx context.Context, rs *reportState, dm *tailcfg.DERPMap, preferredDERP int) (<-chan struct{}, func())] + // GetReport gets a report. The 'opts' argument is optional and can be nil. // Callers are discouraged from passing a ctx with an arbitrary deadline as this // may cause GetReport to return prematurely before all reporting methods have @@ -789,6 +797,13 @@ func (c *Client) SetForcePreferredDERP(region int) { // // It may not be called concurrently with itself. func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetReportOpts) (_ *Report, reterr error) { + onlySTUN := false + if opts != nil && opts.OnlySTUN { + if opts.OnlyTCP443 { + return nil, errors.New("netcheck: only one of OnlySTUN or OnlyTCP443 may be set in opts") + } + onlySTUN = true + } defer func() { if reterr != nil { metricNumGetReportError.Add(1) @@ -863,7 +878,10 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe c.curState = nil }() - if runtime.GOOS == "js" || runtime.GOOS == "tamago" { + if runtime.GOOS == "js" || runtime.GOOS == "tamago" || (runtime.GOOS == "plan9" && hostinfo.IsInVM86()) { + if onlySTUN { + return nil, errors.New("platform is restricted to HTTP, but OnlySTUN is set in opts") + } if err := c.runHTTPOnlyChecks(ctx, last, rs, dm); err != nil { return nil, err } @@ -895,38 +913,9 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe // it's unnecessary. captivePortalDone := syncs.ClosedChan() captivePortalStop := func() {} - if !rs.incremental { - // NOTE(andrew): we can't simply add this goroutine to the - // `NewWaitGroupChan` below, since we don't wait for that - // waitgroup to finish when exiting this function and thus get - // a data race. - ch := make(chan struct{}) - captivePortalDone = ch - - tmr := time.AfterFunc(c.captivePortalDelay(), func() { - defer close(ch) - d := captivedetection.NewDetector(c.logf) - found := d.Detect(ctx, c.NetMon, dm, preferredDERP) - rs.report.CaptivePortal.Set(found) - }) - - captivePortalStop = func() { - // Don't cancel our captive portal check if we're - // explicitly doing a verbose netcheck. - if c.Verbose { - return - } - - if tmr.Stop() { - // Stopped successfully; need to close the - // signal channel ourselves. - close(ch) - return - } - - // Did not stop; do nothing and it'll finish by itself - // and close the signal channel. - } + if buildfeatures.HasCaptivePortal && !rs.incremental && !onlySTUN { + start := hookStartCaptivePortalDetection.Get() + captivePortalDone, captivePortalStop = start(ctx, rs, dm, preferredDERP) } wg := syncs.NewWaitGroupChan() @@ -969,13 +958,13 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe rs.stopTimers() // Try HTTPS and ICMP latency check if all STUN probes failed due to - // UDP presumably being blocked. + // UDP presumably being blocked, and we are not constrained to only STUN. // TODO: this should be moved into the probePlan, using probeProto probeHTTPS. - if !rs.anyUDP() && ctx.Err() == nil { + if !rs.anyUDP() && ctx.Err() == nil && !onlySTUN { var wg sync.WaitGroup var need []*tailcfg.DERPRegion for rid, reg := range dm.Regions { - if !rs.haveRegionLatency(rid) && regionHasDERPNode(reg) { + if !rs.haveRegionLatency(rid) && regionHasDERPNode(reg) && !reg.Avoid && !reg.NoMeasureNoHome { need = append(need, reg) } } @@ -1004,9 +993,9 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe c.logf("[v1] netcheck: measuring HTTPS latency of %v (%d): %v", reg.RegionCode, reg.RegionID, err) } else { rs.mu.Lock() - if l, ok := rs.report.RegionLatency[reg.RegionID]; !ok { + if latency, ok := rs.report.RegionLatency[reg.RegionID]; !ok { mak.Set(&rs.report.RegionLatency, reg.RegionID, d) - } else if l >= d { + } else if latency >= d { rs.report.RegionLatency[reg.RegionID] = d } // We set these IPv4 and IPv6 but they're not really used @@ -1045,7 +1034,7 @@ func (c *Client) finishAndStoreReport(rs *reportState, dm *tailcfg.DERPMap) *Rep } // runHTTPOnlyChecks is the netcheck done by environments that can -// only do HTTP requests, such as ws/wasm. +// only do HTTP requests, such as js/wasm. func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *reportState, dm *tailcfg.DERPMap) error { var regions []*tailcfg.DERPRegion if rs.incremental && last != nil { @@ -1057,9 +1046,25 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report } if len(regions) == 0 { for _, dr := range dm.Regions { + if dr.NoMeasureNoHome { + continue + } regions = append(regions, dr) } } + + if len(regions) == 1 && hostinfo.IsInVM86() { + // If we only have 1 region that's probably and we're in a + // network-limited v86 environment, don't actually probe it. Just fake + // some results. + rg := regions[0] + if len(rg.Nodes) > 0 { + node := rg.Nodes[0] + rs.addNodeLatency(node, netip.AddrPort{}, 999*time.Millisecond) + return nil + } + } + c.logf("running HTTP-only netcheck against %v regions", len(regions)) var wg sync.WaitGroup @@ -1068,7 +1073,6 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report continue } wg.Add(1) - rg := rg go func() { defer wg.Done() node := rg.Nodes[0] @@ -1188,6 +1192,10 @@ func (c *Client) measureAllICMPLatency(ctx context.Context, rs *reportState, nee if len(need) == 0 { return nil } + if runtime.GOOS == "plan9" { + // ICMP isn't implemented. + return nil + } ctx, done := context.WithTimeout(ctx, icmpProbeTimeout) defer done() @@ -1206,9 +1214,9 @@ func (c *Client) measureAllICMPLatency(ctx context.Context, rs *reportState, nee } else if ok { c.logf("[v1] ICMP latency of %v (%d): %v", reg.RegionCode, reg.RegionID, d) rs.mu.Lock() - if l, ok := rs.report.RegionLatency[reg.RegionID]; !ok { + if latency, ok := rs.report.RegionLatency[reg.RegionID]; !ok { mak.Set(&rs.report.RegionLatency, reg.RegionID, d) - } else if l >= d { + } else if latency >= d { rs.report.RegionLatency[reg.RegionID] = d } @@ -1337,6 +1345,15 @@ const ( // even without receiving a STUN response. // Note: must remain higher than the derp package frameReceiveRecordRate PreferredDERPFrameTime = 8 * time.Second + // PreferredDERPKeepAliveTimeout is 2x the DERP Keep Alive timeout. If there + // is no latency data to make judgements from, but we have heard from our + // current DERP region inside of 2x the KeepAlive window, don't switch DERP + // regions yet, keep the current region. This prevents region flapping / + // home DERP removal during short periods of packet loss where the DERP TCP + // connection may itself naturally recover. + // TODO(raggi): expose shared time bounds from the DERP package rather than + // duplicating them here. + PreferredDERPKeepAliveTimeout = 2 * derp.KeepAlive ) // addReportHistoryAndSetPreferredDERP adds r to the set of recent Reports @@ -1421,13 +1438,10 @@ func (c *Client) addReportHistoryAndSetPreferredDERP(rs *reportState, r *Report, // the STUN probe) since we started the netcheck, or in the past 2s, as // another signal for "this region is still working". heardFromOldRegionRecently := false + prevRegionLastHeard := rs.opts.getLastDERPActivity(prevDERP) if changingPreferred { - if lastHeard := rs.opts.getLastDERPActivity(prevDERP); !lastHeard.IsZero() { - now := c.timeNow() - - heardFromOldRegionRecently = lastHeard.After(rs.start) - heardFromOldRegionRecently = heardFromOldRegionRecently || lastHeard.After(now.Add(-PreferredDERPFrameTime)) - } + heardFromOldRegionRecently = prevRegionLastHeard.After(rs.start) + heardFromOldRegionRecently = heardFromOldRegionRecently || prevRegionLastHeard.After(now.Add(-PreferredDERPFrameTime)) } // The old region is accessible if we've heard from it via a non-STUN @@ -1454,17 +1468,20 @@ func (c *Client) addReportHistoryAndSetPreferredDERP(rs *reportState, r *Report, // If the forced DERP region probed successfully, or has recent traffic, // use it. _, haveLatencySample := r.RegionLatency[c.ForcePreferredDERP] - var recentActivity bool - if lastHeard := rs.opts.getLastDERPActivity(c.ForcePreferredDERP); !lastHeard.IsZero() { - now := c.timeNow() - recentActivity = lastHeard.After(rs.start) - recentActivity = recentActivity || lastHeard.After(now.Add(-PreferredDERPFrameTime)) - } + lastHeard := rs.opts.getLastDERPActivity(c.ForcePreferredDERP) + recentActivity := lastHeard.After(rs.start) + recentActivity = recentActivity || lastHeard.After(now.Add(-PreferredDERPFrameTime)) if haveLatencySample || recentActivity { r.PreferredDERP = c.ForcePreferredDERP } } + // If there was no latency data to make judgements on, but there is an + // active DERP connection that has at least been doing KeepAlive recently, + // keep it, rather than dropping it. + if r.PreferredDERP == 0 && prevRegionLastHeard.After(now.Add(-PreferredDERPKeepAliveTimeout)) { + r.PreferredDERP = prevDERP + } } func updateLatency(m map[int]time.Duration, regionID int, d time.Duration) { diff --git a/vendor/tailscale.com/net/netcheck/standalone.go b/vendor/tailscale.com/net/netcheck/standalone.go index c72d700..b4523a8 100644 --- a/vendor/tailscale.com/net/netcheck/standalone.go +++ b/vendor/tailscale.com/net/netcheck/standalone.go @@ -13,7 +13,6 @@ import ( "tailscale.com/net/stun" "tailscale.com/types/logger" "tailscale.com/types/nettype" - "tailscale.com/util/multierr" ) // Standalone creates the necessary UDP sockets on the given bindAddr and starts @@ -62,7 +61,7 @@ func (c *Client) Standalone(ctx context.Context, bindAddr string) error { // If both v4 and v6 failed, report an error, otherwise let one succeed. if len(errs) == 2 { - return multierr.New(errs...) + return errors.Join(errs...) } return nil } diff --git a/vendor/tailscale.com/net/netkernelconf/netkernelconf_default.go b/vendor/tailscale.com/net/netkernelconf/netkernelconf_default.go index ec1b2e6..3e160e5 100644 --- a/vendor/tailscale.com/net/netkernelconf/netkernelconf_default.go +++ b/vendor/tailscale.com/net/netkernelconf/netkernelconf_default.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !linux +//go:build !linux || android package netkernelconf diff --git a/vendor/tailscale.com/net/netkernelconf/netkernelconf_linux.go b/vendor/tailscale.com/net/netkernelconf/netkernelconf_linux.go index 51ed8ea..2a4f0a0 100644 --- a/vendor/tailscale.com/net/netkernelconf/netkernelconf_linux.go +++ b/vendor/tailscale.com/net/netkernelconf/netkernelconf_linux.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build linux && !android + package netkernelconf import ( diff --git a/vendor/tailscale.com/net/netmon/defaultroute_darwin.go b/vendor/tailscale.com/net/netmon/defaultroute_darwin.go index 4efe2f1..57f7e22 100644 --- a/vendor/tailscale.com/net/netmon/defaultroute_darwin.go +++ b/vendor/tailscale.com/net/netmon/defaultroute_darwin.go @@ -6,6 +6,8 @@ package netmon import ( + "errors" + "fmt" "log" "net" @@ -16,14 +18,26 @@ var ( lastKnownDefaultRouteIfName syncs.AtomicValue[string] ) -// UpdateLastKnownDefaultRouteInterface is called by ipn-go-bridge in the iOS app when +// UpdateLastKnownDefaultRouteInterface is called by ipn-go-bridge from apple network extensions when // our NWPathMonitor instance detects a network path transition. func UpdateLastKnownDefaultRouteInterface(ifName string) { if ifName == "" { return } if old := lastKnownDefaultRouteIfName.Swap(ifName); old != ifName { - log.Printf("defaultroute_darwin: update from Swift, ifName = %s (was %s)", ifName, old) + interfaces, err := netInterfaces() + if err != nil { + log.Printf("defaultroute_darwin: UpdateLastKnownDefaultRouteInterface could not get interfaces: %v", err) + return + } + + netif, err := getInterfaceByName(ifName, interfaces) + if err != nil { + log.Printf("defaultroute_darwin: UpdateLastKnownDefaultRouteInterface could not find interface index for %s: %v", ifName, err) + return + } + + log.Printf("defaultroute_darwin: updated last known default if from OS, ifName = %s index: %d (was %s)", ifName, netif.Index, old) } } @@ -40,45 +54,12 @@ func defaultRoute() (d DefaultRouteDetails, err error) { // // If for any reason the Swift machinery didn't work and we don't get any updates, we will // fallback to the BSD logic. - - // Start by getting all available interfaces. - interfaces, err := netInterfaces() - if err != nil { - log.Printf("defaultroute_darwin: could not get interfaces: %v", err) - return d, ErrNoGatewayIndexFound - } - - getInterfaceByName := func(name string) *Interface { - for _, ifc := range interfaces { - if ifc.Name != name { - continue - } - - if !ifc.IsUp() { - log.Printf("defaultroute_darwin: %s is down", name) - return nil - } - - addrs, _ := ifc.Addrs() - if len(addrs) == 0 { - log.Printf("defaultroute_darwin: %s has no addresses", name) - return nil - } - return &ifc - } - return nil - } - - // Did Swift set lastKnownDefaultRouteInterface? If so, we should use it and don't bother - // with anything else. However, for sanity, do check whether Swift gave us with an interface - // that exists, is up, and has an address. - if swiftIfName := lastKnownDefaultRouteIfName.Load(); swiftIfName != "" { - ifc := getInterfaceByName(swiftIfName) - if ifc != nil { - d.InterfaceName = ifc.Name - d.InterfaceIndex = ifc.Index - return d, nil - } + osRoute, osRouteErr := OSDefaultRoute() + if osRouteErr == nil { + // If we got a valid interface from the OS, use it. + d.InterfaceName = osRoute.InterfaceName + d.InterfaceIndex = osRoute.InterfaceIndex + return d, nil } // Fallback to the BSD logic @@ -94,3 +75,48 @@ func defaultRoute() (d DefaultRouteDetails, err error) { d.InterfaceIndex = idx return d, nil } + +// OSDefaultRoute returns the DefaultRouteDetails for the default interface as provided by the OS +// via UpdateLastKnownDefaultRouteInterface. If UpdateLastKnownDefaultRouteInterface has not been called, +// the interface name is not valid, or we cannot find its index, an error is returned. +func OSDefaultRoute() (d DefaultRouteDetails, err error) { + + // Did Swift set lastKnownDefaultRouteInterface? If so, we should use it and don't bother + // with anything else. However, for sanity, do check whether Swift gave us with an interface + // that exists, is up, and has an address and is not the tunnel itself. + if swiftIfName := lastKnownDefaultRouteIfName.Load(); swiftIfName != "" { + // Start by getting all available interfaces. + interfaces, err := netInterfaces() + if err != nil { + log.Printf("defaultroute_darwin: could not get interfaces: %v", err) + return d, err + } + + if ifc, err := getInterfaceByName(swiftIfName, interfaces); err == nil { + d.InterfaceName = ifc.Name + d.InterfaceIndex = ifc.Index + return d, nil + } + } + err = errors.New("no os provided default route interface found") + return d, err +} + +func getInterfaceByName(name string, interfaces []Interface) (*Interface, error) { + for _, ifc := range interfaces { + if ifc.Name != name { + continue + } + + if !ifc.IsUp() { + return nil, fmt.Errorf("defaultroute_darwin: %s is down", name) + } + + addrs, _ := ifc.Addrs() + if len(addrs) == 0 { + return nil, fmt.Errorf("defaultroute_darwin: %s has no addresses", name) + } + return &ifc, nil + } + return nil, errors.New("no interfaces found") +} diff --git a/vendor/tailscale.com/net/netmon/interfaces.go b/vendor/tailscale.com/net/netmon/interfaces.go new file mode 100644 index 0000000..4cf9397 --- /dev/null +++ b/vendor/tailscale.com/net/netmon/interfaces.go @@ -0,0 +1,103 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package netmon + +import ( + "errors" + "net" + + "tailscale.com/syncs" +) + +type ifProps struct { + mu syncs.Mutex + name string // interface name, if known/set + index int // interface index, if known/set +} + +// tsIfProps tracks the properties (name and index) of the tailscale interface. +// There is only one tailscale interface per tailscaled instance. +var tsIfProps ifProps + +func (p *ifProps) tsIfName() string { + p.mu.Lock() + defer p.mu.Unlock() + return p.name +} + +func (p *ifProps) tsIfIndex() int { + p.mu.Lock() + defer p.mu.Unlock() + return p.index +} + +func (p *ifProps) set(ifName string, ifIndex int) { + p.mu.Lock() + defer p.mu.Unlock() + p.name = ifName + p.index = ifIndex +} + +// TODO (barnstar): This doesn't need the Monitor receiver anymore but we're +// keeping it for API compatibility to avoid a breaking change.  This can be +// removed when the various clients have switched to SetTailscaleInterfaceProps +func (m *Monitor) SetTailscaleInterfaceName(ifName string) { + SetTailscaleInterfaceProps(ifName, 0) +} + +// SetTailscaleInterfaceProps sets the name of the Tailscale interface and +// its index for use by various listeners/dialers. If the index is zero, +// an attempt will be made to look it up by name. This makes no attempt +// to validate that the interface exists at the time of calling. +// +// If this method is called, it is the responsibility of the caller to +// update the interface name and index if they change. +// +// This should be called as early as possible during tailscaled startup. +func SetTailscaleInterfaceProps(ifName string, ifIndex int) { + if ifIndex != 0 { + tsIfProps.set(ifName, ifIndex) + return + } + + ifaces, err := net.Interfaces() + if err != nil { + return + } + + for _, iface := range ifaces { + if iface.Name == ifName { + ifIndex = iface.Index + break + } + } + + tsIfProps.set(ifName, ifIndex) +} + +// TailscaleInterfaceName returns the name of the Tailscale interface. +// For example, "tailscale0", "tun0", "utun3", etc or an error if unset. +// +// Callers must handle errors, as the Tailscale interface +// name may not be set in some environments. +func TailscaleInterfaceName() (string, error) { + name := tsIfProps.tsIfName() + if name == "" { + return "", errors.New("Tailscale interface name not set") + } + return name, nil +} + +// TailscaleInterfaceIndex returns the index of the Tailscale interface or +// an error if unset. +// +// Callers must handle errors, as the Tailscale interface +// index may not be set in some environments. +func TailscaleInterfaceIndex() (int, error) { + index := tsIfProps.tsIfIndex() + if index == 0 { + return 0, errors.New("Tailscale interface index not set") + } + return index, nil +} diff --git a/vendor/tailscale.com/net/netmon/interfaces_darwin.go b/vendor/tailscale.com/net/netmon/interfaces_darwin.go index b175f98..1260403 100644 --- a/vendor/tailscale.com/net/netmon/interfaces_darwin.go +++ b/vendor/tailscale.com/net/netmon/interfaces_darwin.go @@ -7,12 +7,12 @@ import ( "fmt" "net" "strings" - "sync" "syscall" "unsafe" "golang.org/x/net/route" "golang.org/x/sys/unix" + "tailscale.com/syncs" "tailscale.com/util/mak" ) @@ -26,7 +26,7 @@ func parseRoutingTable(rib []byte) ([]route.Message, error) { } var ifNames struct { - sync.Mutex + syncs.Mutex m map[int]string // ifindex => name } diff --git a/vendor/tailscale.com/net/netmon/interfaces_linux.go b/vendor/tailscale.com/net/netmon/interfaces_linux.go index d0fb15a..a9b93c0 100644 --- a/vendor/tailscale.com/net/netmon/interfaces_linux.go +++ b/vendor/tailscale.com/net/netmon/interfaces_linux.go @@ -22,6 +22,7 @@ import ( "github.com/mdlayher/netlink" "go4.org/mem" "golang.org/x/sys/unix" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/netaddr" "tailscale.com/util/lineiter" ) @@ -41,6 +42,9 @@ ens18 00000000 0100000A 0003 0 0 0 00000000 ens18 0000000A 00000000 0001 0 0 0 0000FFFF 0 0 0 */ func likelyHomeRouterIPLinux() (ret netip.Addr, myIP netip.Addr, ok bool) { + if !buildfeatures.HasPortMapper { + return + } if procNetRouteErr.Load() { // If we failed to read /proc/net/route previously, don't keep trying. return ret, myIP, false diff --git a/vendor/tailscale.com/net/netmon/interfaces_windows.go b/vendor/tailscale.com/net/netmon/interfaces_windows.go index 00b686e..d6625ea 100644 --- a/vendor/tailscale.com/net/netmon/interfaces_windows.go +++ b/vendor/tailscale.com/net/netmon/interfaces_windows.go @@ -13,6 +13,7 @@ import ( "golang.org/x/sys/windows" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" + "tailscale.com/feature/buildfeatures" "tailscale.com/tsconst" ) @@ -22,7 +23,9 @@ const ( func init() { likelyHomeRouterIP = likelyHomeRouterIPWindows - getPAC = getPACWindows + if buildfeatures.HasUseProxy { + getPAC = getPACWindows + } } func likelyHomeRouterIPWindows() (ret netip.Addr, _ netip.Addr, ok bool) { @@ -244,6 +247,9 @@ const ( ) func getPACWindows() string { + if !buildfeatures.HasUseProxy { + return "" + } var res *uint16 r, _, e := detectAutoProxyConfigURL.Call( winHTTP_AUTO_DETECT_TYPE_DHCP|winHTTP_AUTO_DETECT_TYPE_DNS_A, diff --git a/vendor/tailscale.com/net/netmon/loghelper.go b/vendor/tailscale.com/net/netmon/loghelper.go index 824faee..2876e9b 100644 --- a/vendor/tailscale.com/net/netmon/loghelper.go +++ b/vendor/tailscale.com/net/netmon/loghelper.go @@ -4,39 +4,46 @@ package netmon import ( + "context" "sync" + "time" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) +const cooldownSeconds = 300 + // LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique -// format string to the underlying logger only once per major LinkChange event. +// format string to the underlying logger only once per major LinkChange event +// with a cooldownSeconds second cooldown. // -// The returned function should be called when the logger is no longer needed, -// to release resources from the Monitor. -func LinkChangeLogLimiter(logf logger.Logf, nm *Monitor) (_ logger.Logf, unregister func()) { - var formatSeen sync.Map // map[string]bool - unregister = nm.RegisterChangeCallback(func(cd *ChangeDelta) { - // If we're in a major change or a time jump, clear the seen map. - if cd.Major || cd.TimeJumped { - formatSeen.Clear() +// The logger stops tracking seen format strings when the provided context is +// done. +func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf { + var formatLastSeen sync.Map // map[string]int64 + + sub := eventbus.SubscribeFunc(nm.b, func(cd *ChangeDelta) { + // Any link changes that are flagged as likely require a rebind are + // interesting enough that we should log them. + if cd.RebindLikelyRequired { + formatLastSeen.Clear() } }) - + context.AfterFunc(ctx, sub.Close) return func(format string, args ...any) { - // We only store 'true' in the map, so if it's present then it - // means we've already logged this format string. - _, loaded := formatSeen.LoadOrStore(format, true) - if loaded { - // TODO(andrew-d): we may still want to log this - // message every N minutes (1x/hour?) even if it's been - // seen, so that debugging doesn't require searching - // back in the logs for an unbounded amount of time. - // - // See: https://github.com/tailscale/tailscale/issues/13145 - return + // get the current timestamp + now := time.Now().Unix() + lastSeen, ok := formatLastSeen.Load(format) + if ok { + // if we've seen this format string within the last cooldownSeconds, skip logging + if now-lastSeen.(int64) < cooldownSeconds { + return + } } + // update the last seen timestamp for this format string + formatLastSeen.Store(format, now) logf(format, args...) - }, unregister + } } diff --git a/vendor/tailscale.com/net/netmon/netmon.go b/vendor/tailscale.com/net/netmon/netmon.go index bd62ab2..e18bc39 100644 --- a/vendor/tailscale.com/net/netmon/netmon.go +++ b/vendor/tailscale.com/net/netmon/netmon.go @@ -7,15 +7,20 @@ package netmon import ( - "encoding/json" "errors" + "fmt" + "log" "net/netip" "runtime" + "slices" "sync" "time" + "tailscale.com/feature/buildfeatures" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" "tailscale.com/util/set" ) @@ -42,27 +47,28 @@ type osMon interface { // until the osMon is closed. After a Close, the returned // error is ignored. Receive() (message, error) - - // IsInterestingInterface reports whether the provided interface should - // be considered for network change events. - IsInterestingInterface(iface string) bool } +// IsInterestingInterface is the function used to determine whether +// a given interface name is interesting enough to pay attention to +// for network change monitoring purposes. +// +// If nil, all interfaces are considered interesting. +var IsInterestingInterface func(Interface, []netip.Prefix) bool + // Monitor represents a monitoring instance. type Monitor struct { - logf logger.Logf + logf logger.Logf + b *eventbus.Client + changed *eventbus.Publisher[ChangeDelta] + om osMon // nil means not supported on this platform change chan bool // send false to wake poller, true to also force ChangeDeltas be sent stop chan struct{} // closed on Stop static bool // static Monitor that doesn't actually monitor - // Things that must be set early, before use, - // and not change at runtime. - tsIfName string // tailscale interface name, if known/set ("tailscale0", "utun3", ...) - - mu sync.Mutex // guards all following fields + mu syncs.Mutex // guards all following fields cbs set.HandleSet[ChangeFunc] - ruleDelCB set.HandleSet[RuleDeleteCallback] ifState *State gwValid bool // whether gw and gwSelfIP are valid gw netip.Addr // our gateway's IP @@ -80,55 +86,246 @@ type Monitor struct { type ChangeFunc func(*ChangeDelta) // ChangeDelta describes the difference between two network states. +// +// Use NewChangeDelta to construct a delta and compute the cached fields. type ChangeDelta struct { - // Monitor is the network monitor that sent this delta. - Monitor *Monitor - - // Old is the old interface state, if known. + // old is the old interface state, if known. // It's nil if the old state is unknown. - // Do not mutate it. - Old *State + old *State // New is the new network state. // It is always non-nil. - // Do not mutate it. - New *State - - // Major is our legacy boolean of whether the network changed in some major - // way. - // - // Deprecated: do not remove. As of 2023-08-23 we're in a renewed effort to - // remove it and ask specific qustions of ChangeDelta instead. Look at Old - // and New (or add methods to ChangeDelta) instead of using Major. - Major bool + new *State // TimeJumped is whether there was a big jump in wall time since the last - // time we checked. This is a hint that a mobile sleeping device might have + // time we checked. This is a hint that a sleeping device might have // come out of sleep. TimeJumped bool - // TODO(bradfitz): add some lazy cached fields here as needed with methods - // on *ChangeDelta to let callers ask specific questions + DefaultRouteInterface string + + // Computed Fields + + DefaultInterfaceChanged bool // whether default route interface changed + IsLessExpensive bool // whether new state's default interface is less expensive than old. + HasPACOrProxyConfigChanged bool // whether PAC/HTTP proxy config changed + InterfaceIPsChanged bool // whether any interface IPs changed in a meaningful way + AvailableProtocolsChanged bool // whether we have seen a change in available IPv4/IPv6 + DefaultInterfaceMaybeViable bool // whether the default interface is potentially viable (has usable IPs, is up and is not the tunnel itself) + IsInitialState bool // whether this is the initial state (old == nil, new != nil) + + // RebindLikelyRequired combines the various fields above to report whether this change likely requires us + // to rebind sockets. This is a very conservative estimate and covers a number ofcases where a rebind + // may not be strictly necessary. Consumers of the ChangeDelta should consider checking the individual fields + // above or the state of their sockets. + RebindLikelyRequired bool +} + +// CurrentState returns the current (new) state after the change. +func (cd *ChangeDelta) CurrentState() *State { + return cd.new +} + +// NewChangeDelta builds a ChangeDelta and eagerly computes the cached fields. +// forceViability, if true, forces DefaultInterfaceMaybeViable to be true regardless of the +// actual state of the default interface. This is useful in testing. +func NewChangeDelta(old, new *State, timeJumped bool, forceViability bool) (*ChangeDelta, error) { + cd := ChangeDelta{ + old: old, + new: new, + TimeJumped: timeJumped, + } + + if cd.new == nil { + log.Printf("[unexpected] NewChangeDelta called with nil new state") + return nil, errors.New("new state cannot be nil") + } else if cd.old == nil && cd.new != nil { + cd.DefaultInterfaceChanged = cd.new.DefaultRouteInterface != "" + cd.IsLessExpensive = false + cd.HasPACOrProxyConfigChanged = true + cd.InterfaceIPsChanged = true + cd.IsInitialState = true + } else { + cd.AvailableProtocolsChanged = (cd.old.HaveV4 != cd.new.HaveV4) || (cd.old.HaveV6 != cd.new.HaveV6) + cd.DefaultInterfaceChanged = cd.old.DefaultRouteInterface != cd.new.DefaultRouteInterface + cd.IsLessExpensive = cd.old.IsExpensive && !cd.new.IsExpensive + cd.HasPACOrProxyConfigChanged = (cd.old.PAC != cd.new.PAC) || (cd.old.HTTPProxy != cd.new.HTTPProxy) + cd.InterfaceIPsChanged = cd.isInterestingInterfaceChange() + } + + cd.DefaultRouteInterface = new.DefaultRouteInterface + defIf := new.Interface[cd.DefaultRouteInterface] + + tsIfName, err := TailscaleInterfaceName() + + // The default interface is not viable if it is down or it is the Tailscale interface itself. + if !forceViability && (!defIf.IsUp() || (err == nil && cd.DefaultRouteInterface == tsIfName)) { + cd.DefaultInterfaceMaybeViable = false + } else { + cd.DefaultInterfaceMaybeViable = true + } + + // Compute rebind requirement. The default interface needs to be viable and + // one of the other conditions needs to be true. + cd.RebindLikelyRequired = (cd.old == nil || + cd.TimeJumped || + cd.DefaultInterfaceChanged || + cd.InterfaceIPsChanged || + cd.IsLessExpensive || + cd.HasPACOrProxyConfigChanged || + cd.AvailableProtocolsChanged) && + cd.DefaultInterfaceMaybeViable + + return &cd, nil +} + +// StateDesc returns a description of the old and new states for logging. +func (cd *ChangeDelta) StateDesc() string { + return fmt.Sprintf("old: %v new: %v", cd.old, cd.new) +} + +// InterfaceIPDisappeared reports whether the given IP address exists on any interface +// in the old state, but not in the new state. +func (cd *ChangeDelta) InterfaceIPDisappeared(ip netip.Addr) bool { + if cd.old == nil { + return false + } + if cd.new == nil && cd.old.HasIP(ip) { + return true + } + return cd.new.HasIP(ip) && !cd.old.HasIP(ip) +} + +// AnyInterfaceUp reports whether any interfaces are up in the new state. +func (cd *ChangeDelta) AnyInterfaceUp() bool { + if cd.new == nil { + return false + } + for _, ifi := range cd.new.Interface { + if ifi.IsUp() { + return true + } + } + return false +} + +// isInterestingInterfaceChange reports whether any interfaces have changed in a meaningful way. +// This excludes interfaces that are not interesting per IsInterestingInterface and +// filters out changes to interface IPs that that are uninteresting (e.g. link-local addresses). +func (cd *ChangeDelta) isInterestingInterfaceChange() bool { + // If there is no old state, everything is considered changed. + if cd.old == nil { + return true + } + + // Compare interfaces in both directions. Old to new and new to old. + tsIfName, ifNameErr := TailscaleInterfaceName() + + for iname, oldInterface := range cd.old.Interface { + if ifNameErr == nil && iname == tsIfName { + // Ignore changes in the Tailscale interface itself + continue + } + oldIps := filterRoutableIPs(cd.old.InterfaceIPs[iname]) + if IsInterestingInterface != nil && !IsInterestingInterface(oldInterface, oldIps) { + continue + } + + // Old interfaces with no routable addresses are not interesting + if len(oldIps) == 0 { + continue + } + + // The old interface doesn't exist in the new interface set and it has + // a global unicast IP. That's considered a change from the perspective + // of anything that may have been bound to it. If it didn't have a global + // unicast IP, it's not interesting. + newInterface, ok := cd.new.Interface[iname] + if !ok { + return true + } + newIps, ok := cd.new.InterfaceIPs[iname] + if !ok { + return true + } + newIps = filterRoutableIPs(newIps) + + if !oldInterface.Equal(newInterface) || !prefixesEqual(oldIps, newIps) { + return true + } + } + + for iname, newInterface := range cd.new.Interface { + if ifNameErr == nil && iname == tsIfName { + // Ignore changes in the Tailscale interface itself + continue + } + newIps := filterRoutableIPs(cd.new.InterfaceIPs[iname]) + if IsInterestingInterface != nil && !IsInterestingInterface(newInterface, newIps) { + continue + } + + // New interfaces with no routable addresses are not interesting + if len(newIps) == 0 { + continue + } + + oldInterface, ok := cd.old.Interface[iname] + if !ok { + return true + } + + oldIps, ok := cd.old.InterfaceIPs[iname] + if !ok { + // Redundant but we can't dig up the "old" IPs for this interface. + return true + } + oldIps = filterRoutableIPs(oldIps) + + // The interface's IPs, Name, MTU, etc have changed. This is definitely interesting. + if !newInterface.Equal(oldInterface) || !prefixesEqual(oldIps, newIps) { + return true + } + } + return false +} + +func filterRoutableIPs(addrs []netip.Prefix) []netip.Prefix { + var filtered []netip.Prefix + for _, pfx := range addrs { + a := pfx.Addr() + // Skip link-local multicast addresses. + if a.IsLinkLocalMulticast() { + continue + } + + if isUsableV4(a) || isUsableV6(a) { + filtered = append(filtered, pfx) + } + } + return filtered } // New instantiates and starts a monitoring instance. // The returned monitor is inactive until it's started by the Start method. // Use RegisterChangeCallback to get notified of network changes. -func New(logf logger.Logf) (*Monitor, error) { +func New(bus *eventbus.Bus, logf logger.Logf) (*Monitor, error) { logf = logger.WithPrefix(logf, "monitor: ") m := &Monitor{ logf: logf, + b: bus.Client("netmon"), change: make(chan bool, 1), stop: make(chan struct{}), lastWall: wallTime(), } + m.changed = eventbus.Publish[ChangeDelta](m.b) st, err := m.interfaceStateUncached() if err != nil { return nil, err } m.ifState = st - m.om, err = newOSMon(logf, m) + m.om, err = newOSMon(bus, logf, m) if err != nil { return nil, err } @@ -161,16 +358,7 @@ func (m *Monitor) InterfaceState() *State { } func (m *Monitor) interfaceStateUncached() (*State, error) { - return getState(m.tsIfName) -} - -// SetTailscaleInterfaceName sets the name of the Tailscale interface. For -// example, "tailscale0", "tun0", "utun3", etc. -// -// This must be called only early in tailscaled startup before the monitor is -// used. -func (m *Monitor) SetTailscaleInterfaceName(ifName string) { - m.tsIfName = ifName + return getState(tsIfProps.tsIfName()) } // GatewayAndSelfIP returns the current network's default gateway, and @@ -179,6 +367,9 @@ func (m *Monitor) SetTailscaleInterfaceName(ifName string) { // It's the same as interfaces.LikelyHomeRouterIP, but it caches the // result until the monitor detects a network change. func (m *Monitor) GatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) { + if !buildfeatures.HasPortMapper { + return + } if m.static { return } @@ -218,29 +409,6 @@ func (m *Monitor) RegisterChangeCallback(callback ChangeFunc) (unregister func() } } -// RuleDeleteCallback is a callback when a Linux IP policy routing -// rule is deleted. The table is the table number (52, 253, 354) and -// priority is the priority order number (for Tailscale rules -// currently: 5210, 5230, 5250, 5270) -type RuleDeleteCallback func(table uint8, priority uint32) - -// RegisterRuleDeleteCallback adds callback to the set of parties to be -// notified (in their own goroutine) when a Linux ip rule is deleted. -// To remove this callback, call unregister (or close the monitor). -func (m *Monitor) RegisterRuleDeleteCallback(callback RuleDeleteCallback) (unregister func()) { - if m.static { - return func() {} - } - m.mu.Lock() - defer m.mu.Unlock() - handle := m.ruleDelCB.Add(callback) - return func() { - m.mu.Lock() - defer m.mu.Unlock() - delete(m.ruleDelCB, handle) - } -} - // Start starts the monitor. // A monitor can only be started & closed once. func (m *Monitor) Start() { @@ -353,10 +521,6 @@ func (m *Monitor) pump() { time.Sleep(time.Second) continue } - if rdm, ok := msg.(ipRuleDeletedMessage); ok { - m.notifyRuleDeleted(rdm) - continue - } if msg.ignore() { continue } @@ -364,25 +528,6 @@ func (m *Monitor) pump() { } } -func (m *Monitor) notifyRuleDeleted(rdm ipRuleDeletedMessage) { - m.mu.Lock() - defer m.mu.Unlock() - for _, cb := range m.ruleDelCB { - go cb(rdm.table, rdm.priority) - } -} - -// isInterestingInterface reports whether the provided interface should be -// considered when checking for network state changes. -// The ips parameter should be the IPs of the provided interface. -func (m *Monitor) isInterestingInterface(i Interface, ips []netip.Prefix) bool { - if !m.om.IsInterestingInterface(i.Name) { - return false - } - - return true -} - // debounce calls the callback function with a delay between events // and exits when a stop is issued. func (m *Monitor) debounce() { @@ -404,7 +549,10 @@ func (m *Monitor) debounce() { select { case <-m.stop: return - case <-time.After(250 * time.Millisecond): + // 1s is reasonable debounce time for network changes. Events such as undocking a laptop + // or roaming onto wifi will often generate multiple events in quick succession as interfaces + // flap. We want to avoid spamming consumers of these events. + case <-time.After(1000 * time.Millisecond): } } } @@ -431,146 +579,51 @@ func (m *Monitor) handlePotentialChange(newState *State, forceCallbacks bool) { return } - delta := &ChangeDelta{ - Monitor: m, - Old: oldState, - New: newState, - TimeJumped: timeJumped, + delta, err := NewChangeDelta(oldState, newState, timeJumped, false) + if err != nil { + m.logf("[unexpected] error creating ChangeDelta: %v", err) + return } - delta.Major = m.IsMajorChangeFrom(oldState, newState) - if delta.Major { + if delta.RebindLikelyRequired { m.gwValid = false - m.ifState = newState - - if s1, s2 := oldState.String(), delta.New.String(); s1 == s2 { - m.logf("[unexpected] network state changed, but stringification didn't: %v", s1) - m.logf("[unexpected] old: %s", jsonSummary(oldState)) - m.logf("[unexpected] new: %s", jsonSummary(newState)) - } } + m.ifState = newState // See if we have a queued or new time jump signal. if timeJumped { m.resetTimeJumpedLocked() - if !delta.Major { - // Only log if it wasn't an interesting change. - m.logf("time jumped (probably wake from sleep); synthesizing major change event") - delta.Major = true - } } metricChange.Add(1) - if delta.Major { + if delta.RebindLikelyRequired { metricChangeMajor.Add(1) } if delta.TimeJumped { metricChangeTimeJump.Add(1) } + m.changed.Publish(*delta) for _, cb := range m.cbs { go cb(delta) } } -// IsMajorChangeFrom reports whether the transition from s1 to s2 is -// a "major" change, where major roughly means it's worth tearing down -// a bunch of connections and rebinding. -// -// TODO(bradiftz): tigten this definition. -func (m *Monitor) IsMajorChangeFrom(s1, s2 *State) bool { - if s1 == nil && s2 == nil { +// reports whether a and b contain the same set of prefixes regardless of order. +func prefixesEqual(a, b []netip.Prefix) bool { + if len(a) != len(b) { return false } - if s1 == nil || s2 == nil { - return true - } - if s1.HaveV6 != s2.HaveV6 || - s1.HaveV4 != s2.HaveV4 || - s1.IsExpensive != s2.IsExpensive || - s1.DefaultRouteInterface != s2.DefaultRouteInterface || - s1.HTTPProxy != s2.HTTPProxy || - s1.PAC != s2.PAC { - return true - } - for iname, i := range s1.Interface { - if iname == m.tsIfName { - // Ignore changes in the Tailscale interface itself. - continue - } - ips := s1.InterfaceIPs[iname] - if !m.isInterestingInterface(i, ips) { - continue - } - i2, ok := s2.Interface[iname] - if !ok { - return true - } - ips2, ok := s2.InterfaceIPs[iname] - if !ok { - return true - } - if !i.Equal(i2) || !prefixesMajorEqual(ips, ips2) { - return true - } - } - // Iterate over s2 in case there is a field in s2 that doesn't exist in s1 - for iname, i := range s2.Interface { - if iname == m.tsIfName { - // Ignore changes in the Tailscale interface itself. - continue - } - ips := s2.InterfaceIPs[iname] - if !m.isInterestingInterface(i, ips) { - continue - } - i1, ok := s1.Interface[iname] - if !ok { - return true - } - ips1, ok := s1.InterfaceIPs[iname] - if !ok { - return true - } - if !i.Equal(i1) || !prefixesMajorEqual(ips, ips1) { - return true - } - } - return false -} -// prefixesMajorEqual reports whether a and b are equal after ignoring -// boring things like link-local, loopback, and multicast addresses. -func prefixesMajorEqual(a, b []netip.Prefix) bool { - // trim returns a subslice of p with link local unicast, - // loopback, and multicast prefixes removed from the front. - trim := func(p []netip.Prefix) []netip.Prefix { - for len(p) > 0 { - a := p[0].Addr() - if a.IsLinkLocalUnicast() || a.IsLoopback() || a.IsMulticast() { - p = p[1:] - continue - } - break - } - return p - } - for { - a = trim(a) - b = trim(b) - if len(a) == 0 || len(b) == 0 { - return len(a) == 0 && len(b) == 0 - } - if a[0] != b[0] { - return false - } - a, b = a[1:], b[1:] - } -} + aa := make([]netip.Prefix, len(a)) + bb := make([]netip.Prefix, len(b)) + copy(aa, a) + copy(bb, b) -func jsonSummary(x any) any { - j, err := json.Marshal(x) - if err != nil { - return err + less := func(x, y netip.Prefix) int { + return x.Addr().Compare(y.Addr()) } - return j + + slices.SortFunc(aa, less) + slices.SortFunc(bb, less) + return slices.Equal(aa, bb) } func wallTime() time.Time { @@ -596,7 +649,7 @@ func (m *Monitor) pollWallTime() { // // We don't do this on mobile platforms for battery reasons, and because these // platforms don't really sleep in the same way. -const shouldMonitorTimeJump = runtime.GOOS != "android" && runtime.GOOS != "ios" +const shouldMonitorTimeJump = runtime.GOOS != "android" && runtime.GOOS != "ios" && runtime.GOOS != "plan9" // checkWallTimeAdvanceLocked reports whether wall time jumped more than 150% of // pollWallTimeInterval, indicating we probably just came out of sleep. Once a @@ -617,10 +670,3 @@ func (m *Monitor) checkWallTimeAdvanceLocked() bool { func (m *Monitor) resetTimeJumpedLocked() { m.timeJumped = false } - -type ipRuleDeletedMessage struct { - table uint8 - priority uint32 -} - -func (ipRuleDeletedMessage) ignore() bool { return true } diff --git a/vendor/tailscale.com/net/netmon/netmon_darwin.go b/vendor/tailscale.com/net/netmon/netmon_darwin.go index 8a52191..042f9a3 100644 --- a/vendor/tailscale.com/net/netmon/netmon_darwin.go +++ b/vendor/tailscale.com/net/netmon/netmon_darwin.go @@ -13,8 +13,15 @@ import ( "golang.org/x/sys/unix" "tailscale.com/net/netaddr" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) +func init() { + IsInterestingInterface = func(iface Interface, prefixes []netip.Prefix) bool { + return isInterestingInterface(iface.Name) + } +} + const debugRouteMessages = false // unspecifiedMessage is a minimal message implementation that should not @@ -24,7 +31,7 @@ type unspecifiedMessage struct{} func (unspecifiedMessage) ignore() bool { return false } -func newOSMon(logf logger.Logf, _ *Monitor) (osMon, error) { +func newOSMon(_ *eventbus.Bus, logf logger.Logf, _ *Monitor) (osMon, error) { fd, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0) if err != nil { return nil, err @@ -124,11 +131,10 @@ func addrType(addrs []route.Addr, rtaxType int) route.Addr { return nil } -func (m *darwinRouteMon) IsInterestingInterface(iface string) bool { +func isInterestingInterface(iface string) bool { baseName := strings.TrimRight(iface, "0123456789") switch baseName { - // TODO(maisem): figure out what this list should actually be. - case "llw", "awdl", "ipsec": + case "llw", "awdl", "ipsec", "gif", "XHC", "anpi", "lo", "utun": return false } return true @@ -136,7 +142,7 @@ func (m *darwinRouteMon) IsInterestingInterface(iface string) bool { func (m *darwinRouteMon) skipInterfaceAddrMessage(msg *route.InterfaceAddrMessage) bool { if la, ok := addrType(msg.Addrs, unix.RTAX_IFP).(*route.LinkAddr); ok { - if !m.IsInterestingInterface(la.Name) { + if !isInterestingInterface(la.Name) { return true } } @@ -149,6 +155,14 @@ func (m *darwinRouteMon) skipRouteMessage(msg *route.RouteMessage) bool { // dst = fe80::b476:66ff:fe30:c8f6%15 return true } + + // We can skip route messages from uninteresting interfaces. We do this upstream + // against the InterfaceMonitor, but skipping them here avoids unnecessary work. + if la, ok := addrType(msg.Addrs, unix.RTAX_IFP).(*route.LinkAddr); ok { + if !isInterestingInterface(la.Name) { + return true + } + } return false } diff --git a/vendor/tailscale.com/net/netmon/netmon_freebsd.go b/vendor/tailscale.com/net/netmon/netmon_freebsd.go index 30480a1..3a4fb44 100644 --- a/vendor/tailscale.com/net/netmon/netmon_freebsd.go +++ b/vendor/tailscale.com/net/netmon/netmon_freebsd.go @@ -10,6 +10,7 @@ import ( "strings" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) // unspecifiedMessage is a minimal message implementation that should not @@ -24,7 +25,7 @@ type devdConn struct { conn net.Conn } -func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { +func newOSMon(_ *eventbus.Bus, logf logger.Logf, m *Monitor) (osMon, error) { conn, err := net.Dial("unixpacket", "/var/run/devd.seqpacket.pipe") if err != nil { logf("devd dial error: %v, falling back to polling method", err) @@ -33,8 +34,6 @@ func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { return &devdConn{conn}, nil } -func (c *devdConn) IsInterestingInterface(iface string) bool { return true } - func (c *devdConn) Close() error { return c.conn.Close() } diff --git a/vendor/tailscale.com/net/netmon/netmon_linux.go b/vendor/tailscale.com/net/netmon/netmon_linux.go index dd23dd3..aa5253f 100644 --- a/vendor/tailscale.com/net/netmon/netmon_linux.go +++ b/vendor/tailscale.com/net/netmon/netmon_linux.go @@ -16,6 +16,7 @@ import ( "tailscale.com/envknob" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) var debugNetlinkMessages = envknob.RegisterBool("TS_DEBUG_NETLINK") @@ -27,15 +28,26 @@ type unspecifiedMessage struct{} func (unspecifiedMessage) ignore() bool { return false } +// RuleDeleted reports that one of Tailscale's policy routing rules +// was deleted. +type RuleDeleted struct { + // Table is the table number that the deleted rule referenced. + Table uint8 + // Priority is the lookup priority of the deleted rule. + Priority uint32 +} + // nlConn wraps a *netlink.Conn and returns a monitor.Message // instead of a netlink.Message. Currently, messages are discarded, // but down the line, when messages trigger different logic depending // on the type of event, this provides the capability of handling // each architecture-specific message in a generic fashion. type nlConn struct { - logf logger.Logf - conn *netlink.Conn - buffered []netlink.Message + busClient *eventbus.Client + rulesDeleted *eventbus.Publisher[RuleDeleted] + logf logger.Logf + conn *netlink.Conn + buffered []netlink.Message // addrCache maps interface indices to a set of addresses, and is // used to suppress duplicate RTM_NEWADDR messages. It is populated @@ -44,7 +56,7 @@ type nlConn struct { addrCache map[uint32]map[netip.Addr]bool } -func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { +func newOSMon(bus *eventbus.Bus, logf logger.Logf, m *Monitor) (osMon, error) { conn, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{ // Routes get us most of the events of interest, but we need // address as well to cover things like DHCP deciding to give @@ -59,12 +71,20 @@ func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { logf("monitor_linux: AF_NETLINK RTMGRP failed, falling back to polling") return newPollingMon(logf, m) } - return &nlConn{logf: logf, conn: conn, addrCache: make(map[uint32]map[netip.Addr]bool)}, nil + client := bus.Client("netmon-iprules") + return &nlConn{ + busClient: client, + rulesDeleted: eventbus.Publish[RuleDeleted](client), + logf: logf, + conn: conn, + addrCache: make(map[uint32]map[netip.Addr]bool), + }, nil } -func (c *nlConn) IsInterestingInterface(iface string) bool { return true } - -func (c *nlConn) Close() error { return c.conn.Close() } +func (c *nlConn) Close() error { + c.busClient.Close() + return c.conn.Close() +} func (c *nlConn) Receive() (message, error) { if len(c.buffered) == 0 { @@ -219,14 +239,15 @@ func (c *nlConn) Receive() (message, error) { // On `ip -4 rule del pref 5210 table main`, logs: // monitor: ip rule deleted: {Family:2 DstLength:0 SrcLength:0 Tos:0 Table:254 Protocol:0 Scope:0 Type:1 Flags:0 Attributes:{Dst: Src: Gateway: OutIface:0 Priority:5210 Table:254 Mark:4294967295 Expires: Metrics: Multipath:[]}} } - rdm := ipRuleDeletedMessage{ - table: rmsg.Table, - priority: rmsg.Attributes.Priority, + rd := RuleDeleted{ + Table: rmsg.Table, + Priority: rmsg.Attributes.Priority, } + c.rulesDeleted.Publish(rd) if debugNetlinkMessages() { - c.logf("%+v", rdm) + c.logf("%+v", rd) } - return rdm, nil + return ignoreMessage{}, nil case unix.RTM_NEWLINK, unix.RTM_DELLINK: // This is an unhandled message, but don't print an error. // See https://github.com/tailscale/tailscale/issues/6806 diff --git a/vendor/tailscale.com/net/netmon/netmon_polling.go b/vendor/tailscale.com/net/netmon/netmon_polling.go index 3d6f947..3b5ef6f 100644 --- a/vendor/tailscale.com/net/netmon/netmon_polling.go +++ b/vendor/tailscale.com/net/netmon/netmon_polling.go @@ -7,9 +7,10 @@ package netmon import ( "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) -func newOSMon(logf logger.Logf, m *Monitor) (osMon, error) { +func newOSMon(_ *eventbus.Bus, logf logger.Logf, m *Monitor) (osMon, error) { return newPollingMon(logf, m) } diff --git a/vendor/tailscale.com/net/netmon/netmon_windows.go b/vendor/tailscale.com/net/netmon/netmon_windows.go index ddf13a2..e8966fa 100644 --- a/vendor/tailscale.com/net/netmon/netmon_windows.go +++ b/vendor/tailscale.com/net/netmon/netmon_windows.go @@ -13,6 +13,7 @@ import ( "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" + "tailscale.com/util/eventbus" ) var ( @@ -45,7 +46,7 @@ type winMon struct { noDeadlockTicker *time.Ticker } -func newOSMon(logf logger.Logf, pm *Monitor) (osMon, error) { +func newOSMon(_ *eventbus.Bus, logf logger.Logf, pm *Monitor) (osMon, error) { m := &winMon{ logf: logf, isActive: pm.isActive, @@ -73,8 +74,6 @@ func newOSMon(logf logger.Logf, pm *Monitor) (osMon, error) { return m, nil } -func (m *winMon) IsInterestingInterface(iface string) bool { return true } - func (m *winMon) Close() (ret error) { m.cancel() m.noDeadlockTicker.Stop() diff --git a/vendor/tailscale.com/net/netmon/polling.go b/vendor/tailscale.com/net/netmon/polling.go index ce1618e..2a3e44c 100644 --- a/vendor/tailscale.com/net/netmon/polling.go +++ b/vendor/tailscale.com/net/netmon/polling.go @@ -35,10 +35,6 @@ type pollingMon struct { stop chan struct{} } -func (pm *pollingMon) IsInterestingInterface(iface string) bool { - return true -} - func (pm *pollingMon) Close() error { pm.closeOnce.Do(func() { close(pm.stop) diff --git a/vendor/tailscale.com/net/netmon/state.go b/vendor/tailscale.com/net/netmon/state.go index bd09607..79dd8a0 100644 --- a/vendor/tailscale.com/net/netmon/state.go +++ b/vendor/tailscale.com/net/netmon/state.go @@ -15,10 +15,11 @@ import ( "strings" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/hostinfo" "tailscale.com/net/netaddr" "tailscale.com/net/tsaddr" - "tailscale.com/net/tshttpproxy" "tailscale.com/util/mak" ) @@ -148,12 +149,28 @@ type Interface struct { Desc string // extra description (used on Windows) } -func (i Interface) IsLoopback() bool { return isLoopback(i.Interface) } -func (i Interface) IsUp() bool { return isUp(i.Interface) } +func (i Interface) IsLoopback() bool { + if i.Interface == nil { + return false + } + return isLoopback(i.Interface) +} + +func (i Interface) IsUp() bool { + if i.Interface == nil { + return false + } + return isUp(i.Interface) +} + func (i Interface) Addrs() ([]net.Addr, error) { if i.AltAddrs != nil { return i.AltAddrs, nil } + if i.Interface == nil { + return nil, nil + } + return i.Interface.Addrs() } @@ -182,6 +199,10 @@ func (ifaces InterfaceList) ForeachInterfaceAddress(fn func(Interface, netip.Pre if pfx, ok := netaddr.FromStdIPNet(v); ok { fn(iface, pfx) } + case *net.IPAddr: + if ip, ok := netip.AddrFromSlice(v.IP); ok { + fn(iface, netip.PrefixFrom(ip, ip.BitLen())) + } } } } @@ -214,6 +235,10 @@ func (ifaces InterfaceList) ForeachInterface(fn func(Interface, []netip.Prefix)) if pfx, ok := netaddr.FromStdIPNet(v); ok { pfxs = append(pfxs, pfx) } + case *net.IPAddr: + if ip, ok := netip.AddrFromSlice(v.IP); ok { + pfxs = append(pfxs, netip.PrefixFrom(ip, ip.BitLen())) + } } } sort.Slice(pfxs, func(i, j int) bool { @@ -445,15 +470,22 @@ func hasTailscaleIP(pfxs []netip.Prefix) bool { } func isTailscaleInterface(name string, ips []netip.Prefix) bool { + // Sandboxed macOS and Plan9 (and anything else that explicitly calls SetTailscaleInterfaceProps). + tsIfName, err := TailscaleInterfaceName() + if err == nil { + // If we've been told the Tailscale interface name, use that. + return name == tsIfName + } + + // The sandboxed app should (as of 1.92) set the tun interface name via SetTailscaleInterfaceProps + // early in the startup process. The non-sandboxed app does not. + // TODO (barnstar): If Wireguard created the tun device on darwin, it should know the name and it should + // be explicitly set instead checking addresses here. if runtime.GOOS == "darwin" && strings.HasPrefix(name, "utun") && hasTailscaleIP(ips) { - // On macOS in the sandboxed app (at least as of - // 2021-02-25), we often see two utun devices - // (e.g. utun4 and utun7) with the same IPv4 and IPv6 - // addresses. Just remove all utun devices with - // Tailscale IPs until we know what's happening with - // macOS NetworkExtensions and utun devices. return true } + + // Windows, Linux... return name == "Tailscale" || // as it is on Windows strings.HasPrefix(name, "tailscale") // TODO: use --tun flag value, etc; see TODO in method doc } @@ -476,9 +508,16 @@ func getState(optTSInterfaceName string) (*State, error) { ifUp := ni.IsUp() s.Interface[ni.Name] = ni s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...) + + // Skip uninteresting interfaces + if IsInterestingInterface != nil && !IsInterestingInterface(ni, pfxs) { + return + } + if !ifUp || isTSInterfaceName || isTailscaleInterface(ni.Name, pfxs) { return } + for _, pfx := range pfxs { if pfx.Addr().IsLoopback() { continue @@ -501,13 +540,15 @@ func getState(optTSInterfaceName string) (*State, error) { } } - if s.AnyInterfaceUp() { + if buildfeatures.HasUseProxy && s.AnyInterfaceUp() { req, err := http.NewRequest("GET", LoginEndpointForProxyDetermination, nil) if err != nil { return nil, err } - if u, err := tshttpproxy.ProxyFromEnvironment(req); err == nil && u != nil { - s.HTTPProxy = u.String() + if proxyFromEnv, ok := feature.HookProxyFromEnvironment.GetOk(); ok { + if u, err := proxyFromEnv(req); err == nil && u != nil { + s.HTTPProxy = u.String() + } } if getPAC != nil { s.PAC = getPAC() @@ -570,6 +611,9 @@ var disableLikelyHomeRouterIPSelf = envknob.RegisterBool("TS_DEBUG_DISABLE_LIKEL // the LAN using that gateway. // This is used as the destination for UPnP, NAT-PMP, PCP, etc queries. func LikelyHomeRouterIP() (gateway, myIP netip.Addr, ok bool) { + if !buildfeatures.HasPortMapper { + return + } // If we don't have a way to get the home router IP, then we can't do // anything; just return. if likelyHomeRouterIP == nil { @@ -760,8 +804,7 @@ func (m *Monitor) HasCGNATInterface() (bool, error) { hasCGNATInterface := false cgnatRange := tsaddr.CGNATRange() err := ForeachInterface(func(i Interface, pfxs []netip.Prefix) { - isTSInterfaceName := m.tsIfName != "" && i.Name == m.tsIfName - if hasCGNATInterface || !i.IsUp() || isTSInterfaceName || isTailscaleInterface(i.Name, pfxs) { + if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) { return } for _, pfx := range pfxs { diff --git a/vendor/tailscale.com/net/netns/netns.go b/vendor/tailscale.com/net/netns/netns.go index a473506..81ab5e2 100644 --- a/vendor/tailscale.com/net/netns/netns.go +++ b/vendor/tailscale.com/net/netns/netns.go @@ -17,6 +17,7 @@ import ( "context" "net" "net/netip" + "runtime" "sync/atomic" "tailscale.com/net/netknob" @@ -39,18 +40,36 @@ var bindToInterfaceByRoute atomic.Bool // setting the TS_BIND_TO_INTERFACE_BY_ROUTE. // // Currently, this only changes the behaviour on macOS and Windows. -func SetBindToInterfaceByRoute(v bool) { - bindToInterfaceByRoute.Store(v) +func SetBindToInterfaceByRoute(logf logger.Logf, v bool) { + if bindToInterfaceByRoute.Swap(v) != v { + logf("netns: bindToInterfaceByRoute changed to %v", v) + } } var disableBindConnToInterface atomic.Bool // SetDisableBindConnToInterface disables the (normal) behavior of binding -// connections to the default network interface. +// connections to the default network interface on Darwin nodes. // -// Currently, this only has an effect on Darwin. -func SetDisableBindConnToInterface(v bool) { - disableBindConnToInterface.Store(v) +// Unless you intended to disable this for tailscaled on macos (which is likely +// to break things), you probably wanted to set +// SetDisableBindConnToInterfaceAppleExt which will disable explicit interface +// binding only when tailscaled is running inside a network extension process. +func SetDisableBindConnToInterface(logf logger.Logf, v bool) { + if disableBindConnToInterface.Swap(v) != v { + logf("netns: disableBindConnToInterface changed to %v", v) + } +} + +var disableBindConnToInterfaceAppleExt atomic.Bool + +// SetDisableBindConnToInterfaceAppleExt disables the (normal) behavior of binding +// connections to the default network interface but only on Apple clients where +// tailscaled is running inside a network extension. +func SetDisableBindConnToInterfaceAppleExt(logf logger.Logf, v bool) { + if runtime.GOOS == "darwin" && disableBindConnToInterfaceAppleExt.Swap(v) != v { + logf("netns: disableBindConnToInterfaceAppleExt changed to %v", v) + } } // Listener returns a new net.Listener with its Control hook func diff --git a/vendor/tailscale.com/net/netns/netns_darwin.go b/vendor/tailscale.com/net/netns/netns_darwin.go index ac5e89d..ff05a3f 100644 --- a/vendor/tailscale.com/net/netns/netns_darwin.go +++ b/vendor/tailscale.com/net/netns/netns_darwin.go @@ -21,6 +21,7 @@ import ( "tailscale.com/net/netmon" "tailscale.com/net/tsaddr" "tailscale.com/types/logger" + "tailscale.com/version" ) func control(logf logger.Logf, netMon *netmon.Monitor) func(network, address string, c syscall.RawConn) error { @@ -33,18 +34,14 @@ var bindToInterfaceByRouteEnv = envknob.RegisterBool("TS_BIND_TO_INTERFACE_BY_RO var errInterfaceStateInvalid = errors.New("interface state invalid") -// controlLogf marks c as necessary to dial in a separate network namespace. -// -// It's intentionally the same signature as net.Dialer.Control -// and net.ListenConfig.Control. +// controlLogf binds c to a particular interface as necessary to dial the +// provided (network, address). func controlLogf(logf logger.Logf, netMon *netmon.Monitor, network, address string, c syscall.RawConn) error { - if isLocalhost(address) { - // Don't bind to an interface for localhost connections. + if disableBindConnToInterface.Load() || (version.IsMacGUIVariant() && disableBindConnToInterfaceAppleExt.Load()) { return nil } - if disableBindConnToInterface.Load() { - logf("netns_darwin: binding connection to interfaces disabled") + if isLocalhost(address) { return nil } @@ -78,10 +75,38 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string) return -1, errInterfaceStateInvalid } - if iface, ok := state.Interface[state.DefaultRouteInterface]; ok { - return iface.Index, nil + // Netmon's cached view of the default inteface + cachedIdx, ok := state.Interface[state.DefaultRouteInterface] + // OSes view (if available) of the default interface + osIf, osIferr := netmon.OSDefaultRoute() + + idx := -1 + errOut := errInterfaceStateInvalid + // Preferentially choose the OS's view of the default if index. Due to the way darwin sets the delegated + // interface on tunnel creation only, it is possible for netmon to have a stale view of the default and + // netmon's view is often temporarily wrong during network transitions, or for us to not have the + // the the oses view of the defaultIf yet. + if osIferr == nil { + idx = osIf.InterfaceIndex + errOut = nil + } else if ok { + idx = cachedIdx.Index + errOut = nil } - return -1, errInterfaceStateInvalid + + if osIferr == nil && ok && (osIf.InterfaceIndex != cachedIdx.Index) { + logf("netns: [unexpected] os default if %q (%d) != netmon cached if %q (%d)", osIf.InterfaceName, osIf.InterfaceIndex, cachedIdx.Name, cachedIdx.Index) + } + + // Sanity check to make sure we didn't pick the tailscale interface + if tsif, err2 := tailscaleInterface(); tsif != nil && err2 == nil && errOut == nil { + if tsif.Index == idx { + idx = -1 + errOut = errInterfaceStateInvalid + } + } + + return idx, errOut } useRoute := bindToInterfaceByRoute.Load() || bindToInterfaceByRouteEnv() @@ -100,7 +125,7 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string) idx, err := interfaceIndexFor(addr, true /* canRecurse */) if err != nil { - logf("netns: error in interfaceIndexFor: %v", err) + logf("netns: error getting interface index for %q: %v", address, err) return defaultIdx() } @@ -108,10 +133,13 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string) // if so, we fall back to binding from the default. tsif, err2 := tailscaleInterface() if err2 == nil && tsif != nil && tsif.Index == idx { - logf("[unexpected] netns: interfaceIndexFor returned Tailscale interface") + // note: with an exit node enabled, this is almost always true. defaultIdx() is the + // right thing to do here. return defaultIdx() } + logf("netns: completed success interfaceIndexFor(%s) = %d", address, idx) + return idx, err } diff --git a/vendor/tailscale.com/net/netns/netns_default.go b/vendor/tailscale.com/net/netns/netns_default.go index 94f24d8..58c5936 100644 --- a/vendor/tailscale.com/net/netns/netns_default.go +++ b/vendor/tailscale.com/net/netns/netns_default.go @@ -20,3 +20,7 @@ func control(logger.Logf, *netmon.Monitor) func(network, address string, c sysca func controlC(network, address string, c syscall.RawConn) error { return nil } + +func UseSocketMark() bool { + return false +} diff --git a/vendor/tailscale.com/net/netns/netns_dw.go b/vendor/tailscale.com/net/netns/netns_dw.go index f92ba94..b9f750e 100644 --- a/vendor/tailscale.com/net/netns/netns_dw.go +++ b/vendor/tailscale.com/net/netns/netns_dw.go @@ -25,3 +25,7 @@ func parseAddress(address string) (addr netip.Addr, err error) { return netip.ParseAddr(host) } + +func UseSocketMark() bool { + return false +} diff --git a/vendor/tailscale.com/net/netns/netns_linux.go b/vendor/tailscale.com/net/netns/netns_linux.go index aaf6dab..609f524 100644 --- a/vendor/tailscale.com/net/netns/netns_linux.go +++ b/vendor/tailscale.com/net/netns/netns_linux.go @@ -15,8 +15,8 @@ import ( "golang.org/x/sys/unix" "tailscale.com/envknob" "tailscale.com/net/netmon" + "tailscale.com/tsconst" "tailscale.com/types/logger" - "tailscale.com/util/linuxfw" ) // socketMarkWorksOnce is the sync.Once & cached value for useSocketMark. @@ -111,7 +111,7 @@ func controlC(network, address string, c syscall.RawConn) error { } func setBypassMark(fd uintptr) error { - if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, linuxfw.TailscaleBypassMarkNum); err != nil { + if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, tsconst.LinuxBypassMarkNum); err != nil { return fmt.Errorf("setting SO_MARK bypass: %w", err) } return nil diff --git a/vendor/tailscale.com/net/netns/socks.go b/vendor/tailscale.com/net/netns/socks.go index eea69d8..9a137db 100644 --- a/vendor/tailscale.com/net/netns/socks.go +++ b/vendor/tailscale.com/net/netns/socks.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios && !js +//go:build !ios && !js && !android && !ts_omit_useproxy package netns diff --git a/vendor/tailscale.com/net/netns/zsyscall_windows.go b/vendor/tailscale.com/net/netns/zsyscall_windows.go index 07e2181..3d8f06e 100644 --- a/vendor/tailscale.com/net/netns/zsyscall_windows.go +++ b/vendor/tailscale.com/net/netns/zsyscall_windows.go @@ -45,7 +45,7 @@ var ( ) func getBestInterfaceEx(sockaddr *winipcfg.RawSockaddrInet, bestIfaceIndex *uint32) (ret error) { - r0, _, _ := syscall.Syscall(procGetBestInterfaceEx.Addr(), 2, uintptr(unsafe.Pointer(sockaddr)), uintptr(unsafe.Pointer(bestIfaceIndex)), 0) + r0, _, _ := syscall.SyscallN(procGetBestInterfaceEx.Addr(), uintptr(unsafe.Pointer(sockaddr)), uintptr(unsafe.Pointer(bestIfaceIndex))) if r0 != 0 { ret = syscall.Errno(r0) } diff --git a/vendor/tailscale.com/net/netstat/netstat.go b/vendor/tailscale.com/net/netstat/netstat.go deleted file mode 100644 index 53c7d77..0000000 --- a/vendor/tailscale.com/net/netstat/netstat.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package netstat returns the local machine's network connection table. -package netstat - -import ( - "errors" - "net/netip" - "runtime" -) - -var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS) - -type Entry struct { - Local, Remote netip.AddrPort - Pid int - State string // TODO: type? - OSMetadata OSMetadata -} - -// Table contains local machine's TCP connection entries. -// -// Currently only TCP (IPv4 and IPv6) are included. -type Table struct { - Entries []Entry -} - -// Get returns the connection table. -// -// It returns ErrNotImplemented if the table is not available for the -// current operating system. -func Get() (*Table, error) { - return get() -} diff --git a/vendor/tailscale.com/net/netstat/netstat_noimpl.go b/vendor/tailscale.com/net/netstat/netstat_noimpl.go deleted file mode 100644 index e455c8c..0000000 --- a/vendor/tailscale.com/net/netstat/netstat_noimpl.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !windows - -package netstat - -// OSMetadata includes any additional OS-specific information that may be -// obtained during the retrieval of a given Entry. -type OSMetadata struct{} - -func get() (*Table, error) { - return nil, ErrNotImplemented -} diff --git a/vendor/tailscale.com/net/netstat/netstat_windows.go b/vendor/tailscale.com/net/netstat/netstat_windows.go deleted file mode 100644 index 24191a5..0000000 --- a/vendor/tailscale.com/net/netstat/netstat_windows.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package netstat - -import ( - "errors" - "fmt" - "math/bits" - "net/netip" - "unsafe" - - "golang.org/x/sys/cpu" - "golang.org/x/sys/windows" - "tailscale.com/net/netaddr" -) - -// OSMetadata includes any additional OS-specific information that may be -// obtained during the retrieval of a given Entry. -type OSMetadata interface { - // GetModule returns the entry's module name. - // - // It returns ("", nil) if no entry is found. As of 2023-01-27, any returned - // error is silently discarded by its sole caller in portlist_windows.go and - // treated equivalently as returning ("", nil), but this may change in the - // future. An error should only be returned in casees that are worthy of - // being logged at least. - GetModule() (string, error) -} - -// See https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getextendedtcptable - -// TCP_TABLE_OWNER_MODULE_ALL means to include the PID and module. The table type -// we get back from Windows depends on AF_INET vs AF_INET6: -// MIB_TCPTABLE_OWNER_MODULE for v4 or MIB_TCP6TABLE_OWNER_MODULE for v6. -const tcpTableOwnerModuleAll = 8 - -// TCPIP_OWNER_MODULE_BASIC_INFO means to request "basic information" about the -// owner module. -const tcpipOwnerModuleBasicInfo = 0 - -var ( - iphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") - getTCPTable = iphlpapi.NewProc("GetExtendedTcpTable") - getOwnerModuleFromTcpEntry = iphlpapi.NewProc("GetOwnerModuleFromTcpEntry") - getOwnerModuleFromTcp6Entry = iphlpapi.NewProc("GetOwnerModuleFromTcp6Entry") - // TODO: GetExtendedUdpTable also? if/when needed. -) - -// See https://web.archive.org/web/20221219211913/https://learn.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcprow_owner_module -type _MIB_TCPROW_OWNER_MODULE struct { - state uint32 - localAddr uint32 - localPort uint32 - remoteAddr uint32 - remotePort uint32 - pid uint32 - createTimestamp int64 - owningModuleInfo [16]uint64 -} - -func (row *_MIB_TCPROW_OWNER_MODULE) asEntry() Entry { - return Entry{ - Local: ipport4(row.localAddr, port(&row.localPort)), - Remote: ipport4(row.remoteAddr, port(&row.remotePort)), - Pid: int(row.pid), - State: state(row.state), - OSMetadata: row, - } -} - -type _MIB_TCPTABLE_OWNER_MODULE struct { - numEntries uint32 - table _MIB_TCPROW_OWNER_MODULE -} - -func (m *_MIB_TCPTABLE_OWNER_MODULE) getRows() []_MIB_TCPROW_OWNER_MODULE { - return unsafe.Slice(&m.table, m.numEntries) -} - -// See https://web.archive.org/web/20221219212442/https://learn.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcp6row_owner_module -type _MIB_TCP6ROW_OWNER_MODULE struct { - localAddr [16]byte - localScope uint32 - localPort uint32 - remoteAddr [16]byte - remoteScope uint32 - remotePort uint32 - state uint32 - pid uint32 - createTimestamp int64 - owningModuleInfo [16]uint64 -} - -func (row *_MIB_TCP6ROW_OWNER_MODULE) asEntry() Entry { - return Entry{ - Local: ipport6(row.localAddr, row.localScope, port(&row.localPort)), - Remote: ipport6(row.remoteAddr, row.remoteScope, port(&row.remotePort)), - Pid: int(row.pid), - State: state(row.state), - OSMetadata: row, - } -} - -type _MIB_TCP6TABLE_OWNER_MODULE struct { - numEntries uint32 - table _MIB_TCP6ROW_OWNER_MODULE -} - -func (m *_MIB_TCP6TABLE_OWNER_MODULE) getRows() []_MIB_TCP6ROW_OWNER_MODULE { - return unsafe.Slice(&m.table, m.numEntries) -} - -// See https://web.archive.org/web/20221219213143/https://learn.microsoft.com/en-us/windows/win32/api/iprtrmib/ns-iprtrmib-tcpip_owner_module_basic_info -type _TCPIP_OWNER_MODULE_BASIC_INFO struct { - moduleName *uint16 - modulePath *uint16 -} - -func get() (*Table, error) { - t := new(Table) - if err := t.addEntries(windows.AF_INET); err != nil { - return nil, fmt.Errorf("failed to get IPv4 entries: %w", err) - } - if err := t.addEntries(windows.AF_INET6); err != nil { - return nil, fmt.Errorf("failed to get IPv6 entries: %w", err) - } - return t, nil -} - -func (t *Table) addEntries(fam int) error { - var size uint32 - var addr unsafe.Pointer - var buf []byte - for { - err, _, _ := getTCPTable.Call( - uintptr(addr), - uintptr(unsafe.Pointer(&size)), - 1, // sorted - uintptr(fam), - tcpTableOwnerModuleAll, - 0, // reserved; "must be zero" - ) - if err == 0 { - break - } - if err == uintptr(windows.ERROR_INSUFFICIENT_BUFFER) { - const maxSize = 10 << 20 - if size > maxSize || size < 4 { - return fmt.Errorf("unreasonable kernel-reported size %d", size) - } - buf = make([]byte, size) - addr = unsafe.Pointer(&buf[0]) - continue - } - return windows.Errno(err) - } - if len(buf) < int(size) { - return errors.New("unexpected size growth from system call") - } - buf = buf[:size] - - switch fam { - case windows.AF_INET: - info := (*_MIB_TCPTABLE_OWNER_MODULE)(unsafe.Pointer(&buf[0])) - rows := info.getRows() - for _, row := range rows { - t.Entries = append(t.Entries, row.asEntry()) - } - case windows.AF_INET6: - info := (*_MIB_TCP6TABLE_OWNER_MODULE)(unsafe.Pointer(&buf[0])) - rows := info.getRows() - for _, row := range rows { - t.Entries = append(t.Entries, row.asEntry()) - } - } - - return nil -} - -var states = []string{ - "", - "CLOSED", - "LISTEN", - "SYN-SENT", - "SYN-RECEIVED", - "ESTABLISHED", - "FIN-WAIT-1", - "FIN-WAIT-2", - "CLOSE-WAIT", - "CLOSING", - "LAST-ACK", - "DELETE-TCB", -} - -func state(v uint32) string { - if v < uint32(len(states)) { - return states[v] - } - return fmt.Sprintf("unknown-state-%d", v) -} - -func ipport4(addr uint32, port uint16) netip.AddrPort { - if !cpu.IsBigEndian { - addr = bits.ReverseBytes32(addr) - } - return netip.AddrPortFrom( - netaddr.IPv4(byte(addr>>24), byte(addr>>16), byte(addr>>8), byte(addr)), - port) -} - -func ipport6(addr [16]byte, scope uint32, port uint16) netip.AddrPort { - ip := netip.AddrFrom16(addr).Unmap() - if scope != 0 { - // TODO: something better here? - ip = ip.WithZone(fmt.Sprint(scope)) - } - return netip.AddrPortFrom(ip, port) -} - -func port(v *uint32) uint16 { - if !cpu.IsBigEndian { - return uint16(bits.ReverseBytes32(*v) >> 16) - } - return uint16(*v >> 16) -} - -type moduleInfoConstraint interface { - _MIB_TCPROW_OWNER_MODULE | _MIB_TCP6ROW_OWNER_MODULE -} - -// moduleInfo implements OSMetadata.GetModule. It calls -// getOwnerModuleFromTcpEntry or getOwnerModuleFromTcp6Entry. -// -// See -// https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getownermodulefromtcpentry -// -// It may return "", nil indicating a successful call but with empty data. -func moduleInfo[entryType moduleInfoConstraint](entry *entryType, proc *windows.LazyProc) (string, error) { - var buf []byte - var desiredLen uint32 - var addr unsafe.Pointer - - for { - e, _, _ := proc.Call( - uintptr(unsafe.Pointer(entry)), - uintptr(tcpipOwnerModuleBasicInfo), - uintptr(addr), - uintptr(unsafe.Pointer(&desiredLen)), - ) - err := windows.Errno(e) - if err == windows.ERROR_SUCCESS { - break - } - if err == windows.ERROR_NOT_FOUND { - return "", nil - } - if err != windows.ERROR_INSUFFICIENT_BUFFER { - return "", err - } - if desiredLen > 1<<20 { - // Sanity check before allocating too much. - return "", nil - } - buf = make([]byte, desiredLen) - addr = unsafe.Pointer(&buf[0]) - } - if addr == nil { - // GetOwnerModuleFromTcp*Entry can apparently return ERROR_SUCCESS - // (NO_ERROR) on the first call without the usual first - // ERROR_INSUFFICIENT_BUFFER result. Windows said success, so interpret - // that was sucessfully not having data. - return "", nil - } - basicInfo := (*_TCPIP_OWNER_MODULE_BASIC_INFO)(addr) - return windows.UTF16PtrToString(basicInfo.moduleName), nil -} - -// GetModule implements OSMetadata. -func (m *_MIB_TCPROW_OWNER_MODULE) GetModule() (string, error) { - return moduleInfo(m, getOwnerModuleFromTcpEntry) -} - -// GetModule implements OSMetadata. -func (m *_MIB_TCP6ROW_OWNER_MODULE) GetModule() (string, error) { - return moduleInfo(m, getOwnerModuleFromTcp6Entry) -} diff --git a/vendor/tailscale.com/net/netutil/netutil.go b/vendor/tailscale.com/net/netutil/netutil.go index bc64e8f..5c42f51 100644 --- a/vendor/tailscale.com/net/netutil/netutil.go +++ b/vendor/tailscale.com/net/netutil/netutil.go @@ -8,7 +8,8 @@ import ( "bufio" "io" "net" - "sync" + + "tailscale.com/syncs" ) // NewOneConnListener returns a net.Listener that returns c on its @@ -29,7 +30,7 @@ func NewOneConnListener(c net.Conn, addr net.Addr) net.Listener { type oneConnListener struct { addr net.Addr - mu sync.Mutex + mu syncs.Mutex conn net.Conn } diff --git a/vendor/tailscale.com/net/netx/netx.go b/vendor/tailscale.com/net/netx/netx.go new file mode 100644 index 0000000..014daa9 --- /dev/null +++ b/vendor/tailscale.com/net/netx/netx.go @@ -0,0 +1,53 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package netx contains types to describe and abstract over how dialing and +// listening are performed. +package netx + +import ( + "context" + "fmt" + "net" +) + +// DialFunc is a function that dials a network address. +// +// It's the type implemented by net.Dialer.DialContext or required +// by net/http.Transport.DialContext, etc. +type DialFunc func(ctx context.Context, network, address string) (net.Conn, error) + +// Network describes a network that can listen and dial. The two common +// implementations are [RealNetwork], using the net package to use the real +// network, or [memnet.Network], using an in-memory network (typically for testing) +type Network interface { + NewLocalTCPListener() net.Listener + Listen(network, address string) (net.Listener, error) + Dial(ctx context.Context, network, address string) (net.Conn, error) +} + +// RealNetwork returns a Network implementation that uses the real +// net package. +func RealNetwork() Network { return realNetwork{} } + +// realNetwork implements [Network] using the real net package. +type realNetwork struct{} + +func (realNetwork) Listen(network, address string) (net.Listener, error) { + return net.Listen(network, address) +} + +func (realNetwork) Dial(ctx context.Context, network, address string) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, network, address) +} + +func (realNetwork) NewLocalTCPListener() net.Listener { + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + if ln, err = net.Listen("tcp6", "[::1]:0"); err != nil { + panic(fmt.Sprintf("failed to listen on either IPv4 or IPv6 localhost port: %v", err)) + } + } + return ln +} diff --git a/vendor/tailscale.com/net/packet/checksum/checksum.go b/vendor/tailscale.com/net/packet/checksum/checksum.go index 547ea3a..4b5b821 100644 --- a/vendor/tailscale.com/net/packet/checksum/checksum.go +++ b/vendor/tailscale.com/net/packet/checksum/checksum.go @@ -8,8 +8,6 @@ import ( "encoding/binary" "net/netip" - "gvisor.dev/gvisor/pkg/tcpip" - "gvisor.dev/gvisor/pkg/tcpip/header" "tailscale.com/net/packet" "tailscale.com/types/ipproto" ) @@ -88,13 +86,13 @@ func updateV4PacketChecksums(p *packet.Parsed, old, new netip.Addr) { tr := p.Transport() switch p.IPProto { case ipproto.UDP, ipproto.DCCP: - if len(tr) < header.UDPMinimumSize { + if len(tr) < minUDPSize { // Not enough space for a UDP header. return } updateV4Checksum(tr[6:8], o4[:], n4[:]) case ipproto.TCP: - if len(tr) < header.TCPMinimumSize { + if len(tr) < minTCPSize { // Not enough space for a TCP header. return } @@ -112,34 +110,60 @@ func updateV4PacketChecksums(p *packet.Parsed, old, new netip.Addr) { } } +const ( + minUDPSize = 8 + minTCPSize = 20 + minICMPv6Size = 8 + minIPv6Header = 40 + + offsetICMPv6Checksum = 2 + offsetUDPChecksum = 6 + offsetTCPChecksum = 16 +) + // updateV6PacketChecksums updates the checksums in the packet buffer. // p is modified in place. // If p.IPProto is unknown, no checksums are updated. func updateV6PacketChecksums(p *packet.Parsed, old, new netip.Addr) { - if len(p.Buffer()) < 40 { + if len(p.Buffer()) < minIPv6Header { // Not enough space for an IPv6 header. return } - o6, n6 := tcpip.AddrFrom16Slice(old.AsSlice()), tcpip.AddrFrom16Slice(new.AsSlice()) + o6, n6 := old.As16(), new.As16() // Now update the transport layer checksums, where applicable. tr := p.Transport() switch p.IPProto { case ipproto.ICMPv6: - if len(tr) < header.ICMPv6MinimumSize { + if len(tr) < minICMPv6Size { return } - header.ICMPv6(tr).UpdateChecksumPseudoHeaderAddress(o6, n6) + + ss := tr[offsetICMPv6Checksum:] + xsum := binary.BigEndian.Uint16(ss) + binary.BigEndian.PutUint16(ss, + ^checksumUpdate2ByteAlignedAddress(^xsum, o6, n6)) + case ipproto.UDP, ipproto.DCCP: - if len(tr) < header.UDPMinimumSize { + if len(tr) < minUDPSize { return } - header.UDP(tr).UpdateChecksumPseudoHeaderAddress(o6, n6, true) + ss := tr[offsetUDPChecksum:] + xsum := binary.BigEndian.Uint16(ss) + xsum = ^xsum + xsum = checksumUpdate2ByteAlignedAddress(xsum, o6, n6) + xsum = ^xsum + binary.BigEndian.PutUint16(ss, xsum) case ipproto.TCP: - if len(tr) < header.TCPMinimumSize { + if len(tr) < minTCPSize { return } - header.TCP(tr).UpdateChecksumPseudoHeaderAddress(o6, n6, true) + ss := tr[offsetTCPChecksum:] + xsum := binary.BigEndian.Uint16(ss) + xsum = ^xsum + xsum = checksumUpdate2ByteAlignedAddress(xsum, o6, n6) + xsum = ^xsum + binary.BigEndian.PutUint16(ss, xsum) case ipproto.SCTP: // No transport layer update required. } @@ -195,3 +219,77 @@ func updateV4Checksum(oldSum, old, new []byte) { hcPrime := ^uint16(cPrime) binary.BigEndian.PutUint16(oldSum, hcPrime) } + +// checksumUpdate2ByteAlignedAddress updates an address in a calculated +// checksum. +// +// The addresses must have the same length and must contain an even number +// of bytes. The address MUST begin at a 2-byte boundary in the original buffer. +// +// This implementation is copied from gVisor, but updated to use [16]byte. +func checksumUpdate2ByteAlignedAddress(xsum uint16, old, new [16]byte) uint16 { + const uint16Bytes = 2 + + oldAddr := old[:] + newAddr := new[:] + + // As per RFC 1071 page 4, + // (4) Incremental Update + // + // ... + // + // To update the checksum, simply add the differences of the + // sixteen bit integers that have been changed. To see why this + // works, observe that every 16-bit integer has an additive inverse + // and that addition is associative. From this it follows that + // given the original value m, the new value m', and the old + // checksum C, the new checksum C' is: + // + // C' = C + (-m) + m' = C + (m' - m) + for len(oldAddr) != 0 { + // Convert the 2 byte sequences to uint16 values then apply the increment + // update. + xsum = checksumUpdate2ByteAlignedUint16(xsum, (uint16(oldAddr[0])<<8)+uint16(oldAddr[1]), (uint16(newAddr[0])<<8)+uint16(newAddr[1])) + oldAddr = oldAddr[uint16Bytes:] + newAddr = newAddr[uint16Bytes:] + } + + return xsum +} + +// checksumUpdate2ByteAlignedUint16 updates a uint16 value in a calculated +// checksum. +// +// The value MUST begin at a 2-byte boundary in the original buffer. +// +// This implementation is copied from gVisor. +func checksumUpdate2ByteAlignedUint16(xsum, old, new uint16) uint16 { + // As per RFC 1071 page 4, + // (4) Incremental Update + // + // ... + // + // To update the checksum, simply add the differences of the + // sixteen bit integers that have been changed. To see why this + // works, observe that every 16-bit integer has an additive inverse + // and that addition is associative. From this it follows that + // given the original value m, the new value m', and the old + // checksum C, the new checksum C' is: + // + // C' = C + (-m) + m' = C + (m' - m) + if old == new { + return xsum + } + return checksumCombine(xsum, checksumCombine(new, ^old)) +} + +// 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. +// +// This implementation is copied from gVisor. +func checksumCombine(a, b uint16) uint16 { + v := uint32(a) + uint32(b) + return uint16(v + v>>16) +} diff --git a/vendor/tailscale.com/net/packet/geneve.go b/vendor/tailscale.com/net/packet/geneve.go index 29970a8..71b365a 100644 --- a/vendor/tailscale.com/net/packet/geneve.go +++ b/vendor/tailscale.com/net/packet/geneve.go @@ -24,6 +24,33 @@ const ( GeneveProtocolWireGuard uint16 = 0x7A12 ) +// VirtualNetworkID is a Geneve header (RFC8926) 3-byte virtual network +// identifier. Its methods are NOT thread-safe. +type VirtualNetworkID struct { + _vni uint32 +} + +const ( + vniSetMask uint32 = 0xFF000000 + vniGetMask uint32 = ^vniSetMask +) + +// IsSet returns true if Set() had been called previously, otherwise false. +func (v *VirtualNetworkID) IsSet() bool { + return v._vni&vniSetMask != 0 +} + +// Set sets the provided VNI. If VNI exceeds the 3-byte storage it will be +// clamped. +func (v *VirtualNetworkID) Set(vni uint32) { + v._vni = vni | vniSetMask +} + +// Get returns the VNI value. +func (v *VirtualNetworkID) Get() uint32 { + return v._vni & vniGetMask +} + // GeneveHeader represents the fixed size Geneve header from RFC8926. // TLVs/options are not implemented/supported. // @@ -51,7 +78,7 @@ type GeneveHeader struct { // decisions or MAY be used as a mechanism to distinguish between // overlapping address spaces contained in the encapsulated packet when load // balancing across CPUs. - VNI uint32 + VNI VirtualNetworkID // O (1 bit): Control packet. This packet contains a control message. // Control messages are sent between tunnel endpoints. Tunnel endpoints MUST @@ -65,12 +92,18 @@ type GeneveHeader struct { Control bool } -// Encode encodes GeneveHeader into b. If len(b) < GeneveFixedHeaderLength an -// io.ErrShortBuffer error is returned. +var ErrGeneveVNIUnset = errors.New("VNI is unset") + +// Encode encodes GeneveHeader into b. If len(b) < [GeneveFixedHeaderLength] an +// [io.ErrShortBuffer] error is returned. If !h.VNI.IsSet() then an +// [ErrGeneveVNIUnset] error is returned. func (h *GeneveHeader) Encode(b []byte) error { if len(b) < GeneveFixedHeaderLength { return io.ErrShortBuffer } + if !h.VNI.IsSet() { + return ErrGeneveVNIUnset + } if h.Version > 3 { return errors.New("version must be <= 3") } @@ -81,15 +114,12 @@ func (h *GeneveHeader) Encode(b []byte) error { b[1] |= 0x80 } binary.BigEndian.PutUint16(b[2:], h.Protocol) - if h.VNI > 1<<24-1 { - return errors.New("VNI must be <= 2^24-1") - } - binary.BigEndian.PutUint32(b[4:], h.VNI<<8) + binary.BigEndian.PutUint32(b[4:], h.VNI.Get()<<8) return nil } -// Decode decodes GeneveHeader from b. If len(b) < GeneveFixedHeaderLength an -// io.ErrShortBuffer error is returned. +// Decode decodes GeneveHeader from b. If len(b) < [GeneveFixedHeaderLength] an +// [io.ErrShortBuffer] error is returned. func (h *GeneveHeader) Decode(b []byte) error { if len(b) < GeneveFixedHeaderLength { return io.ErrShortBuffer @@ -99,6 +129,6 @@ func (h *GeneveHeader) Decode(b []byte) error { h.Control = true } h.Protocol = binary.BigEndian.Uint16(b[2:]) - h.VNI = binary.BigEndian.Uint32(b[4:]) >> 8 + h.VNI.Set(binary.BigEndian.Uint32(b[4:]) >> 8) return nil } diff --git a/vendor/tailscale.com/net/packet/header.go b/vendor/tailscale.com/net/packet/header.go index dbe8442..fa66a86 100644 --- a/vendor/tailscale.com/net/packet/header.go +++ b/vendor/tailscale.com/net/packet/header.go @@ -8,6 +8,7 @@ import ( "math" ) +const igmpHeaderLength = 8 const tcpHeaderLength = 20 const sctpHeaderLength = 12 diff --git a/vendor/tailscale.com/net/packet/packet.go b/vendor/tailscale.com/net/packet/packet.go index b683b22..34b63aa 100644 --- a/vendor/tailscale.com/net/packet/packet.go +++ b/vendor/tailscale.com/net/packet/packet.go @@ -51,10 +51,11 @@ type Parsed struct { IPVersion uint8 // IPProto is the IP subprotocol (UDP, TCP, etc.). Valid iff IPVersion != 0. IPProto ipproto.Proto - // SrcIP4 is the source address. Family matches IPVersion. Port is - // valid iff IPProto == TCP || IPProto == UDP. + // Src is the source address. Family matches IPVersion. Port is + // valid iff IPProto == TCP || IPProto == UDP || IPProto == SCTP. Src netip.AddrPort - // DstIP4 is the destination address. Family matches IPVersion. + // Dst is the destination address. Family matches IPVersion. Port is + // valid iff IPProto == TCP || IPProto == UDP || IPProto == SCTP. Dst netip.AddrPort // TCPFlags is the packet's TCP flag bits. Valid iff IPProto == TCP. TCPFlags TCPFlag @@ -160,14 +161,8 @@ func (q *Parsed) decode4(b []byte) { if fragOfs == 0 { // This is the first fragment - if moreFrags && len(sub) < minFragBlks { - // Suspiciously short first fragment, dump it. - q.IPProto = unknown - return - } - // otherwise, this is either non-fragmented (the usual case) - // or a big enough initial fragment that we can read the - // whole subprotocol header. + // Every protocol below MUST check that it has at least one entire + // transport header in order to protect against fragment confusion. switch q.IPProto { case ipproto.ICMPv4: if len(sub) < icmp4HeaderLength { @@ -179,6 +174,10 @@ func (q *Parsed) decode4(b []byte) { q.dataofs = q.subofs + icmp4HeaderLength return case ipproto.IGMP: + if len(sub) < igmpHeaderLength { + q.IPProto = unknown + return + } // Keep IPProto, but don't parse anything else // out. return @@ -211,6 +210,15 @@ func (q *Parsed) decode4(b []byte) { q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4])) return case ipproto.TSMP: + // Strictly disallow fragmented TSMP + if moreFrags { + q.IPProto = unknown + return + } + if len(sub) < minTSMPSize { + q.IPProto = unknown + return + } // Inter-tailscale messages. q.dataofs = q.subofs return @@ -223,8 +231,11 @@ func (q *Parsed) decode4(b []byte) { } else { // This is a fragment other than the first one. if fragOfs < minFragBlks { - // First frag was suspiciously short, so we can't - // trust the followup either. + // disallow fragment offsets that are potentially inside of a + // transport header. This is notably asymmetric with the + // first-packet limit, that may allow a first-packet that requires a + // shorter offset than this limit, but without state to tie this + // to the first fragment we can not allow shorter packets. q.IPProto = unknown return } @@ -314,6 +325,10 @@ func (q *Parsed) decode6(b []byte) { q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4])) return case ipproto.TSMP: + if len(sub) < minTSMPSize { + q.IPProto = unknown + return + } // Inter-tailscale messages. q.dataofs = q.subofs return diff --git a/vendor/tailscale.com/net/packet/tsmp.go b/vendor/tailscale.com/net/packet/tsmp.go index 4e004cc..9881299 100644 --- a/vendor/tailscale.com/net/packet/tsmp.go +++ b/vendor/tailscale.com/net/packet/tsmp.go @@ -15,10 +15,13 @@ import ( "fmt" "net/netip" - "tailscale.com/net/flowtrack" + "go4.org/mem" "tailscale.com/types/ipproto" + "tailscale.com/types/key" ) +const minTSMPSize = 7 // the rejected body is 7 bytes + // TailscaleRejectedHeader is a TSMP message that says that one // Tailscale node has rejected the connection from another. Unlike a // TCP RST, this includes a reason. @@ -56,10 +59,6 @@ type TailscaleRejectedHeader struct { const rejectFlagBitMaybeBroken = 0x1 -func (rh TailscaleRejectedHeader) Flow() flowtrack.Tuple { - return flowtrack.MakeTuple(rh.Proto, rh.Src, rh.Dst) -} - func (rh TailscaleRejectedHeader) String() string { return fmt.Sprintf("TSMP-reject-flow{%s %s > %s}: %s", rh.Proto, rh.Src, rh.Dst, rh.Reason) } @@ -75,6 +74,9 @@ const ( // TSMPTypePong is the type byte for a TailscalePongResponse. TSMPTypePong TSMPType = 'o' + + // TSPMTypeDiscoAdvertisement is the type byte for sending disco keys + TSMPTypeDiscoAdvertisement TSMPType = 'a' ) type TailscaleRejectReason byte @@ -262,3 +264,54 @@ func (h TSMPPongReply) Marshal(buf []byte) error { binary.BigEndian.PutUint16(buf[9:11], h.PeerAPIPort) return nil } + +// TSMPDiscoKeyAdvertisement is a TSMP message that's used for distributing Disco Keys. +// +// On the wire, after the IP header, it's currently 33 bytes: +// - 'a' (TSMPTypeDiscoAdvertisement) +// - 32 disco key bytes +type TSMPDiscoKeyAdvertisement struct { + Src, Dst netip.Addr // Src and Dst are set from the parent IP Header when parsing. + Key key.DiscoPublic +} + +func (ka *TSMPDiscoKeyAdvertisement) Marshal() ([]byte, error) { + var iph Header + if ka.Src.Is4() { + iph = IP4Header{ + IPProto: ipproto.TSMP, + Src: ka.Src, + Dst: ka.Dst, + } + } else { + iph = IP6Header{ + IPProto: ipproto.TSMP, + Src: ka.Src, + Dst: ka.Dst, + } + } + payload := make([]byte, 0, 33) + payload = append(payload, byte(TSMPTypeDiscoAdvertisement)) + payload = ka.Key.AppendTo(payload) + if len(payload) != 33 { + // Mostly to safeguard against ourselves changing this in the future. + return []byte{}, fmt.Errorf("expected payload length 33, got %d", len(payload)) + } + + return Generate(iph, payload[:]), nil +} + +func (pp *Parsed) AsTSMPDiscoAdvertisement() (tka TSMPDiscoKeyAdvertisement, ok bool) { + if pp.IPProto != ipproto.TSMP { + return + } + p := pp.Payload() + if len(p) < 33 || p[0] != byte(TSMPTypeDiscoAdvertisement) { + return + } + tka.Src = pp.Src.Addr() + tka.Dst = pp.Dst.Addr() + tka.Key = key.DiscoPublicFromRaw32(mem.B(p[1:33])) + + return tka, true +} diff --git a/vendor/tailscale.com/net/ping/ping.go b/vendor/tailscale.com/net/ping/ping.go index 01f3dcf..8e16a69 100644 --- a/vendor/tailscale.com/net/ping/ping.go +++ b/vendor/tailscale.com/net/ping/ping.go @@ -10,6 +10,7 @@ import ( "context" "crypto/rand" "encoding/binary" + "errors" "fmt" "io" "log" @@ -22,9 +23,9 @@ import ( "golang.org/x/net/icmp" "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/util/mak" - "tailscale.com/util/multierr" ) const ( @@ -64,7 +65,7 @@ type Pinger struct { wg sync.WaitGroup // Following fields protected by mu - mu sync.Mutex + mu syncs.Mutex // conns is a map of "type" to net.PacketConn, type is either // "ip4:icmp" or "ip6:icmp" conns map[string]net.PacketConn @@ -157,17 +158,17 @@ func (p *Pinger) Close() error { p.conns = nil p.mu.Unlock() - var errors []error + var errs []error for _, c := range conns { if err := c.Close(); err != nil { - errors = append(errors, err) + errs = append(errs, err) } } p.wg.Wait() p.cleanupOutstanding() - return multierr.New(errors...) + return errors.Join(errs...) } func (p *Pinger) run(ctx context.Context, conn net.PacketConn, typ string) { diff --git a/vendor/tailscale.com/net/portmapper/legacy_upnp.go b/vendor/tailscale.com/net/portmapper/legacy_upnp.go index 042ced1..2ce92dc 100644 --- a/vendor/tailscale.com/net/portmapper/legacy_upnp.go +++ b/vendor/tailscale.com/net/portmapper/legacy_upnp.go @@ -10,8 +10,8 @@ package portmapper import ( "context" - "github.com/tailscale/goupnp" - "github.com/tailscale/goupnp/soap" + "github.com/huin/goupnp" + "github.com/huin/goupnp/soap" ) const ( @@ -32,8 +32,8 @@ type legacyWANPPPConnection1 struct { goupnp.ServiceClient } -// AddPortMapping implements upnpClient -func (client *legacyWANPPPConnection1) AddPortMapping( +// AddPortMappingCtx implements upnpClient +func (client *legacyWANPPPConnection1) AddPortMappingCtx( ctx context.Context, NewRemoteHost string, NewExternalPort uint16, @@ -85,11 +85,11 @@ func (client *legacyWANPPPConnection1) AddPortMapping( response := any(nil) // Perform the SOAP call. - return client.SOAPClient.PerformAction(ctx, urn_LegacyWANPPPConnection_1, "AddPortMapping", request, response) + return client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANPPPConnection_1, "AddPortMapping", request, response) } -// DeletePortMapping implements upnpClient -func (client *legacyWANPPPConnection1) DeletePortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { +// DeletePortMappingCtx implements upnpClient +func (client *legacyWANPPPConnection1) DeletePortMappingCtx(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { NewRemoteHost string @@ -110,11 +110,11 @@ func (client *legacyWANPPPConnection1) DeletePortMapping(ctx context.Context, Ne response := any(nil) // Perform the SOAP call. - return client.SOAPClient.PerformAction(ctx, urn_LegacyWANPPPConnection_1, "DeletePortMapping", request, response) + return client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANPPPConnection_1, "DeletePortMapping", request, response) } -// GetExternalIPAddress implements upnpClient -func (client *legacyWANPPPConnection1) GetExternalIPAddress(ctx context.Context) (NewExternalIPAddress string, err error) { +// GetExternalIPAddressCtx implements upnpClient +func (client *legacyWANPPPConnection1) GetExternalIPAddressCtx(ctx context.Context) (NewExternalIPAddress string, err error) { // Request structure. request := any(nil) @@ -124,7 +124,7 @@ func (client *legacyWANPPPConnection1) GetExternalIPAddress(ctx context.Context) }{} // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, urn_LegacyWANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { + if err = client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil { return } @@ -134,8 +134,8 @@ func (client *legacyWANPPPConnection1) GetExternalIPAddress(ctx context.Context) return } -// GetStatusInfo implements upnpClient -func (client *legacyWANPPPConnection1) GetStatusInfo(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { +// GetStatusInfoCtx implements upnpClient +func (client *legacyWANPPPConnection1) GetStatusInfoCtx(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { // Request structure. request := any(nil) @@ -147,7 +147,7 @@ func (client *legacyWANPPPConnection1) GetStatusInfo(ctx context.Context) (NewCo }{} // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, urn_LegacyWANPPPConnection_1, "GetStatusInfo", request, response); err != nil { + if err = client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANPPPConnection_1, "GetStatusInfo", request, response); err != nil { return } @@ -171,8 +171,8 @@ type legacyWANIPConnection1 struct { goupnp.ServiceClient } -// AddPortMapping implements upnpClient -func (client *legacyWANIPConnection1) AddPortMapping( +// AddPortMappingCtx implements upnpClient +func (client *legacyWANIPConnection1) AddPortMappingCtx( ctx context.Context, NewRemoteHost string, NewExternalPort uint16, @@ -224,11 +224,11 @@ func (client *legacyWANIPConnection1) AddPortMapping( response := any(nil) // Perform the SOAP call. - return client.SOAPClient.PerformAction(ctx, urn_LegacyWANIPConnection_1, "AddPortMapping", request, response) + return client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANIPConnection_1, "AddPortMapping", request, response) } -// DeletePortMapping implements upnpClient -func (client *legacyWANIPConnection1) DeletePortMapping(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { +// DeletePortMappingCtx implements upnpClient +func (client *legacyWANIPConnection1) DeletePortMappingCtx(ctx context.Context, NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { NewRemoteHost string @@ -249,11 +249,11 @@ func (client *legacyWANIPConnection1) DeletePortMapping(ctx context.Context, New response := any(nil) // Perform the SOAP call. - return client.SOAPClient.PerformAction(ctx, urn_LegacyWANIPConnection_1, "DeletePortMapping", request, response) + return client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANIPConnection_1, "DeletePortMapping", request, response) } -// GetExternalIPAddress implements upnpClient -func (client *legacyWANIPConnection1) GetExternalIPAddress(ctx context.Context) (NewExternalIPAddress string, err error) { +// GetExternalIPAddressCtx implements upnpClient +func (client *legacyWANIPConnection1) GetExternalIPAddressCtx(ctx context.Context) (NewExternalIPAddress string, err error) { // Request structure. request := any(nil) @@ -263,7 +263,7 @@ func (client *legacyWANIPConnection1) GetExternalIPAddress(ctx context.Context) }{} // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, urn_LegacyWANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { + if err = client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANIPConnection_1, "GetExternalIPAddress", request, response); err != nil { return } @@ -273,8 +273,8 @@ func (client *legacyWANIPConnection1) GetExternalIPAddress(ctx context.Context) return } -// GetStatusInfo implements upnpClient -func (client *legacyWANIPConnection1) GetStatusInfo(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { +// GetStatusInfoCtx implements upnpClient +func (client *legacyWANIPConnection1) GetStatusInfoCtx(ctx context.Context) (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) { // Request structure. request := any(nil) @@ -286,7 +286,7 @@ func (client *legacyWANIPConnection1) GetStatusInfo(ctx context.Context) (NewCon }{} // Perform the SOAP call. - if err = client.SOAPClient.PerformAction(ctx, urn_LegacyWANIPConnection_1, "GetStatusInfo", request, response); err != nil { + if err = client.SOAPClient.PerformActionCtx(ctx, urn_LegacyWANIPConnection_1, "GetStatusInfo", request, response); err != nil { return } diff --git a/vendor/tailscale.com/net/portmapper/pmpresultcode_string.go b/vendor/tailscale.com/net/portmapper/pmpresultcode_string.go index 603636a..18d911d 100644 --- a/vendor/tailscale.com/net/portmapper/pmpresultcode_string.go +++ b/vendor/tailscale.com/net/portmapper/pmpresultcode_string.go @@ -24,8 +24,9 @@ const _pmpResultCode_name = "OKUnsupportedVersionNotAuthorizedNetworkFailureOutO var _pmpResultCode_index = [...]uint8{0, 2, 20, 33, 47, 61, 78} func (i pmpResultCode) String() string { - if i >= pmpResultCode(len(_pmpResultCode_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_pmpResultCode_index)-1 { return "pmpResultCode(" + strconv.FormatInt(int64(i), 10) + ")" } - return _pmpResultCode_name[_pmpResultCode_index[i]:_pmpResultCode_index[i+1]] + return _pmpResultCode_name[_pmpResultCode_index[idx]:_pmpResultCode_index[idx+1]] } diff --git a/vendor/tailscale.com/net/portmapper/portmapper.go b/vendor/tailscale.com/net/portmapper/portmapper.go index 71b55b8..16a981d 100644 --- a/vendor/tailscale.com/net/portmapper/portmapper.go +++ b/vendor/tailscale.com/net/portmapper/portmapper.go @@ -8,29 +8,36 @@ package portmapper import ( "context" "encoding/binary" - "errors" "fmt" "io" "net" "net/http" "net/netip" "slices" - "sync" "sync/atomic" "time" "go4.org/mem" - "tailscale.com/control/controlknobs" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/netaddr" "tailscale.com/net/neterror" "tailscale.com/net/netmon" "tailscale.com/net/netns" + "tailscale.com/net/portmapper/portmappertype" "tailscale.com/net/sockstats" "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/types/nettype" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" +) + +var ( + ErrNoPortMappingServices = portmappertype.ErrNoPortMappingServices + ErrGatewayRange = portmappertype.ErrGatewayRange + ErrGatewayIPv6 = portmappertype.ErrGatewayIPv6 + ErrPortMappingDisabled = portmappertype.ErrPortMappingDisabled ) var disablePortMapperEnv = envknob.RegisterBool("TS_DISABLE_PORTMAPPER") @@ -48,15 +55,33 @@ type DebugKnobs struct { LogHTTP bool // Disable* disables a specific service from mapping. - DisableUPnP bool - DisablePMP bool - DisablePCP bool + // If the funcs are nil or return false, the service is not disabled. + // Use the corresponding accessor methods without the "Func" suffix + // to check whether a service is disabled. + DisableUPnPFunc func() bool + DisablePMPFunc func() bool + DisablePCPFunc func() bool // DisableAll, if non-nil, is a func that reports whether all port // mapping attempts should be disabled. DisableAll func() bool } +// DisableUPnP reports whether UPnP is disabled. +func (k *DebugKnobs) DisableUPnP() bool { + return k != nil && k.DisableUPnPFunc != nil && k.DisableUPnPFunc() +} + +// DisablePMP reports whether NAT-PMP is disabled. +func (k *DebugKnobs) DisablePMP() bool { + return k != nil && k.DisablePMPFunc != nil && k.DisablePMPFunc() +} + +// DisablePCP reports whether PCP is disabled. +func (k *DebugKnobs) DisablePCP() bool { + return k != nil && k.DisablePCPFunc != nil && k.DisablePCPFunc() +} + func (k *DebugKnobs) disableAll() bool { if disablePortMapperEnv() { return true @@ -84,16 +109,20 @@ const trustServiceStillAvailableDuration = 10 * time.Minute // Client is a port mapping client. type Client struct { + // The following two fields must both be non-nil. + // Both are immutable after construction. + pubClient *eventbus.Client + updates *eventbus.Publisher[portmappertype.Mapping] + logf logger.Logf netMon *netmon.Monitor // optional; nil means interfaces will be looked up on-demand - controlKnobs *controlknobs.Knobs ipAndGateway func() (gw, ip netip.Addr, ok bool) onChange func() // or nil debug DebugKnobs testPxPPort uint16 // if non-zero, pxpPort to use for tests testUPnPPort uint16 // if non-zero, uPnPPort to use for tests - mu sync.Mutex // guards following, and all fields thereof + mu syncs.Mutex // guards following, and all fields thereof // runningCreate is whether we're currently working on creating // a port mapping (whether GetCachedMappingOrStartCreatingOne kicked @@ -124,6 +153,8 @@ type Client struct { mapping mapping // non-nil if we have a mapping } +var _ portmappertype.Client = (*Client)(nil) + func (c *Client) vlogf(format string, args ...any) { if c.debug.VerboseLogs { c.logf(format, args...) @@ -153,7 +184,6 @@ type mapping interface { MappingDebug() string } -// HaveMapping reports whether we have a current valid mapping. func (c *Client) HaveMapping() bool { c.mu.Lock() defer c.mu.Unlock() @@ -201,32 +231,52 @@ func (m *pmpMapping) Release(ctx context.Context) { uc.WriteToUDPAddrPort(pkt, m.gw) } -// NewClient returns a new portmapping client. -// -// The netMon parameter is required. -// -// The debug argument allows configuring the behaviour of the portmapper for -// debugging; if nil, a sensible set of defaults will be used. -// -// The controlKnobs, if non-nil, specifies the control knobs from the control -// plane that might disable portmapping. -// -// The optional onChange argument specifies a func to run in a new goroutine -// whenever the port mapping status has changed. If nil, it doesn't make a -// callback. -func NewClient(logf logger.Logf, netMon *netmon.Monitor, debug *DebugKnobs, controlKnobs *controlknobs.Knobs, onChange func()) *Client { - if netMon == nil { - panic("nil netMon") +// Config carries the settings for a [Client]. +type Config struct { + // EventBus, which must be non-nil, is used for event publication and + // subscription by portmapper clients created from this config. + EventBus *eventbus.Bus + + // Logf is called to generate text logs for the client. If nil, logger.Discard is used. + Logf logger.Logf + + // NetMon is the network monitor used by the client. It must be non-nil. + NetMon *netmon.Monitor + + // DebugKnobs, if non-nil, configure the behaviour of the portmapper for + // debugging. If nil, a sensible set of defaults will be used. + DebugKnobs *DebugKnobs + + // OnChange is called to run in a new goroutine whenever the port mapping + // status has changed. If nil, no callback is issued. + OnChange func() +} + +// NewClient constructs a new portmapping [Client] from c. It will panic if any +// required parameters are omitted. +func NewClient(c Config) *Client { + switch { + case c.NetMon == nil: + panic("nil NetMon") + case c.EventBus == nil: + panic("nil EventBus") } ret := &Client{ - logf: logf, - netMon: netMon, - ipAndGateway: netmon.LikelyHomeRouterIP, // TODO(bradfitz): move this to method on netMon - onChange: onChange, - controlKnobs: controlKnobs, + logf: c.Logf, + netMon: c.NetMon, + onChange: c.OnChange, } - if debug != nil { - ret.debug = *debug + if buildfeatures.HasPortMapper { + // TODO(bradfitz): move this to method on netMon + ret.ipAndGateway = netmon.LikelyHomeRouterIP + } + ret.pubClient = c.EventBus.Client("portmapper") + ret.updates = eventbus.Publish[portmappertype.Mapping](ret.pubClient) + if ret.logf == nil { + ret.logf = logger.Discard + } + if c.DebugKnobs != nil { + ret.debug = *c.DebugKnobs } return ret } @@ -256,6 +306,9 @@ func (c *Client) Close() error { } c.closed = true c.invalidateMappingsLocked(true) + c.updates.Close() + c.pubClient.Close() + // TODO: close some future ever-listening UDP socket(s), // waiting for multicast announcements from router. return nil @@ -417,13 +470,6 @@ func IsNoMappingError(err error) bool { return ok } -var ( - ErrNoPortMappingServices = errors.New("no port mapping services were found") - ErrGatewayRange = errors.New("skipping portmap; gateway range likely lacks support") - ErrGatewayIPv6 = errors.New("skipping portmap; no IPv6 support for portmapping") - ErrPortMappingDisabled = errors.New("port mapping is disabled") -) - // GetCachedMappingOrStartCreatingOne quickly returns with our current cached portmapping, if any. // If there's not one, it starts up a background goroutine to create one. // If the background goroutine ends up creating one, the onChange hook registered with the @@ -467,10 +513,29 @@ func (c *Client) createMapping() { c.runningCreate = false }() - if _, err := c.createOrGetMapping(ctx); err == nil && c.onChange != nil { + mapping, _, err := c.createOrGetMapping(ctx) + if err != nil { + if !IsNoMappingError(err) { + c.logf("createOrGetMapping: %v", err) + } + return + } else if mapping == nil { + return + + // TODO(creachadair): This was already logged in createOrGetMapping. + // It really should not happen at all, but we will need to untangle + // the control flow to eliminate that possibility. Meanwhile, this + // mitigates a panic downstream, cf. #16662. + } + c.updates.Publish(portmappertype.Mapping{ + External: mapping.External(), + Type: mapping.MappingType(), + GoodUntil: mapping.GoodUntil(), + }) + // TODO(creachadair): Remove this entirely once there are no longer any + // places where the callback is set. + if c.onChange != nil { go c.onChange() - } else if err != nil && !IsNoMappingError(err) { - c.logf("createOrGetMapping: %v", err) } } @@ -482,19 +547,19 @@ var wildcardIP = netip.MustParseAddr("0.0.0.0") // // If no mapping is available, the error will be of type // NoMappingError; see IsNoMappingError. -func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPort, err error) { +func (c *Client) createOrGetMapping(ctx context.Context) (mapping mapping, external netip.AddrPort, err error) { if c.debug.disableAll() { - return netip.AddrPort{}, NoMappingError{ErrPortMappingDisabled} + return nil, netip.AddrPort{}, NoMappingError{ErrPortMappingDisabled} } - if c.debug.DisableUPnP && c.debug.DisablePCP && c.debug.DisablePMP { - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + if c.debug.DisableUPnP() && c.debug.DisablePCP() && c.debug.DisablePMP() { + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } gw, myIP, ok := c.gatewayAndSelfIP() if !ok { - return netip.AddrPort{}, NoMappingError{ErrGatewayRange} + return nil, netip.AddrPort{}, NoMappingError{ErrGatewayRange} } if gw.Is6() { - return netip.AddrPort{}, NoMappingError{ErrGatewayIPv6} + return nil, netip.AddrPort{}, NoMappingError{ErrGatewayIPv6} } now := time.Now() @@ -523,6 +588,17 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor return } + // TODO(creachadair): This is more subtle than it should be. Ideally we + // would just return the mapping directly, but there are many different + // paths through the function with carefully-balanced locks, and not all + // the paths have a mapping to return. As a workaround, while we're here + // doing cleanup under the lock, grab the final mapping value and return + // it, so the caller does not need to grab the lock again and potentially + // race with a later update. The mapping itself is concurrency-safe. + // + // We should restructure this code so the locks are properly scoped. + mapping = c.mapping + // Print the internal details of each mapping if we're being verbose. if c.debug.VerboseLogs { c.logf("successfully obtained mapping: now=%d external=%v type=%s mapping=%s", @@ -548,19 +624,19 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor if now.Before(m.RenewAfter()) { defer c.mu.Unlock() reusedExisting = true - return m.External(), nil + return nil, m.External(), nil } // The mapping might still be valid, so just try to renew it. prevPort = m.External().Port() } - if c.debug.DisablePCP && c.debug.DisablePMP { + if c.debug.DisablePCP() && c.debug.DisablePMP() { c.mu.Unlock() if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok { - return external, nil + return nil, external, nil } c.vlogf("fallback to UPnP due to PCP and PMP being disabled failed") - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } // If we just did a Probe (e.g. via netchecker) but didn't @@ -587,16 +663,16 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor c.mu.Unlock() // fallback to UPnP portmapping if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok { - return external, nil + return nil, external, nil } c.vlogf("fallback to UPnP due to no PCP and PMP failed") - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } c.mu.Unlock() uc, err := c.listenPacket(ctx, "udp4", ":0") if err != nil { - return netip.AddrPort{}, err + return nil, netip.AddrPort{}, err } defer uc.Close() @@ -605,7 +681,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor pxpAddr := netip.AddrPortFrom(gw, c.pxpPort()) - preferPCP := !c.debug.DisablePCP && (c.debug.DisablePMP || (!haveRecentPMP && haveRecentPCP)) + preferPCP := !c.debug.DisablePCP() && (c.debug.DisablePMP() || (!haveRecentPMP && haveRecentPCP)) // Create a mapping, defaulting to PMP unless only PCP was seen recently. if preferPCP { @@ -616,7 +692,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor if neterror.TreatAsLostUDP(err) { err = NoMappingError{ErrNoPortMappingServices} } - return netip.AddrPort{}, err + return nil, netip.AddrPort{}, err } } else { // Ask for our external address if needed. @@ -625,7 +701,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor if neterror.TreatAsLostUDP(err) { err = NoMappingError{ErrNoPortMappingServices} } - return netip.AddrPort{}, err + return nil, netip.AddrPort{}, err } } @@ -634,7 +710,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor if neterror.TreatAsLostUDP(err) { err = NoMappingError{ErrNoPortMappingServices} } - return netip.AddrPort{}, err + return nil, netip.AddrPort{}, err } } @@ -643,13 +719,13 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor n, src, err := uc.ReadFromUDPAddrPort(res) if err != nil { if ctx.Err() == context.Canceled { - return netip.AddrPort{}, err + return nil, netip.AddrPort{}, err } // fallback to UPnP portmapping if mapping, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok { - return mapping, nil + return nil, mapping, nil } - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } src = netaddr.Unmap(src) if !src.IsValid() { @@ -665,7 +741,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor continue } if pres.ResultCode != 0 { - return netip.AddrPort{}, NoMappingError{fmt.Errorf("PMP response Op=0x%x,Res=0x%x", pres.OpCode, pres.ResultCode)} + return nil, netip.AddrPort{}, NoMappingError{fmt.Errorf("PMP response Op=0x%x,Res=0x%x", pres.OpCode, pres.ResultCode)} } if pres.OpCode == pmpOpReply|pmpOpMapPublicAddr { m.external = netip.AddrPortFrom(pres.PublicAddr, m.external.Port()) @@ -683,7 +759,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor if err != nil { c.logf("failed to get PCP mapping: %v", err) // PCP should only have a single packet response - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } pcpMapping.c = c pcpMapping.internal = m.internal @@ -691,10 +767,10 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor c.mu.Lock() defer c.mu.Unlock() c.mapping = pcpMapping - return pcpMapping.external, nil + return pcpMapping, pcpMapping.external, nil default: c.logf("unknown PMP/PCP version number: %d %v", version, res[:n]) - return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} + return nil, netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices} } } @@ -702,7 +778,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPor c.mu.Lock() defer c.mu.Unlock() c.mapping = m - return m.external, nil + return nil, m.external, nil } } } @@ -790,19 +866,13 @@ func parsePMPResponse(pkt []byte) (res pmpResponse, ok bool) { return res, true } -type ProbeResult struct { - PCP bool - PMP bool - UPnP bool -} - // Probe returns a summary of which port mapping services are // available on the network. // // If a probe has run recently and there haven't been any network changes since, // the returned result might be server from the Client's cache, without // sending any network traffic. -func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) { +func (c *Client) Probe(ctx context.Context) (res portmappertype.ProbeResult, err error) { if c.debug.disableAll() { return res, ErrPortMappingDisabled } @@ -837,19 +907,19 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) { // https://github.com/tailscale/tailscale/issues/1001 if c.sawPMPRecently() { res.PMP = true - } else if !c.debug.DisablePMP { + } else if !c.debug.DisablePMP() { metricPMPSent.Add(1) uc.WriteToUDPAddrPort(pmpReqExternalAddrPacket, pxpAddr) } if c.sawPCPRecently() { res.PCP = true - } else if !c.debug.DisablePCP { + } else if !c.debug.DisablePCP() { metricPCPSent.Add(1) uc.WriteToUDPAddrPort(pcpAnnounceRequest(myIP), pxpAddr) } if c.sawUPnPRecently() { res.UPnP = true - } else if !c.debug.DisableUPnP { + } else if !c.debug.DisableUPnP() { // Strictly speaking, you discover UPnP services by sending an // SSDP query (which uPnPPacket is) to udp/1900 on the SSDP // multicast address, and then get a flood of responses back diff --git a/vendor/tailscale.com/net/portmapper/portmappertype/portmappertype.go b/vendor/tailscale.com/net/portmapper/portmappertype/portmappertype.go new file mode 100644 index 0000000..cc8358a --- /dev/null +++ b/vendor/tailscale.com/net/portmapper/portmappertype/portmappertype.go @@ -0,0 +1,88 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package portmappertype defines the net/portmapper interface, which may or may not be +// linked into the binary. +package portmappertype + +import ( + "context" + "errors" + "net/netip" + "time" + + "tailscale.com/feature" + "tailscale.com/net/netmon" + "tailscale.com/types/logger" + "tailscale.com/util/eventbus" +) + +// HookNewPortMapper is a hook to install the portmapper creation function. +// It must be set by an init function when buildfeatures.HasPortmapper is true. +var HookNewPortMapper feature.Hook[func(logf logger.Logf, + bus *eventbus.Bus, + netMon *netmon.Monitor, + disableUPnPOrNil, + onlyTCP443OrNil func() bool) Client] + +var ( + ErrNoPortMappingServices = errors.New("no port mapping services were found") + ErrGatewayRange = errors.New("skipping portmap; gateway range likely lacks support") + ErrGatewayIPv6 = errors.New("skipping portmap; no IPv6 support for portmapping") + ErrPortMappingDisabled = errors.New("port mapping is disabled") +) + +// ProbeResult is the result of a portmapper probe, saying +// which port mapping protocols were discovered. +type ProbeResult struct { + PCP bool + PMP bool + UPnP bool +} + +// Client is the interface implemented by a portmapper client. +type Client interface { + // Probe returns a summary of which port mapping services are available on + // the network. + // + // If a probe has run recently and there haven't been any network changes + // since, the returned result might be server from the Client's cache, + // without sending any network traffic. + Probe(context.Context) (ProbeResult, error) + + // HaveMapping reports whether we have a current valid mapping. + HaveMapping() bool + + // SetGatewayLookupFunc set the func that returns the machine's default + // gateway IP, and the primary IP address for that gateway. It must be + // called before the client is used. If not called, + // interfaces.LikelyHomeRouterIP is used. + SetGatewayLookupFunc(f func() (gw, myIP netip.Addr, ok bool)) + + // NoteNetworkDown should be called when the network has transitioned to a down state. + // It's too late to release port mappings at this point (the user might've just turned off + // their wifi), but we can make sure we invalidate mappings for later when the network + // comes back. + NoteNetworkDown() + + // GetCachedMappingOrStartCreatingOne quickly returns with our current cached portmapping, if any. + // If there's not one, it starts up a background goroutine to create one. + // If the background goroutine ends up creating one, the onChange hook registered with the + // NewClient constructor (if any) will fire. + GetCachedMappingOrStartCreatingOne() (external netip.AddrPort, ok bool) + + // SetLocalPort updates the local port number to which we want to port + // map UDP traffic + SetLocalPort(localPort uint16) + + Close() error +} + +// Mapping is an event recording the allocation of a port mapping. +type Mapping struct { + External netip.AddrPort + Type string + GoodUntil time.Time + + // TODO(creachadair): Record whether we reused an existing mapping? +} diff --git a/vendor/tailscale.com/net/portmapper/upnp.go b/vendor/tailscale.com/net/portmapper/upnp.go index 1341831..34140e9 100644 --- a/vendor/tailscale.com/net/portmapper/upnp.go +++ b/vendor/tailscale.com/net/portmapper/upnp.go @@ -25,15 +25,47 @@ import ( "sync/atomic" "time" - "github.com/tailscale/goupnp" - "github.com/tailscale/goupnp/dcps/internetgateway2" - "github.com/tailscale/goupnp/soap" + "github.com/huin/goupnp" + "github.com/huin/goupnp/dcps/internetgateway2" + "github.com/huin/goupnp/soap" "tailscale.com/envknob" "tailscale.com/net/netns" "tailscale.com/types/logger" + "tailscale.com/util/ctxkey" "tailscale.com/util/mak" ) +// upnpHTTPClientKey is a context key for storing an HTTP client to use +// for UPnP requests. This allows us to use a custom HTTP client (with custom +// dialer, timeouts, etc.) while using the upstream goupnp library which only +// supports a global HTTPClientDefault. +var upnpHTTPClientKey = ctxkey.New[*http.Client]("portmapper.upnpHTTPClient", nil) + +// delegatingRoundTripper implements http.RoundTripper by delegating to +// the HTTP client stored in the request's context. This allows us to use +// per-request HTTP client configuration with the upstream goupnp library. +type delegatingRoundTripper struct { + inner *http.Client +} + +func (d delegatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + if c := upnpHTTPClientKey.Value(req.Context()); c != nil { + return c.Transport.RoundTrip(req) + } + return d.inner.Do(req) +} + +func init() { + // The upstream goupnp library uses a global HTTP client for all + // requests, while we want to be able to use a per-Client + // [http.Client]. We replace its global HTTP client with one that + // delegates to the HTTP client stored in the request's context. + old := goupnp.HTTPClientDefault + goupnp.HTTPClientDefault = &http.Client{ + Transport: delegatingRoundTripper{old}, + } +} + // References: // // WANIP Connection v2: http://upnp.org/specs/gw/UPnP-gw-WANIPConnection-v2-Service.pdf @@ -79,14 +111,17 @@ func (u *upnpMapping) MappingDebug() string { u.loc) } func (u *upnpMapping) Release(ctx context.Context) { - u.client.DeletePortMapping(ctx, "", u.external.Port(), upnpProtocolUDP) + u.client.DeletePortMappingCtx(ctx, "", u.external.Port(), upnpProtocolUDP) } // upnpClient is an interface over the multiple different clients exported by goupnp, // exposing the functions we need for portmapping. Those clients are auto-generated from XML-specs, // which is why they're not very idiomatic. +// +// The method names use the *Ctx suffix to match the upstream goupnp library's convention +// for context-aware methods. type upnpClient interface { - AddPortMapping( + AddPortMappingCtx( ctx context.Context, // remoteHost is the remote device sending packets to this device, in the format of x.x.x.x. @@ -119,9 +154,9 @@ type upnpClient interface { leaseDurationSec uint32, ) error - DeletePortMapping(ctx context.Context, remoteHost string, externalPort uint16, protocol string) error - GetExternalIPAddress(ctx context.Context) (externalIPAddress string, err error) - GetStatusInfo(ctx context.Context) (status string, lastConnError string, uptime uint32, err error) + DeletePortMappingCtx(ctx context.Context, remoteHost string, externalPort uint16, protocol string) error + GetExternalIPAddressCtx(ctx context.Context) (externalIPAddress string, err error) + GetStatusInfoCtx(ctx context.Context) (status string, lastConnError string, uptime uint32, err error) } // tsPortMappingDesc gets sent to UPnP clients as a human-readable label for the portmapping. @@ -171,7 +206,7 @@ func addAnyPortMapping( // First off, try using AddAnyPortMapping; if there's a conflict, the // router will pick another port and return it. if upnp, ok := upnp.(*internetgateway2.WANIPConnection2); ok { - return upnp.AddAnyPortMapping( + return upnp.AddAnyPortMappingCtx( ctx, "", externalPort, @@ -186,7 +221,7 @@ func addAnyPortMapping( // Fall back to using AddPortMapping, which requests a mapping to/from // a specific external port. - err = upnp.AddPortMapping( + err = upnp.AddPortMappingCtx( ctx, "", externalPort, @@ -209,7 +244,7 @@ func addAnyPortMapping( // The meta is the most recently parsed UDP discovery packet response // from the Internet Gateway Device. func getUPnPRootDevice(ctx context.Context, logf logger.Logf, debug DebugKnobs, gw netip.Addr, meta uPnPDiscoResponse) (rootDev *goupnp.RootDevice, loc *url.URL, err error) { - if debug.DisableUPnP { + if debug.DisableUPnP() { return nil, nil, nil } @@ -244,7 +279,7 @@ func getUPnPRootDevice(ctx context.Context, logf logger.Logf, debug DebugKnobs, defer cancel() // This part does a network fetch. - root, err := goupnp.DeviceByURL(ctx, u) + root, err := goupnp.DeviceByURLCtx(ctx, u) if err != nil { return nil, nil, err } @@ -257,8 +292,7 @@ func getUPnPRootDevice(ctx context.Context, logf logger.Logf, debug DebugKnobs, // // loc is the parsed location that was used to fetch the given RootDevice. // -// The provided ctx is not retained in the returned upnpClient, but -// its associated HTTP client is (if set via goupnp.WithHTTPClient). +// The provided ctx is not retained in the returned upnpClient. func selectBestService(ctx context.Context, logf logger.Logf, root *goupnp.RootDevice, loc *url.URL) (client upnpClient, err error) { method := "none" defer func() { @@ -274,9 +308,9 @@ func selectBestService(ctx context.Context, logf logger.Logf, root *goupnp.RootD // First, get all available clients from the device, and append to our // list of possible clients. Order matters here; we want to prefer // WANIPConnection2 over WANIPConnection1 or WANPPPConnection. - wanIP2, _ := internetgateway2.NewWANIPConnection2ClientsFromRootDevice(ctx, root, loc) - wanIP1, _ := internetgateway2.NewWANIPConnection1ClientsFromRootDevice(ctx, root, loc) - wanPPP, _ := internetgateway2.NewWANPPPConnection1ClientsFromRootDevice(ctx, root, loc) + wanIP2, _ := internetgateway2.NewWANIPConnection2ClientsFromRootDevice(root, loc) + wanIP1, _ := internetgateway2.NewWANIPConnection1ClientsFromRootDevice(root, loc) + wanPPP, _ := internetgateway2.NewWANPPPConnection1ClientsFromRootDevice(root, loc) var clients []upnpClient for _, v := range wanIP2 { @@ -291,12 +325,12 @@ func selectBestService(ctx context.Context, logf logger.Logf, root *goupnp.RootD // These are legacy services that were deprecated in 2015, but are // still in use by older devices; try them just in case. - legacyClients, _ := goupnp.NewServiceClientsFromRootDevice(ctx, root, loc, urn_LegacyWANPPPConnection_1) + legacyClients, _ := goupnp.NewServiceClientsFromRootDevice(root, loc, urn_LegacyWANPPPConnection_1) metricUPnPSelectLegacy.Add(int64(len(legacyClients))) for _, client := range legacyClients { clients = append(clients, &legacyWANPPPConnection1{client}) } - legacyClients, _ = goupnp.NewServiceClientsFromRootDevice(ctx, root, loc, urn_LegacyWANIPConnection_1) + legacyClients, _ = goupnp.NewServiceClientsFromRootDevice(root, loc, urn_LegacyWANIPConnection_1) metricUPnPSelectLegacy.Add(int64(len(legacyClients))) for _, client := range legacyClients { clients = append(clients, &legacyWANIPConnection1{client}) @@ -346,7 +380,7 @@ func selectBestService(ctx context.Context, logf logger.Logf, root *goupnp.RootD } // Check if the device has an external IP address. - extIP, err := svc.GetExternalIPAddress(ctx) + extIP, err := svc.GetExternalIPAddressCtx(ctx) if err != nil { continue } @@ -399,7 +433,7 @@ func selectBestService(ctx context.Context, logf logger.Logf, root *goupnp.RootD // serviceIsConnected returns whether a given UPnP service is connected, based // on the NewConnectionStatus field returned from GetStatusInfo. func serviceIsConnected(ctx context.Context, logf logger.Logf, svc upnpClient) bool { - status, _ /* NewLastConnectionError */, _ /* NewUptime */, err := svc.GetStatusInfo(ctx) + status, _ /* NewLastConnectionError */, _ /* NewUptime */, err := svc.GetStatusInfoCtx(ctx) if err != nil { return false } @@ -434,7 +468,7 @@ func (c *Client) getUPnPPortMapping( internal netip.AddrPort, prevPort uint16, ) (external netip.AddrPort, ok bool) { - if disableUPnpEnv() || c.debug.DisableUPnP || (c.controlKnobs != nil && c.controlKnobs.DisableUPnP.Load()) { + if disableUPnpEnv() || c.debug.DisableUPnP() { return netip.AddrPort{}, false } @@ -454,7 +488,7 @@ func (c *Client) getUPnPPortMapping( c.mu.Lock() oldMapping, ok := c.mapping.(*upnpMapping) metas := c.uPnPMetas - ctx = goupnp.WithHTTPClient(ctx, c.upnpHTTPClientLocked()) + ctx = upnpHTTPClientKey.WithValue(ctx, c.upnpHTTPClientLocked()) c.mu.Unlock() // Wrapper for a uPnPDiscoResponse with an optional existing root @@ -629,7 +663,7 @@ func (c *Client) tryUPnPPortmapWithDevice( } // TODO cache this ip somewhere? - extIP, err := client.GetExternalIPAddress(ctx) + extIP, err := client.GetExternalIPAddressCtx(ctx) c.vlogf("client.GetExternalIPAddress: %v, %v", extIP, err) if err != nil { return netip.AddrPort{}, nil, err diff --git a/vendor/tailscale.com/net/routetable/routetable.go b/vendor/tailscale.com/net/routetable/routetable.go deleted file mode 100644 index 2884706..0000000 --- a/vendor/tailscale.com/net/routetable/routetable.go +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package routetable provides functions that operate on the system's route -// table. -package routetable - -import ( - "bufio" - "fmt" - "net/netip" - "strconv" - - "tailscale.com/types/logger" -) - -var ( - //lint:ignore U1000 used in routetable_linux_test.go and routetable_bsd_test.go - defaultRouteIPv4 = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv4Unspecified(), 0)} - //lint:ignore U1000 used in routetable_bsd_test.go - defaultRouteIPv6 = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv6Unspecified(), 0)} -) - -// RouteEntry contains common cross-platform fields describing an entry in the -// system route table. -type RouteEntry struct { - // Family is the IP family of the route; it will be either 4 or 6. - Family int - // Type is the type of this route. - Type RouteType - // Dst is the destination of the route. - Dst RouteDestination - // Gatewayis the gateway address specified for this route. - // This value will be invalid (where !r.Gateway.IsValid()) in cases - // where there is no gateway address for this route. - Gateway netip.Addr - // Interface is the name of the network interface to use when sending - // packets that match this route. This field can be empty. - Interface string - // Sys contains platform-specific information about this route. - Sys any -} - -// Format implements the fmt.Formatter interface. -func (r RouteEntry) Format(f fmt.State, verb rune) { - logger.ArgWriter(func(w *bufio.Writer) { - switch r.Family { - case 4: - fmt.Fprintf(w, "{Family: IPv4") - case 6: - fmt.Fprintf(w, "{Family: IPv6") - default: - fmt.Fprintf(w, "{Family: unknown(%d)", r.Family) - } - - // Match 'ip route' and other tools by not printing the route - // type if it's a unicast route. - if r.Type != RouteTypeUnicast { - fmt.Fprintf(w, ", Type: %s", r.Type) - } - - if r.Dst.IsValid() { - fmt.Fprintf(w, ", Dst: %s", r.Dst) - } else { - w.WriteString(", Dst: invalid") - } - - if r.Gateway.IsValid() { - fmt.Fprintf(w, ", Gateway: %s", r.Gateway) - } - - if r.Interface != "" { - fmt.Fprintf(w, ", Interface: %s", r.Interface) - } - - if r.Sys != nil { - var formatVerb string - switch { - case f.Flag('#'): - formatVerb = "%#v" - case f.Flag('+'): - formatVerb = "%+v" - default: - formatVerb = "%v" - } - fmt.Fprintf(w, ", Sys: "+formatVerb, r.Sys) - } - - w.WriteString("}") - }).Format(f, verb) -} - -// RouteDestination is the destination of a route. -// -// This is similar to net/netip.Prefix, but also contains an optional IPv6 -// zone. -type RouteDestination struct { - netip.Prefix - Zone string -} - -func (r RouteDestination) String() string { - ip := r.Prefix.Addr() - if r.Zone != "" { - ip = ip.WithZone(r.Zone) - } - return ip.String() + "/" + strconv.Itoa(r.Prefix.Bits()) -} - -// RouteType describes the type of a route. -type RouteType int - -const ( - // RouteTypeUnspecified is the unspecified route type. - RouteTypeUnspecified RouteType = iota - // RouteTypeLocal indicates that the destination of this route is an - // address that belongs to this system. - RouteTypeLocal - // RouteTypeUnicast indicates that the destination of this route is a - // "regular" address--one that neither belongs to this host, nor is a - // broadcast/multicast/etc. address. - RouteTypeUnicast - // RouteTypeBroadcast indicates that the destination of this route is a - // broadcast address. - RouteTypeBroadcast - // RouteTypeMulticast indicates that the destination of this route is a - // multicast address. - RouteTypeMulticast - // RouteTypeOther indicates that the route is of some other valid type; - // see the Sys field for the OS-provided route information to determine - // the exact type. - RouteTypeOther -) - -func (r RouteType) String() string { - switch r { - case RouteTypeUnspecified: - return "unspecified" - case RouteTypeLocal: - return "local" - case RouteTypeUnicast: - return "unicast" - case RouteTypeBroadcast: - return "broadcast" - case RouteTypeMulticast: - return "multicast" - case RouteTypeOther: - return "other" - default: - return "invalid" - } -} diff --git a/vendor/tailscale.com/net/routetable/routetable_bsd.go b/vendor/tailscale.com/net/routetable/routetable_bsd.go deleted file mode 100644 index 1de1a27..0000000 --- a/vendor/tailscale.com/net/routetable/routetable_bsd.go +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin || freebsd - -package routetable - -import ( - "bufio" - "fmt" - "net" - "net/netip" - "runtime" - "sort" - "strings" - "syscall" - - "golang.org/x/net/route" - "golang.org/x/sys/unix" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -type RouteEntryBSD struct { - // GatewayInterface is the name of the interface specified as a gateway - // for this route, if any. - GatewayInterface string - // GatewayIdx is the index of the interface specified as a gateway for - // this route, if any. - GatewayIdx int - // GatewayAddr is the link-layer address of the gateway for this route, - // if any. - GatewayAddr string - // Flags contains a string representation of common flags for this - // route. - Flags []string - // RawFlags contains the raw flags that were returned by the operating - // system for this route. - RawFlags int -} - -// Format implements the fmt.Formatter interface. -func (r RouteEntryBSD) Format(f fmt.State, verb rune) { - logger.ArgWriter(func(w *bufio.Writer) { - var pstart bool - pr := func(format string, args ...any) { - if pstart { - fmt.Fprintf(w, ", "+format, args...) - } else { - fmt.Fprintf(w, format, args...) - pstart = true - } - } - - w.WriteString("{") - if r.GatewayInterface != "" { - pr("GatewayInterface: %s", r.GatewayInterface) - } - if r.GatewayIdx > 0 { - pr("GatewayIdx: %d", r.GatewayIdx) - } - if r.GatewayAddr != "" { - pr("GatewayAddr: %s", r.GatewayAddr) - } - pr("Flags: %v", r.Flags) - - unknownFlags := r.RawFlags - for fv := range flags { - if r.RawFlags&fv == fv { - unknownFlags &= ^fv - } - } - if unknownFlags != 0 { - pr("UnknownFlags: %x ", unknownFlags) - } - - w.WriteString("}") - }).Format(f, verb) -} - -// ipFromRMAddr returns a netip.Addr converted from one of the -// route.Inet{4,6}Addr types. -func ipFromRMAddr(ifs map[int]netmon.Interface, addr any) netip.Addr { - switch v := addr.(type) { - case *route.Inet4Addr: - return netip.AddrFrom4(v.IP) - - case *route.Inet6Addr: - ip := netip.AddrFrom16(v.IP) - if v.ZoneID != 0 { - if iif, ok := ifs[v.ZoneID]; ok { - ip = ip.WithZone(iif.Name) - } else { - ip = ip.WithZone(fmt.Sprint(v.ZoneID)) - } - } - - return ip - } - - return netip.Addr{} -} - -// populateGateway populates gateway fields on a RouteEntry/RouteEntryBSD. -func populateGateway(re *RouteEntry, reSys *RouteEntryBSD, ifs map[int]netmon.Interface, addr any) { - // If the address type has a valid IP, use that. - if ip := ipFromRMAddr(ifs, addr); ip.IsValid() { - re.Gateway = ip - return - } - - switch v := addr.(type) { - case *route.LinkAddr: - reSys.GatewayIdx = v.Index - if iif, ok := ifs[v.Index]; ok { - reSys.GatewayInterface = iif.Name - } - var sb strings.Builder - for i, x := range v.Addr { - if i != 0 { - sb.WriteByte(':') - } - fmt.Fprintf(&sb, "%02x", x) - } - reSys.GatewayAddr = sb.String() - } -} - -// populateDestination populates the 'Dst' field on a RouteEntry based on the -// RouteMessage's destination and netmask fields. -func populateDestination(re *RouteEntry, ifs map[int]netmon.Interface, rm *route.RouteMessage) { - dst := rm.Addrs[unix.RTAX_DST] - if dst == nil { - return - } - - ip := ipFromRMAddr(ifs, dst) - if !ip.IsValid() { - return - } - - if ip.Is4() { - re.Family = 4 - } else { - re.Family = 6 - } - re.Dst = RouteDestination{ - Prefix: netip.PrefixFrom(ip, 32), // default if nothing more specific - } - - // If the RTF_HOST flag is set, then this is a host route and there's - // no netmask in this RouteMessage. - if rm.Flags&unix.RTF_HOST != 0 { - return - } - - // As above if there's no netmask in the list of addrs - if len(rm.Addrs) < unix.RTAX_NETMASK || rm.Addrs[unix.RTAX_NETMASK] == nil { - return - } - - nm := ipFromRMAddr(ifs, rm.Addrs[unix.RTAX_NETMASK]) - if !ip.IsValid() { - return - } - - // Count the number of bits in the netmask IP and use that to make our prefix. - ones, _ /* bits */ := net.IPMask(nm.AsSlice()).Size() - - // Print this ourselves instead of using netip.Prefix so that we don't - // lose the zone (since netip.Prefix strips that). - // - // NOTE(andrew): this doesn't print the same values as the 'netstat' tool - // for some addresses on macOS, and I have no idea why. Specifically, - // 'netstat -rn' will show something like: - // ff00::/8 ::1 UmCI lo0 - // - // But we will get: - // destination=ff00::/40 [...] - // - // The netmask that we get back from FetchRIB has 32 more bits in it - // than netstat prints, but only for multicast routes. - // - // For consistency's sake, we're going to do the same here so that we - // get the same values as netstat returns. - if runtime.GOOS == "darwin" && ip.Is6() && ip.IsMulticast() && ones > 32 { - ones -= 32 - } - re.Dst = RouteDestination{ - Prefix: netip.PrefixFrom(ip, ones), - Zone: ip.Zone(), - } -} - -// routeEntryFromMsg returns a RouteEntry from a single route.Message -// returned by the operating system. -func routeEntryFromMsg(ifsByIdx map[int]netmon.Interface, msg route.Message) (RouteEntry, bool) { - rm, ok := msg.(*route.RouteMessage) - if !ok { - return RouteEntry{}, false - } - - // Ignore things that we don't understand - if rm.Version < 3 || rm.Version > 5 { - return RouteEntry{}, false - } - if rm.Type != rmExpectedType { - return RouteEntry{}, false - } - if len(rm.Addrs) < unix.RTAX_GATEWAY { - return RouteEntry{}, false - } - - if rm.Flags&skipFlags != 0 { - return RouteEntry{}, false - } - - reSys := RouteEntryBSD{ - RawFlags: rm.Flags, - } - for fv, fs := range flags { - if rm.Flags&fv == fv { - reSys.Flags = append(reSys.Flags, fs) - } - } - sort.Strings(reSys.Flags) - - re := RouteEntry{} - hasFlag := func(f int) bool { return rm.Flags&f != 0 } - switch { - case hasFlag(unix.RTF_LOCAL): - re.Type = RouteTypeLocal - case hasFlag(unix.RTF_BROADCAST): - re.Type = RouteTypeBroadcast - case hasFlag(unix.RTF_MULTICAST): - re.Type = RouteTypeMulticast - - // From the manpage: "host entry (net otherwise)" - case !hasFlag(unix.RTF_HOST): - re.Type = RouteTypeUnicast - - default: - re.Type = RouteTypeOther - } - populateDestination(&re, ifsByIdx, rm) - if unix.RTAX_GATEWAY < len(rm.Addrs) { - populateGateway(&re, &reSys, ifsByIdx, rm.Addrs[unix.RTAX_GATEWAY]) - } - - if outif, ok := ifsByIdx[rm.Index]; ok { - re.Interface = outif.Name - } - - re.Sys = reSys - return re, true -} - -// Get returns route entries from the system route table, limited to at most -// 'max' results. -func Get(max int) ([]RouteEntry, error) { - // Fetching the list of interfaces can race with fetching our route - // table, but we do it anyway since it's helpful for debugging. - ifs, err := netmon.GetInterfaceList() - if err != nil { - return nil, err - } - - ifsByIdx := make(map[int]netmon.Interface) - for _, iif := range ifs { - ifsByIdx[iif.Index] = iif - } - - rib, err := route.FetchRIB(syscall.AF_UNSPEC, ribType, 0) - if err != nil { - return nil, err - } - msgs, err := route.ParseRIB(parseType, rib) - if err != nil { - return nil, err - } - - var ret []RouteEntry - for _, m := range msgs { - re, ok := routeEntryFromMsg(ifsByIdx, m) - if ok { - ret = append(ret, re) - if len(ret) == max { - break - } - } - } - return ret, nil -} diff --git a/vendor/tailscale.com/net/routetable/routetable_darwin.go b/vendor/tailscale.com/net/routetable/routetable_darwin.go deleted file mode 100644 index 7f525ae..0000000 --- a/vendor/tailscale.com/net/routetable/routetable_darwin.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin - -package routetable - -import "golang.org/x/sys/unix" - -const ( - ribType = unix.NET_RT_DUMP2 - parseType = unix.NET_RT_IFLIST2 - rmExpectedType = unix.RTM_GET2 - - // Skip routes that were cloned from a parent - skipFlags = unix.RTF_WASCLONED -) - -var flags = map[int]string{ - unix.RTF_BLACKHOLE: "blackhole", - unix.RTF_BROADCAST: "broadcast", - unix.RTF_GATEWAY: "gateway", - unix.RTF_GLOBAL: "global", - unix.RTF_HOST: "host", - unix.RTF_IFSCOPE: "ifscope", - unix.RTF_LOCAL: "local", - unix.RTF_MULTICAST: "multicast", - unix.RTF_REJECT: "reject", - unix.RTF_ROUTER: "router", - unix.RTF_STATIC: "static", - unix.RTF_UP: "up", - // More obscure flags, just to have full coverage. - unix.RTF_LLINFO: "{RTF_LLINFO}", - unix.RTF_PRCLONING: "{RTF_PRCLONING}", - unix.RTF_CLONING: "{RTF_CLONING}", -} diff --git a/vendor/tailscale.com/net/routetable/routetable_freebsd.go b/vendor/tailscale.com/net/routetable/routetable_freebsd.go deleted file mode 100644 index 8e57a33..0000000 --- a/vendor/tailscale.com/net/routetable/routetable_freebsd.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build freebsd - -package routetable - -import "golang.org/x/sys/unix" - -const ( - ribType = unix.NET_RT_DUMP - parseType = unix.NET_RT_IFLIST - rmExpectedType = unix.RTM_GET - - // Nothing to skip - skipFlags = 0 -) - -var flags = map[int]string{ - unix.RTF_BLACKHOLE: "blackhole", - unix.RTF_BROADCAST: "broadcast", - unix.RTF_GATEWAY: "gateway", - unix.RTF_HOST: "host", - unix.RTF_MULTICAST: "multicast", - unix.RTF_REJECT: "reject", - unix.RTF_STATIC: "static", - unix.RTF_UP: "up", -} diff --git a/vendor/tailscale.com/net/routetable/routetable_linux.go b/vendor/tailscale.com/net/routetable/routetable_linux.go deleted file mode 100644 index 88dc853..0000000 --- a/vendor/tailscale.com/net/routetable/routetable_linux.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package routetable - -import ( - "bufio" - "fmt" - "net/netip" - "strconv" - - "github.com/tailscale/netlink" - "golang.org/x/sys/unix" - "tailscale.com/net/netaddr" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -// RouteEntryLinux is the structure that makes up the Sys field of the -// RouteEntry structure. -type RouteEntryLinux struct { - // Type is the raw type of the route. - Type int - // Table is the routing table index of this route. - Table int - // Src is the source of the route (if any). - Src netip.Addr - // Proto describes the source of the route--i.e. what caused this route - // to be added to the route table. - Proto netlink.RouteProtocol - // Priority is the route's priority. - Priority int - // Scope is the route's scope. - Scope int - // InputInterfaceIdx is the input interface index. - InputInterfaceIdx int - // InputInterfaceName is the input interface name (if available). - InputInterfaceName string -} - -// Format implements the fmt.Formatter interface. -func (r RouteEntryLinux) Format(f fmt.State, verb rune) { - logger.ArgWriter(func(w *bufio.Writer) { - // TODO(andrew): should we skip printing anything if type is unicast? - fmt.Fprintf(w, "{Type: %s", r.TypeName()) - - // Match 'ip route' behaviour when printing these fields - if r.Table != unix.RT_TABLE_MAIN { - fmt.Fprintf(w, ", Table: %s", r.TableName()) - } - if r.Proto != unix.RTPROT_BOOT { - fmt.Fprintf(w, ", Proto: %s", r.Proto) - } - - if r.Src.IsValid() { - fmt.Fprintf(w, ", Src: %s", r.Src) - } - if r.Priority != 0 { - fmt.Fprintf(w, ", Priority: %d", r.Priority) - } - if r.Scope != unix.RT_SCOPE_UNIVERSE { - fmt.Fprintf(w, ", Scope: %s", r.ScopeName()) - } - if r.InputInterfaceName != "" { - fmt.Fprintf(w, ", InputInterfaceName: %s", r.InputInterfaceName) - } else if r.InputInterfaceIdx != 0 { - fmt.Fprintf(w, ", InputInterfaceIdx: %d", r.InputInterfaceIdx) - } - w.WriteString("}") - }).Format(f, verb) -} - -// TypeName returns the string representation of this route's Type. -func (r RouteEntryLinux) TypeName() string { - switch r.Type { - case unix.RTN_UNSPEC: - return "none" - case unix.RTN_UNICAST: - return "unicast" - case unix.RTN_LOCAL: - return "local" - case unix.RTN_BROADCAST: - return "broadcast" - case unix.RTN_ANYCAST: - return "anycast" - case unix.RTN_MULTICAST: - return "multicast" - case unix.RTN_BLACKHOLE: - return "blackhole" - case unix.RTN_UNREACHABLE: - return "unreachable" - case unix.RTN_PROHIBIT: - return "prohibit" - case unix.RTN_THROW: - return "throw" - case unix.RTN_NAT: - return "nat" - case unix.RTN_XRESOLVE: - return "xresolve" - default: - return strconv.Itoa(r.Type) - } -} - -// TableName returns the string representation of this route's Table. -func (r RouteEntryLinux) TableName() string { - switch r.Table { - case unix.RT_TABLE_DEFAULT: - return "default" - case unix.RT_TABLE_MAIN: - return "main" - case unix.RT_TABLE_LOCAL: - return "local" - default: - return strconv.Itoa(r.Table) - } -} - -// ScopeName returns the string representation of this route's Scope. -func (r RouteEntryLinux) ScopeName() string { - switch r.Scope { - case unix.RT_SCOPE_UNIVERSE: - return "global" - case unix.RT_SCOPE_NOWHERE: - return "nowhere" - case unix.RT_SCOPE_HOST: - return "host" - case unix.RT_SCOPE_LINK: - return "link" - case unix.RT_SCOPE_SITE: - return "site" - default: - return strconv.Itoa(r.Scope) - } -} - -// Get returns route entries from the system route table, limited to at most -// max results. -func Get(max int) ([]RouteEntry, error) { - // Fetching the list of interfaces can race with fetching our route - // table, but we do it anyway since it's helpful for debugging. - ifs, err := netmon.GetInterfaceList() - if err != nil { - return nil, err - } - - ifsByIdx := make(map[int]netmon.Interface) - for _, iif := range ifs { - ifsByIdx[iif.Index] = iif - } - - filter := &netlink.Route{} - routes, err := netlink.RouteListFiltered(netlink.FAMILY_ALL, filter, netlink.RT_FILTER_TABLE) - if err != nil { - return nil, err - } - - var ret []RouteEntry - for _, route := range routes { - if route.Family != netlink.FAMILY_V4 && route.Family != netlink.FAMILY_V6 { - continue - } - - re := RouteEntry{} - if route.Family == netlink.FAMILY_V4 { - re.Family = 4 - } else { - re.Family = 6 - } - switch route.Type { - case unix.RTN_UNSPEC: - re.Type = RouteTypeUnspecified - case unix.RTN_UNICAST: - re.Type = RouteTypeUnicast - case unix.RTN_LOCAL: - re.Type = RouteTypeLocal - case unix.RTN_BROADCAST: - re.Type = RouteTypeBroadcast - case unix.RTN_MULTICAST: - re.Type = RouteTypeMulticast - default: - re.Type = RouteTypeOther - } - if route.Dst != nil { - if d, ok := netaddr.FromStdIPNet(route.Dst); ok { - re.Dst = RouteDestination{Prefix: d} - } - } else if route.Family == netlink.FAMILY_V4 { - re.Dst = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv4Unspecified(), 0)} - } else { - re.Dst = RouteDestination{Prefix: netip.PrefixFrom(netip.IPv6Unspecified(), 0)} - } - if gw := route.Gw; gw != nil { - if gwa, ok := netip.AddrFromSlice(gw); ok { - re.Gateway = gwa - } - } - if outif, ok := ifsByIdx[route.LinkIndex]; ok { - re.Interface = outif.Name - } else if route.LinkIndex > 0 { - re.Interface = fmt.Sprintf("link#%d", route.LinkIndex) - } - reSys := RouteEntryLinux{ - Type: route.Type, - Table: route.Table, - Proto: route.Protocol, - Priority: route.Priority, - Scope: int(route.Scope), - InputInterfaceIdx: route.ILinkIndex, - } - if src, ok := netip.AddrFromSlice(route.Src); ok { - reSys.Src = src - } - if iif, ok := ifsByIdx[route.ILinkIndex]; ok { - reSys.InputInterfaceName = iif.Name - } - - re.Sys = reSys - ret = append(ret, re) - - // Stop after we've reached the maximum number of routes - if len(ret) == max { - break - } - } - return ret, nil -} diff --git a/vendor/tailscale.com/net/routetable/routetable_other.go b/vendor/tailscale.com/net/routetable/routetable_other.go deleted file mode 100644 index 35c83e3..0000000 --- a/vendor/tailscale.com/net/routetable/routetable_other.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux && !darwin && !freebsd - -package routetable - -import ( - "errors" - "runtime" -) - -var errUnsupported = errors.New("cannot get route table on platform " + runtime.GOOS) - -func Get(max int) ([]RouteEntry, error) { - return nil, errUnsupported -} diff --git a/vendor/tailscale.com/net/sockopts/sockopts.go b/vendor/tailscale.com/net/sockopts/sockopts.go new file mode 100644 index 0000000..0c0ee76 --- /dev/null +++ b/vendor/tailscale.com/net/sockopts/sockopts.go @@ -0,0 +1,37 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package sockopts contains logic for applying socket options. +package sockopts + +import ( + "net" + "runtime" + + "tailscale.com/types/nettype" +) + +// BufferDirection represents either the read/receive or write/send direction +// of a socket buffer. +type BufferDirection string + +const ( + ReadDirection BufferDirection = "read" + WriteDirection BufferDirection = "write" +) + +func portableSetBufferSize(pconn nettype.PacketConn, direction BufferDirection, size int) error { + if runtime.GOOS == "plan9" { + // Not supported. Don't try. Avoid logspam. + return nil + } + var err error + if c, ok := pconn.(*net.UDPConn); ok { + if direction == WriteDirection { + err = c.SetWriteBuffer(size) + } else { + err = c.SetReadBuffer(size) + } + } + return err +} diff --git a/vendor/tailscale.com/net/sockopts/sockopts_default.go b/vendor/tailscale.com/net/sockopts/sockopts_default.go new file mode 100644 index 0000000..3cc8679 --- /dev/null +++ b/vendor/tailscale.com/net/sockopts/sockopts_default.go @@ -0,0 +1,21 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !linux + +package sockopts + +import ( + "tailscale.com/types/nettype" +) + +// SetBufferSize sets pconn's buffer to size for direction. size may be silently +// capped depending on platform. +// +// errForce is only relevant for Linux, and will always be nil otherwise, +// but we maintain a consistent cross-platform API. +// +// If pconn is not a [*net.UDPConn], then SetBufferSize is no-op. +func SetBufferSize(pconn nettype.PacketConn, direction BufferDirection, size int) (errForce error, errPortable error) { + return nil, portableSetBufferSize(pconn, direction, size) +} diff --git a/vendor/tailscale.com/net/sockopts/sockopts_linux.go b/vendor/tailscale.com/net/sockopts/sockopts_linux.go new file mode 100644 index 0000000..5d778d3 --- /dev/null +++ b/vendor/tailscale.com/net/sockopts/sockopts_linux.go @@ -0,0 +1,40 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build linux + +package sockopts + +import ( + "net" + "syscall" + + "tailscale.com/types/nettype" +) + +// SetBufferSize sets pconn's buffer to size for direction. It attempts +// (errForce) to set SO_SNDBUFFORCE or SO_RECVBUFFORCE which can overcome the +// limit of net.core.{r,w}mem_max, but require CAP_NET_ADMIN. It falls back to +// the portable implementation (errPortable) if that fails, which may be +// silently capped to net.core.{r,w}mem_max. +// +// If pconn is not a [*net.UDPConn], then SetBufferSize is no-op. +func SetBufferSize(pconn nettype.PacketConn, direction BufferDirection, size int) (errForce error, errPortable error) { + opt := syscall.SO_RCVBUFFORCE + if direction == WriteDirection { + opt = syscall.SO_SNDBUFFORCE + } + if c, ok := pconn.(*net.UDPConn); ok { + var rc syscall.RawConn + rc, errForce = c.SyscallConn() + if errForce == nil { + rc.Control(func(fd uintptr) { + errForce = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, opt, size) + }) + } + if errForce != nil { + errPortable = portableSetBufferSize(pconn, direction, size) + } + } + return errForce, errPortable +} diff --git a/vendor/tailscale.com/wgengine/magicsock/magicsock_notwindows.go b/vendor/tailscale.com/net/sockopts/sockopts_notwindows.go similarity index 52% rename from vendor/tailscale.com/wgengine/magicsock/magicsock_notwindows.go rename to vendor/tailscale.com/net/sockopts/sockopts_notwindows.go index 7c31c82..f1bc7fd 100644 --- a/vendor/tailscale.com/wgengine/magicsock/magicsock_notwindows.go +++ b/vendor/tailscale.com/net/sockopts/sockopts_notwindows.go @@ -3,11 +3,13 @@ //go:build !windows -package magicsock +package sockopts import ( - "tailscale.com/types/logger" "tailscale.com/types/nettype" ) -func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) {} +// SetICMPErrImmunity is no-op on non-Windows. +func SetICMPErrImmunity(pconn nettype.PacketConn) error { + return nil +} diff --git a/vendor/tailscale.com/wgengine/magicsock/magicsock_windows.go b/vendor/tailscale.com/net/sockopts/sockopts_windows.go similarity index 67% rename from vendor/tailscale.com/wgengine/magicsock/magicsock_windows.go rename to vendor/tailscale.com/net/sockopts/sockopts_windows.go index fe2a80e..1e6c3f6 100644 --- a/vendor/tailscale.com/wgengine/magicsock/magicsock_windows.go +++ b/vendor/tailscale.com/net/sockopts/sockopts_windows.go @@ -3,28 +3,31 @@ //go:build windows -package magicsock +package sockopts import ( + "fmt" "net" "unsafe" "golang.org/x/sys/windows" - "tailscale.com/types/logger" "tailscale.com/types/nettype" ) -func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) { +// SetICMPErrImmunity sets socket options on pconn to prevent ICMP reception, +// e.g. ICMP Port Unreachable, from surfacing as a syscall error. +// +// If pconn is not a [*net.UDPConn], then SetICMPErrImmunity is no-op. +func SetICMPErrImmunity(pconn nettype.PacketConn) error { c, ok := pconn.(*net.UDPConn) if !ok { // not a UDP connection; nothing to do - return + return nil } sysConn, err := c.SyscallConn() if err != nil { - logf("trySetUDPSocketOptions: getting SyscallConn failed: %v", err) - return + return fmt.Errorf("SetICMPErrImmunity: getting SyscallConn failed: %v", err) } // Similar to https://github.com/golang/go/issues/5834 (which involved @@ -50,9 +53,10 @@ func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) { ) }) if ioctlErr != nil { - logf("trySetUDPSocketOptions: could not set SIO_UDP_NETRESET: %v", ioctlErr) + return fmt.Errorf("SetICMPErrImmunity: could not set SIO_UDP_NETRESET: %v", ioctlErr) } if err != nil { - logf("trySetUDPSocketOptions: SyscallConn.Control failed: %v", err) + return fmt.Errorf("SetICMPErrImmunity: SyscallConn.Control failed: %v", err) } + return nil } diff --git a/vendor/tailscale.com/net/socks5/socks5.go b/vendor/tailscale.com/net/socks5/socks5.go index 4a5befa..2e27714 100644 --- a/vendor/tailscale.com/net/socks5/socks5.go +++ b/vendor/tailscale.com/net/socks5/socks5.go @@ -120,10 +120,10 @@ func (s *Server) logf(format string, args ...any) { } // Serve accepts and handles incoming connections on the given listener. -func (s *Server) Serve(l net.Listener) error { - defer l.Close() +func (s *Server) Serve(ln net.Listener) error { + defer ln.Close() for { - c, err := l.Accept() + c, err := ln.Accept() if err != nil { return err } diff --git a/vendor/tailscale.com/net/sockstats/label_string.go b/vendor/tailscale.com/net/sockstats/label_string.go index f9a111a..cc503d9 100644 --- a/vendor/tailscale.com/net/sockstats/label_string.go +++ b/vendor/tailscale.com/net/sockstats/label_string.go @@ -28,8 +28,9 @@ const _Label_name = "ControlClientAutoControlClientDialerDERPHTTPClientLogtailLo var _Label_index = [...]uint8{0, 17, 36, 50, 63, 78, 93, 107, 123, 140, 157, 169, 186, 201} func (i Label) String() string { - if i >= Label(len(_Label_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_Label_index)-1 { return "Label(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Label_name[_Label_index[i]:_Label_index[i+1]] + return _Label_name[_Label_index[idx]:_Label_index[idx+1]] } diff --git a/vendor/tailscale.com/net/sockstats/sockstats_tsgo.go b/vendor/tailscale.com/net/sockstats/sockstats_tsgo.go index fec9ec3..4e9f4a9 100644 --- a/vendor/tailscale.com/net/sockstats/sockstats_tsgo.go +++ b/vendor/tailscale.com/net/sockstats/sockstats_tsgo.go @@ -10,12 +10,12 @@ import ( "fmt" "net" "strings" - "sync" "sync/atomic" "syscall" "time" "tailscale.com/net/netmon" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/util/clientmetric" "tailscale.com/version" @@ -40,7 +40,7 @@ var sockStats = struct { // mu protects fields in this group (but not the fields within // sockStatCounters). It should not be held in the per-read/write // callbacks. - mu sync.Mutex + mu syncs.Mutex countersByLabel map[Label]*sockStatCounters knownInterfaces map[int]string // interface index -> name usedInterfaces map[int]int // set of interface indexes @@ -271,10 +271,10 @@ func setNetMon(netMon *netmon.Monitor) { } netMon.RegisterChangeCallback(func(delta *netmon.ChangeDelta) { - if !delta.Major { + if !delta.RebindLikelyRequired { return } - state := delta.New + state := delta.CurrentState() ifName := state.DefaultRouteInterface if ifName == "" { return diff --git a/vendor/tailscale.com/net/tcpinfo/tcpinfo.go b/vendor/tailscale.com/net/tcpinfo/tcpinfo.go deleted file mode 100644 index a757add..0000000 --- a/vendor/tailscale.com/net/tcpinfo/tcpinfo.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package tcpinfo provides platform-agnostic accessors to information about a -// TCP connection (e.g. RTT, MSS, etc.). -package tcpinfo - -import ( - "errors" - "net" - "time" -) - -var ( - ErrNotTCP = errors.New("tcpinfo: not a TCP conn") - ErrUnimplemented = errors.New("tcpinfo: unimplemented") -) - -// RTT returns the RTT for the given net.Conn. -// -// If the net.Conn is not a *net.TCPConn and cannot be unwrapped into one, then -// ErrNotTCP will be returned. If retrieving the RTT is not supported on the -// current platform, ErrUnimplemented will be returned. -func RTT(conn net.Conn) (time.Duration, error) { - tcpConn, err := unwrap(conn) - if err != nil { - return 0, err - } - - return rttImpl(tcpConn) -} - -// netConner is implemented by crypto/tls.Conn to unwrap into an underlying -// net.Conn. -type netConner interface { - NetConn() net.Conn -} - -// unwrap attempts to unwrap a net.Conn into an underlying *net.TCPConn -func unwrap(nc net.Conn) (*net.TCPConn, error) { - for { - switch v := nc.(type) { - case *net.TCPConn: - return v, nil - case netConner: - nc = v.NetConn() - default: - return nil, ErrNotTCP - } - } -} diff --git a/vendor/tailscale.com/net/tcpinfo/tcpinfo_darwin.go b/vendor/tailscale.com/net/tcpinfo/tcpinfo_darwin.go deleted file mode 100644 index 53fa22f..0000000 --- a/vendor/tailscale.com/net/tcpinfo/tcpinfo_darwin.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package tcpinfo - -import ( - "net" - "time" - - "golang.org/x/sys/unix" -) - -func rttImpl(conn *net.TCPConn) (time.Duration, error) { - rawConn, err := conn.SyscallConn() - if err != nil { - return 0, err - } - - var ( - tcpInfo *unix.TCPConnectionInfo - sysErr error - ) - err = rawConn.Control(func(fd uintptr) { - tcpInfo, sysErr = unix.GetsockoptTCPConnectionInfo(int(fd), unix.IPPROTO_TCP, unix.TCP_CONNECTION_INFO) - }) - if err != nil { - return 0, err - } else if sysErr != nil { - return 0, sysErr - } - - return time.Duration(tcpInfo.Rttcur) * time.Millisecond, nil -} diff --git a/vendor/tailscale.com/net/tcpinfo/tcpinfo_linux.go b/vendor/tailscale.com/net/tcpinfo/tcpinfo_linux.go deleted file mode 100644 index 885d462..0000000 --- a/vendor/tailscale.com/net/tcpinfo/tcpinfo_linux.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package tcpinfo - -import ( - "net" - "time" - - "golang.org/x/sys/unix" -) - -func rttImpl(conn *net.TCPConn) (time.Duration, error) { - rawConn, err := conn.SyscallConn() - if err != nil { - return 0, err - } - - var ( - tcpInfo *unix.TCPInfo - sysErr error - ) - err = rawConn.Control(func(fd uintptr) { - tcpInfo, sysErr = unix.GetsockoptTCPInfo(int(fd), unix.IPPROTO_TCP, unix.TCP_INFO) - }) - if err != nil { - return 0, err - } else if sysErr != nil { - return 0, sysErr - } - - return time.Duration(tcpInfo.Rtt) * time.Microsecond, nil -} diff --git a/vendor/tailscale.com/net/tcpinfo/tcpinfo_other.go b/vendor/tailscale.com/net/tcpinfo/tcpinfo_other.go deleted file mode 100644 index be45523..0000000 --- a/vendor/tailscale.com/net/tcpinfo/tcpinfo_other.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux && !darwin - -package tcpinfo - -import ( - "net" - "time" -) - -func rttImpl(conn *net.TCPConn) (time.Duration, error) { - return 0, ErrUnimplemented -} diff --git a/vendor/tailscale.com/net/tlsdial/blockblame/blockblame.go b/vendor/tailscale.com/net/tlsdial/blockblame/blockblame.go index 57dc7a6..5b48dc0 100644 --- a/vendor/tailscale.com/net/tlsdial/blockblame/blockblame.go +++ b/vendor/tailscale.com/net/tlsdial/blockblame/blockblame.go @@ -9,13 +9,19 @@ package blockblame import ( "crypto/x509" "strings" + "sync" + + "tailscale.com/feature/buildfeatures" ) // VerifyCertificate checks if the given certificate c is issued by a firewall manufacturer // that is known to block Tailscale connections. It returns true and the Manufacturer of // the equipment if it is, or false and nil if it is not. func VerifyCertificate(c *x509.Certificate) (m *Manufacturer, ok bool) { - for _, m := range Manufacturers { + if !buildfeatures.HasDebug { + return nil, false + } + for _, m := range manufacturers() { if m.match != nil && m.match(c) { return m, true } @@ -33,46 +39,56 @@ type Manufacturer struct { match matchFunc } -var Manufacturers = []*Manufacturer{ - { - Name: "Aruba Networks", - match: issuerContains("Aruba"), - }, - { - Name: "Cisco", - match: issuerContains("Cisco"), - }, - { - Name: "Fortinet", - match: matchAny( - issuerContains("Fortinet"), - certEmail("support@fortinet.com"), - ), - }, - { - Name: "Huawei", - match: certEmail("mobile@huawei.com"), - }, - { - Name: "Palo Alto Networks", - match: matchAny( - issuerContains("Palo Alto Networks"), - issuerContains("PAN-FW"), - ), - }, - { - Name: "Sophos", - match: issuerContains("Sophos"), - }, - { - Name: "Ubiquiti", - match: matchAny( - issuerContains("UniFi"), - issuerContains("Ubiquiti"), - ), - }, +func manufacturers() []*Manufacturer { + manufacturersOnce.Do(func() { + manufacturersList = []*Manufacturer{ + { + Name: "Aruba Networks", + match: issuerContains("Aruba"), + }, + { + Name: "Cisco", + match: issuerContains("Cisco"), + }, + { + Name: "Fortinet", + match: matchAny( + issuerContains("Fortinet"), + certEmail("support@fortinet.com"), + ), + }, + { + Name: "Huawei", + match: certEmail("mobile@huawei.com"), + }, + { + Name: "Palo Alto Networks", + match: matchAny( + issuerContains("Palo Alto Networks"), + issuerContains("PAN-FW"), + ), + }, + { + Name: "Sophos", + match: issuerContains("Sophos"), + }, + { + Name: "Ubiquiti", + match: matchAny( + issuerContains("UniFi"), + issuerContains("Ubiquiti"), + ), + }, + } + }) + return manufacturersList } +var ( + manufacturersOnce sync.Once + manufacturersList []*Manufacturer +) + type matchFunc func(*x509.Certificate) bool func issuerContains(s string) matchFunc { diff --git a/vendor/tailscale.com/net/tlsdial/tlsdial.go b/vendor/tailscale.com/net/tlsdial/tlsdial.go index 4d22383..ee4771d 100644 --- a/vendor/tailscale.com/net/tlsdial/tlsdial.go +++ b/vendor/tailscale.com/net/tlsdial/tlsdial.go @@ -21,11 +21,14 @@ import ( "net" "net/http" "os" + "strings" "sync" "sync/atomic" "time" + "tailscale.com/derp/derpconst" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/hostinfo" "tailscale.com/net/bakedroots" @@ -34,12 +37,6 @@ import ( var counterFallbackOK int32 // atomic -// If SSLKEYLOGFILE is set, it's a file to which we write our TLS private keys -// in a way that WireShark can read. -// -// See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format -var sslKeyLogFile = os.Getenv("SSLKEYLOGFILE") - var debug = envknob.RegisterBool("TS_DEBUG_TLS_DIAL") // tlsdialWarningPrinted tracks whether we've printed a warning about a given @@ -57,26 +54,40 @@ var mitmBlockWarnable = health.Register(&health.Warnable{ ImpactsConnectivity: true, }) -// Config returns a tls.Config for connecting to a server. +// Config returns a tls.Config for connecting to a server that +// uses system roots for validation but, if those fail, also tries +// the baked-in LetsEncrypt roots as a fallback validation method. +// // If base is non-nil, it's cloned as the base config before // being configured and returned. // If ht is non-nil, it's used to report health errors. -func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { +func Config(ht *health.Tracker, base *tls.Config) *tls.Config { var conf *tls.Config if base == nil { conf = new(tls.Config) } else { conf = base.Clone() } - conf.ServerName = host - if n := sslKeyLogFile; n != "" { - f, err := os.OpenFile(n, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) - if err != nil { - log.Fatal(err) + // Note: we do NOT set conf.ServerName here (as we accidentally did + // previously), as this path is also used when dialing an HTTPS proxy server + // (through which we'll send a CONNECT request to get a TCP connection to do + // the real TCP connection) because host is the ultimate hostname, but this + // tls.Config is used for both the proxy and the ultimate target. + + if buildfeatures.HasDebug { + // If SSLKEYLOGFILE is set, it's a file to which we write our TLS private keys + // in a way that WireShark can read. + // + // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format + if n := os.Getenv("SSLKEYLOGFILE"); n != "" { + f, err := os.OpenFile(n, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) + if err != nil { + log.Fatal(err) + } + log.Printf("WARNING: writing to SSLKEYLOGFILE %v", n) + conf.KeyLogWriter = f } - log.Printf("WARNING: writing to SSLKEYLOGFILE %v", n) - conf.KeyLogWriter = f } if conf.InsecureSkipVerify { @@ -91,7 +102,9 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { // (with the baked-in fallback root) in the VerifyConnection hook. conf.InsecureSkipVerify = true conf.VerifyConnection = func(cs tls.ConnectionState) (retErr error) { - if host == "log.tailscale.com" && hostinfo.IsNATLabGuestVM() { + dialedHost := cs.ServerName + + if dialedHost == "log.tailscale.com" && hostinfo.IsNATLabGuestVM() { // Allow log.tailscale.com TLS MITM for integration tests when // the client's running within a NATLab VM. return nil @@ -114,7 +127,7 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { // Show a dedicated warning. m, ok := blockblame.VerifyCertificate(cert) if ok { - log.Printf("tlsdial: server cert for %q looks like %q equipment (could be blocking Tailscale)", host, m.Name) + log.Printf("tlsdial: server cert seen while dialing %q looks like %q equipment (could be blocking Tailscale)", dialedHost, m.Name) ht.SetUnhealthy(mitmBlockWarnable, health.Args{"manufacturer": m.Name}) } else { ht.SetHealthy(mitmBlockWarnable) @@ -133,7 +146,7 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { ht.SetTLSConnectionError(cs.ServerName, nil) if selfSignedIssuer != "" { // Log the self-signed issuer, but don't treat it as an error. - log.Printf("tlsdial: warning: server cert for %q passed x509 validation but is self-signed by %q", host, selfSignedIssuer) + log.Printf("tlsdial: warning: server cert for %q passed x509 validation but is self-signed by %q", dialedHost, selfSignedIssuer) } } }() @@ -142,7 +155,7 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { // First try doing x509 verification with the system's // root CA pool. opts := x509.VerifyOptions{ - DNSName: cs.ServerName, + DNSName: dialedHost, Intermediates: x509.NewCertPool(), } for _, cert := range cs.PeerCertificates[1:] { @@ -150,22 +163,22 @@ func Config(host string, ht *health.Tracker, base *tls.Config) *tls.Config { } _, errSys := cs.PeerCertificates[0].Verify(opts) if debug() { - log.Printf("tlsdial(sys %q): %v", host, errSys) + log.Printf("tlsdial(sys %q): %v", dialedHost, errSys) + } + if !buildfeatures.HasBakedRoots || (errSys == nil && !debug()) { + return errSys } - // Always verify with our baked-in Let's Encrypt certificate, - // so we can log an informational message. This is useful for - // detecting SSL MiTM. + // If we have baked-in LetsEncrypt roots and we either failed above, or + // debug logging is enabled, also verify with LetsEncrypt. opts.Roots = bakedroots.Get() _, bakedErr := cs.PeerCertificates[0].Verify(opts) if debug() { - log.Printf("tlsdial(bake %q): %v", host, bakedErr) + log.Printf("tlsdial(bake %q): %v", dialedHost, bakedErr) } else if bakedErr != nil { - if _, loaded := tlsdialWarningPrinted.LoadOrStore(host, true); !loaded { - if errSys == nil { - log.Printf("tlsdial: warning: server cert for %q is not a Let's Encrypt cert", host) - } else { - log.Printf("tlsdial: error: server cert for %q failed to verify and is not a Let's Encrypt cert", host) + if _, loaded := tlsdialWarningPrinted.LoadOrStore(dialedHost, true); !loaded { + if errSys != nil { + log.Printf("tlsdial: error: server cert for %q failed both system roots & Let's Encrypt root validation", dialedHost) } } } @@ -200,9 +213,6 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) { c.ServerName = certDNSName return } - if c.VerifyPeerCertificate != nil { - panic("refusing to override tls.Config.VerifyPeerCertificate") - } // Set InsecureSkipVerify to prevent crypto/tls from doing its // own cert verification, but do the same work that it'd do // (but using certDNSName) in the VerifyPeerCertificate hook. @@ -232,8 +242,8 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) { if debug() { log.Printf("tlsdial(sys %q/%q): %v", c.ServerName, certDNSName, errSys) } - if errSys == nil { - return nil + if !buildfeatures.HasBakedRoots || errSys == nil { + return errSys } opts.Roots = bakedroots.Get() _, err := certs[0].Verify(opts) @@ -247,41 +257,50 @@ func SetConfigExpectedCert(c *tls.Config, certDNSName string) { } } -// SetConfigExpectedCertHash configures c's VerifyPeerCertificate function -// to require that exactly 1 cert is presented, and that the hex of its SHA256 hash -// is equal to wantFullCertSHA256Hex and that it's a valid cert for c.ServerName. +// SetConfigExpectedCertHash configures c's VerifyPeerCertificate function to +// require that exactly 1 cert is presented (not counting any present MetaCert), +// and that the hex of its SHA256 hash is equal to wantFullCertSHA256Hex and +// that it's a valid cert for c.ServerName. func SetConfigExpectedCertHash(c *tls.Config, wantFullCertSHA256Hex string) { if c.VerifyPeerCertificate != nil { panic("refusing to override tls.Config.VerifyPeerCertificate") } + // Set InsecureSkipVerify to prevent crypto/tls from doing its // own cert verification, but do the same work that it'd do - // (but using certDNSName) in the VerifyPeerCertificate hook. + // (but using certDNSName) in the VerifyConnection hook. c.InsecureSkipVerify = true - c.VerifyConnection = nil - c.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { - if len(rawCerts) == 0 { - return errors.New("no certs presented") + + c.VerifyConnection = func(cs tls.ConnectionState) error { + dialedHost := cs.ServerName + var sawGoodCert bool + + for _, cert := range cs.PeerCertificates { + if strings.HasPrefix(cert.Subject.CommonName, derpconst.MetaCertCommonNamePrefix) { + continue + } + if sawGoodCert { + return errors.New("unexpected multiple certs presented") + } + if fmt.Sprintf("%02x", sha256.Sum256(cert.Raw)) != wantFullCertSHA256Hex { + return fmt.Errorf("cert hash does not match expected cert hash") + } + if dialedHost != "" { // it's empty when dialing a derper by IP with no hostname + if err := cert.VerifyHostname(dialedHost); err != nil { + return fmt.Errorf("cert does not match server name %q: %w", dialedHost, err) + } + } + now := time.Now() + if now.After(cert.NotAfter) { + return fmt.Errorf("cert expired %v", cert.NotAfter) + } + if now.Before(cert.NotBefore) { + return fmt.Errorf("cert not yet valid until %v; is your clock correct?", cert.NotBefore) + } + sawGoodCert = true } - if len(rawCerts) > 1 { - return errors.New("unexpected multiple certs presented") - } - if fmt.Sprintf("%02x", sha256.Sum256(rawCerts[0])) != wantFullCertSHA256Hex { - return fmt.Errorf("cert hash does not match expected cert hash") - } - cert, err := x509.ParseCertificate(rawCerts[0]) - if err != nil { - return fmt.Errorf("ParseCertificate: %w", err) - } - if err := cert.VerifyHostname(c.ServerName); err != nil { - return fmt.Errorf("cert does not match server name %q: %w", c.ServerName, err) - } - now := time.Now() - if now.After(cert.NotAfter) { - return fmt.Errorf("cert expired %v", cert.NotAfter) - } - if now.Before(cert.NotBefore) { - return fmt.Errorf("cert not yet valid until %v; is your clock correct?", cert.NotBefore) + if !sawGoodCert { + return errors.New("expected cert not presented") } return nil } @@ -292,12 +311,8 @@ func SetConfigExpectedCertHash(c *tls.Config, wantFullCertSHA256Hex string) { func NewTransport() *http.Transport { return &http.Transport{ DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } var d tls.Dialer - d.Config = Config(host, nil, nil) + d.Config = Config(nil, nil) return d.DialContext(ctx, network, addr) }, } diff --git a/vendor/tailscale.com/net/tsdial/dnsmap.go b/vendor/tailscale.com/net/tsdial/dnsmap.go index 2ef1cb1..37fedd1 100644 --- a/vendor/tailscale.com/net/tsdial/dnsmap.go +++ b/vendor/tailscale.com/net/tsdial/dnsmap.go @@ -36,11 +36,11 @@ func dnsMapFromNetworkMap(nm *netmap.NetworkMap) dnsMap { suffix := nm.MagicDNSSuffix() have4 := false addrs := nm.GetAddresses() - if nm.Name != "" && addrs.Len() > 0 { + if name := nm.SelfName(); name != "" && addrs.Len() > 0 { ip := addrs.At(0).Addr() - ret[canonMapKey(nm.Name)] = ip - if dnsname.HasSuffix(nm.Name, suffix) { - ret[canonMapKey(dnsname.TrimSuffix(nm.Name, suffix))] = ip + ret[canonMapKey(name)] = ip + if dnsname.HasSuffix(name, suffix) { + ret[canonMapKey(dnsname.TrimSuffix(name, suffix))] = ip } for _, p := range addrs.All() { if p.Addr().Is4() { diff --git a/vendor/tailscale.com/net/tsdial/tsdial.go b/vendor/tailscale.com/net/tsdial/tsdial.go index 3606dd6..df2d80a 100644 --- a/vendor/tailscale.com/net/tsdial/tsdial.go +++ b/vendor/tailscale.com/net/tsdial/tsdial.go @@ -19,14 +19,19 @@ import ( "time" "github.com/gaissmai/bart" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/dnscache" "tailscale.com/net/netknob" "tailscale.com/net/netmon" "tailscale.com/net/netns" + "tailscale.com/net/netx" "tailscale.com/net/tsaddr" + "tailscale.com/syncs" "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" "tailscale.com/util/testenv" "tailscale.com/version" @@ -43,6 +48,13 @@ func NewDialer(netMon *netmon.Monitor) *Dialer { return d } +// NewFromFuncForDebug is like NewDialer but takes a netx.DialFunc +// and no netMon. It's meant exclusively for the "tailscale debug ts2021" +// debug command, and perhaps tests. +func NewFromFuncForDebug(logf logger.Logf, dial netx.DialFunc) *Dialer { + return &Dialer{sysDialForTest: dial, Logf: logf} +} + // Dialer dials out of tailscaled, while taking care of details while // handling the dozens of edge cases depending on the server mode // (TUN, netstack), the OS network sandboxing style (macOS/iOS @@ -71,10 +83,11 @@ type Dialer struct { netnsDialerOnce sync.Once netnsDialer netns.Dialer + sysDialForTest netx.DialFunc // or nil routes atomic.Pointer[bart.Table[bool]] // or nil if UserDial should not use routes. `true` indicates routes that point into the Tailscale interface - mu sync.Mutex + mu syncs.Mutex closed bool dns dnsMap tunName string // tun device name @@ -84,6 +97,9 @@ type Dialer struct { dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH nextSysConnID int activeSysConns map[int]net.Conn // active connections not yet closed + bus *eventbus.Bus // only used for comparison with already set bus. + eventClient *eventbus.Client + eventBusSubs eventbus.Monitor } // sysConn wraps a net.Conn that was created using d.SystemDial. @@ -123,6 +139,9 @@ func (d *Dialer) TUNName() string { // // For example, "http://100.68.82.120:47830/dns-query". func (d *Dialer) SetExitDNSDoH(doh string) { + if !buildfeatures.HasUseExitNode { + return + } d.mu.Lock() defer d.mu.Unlock() if d.exitDNSDoHBase == doh { @@ -149,12 +168,16 @@ func (d *Dialer) SetRoutes(routes, localRoutes []netip.Prefix) { for _, r := range localRoutes { rt.Insert(r, false) } + d.logf("tsdial: bart table size: %d", rt.Size()) } d.routes.Store(rt) } func (d *Dialer) Close() error { + if d.eventClient != nil { + d.eventBusSubs.Close() + } d.mu.Lock() defer d.mu.Unlock() d.closed = true @@ -183,6 +206,14 @@ func (d *Dialer) SetNetMon(netMon *netmon.Monitor) { d.netMonUnregister = nil } d.netMon = netMon + // Having multiple watchers could lead to problems, + // so remove the eventClient if it exists. + // This should really not happen, but better checking for it than not. + // TODO(cmol): Should this just be a panic? + if d.eventClient != nil { + d.eventBusSubs.Close() + d.eventClient = nil + } d.netMonUnregister = d.netMon.RegisterChangeCallback(d.linkChanged) } @@ -194,6 +225,38 @@ func (d *Dialer) NetMon() *netmon.Monitor { return d.netMon } +func (d *Dialer) SetBus(bus *eventbus.Bus) { + d.mu.Lock() + defer d.mu.Unlock() + if d.bus == bus { + return + } else if d.bus != nil { + panic("different eventbus has already been set") + } + // Having multiple watchers could lead to problems, + // so unregister the callback if it exists. + if d.netMonUnregister != nil { + d.netMonUnregister() + } + d.bus = bus + d.eventClient = bus.Client("tsdial.Dialer") + d.eventBusSubs = d.eventClient.Monitor(d.linkChangeWatcher(d.eventClient)) +} + +func (d *Dialer) linkChangeWatcher(ec *eventbus.Client) func(*eventbus.Client) { + linkChangeSub := eventbus.Subscribe[netmon.ChangeDelta](ec) + return func(ec *eventbus.Client) { + for { + select { + case <-ec.Done(): + return + case cd := <-linkChangeSub.Events(): + d.linkChanged(&cd) + } + } + } +} + var ( metricLinkChangeConnClosed = clientmetric.NewCounter("tsdial_linkchange_closes") metricChangeDeltaNoDefaultRoute = clientmetric.NewCounter("tsdial_changedelta_no_default_route") @@ -201,7 +264,7 @@ var ( func (d *Dialer) linkChanged(delta *netmon.ChangeDelta) { // Track how often we see ChangeDeltas with no DefaultRouteInterface. - if delta.New.DefaultRouteInterface == "" { + if delta.DefaultRouteInterface == "" { metricChangeDeltaNoDefaultRoute.Add(1) } @@ -231,22 +294,23 @@ func changeAffectsConn(delta *netmon.ChangeDelta, conn net.Conn) bool { } lip, rip := la.AddrPort().Addr(), ra.AddrPort().Addr() - if delta.Old == nil { + if delta.IsInitialState { return false } - if delta.Old.DefaultRouteInterface != delta.New.DefaultRouteInterface || - delta.Old.HTTPProxy != delta.New.HTTPProxy { + + if delta.DefaultInterfaceChanged || + delta.HasPACOrProxyConfigChanged { return true } // In a few cases, we don't have a new DefaultRouteInterface (e.g. on - // Android; see tailscale/corp#19124); if so, pessimistically assume + // Android and macOS/iOS; see tailscale/corp#19124); if so, pessimistically assume // that all connections are affected. - if delta.New.DefaultRouteInterface == "" { + if delta.DefaultRouteInterface == "" && runtime.GOOS != "plan9" { return true } - if !delta.New.HasIP(lip) && delta.Old.HasIP(lip) { + if delta.InterfaceIPDisappeared(lip) { // Our interface with this source IP went away. return true } @@ -319,7 +383,7 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net } var r net.Resolver - if exitDNSDoH != "" && runtime.GOOS != "windows" { // Windows: https://github.com/golang/go/issues/33097 + if buildfeatures.HasUseExitNode && buildfeatures.HasPeerAPIClient && exitDNSDoH != "" { r.PreferGo = true r.Dial = func(ctx context.Context, network, address string) (net.Conn, error) { return &dohConn{ @@ -361,13 +425,20 @@ func (d *Dialer) logf(format string, args ...any) { } } +// SetSystemDialerForTest sets an alternate function to use for SystemDial +// instead of netns.Dialer. This is intended for use with nettest.MemoryNetwork. +func (d *Dialer) SetSystemDialerForTest(fn netx.DialFunc) { + testenv.AssertInTest() + d.sysDialForTest = fn +} + // SystemDial connects to the provided network address without going over // Tailscale. It prefers going over the default interface and closes existing // connections if the default interface changes. It is used to connect to // Control and (in the future, as of 2022-04-27) DERPs.. func (d *Dialer) SystemDial(ctx context.Context, network, addr string) (net.Conn, error) { d.mu.Lock() - if d.netMon == nil { + if d.netMon == nil && d.sysDialForTest == nil { d.mu.Unlock() if testenv.InTest() { panic("SystemDial requires a netmon.Monitor; call SetNetMon first") @@ -380,10 +451,16 @@ func (d *Dialer) SystemDial(ctx context.Context, network, addr string) (net.Conn return nil, net.ErrClosed } - d.netnsDialerOnce.Do(func() { - d.netnsDialer = netns.NewDialer(d.logf, d.netMon) - }) - c, err := d.netnsDialer.DialContext(ctx, network, addr) + var c net.Conn + var err error + if d.sysDialForTest != nil { + c, err = d.sysDialForTest(ctx, network, addr) + } else { + d.netnsDialerOnce.Do(func() { + d.netnsDialer = netns.NewDialer(d.logf, d.netMon) + }) + c, err = d.netnsDialer.DialContext(ctx, network, addr) + } if err != nil { return nil, err } @@ -443,6 +520,9 @@ func (d *Dialer) UserDial(ctx context.Context, network, addr string) (net.Conn, // network must a "tcp" type, and addr must be an ip:port. Name resolution // is not supported. func (d *Dialer) dialPeerAPI(ctx context.Context, network, addr string) (net.Conn, error) { + if !buildfeatures.HasPeerAPIClient { + return nil, feature.ErrUnavailable + } switch network { case "tcp", "tcp6", "tcp4": default: @@ -485,6 +565,9 @@ func (d *Dialer) getPeerDialer() *net.Dialer { // The returned Client must not be mutated; it's owned by the Dialer // and shared by callers. func (d *Dialer) PeerAPIHTTPClient() *http.Client { + if !buildfeatures.HasPeerAPIClient { + panic("unreachable") + } d.peerClientOnce.Do(func() { t := http.DefaultTransport.(*http.Transport).Clone() t.Dial = nil diff --git a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy.go b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy.go index 2ca440b..0456009 100644 --- a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy.go +++ b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy.go @@ -7,6 +7,7 @@ package tshttpproxy import ( "context" + "errors" "fmt" "log" "net" @@ -38,6 +39,23 @@ var ( proxyFunc func(*url.URL) (*url.URL, error) ) +// SetProxyFunc can be used by clients to set a platform-specific function for proxy resolution. +// If config is set when this function is called, an error will be returned. +// The provided function should return a proxy URL for the given request URL, +// nil if no proxy is enabled for the request URL, or an error if proxy settings cannot be resolved. +func SetProxyFunc(fn func(*url.URL) (*url.URL, error)) error { + mu.Lock() + defer mu.Unlock() + + // Allow override only if config is not set + if config != nil { + return errors.New("tshttpproxy: SetProxyFunc can only be called when config is not set") + } + + proxyFunc = fn + return nil +} + func getProxyFunc() func(*url.URL) (*url.URL, error) { // Create config/proxyFunc if it's not created mu.Lock() diff --git a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_linux.go b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_linux.go index b241c25..7e086e4 100644 --- a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_linux.go +++ b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_linux.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" + "tailscale.com/feature/buildfeatures" "tailscale.com/version/distro" ) @@ -17,7 +18,7 @@ func init() { } func linuxSysProxyFromEnv(req *http.Request) (*url.URL, error) { - if distro.Get() == distro.Synology { + if buildfeatures.HasSynology && distro.Get() == distro.Synology { return synologyProxyFromConfigCached(req) } return nil, nil diff --git a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_windows.go b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_windows.go index 06a1f5a..7163c78 100644 --- a/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_windows.go +++ b/vendor/tailscale.com/net/tshttpproxy/tshttpproxy_windows.go @@ -18,6 +18,7 @@ import ( "unsafe" "github.com/alexbrainman/sspi/negotiate" + "github.com/dblohm7/wingoes" "golang.org/x/sys/windows" "tailscale.com/hostinfo" "tailscale.com/syncs" @@ -97,9 +98,7 @@ func proxyFromWinHTTPOrCache(req *http.Request) (*url.URL, error) { } if err == windows.ERROR_INVALID_PARAMETER { metricErrInvalidParameters.Add(1) - // Seen on Windows 8.1. (https://github.com/tailscale/tailscale/issues/879) - // TODO(bradfitz): figure this out. - setNoProxyUntil(time.Hour) + setNoProxyUntil(10 * time.Second) proxyErrorf("tshttpproxy: winhttp: GetProxyForURL(%q): ERROR_INVALID_PARAMETER [unexpected]", urlStr) return nil, nil } @@ -238,17 +237,30 @@ func (pi *winHTTPProxyInfo) free() { } } -var proxyForURLOpts = &winHTTPAutoProxyOptions{ - DwFlags: winHTTP_AUTOPROXY_ALLOW_AUTOCONFIG | winHTTP_AUTOPROXY_AUTO_DETECT, - DwAutoDetectFlags: winHTTP_AUTO_DETECT_TYPE_DHCP, // | winHTTP_AUTO_DETECT_TYPE_DNS_A, -} +var getProxyForURLOpts = sync.OnceValue(func() *winHTTPAutoProxyOptions { + opts := &winHTTPAutoProxyOptions{ + DwFlags: winHTTP_AUTOPROXY_AUTO_DETECT, + DwAutoDetectFlags: winHTTP_AUTO_DETECT_TYPE_DHCP | winHTTP_AUTO_DETECT_TYPE_DNS_A, + } + // Support for the WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG flag was added in Windows 10, version 1703. + // + // Using it on earlier versions causes GetProxyForURL to fail with ERROR_INVALID_PARAMETER, + // which prevents proxy detection and can lead to failures reaching the control server + // on environments where a proxy is required. + // + // https://web.archive.org/web/20250529044903/https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_autoproxy_options + if wingoes.IsWin10BuildOrGreater(wingoes.Win10Build1703) { + opts.DwFlags |= winHTTP_AUTOPROXY_ALLOW_AUTOCONFIG + } + return opts +}) func (hi winHTTPInternet) GetProxyForURL(urlStr string) (string, error) { var out winHTTPProxyInfo err := winHTTPGetProxyForURL( hi, windows.StringToUTF16Ptr(urlStr), - proxyForURLOpts, + getProxyForURLOpts(), &out, ) if err != nil { diff --git a/vendor/tailscale.com/net/tshttpproxy/zsyscall_windows.go b/vendor/tailscale.com/net/tshttpproxy/zsyscall_windows.go index c07e9ee..5dcfae8 100644 --- a/vendor/tailscale.com/net/tshttpproxy/zsyscall_windows.go +++ b/vendor/tailscale.com/net/tshttpproxy/zsyscall_windows.go @@ -48,7 +48,7 @@ var ( ) func globalFree(hglobal winHGlobal) (err error) { - r1, _, e1 := syscall.Syscall(procGlobalFree.Addr(), 1, uintptr(hglobal), 0, 0) + r1, _, e1 := syscall.SyscallN(procGlobalFree.Addr(), uintptr(hglobal)) if r1 == 0 { err = errnoErr(e1) } @@ -56,7 +56,7 @@ func globalFree(hglobal winHGlobal) (err error) { } func winHTTPCloseHandle(whi winHTTPInternet) (err error) { - r1, _, e1 := syscall.Syscall(procWinHttpCloseHandle.Addr(), 1, uintptr(whi), 0, 0) + r1, _, e1 := syscall.SyscallN(procWinHttpCloseHandle.Addr(), uintptr(whi)) if r1 == 0 { err = errnoErr(e1) } @@ -64,7 +64,7 @@ func winHTTPCloseHandle(whi winHTTPInternet) (err error) { } func winHTTPGetProxyForURL(whi winHTTPInternet, url *uint16, options *winHTTPAutoProxyOptions, proxyInfo *winHTTPProxyInfo) (err error) { - r1, _, e1 := syscall.Syscall6(procWinHttpGetProxyForUrl.Addr(), 4, uintptr(whi), uintptr(unsafe.Pointer(url)), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(proxyInfo)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWinHttpGetProxyForUrl.Addr(), uintptr(whi), uintptr(unsafe.Pointer(url)), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(proxyInfo))) if r1 == 0 { err = errnoErr(e1) } @@ -72,7 +72,7 @@ func winHTTPGetProxyForURL(whi winHTTPInternet, url *uint16, options *winHTTPAut } func winHTTPOpen(agent *uint16, accessType uint32, proxy *uint16, proxyBypass *uint16, flags uint32) (whi winHTTPInternet, err error) { - r0, _, e1 := syscall.Syscall6(procWinHttpOpen.Addr(), 5, uintptr(unsafe.Pointer(agent)), uintptr(accessType), uintptr(unsafe.Pointer(proxy)), uintptr(unsafe.Pointer(proxyBypass)), uintptr(flags), 0) + r0, _, e1 := syscall.SyscallN(procWinHttpOpen.Addr(), uintptr(unsafe.Pointer(agent)), uintptr(accessType), uintptr(unsafe.Pointer(proxy)), uintptr(unsafe.Pointer(proxyBypass)), uintptr(flags)) whi = winHTTPInternet(r0) if whi == 0 { err = errnoErr(e1) diff --git a/vendor/tailscale.com/net/tstun/linkattrs_linux.go b/vendor/tailscale.com/net/tstun/linkattrs_linux.go deleted file mode 100644 index 681e792..0000000 --- a/vendor/tailscale.com/net/tstun/linkattrs_linux.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package tstun - -import ( - "github.com/mdlayher/genetlink" - "github.com/mdlayher/netlink" - "github.com/tailscale/wireguard-go/tun" - "golang.org/x/sys/unix" -) - -// setLinkSpeed sets the advertised link speed of the TUN interface. -func setLinkSpeed(iface tun.Device, mbps int) error { - name, err := iface.Name() - if err != nil { - return err - } - - conn, err := genetlink.Dial(&netlink.Config{Strict: true}) - if err != nil { - return err - } - - defer conn.Close() - - f, err := conn.GetFamily(unix.ETHTOOL_GENL_NAME) - if err != nil { - return err - } - - ae := netlink.NewAttributeEncoder() - ae.Nested(unix.ETHTOOL_A_LINKMODES_HEADER, func(nae *netlink.AttributeEncoder) error { - nae.String(unix.ETHTOOL_A_HEADER_DEV_NAME, name) - return nil - }) - ae.Uint32(unix.ETHTOOL_A_LINKMODES_SPEED, uint32(mbps)) - - b, err := ae.Encode() - if err != nil { - return err - } - - _, err = conn.Execute( - genetlink.Message{ - Header: genetlink.Header{ - Command: unix.ETHTOOL_MSG_LINKMODES_SET, - Version: unix.ETHTOOL_GENL_VERSION, - }, - Data: b, - }, - f.ID, - netlink.Request|netlink.Acknowledge, - ) - return err -} - -// setLinkAttrs sets up link attributes that can be queried by external tools. -// Its failure is non-fatal to interface bringup. -func setLinkAttrs(iface tun.Device) error { - // By default the link speed is 10Mbps, which is easily exceeded and causes monitoring tools to complain (#3933). - return setLinkSpeed(iface, unix.SPEED_UNKNOWN) -} diff --git a/vendor/tailscale.com/net/tstun/linkattrs_notlinux.go b/vendor/tailscale.com/net/tstun/linkattrs_notlinux.go deleted file mode 100644 index 7a7b40f..0000000 --- a/vendor/tailscale.com/net/tstun/linkattrs_notlinux.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package tstun - -import "github.com/tailscale/wireguard-go/tun" - -func setLinkAttrs(iface tun.Device) error { - return nil -} diff --git a/vendor/tailscale.com/net/tstun/netstack_disabled.go b/vendor/tailscale.com/net/tstun/netstack_disabled.go new file mode 100644 index 0000000..c1266b3 --- /dev/null +++ b/vendor/tailscale.com/net/tstun/netstack_disabled.go @@ -0,0 +1,69 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_netstack + +package tstun + +type netstack_PacketBuffer struct { + GSOOptions netstack_GSO +} + +func (*netstack_PacketBuffer) DecRef() { panic("unreachable") } +func (*netstack_PacketBuffer) Size() int { panic("unreachable") } + +type netstack_GSOType int + +const ( + netstack_GSONone netstack_GSOType = iota + netstack_GSOTCPv4 + netstack_GSOTCPv6 + netstack_GSOGvisor +) + +type netstack_GSO struct { + // Type is one of GSONone, GSOTCPv4, etc. + Type netstack_GSOType + // NeedsCsum is set if the checksum offload is enabled. + NeedsCsum bool + // CsumOffset is offset after that to place checksum. + CsumOffset uint16 + + // Mss is maximum segment size. + MSS uint16 + // L3Len is L3 (IP) header length. + L3HdrLen uint16 + + // MaxSize is maximum GSO packet size. + MaxSize uint32 +} + +func (p *netstack_PacketBuffer) NetworkHeader() slicer { + panic("unreachable") +} + +func (p *netstack_PacketBuffer) TransportHeader() slicer { + panic("unreachable") +} + +func (p *netstack_PacketBuffer) ToBuffer() netstack_Buffer { panic("unreachable") } + +func (p *netstack_PacketBuffer) Data() asRanger { + panic("unreachable") +} + +type asRanger struct{} + +func (asRanger) AsRange() toSlicer { panic("unreachable") } + +type toSlicer struct{} + +func (toSlicer) ToSlice() []byte { panic("unreachable") } + +type slicer struct{} + +func (s slicer) Slice() []byte { panic("unreachable") } + +type netstack_Buffer struct{} + +func (netstack_Buffer) Flatten() []byte { panic("unreachable") } diff --git a/vendor/tailscale.com/net/tstun/netstack_enabled.go b/vendor/tailscale.com/net/tstun/netstack_enabled.go new file mode 100644 index 0000000..8fc1a2e --- /dev/null +++ b/vendor/tailscale.com/net/tstun/netstack_enabled.go @@ -0,0 +1,22 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_netstack + +package tstun + +import ( + "gvisor.dev/gvisor/pkg/tcpip/stack" +) + +type ( + netstack_PacketBuffer = stack.PacketBuffer + netstack_GSO = stack.GSO +) + +const ( + netstack_GSONone = stack.GSONone + netstack_GSOTCPv4 = stack.GSOTCPv4 + netstack_GSOTCPv6 = stack.GSOTCPv6 + netstack_GSOGvisor = stack.GSOGvisor +) diff --git a/vendor/tailscale.com/net/tstun/tstun_stub.go b/vendor/tailscale.com/net/tstun/tstun_stub.go index 3119d64..d21eda6 100644 --- a/vendor/tailscale.com/net/tstun/tstun_stub.go +++ b/vendor/tailscale.com/net/tstun/tstun_stub.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build plan9 || aix || solaris || illumos +//go:build aix || solaris || illumos package tstun diff --git a/vendor/tailscale.com/net/tstun/tun.go b/vendor/tailscale.com/net/tstun/tun.go index 44ccdfc..19b0a53 100644 --- a/vendor/tailscale.com/net/tstun/tun.go +++ b/vendor/tailscale.com/net/tstun/tun.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !wasm && !plan9 && !tamago && !aix && !solaris && !illumos +//go:build !wasm && !tamago && !aix && !solaris && !illumos // Package tun creates a tuntap device, working around OS-specific // quirks if necessary. @@ -9,18 +9,28 @@ package tstun import ( "errors" + "fmt" + "log" + "os" "runtime" "strings" "time" "github.com/tailscale/wireguard-go/tun" "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/types/logger" ) -// CrateTAP is the hook set by feature/tap. +// CreateTAP is the hook maybe set by feature/tap. var CreateTAP feature.Hook[func(logf logger.Logf, tapName, bridgeName string) (tun.Device, error)] +// HookSetLinkAttrs is the hook maybe set by feature/linkspeed. +var HookSetLinkAttrs feature.Hook[func(tun.Device) error] + +// modprobeTunHook is a Linux-specific hook to run "/sbin/modprobe tun". +var modprobeTunHook feature.Hook[func() error] + // New returns a tun.Device for the requested device name, along with // the OS-dependent name that was allocated to the device. func New(logf logger.Logf, tunName string) (tun.Device, string, error) { @@ -45,7 +55,25 @@ func New(logf logger.Logf, tunName string) (tun.Device, string, error) { } dev, err = CreateTAP.Get()(logf, tapName, bridgeName) } else { - dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU())) + if runtime.GOOS == "plan9" { + cleanUpPlan9Interfaces() + } + // Try to create the TUN device up to two times. If it fails + // the first time and we're on Linux, try a desperate + // "modprobe tun" to load the tun module and try again. + for try := range 2 { + dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU())) + if err == nil || !modprobeTunHook.IsSet() { + if try > 0 { + logf("created TUN device %q after doing `modprobe tun`", tunName) + } + break + } + if modprobeTunHook.Get()() != nil { + // modprobe failed; no point trying again. + break + } + } } if err != nil { return nil, "", err @@ -54,8 +82,12 @@ func New(logf logger.Logf, tunName string) (tun.Device, string, error) { dev.Close() return nil, "", err } - if err := setLinkAttrs(dev); err != nil { - logf("setting link attributes: %v", err) + if buildfeatures.HasLinkSpeed { + if f, ok := HookSetLinkAttrs.GetOk(); ok { + if err := f(dev); err != nil { + logf("setting link attributes: %v", err) + } + } } name, err := interfaceName(dev) if err != nil { @@ -65,6 +97,36 @@ func New(logf logger.Logf, tunName string) (tun.Device, string, error) { return dev, name, nil } +func cleanUpPlan9Interfaces() { + maybeUnbind := func(n int) { + b, err := os.ReadFile(fmt.Sprintf("/net/ipifc/%d/status", n)) + if err != nil { + return + } + status := string(b) + if !(strings.HasPrefix(status, "device maxtu ") || + strings.Contains(status, "fd7a:115c:a1e0:")) { + return + } + f, err := os.OpenFile(fmt.Sprintf("/net/ipifc/%d/ctl", n), os.O_RDWR, 0) + if err != nil { + return + } + defer f.Close() + if _, err := fmt.Fprintf(f, "unbind\n"); err != nil { + log.Printf("unbind interface %v: %v", n, err) + return + } + log.Printf("tun: unbound stale interface %v", n) + } + + // A common case: after unclean shutdown we might leave interfaces + // behind. Look for our straggler(s) and clean them up. + for n := 2; n < 5; n++ { + maybeUnbind(n) + } +} + // tunDiagnoseFailure, if non-nil, does OS-specific diagnostics of why // TUN failed to work. var tunDiagnoseFailure func(tunName string, logf logger.Logf, err error) diff --git a/vendor/tailscale.com/net/tstun/tun_linux.go b/vendor/tailscale.com/net/tstun/tun_linux.go index 9600ceb..05cf58c 100644 --- a/vendor/tailscale.com/net/tstun/tun_linux.go +++ b/vendor/tailscale.com/net/tstun/tun_linux.go @@ -17,6 +17,14 @@ import ( func init() { tunDiagnoseFailure = diagnoseLinuxTUNFailure + modprobeTunHook.Set(func() error { + _, err := modprobeTun() + return err + }) +} + +func modprobeTun() ([]byte, error) { + return exec.Command("/sbin/modprobe", "tun").CombinedOutput() } func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error) { @@ -36,7 +44,7 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error) kernel := utsReleaseField(&un) logf("Linux kernel version: %s", kernel) - modprobeOut, err := exec.Command("/sbin/modprobe", "tun").CombinedOutput() + modprobeOut, err := modprobeTun() if err == nil { logf("'modprobe tun' successful") // Either tun is currently loaded, or it's statically diff --git a/vendor/tailscale.com/net/tstun/wrap.go b/vendor/tailscale.com/net/tstun/wrap.go index 4421840..fe1bc31 100644 --- a/vendor/tailscale.com/net/tstun/wrap.go +++ b/vendor/tailscale.com/net/tstun/wrap.go @@ -22,10 +22,8 @@ import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" "go4.org/mem" - "gvisor.dev/gvisor/pkg/tcpip/stack" "tailscale.com/disco" - tsmetrics "tailscale.com/metrics" - "tailscale.com/net/connstats" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/packet" "tailscale.com/net/packet/checksum" "tailscale.com/net/tsaddr" @@ -34,7 +32,9 @@ import ( "tailscale.com/types/ipproto" "tailscale.com/types/key" "tailscale.com/types/logger" + "tailscale.com/types/netlogfunc" "tailscale.com/util/clientmetric" + "tailscale.com/util/eventbus" "tailscale.com/util/usermetric" "tailscale.com/wgengine/filter" "tailscale.com/wgengine/netstack/gro" @@ -204,17 +204,20 @@ type Wrapper struct { // disableTSMPRejected disables TSMP rejected responses. For tests. disableTSMPRejected bool - // stats maintains per-connection counters. - stats atomic.Pointer[connstats.Statistics] + // connCounter maintains per-connection counters. + connCounter syncs.AtomicValue[netlogfunc.ConnectionCounter] captureHook syncs.AtomicValue[packet.CaptureCallback] metrics *metrics + + eventClient *eventbus.Client + discoKeyAdvertisementPub *eventbus.Publisher[DiscoKeyAdvertisement] } type metrics struct { - inboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[usermetric.DropLabels] - outboundDroppedPacketsTotal *tsmetrics.MultiLabelMap[usermetric.DropLabels] + inboundDroppedPacketsTotal *usermetric.MultiLabelMap[usermetric.DropLabels] + outboundDroppedPacketsTotal *usermetric.MultiLabelMap[usermetric.DropLabels] } func registerMetrics(reg *usermetric.Registry) *metrics { @@ -228,7 +231,7 @@ func registerMetrics(reg *usermetric.Registry) *metrics { type tunInjectedRead struct { // Only one of packet or data should be set, and are read in that order of // precedence. - packet *stack.PacketBuffer + packet *netstack_PacketBuffer data []byte } @@ -255,15 +258,15 @@ func (w *Wrapper) Start() { close(w.startCh) } -func WrapTAP(logf logger.Logf, tdev tun.Device, m *usermetric.Registry) *Wrapper { - return wrap(logf, tdev, true, m) +func WrapTAP(logf logger.Logf, tdev tun.Device, m *usermetric.Registry, bus *eventbus.Bus) *Wrapper { + return wrap(logf, tdev, true, m, bus) } -func Wrap(logf logger.Logf, tdev tun.Device, m *usermetric.Registry) *Wrapper { - return wrap(logf, tdev, false, m) +func Wrap(logf logger.Logf, tdev tun.Device, m *usermetric.Registry, bus *eventbus.Bus) *Wrapper { + return wrap(logf, tdev, false, m, bus) } -func wrap(logf logger.Logf, tdev tun.Device, isTAP bool, m *usermetric.Registry) *Wrapper { +func wrap(logf logger.Logf, tdev tun.Device, isTAP bool, m *usermetric.Registry, bus *eventbus.Bus) *Wrapper { logf = logger.WithPrefix(logf, "tstun: ") w := &Wrapper{ logf: logf, @@ -284,6 +287,9 @@ func wrap(logf logger.Logf, tdev tun.Device, isTAP bool, m *usermetric.Registry) metrics: registerMetrics(m), } + w.eventClient = bus.Client("net.tstun") + w.discoKeyAdvertisementPub = eventbus.Publish[DiscoKeyAdvertisement](w.eventClient) + w.vectorBuffer = make([][]byte, tdev.BatchSize()) for i := range w.vectorBuffer { w.vectorBuffer[i] = make([]byte, maxBufferSize) @@ -312,7 +318,9 @@ func (t *Wrapper) now() time.Time { // // The map ownership passes to the Wrapper. It must be non-nil. func (t *Wrapper) SetDestIPActivityFuncs(m map[netip.Addr]func()) { - t.destIPActivity.Store(m) + if buildfeatures.HasLazyWG { + t.destIPActivity.Store(m) + } } // SetDiscoKey sets the current discovery key. @@ -356,6 +364,7 @@ func (t *Wrapper) Close() error { close(t.vectorOutbound) t.outboundMu.Unlock() err = t.tdev.Close() + t.eventClient.Close() }) return err } @@ -948,12 +957,14 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) { for _, data := range res.data { p.Decode(data[res.dataOffset:]) - if m := t.destIPActivity.Load(); m != nil { - if fn := m[p.Dst.Addr()]; fn != nil { - fn() + if buildfeatures.HasLazyWG { + if m := t.destIPActivity.Load(); m != nil { + if fn := m[p.Dst.Addr()]; fn != nil { + fn() + } } } - if captHook != nil { + if buildfeatures.HasCapture && captHook != nil { captHook(packet.FromLocal, t.now(), p.Buffer(), p.CaptureMeta) } if !t.disableFilter { @@ -964,6 +975,11 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) { continue } } + if buildfeatures.HasNetLog { + if update := t.connCounter.Load(); update != nil { + updateConnCounter(update, p.Buffer(), false) + } + } // Make sure to do SNAT after filtering, so that any flow tracking in // the filter sees the original source address. See #12133. @@ -973,9 +989,6 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) { panic(fmt.Sprintf("short copy: %d != %d", n, len(data)-res.dataOffset)) } sizes[buffsPos] = n - if stats := t.stats.Load(); stats != nil { - stats.UpdateTxVirtual(p.Buffer()) - } buffsPos++ } if buffsGRO != nil { @@ -998,7 +1011,10 @@ const ( minTCPHeaderSize = 20 ) -func stackGSOToTunGSO(pkt []byte, gso stack.GSO) (tun.GSOOptions, error) { +func stackGSOToTunGSO(pkt []byte, gso netstack_GSO) (tun.GSOOptions, error) { + if !buildfeatures.HasNetstack { + panic("unreachable") + } options := tun.GSOOptions{ CsumStart: gso.L3HdrLen, CsumOffset: gso.CsumOffset, @@ -1006,12 +1022,12 @@ func stackGSOToTunGSO(pkt []byte, gso stack.GSO) (tun.GSOOptions, error) { NeedsCsum: gso.NeedsCsum, } switch gso.Type { - case stack.GSONone: + case netstack_GSONone: options.GSOType = tun.GSONone return options, nil - case stack.GSOTCPv4: + case netstack_GSOTCPv4: options.GSOType = tun.GSOTCPv4 - case stack.GSOTCPv6: + case netstack_GSOTCPv6: options.GSOType = tun.GSOTCPv6 default: return tun.GSOOptions{}, fmt.Errorf("unsupported gVisor GSOType: %v", gso.Type) @@ -1034,7 +1050,10 @@ func stackGSOToTunGSO(pkt []byte, gso stack.GSO) (tun.GSOOptions, error) { // both before and after partial checksum updates where later checksum // offloading still expects a partial checksum. // TODO(jwhited): plumb partial checksum awareness into net/packet/checksum. -func invertGSOChecksum(pkt []byte, gso stack.GSO) { +func invertGSOChecksum(pkt []byte, gso netstack_GSO) { + if !buildfeatures.HasNetstack { + panic("unreachable") + } if gso.NeedsCsum != true { return } @@ -1048,10 +1067,13 @@ func invertGSOChecksum(pkt []byte, gso stack.GSO) { // injectedRead handles injected reads, which bypass filters. func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []int, offset int) (n int, err error) { - var gso stack.GSO + var gso netstack_GSO pkt := outBuffs[0][offset:] if res.packet != nil { + if !buildfeatures.HasNetstack { + panic("unreachable") + } bufN := copy(pkt, res.packet.NetworkHeader().Slice()) bufN += copy(pkt[bufN:], res.packet.TransportHeader().Slice()) bufN += copy(pkt[bufN:], res.packet.Data().AsRange().ToSlice()) @@ -1074,9 +1096,11 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i pc.snat(p) invertGSOChecksum(pkt, gso) - if m := t.destIPActivity.Load(); m != nil { - if fn := m[p.Dst.Addr()]; fn != nil { - fn() + if buildfeatures.HasLazyWG { + if m := t.destIPActivity.Load(); m != nil { + if fn := m[p.Dst.Addr()]; fn != nil { + fn() + } } } @@ -1089,9 +1113,11 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i n, err = tun.GSOSplit(pkt, gsoOptions, outBuffs, sizes, offset) } - if stats := t.stats.Load(); stats != nil { - for i := 0; i < n; i++ { - stats.UpdateTxVirtual(outBuffs[i][offset : offset+sizes[i]]) + if buildfeatures.HasNetLog { + if update := t.connCounter.Load(); update != nil { + for i := 0; i < n; i++ { + updateConnCounter(update, outBuffs[i][offset:offset+sizes[i]], false) + } } } @@ -1100,6 +1126,13 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i return n, err } +// DiscoKeyAdvertisement is a TSMP message used for distributing disco keys. +// This struct is used an an event on the [eventbus.Bus]. +type DiscoKeyAdvertisement struct { + Src netip.Addr // Src field is populated by the IP header of the packet, not from the payload itself. + Key key.DiscoPublic +} + func (t *Wrapper) filterPacketInboundFromWireGuard(p *packet.Parsed, captHook packet.CaptureCallback, pc *peerConfigTable, gro *gro.GRO) (filter.Response, *gro.GRO) { if captHook != nil { captHook(packet.FromPeer, t.now(), p.Buffer(), p.CaptureMeta) @@ -1110,6 +1143,12 @@ func (t *Wrapper) filterPacketInboundFromWireGuard(p *packet.Parsed, captHook pa t.noteActivity() t.injectOutboundPong(p, pingReq) return filter.DropSilently, gro + } else if discoKeyAdvert, ok := p.AsTSMPDiscoAdvertisement(); ok { + t.discoKeyAdvertisementPub.Publish(DiscoKeyAdvertisement{ + Src: discoKeyAdvert.Src, + Key: discoKeyAdvert.Key, + }) + return filter.DropSilently, gro } else if data, ok := p.AsTSMPPong(); ok { if f := t.OnTSMPPongReceived; f != nil { f(data) @@ -1257,9 +1296,11 @@ func (t *Wrapper) Write(buffs [][]byte, offset int) (int, error) { } func (t *Wrapper) tdevWrite(buffs [][]byte, offset int) (int, error) { - if stats := t.stats.Load(); stats != nil { - for i := range buffs { - stats.UpdateRxVirtual((buffs)[i][offset:]) + if buildfeatures.HasNetLog { + if update := t.connCounter.Load(); update != nil { + for i := range buffs { + updateConnCounter(update, buffs[i][offset:], true) + } } } return t.tdev.Write(buffs, offset) @@ -1297,7 +1338,10 @@ func (t *Wrapper) SetJailedFilter(filt *filter.Filter) { // // This path is typically used to deliver synthesized packets to the // host networking stack. -func (t *Wrapper) InjectInboundPacketBuffer(pkt *stack.PacketBuffer, buffs [][]byte, sizes []int) error { +func (t *Wrapper) InjectInboundPacketBuffer(pkt *netstack_PacketBuffer, buffs [][]byte, sizes []int) error { + if !buildfeatures.HasNetstack { + panic("unreachable") + } buf := buffs[0][PacketStartOffset:] bufN := copy(buf, pkt.NetworkHeader().Slice()) @@ -1436,7 +1480,10 @@ func (t *Wrapper) InjectOutbound(pkt []byte) error { // InjectOutboundPacketBuffer logically behaves as InjectOutbound. It takes ownership of one // reference count on the packet, and the packet may be mutated. The packet refcount will be // decremented after the injected buffer has been read. -func (t *Wrapper) InjectOutboundPacketBuffer(pkt *stack.PacketBuffer) error { +func (t *Wrapper) InjectOutboundPacketBuffer(pkt *netstack_PacketBuffer) error { + if !buildfeatures.HasNetstack { + panic("unreachable") + } size := pkt.Size() if size > MaxPacketSize { pkt.DecRef() @@ -1472,10 +1519,12 @@ func (t *Wrapper) Unwrap() tun.Device { return t.tdev } -// SetStatistics specifies a per-connection statistics aggregator. +// SetConnectionCounter specifies a per-connection statistics aggregator. // Nil may be specified to disable statistics gathering. -func (t *Wrapper) SetStatistics(stats *connstats.Statistics) { - t.stats.Store(stats) +func (t *Wrapper) SetConnectionCounter(fn netlogfunc.ConnectionCounter) { + if buildfeatures.HasNetLog { + t.connCounter.Store(fn) + } } var ( @@ -1491,5 +1540,18 @@ var ( ) func (t *Wrapper) InstallCaptureHook(cb packet.CaptureCallback) { + if !buildfeatures.HasCapture { + return + } t.captureHook.Store(cb) } + +func updateConnCounter(update netlogfunc.ConnectionCounter, b []byte, receive bool) { + var p packet.Parsed + p.Decode(b) + if receive { + update(p.IPProto, p.Dst, p.Src, 1, len(b), true) + } else { + update(p.IPProto, p.Src, p.Dst, 1, len(b), false) + } +} diff --git a/vendor/tailscale.com/net/tstun/wrap_linux.go b/vendor/tailscale.com/net/tstun/wrap_linux.go index 136ddfe..7498f10 100644 --- a/vendor/tailscale.com/net/tstun/wrap_linux.go +++ b/vendor/tailscale.com/net/tstun/wrap_linux.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build linux && !ts_omit_gro + package tstun import ( diff --git a/vendor/tailscale.com/net/tstun/wrap_noop.go b/vendor/tailscale.com/net/tstun/wrap_noop.go index c743072..8ad04ba 100644 --- a/vendor/tailscale.com/net/tstun/wrap_noop.go +++ b/vendor/tailscale.com/net/tstun/wrap_noop.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !linux +//go:build !linux || ts_omit_gro package tstun diff --git a/vendor/tailscale.com/net/udprelay/endpoint/endpoint.go b/vendor/tailscale.com/net/udprelay/endpoint/endpoint.go new file mode 100644 index 0000000..0d2a14e --- /dev/null +++ b/vendor/tailscale.com/net/udprelay/endpoint/endpoint.go @@ -0,0 +1,64 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package endpoint contains types relating to UDP relay server endpoints. It +// does not import tailscale.com/net/udprelay. +package endpoint + +import ( + "net/netip" + "time" + + "tailscale.com/tstime" + "tailscale.com/types/key" +) + +// ServerRetryAfter is the default +// [tailscale.com/net/udprelay.ErrServerNotReady.RetryAfter] value. +const ServerRetryAfter = time.Second * 3 + +// ServerEndpoint contains details for an endpoint served by a +// [tailscale.com/net/udprelay.Server]. +type ServerEndpoint struct { + // ServerDisco is the Server's Disco public key used as part of the 3-way + // bind handshake. Server will use the same ServerDisco for its lifetime. + // ServerDisco value in combination with LamportID value represents a + // unique ServerEndpoint allocation. + ServerDisco key.DiscoPublic + + // ClientDisco are the Disco public keys of the relay participants permitted + // to handshake with this endpoint. + ClientDisco [2]key.DiscoPublic + + // LamportID is unique and monotonically non-decreasing across + // ServerEndpoint allocations for the lifetime of Server. It enables clients + // to dedup and resolve allocation event order. Clients may race to allocate + // on the same Server, and signal ServerEndpoint details via alternative + // channels, e.g. DERP. Additionally, Server.AllocateEndpoint() requests may + // not result in a new allocation depending on existing server-side endpoint + // state. Therefore, where clients have local, existing state that contains + // ServerDisco and LamportID values matching a newly learned endpoint, these + // can be considered one and the same. If ServerDisco is equal, but + // LamportID is unequal, LamportID comparison determines which + // ServerEndpoint was allocated most recently. + LamportID uint64 + + // AddrPorts are the IP:Port candidate pairs the Server may be reachable + // over. + AddrPorts []netip.AddrPort + + // VNI (Virtual Network Identifier) is the Geneve header VNI the Server + // will use for transmitted packets, and expects for received packets + // associated with this endpoint. + VNI uint32 + + // BindLifetime is amount of time post-allocation the Server will consider + // the endpoint active while it has yet to be bound via 3-way bind handshake + // from both client parties. + BindLifetime tstime.GoDuration + + // SteadyStateLifetime is the amount of time post 3-way bind handshake from + // both client parties the Server will consider the endpoint active lacking + // bidirectional data flow. + SteadyStateLifetime tstime.GoDuration +} diff --git a/vendor/tailscale.com/net/udprelay/status/status.go b/vendor/tailscale.com/net/udprelay/status/status.go new file mode 100644 index 0000000..9ed9a0d --- /dev/null +++ b/vendor/tailscale.com/net/udprelay/status/status.go @@ -0,0 +1,76 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package status contains types relating to the status of peer relay sessions +// between peer relay client nodes via a peer relay server. +package status + +import ( + "net/netip" +) + +// ServerStatus contains the listening UDP port and active sessions (if any) for +// this node's peer relay server at a point in time. +type ServerStatus struct { + // UDPPort is the UDP port number that the peer relay server forwards over, + // as configured by the user with 'tailscale set --relay-server-port='. + // If the port has not been configured, UDPPort will be nil. A non-nil zero + // value signifies the user has opted for a random unused port. + UDPPort *uint16 + // Sessions is a slice of detailed status information about each peer + // relay session that this node's peer relay server is involved with. It + // may be empty. + Sessions []ServerSession +} + +// ClientInfo contains status-related information about a single peer relay +// client involved in a single peer relay session. +type ClientInfo struct { + // Endpoint is the [netip.AddrPort] of this peer relay client's underlay + // endpoint participating in the session, or a zero value if the client + // has not completed a handshake. + Endpoint netip.AddrPort + // ShortDisco is a string representation of this peer relay client's disco + // public key. + // + // TODO: disco keys are pretty meaningless to end users, and they are also + // ephemeral. We really need node keys (or translation to first ts addr), + // but those are not fully plumbed into the [udprelay.Server]. Disco keys + // can also be ambiguous to a node key, but we could add node key into a + // [disco.AllocateUDPRelayEndpointRequest] in similar fashion to + // [disco.Ping]. There's also the problem of netmap trimming, where we + // can't verify a node key maps to a disco key. + ShortDisco string + // PacketsTx is the number of packets this peer relay client has sent to + // the other client via the relay server after completing a handshake. This + // is identical to the number of packets that the peer relay server has + // received from this client. + PacketsTx uint64 + // BytesTx is the total overlay bytes this peer relay client has sent to + // the other client via the relay server after completing a handshake. This + // is identical to the total overlay bytes that the peer relay server has + // received from this client. + BytesTx uint64 +} + +// ServerSession contains status information for a single session between two +// peer relay clients, which are relayed via one peer relay server. This is the +// status as seen by the peer relay server; each client node may have a +// different view of the session's current status based on connectivity and +// where the client is in the peer relay endpoint setup (allocation, binding, +// pinging, active). +type ServerSession struct { + // VNI is the Virtual Network Identifier for this peer relay session, which + // comes from the Geneve header and is unique to this session. + VNI uint32 + // Client1 contains status information about one of the two peer relay + // clients involved in this session. Note that 'Client1' does NOT mean this + // was/wasn't the allocating client, or the first client to bind, etc; this + // is just one client of two. + Client1 ClientInfo + // Client2 contains status information about one of the two peer relay + // clients involved in this session. Note that 'Client2' does NOT mean this + // was/wasn't the allocating client, or the second client to bind, etc; this + // is just one client of two. + Client2 ClientInfo +} diff --git a/vendor/tailscale.com/net/wsconn/wsconn.go b/vendor/tailscale.com/net/wsconn/wsconn.go index 22b511e..9e44da5 100644 --- a/vendor/tailscale.com/net/wsconn/wsconn.go +++ b/vendor/tailscale.com/net/wsconn/wsconn.go @@ -2,9 +2,7 @@ // SPDX-License-Identifier: BSD-3-Clause // Package wsconn contains an adapter type that turns -// a websocket connection into a net.Conn. It a temporary fork of the -// netconn.go file from the github.com/coder/websocket package while we wait for -// https://github.com/nhooyr/websocket/pull/350 to be merged. +// a websocket connection into a net.Conn. package wsconn import ( @@ -14,11 +12,11 @@ import ( "math" "net" "os" - "sync" "sync/atomic" "time" "github.com/coder/websocket" + "tailscale.com/syncs" ) // NetConn converts a *websocket.Conn into a net.Conn. @@ -104,7 +102,7 @@ type netConn struct { reading atomic.Bool afterReadDeadline atomic.Bool - readMu sync.Mutex + readMu syncs.Mutex // eofed is true if the reader should return io.EOF from the Read call. // // +checklocks:readMu diff --git a/vendor/tailscale.com/paths/paths.go b/vendor/tailscale.com/paths/paths.go index 28c3be0..6c9c3fa 100644 --- a/vendor/tailscale.com/paths/paths.go +++ b/vendor/tailscale.com/paths/paths.go @@ -6,6 +6,7 @@ package paths import ( + "log" "os" "path/filepath" "runtime" @@ -70,6 +71,37 @@ func DefaultTailscaledStateFile() string { return "" } +// DefaultTailscaledStateDir returns the default state directory +// to use for tailscaled, for use when the user provided neither +// a state directory or state file path to use. +// +// It returns the empty string if there's no reasonable default. +func DefaultTailscaledStateDir() string { + if runtime.GOOS == "plan9" { + home, err := os.UserHomeDir() + if err != nil { + log.Fatalf("failed to get home directory: %v", err) + } + return filepath.Join(home, "tailscale-state") + } + return filepath.Dir(DefaultTailscaledStateFile()) +} + +// MakeAutomaticStateDir reports whether the platform +// automatically creates the state directory for tailscaled +// when it's absent. +func MakeAutomaticStateDir() bool { + switch runtime.GOOS { + case "plan9": + return true + case "linux": + if distro.Get() == distro.JetKVM { + return true + } + } + return false +} + // MkStateDir ensures that dirPath, the daemon's configuration directory // containing machine keys etc, both exists and has the correct permissions. // We want it to only be accessible to the user the daemon is running under. diff --git a/vendor/tailscale.com/paths/paths_unix.go b/vendor/tailscale.com/paths/paths_unix.go index 50a8b7c..d317921 100644 --- a/vendor/tailscale.com/paths/paths_unix.go +++ b/vendor/tailscale.com/paths/paths_unix.go @@ -21,6 +21,9 @@ func init() { } func statePath() string { + if runtime.GOOS == "linux" && distro.Get() == distro.JetKVM { + return "/userdata/tailscale/var/tailscaled.state" + } switch runtime.GOOS { case "linux", "illumos", "solaris": return "/var/lib/tailscale/tailscaled.state" diff --git a/vendor/tailscale.com/portlist/clean.go b/vendor/tailscale.com/portlist/clean.go deleted file mode 100644 index 7e137de..0000000 --- a/vendor/tailscale.com/portlist/clean.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package portlist - -import ( - "path/filepath" - "strings" -) - -// argvSubject takes a command and its flags, and returns the -// short/pretty name for the process. This is usually the basename of -// the binary being executed, but can sometimes vary (e.g. so that we -// don't report all Java programs as "java"). -func argvSubject(argv ...string) string { - if len(argv) == 0 { - return "" - } - ret := filepath.Base(argv[0]) - - // Handle special cases. - switch { - case ret == "mono" && len(argv) >= 2: - // .Net programs execute as `mono actualProgram.exe`. - ret = filepath.Base(argv[1]) - } - - // Handle space separated argv - ret, _, _ = strings.Cut(ret, " ") - - // Remove common noise. - ret = strings.TrimSpace(ret) - ret = strings.TrimSuffix(ret, ".exe") - - return ret -} diff --git a/vendor/tailscale.com/portlist/netstat.go b/vendor/tailscale.com/portlist/netstat.go deleted file mode 100644 index 5fdef67..0000000 --- a/vendor/tailscale.com/portlist/netstat.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin && !ios - -package portlist - -import ( - "bufio" - "bytes" - "io" - - "go4.org/mem" -) - -// parsePort returns the port number at the end of s following the last "." or -// ":", whichever comes last. It returns -1 on a parse error or invalid number -// and 0 if the port number was "*". -// -// This is basically net.SplitHostPort except that it handles a "." (as macOS -// and others return in netstat output), uses mem.RO, and validates that the -// port must be numeric and in the uint16 range. -func parsePort(s mem.RO) int { - // a.b.c.d:1234 or [a:b:c:d]:1234 - i1 := mem.LastIndexByte(s, ':') - // a.b.c.d.1234 or [a:b:c:d].1234 - i2 := mem.LastIndexByte(s, '.') - - i := i1 - if i2 > i { - i = i2 - } - if i < 0 { - // no match; weird - return -1 - } - - portstr := s.SliceFrom(i + 1) - if portstr.EqualString("*") { - return 0 - } - - port, err := mem.ParseUint(portstr, 10, 16) - if err != nil { - // invalid port; weird - return -1 - } - - return int(port) -} - -func isLoopbackAddr(s mem.RO) bool { - return mem.HasPrefix(s, mem.S("127.")) || - mem.HasPrefix(s, mem.S("[::1]:")) || - mem.HasPrefix(s, mem.S("::1.")) -} - -// appendParsePortsNetstat appends to base listening ports -// from "netstat" output, read from br. See TestParsePortsNetstat -// for example input lines. -// -// This used to be a lowest common denominator parser for "netstat -na" format. -// All of Linux, Windows, and macOS support -na and give similar-ish output -// formats that we can parse without special detection logic. -// Unfortunately, options to filter by proto or state are non-portable, -// so we'll filter for ourselves. -// Nowadays, though, we only use it for macOS as of 2022-11-04. -func appendParsePortsNetstat(base []Port, br *bufio.Reader, includeLocalhost bool) ([]Port, error) { - ret := base - var fieldBuf [10]mem.RO - for { - line, err := br.ReadBytes('\n') - if err != nil { - if err == io.EOF { - break - } - return nil, err - } - trimline := bytes.TrimSpace(line) - cols := mem.AppendFields(fieldBuf[:0], mem.B(trimline)) - if len(cols) < 1 { - continue - } - protos := cols[0] - - var proto string - var laddr, raddr mem.RO - if mem.HasPrefixFold(protos, mem.S("tcp")) { - if len(cols) < 4 { - continue - } - proto = "tcp" - laddr = cols[len(cols)-3] - raddr = cols[len(cols)-2] - state := cols[len(cols)-1] - if !mem.HasPrefix(state, mem.S("LISTEN")) { - // not interested in non-listener sockets - continue - } - if !includeLocalhost && isLoopbackAddr(laddr) { - // not interested in loopback-bound listeners - continue - } - } else if mem.HasPrefixFold(protos, mem.S("udp")) { - if len(cols) < 3 { - continue - } - proto = "udp" - laddr = cols[len(cols)-2] - raddr = cols[len(cols)-1] - if !includeLocalhost && isLoopbackAddr(laddr) { - // not interested in loopback-bound listeners - continue - } - } else { - // not interested in other protocols - continue - } - - lport := parsePort(laddr) - rport := parsePort(raddr) - if rport > 0 || lport <= 0 { - // not interested in "connected" sockets - continue - } - ret = append(ret, Port{ - Proto: proto, - Port: uint16(lport), - }) - } - return ret, nil -} diff --git a/vendor/tailscale.com/portlist/poller.go b/vendor/tailscale.com/portlist/poller.go deleted file mode 100644 index 423bad3..0000000 --- a/vendor/tailscale.com/portlist/poller.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// This file contains the code related to the Poller type and its methods. -// The hot loop to keep efficient is Poller.Run. - -package portlist - -import ( - "errors" - "fmt" - "runtime" - "slices" - "sync" - "time" - - "tailscale.com/envknob" -) - -var ( - newOSImpl func(includeLocalhost bool) osImpl // if non-nil, constructs a new osImpl. - pollInterval = 5 * time.Second // default; changed by some OS-specific init funcs - debugDisablePortlist = envknob.RegisterBool("TS_DEBUG_DISABLE_PORTLIST") -) - -// PollInterval is the recommended OS-specific interval -// to wait between *Poller.Poll method calls. -func PollInterval() time.Duration { - return pollInterval -} - -// Poller scans the systems for listening ports periodically and sends -// the results to C. -type Poller struct { - // IncludeLocalhost controls whether services bound to localhost are included. - // - // This field should only be changed before calling Run. - IncludeLocalhost bool - - // os, if non-nil, is an OS-specific implementation of the portlist getting - // code. When non-nil, it's responsible for getting the complete list of - // cached ports complete with the process name. That is, when set, - // addProcesses is not used. - // A nil values means we don't have code for getting the list on the current - // operating system. - os osImpl - initOnce sync.Once // guards init of os - initErr error - - // scatch is memory for Poller.getList to reuse between calls. - scratch []Port - - prev List // most recent data, not aliasing scratch -} - -// osImpl is the OS-specific implementation of getting the open listening ports. -type osImpl interface { - Close() error - - // AppendListeningPorts appends to base (which must have length 0 but - // optional capacity) the list of listening ports. The Port struct should be - // populated as completely as possible. Another pass will not add anything - // to it. - // - // The appended ports should be in a sorted (or at least stable) order so - // the caller can cheaply detect when there are no changes. - AppendListeningPorts(base []Port) ([]Port, error) -} - -func (p *Poller) setPrev(pl List) { - // Make a copy, as the pass in pl slice aliases pl.scratch and we don't want - // that to except to the caller. - p.prev = slices.Clone(pl) -} - -// init initializes the Poller by ensuring it has an underlying -// OS implementation and is not turned off by envknob. -func (p *Poller) init() { - switch { - case debugDisablePortlist(): - p.initErr = errors.New("portlist disabled by envknob") - case newOSImpl == nil: - p.initErr = errors.New("portlist poller not implemented on " + runtime.GOOS) - default: - p.os = newOSImpl(p.IncludeLocalhost) - } -} - -// Close closes the Poller. -func (p *Poller) Close() error { - if p.initErr != nil { - return p.initErr - } - if p.os == nil { - return nil - } - return p.os.Close() -} - -// Poll returns the list of listening ports, if changed from -// a previous call as indicated by the changed result. -func (p *Poller) Poll() (ports []Port, changed bool, err error) { - p.initOnce.Do(p.init) - if p.initErr != nil { - return nil, false, fmt.Errorf("error initializing poller: %w", p.initErr) - } - pl, err := p.getList() - if err != nil { - return nil, false, err - } - if pl.equal(p.prev) { - return nil, false, nil - } - p.setPrev(pl) - return p.prev, true, nil -} - -func (p *Poller) getList() (List, error) { - var err error - p.scratch, err = p.os.AppendListeningPorts(p.scratch[:0]) - return p.scratch, err -} diff --git a/vendor/tailscale.com/portlist/portlist.go b/vendor/tailscale.com/portlist/portlist.go deleted file mode 100644 index 9f7af40..0000000 --- a/vendor/tailscale.com/portlist/portlist.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// This file is just the types. The bulk of the code is in poller.go. - -// The portlist package contains code that checks what ports are open and -// listening on the current machine. -package portlist - -import ( - "fmt" - "sort" - "strings" -) - -// Port is a listening port on the machine. -type Port struct { - Proto string // "tcp" or "udp" - Port uint16 // port number - Process string // optional process name, if found (requires suitable permissions) - Pid int // process ID, if known (requires suitable permissions) -} - -// List is a list of Ports. -type List []Port - -func (a *Port) lessThan(b *Port) bool { - if a.Port != b.Port { - return a.Port < b.Port - } - if a.Proto != b.Proto { - return a.Proto < b.Proto - } - return a.Process < b.Process -} - -func (a *Port) equal(b *Port) bool { - return a.Port == b.Port && - a.Proto == b.Proto && - a.Process == b.Process -} - -func (a List) equal(b List) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if !a[i].equal(&b[i]) { - return false - } - } - return true -} - -func (pl List) String() string { - var sb strings.Builder - for _, v := range pl { - fmt.Fprintf(&sb, "%-3s %5d %#v\n", - v.Proto, v.Port, v.Process) - } - return strings.TrimRight(sb.String(), "\n") -} - -// sortAndDedup sorts ps in place (by Port.lessThan) and then returns -// a subset of it with duplicate (Proto, Port) removed. -func sortAndDedup(ps List) List { - sort.Slice(ps, func(i, j int) bool { - return (&ps[i]).lessThan(&ps[j]) - }) - out := ps[:0] - var last Port - for _, p := range ps { - if last.Proto == p.Proto && last.Port == p.Port { - continue - } - out = append(out, p) - last = p - } - return out -} diff --git a/vendor/tailscale.com/portlist/portlist_linux.go b/vendor/tailscale.com/portlist/portlist_linux.go deleted file mode 100644 index 94f8437..0000000 --- a/vendor/tailscale.com/portlist/portlist_linux.go +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package portlist - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "io/fs" - "log" - "os" - "path/filepath" - "runtime" - "strings" - "syscall" - "time" - "unsafe" - - "go4.org/mem" - "golang.org/x/sys/unix" - "tailscale.com/util/dirwalk" - "tailscale.com/util/mak" -) - -func init() { - newOSImpl = newLinuxImpl - // Reading the sockfiles on Linux is very fast, so we can do it often. - pollInterval = 1 * time.Second -} - -type linuxImpl struct { - procNetFiles []*os.File // seeked to start & reused between calls - readlinkPathBuf []byte - - known map[string]*portMeta // inode string => metadata - br *bufio.Reader - includeLocalhost bool -} - -type portMeta struct { - port Port - pid int - keep bool - needsProcName bool -} - -func newLinuxImplBase(includeLocalhost bool) *linuxImpl { - return &linuxImpl{ - br: bufio.NewReader(eofReader), - known: map[string]*portMeta{}, - includeLocalhost: includeLocalhost, - } -} - -func newLinuxImpl(includeLocalhost bool) osImpl { - li := newLinuxImplBase(includeLocalhost) - for _, name := range []string{ - "/proc/net/tcp", - "/proc/net/tcp6", - "/proc/net/udp", - "/proc/net/udp6", - } { - f, err := os.Open(name) - if err != nil { - if os.IsNotExist(err) { - continue - } - log.Printf("portlist warning; ignoring: %v", err) - continue - } - li.procNetFiles = append(li.procNetFiles, f) - } - return li -} - -func (li *linuxImpl) Close() error { - for _, f := range li.procNetFiles { - f.Close() - } - li.procNetFiles = nil - return nil -} - -const ( - v6Localhost = "00000000000000000000000001000000:" - v6Any = "00000000000000000000000000000000:0000" - v4Localhost = "0100007F:" - v4Any = "00000000:0000" -) - -var eofReader = bytes.NewReader(nil) - -func (li *linuxImpl) AppendListeningPorts(base []Port) ([]Port, error) { - if runtime.GOOS == "android" { - // Android 10+ doesn't allow access to this anymore. - // https://developer.android.com/about/versions/10/privacy/changes#proc-net-filesystem - // Ignore it rather than have the system log about our violation. - return nil, nil - } - - br := li.br - defer br.Reset(eofReader) - - // Start by marking all previous known ports as gone. If this mark - // bit is still false later, we'll remove them. - for _, pm := range li.known { - pm.keep = false - } - - for _, f := range li.procNetFiles { - name := f.Name() - _, err := f.Seek(0, io.SeekStart) - if err != nil { - return nil, err - } - br.Reset(f) - err = li.parseProcNetFile(br, filepath.Base(name)) - if err != nil { - return nil, fmt.Errorf("parsing %q: %w", name, err) - } - } - - // Delete ports that aren't open any longer. - // And see if there are any process names we need to look for. - var needProc map[string]*portMeta - for inode, pm := range li.known { - if !pm.keep { - delete(li.known, inode) - continue - } - if pm.needsProcName { - mak.Set(&needProc, inode, pm) - } - } - err := li.findProcessNames(needProc) - if err != nil { - return nil, err - } - - ret := base - for _, pm := range li.known { - ret = append(ret, pm.port) - } - return sortAndDedup(ret), nil -} - -// fileBase is one of "tcp", "tcp6", "udp", "udp6". -func (li *linuxImpl) parseProcNetFile(r *bufio.Reader, fileBase string) error { - proto := strings.TrimSuffix(fileBase, "6") - - // skip header row - _, err := r.ReadSlice('\n') - if err != nil { - return err - } - - fields := make([]mem.RO, 0, 20) // 17 current fields + some future slop - - wantRemote := mem.S(v4Any) - if strings.HasSuffix(fileBase, "6") { - wantRemote = mem.S(v6Any) - } - - // remoteIndex is the index within a line to the remote address field. - // -1 means not yet found. - remoteIndex := -1 - - // Add an upper bound on how many rows we'll attempt to read just - // to make sure this doesn't consume too much of their CPU. - // TODO(bradfitz,crawshaw): adaptively adjust polling interval as function - // of open sockets. - const maxRows = 1e6 - rows := 0 - - // Scratch buffer for making inode strings. - inoBuf := make([]byte, 0, 50) - - for { - line, err := r.ReadSlice('\n') - if err == io.EOF { - break - } - if err != nil { - return err - } - rows++ - if rows >= maxRows { - break - } - if len(line) == 0 { - continue - } - - // On the first row of output, find the index of the 3rd field (index 2), - // the remote address. All the rows are aligned, at least until 4 billion open - // TCP connections, per the Linux get_tcp4_sock's "%4d: " on an int i. - if remoteIndex == -1 { - remoteIndex = fieldIndex(line, 2) - if remoteIndex == -1 { - break - } - } - - if len(line) < remoteIndex || !mem.HasPrefix(mem.B(line).SliceFrom(remoteIndex), wantRemote) { - // Fast path for not being a listener port. - continue - } - - // sl local rem ... inode - fields = mem.AppendFields(fields[:0], mem.B(line)) - local := fields[1] - rem := fields[2] - inode := fields[9] - - if !rem.Equal(wantRemote) { - // not a "listener" port - continue - } - - // If a port is bound to localhost, ignore it. - // TODO: localhost is bigger than 1 IP, we need to ignore - // more things. - if !li.includeLocalhost && (mem.HasPrefix(local, mem.S(v4Localhost)) || mem.HasPrefix(local, mem.S(v6Localhost))) { - continue - } - - // Don't use strings.Split here, because it causes - // allocations significant enough to show up in profiles. - i := mem.IndexByte(local, ':') - if i == -1 { - return fmt.Errorf("%q unexpectedly didn't have a colon", local.StringCopy()) - } - portv, err := mem.ParseUint(local.SliceFrom(i+1), 16, 16) - if err != nil { - return fmt.Errorf("%#v: %s", local.SliceFrom(9).StringCopy(), err) - } - inoBuf = append(inoBuf[:0], "socket:["...) - inoBuf = mem.Append(inoBuf, inode) - inoBuf = append(inoBuf, ']') - - if pm, ok := li.known[string(inoBuf)]; ok { - pm.keep = true - // Rest should be unchanged. - } else { - li.known[string(inoBuf)] = &portMeta{ - needsProcName: true, - keep: true, - port: Port{ - Proto: proto, - Port: uint16(portv), - }, - } - } - } - - return nil -} - -// errDone is an internal sentinel error that we found everything we were looking for. -var errDone = errors.New("done") - -// need is keyed by inode string. -func (li *linuxImpl) findProcessNames(need map[string]*portMeta) error { - if len(need) == 0 { - return nil - } - defer func() { - // Anything we didn't find, give up on and don't try to look for it later. - for _, pm := range need { - pm.needsProcName = false - } - }() - - err := foreachPID(func(pid mem.RO) error { - var procBuf [128]byte - fdPath := mem.Append(procBuf[:0], mem.S("/proc/")) - fdPath = mem.Append(fdPath, pid) - fdPath = mem.Append(fdPath, mem.S("/fd")) - - // Android logs a bunch of audit violations in logcat - // if we try to open things we don't have access - // to. So on Android only, ask if we have permission - // rather than just trying it to determine whether we - // have permission. - if runtime.GOOS == "android" && syscall.Access(string(fdPath), unix.R_OK) != nil { - return nil - } - - dirwalk.WalkShallow(mem.B(fdPath), func(fd mem.RO, de fs.DirEntry) error { - targetBuf := make([]byte, 64) // plenty big for "socket:[165614651]" - - linkPath := li.readlinkPathBuf[:0] - linkPath = fmt.Appendf(linkPath, "/proc/") - linkPath = mem.Append(linkPath, pid) - linkPath = append(linkPath, "/fd/"...) - linkPath = mem.Append(linkPath, fd) - linkPath = append(linkPath, 0) // terminating NUL - li.readlinkPathBuf = linkPath // to reuse its buffer next time - n, ok := readlink(linkPath, targetBuf) - if !ok { - // Not a symlink or no permission. - // Skip it. - return nil - } - - pe := need[string(targetBuf[:n])] // m[string([]byte)] avoids alloc - if pe == nil { - return nil - } - bs, err := os.ReadFile(fmt.Sprintf("/proc/%s/cmdline", pid.StringCopy())) - if err != nil { - // Usually shouldn't happen. One possibility is - // the process has gone away, so let's skip it. - return nil - } - - argv := strings.Split(strings.TrimSuffix(string(bs), "\x00"), "\x00") - if p, err := mem.ParseInt(pid, 10, 0); err == nil { - pe.pid = int(p) - } - pe.port.Process = argvSubject(argv...) - pid64, _ := mem.ParseInt(pid, 10, 0) - pe.port.Pid = int(pid64) - pe.needsProcName = false - delete(need, string(targetBuf[:n])) - if len(need) == 0 { - return errDone - } - return nil - }) - return nil - }) - if err == errDone { - return nil - } - return err -} - -func foreachPID(fn func(pidStr mem.RO) error) error { - err := dirwalk.WalkShallow(mem.S("/proc"), func(name mem.RO, de fs.DirEntry) error { - if !isNumeric(name) { - return nil - } - return fn(name) - }) - if os.IsNotExist(err) { - // This can happen if the directory we're - // reading disappears during the run. No big - // deal. - return nil - } - return err -} - -func isNumeric(s mem.RO) bool { - for i, n := 0, s.Len(); i < n; i++ { - b := s.At(i) - if b < '0' || b > '9' { - return false - } - } - return s.Len() > 0 -} - -// fieldIndex returns the offset in line where the Nth field (0-based) begins, or -1 -// if there aren't that many fields. Fields are separated by 1 or more spaces. -func fieldIndex(line []byte, n int) int { - skip := 0 - for i := 0; i <= n; i++ { - // Skip spaces. - for skip < len(line) && line[skip] == ' ' { - skip++ - } - if skip == len(line) { - return -1 - } - if i == n { - break - } - // Skip non-space. - for skip < len(line) && line[skip] != ' ' { - skip++ - } - } - return skip -} - -// path must be null terminated. -func readlink(path, buf []byte) (n int, ok bool) { - if len(buf) == 0 || len(path) < 2 || path[len(path)-1] != 0 { - return 0, false - } - var dirfd int = unix.AT_FDCWD - r0, _, e1 := unix.Syscall6(unix.SYS_READLINKAT, - uintptr(dirfd), - uintptr(unsafe.Pointer(&path[0])), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(len(buf)), - 0, 0) - n = int(r0) - if e1 != 0 { - return 0, false - } - return n, true -} diff --git a/vendor/tailscale.com/portlist/portlist_macos.go b/vendor/tailscale.com/portlist/portlist_macos.go deleted file mode 100644 index e67b2c9..0000000 --- a/vendor/tailscale.com/portlist/portlist_macos.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin && !ios - -package portlist - -import ( - "bufio" - "bytes" - "fmt" - "log" - "os/exec" - "strings" - "sync/atomic" - "time" - - "go4.org/mem" -) - -func init() { - newOSImpl = newMacOSImpl - - // We have to run netstat, which is a bit expensive, so don't do it too often. - pollInterval = 5 * time.Second -} - -type macOSImpl struct { - known map[protoPort]*portMeta // inode string => metadata - netstatPath string // lazily populated - - br *bufio.Reader // reused - portsBuf []Port - includeLocalhost bool -} - -type protoPort struct { - proto string - port uint16 -} - -type portMeta struct { - port Port - keep bool -} - -func newMacOSImpl(includeLocalhost bool) osImpl { - return &macOSImpl{ - known: map[protoPort]*portMeta{}, - br: bufio.NewReader(bytes.NewReader(nil)), - includeLocalhost: includeLocalhost, - } -} - -func (*macOSImpl) Close() error { return nil } - -func (im *macOSImpl) AppendListeningPorts(base []Port) ([]Port, error) { - var err error - im.portsBuf, err = im.appendListeningPortsNetstat(im.portsBuf[:0]) - if err != nil { - return nil, err - } - - for _, pm := range im.known { - pm.keep = false - } - - var needProcs bool - for _, p := range im.portsBuf { - fp := protoPort{ - proto: p.Proto, - port: p.Port, - } - if pm, ok := im.known[fp]; ok { - pm.keep = true - } else { - needProcs = true - im.known[fp] = &portMeta{ - port: p, - keep: true, - } - } - } - - ret := base - for k, m := range im.known { - if !m.keep { - delete(im.known, k) - } - } - - if needProcs { - im.addProcesses() // best effort - } - - for _, m := range im.known { - ret = append(ret, m.port) - } - return sortAndDedup(ret), nil -} - -func (im *macOSImpl) appendListeningPortsNetstat(base []Port) ([]Port, error) { - if im.netstatPath == "" { - var err error - im.netstatPath, err = exec.LookPath("netstat") - if err != nil { - return nil, fmt.Errorf("netstat: lookup: %v", err) - } - } - - cmd := exec.Command(im.netstatPath, "-na") - outPipe, err := cmd.StdoutPipe() - if err != nil { - return nil, err - } - im.br.Reset(outPipe) - - if err := cmd.Start(); err != nil { - return nil, err - } - defer cmd.Process.Wait() - defer cmd.Process.Kill() - - return appendParsePortsNetstat(base, im.br, im.includeLocalhost) -} - -var lsofFailed atomic.Bool - -// In theory, lsof could replace the function of both listPorts() and -// addProcesses(), since it provides a superset of the netstat output. -// However, "netstat -na" runs ~100x faster than lsof on my machine, so -// we should do it only if the list of open ports has actually changed. -// -// This fails in a macOS sandbox (i.e. in the Mac App Store or System -// Extension GUI build), but does at least work in the -// tailscaled-on-macos mode. -func (im *macOSImpl) addProcesses() error { - if lsofFailed.Load() { - // This previously failed in the macOS sandbox, so don't try again. - return nil - } - exe, err := exec.LookPath("lsof") - if err != nil { - return fmt.Errorf("lsof: lookup: %v", err) - } - lsofCmd := exec.Command(exe, "-F", "-n", "-P", "-O", "-S2", "-T", "-i4", "-i6") - outPipe, err := lsofCmd.StdoutPipe() - if err != nil { - return err - } - err = lsofCmd.Start() - if err != nil { - var stderr []byte - if xe, ok := err.(*exec.ExitError); ok { - stderr = xe.Stderr - } - // fails when run in a macOS sandbox, so make this non-fatal. - if lsofFailed.CompareAndSwap(false, true) { - log.Printf("portlist: can't run lsof in Mac sandbox; omitting process names from service list. Error details: %v, %s", err, bytes.TrimSpace(stderr)) - } - return nil - } - defer func() { - ps, err := lsofCmd.Process.Wait() - if err != nil || ps.ExitCode() != 0 { - log.Printf("portlist: can't run lsof in Mac sandbox; omitting process names from service list. Error: %v, exit code %d", err, ps.ExitCode()) - lsofFailed.Store(true) - } - }() - defer lsofCmd.Process.Kill() - - im.br.Reset(outPipe) - - var cmd, proto string - var pid int - for { - line, err := im.br.ReadBytes('\n') - if err != nil { - break - } - if len(line) < 1 { - continue - } - field, val := line[0], bytes.TrimSpace(line[1:]) - switch field { - case 'p': - // starting a new process - cmd = "" - proto = "" - pid = 0 - if p, err := mem.ParseInt(mem.B(val), 10, 0); err == nil { - pid = int(p) - } - case 'c': - cmd = string(val) // TODO(bradfitz): avoid garbage; cache process names between runs? - case 'P': - proto = lsofProtoLower(val) - case 'n': - if mem.Contains(mem.B(val), mem.S("->")) { - continue - } - // a listening port - port := parsePort(mem.B(val)) - if port <= 0 { - continue - } - pp := protoPort{proto, uint16(port)} - m := im.known[pp] - switch { - case m != nil: - m.port.Process = cmd - m.port.Pid = pid - default: - // ignore: processes and ports come and go - } - } - } - - return nil -} - -func lsofProtoLower(p []byte) string { - if string(p) == "TCP" { - return "tcp" - } - if string(p) == "UDP" { - return "udp" - } - return strings.ToLower(string(p)) -} diff --git a/vendor/tailscale.com/portlist/portlist_windows.go b/vendor/tailscale.com/portlist/portlist_windows.go deleted file mode 100644 index f449973..0000000 --- a/vendor/tailscale.com/portlist/portlist_windows.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package portlist - -import ( - "time" - - "tailscale.com/net/netstat" -) - -func init() { - newOSImpl = newWindowsImpl - // The portlist poller used to fork on Windows, which is insanely expensive, - // so historically we only did this every 5 seconds on Windows. Maybe we - // could reduce it down to 1 seconds like Linux, but nobody's benchmarked as - // of 2022-11-04. - pollInterval = 5 * time.Second -} - -type famPort struct { - proto string - port uint16 - pid uint32 -} - -type windowsImpl struct { - known map[famPort]*portMeta // inode string => metadata - includeLocalhost bool -} - -type portMeta struct { - port Port - keep bool -} - -func newWindowsImpl(includeLocalhost bool) osImpl { - return &windowsImpl{ - known: map[famPort]*portMeta{}, - includeLocalhost: includeLocalhost, - } -} - -func (*windowsImpl) Close() error { return nil } - -func (im *windowsImpl) AppendListeningPorts(base []Port) ([]Port, error) { - // TODO(bradfitz): netstat.Get makes a bunch of garbage. Add an Append-style - // API to that package instead/additionally. - tab, err := netstat.Get() - if err != nil { - return nil, err - } - - for _, pm := range im.known { - pm.keep = false - } - - ret := base - for _, e := range tab.Entries { - if e.State != "LISTEN" { - continue - } - if !im.includeLocalhost && !e.Local.Addr().IsUnspecified() { - continue - } - fp := famPort{ - proto: "tcp", // TODO(bradfitz): UDP too; add to netstat - port: e.Local.Port(), - pid: uint32(e.Pid), - } - pm, ok := im.known[fp] - if ok { - pm.keep = true - continue - } - var process string - if e.OSMetadata != nil { - if module, err := e.OSMetadata.GetModule(); err == nil { - process = module - } - } - pm = &portMeta{ - keep: true, - port: Port{ - Proto: "tcp", - Port: e.Local.Port(), - Process: process, - Pid: e.Pid, - }, - } - im.known[fp] = pm - } - - for k, m := range im.known { - if !m.keep { - delete(im.known, k) - continue - } - ret = append(ret, m.port) - } - - return sortAndDedup(ret), nil -} diff --git a/vendor/tailscale.com/posture/doc.go b/vendor/tailscale.com/posture/doc.go deleted file mode 100644 index d061065..0000000 --- a/vendor/tailscale.com/posture/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package posture contains functions to query the local system -// state for managed posture checks. -package posture diff --git a/vendor/tailscale.com/posture/hwaddr.go b/vendor/tailscale.com/posture/hwaddr.go deleted file mode 100644 index dd0b6d8..0000000 --- a/vendor/tailscale.com/posture/hwaddr.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package posture - -import ( - "net/netip" - "slices" - - "tailscale.com/net/netmon" -) - -// GetHardwareAddrs returns the hardware addresses of all non-loopback -// network interfaces. -func GetHardwareAddrs() (hwaddrs []string, err error) { - err = netmon.ForeachInterface(func(i netmon.Interface, _ []netip.Prefix) { - if i.IsLoopback() { - return - } - if a := i.HardwareAddr.String(); a != "" { - hwaddrs = append(hwaddrs, a) - } - }) - slices.Sort(hwaddrs) - return slices.Compact(hwaddrs), err -} diff --git a/vendor/tailscale.com/posture/serialnumber_ios.go b/vendor/tailscale.com/posture/serialnumber_ios.go deleted file mode 100644 index 55d0e43..0000000 --- a/vendor/tailscale.com/posture/serialnumber_ios.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package posture - -import ( - "fmt" - - "tailscale.com/types/logger" - "tailscale.com/util/syspolicy" -) - -// GetSerialNumbers returns the serial number of the iOS/tvOS device as reported by an -// MDM solution. It requires configuration via the DeviceSerialNumber system policy. -// This is the only way to gather serial numbers on iOS and tvOS. -func GetSerialNumbers(_ logger.Logf) ([]string, error) { - s, err := syspolicy.GetString(syspolicy.DeviceSerialNumber, "") - if err != nil { - return nil, fmt.Errorf("failed to get serial number from MDM: %v", err) - } - if s != "" { - return []string{s}, nil - } - return nil, nil -} diff --git a/vendor/tailscale.com/posture/serialnumber_macos.go b/vendor/tailscale.com/posture/serialnumber_macos.go deleted file mode 100644 index 48355d3..0000000 --- a/vendor/tailscale.com/posture/serialnumber_macos.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build cgo && darwin && !ios - -package posture - -// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -// #include -// #include -// -// #if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 -// #define kIOMainPortDefault kIOMasterPortDefault -// #endif -// -// const char * -// getSerialNumber() -// { -// CFMutableDictionaryRef matching = IOServiceMatching("IOPlatformExpertDevice"); -// if (!matching) { -// return "err: failed to create dictionary to match IOServices"; -// } -// -// io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, matching); -// if (!service) { -// return "err: failed to look up registered IOService objects that match a matching dictionary"; -// } -// -// CFStringRef serialNumberRef = IORegistryEntryCreateCFProperty( -// service, -// CFSTR("IOPlatformSerialNumber"), -// kCFAllocatorDefault, -// 0 -// ); -// if (!serialNumberRef) { -// return "err: failed to look up serial number in IORegistry"; -// } -// -// CFIndex length = CFStringGetLength(serialNumberRef); -// CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; -// char *serialNumberBuf = (char *)malloc(max_size); -// -// bool result = CFStringGetCString(serialNumberRef, serialNumberBuf, max_size, kCFStringEncodingUTF8); -// -// CFRelease(serialNumberRef); -// IOObjectRelease(service); -// -// if (!result) { -// free(serialNumberBuf); -// -// return "err: failed to convert serial number reference to string"; -// } -// -// return serialNumberBuf; -// } -import "C" -import ( - "fmt" - "strings" - - "tailscale.com/types/logger" -) - -// GetSerialNumber returns the platform serial sumber as reported by IOKit. -func GetSerialNumbers(_ logger.Logf) ([]string, error) { - csn := C.getSerialNumber() - serialNumber := C.GoString(csn) - - if err, ok := strings.CutPrefix(serialNumber, "err: "); ok { - return nil, fmt.Errorf("failed to get serial number from IOKit: %s", err) - } - - return []string{serialNumber}, nil -} diff --git a/vendor/tailscale.com/posture/serialnumber_notmacos.go b/vendor/tailscale.com/posture/serialnumber_notmacos.go deleted file mode 100644 index 8b91738..0000000 --- a/vendor/tailscale.com/posture/serialnumber_notmacos.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Build on Windows, Linux and *BSD - -//go:build windows || (linux && !android) || freebsd || openbsd || dragonfly || netbsd - -package posture - -import ( - "fmt" - "strings" - - "github.com/digitalocean/go-smbios/smbios" - "tailscale.com/types/logger" -) - -// getByteFromSmbiosStructure retrieves a 8-bit unsigned integer at the given specOffset. -func getByteFromSmbiosStructure(s *smbios.Structure, specOffset int) uint8 { - // the `Formatted` byte slice is missing the first 4 bytes of the structure that are stripped out as header info. - // so we need to subtract 4 from the offset mentioned in the SMBIOS documentation to get the right value. - index := specOffset - 4 - if index >= len(s.Formatted) || index < 0 { - return 0 - } - - return s.Formatted[index] -} - -// getStringFromSmbiosStructure retrieves a string at the given specOffset. -// Returns an empty string if no string was present. -func getStringFromSmbiosStructure(s *smbios.Structure, specOffset int) string { - index := getByteFromSmbiosStructure(s, specOffset) - - if index == 0 || int(index) > len(s.Strings) { - return "" - } - - str := s.Strings[index-1] - trimmed := strings.TrimSpace(str) - - return trimmed -} - -// Product Table (Type 1) structure -// https://web.archive.org/web/20220126173219/https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf -// Page 34 and onwards. -const ( - // Serial is present at the same offset in all IDs - serialNumberOffset = 0x07 - - productID = 1 - baseboardID = 2 - chassisID = 3 -) - -var ( - idToTableName = map[int]string{ - 1: "product", - 2: "baseboard", - 3: "chassis", - } - validTables []string - numOfTables int -) - -func init() { - for _, table := range idToTableName { - validTables = append(validTables, table) - } - numOfTables = len(validTables) -} - -func GetSerialNumbers(logf logger.Logf) ([]string, error) { - // Find SMBIOS data in operating system-specific location. - rc, _, err := smbios.Stream() - if err != nil { - return nil, fmt.Errorf("failed to open dmi/smbios stream: %w", err) - } - defer rc.Close() - - // Decode SMBIOS structures from the stream. - d := smbios.NewDecoder(rc) - ss, err := d.Decode() - if err != nil { - return nil, fmt.Errorf("failed to decode dmi/smbios structures: %w", err) - } - - serials := make([]string, 0, numOfTables) - - for _, s := range ss { - switch s.Header.Type { - case productID, baseboardID, chassisID: - serial := getStringFromSmbiosStructure(s, serialNumberOffset) - - if serial != "" { - serials = append(serials, serial) - } - } - } - return serials, nil -} diff --git a/vendor/tailscale.com/posture/serialnumber_stub.go b/vendor/tailscale.com/posture/serialnumber_stub.go deleted file mode 100644 index cdabf03..0000000 --- a/vendor/tailscale.com/posture/serialnumber_stub.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// android: not implemented -// js: not implemented -// plan9: not implemented -// solaris: currently unsupported by go-smbios: -// https://github.com/digitalocean/go-smbios/pull/21 - -//go:build android || solaris || plan9 || js || wasm || tamago || aix || (darwin && !cgo && !ios) - -package posture - -import ( - "errors" - - "tailscale.com/types/logger" -) - -// GetSerialNumber returns client machine serial number(s). -func GetSerialNumbers(_ logger.Logf) ([]string, error) { - return nil, errors.New("not implemented") -} diff --git a/vendor/tailscale.com/proxymap/proxymap.go b/vendor/tailscale.com/proxymap/proxymap.go index dfe6f2d..20dc96c 100644 --- a/vendor/tailscale.com/proxymap/proxymap.go +++ b/vendor/tailscale.com/proxymap/proxymap.go @@ -9,9 +9,9 @@ import ( "fmt" "net/netip" "strings" - "sync" "time" + "tailscale.com/syncs" "tailscale.com/util/mak" ) @@ -22,7 +22,7 @@ import ( // ask tailscaled (via the LocalAPI WhoIs method) the Tailscale identity that a // given localhost:port corresponds to. type Mapper struct { - mu sync.Mutex + mu syncs.Mutex // m holds the mapping from localhost IP:ports to Tailscale IPs. It is // keyed first by the protocol ("tcp" or "udp"), then by the IP:port. diff --git a/vendor/tailscale.com/pull-toolchain.sh b/vendor/tailscale.com/pull-toolchain.sh index f5a19e7..eb8febf 100644 --- a/vendor/tailscale.com/pull-toolchain.sh +++ b/vendor/tailscale.com/pull-toolchain.sh @@ -11,6 +11,10 @@ if [ "$upstream" != "$current" ]; then echo "$upstream" >go.toolchain.rev fi -if [ -n "$(git diff-index --name-only HEAD -- go.toolchain.rev)" ]; then +./tool/go version 2>/dev/null | awk '{print $3}' | sed 's/^go//' > go.toolchain.version + +./update-flake.sh + +if [ -n "$(git diff-index --name-only HEAD -- go.toolchain.rev go.toolchain.rev.sri go.toolchain.version)" ]; then echo "pull-toolchain.sh: changes imported. Use git commit to make them permanent." >&2 fi diff --git a/vendor/tailscale.com/safesocket/pipe_windows.go b/vendor/tailscale.com/safesocket/pipe_windows.go index 5828341..2968542 100644 --- a/vendor/tailscale.com/safesocket/pipe_windows.go +++ b/vendor/tailscale.com/safesocket/pipe_windows.go @@ -10,6 +10,7 @@ import ( "fmt" "net" "runtime" + "sync" "time" "github.com/tailscale/go-winio" @@ -49,7 +50,9 @@ func listen(path string) (net.Listener, error) { // embedded net.Conn must be a go-winio PipeConn. type WindowsClientConn struct { winioPipeConn - token windows.Token + tokenOnce sync.Once + token windows.Token // or zero, if we couldn't obtain the client's token + tokenErr error } // winioPipeConn is a subset of the interface implemented by the go-winio's @@ -79,12 +82,63 @@ func (conn *WindowsClientConn) ClientPID() (int, error) { return int(pid), nil } -// Token returns the Windows access token of the client user. -func (conn *WindowsClientConn) Token() windows.Token { - return conn.token +// CheckToken returns an error if the client user's access token could not be retrieved, +// for example when the client opens the pipe with an anonymous impersonation level. +// +// Deprecated: use [WindowsClientConn.Token] instead. +func (conn *WindowsClientConn) CheckToken() error { + _, err := conn.getToken() + return err +} + +// getToken returns the Windows access token of the client user, +// or an error if the token could not be retrieved, for example +// when the client opens the pipe with an anonymous impersonation level. +// +// The connection retains ownership of the returned token handle; +// the caller must not close it. +// +// TODO(nickkhyl): Remove this, along with [WindowsClientConn.CheckToken], +// once [ipnauth.ConnIdentity] is removed in favor of [ipnauth.Actor]. +func (conn *WindowsClientConn) getToken() (windows.Token, error) { + conn.tokenOnce.Do(func() { + conn.token, conn.tokenErr = clientUserAccessToken(conn.winioPipeConn) + }) + return conn.token, conn.tokenErr +} + +// Token returns the Windows access token of the client user, +// or an error if the token could not be retrieved, for example +// when the client opens the pipe with an anonymous impersonation level. +// +// The caller is responsible for closing the returned token handle. +func (conn *WindowsClientConn) Token() (windows.Token, error) { + token, err := conn.getToken() + if err != nil { + return 0, err + } + + var dupToken windows.Handle + if err := windows.DuplicateHandle( + windows.CurrentProcess(), + windows.Handle(token), + windows.CurrentProcess(), + &dupToken, + 0, + false, + windows.DUPLICATE_SAME_ACCESS, + ); err != nil { + return 0, err + } + return windows.Token(dupToken), nil } func (conn *WindowsClientConn) Close() error { + // Either wait for any pending [WindowsClientConn.Token] calls to complete, + // or ensure that the token will never be opened. + conn.tokenOnce.Do(func() { + conn.tokenErr = net.ErrClosed + }) if conn.token != 0 { conn.token.Close() conn.token = 0 @@ -110,17 +164,7 @@ func (lw *winIOPipeListener) Accept() (net.Conn, error) { conn.Close() return nil, fmt.Errorf("unexpected type %T from winio.ListenPipe listener (itself a %T)", conn, lw.Listener) } - - token, err := clientUserAccessToken(pipeConn) - if err != nil { - conn.Close() - return nil, err - } - - return &WindowsClientConn{ - winioPipeConn: pipeConn, - token: token, - }, nil + return &WindowsClientConn{winioPipeConn: pipeConn}, nil } func clientUserAccessToken(pc winioPipeConn) (windows.Token, error) { diff --git a/vendor/tailscale.com/safesocket/safesocket.go b/vendor/tailscale.com/safesocket/safesocket.go index 721b694..287cdca 100644 --- a/vendor/tailscale.com/safesocket/safesocket.go +++ b/vendor/tailscale.com/safesocket/safesocket.go @@ -11,6 +11,9 @@ import ( "net" "runtime" "time" + + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" ) type closeable interface { @@ -31,7 +34,8 @@ func ConnCloseWrite(c net.Conn) error { } var processStartTime = time.Now() -var tailscaledProcExists = func() bool { return false } // set by safesocket_ps.go + +var tailscaledProcExists feature.Hook[func() bool] // tailscaledStillStarting reports whether tailscaled is probably // still starting up. That is, it reports whether the caller should @@ -50,7 +54,8 @@ func tailscaledStillStarting() bool { if d > 5*time.Second { return false } - return tailscaledProcExists() + f, ok := tailscaledProcExists.GetOk() + return ok && f() } // ConnectContext connects to tailscaled using a unix socket or named pipe. @@ -104,7 +109,12 @@ func LocalTCPPortAndToken() (port int, token string, err error) { // PlatformUsesPeerCreds reports whether the current platform uses peer credentials // to authenticate connections. -func PlatformUsesPeerCreds() bool { return GOOSUsesPeerCreds(runtime.GOOS) } +func PlatformUsesPeerCreds() bool { + if !buildfeatures.HasUnixSocketIdentity { + return false + } + return GOOSUsesPeerCreds(runtime.GOOS) +} // GOOSUsesPeerCreds is like PlatformUsesPeerCreds but takes a // runtime.GOOS value instead of using the current one. diff --git a/vendor/tailscale.com/safesocket/safesocket_plan9.go b/vendor/tailscale.com/safesocket/safesocket_plan9.go index 196c1df..c8a5e3b 100644 --- a/vendor/tailscale.com/safesocket/safesocket_plan9.go +++ b/vendor/tailscale.com/safesocket/safesocket_plan9.go @@ -7,119 +7,13 @@ package safesocket import ( "context" - "fmt" "net" - "os" - "syscall" - "time" - - "golang.org/x/sys/plan9" ) -// Plan 9's devsrv srv(3) is a server registry and -// it is conventionally bound to "/srv" in the default -// namespace. It is "a one level directory for holding -// already open channels to services". Post one end of -// a pipe to "/srv/tailscale.sock" and use the other -// end for communication with a requestor. Plan 9 pipes -// are bidirectional. - -type plan9SrvAddr string - -func (sl plan9SrvAddr) Network() string { - return "/srv" -} - -func (sl plan9SrvAddr) String() string { - return string(sl) -} - -// There is no net.FileListener for Plan 9 at this time -type plan9SrvListener struct { - name string - srvf *os.File - file *os.File -} - -func (sl *plan9SrvListener) Accept() (net.Conn, error) { - // sl.file is the server end of the pipe that's - // connected to /srv/tailscale.sock - return plan9FileConn{name: sl.name, file: sl.file}, nil -} - -func (sl *plan9SrvListener) Close() error { - sl.file.Close() - return sl.srvf.Close() -} - -func (sl *plan9SrvListener) Addr() net.Addr { - return plan9SrvAddr(sl.name) -} - -type plan9FileConn struct { - name string - file *os.File -} - -func (fc plan9FileConn) Read(b []byte) (n int, err error) { - return fc.file.Read(b) -} -func (fc plan9FileConn) Write(b []byte) (n int, err error) { - return fc.file.Write(b) -} -func (fc plan9FileConn) Close() error { - return fc.file.Close() -} -func (fc plan9FileConn) LocalAddr() net.Addr { - return plan9SrvAddr(fc.name) -} -func (fc plan9FileConn) RemoteAddr() net.Addr { - return plan9SrvAddr(fc.name) -} -func (fc plan9FileConn) SetDeadline(t time.Time) error { - return syscall.EPLAN9 -} -func (fc plan9FileConn) SetReadDeadline(t time.Time) error { - return syscall.EPLAN9 -} -func (fc plan9FileConn) SetWriteDeadline(t time.Time) error { - return syscall.EPLAN9 -} - func connect(_ context.Context, path string) (net.Conn, error) { - f, err := os.OpenFile(path, os.O_RDWR, 0666) - if err != nil { - return nil, err - } - - return plan9FileConn{name: path, file: f}, nil + return net.Dial("tcp", "localhost:5252") } -// Create an entry in /srv, open a pipe, write the -// client end to the entry and return the server -// end of the pipe to the caller. When the server -// end of the pipe is closed, /srv name associated -// with it will be removed (controlled by ORCLOSE flag) func listen(path string) (net.Listener, error) { - const O_RCLOSE = 64 // remove on close; should be in plan9 package - var pip [2]int - - err := plan9.Pipe(pip[:]) - if err != nil { - return nil, err - } - defer plan9.Close(pip[1]) - - srvfd, err := plan9.Create(path, plan9.O_WRONLY|plan9.O_CLOEXEC|O_RCLOSE, 0600) - if err != nil { - return nil, err - } - srv := os.NewFile(uintptr(srvfd), path) - - _, err = fmt.Fprintf(srv, "%d", pip[1]) - if err != nil { - return nil, err - } - - return &plan9SrvListener{name: path, srvf: srv, file: os.NewFile(uintptr(pip[0]), path)}, nil + return net.Listen("tcp", "localhost:5252") } diff --git a/vendor/tailscale.com/safesocket/safesocket_ps.go b/vendor/tailscale.com/safesocket/safesocket_ps.go index 1819784..d3f409d 100644 --- a/vendor/tailscale.com/safesocket/safesocket_ps.go +++ b/vendor/tailscale.com/safesocket/safesocket_ps.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build linux || windows || (darwin && !ios) || freebsd +//go:build ((linux && !android) || windows || (darwin && !ios) || freebsd) && !ts_omit_cliconndiag package safesocket @@ -12,7 +12,7 @@ import ( ) func init() { - tailscaledProcExists = func() bool { + tailscaledProcExists.Set(func() bool { procs, err := ps.Processes() if err != nil { return false @@ -30,5 +30,5 @@ func init() { } } return false - } + }) } diff --git a/vendor/tailscale.com/shell.nix b/vendor/tailscale.com/shell.nix index 4d2e243..ccec5fa 100644 --- a/vendor/tailscale.com/shell.nix +++ b/vendor/tailscale.com/shell.nix @@ -16,4 +16,4 @@ ) { src = ./.; }).shellNix -# nix-direnv cache busting line: sha256-xO1DuLWi6/lpA9ubA2ZYVJM+CkVNA5IaVGZxX9my0j0= +# nix-direnv cache busting line: sha256-WeMTOkERj4hvdg4yPaZ1gRgKnhRIBXX55kUVbX/k/xM= diff --git a/vendor/tailscale.com/syncs/locked.go b/vendor/tailscale.com/syncs/locked.go index d204866..d2e9ede 100644 --- a/vendor/tailscale.com/syncs/locked.go +++ b/vendor/tailscale.com/syncs/locked.go @@ -8,7 +8,7 @@ import ( ) // AssertLocked panics if m is not locked. -func AssertLocked(m *sync.Mutex) { +func AssertLocked(m *Mutex) { if m.TryLock() { m.Unlock() panic("mutex is not locked") @@ -16,7 +16,7 @@ func AssertLocked(m *sync.Mutex) { } // AssertRLocked panics if rw is not locked for reading or writing. -func AssertRLocked(rw *sync.RWMutex) { +func AssertRLocked(rw *RWMutex) { if rw.TryLock() { rw.Unlock() panic("mutex is not locked") diff --git a/vendor/tailscale.com/syncs/mutex.go b/vendor/tailscale.com/syncs/mutex.go new file mode 100644 index 0000000..8034e17 --- /dev/null +++ b/vendor/tailscale.com/syncs/mutex.go @@ -0,0 +1,23 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_mutex_debug + +package syncs + +import "sync" + +// Mutex is an alias for sync.Mutex. +// +// It's only not a sync.Mutex when built with the ts_mutex_debug build tag. +type Mutex = sync.Mutex + +// RWMutex is an alias for sync.RWMutex. +// +// It's only not a sync.RWMutex when built with the ts_mutex_debug build tag. +type RWMutex = sync.RWMutex + +// RequiresMutex declares the caller assumes it has the given +// mutex held. In non-debug builds, it's a no-op and compiles to +// nothing. +func RequiresMutex(mu *sync.Mutex) {} diff --git a/vendor/tailscale.com/syncs/mutex_debug.go b/vendor/tailscale.com/syncs/mutex_debug.go new file mode 100644 index 0000000..55a9b12 --- /dev/null +++ b/vendor/tailscale.com/syncs/mutex_debug.go @@ -0,0 +1,22 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_mutex_debug + +package syncs + +import "sync" + +type Mutex struct { + sync.Mutex +} + +type RWMutex struct { + sync.RWMutex +} + +func RequiresMutex(mu *sync.Mutex) { + // TODO: check +} + +// TODO(bradfitz): actually track stuff when in debug mode. diff --git a/vendor/tailscale.com/syncs/syncs.go b/vendor/tailscale.com/syncs/syncs.go index 337fca7..3b37bca 100644 --- a/vendor/tailscale.com/syncs/syncs.go +++ b/vendor/tailscale.com/syncs/syncs.go @@ -67,12 +67,18 @@ func (v *AtomicValue[T]) Swap(x T) (old T) { if oldV != nil { return oldV.(wrappedValue[T]).v } - return old + return old // zero value of T } // CompareAndSwap executes the compare-and-swap operation for the Value. +// It panics if T is not comparable. func (v *AtomicValue[T]) CompareAndSwap(oldV, newV T) (swapped bool) { - return v.v.CompareAndSwap(wrappedValue[T]{oldV}, wrappedValue[T]{newV}) + var zero T + return v.v.CompareAndSwap(wrappedValue[T]{oldV}, wrappedValue[T]{newV}) || + // In the edge-case where [atomic.Value.Store] is uninitialized + // and trying to compare with the zero value of T, + // then compare-and-swap with the nil any value. + (any(oldV) == any(zero) && v.v.CompareAndSwap(any(nil), wrappedValue[T]{newV})) } // MutexValue is a value protected by a mutex. @@ -195,6 +201,13 @@ func NewSemaphore(n int) Semaphore { return Semaphore{c: make(chan struct{}, n)} } +// Len reports the number of in-flight acquisitions. +// It is incremented whenever the semaphore is acquired. +// It is decremented whenever the semaphore is released. +func (s Semaphore) Len() int { + return len(s.c) +} + // Acquire blocks until a resource is acquired. func (s Semaphore) Acquire() { s.c <- struct{}{} @@ -396,19 +409,3 @@ func (m *Map[K, V]) Swap(key K, value V) (oldValue V) { mak.Set(&m.m, key, value) return oldValue } - -// WaitGroup is identical to [sync.WaitGroup], -// but provides a Go method to start a goroutine. -type WaitGroup struct{ sync.WaitGroup } - -// Go calls the given function in a new goroutine. -// It automatically increments the counter before execution and -// automatically decrements the counter after execution. -// It must not be called concurrently with Wait. -func (wg *WaitGroup) Go(f func()) { - wg.Add(1) - go func() { - defer wg.Done() - f() - }() -} diff --git a/vendor/tailscale.com/tailcfg/c2ntypes.go b/vendor/tailscale.com/tailcfg/c2ntypes.go index 66f9578..d78baef 100644 --- a/vendor/tailscale.com/tailcfg/c2ntypes.go +++ b/vendor/tailscale.com/tailcfg/c2ntypes.go @@ -5,7 +5,10 @@ package tailcfg -import "net/netip" +import ( + "encoding/json" + "net/netip" +) // C2NSSHUsernamesRequest is the request for the /ssh/usernames. // A GET request without a request body is equivalent to the zero value of this type. @@ -117,3 +120,29 @@ type C2NVIPServicesResponse struct { // changes. This value matches what is reported in latest [Hostinfo.ServicesHash]. ServicesHash string } + +// C2NDebugNetmapRequest is the request (from control to node) for the +// /debug/netmap handler. +type C2NDebugNetmapRequest struct { + // Candidate is an optional full MapResponse to be used for generating a candidate + // network map. If unset, only the current network map is returned. + Candidate *MapResponse `json:"candidate,omitzero"` + + // OmitFields is an optional list of netmap fields to omit from the response. + // If unset, no fields are omitted. + OmitFields []string `json:"omitFields,omitzero"` +} + +// C2NDebugNetmapResponse is the response (from node to control) from the +// /debug/netmap handler. It contains the current network map and, if a +// candidate full MapResponse was provided in the request, a candidate network +// map generated from it. +// To avoid import cycles, and reflect the non-stable nature of +// netmap.NetworkMap values, they are returned as json.RawMessage. +type C2NDebugNetmapResponse struct { + // Current is the current network map (netmap.NetworkMap). + Current json.RawMessage `json:"current"` + + // Candidate is a network map produced based on the candidate MapResponse. + Candidate json.RawMessage `json:"candidate,omitzero"` +} diff --git a/vendor/tailscale.com/tailcfg/proto_port_range.go b/vendor/tailscale.com/tailcfg/proto_port_range.go index f65c588..03505db 100644 --- a/vendor/tailscale.com/tailcfg/proto_port_range.go +++ b/vendor/tailscale.com/tailcfg/proto_port_range.go @@ -5,7 +5,6 @@ package tailcfg import ( "errors" - "fmt" "strconv" "strings" @@ -70,14 +69,7 @@ func (ppr ProtoPortRange) String() string { buf.Write(text) buf.Write([]byte(":")) } - pr := ppr.Ports - if pr.First == pr.Last { - fmt.Fprintf(&buf, "%d", pr.First) - } else if pr == PortRangeAny { - buf.WriteByte('*') - } else { - fmt.Fprintf(&buf, "%d-%d", pr.First, pr.Last) - } + buf.WriteString(ppr.Ports.String()) return buf.String() } @@ -104,7 +96,7 @@ func parseProtoPortRange(ipProtoPort string) (*ProtoPortRange, error) { if !strings.Contains(ipProtoPort, ":") { ipProtoPort = "*:" + ipProtoPort } - protoStr, portRange, err := parseHostPortRange(ipProtoPort) + protoStr, portRange, err := ParseHostPortRange(ipProtoPort) if err != nil { return nil, err } @@ -126,9 +118,9 @@ func parseProtoPortRange(ipProtoPort string) (*ProtoPortRange, error) { return ppr, nil } -// parseHostPortRange parses hostport as HOST:PORTS where HOST is +// ParseHostPortRange parses hostport as HOST:PORTS where HOST is // returned unchanged and PORTS is is either "*" or PORTLOW-PORTHIGH ranges. -func parseHostPortRange(hostport string) (host string, ports PortRange, err error) { +func ParseHostPortRange(hostport string) (host string, ports PortRange, err error) { hostport = strings.ToLower(hostport) colon := strings.LastIndexByte(hostport, ':') if colon < 0 { diff --git a/vendor/tailscale.com/tailcfg/tailcfg.go b/vendor/tailscale.com/tailcfg/tailcfg.go index 83fab9c..8468aa0 100644 --- a/vendor/tailscale.com/tailcfg/tailcfg.go +++ b/vendor/tailscale.com/tailcfg/tailcfg.go @@ -5,7 +5,7 @@ // the node and the coordination server. package tailcfg -//go:generate go run tailscale.com/cmd/viewer --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile --clonefunc +//go:generate go run tailscale.com/cmd/viewer --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy --clonefunc import ( "bytes" @@ -17,9 +17,11 @@ import ( "net/netip" "reflect" "slices" + "strconv" "strings" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/types/dnstype" "tailscale.com/types/key" "tailscale.com/types/opt" @@ -160,7 +162,23 @@ type CapabilityVersion int // - 113: 2025-01-20: Client communicates to control whether funnel is enabled by sending Hostinfo.IngressEnabled (#14688) // - 114: 2025-01-30: NodeAttrMaxKeyDuration CapMap defined, clients might use it (no tailscaled code change) (#14829) // - 115: 2025-03-07: Client understands DERPRegion.NoMeasureNoHome. -const CurrentCapabilityVersion CapabilityVersion = 115 +// - 116: 2025-05-05: Client serves MagicDNS "AAAA" if NodeAttrMagicDNSPeerAAAA set on self node +// - 117: 2025-05-28: Client understands DisplayMessages (structured health messages), but not necessarily PrimaryAction. +// - 118: 2025-07-01: Client sends Hostinfo.StateEncrypted to report whether the state file is encrypted at rest (#15830) +// - 119: 2025-07-10: Client uses Hostinfo.Location.Priority to prioritize one route over another. +// - 120: 2025-07-15: Client understands peer relay disco messages, and implements peer client and relay server functions +// - 121: 2025-07-19: Client understands peer relay endpoint alloc with [disco.AllocateUDPRelayEndpointRequest] & [disco.AllocateUDPRelayEndpointResponse] +// - 122: 2025-07-21: Client sends Hostinfo.ExitNodeID to report which exit node it has selected, if any. +// - 123: 2025-07-28: fix deadlock regression from cryptokey routing change (issue #16651) +// - 124: 2025-08-08: removed NodeAttrDisableMagicSockCryptoRouting support, crypto routing is now mandatory +// - 125: 2025-08-11: dnstype.Resolver adds UseWithExitNode field. +// - 126: 2025-09-17: Client uses seamless key renewal unless disabled by control (tailscale/corp#31479) +// - 127: 2025-09-19: can handle C2N /debug/netmap. +// - 128: 2025-10-02: can handle C2N /debug/health. +// - 129: 2025-10-04: Fixed sleep/wake deadlock in magicsock when using peer relay (PR #17449) +// - 130: 2025-10-06: client can send key.HardwareAttestationPublic and key.HardwareAttestationKeySignature in MapRequest +// - 131: 2025-11-25: client respects [NodeAttrDefaultAutoUpdate] +const CurrentCapabilityVersion CapabilityVersion = 131 // ID is an integer ID for a user, node, or login allocated by the // control plane. @@ -238,9 +256,9 @@ func (u StableNodeID) IsZero() bool { // have a general gmail address login associated with the user. type User struct { ID UserID - DisplayName string // if non-empty overrides Login field - ProfilePicURL string // if non-empty overrides Login field - Created time.Time + DisplayName string // if non-empty overrides Login field + ProfilePicURL string `json:",omitzero"` // if non-empty overrides Login field + Created time.Time `json:",omitzero"` } // Login is a user from a specific identity provider, not associated with any @@ -251,7 +269,7 @@ type Login struct { Provider string // "google", "github", "okta_foo", etc. LoginName string // an email address or "email-ish" string (like alice@github) DisplayName string // from the IdP - ProfilePicURL string // from the IdP + ProfilePicURL string `json:",omitzero"` // from the IdP } // A UserProfile is display-friendly data for a [User]. @@ -261,7 +279,7 @@ type UserProfile struct { ID UserID LoginName string // "alice@smith.com"; for display purposes only (provider is not listed) DisplayName string // "Alice Smith" - ProfilePicURL string `json:",omitempty"` + ProfilePicURL string `json:",omitzero"` } func (p *UserProfile) Equal(p2 *UserProfile) bool { @@ -328,13 +346,13 @@ type Node struct { User UserID // Sharer, if non-zero, is the user who shared this node, if different than User. - Sharer UserID `json:",omitempty"` + Sharer UserID `json:",omitzero"` Key key.NodePublic - KeyExpiry time.Time // the zero value if this node does not expire + KeyExpiry time.Time `json:",omitzero"` // the zero value if this node does not expire KeySignature tkatype.MarshaledSignature `json:",omitempty"` - Machine key.MachinePublic - DiscoKey key.DiscoPublic + Machine key.MachinePublic `json:",omitzero"` + DiscoKey key.DiscoPublic `json:",omitzero"` // Addresses are the IP addresses of this Node directly. Addresses []netip.Prefix @@ -344,7 +362,7 @@ type Node struct { // As of CapabilityVersion 112, this may be nil (null or undefined) on the wire // to mean the same as Addresses. Internally, it is always filled in with // its possibly-implicit value. - AllowedIPs []netip.Prefix + AllowedIPs []netip.Prefix `json:",omitzero"` // _not_ omitempty; only nil is special Endpoints []netip.AddrPort `json:",omitempty"` // IP+port (public via STUN, and local LANs) @@ -358,18 +376,18 @@ type Node struct { // this field. See tailscale/tailscale#14636. Do not use this field in code // other than in the upgradeNode func, which canonicalizes it to HomeDERP // if it arrives as a LegacyDERPString string on the wire. - LegacyDERPString string `json:"DERP,omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint + LegacyDERPString string `json:"DERP,omitzero"` // DERP-in-IP:port ("127.3.3.40:N") endpoint // HomeDERP is the modern version of the DERP string field, with just an // integer. The client advertises support for this as of capver 111. // // HomeDERP may be zero if not (yet) known, but ideally always be non-zero // for magicsock connectivity to function normally. - HomeDERP int `json:",omitempty"` // DERP region ID of the node's home DERP + HomeDERP int `json:",omitzero"` // DERP region ID of the node's home DERP - Hostinfo HostinfoView - Created time.Time - Cap CapabilityVersion `json:",omitempty"` // if non-zero, the node's capability version; old servers might not send + Hostinfo HostinfoView `json:",omitzero"` + Created time.Time `json:",omitzero"` + Cap CapabilityVersion `json:",omitzero"` // if non-zero, the node's capability version; old servers might not send // Tags are the list of ACL tags applied to this node. // Tags take the form of `tag:` where value starts @@ -436,25 +454,25 @@ type Node struct { // it do anything. It is the tailscaled client's job to double-check the // MapResponse's PacketFilter to verify that its AllowedIPs will not be // accepted by the packet filter. - UnsignedPeerAPIOnly bool `json:",omitempty"` + UnsignedPeerAPIOnly bool `json:",omitzero"` // The following three computed fields hold the various names that can // be used for this node in UIs. They are populated from controlclient // (not from control) by calling node.InitDisplayNames. These can be // used directly or accessed via node.DisplayName or node.DisplayNames. - ComputedName string `json:",omitempty"` // MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS) + ComputedName string `json:",omitzero"` // MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS) computedHostIfDifferent string // hostname, if different than ComputedName, otherwise empty - ComputedNameWithHost string `json:",omitempty"` // either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set + ComputedNameWithHost string `json:",omitzero"` // either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set // DataPlaneAuditLogID is the per-node logtail ID used for data plane audit logging. - DataPlaneAuditLogID string `json:",omitempty"` + DataPlaneAuditLogID string `json:",omitzero"` // Expired is whether this node's key has expired. Control may send // this; clients are only allowed to set this from false to true. On // the client, this is calculated client-side based on a timestamp sent // from control, to avoid clock skew issues. - Expired bool `json:",omitempty"` + Expired bool `json:",omitzero"` // SelfNodeV4MasqAddrForThisPeer is the IPv4 that this peer knows the current node as. // It may be empty if the peer knows the current node by its native @@ -469,7 +487,7 @@ type Node struct { // This only applies to traffic originating from the current node to the // peer or any of its subnets. Traffic originating from subnet routes will // not be masqueraded (e.g. in case of --snat-subnet-routes). - SelfNodeV4MasqAddrForThisPeer *netip.Addr `json:",omitempty"` + SelfNodeV4MasqAddrForThisPeer *netip.Addr `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 // SelfNodeV6MasqAddrForThisPeer is the IPv6 that this peer knows the current node as. // It may be empty if the peer knows the current node by its native @@ -484,17 +502,17 @@ type Node struct { // This only applies to traffic originating from the current node to the // peer or any of its subnets. Traffic originating from subnet routes will // not be masqueraded (e.g. in case of --snat-subnet-routes). - SelfNodeV6MasqAddrForThisPeer *netip.Addr `json:",omitempty"` + SelfNodeV6MasqAddrForThisPeer *netip.Addr `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 // IsWireGuardOnly indicates that this is a non-Tailscale WireGuard peer, it // is not expected to speak Disco or DERP, and it must have Endpoints in // order to be reachable. - IsWireGuardOnly bool `json:",omitempty"` + IsWireGuardOnly bool `json:",omitzero"` // IsJailed indicates that this node is jailed and should not be allowed // initiate connections, however outbound connections to it should still be // allowed. - IsJailed bool `json:",omitempty"` + IsJailed bool `json:",omitzero"` // ExitNodeDNSResolvers is the list of DNS servers that should be used when this // node is marked IsWireGuardOnly and being used as an exit node. @@ -810,10 +828,10 @@ type Location struct { // Because it contains pointers (slices), this type should not be used // as a value type. type Hostinfo struct { - IPNVersion string `json:",omitempty"` // version of this code (in version.Long format) - FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance - BackendLogID string `json:",omitempty"` // logtail ID of backend instance - OS string `json:",omitempty"` // operating system the client runs on (a version.OS value) + IPNVersion string `json:",omitzero"` // version of this code (in version.Long format) + FrontendLogID string `json:",omitzero"` // logtail ID of frontend instance + BackendLogID string `json:",omitzero"` // logtail ID of backend instance + OS string `json:",omitzero"` // operating system the client runs on (a version.OS value) // OSVersion is the version of the OS, if available. // @@ -825,25 +843,25 @@ type Hostinfo struct { // string on Linux, like "Debian 10.4; kernel=xxx; container; env=kn" and so // on. As of Tailscale 1.32, this is simply the kernel version on Linux, like // "5.10.0-17-amd64". - OSVersion string `json:",omitempty"` + OSVersion string `json:",omitzero"` - Container opt.Bool `json:",omitempty"` // best-effort whether the client is running in a container - Env string `json:",omitempty"` // a hostinfo.EnvType in string form - Distro string `json:",omitempty"` // "debian", "ubuntu", "nixos", ... - DistroVersion string `json:",omitempty"` // "20.04", ... - DistroCodeName string `json:",omitempty"` // "jammy", "bullseye", ... + Container opt.Bool `json:",omitzero"` // best-effort whether the client is running in a container + Env string `json:",omitzero"` // a hostinfo.EnvType in string form + Distro string `json:",omitzero"` // "debian", "ubuntu", "nixos", ... + DistroVersion string `json:",omitzero"` // "20.04", ... + DistroCodeName string `json:",omitzero"` // "jammy", "bullseye", ... // App is used to disambiguate Tailscale clients that run using tsnet. - App string `json:",omitempty"` // "k8s-operator", "golinks", ... + App string `json:",omitzero"` // "k8s-operator", "golinks", ... - Desktop opt.Bool `json:",omitempty"` // if a desktop was detected on Linux - Package string `json:",omitempty"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown) - DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3") - PushDeviceToken string `json:",omitempty"` // macOS/iOS APNs device token for notifications (and Android in the future) - Hostname string `json:",omitempty"` // name of the host the client runs on - ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections - ShareeNode bool `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user - NoLogsNoSupport bool `json:",omitempty"` // indicates that the user has opted out of sending logs and support + Desktop opt.Bool `json:",omitzero"` // if a desktop was detected on Linux + Package string `json:",omitzero"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown) + DeviceModel string `json:",omitzero"` // mobile phone model ("Pixel 3a", "iPhone12,3") + PushDeviceToken string `json:",omitzero"` // macOS/iOS APNs device token for notifications (and Android in the future) + Hostname string `json:",omitzero"` // name of the host the client runs on + ShieldsUp bool `json:",omitzero"` // indicates whether the host is blocking incoming connections + ShareeNode bool `json:",omitzero"` // indicates this node exists in netmap because it's owned by a shared-to user + NoLogsNoSupport bool `json:",omitzero"` // indicates that the user has opted out of sending logs and support // WireIngress indicates that the node would like to be wired up server-side // (DNS, etc) to be able to use Tailscale Funnel, even if it's not currently // enabled. For example, the user might only use it for intermittent @@ -851,34 +869,75 @@ type Hostinfo struct { // away, even if it's disabled most of the time. As an optimization, this is // only sent if IngressEnabled is false, as IngressEnabled implies that this // option is true. - WireIngress bool `json:",omitempty"` - IngressEnabled bool `json:",omitempty"` // if the node has any funnel endpoint enabled - AllowsUpdate bool `json:",omitempty"` // indicates that the node has opted-in to admin-console-drive remote updates - Machine string `json:",omitempty"` // the current host's machine type (uname -m) - GoArch string `json:",omitempty"` // GOARCH value (of the built binary) - GoArchVar string `json:",omitempty"` // GOARM, GOAMD64, etc (of the built binary) - GoVersion string `json:",omitempty"` // Go version binary was built with + WireIngress bool `json:",omitzero"` + IngressEnabled bool `json:",omitzero"` // if the node has any funnel endpoint enabled + AllowsUpdate bool `json:",omitzero"` // indicates that the node has opted-in to admin-console-drive remote updates + Machine string `json:",omitzero"` // the current host's machine type (uname -m) + GoArch string `json:",omitzero"` // GOARCH value (of the built binary) + GoArchVar string `json:",omitzero"` // GOARM, GOAMD64, etc (of the built binary) + GoVersion string `json:",omitzero"` // Go version binary was built with RoutableIPs []netip.Prefix `json:",omitempty"` // set of IP ranges this client can route RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim WoLMACs []string `json:",omitempty"` // MAC address(es) to send Wake-on-LAN packets to wake this node (lowercase hex w/ colons) Services []Service `json:",omitempty"` // services advertised by this machine - NetInfo *NetInfo `json:",omitempty"` + NetInfo *NetInfo `json:",omitzero"` SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised - Cloud string `json:",omitempty"` - Userspace opt.Bool `json:",omitempty"` // if the client is running in userspace (netstack) mode - UserspaceRouter opt.Bool `json:",omitempty"` // if the client's subnet router is running in userspace (netstack) mode - AppConnector opt.Bool `json:",omitempty"` // if the client is running the app-connector service - ServicesHash string `json:",omitempty"` // opaque hash of the most recent list of tailnet services, change in hash indicates config should be fetched via c2n + Cloud string `json:",omitzero"` + Userspace opt.Bool `json:",omitzero"` // if the client is running in userspace (netstack) mode + UserspaceRouter opt.Bool `json:",omitzero"` // if the client's subnet router is running in userspace (netstack) mode + AppConnector opt.Bool `json:",omitzero"` // if the client is running the app-connector service + ServicesHash string `json:",omitzero"` // opaque hash of the most recent list of tailnet services, change in hash indicates config should be fetched via c2n + ExitNodeID StableNodeID `json:",omitzero"` // the client’s selected exit node, empty when unselected. // Location represents geographical location data about a // Tailscale host. Location is optional and only set if // explicitly declared by a node. - Location *Location `json:",omitempty"` + Location *Location `json:",omitzero"` + + TPM *TPMInfo `json:",omitzero"` // TPM device metadata, if available + // StateEncrypted reports whether the node state is stored encrypted on + // disk. The actual mechanism is platform-specific: + // * Apple nodes use the Keychain + // * Linux and Windows nodes use the TPM + // * Android apps use EncryptedSharedPreferences + StateEncrypted opt.Bool `json:",omitzero"` // NOTE: any new fields containing pointers in this type // require changes to Hostinfo.Equal. } +// TPMInfo contains information about a TPM 2.0 device present on a node. +// All fields are read from TPM_CAP_TPM_PROPERTIES, see Part 2, section 6.13 of +// https://trustedcomputinggroup.org/resource/tpm-library-specification/. +type TPMInfo struct { + // Manufacturer is a 4-letter code from section 4.1 of + // https://trustedcomputinggroup.org/resource/vendor-id-registry/, + // for example "MSFT" for Microsoft. + // Read from TPM_PT_MANUFACTURER. + Manufacturer string `json:",omitzero"` + // Vendor is a vendor ID string, up to 16 characters. + // Read from TPM_PT_VENDOR_STRING_*. + Vendor string `json:",omitzero"` + // Model is a vendor-defined TPM model. + // Read from TPM_PT_VENDOR_TPM_TYPE. + Model int `json:",omitzero"` + // FirmwareVersion is the version number of the firmware. + // Read from TPM_PT_FIRMWARE_VERSION_*. + FirmwareVersion uint64 `json:",omitzero"` + // SpecRevision is the TPM 2.0 spec revision encoded as a single number. All + // revisions can be found at + // https://trustedcomputinggroup.org/resource/tpm-library-specification/. + // Before revision 184, TCG used the "01.83" format for revision 183. + SpecRevision int `json:",omitzero"` + + // FamilyIndicator is the TPM spec family, like "2.0". + // Read from TPM_PT_FAMILY_INDICATOR. + FamilyIndicator string `json:",omitzero"` +} + +// Present reports whether a TPM device is present on this machine. +func (t *TPMInfo) Present() bool { return t != nil } + // ServiceName is the name of a service, of the form `svc:dns-label`. Services // represent some kind of application provided for users of the tailnet with a // MagicDNS name and possibly dedicated IP addresses. Currently (2024-01-21), @@ -886,6 +945,16 @@ type Hostinfo struct { // This is not related to the older [Service] used in [Hostinfo.Services]. type ServiceName string +// AsServiceName reports whether the given string is a valid service name. +// If so returns the name as a [tailcfg.ServiceName], otherwise returns "". +func AsServiceName(s string) ServiceName { + svcName := ServiceName(s) + if err := svcName.Validate(); err != nil { + return "" + } + return svcName +} + // Validate validates if the service name is formatted correctly. // We only allow valid DNS labels, since the expectation is that these will be // used as parts of domain names. All errors are [vizerror.Error]. @@ -948,41 +1017,37 @@ func (v HostinfoView) TailscaleSSHEnabled() bool { return v.ж.TailscaleSSHEnabl type NetInfo struct { // MappingVariesByDestIP says whether the host's NAT mappings // vary based on the destination IP. - MappingVariesByDestIP opt.Bool - - // HairPinning is their router does hairpinning. - // It reports true even if there's no NAT involved. - HairPinning opt.Bool + MappingVariesByDestIP opt.Bool `json:",omitzero"` // WorkingIPv6 is whether the host has IPv6 internet connectivity. - WorkingIPv6 opt.Bool + WorkingIPv6 opt.Bool `json:",omitzero"` // OSHasIPv6 is whether the OS supports IPv6 at all, regardless of // whether IPv6 internet connectivity is available. - OSHasIPv6 opt.Bool + OSHasIPv6 opt.Bool `json:",omitzero"` // WorkingUDP is whether the host has UDP internet connectivity. - WorkingUDP opt.Bool + WorkingUDP opt.Bool `json:",omitzero"` // WorkingICMPv4 is whether ICMPv4 works. // Empty means not checked. - WorkingICMPv4 opt.Bool + WorkingICMPv4 opt.Bool `json:",omitzero"` // HavePortMap is whether we have an existing portmap open // (UPnP, PMP, or PCP). - HavePortMap bool `json:",omitempty"` + HavePortMap bool `json:",omitzero"` // UPnP is whether UPnP appears present on the LAN. // Empty means not checked. - UPnP opt.Bool + UPnP opt.Bool `json:",omitzero"` // PMP is whether NAT-PMP appears present on the LAN. // Empty means not checked. - PMP opt.Bool + PMP opt.Bool `json:",omitzero"` // PCP is whether PCP appears present on the LAN. // Empty means not checked. - PCP opt.Bool + PCP opt.Bool `json:",omitzero"` // PreferredDERP is this node's preferred (home) DERP region ID. // This is where the node expects to be contacted to begin a @@ -991,10 +1056,10 @@ type NetInfo struct { // that are located elsewhere) but PreferredDERP is the region ID // that the node subscribes to traffic at. // Zero means disconnected or unknown. - PreferredDERP int + PreferredDERP int `json:",omitzero"` // LinkType is the current link type, if known. - LinkType string `json:",omitempty"` // "wired", "wifi", "mobile" (LTE, 4G, 3G, etc) + LinkType string `json:",omitzero"` // "wired", "wifi", "mobile" (LTE, 4G, 3G, etc) // DERPLatency is the fastest recent time to reach various // DERP STUN servers, in seconds. The map key is the @@ -1012,7 +1077,7 @@ type NetInfo struct { // "{nft,ift}-REASON", like "nft-forced" or "ipt-default". Empty means // either not Linux or a configuration in which the host firewall rules // are not managed by tailscaled. - FirewallMode string `json:",omitempty"` + FirewallMode string `json:",omitzero"` // Update BasicallyEqual when adding fields. } @@ -1021,13 +1086,16 @@ func (ni *NetInfo) String() string { if ni == nil { return "NetInfo(nil)" } - return fmt.Sprintf("NetInfo{varies=%v hairpin=%v ipv6=%v ipv6os=%v udp=%v icmpv4=%v derp=#%v portmap=%v link=%q firewallmode=%q}", - ni.MappingVariesByDestIP, ni.HairPinning, ni.WorkingIPv6, + return fmt.Sprintf("NetInfo{varies=%v ipv6=%v ipv6os=%v udp=%v icmpv4=%v derp=#%v portmap=%v link=%q firewallmode=%q}", + ni.MappingVariesByDestIP, ni.WorkingIPv6, ni.OSHasIPv6, ni.WorkingUDP, ni.WorkingICMPv4, ni.PreferredDERP, ni.portMapSummary(), ni.LinkType, ni.FirewallMode) } func (ni *NetInfo) portMapSummary() string { + if !buildfeatures.HasPortMapper { + return "x" + } if !ni.HavePortMap && ni.UPnP == "" && ni.PMP == "" && ni.PCP == "" { return "?" } @@ -1062,7 +1130,6 @@ func (ni *NetInfo) BasicallyEqual(ni2 *NetInfo) bool { return true } return ni.MappingVariesByDestIP == ni2.MappingVariesByDestIP && - ni.HairPinning == ni2.HairPinning && ni.WorkingIPv6 == ni2.WorkingIPv6 && ni.OSHasIPv6 == ni2.OSHasIPv6 && ni.WorkingUDP == ni2.WorkingUDP && @@ -1298,11 +1365,22 @@ type MapRequest struct { // For current values and history, see the CapabilityVersion type's docs. Version CapabilityVersion - Compress string // "zstd" or "" (no compression) - KeepAlive bool // whether server should send keep-alives back to us + Compress string `json:",omitzero"` // "zstd" or "" (no compression) + KeepAlive bool `json:",omitzero"` // whether server should send keep-alives back to us NodeKey key.NodePublic DiscoKey key.DiscoPublic + // HardwareAttestationKey is the public key of the node's hardware-backed + // identity attestation key, if any. + HardwareAttestationKey key.HardwareAttestationPublic `json:",omitzero"` + // HardwareAttestationKeySignature is the signature of + // "$UNIX_TIMESTAMP|$NODE_KEY" using its hardware attestation key, if any. + HardwareAttestationKeySignature []byte `json:",omitempty"` + // HardwareAttestationKeySignatureTimestamp is the time at which the + // HardwareAttestationKeySignature was created, if any. This UNIX timestamp + // value is prepended to the node key when signing. + HardwareAttestationKeySignatureTimestamp time.Time `json:",omitzero"` + // Stream is whether the client wants to receive multiple MapResponses over // the same HTTP connection. // @@ -1311,7 +1389,7 @@ type MapRequest struct { // // If true and Version >= 68, the server should treat this as a read-only // request and ignore any Hostinfo or other fields that might be set. - Stream bool + Stream bool `json:",omitzero"` // Hostinfo is the client's current Hostinfo. Although it is always included // in the request, the server may choose to ignore it when Stream is true @@ -1328,14 +1406,14 @@ type MapRequest struct { // // The server may choose to ignore the request for any reason and start a // new map session. This is only applicable when Stream is true. - MapSessionHandle string `json:",omitempty"` + MapSessionHandle string `json:",omitzero"` // MapSessionSeq is the sequence number in the map session identified by // MapSesssionHandle that was most recently processed by the client. // It is only applicable when MapSessionHandle is specified. // If the server chooses to honor the MapSessionHandle request, only sequence // numbers greater than this value will be returned. - MapSessionSeq int64 `json:",omitempty"` + MapSessionSeq int64 `json:",omitzero"` // Endpoints are the client's magicsock UDP ip:port endpoints (IPv4 or IPv6). // These can be ignored if Stream is true and Version >= 68. @@ -1346,7 +1424,7 @@ type MapRequest struct { // TKAHead describes the hash of the latest AUM applied to the local // tailnet key authority, if one is operating. // It is encoded as tka.AUMHash.MarshalText. - TKAHead string `json:",omitempty"` + TKAHead string `json:",omitzero"` // ReadOnly was set when client just wanted to fetch the MapResponse, // without updating their Endpoints. The intended use was for clients to @@ -1354,7 +1432,7 @@ type MapRequest struct { // update. // // Deprecated: always false as of Version 68. - ReadOnly bool `json:",omitempty"` + ReadOnly bool `json:",omitzero"` // OmitPeers is whether the client is okay with the Peers list being omitted // in the response. @@ -1370,7 +1448,7 @@ type MapRequest struct { // If OmitPeers is true, Stream is false, but ReadOnly is true, // then all the response fields are included. (This is what the client does // when initially fetching the DERP map.) - OmitPeers bool `json:",omitempty"` + OmitPeers bool `json:",omitzero"` // DebugFlags is a list of strings specifying debugging and // development features to enable in handling this map @@ -1385,6 +1463,12 @@ type MapRequest struct { // * "warn-router-unhealthy": client's Router implementation is // having problems. DebugFlags []string `json:",omitempty"` + + // ConnectionHandleForTest, if non-empty, is an opaque string sent by the client that + // identifies this specific connection to the server. The server may choose to + // use this handle to identify the connection for debugging or testing + // purposes. It has no semantic meaning. + ConnectionHandleForTest string `json:",omitzero"` } // PortRange represents a range of UDP or TCP port numbers. @@ -1400,6 +1484,15 @@ func (pr PortRange) Contains(port uint16) bool { var PortRangeAny = PortRange{0, 65535} +func (pr PortRange) String() string { + if pr.First == pr.Last { + return strconv.FormatUint(uint64(pr.First), 10) + } else if pr == PortRangeAny { + return "*" + } + return fmt.Sprintf("%d-%d", pr.First, pr.Last) +} + // NetPortRange represents a range of ports that's allowed for one or more IPs. type NetPortRange struct { _ structs.Incomparable @@ -1462,6 +1555,18 @@ const ( // user groups as Kubernetes user groups. This capability is read by // peers that are Tailscale Kubernetes operator instances. PeerCapabilityKubernetes PeerCapability = "tailscale.com/cap/kubernetes" + + // PeerCapabilityRelay grants the ability for a peer to allocate relay + // endpoints. + PeerCapabilityRelay PeerCapability = "tailscale.com/cap/relay" + // PeerCapabilityRelayTarget grants the current node the ability to allocate + // relay endpoints to the peer which has this capability. + PeerCapabilityRelayTarget PeerCapability = "tailscale.com/cap/relay-target" + + // PeerCapabilityTsIDP grants a peer tsidp-specific + // capabilities, such as the ability to add user groups to the OIDC + // claim + PeerCapabilityTsIDP PeerCapability = "tailscale.com/cap/tsidp" ) // NodeCapMap is a map of capabilities to their optional values. It is valid for @@ -1654,12 +1759,11 @@ type DNSConfig struct { // in the network map, aka MagicDNS. // Despite the (legacy) name, does not necessarily cause request // proxying to be enabled. - Proxied bool `json:",omitempty"` + Proxied bool `json:",omitzero"` - // The following fields are only set and used by - // MapRequest.Version >=9 and <14. - - // Nameservers are the IP addresses of the nameservers to use. + // Nameservers are the IP addresses of the global nameservers to use. + // + // Deprecated: this is only set and used by MapRequest.Version >=9 and <14. Use Resolvers instead. Nameservers []netip.Addr `json:",omitempty"` // CertDomains are the set of DNS names for which the control @@ -1692,7 +1796,7 @@ type DNSConfig struct { // TempCorpIssue13969 is a temporary (2023-08-16) field for an internal hack day prototype. // It contains a user inputed URL that should have a list of domains to be blocked. // See https://github.com/tailscale/corp/issues/13969. - TempCorpIssue13969 string `json:",omitempty"` + TempCorpIssue13969 string `json:",omitzero"` } // DNSRecord is an extra DNS record to add to MagicDNS. @@ -1704,7 +1808,7 @@ type DNSRecord struct { // Type is the DNS record type. // Empty means A or AAAA, depending on value. // Other values are currently ignored. - Type string `json:",omitempty"` + Type string `json:",omitzero"` // Value is the IP address in string form. // TODO(bradfitz): if we ever add support for record types @@ -1752,11 +1856,11 @@ type PingRequest struct { // URLIsNoise, if true, means that the client should hit URL over the Noise // transport instead of TLS. - URLIsNoise bool `json:",omitempty"` + URLIsNoise bool `json:",omitzero"` // Log is whether to log about this ping in the success case. // For failure cases, the client will log regardless. - Log bool `json:",omitempty"` + Log bool `json:",omitzero"` // Types is the types of ping that are initiated. Can be any PingType, comma // separated, e.g. "disco,TSMP" @@ -1766,10 +1870,10 @@ type PingRequest struct { // node's c2n handler and the HTTP response sent in a POST to URL. For c2n, // the value of URLIsNoise is ignored and only the Noise transport (back to // the control plane) will be used, as if URLIsNoise were true. - Types string `json:",omitempty"` + Types string `json:",omitzero"` // IP is the ping target, when needed by the PingType(s) given in Types. - IP netip.Addr + IP netip.Addr `json:",omitzero"` // Payload is the ping payload. // @@ -1797,10 +1901,14 @@ type PingResponse struct { // omitted, Err should contain information as to the cause. LatencySeconds float64 `json:",omitempty"` - // Endpoint is the ip:port if direct UDP was used. - // It is not currently set for TSMP pings. + // Endpoint is a string of the form "{ip}:{port}" if direct UDP was used. It + // is not currently set for TSMP. Endpoint string `json:",omitempty"` + // PeerRelay is a string of the form "{ip}:{port}:vni:{vni}" if a peer + // relay was used. It is not currently set for TSMP. + PeerRelay string `json:",omitempty"` + // DERPRegionID is non-zero DERP region ID if DERP was used. // It is not currently set for TSMP pings. DERPRegionID int `json:",omitempty"` @@ -1982,13 +2090,31 @@ type MapResponse struct { // plane's perspective. A nil value means no change from the previous // MapResponse. A non-nil 0-length slice restores the health to good (no // known problems). A non-zero length slice are the list of problems that - // the control place sees. + // the control plane sees. + // + // Either this will be set, or DisplayMessages will be set, but not both. // // Note that this package's type, due its use of a slice and omitempty, is // unable to marshal a zero-length non-nil slice. The control server needs // to marshal this type using a separate type. See MapResponse docs. Health []string `json:",omitempty"` + // DisplayMessages sets the health state of the node from the control + // plane's perspective. + // + // Either this will be set, or Health will be set, but not both. + // + // The map keys are IDs that uniquely identify the type of health issue. The + // map values are the messages. If the server sends down a map with entries, + // the client treats it as a patch: new entries are added, keys with a value + // of nil are deleted, existing entries with new values are updated. A nil + // map and an empty map both mean no change has occurred since the last + // update. + // + // As a special case, the map key "*" with a value of nil means to clear all + // prior display messages before processing the other map entries. + DisplayMessages map[DisplayMessageID]*DisplayMessage `json:",omitempty"` + // SSHPolicy, if non-nil, updates the SSH policy for how incoming // SSH connections should be handled. SSHPolicy *SSHPolicy `json:",omitempty"` @@ -2024,14 +2150,98 @@ type MapResponse struct { // or nothing to report. ClientVersion *ClientVersion `json:",omitempty"` - // DefaultAutoUpdate is the default node auto-update setting for this + // DeprecatedDefaultAutoUpdate is the default node auto-update setting for this // tailnet. The node is free to opt-in or out locally regardless of this - // value. This value is only used on first MapResponse from control, the - // auto-update setting doesn't change if the tailnet admin flips the - // default after the node registered. - DefaultAutoUpdate opt.Bool `json:",omitempty"` + // value. Once this value has been set and stored in the client, future + // changes from the control plane are ignored. + // + // Deprecated: use NodeAttrDefaultAutoUpdate instead. See + // https://github.com/tailscale/tailscale/issues/11502. + DeprecatedDefaultAutoUpdate opt.Bool `json:"DefaultAutoUpdate,omitempty"` } +// DisplayMessage represents a health state of the node from the control plane's +// perspective. It is deliberately similar to [health.Warnable] as both get +// converted into [health.UnhealthyState] to be sent to the GUI. +type DisplayMessage struct { + // Title is a string that the GUI uses as title for this message. The title + // should be short and fit in a single line. It should not end in a period. + // + // Example: "Network may be blocking Tailscale". + // + // See the various instantiations of [health.Warnable] for more examples. + Title string + + // Text is an extended string that the GUI will display to the user. This + // could be multiple sentences explaining the issue in more detail. + // + // Example: "macOS Screen Time seems to be blocking Tailscale. Try disabling + // Screen Time in System Settings > Screen Time > Content & Privacy > Access + // to Web Content." + // + // See the various instantiations of [health.Warnable] for more examples. + Text string + + // Severity is the severity of the DisplayMessage, which the GUI can use to + // determine how to display it. Maps to [health.Severity]. + Severity DisplayMessageSeverity + + // ImpactsConnectivity is whether the health problem will impact the user's + // ability to connect to the Internet or other nodes on the tailnet, which + // the GUI can use to determine how to display it. + ImpactsConnectivity bool `json:",omitempty"` + + // Primary action, if present, represents the action to allow the user to + // take when interacting with this message. For example, if the + // DisplayMessage is shown via a notification, the action label might be a + // button on that notification and clicking the button would open the URL. + PrimaryAction *DisplayMessageAction `json:",omitempty"` +} + +// DisplayMessageAction represents an action (URL and link) to be presented to +// the user associated with a [DisplayMessage]. +type DisplayMessageAction struct { + // URL is the URL to navigate to when the user interacts with this action + URL string + + // Label is the call to action for the UI to display on the UI element that + // will open the URL (such as a button or link). For example, "Sign in" or + // "Learn more". + Label string +} + +// DisplayMessageID is a string that uniquely identifies the kind of health +// issue (e.g. "session-expired"). +type DisplayMessageID string + +// Equal returns true iff all fields are equal. +func (m DisplayMessage) Equal(o DisplayMessage) bool { + return m.Title == o.Title && + m.Text == o.Text && + m.Severity == o.Severity && + m.ImpactsConnectivity == o.ImpactsConnectivity && + (m.PrimaryAction == nil) == (o.PrimaryAction == nil) && + (m.PrimaryAction == nil || (m.PrimaryAction.URL == o.PrimaryAction.URL && + m.PrimaryAction.Label == o.PrimaryAction.Label)) +} + +// DisplayMessageSeverity represents how serious a [DisplayMessage] is. Analogous +// to health.Severity. +type DisplayMessageSeverity string + +const ( + // SeverityHigh is the highest severity level, used for critical errors that need immediate attention. + // On platforms where the client GUI can deliver notifications, a SeverityHigh message will trigger + // a modal notification. + SeverityHigh DisplayMessageSeverity = "high" + // SeverityMedium is used for errors that are important but not critical. This won't trigger a modal + // notification, however it will be displayed in a more visible way than a SeverityLow message. + SeverityMedium DisplayMessageSeverity = "medium" + // SeverityLow is used for less important notices that don't need immediate attention. The user will + // have to go to a Settings window, or another "hidden" GUI location to see these messages. + SeverityLow DisplayMessageSeverity = "low" +) + // ClientVersion is information about the latest client version that's available // for the client (and whether they're already running it). // @@ -2077,7 +2287,14 @@ type ControlDialPlan struct { // connecting to the control server. type ControlIPCandidate struct { // IP is the address to attempt connecting to. - IP netip.Addr + IP netip.Addr `json:",omitzero"` + + // ACEHost, if non-empty, means that the client should connect to the + // control plane using an HTTPS CONNECT request to the provided hostname. If + // the IP field is also set, then the IP is the IP address of the ACEHost + // (and not the control plane) and DNS should not be used. The target (the + // argument to CONNECT) is always the control plane's hostname, not an IP. + ACEHost string `json:",omitempty"` // DialStartSec is the number of seconds after the beginning of the // connection process to wait before trying this candidate. @@ -2118,10 +2335,10 @@ type Debug struct { Exit *int `json:",omitempty"` } -func (id ID) String() string { return fmt.Sprintf("id:%x", int64(id)) } -func (id UserID) String() string { return fmt.Sprintf("userid:%x", int64(id)) } -func (id LoginID) String() string { return fmt.Sprintf("loginid:%x", int64(id)) } -func (id NodeID) String() string { return fmt.Sprintf("nodeid:%x", int64(id)) } +func (id ID) String() string { return fmt.Sprintf("id:%d", int64(id)) } +func (id UserID) String() string { return fmt.Sprintf("userid:%d", int64(id)) } +func (id LoginID) String() string { return fmt.Sprintf("loginid:%d", int64(id)) } +func (id NodeID) String() string { return fmt.Sprintf("nodeid:%d", int64(id)) } // Equal reports whether n and n2 are equal. func (n *Node) Equal(n2 *Node) bool { @@ -2220,12 +2437,16 @@ type NodeCapability string const ( CapabilityFileSharing NodeCapability = "https://tailscale.com/cap/file-sharing" CapabilityAdmin NodeCapability = "https://tailscale.com/cap/is-admin" + CapabilityOwner NodeCapability = "https://tailscale.com/cap/is-owner" CapabilitySSH NodeCapability = "https://tailscale.com/cap/ssh" // feature enabled/available CapabilitySSHRuleIn NodeCapability = "https://tailscale.com/cap/ssh-rule-in" // some SSH rule reach this node CapabilityDataPlaneAuditLogs NodeCapability = "https://tailscale.com/cap/data-plane-audit-logs" // feature enabled CapabilityDebug NodeCapability = "https://tailscale.com/cap/debug" // exposes debug endpoints over the PeerAPI CapabilityHTTPS NodeCapability = "https" + // CapabilityMacUIV2 makes the macOS GUI enable its v2 mode. + CapabilityMacUIV2 NodeCapability = "https://tailscale.com/cap/mac-ui-v2" + // CapabilityBindToInterfaceByRoute changes how Darwin nodes create // sockets (in the net/netns package). See that package for more // details on the behaviour of this capability. @@ -2242,6 +2463,10 @@ const ( // of connections to the default network interface on Darwin nodes. CapabilityDebugDisableBindConnToInterface NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface" + // CapabilityDebugDisableBindConnToInterface disables the automatic binding + // of connections to the default network interface on Darwin nodes using network extensions + CapabilityDebugDisableBindConnToInterfaceAppleExt NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface-apple-ext" + // CapabilityTailnetLock indicates the node may initialize tailnet lock. CapabilityTailnetLock NodeCapability = "https://tailscale.com/cap/tailnet-lock" @@ -2341,8 +2566,19 @@ const ( // This cannot be set simultaneously with NodeAttrLinuxMustUseIPTables. NodeAttrLinuxMustUseNfTables NodeCapability = "linux-netfilter?v=nftables" - // NodeAttrSeamlessKeyRenewal makes clients enable beta functionality - // of renewing node keys without breaking connections. + // NodeAttrDisableSeamlessKeyRenewal disables seamless key renewal, which is + // enabled by default in clients as of 2025-09-17 (1.90 and later). + // + // We will use this attribute to manage the rollout, and disable seamless in + // clients with known bugs. + // http://go/seamless-key-renewal + NodeAttrDisableSeamlessKeyRenewal NodeCapability = "disable-seamless-key-renewal" + + // NodeAttrSeamlessKeyRenewal was used to opt-in to seamless key renewal + // during its private alpha. + // + // Deprecated: NodeAttrSeamlessKeyRenewal is deprecated as of CapabilityVersion 126, + // because seamless key renewal is now enabled by default. NodeAttrSeamlessKeyRenewal NodeCapability = "seamless-key-renewal" // NodeAttrProbeUDPLifetime makes the client probe UDP path lifetime at the @@ -2412,6 +2648,9 @@ const ( // NodeAttrDisableMagicSockCryptoRouting disables the use of the // magicsock cryptorouting hook. See tailscale/corp#20732. + // + // Deprecated: NodeAttrDisableMagicSockCryptoRouting is deprecated as of + // CapabilityVersion 124, CryptoRouting is now mandatory. See tailscale/corp#31083. NodeAttrDisableMagicSockCryptoRouting NodeCapability = "disable-magicsock-crypto-routing" // NodeAttrDisableCaptivePortalDetection instructs the client to not perform captive portal detection @@ -2446,6 +2685,53 @@ const ( // native tailnet. This is currently only sent to Hello, in its // peer node list. NodeAttrNativeIPV4 NodeCapability = "native-ipv4" + + // NodeAttrDisableRelayServer prevents the node from acting as an underlay + // UDP relay server. There are no expected values for this key; the key + // only needs to be present in [NodeCapMap] to take effect. + NodeAttrDisableRelayServer NodeCapability = "disable-relay-server" + + // NodeAttrDisableRelayClient prevents the node from both allocating UDP + // relay server endpoints itself, and from using endpoints allocated by + // its peers. This attribute can be added to the node dynamically; if added + // while the node is already running, the node will be unable to allocate + // endpoints after it next updates its network map, and will be immediately + // unable to use new paths via a UDP relay server. Setting this attribute + // dynamically does not remove any existing paths, including paths that + // traverse a UDP relay server. There are no expected values for this key + // in [NodeCapMap]; the key only needs to be present in [NodeCapMap] to + // take effect. + NodeAttrDisableRelayClient NodeCapability = "disable-relay-client" + + // NodeAttrMagicDNSPeerAAAA is a capability that tells the node's MagicDNS + // server to answer AAAA queries about its peers. See tailscale/tailscale#1152. + NodeAttrMagicDNSPeerAAAA NodeCapability = "magicdns-aaaa" + + // NodeAttrTrafficSteering configures the node to use the traffic + // steering subsystem for via routes. See tailscale/corp#29966. + NodeAttrTrafficSteering NodeCapability = "traffic-steering" + + // NodeAttrTailnetDisplayName is an optional alternate name for the tailnet + // to be displayed to the user. + // If empty or absent, a default is used. + // If this value is present and set by a user this will only include letters, + // numbers, apostrophe, spaces, and hyphens. This may not be true for the default. + // Values can look like "foo.com" or "Foo's Test Tailnet - Staging". + NodeAttrTailnetDisplayName NodeCapability = "tailnet-display-name" + + // NodeAttrClientSideReachability configures the node to determine + // reachability itself when choosing connectors. When absent, the + // default behavior is to trust the control plane when it claims that a + // node is no longer online, but that is not a reliable signal. + NodeAttrClientSideReachability = "client-side-reachability" + + // NodeAttrDefaultAutoUpdate advertises the default node auto-update setting + // for this tailnet. The node is free to opt-in or out locally regardless of + // this value. Once this has been set and stored in the client, future + // changes from the control plane are ignored. + // + // The value of the key in [NodeCapMap] is a JSON boolean. + NodeAttrDefaultAutoUpdate NodeCapability = "default-auto-update" ) // SetDNSRequest is a request to add a DNS record. @@ -2489,6 +2775,9 @@ type SetDNSResponse struct{} // node health changes to: // // POST https:///machine/update-health. +// +// As of 2025-10-02, we stopped sending this to the control plane proactively. +// It was never useful enough with its current design and needs more thought. type HealthChangeRequest struct { Subsys string // a health.Subsystem value in string form Error string // or empty if cleared @@ -2633,7 +2922,7 @@ type SSHAction struct { // SessionDuration, if non-zero, is how long the session can stay open // before being forcefully terminated. - SessionDuration time.Duration `json:"sessionDuration,omitempty"` + SessionDuration time.Duration `json:"sessionDuration,omitempty,format:nano"` // AllowAgentForwarding, if true, allows accepted connections to forward // the ssh agent if requested. @@ -2765,29 +3054,29 @@ type SSHRecordingAttempt struct { // See QueryFeatureResponse for response structure. type QueryFeatureRequest struct { // Feature is the string identifier for a feature. - Feature string `json:",omitempty"` + Feature string `json:",omitzero"` // NodeKey is the client's current node key. - NodeKey key.NodePublic `json:",omitempty"` + NodeKey key.NodePublic `json:",omitzero"` } // QueryFeatureResponse is the response to an QueryFeatureRequest. // See cli.enableFeatureInteractive for usage. type QueryFeatureResponse struct { // Complete is true when the feature is already enabled. - Complete bool `json:",omitempty"` + Complete bool `json:",omitzero"` // Text holds lines to display in the CLI with information // about the feature and how to enable it. // // Lines are separated by newline characters. The final // newline may be omitted. - Text string `json:",omitempty"` + Text string `json:",omitzero"` // URL is the link for the user to visit to take action on // enabling the feature. // // When empty, there is no action for this user to take. - URL string `json:",omitempty"` + URL string `json:",omitzero"` // ShouldWait specifies whether the CLI should block and // wait for the user to enable the feature. @@ -2800,7 +3089,7 @@ type QueryFeatureResponse struct { // // The CLI can watch the IPN notification bus for changes in // required node capabilities to know when to continue. - ShouldWait bool `json:",omitempty"` + ShouldWait bool `json:",omitzero"` } // WebClientAuthResponse is the response to a web client authentication request @@ -2810,15 +3099,15 @@ type WebClientAuthResponse struct { // ID is a unique identifier for the session auth request. // It can be supplied to "/machine/webclient/wait" to pause until // the session authentication has been completed. - ID string `json:",omitempty"` + ID string `json:",omitzero"` // URL is the link for the user to visit to authenticate the session. // // When empty, there is no action for the user to take. - URL string `json:",omitempty"` + URL string `json:",omitzero"` // Complete is true when the session authentication has been completed. - Complete bool `json:",omitempty"` + Complete bool `json:",omitzero"` } // OverTLSPublicKeyResponse is the JSON response to /key?v= @@ -2894,10 +3183,10 @@ type PeerChange struct { // DERPRegion, if non-zero, means that NodeID's home DERP // region ID is now this number. - DERPRegion int `json:",omitempty"` + DERPRegion int `json:",omitzero"` // Cap, if non-zero, means that NodeID's capability version has changed. - Cap CapabilityVersion `json:",omitempty"` + Cap CapabilityVersion `json:",omitzero"` // CapMap, if non-nil, means that NodeID's capability map has changed. CapMap NodeCapMap `json:",omitempty"` @@ -2907,23 +3196,23 @@ type PeerChange struct { Endpoints []netip.AddrPort `json:",omitempty"` // Key, if non-nil, means that the NodeID's wireguard public key changed. - Key *key.NodePublic `json:",omitempty"` + Key *key.NodePublic `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 // KeySignature, if non-nil, means that the signature of the wireguard // public key has changed. KeySignature tkatype.MarshaledSignature `json:",omitempty"` // DiscoKey, if non-nil, means that the NodeID's discokey changed. - DiscoKey *key.DiscoPublic `json:",omitempty"` + DiscoKey *key.DiscoPublic `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 // Online, if non-nil, means that the NodeID's online status changed. - Online *bool `json:",omitempty"` + Online *bool `json:",omitzero"` // LastSeen, if non-nil, means that the NodeID's online status changed. - LastSeen *time.Time `json:",omitempty"` + LastSeen *time.Time `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 // KeyExpiry, if non-nil, changes the NodeID's key expiry. - KeyExpiry *time.Time `json:",omitempty"` + KeyExpiry *time.Time `json:",omitzero"` // TODO: de-pointer: tailscale/tailscale#17978 } // DerpMagicIP is a fake WireGuard endpoint IP address that means to @@ -3001,14 +3290,14 @@ const ( // POST https:///machine/audit-log type AuditLogRequest struct { // Version is the client's current CapabilityVersion. - Version CapabilityVersion `json:",omitempty"` + Version CapabilityVersion `json:",omitzero"` // NodeKey is the client's current node key. NodeKey key.NodePublic `json:",omitzero"` // Action is the action to be logged. It must correspond to a known action in the control plane. - Action ClientAuditAction `json:",omitempty"` + Action ClientAuditAction `json:",omitzero"` // Details is an opaque string, specific to the action being logged. Empty strings may not // be valid depending on the action being logged. - Details string `json:",omitempty"` + Details string `json:",omitzero"` // Timestamp is the time at which the audit log was generated on the node. Timestamp time.Time `json:",omitzero"` } diff --git a/vendor/tailscale.com/tailcfg/tailcfg_clone.go b/vendor/tailscale.com/tailcfg/tailcfg_clone.go index da1f4f3..751b7c2 100644 --- a/vendor/tailscale.com/tailcfg/tailcfg_clone.go +++ b/vendor/tailscale.com/tailcfg/tailcfg_clone.go @@ -141,6 +141,9 @@ func (src *Hostinfo) Clone() *Hostinfo { if dst.Location != nil { dst.Location = ptr.To(*src.Location) } + if dst.TPM != nil { + dst.TPM = ptr.To(*src.TPM) + } return dst } @@ -183,7 +186,10 @@ var _HostinfoCloneNeedsRegeneration = Hostinfo(struct { UserspaceRouter opt.Bool AppConnector opt.Bool ServicesHash string + ExitNodeID StableNodeID Location *Location + TPM *TPMInfo + StateEncrypted opt.Bool }{}) // Clone makes a deep copy of NetInfo. @@ -201,7 +207,6 @@ func (src *NetInfo) Clone() *NetInfo { // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _NetInfoCloneNeedsRegeneration = NetInfo(struct { MappingVariesByDestIP opt.Bool - HairPinning opt.Bool WorkingIPv6 opt.Bool OSHasIPv6 opt.Bool WorkingUDP opt.Bool @@ -626,9 +631,54 @@ var _UserProfileCloneNeedsRegeneration = UserProfile(struct { ProfilePicURL string }{}) +// Clone makes a deep copy of VIPService. +// The result aliases no memory with the original. +func (src *VIPService) Clone() *VIPService { + if src == nil { + return nil + } + dst := new(VIPService) + *dst = *src + dst.Ports = append(src.Ports[:0:0], src.Ports...) + return dst +} + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _VIPServiceCloneNeedsRegeneration = VIPService(struct { + Name ServiceName + Ports []ProtoPortRange + Active bool +}{}) + +// Clone makes a deep copy of SSHPolicy. +// The result aliases no memory with the original. +func (src *SSHPolicy) Clone() *SSHPolicy { + if src == nil { + return nil + } + dst := new(SSHPolicy) + *dst = *src + if src.Rules != nil { + dst.Rules = make([]*SSHRule, len(src.Rules)) + for i := range dst.Rules { + if src.Rules[i] == nil { + dst.Rules[i] = nil + } else { + dst.Rules[i] = src.Rules[i].Clone() + } + } + } + return dst +} + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _SSHPolicyCloneNeedsRegeneration = SSHPolicy(struct { + Rules []*SSHRule +}{}) + // Clone duplicates src into dst and reports whether it succeeded. // To succeed, must be of types <*T, *T> or <*T, **T>, -// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile. +// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy. func Clone(dst, src any) bool { switch src := src.(type) { case *User: @@ -802,6 +852,24 @@ func Clone(dst, src any) bool { *dst = src.Clone() return true } + case *VIPService: + switch dst := dst.(type) { + case *VIPService: + *dst = *src.Clone() + return true + case **VIPService: + *dst = src.Clone() + return true + } + case *SSHPolicy: + switch dst := dst.(type) { + case *SSHPolicy: + *dst = *src.Clone() + return true + case **SSHPolicy: + *dst = src.Clone() + return true + } } return false } diff --git a/vendor/tailscale.com/tailcfg/tailcfg_view.go b/vendor/tailscale.com/tailcfg/tailcfg_view.go index b1aacab..dbd29a8 100644 --- a/vendor/tailscale.com/tailcfg/tailcfg_view.go +++ b/vendor/tailscale.com/tailcfg/tailcfg_view.go @@ -6,11 +6,13 @@ package tailcfg import ( - "encoding/json" + jsonv1 "encoding/json" "errors" "net/netip" "time" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "tailscale.com/types/dnstype" "tailscale.com/types/key" "tailscale.com/types/opt" @@ -19,7 +21,7 @@ import ( "tailscale.com/types/views" ) -//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile +//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy // View returns a read-only view of User. func (p *User) View() UserView { @@ -49,8 +51,17 @@ func (v UserView) AsStruct() *User { return v.ж.Clone() } -func (v UserView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v UserView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v UserView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *UserView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -59,15 +70,32 @@ func (v *UserView) UnmarshalJSON(b []byte) error { return nil } var x User - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v UserView) ID() UserID { return v.ж.ID } -func (v UserView) DisplayName() string { return v.ж.DisplayName } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *UserView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x User + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v UserView) ID() UserID { return v.ж.ID } + +// if non-empty overrides Login field +func (v UserView) DisplayName() string { return v.ж.DisplayName } + +// if non-empty overrides Login field func (v UserView) ProfilePicURL() string { return v.ж.ProfilePicURL } func (v UserView) Created() time.Time { return v.ж.Created } @@ -107,8 +135,17 @@ func (v NodeView) AsStruct() *Node { return v.ж.Clone() } -func (v NodeView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v NodeView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v NodeView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *NodeView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -117,7 +154,20 @@ func (v *NodeView) UnmarshalJSON(b []byte) error { return nil } var x Node - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *NodeView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Node + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } v.ж = &x @@ -126,53 +176,202 @@ func (v *NodeView) UnmarshalJSON(b []byte) error { func (v NodeView) ID() NodeID { return v.ж.ID } func (v NodeView) StableID() StableNodeID { return v.ж.StableID } -func (v NodeView) Name() string { return v.ж.Name } -func (v NodeView) User() UserID { return v.ж.User } -func (v NodeView) Sharer() UserID { return v.ж.Sharer } -func (v NodeView) Key() key.NodePublic { return v.ж.Key } -func (v NodeView) KeyExpiry() time.Time { return v.ж.KeyExpiry } + +// Name is the FQDN of the node. +// It is also the MagicDNS name for the node. +// It has a trailing dot. +// e.g. "host.tail-scale.ts.net." +func (v NodeView) Name() string { return v.ж.Name } + +// User is the user who created the node. If ACL tags are in use for the +// node then it doesn't reflect the ACL identity that the node is running +// as. +func (v NodeView) User() UserID { return v.ж.User } + +// Sharer, if non-zero, is the user who shared this node, if different than User. +func (v NodeView) Sharer() UserID { return v.ж.Sharer } +func (v NodeView) Key() key.NodePublic { return v.ж.Key } + +// the zero value if this node does not expire +func (v NodeView) KeyExpiry() time.Time { return v.ж.KeyExpiry } func (v NodeView) KeySignature() views.ByteSlice[tkatype.MarshaledSignature] { return views.ByteSliceOf(v.ж.KeySignature) } -func (v NodeView) Machine() key.MachinePublic { return v.ж.Machine } -func (v NodeView) DiscoKey() key.DiscoPublic { return v.ж.DiscoKey } -func (v NodeView) Addresses() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.Addresses) } -func (v NodeView) AllowedIPs() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.AllowedIPs) } -func (v NodeView) Endpoints() views.Slice[netip.AddrPort] { return views.SliceOf(v.ж.Endpoints) } -func (v NodeView) LegacyDERPString() string { return v.ж.LegacyDERPString } -func (v NodeView) HomeDERP() int { return v.ж.HomeDERP } -func (v NodeView) Hostinfo() HostinfoView { return v.ж.Hostinfo } -func (v NodeView) Created() time.Time { return v.ж.Created } -func (v NodeView) Cap() CapabilityVersion { return v.ж.Cap } -func (v NodeView) Tags() views.Slice[string] { return views.SliceOf(v.ж.Tags) } +func (v NodeView) Machine() key.MachinePublic { return v.ж.Machine } +func (v NodeView) DiscoKey() key.DiscoPublic { return v.ж.DiscoKey } + +// Addresses are the IP addresses of this Node directly. +func (v NodeView) Addresses() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.Addresses) } + +// AllowedIPs are the IP ranges to route to this node. +// +// As of CapabilityVersion 112, this may be nil (null or undefined) on the wire +// to mean the same as Addresses. Internally, it is always filled in with +// its possibly-implicit value. +func (v NodeView) AllowedIPs() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.AllowedIPs) } + +// IP+port (public via STUN, and local LANs) +func (v NodeView) Endpoints() views.Slice[netip.AddrPort] { return views.SliceOf(v.ж.Endpoints) } + +// LegacyDERPString is this node's home LegacyDERPString region ID integer, but shoved into an +// IP:port string for legacy reasons. The IP address is always "127.3.3.40" +// (a loopback address (127) followed by the digits over the letters DERP on +// a QWERTY keyboard (3.3.40)). The "port number" is the home LegacyDERPString region ID +// integer. +// +// Deprecated: HomeDERP has replaced this, but old servers might still send +// this field. See tailscale/tailscale#14636. Do not use this field in code +// other than in the upgradeNode func, which canonicalizes it to HomeDERP +// if it arrives as a LegacyDERPString string on the wire. +func (v NodeView) LegacyDERPString() string { return v.ж.LegacyDERPString } + +// HomeDERP is the modern version of the DERP string field, with just an +// integer. The client advertises support for this as of capver 111. +// +// HomeDERP may be zero if not (yet) known, but ideally always be non-zero +// for magicsock connectivity to function normally. +func (v NodeView) HomeDERP() int { return v.ж.HomeDERP } +func (v NodeView) Hostinfo() HostinfoView { return v.ж.Hostinfo } +func (v NodeView) Created() time.Time { return v.ж.Created } + +// if non-zero, the node's capability version; old servers might not send +func (v NodeView) Cap() CapabilityVersion { return v.ж.Cap } + +// Tags are the list of ACL tags applied to this node. +// Tags take the form of `tag:` where value starts +// with a letter and only contains alphanumerics and dashes `-`. +// Some valid tag examples: +// +// `tag:prod` +// `tag:database` +// `tag:lab-1` +func (v NodeView) Tags() views.Slice[string] { return views.SliceOf(v.ж.Tags) } + +// PrimaryRoutes are the routes from AllowedIPs that this node +// is currently the primary subnet router for, as determined +// by the control plane. It does not include the self address +// values from Addresses that are in AllowedIPs. func (v NodeView) PrimaryRoutes() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.PrimaryRoutes) } + +// LastSeen is when the node was last online. It is not +// updated when Online is true. It is nil if the current +// node doesn't have permission to know, or the node +// has never been online. func (v NodeView) LastSeen() views.ValuePointer[time.Time] { return views.ValuePointerOf(v.ж.LastSeen) } +// Online is whether the node is currently connected to the +// coordination server. A value of nil means unknown, or the +// current node doesn't have permission to know. func (v NodeView) Online() views.ValuePointer[bool] { return views.ValuePointerOf(v.ж.Online) } -func (v NodeView) MachineAuthorized() bool { return v.ж.MachineAuthorized } +// TODO(crawshaw): replace with MachineStatus +func (v NodeView) MachineAuthorized() bool { return v.ж.MachineAuthorized } + +// Capabilities are capabilities that the node has. +// They're free-form strings, but should be in the form of URLs/URIs +// such as: +// +// "https://tailscale.com/cap/is-admin" +// "https://tailscale.com/cap/file-sharing" +// +// Deprecated: use CapMap instead. See https://github.com/tailscale/tailscale/issues/11508 func (v NodeView) Capabilities() views.Slice[NodeCapability] { return views.SliceOf(v.ж.Capabilities) } +// CapMap is a map of capabilities to their optional argument/data values. +// +// It is valid for a capability to not have any argument/data values; such +// capabilities can be tested for using the HasCap method. These type of +// capabilities are used to indicate that a node has a capability, but there +// is no additional data associated with it. These were previously +// represented by the Capabilities field, but can now be represented by +// CapMap with an empty value. +// +// See NodeCapability for more information on keys. +// +// Metadata about nodes can be transmitted in 3 ways: +// 1. MapResponse.Node.CapMap describes attributes that affect behavior for +// this node, such as which features have been enabled through the admin +// panel and any associated configuration details. +// 2. MapResponse.PacketFilter(s) describes access (both IP and application +// based) that should be granted to peers. +// 3. MapResponse.Peers[].CapMap describes attributes regarding a peer node, +// such as which features the peer supports or if that peer is preferred +// for a particular task vs other peers that could also be chosen. func (v NodeView) CapMap() views.MapSlice[NodeCapability, RawMessage] { return views.MapSliceOf(v.ж.CapMap) } -func (v NodeView) UnsignedPeerAPIOnly() bool { return v.ж.UnsignedPeerAPIOnly } -func (v NodeView) ComputedName() string { return v.ж.ComputedName } + +// UnsignedPeerAPIOnly means that this node is not signed nor subject to TKA +// restrictions. However, in exchange for that privilege, it does not get +// network access. It can only access this node's peerapi, which may not let +// it do anything. It is the tailscaled client's job to double-check the +// MapResponse's PacketFilter to verify that its AllowedIPs will not be +// accepted by the packet filter. +func (v NodeView) UnsignedPeerAPIOnly() bool { return v.ж.UnsignedPeerAPIOnly } + +// MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS) +func (v NodeView) ComputedName() string { return v.ж.ComputedName } + +// either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost } -func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID } -func (v NodeView) Expired() bool { return v.ж.Expired } + +// DataPlaneAuditLogID is the per-node logtail ID used for data plane audit logging. +func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID } + +// Expired is whether this node's key has expired. Control may send +// this; clients are only allowed to set this from false to true. On +// the client, this is calculated client-side based on a timestamp sent +// from control, to avoid clock skew issues. +func (v NodeView) Expired() bool { return v.ж.Expired } + +// SelfNodeV4MasqAddrForThisPeer is the IPv4 that this peer knows the current node as. +// It may be empty if the peer knows the current node by its native +// IPv4 address. +// This field is only populated in a MapResponse for peers and not +// for the current node. +// +// If set, it should be used to masquerade traffic originating from the +// current node to this peer. The masquerade address is only relevant +// for this peer and not for other peers. +// +// This only applies to traffic originating from the current node to the +// peer or any of its subnets. Traffic originating from subnet routes will +// not be masqueraded (e.g. in case of --snat-subnet-routes). func (v NodeView) SelfNodeV4MasqAddrForThisPeer() views.ValuePointer[netip.Addr] { return views.ValuePointerOf(v.ж.SelfNodeV4MasqAddrForThisPeer) } +// SelfNodeV6MasqAddrForThisPeer is the IPv6 that this peer knows the current node as. +// It may be empty if the peer knows the current node by its native +// IPv6 address. +// This field is only populated in a MapResponse for peers and not +// for the current node. +// +// If set, it should be used to masquerade traffic originating from the +// current node to this peer. The masquerade address is only relevant +// for this peer and not for other peers. +// +// This only applies to traffic originating from the current node to the +// peer or any of its subnets. Traffic originating from subnet routes will +// not be masqueraded (e.g. in case of --snat-subnet-routes). func (v NodeView) SelfNodeV6MasqAddrForThisPeer() views.ValuePointer[netip.Addr] { return views.ValuePointerOf(v.ж.SelfNodeV6MasqAddrForThisPeer) } +// IsWireGuardOnly indicates that this is a non-Tailscale WireGuard peer, it +// is not expected to speak Disco or DERP, and it must have Endpoints in +// order to be reachable. func (v NodeView) IsWireGuardOnly() bool { return v.ж.IsWireGuardOnly } -func (v NodeView) IsJailed() bool { return v.ж.IsJailed } + +// IsJailed indicates that this node is jailed and should not be allowed +// initiate connections, however outbound connections to it should still be +// allowed. +func (v NodeView) IsJailed() bool { return v.ж.IsJailed } + +// ExitNodeDNSResolvers is the list of DNS servers that should be used when this +// node is marked IsWireGuardOnly and being used as an exit node. func (v NodeView) ExitNodeDNSResolvers() views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](v.ж.ExitNodeDNSResolvers) } @@ -246,8 +445,17 @@ func (v HostinfoView) AsStruct() *Hostinfo { return v.ж.Clone() } -func (v HostinfoView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v HostinfoView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v HostinfoView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *HostinfoView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -256,52 +464,166 @@ func (v *HostinfoView) UnmarshalJSON(b []byte) error { return nil } var x Hostinfo - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v HostinfoView) IPNVersion() string { return v.ж.IPNVersion } -func (v HostinfoView) FrontendLogID() string { return v.ж.FrontendLogID } -func (v HostinfoView) BackendLogID() string { return v.ж.BackendLogID } -func (v HostinfoView) OS() string { return v.ж.OS } -func (v HostinfoView) OSVersion() string { return v.ж.OSVersion } -func (v HostinfoView) Container() opt.Bool { return v.ж.Container } -func (v HostinfoView) Env() string { return v.ж.Env } -func (v HostinfoView) Distro() string { return v.ж.Distro } -func (v HostinfoView) DistroVersion() string { return v.ж.DistroVersion } -func (v HostinfoView) DistroCodeName() string { return v.ж.DistroCodeName } -func (v HostinfoView) App() string { return v.ж.App } -func (v HostinfoView) Desktop() opt.Bool { return v.ж.Desktop } -func (v HostinfoView) Package() string { return v.ж.Package } -func (v HostinfoView) DeviceModel() string { return v.ж.DeviceModel } -func (v HostinfoView) PushDeviceToken() string { return v.ж.PushDeviceToken } -func (v HostinfoView) Hostname() string { return v.ж.Hostname } -func (v HostinfoView) ShieldsUp() bool { return v.ж.ShieldsUp } -func (v HostinfoView) ShareeNode() bool { return v.ж.ShareeNode } -func (v HostinfoView) NoLogsNoSupport() bool { return v.ж.NoLogsNoSupport } -func (v HostinfoView) WireIngress() bool { return v.ж.WireIngress } -func (v HostinfoView) IngressEnabled() bool { return v.ж.IngressEnabled } -func (v HostinfoView) AllowsUpdate() bool { return v.ж.AllowsUpdate } -func (v HostinfoView) Machine() string { return v.ж.Machine } -func (v HostinfoView) GoArch() string { return v.ж.GoArch } -func (v HostinfoView) GoArchVar() string { return v.ж.GoArchVar } -func (v HostinfoView) GoVersion() string { return v.ж.GoVersion } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *HostinfoView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Hostinfo + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// version of this code (in version.Long format) +func (v HostinfoView) IPNVersion() string { return v.ж.IPNVersion } + +// logtail ID of frontend instance +func (v HostinfoView) FrontendLogID() string { return v.ж.FrontendLogID } + +// logtail ID of backend instance +func (v HostinfoView) BackendLogID() string { return v.ж.BackendLogID } + +// operating system the client runs on (a version.OS value) +func (v HostinfoView) OS() string { return v.ж.OS } + +// OSVersion is the version of the OS, if available. +// +// For Android, it's like "10", "11", "12", etc. For iOS and macOS it's like +// "15.6.1" or "12.4.0". For Windows it's like "10.0.19044.1889". For +// FreeBSD it's like "12.3-STABLE". +// +// For Linux, prior to Tailscale 1.32, we jammed a bunch of fields into this +// string on Linux, like "Debian 10.4; kernel=xxx; container; env=kn" and so +// on. As of Tailscale 1.32, this is simply the kernel version on Linux, like +// "5.10.0-17-amd64". +func (v HostinfoView) OSVersion() string { return v.ж.OSVersion } + +// best-effort whether the client is running in a container +func (v HostinfoView) Container() opt.Bool { return v.ж.Container } + +// a hostinfo.EnvType in string form +func (v HostinfoView) Env() string { return v.ж.Env } + +// "debian", "ubuntu", "nixos", ... +func (v HostinfoView) Distro() string { return v.ж.Distro } + +// "20.04", ... +func (v HostinfoView) DistroVersion() string { return v.ж.DistroVersion } + +// "jammy", "bullseye", ... +func (v HostinfoView) DistroCodeName() string { return v.ж.DistroCodeName } + +// App is used to disambiguate Tailscale clients that run using tsnet. +func (v HostinfoView) App() string { return v.ж.App } + +// if a desktop was detected on Linux +func (v HostinfoView) Desktop() opt.Bool { return v.ж.Desktop } + +// Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown) +func (v HostinfoView) Package() string { return v.ж.Package } + +// mobile phone model ("Pixel 3a", "iPhone12,3") +func (v HostinfoView) DeviceModel() string { return v.ж.DeviceModel } + +// macOS/iOS APNs device token for notifications (and Android in the future) +func (v HostinfoView) PushDeviceToken() string { return v.ж.PushDeviceToken } + +// name of the host the client runs on +func (v HostinfoView) Hostname() string { return v.ж.Hostname } + +// indicates whether the host is blocking incoming connections +func (v HostinfoView) ShieldsUp() bool { return v.ж.ShieldsUp } + +// indicates this node exists in netmap because it's owned by a shared-to user +func (v HostinfoView) ShareeNode() bool { return v.ж.ShareeNode } + +// indicates that the user has opted out of sending logs and support +func (v HostinfoView) NoLogsNoSupport() bool { return v.ж.NoLogsNoSupport } + +// WireIngress indicates that the node would like to be wired up server-side +// (DNS, etc) to be able to use Tailscale Funnel, even if it's not currently +// enabled. For example, the user might only use it for intermittent +// foreground CLI serve sessions, for which they'd like it to work right +// away, even if it's disabled most of the time. As an optimization, this is +// only sent if IngressEnabled is false, as IngressEnabled implies that this +// option is true. +func (v HostinfoView) WireIngress() bool { return v.ж.WireIngress } + +// if the node has any funnel endpoint enabled +func (v HostinfoView) IngressEnabled() bool { return v.ж.IngressEnabled } + +// indicates that the node has opted-in to admin-console-drive remote updates +func (v HostinfoView) AllowsUpdate() bool { return v.ж.AllowsUpdate } + +// the current host's machine type (uname -m) +func (v HostinfoView) Machine() string { return v.ж.Machine } + +// GOARCH value (of the built binary) +func (v HostinfoView) GoArch() string { return v.ж.GoArch } + +// GOARM, GOAMD64, etc (of the built binary) +func (v HostinfoView) GoArchVar() string { return v.ж.GoArchVar } + +// Go version binary was built with +func (v HostinfoView) GoVersion() string { return v.ж.GoVersion } + +// set of IP ranges this client can route func (v HostinfoView) RoutableIPs() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.RoutableIPs) } -func (v HostinfoView) RequestTags() views.Slice[string] { return views.SliceOf(v.ж.RequestTags) } -func (v HostinfoView) WoLMACs() views.Slice[string] { return views.SliceOf(v.ж.WoLMACs) } -func (v HostinfoView) Services() views.Slice[Service] { return views.SliceOf(v.ж.Services) } -func (v HostinfoView) NetInfo() NetInfoView { return v.ж.NetInfo.View() } -func (v HostinfoView) SSH_HostKeys() views.Slice[string] { return views.SliceOf(v.ж.SSH_HostKeys) } -func (v HostinfoView) Cloud() string { return v.ж.Cloud } -func (v HostinfoView) Userspace() opt.Bool { return v.ж.Userspace } -func (v HostinfoView) UserspaceRouter() opt.Bool { return v.ж.UserspaceRouter } -func (v HostinfoView) AppConnector() opt.Bool { return v.ж.AppConnector } -func (v HostinfoView) ServicesHash() string { return v.ж.ServicesHash } -func (v HostinfoView) Location() LocationView { return v.ж.Location.View() } -func (v HostinfoView) Equal(v2 HostinfoView) bool { return v.ж.Equal(v2.ж) } + +// set of ACL tags this node wants to claim +func (v HostinfoView) RequestTags() views.Slice[string] { return views.SliceOf(v.ж.RequestTags) } + +// MAC address(es) to send Wake-on-LAN packets to wake this node (lowercase hex w/ colons) +func (v HostinfoView) WoLMACs() views.Slice[string] { return views.SliceOf(v.ж.WoLMACs) } + +// services advertised by this machine +func (v HostinfoView) Services() views.Slice[Service] { return views.SliceOf(v.ж.Services) } +func (v HostinfoView) NetInfo() NetInfoView { return v.ж.NetInfo.View() } + +// if advertised +func (v HostinfoView) SSH_HostKeys() views.Slice[string] { return views.SliceOf(v.ж.SSH_HostKeys) } +func (v HostinfoView) Cloud() string { return v.ж.Cloud } + +// if the client is running in userspace (netstack) mode +func (v HostinfoView) Userspace() opt.Bool { return v.ж.Userspace } + +// if the client's subnet router is running in userspace (netstack) mode +func (v HostinfoView) UserspaceRouter() opt.Bool { return v.ж.UserspaceRouter } + +// if the client is running the app-connector service +func (v HostinfoView) AppConnector() opt.Bool { return v.ж.AppConnector } + +// opaque hash of the most recent list of tailnet services, change in hash indicates config should be fetched via c2n +func (v HostinfoView) ServicesHash() string { return v.ж.ServicesHash } + +// the client’s selected exit node, empty when unselected. +func (v HostinfoView) ExitNodeID() StableNodeID { return v.ж.ExitNodeID } + +// Location represents geographical location data about a +// Tailscale host. Location is optional and only set if +// explicitly declared by a node. +func (v HostinfoView) Location() LocationView { return v.ж.Location.View() } + +// TPM device metadata, if available +func (v HostinfoView) TPM() views.ValuePointer[TPMInfo] { return views.ValuePointerOf(v.ж.TPM) } + +// StateEncrypted reports whether the node state is stored encrypted on +// disk. The actual mechanism is platform-specific: +// - Apple nodes use the Keychain +// - Linux and Windows nodes use the TPM +// - Android apps use EncryptedSharedPreferences +func (v HostinfoView) StateEncrypted() opt.Bool { return v.ж.StateEncrypted } +func (v HostinfoView) Equal(v2 HostinfoView) bool { return v.ж.Equal(v2.ж) } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _HostinfoViewNeedsRegeneration = Hostinfo(struct { @@ -342,7 +664,10 @@ var _HostinfoViewNeedsRegeneration = Hostinfo(struct { UserspaceRouter opt.Bool AppConnector opt.Bool ServicesHash string + ExitNodeID StableNodeID Location *Location + TPM *TPMInfo + StateEncrypted opt.Bool }{}) // View returns a read-only view of NetInfo. @@ -373,8 +698,17 @@ func (v NetInfoView) AsStruct() *NetInfo { return v.ж.Clone() } -func (v NetInfoView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v NetInfoView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v NetInfoView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *NetInfoView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -383,34 +717,94 @@ func (v *NetInfoView) UnmarshalJSON(b []byte) error { return nil } var x NetInfo - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v NetInfoView) MappingVariesByDestIP() opt.Bool { return v.ж.MappingVariesByDestIP } -func (v NetInfoView) HairPinning() opt.Bool { return v.ж.HairPinning } -func (v NetInfoView) WorkingIPv6() opt.Bool { return v.ж.WorkingIPv6 } -func (v NetInfoView) OSHasIPv6() opt.Bool { return v.ж.OSHasIPv6 } -func (v NetInfoView) WorkingUDP() opt.Bool { return v.ж.WorkingUDP } -func (v NetInfoView) WorkingICMPv4() opt.Bool { return v.ж.WorkingICMPv4 } -func (v NetInfoView) HavePortMap() bool { return v.ж.HavePortMap } -func (v NetInfoView) UPnP() opt.Bool { return v.ж.UPnP } -func (v NetInfoView) PMP() opt.Bool { return v.ж.PMP } -func (v NetInfoView) PCP() opt.Bool { return v.ж.PCP } -func (v NetInfoView) PreferredDERP() int { return v.ж.PreferredDERP } -func (v NetInfoView) LinkType() string { return v.ж.LinkType } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *NetInfoView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x NetInfo + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} +// MappingVariesByDestIP says whether the host's NAT mappings +// vary based on the destination IP. +func (v NetInfoView) MappingVariesByDestIP() opt.Bool { return v.ж.MappingVariesByDestIP } + +// WorkingIPv6 is whether the host has IPv6 internet connectivity. +func (v NetInfoView) WorkingIPv6() opt.Bool { return v.ж.WorkingIPv6 } + +// OSHasIPv6 is whether the OS supports IPv6 at all, regardless of +// whether IPv6 internet connectivity is available. +func (v NetInfoView) OSHasIPv6() opt.Bool { return v.ж.OSHasIPv6 } + +// WorkingUDP is whether the host has UDP internet connectivity. +func (v NetInfoView) WorkingUDP() opt.Bool { return v.ж.WorkingUDP } + +// WorkingICMPv4 is whether ICMPv4 works. +// Empty means not checked. +func (v NetInfoView) WorkingICMPv4() opt.Bool { return v.ж.WorkingICMPv4 } + +// HavePortMap is whether we have an existing portmap open +// (UPnP, PMP, or PCP). +func (v NetInfoView) HavePortMap() bool { return v.ж.HavePortMap } + +// UPnP is whether UPnP appears present on the LAN. +// Empty means not checked. +func (v NetInfoView) UPnP() opt.Bool { return v.ж.UPnP } + +// PMP is whether NAT-PMP appears present on the LAN. +// Empty means not checked. +func (v NetInfoView) PMP() opt.Bool { return v.ж.PMP } + +// PCP is whether PCP appears present on the LAN. +// Empty means not checked. +func (v NetInfoView) PCP() opt.Bool { return v.ж.PCP } + +// PreferredDERP is this node's preferred (home) DERP region ID. +// This is where the node expects to be contacted to begin a +// peer-to-peer connection. The node might be be temporarily +// connected to multiple DERP servers (to speak to other nodes +// that are located elsewhere) but PreferredDERP is the region ID +// that the node subscribes to traffic at. +// Zero means disconnected or unknown. +func (v NetInfoView) PreferredDERP() int { return v.ж.PreferredDERP } + +// LinkType is the current link type, if known. +func (v NetInfoView) LinkType() string { return v.ж.LinkType } + +// DERPLatency is the fastest recent time to reach various +// DERP STUN servers, in seconds. The map key is the +// "regionID-v4" or "-v6"; it was previously the DERP server's +// STUN host:port. +// +// This should only be updated rarely, or when there's a +// material change, as any change here also gets uploaded to +// the control plane. func (v NetInfoView) DERPLatency() views.Map[string, float64] { return views.MapOf(v.ж.DERPLatency) } -func (v NetInfoView) FirewallMode() string { return v.ж.FirewallMode } -func (v NetInfoView) String() string { return v.ж.String() } + +// FirewallMode encodes both which firewall mode was selected and why. +// It is Linux-specific (at least as of 2023-08-19) and is meant to help +// debug iptables-vs-nftables issues. The string is of the form +// "{nft,ift}-REASON", like "nft-forced" or "ipt-default". Empty means +// either not Linux or a configuration in which the host firewall rules +// are not managed by tailscaled. +func (v NetInfoView) FirewallMode() string { return v.ж.FirewallMode } +func (v NetInfoView) String() string { return v.ж.String() } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _NetInfoViewNeedsRegeneration = NetInfo(struct { MappingVariesByDestIP opt.Bool - HairPinning opt.Bool WorkingIPv6 opt.Bool OSHasIPv6 opt.Bool WorkingUDP opt.Bool @@ -453,8 +847,17 @@ func (v LoginView) AsStruct() *Login { return v.ж.Clone() } -func (v LoginView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v LoginView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v LoginView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *LoginView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -463,17 +866,39 @@ func (v *LoginView) UnmarshalJSON(b []byte) error { return nil } var x Login - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v LoginView) ID() LoginID { return v.ж.ID } -func (v LoginView) Provider() string { return v.ж.Provider } -func (v LoginView) LoginName() string { return v.ж.LoginName } -func (v LoginView) DisplayName() string { return v.ж.DisplayName } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *LoginView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Login + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// unused in the Tailscale client +func (v LoginView) ID() LoginID { return v.ж.ID } + +// "google", "github", "okta_foo", etc. +func (v LoginView) Provider() string { return v.ж.Provider } + +// an email address or "email-ish" string (like alice@github) +func (v LoginView) LoginName() string { return v.ж.LoginName } + +// from the IdP +func (v LoginView) DisplayName() string { return v.ж.DisplayName } + +// from the IdP func (v LoginView) ProfilePicURL() string { return v.ж.ProfilePicURL } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -514,8 +939,17 @@ func (v DNSConfigView) AsStruct() *DNSConfig { return v.ж.Clone() } -func (v DNSConfigView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v DNSConfigView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v DNSConfigView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *DNSConfigView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -524,33 +958,102 @@ func (v *DNSConfigView) UnmarshalJSON(b []byte) error { return nil } var x DNSConfig - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *DNSConfigView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x DNSConfig + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Resolvers are the DNS resolvers to use, in order of preference. func (v DNSConfigView) Resolvers() views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](v.ж.Resolvers) } +// Routes maps DNS name suffixes to a set of DNS resolvers to +// use. It is used to implement "split DNS" and other advanced DNS +// routing overlays. +// +// Map keys are fully-qualified DNS name suffixes; they may +// optionally contain a trailing dot but no leading dot. +// +// If the value is an empty slice, that means the suffix should still +// be handled by Tailscale's built-in resolver (100.100.100.100), such +// as for the purpose of handling ExtraRecords. func (v DNSConfigView) Routes() views.MapFn[string, []*dnstype.Resolver, views.SliceView[*dnstype.Resolver, dnstype.ResolverView]] { return views.MapFnOf(v.ж.Routes, func(t []*dnstype.Resolver) views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](t) }) } + +// FallbackResolvers is like Resolvers, but is only used if a +// split DNS configuration is requested in a configuration that +// doesn't work yet without explicit default resolvers. +// https://github.com/tailscale/tailscale/issues/1743 func (v DNSConfigView) FallbackResolvers() views.SliceView[*dnstype.Resolver, dnstype.ResolverView] { return views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](v.ж.FallbackResolvers) } -func (v DNSConfigView) Domains() views.Slice[string] { return views.SliceOf(v.ж.Domains) } -func (v DNSConfigView) Proxied() bool { return v.ж.Proxied } + +// Domains are the search domains to use. +// Search domains must be FQDNs, but *without* the trailing dot. +func (v DNSConfigView) Domains() views.Slice[string] { return views.SliceOf(v.ж.Domains) } + +// Proxied turns on automatic resolution of hostnames for devices +// in the network map, aka MagicDNS. +// Despite the (legacy) name, does not necessarily cause request +// proxying to be enabled. +func (v DNSConfigView) Proxied() bool { return v.ж.Proxied } + +// Nameservers are the IP addresses of the global nameservers to use. +// +// Deprecated: this is only set and used by MapRequest.Version >=9 and <14. Use Resolvers instead. func (v DNSConfigView) Nameservers() views.Slice[netip.Addr] { return views.SliceOf(v.ж.Nameservers) } -func (v DNSConfigView) CertDomains() views.Slice[string] { return views.SliceOf(v.ж.CertDomains) } + +// CertDomains are the set of DNS names for which the control +// plane server will assist with provisioning TLS +// certificates. See SetDNSRequest, which can be used to +// answer dns-01 ACME challenges for e.g. LetsEncrypt. +// These names are FQDNs without trailing periods, and without +// any "_acme-challenge." prefix. +func (v DNSConfigView) CertDomains() views.Slice[string] { return views.SliceOf(v.ж.CertDomains) } + +// ExtraRecords contains extra DNS records to add to the +// MagicDNS config. func (v DNSConfigView) ExtraRecords() views.Slice[DNSRecord] { return views.SliceOf(v.ж.ExtraRecords) } + +// ExitNodeFilteredSuffixes are the DNS suffixes that the +// node, when being an exit node DNS proxy, should not answer. +// +// The entries do not contain trailing periods and are always +// all lowercase. +// +// If an entry starts with a period, it's a suffix match (but +// suffix ".a.b" doesn't match "a.b"; a prefix is required). +// +// If an entry does not start with a period, it's an exact +// match. +// +// Matches are case insensitive. func (v DNSConfigView) ExitNodeFilteredSet() views.Slice[string] { return views.SliceOf(v.ж.ExitNodeFilteredSet) } + +// TempCorpIssue13969 is a temporary (2023-08-16) field for an internal hack day prototype. +// It contains a user inputed URL that should have a list of domains to be blocked. +// See https://github.com/tailscale/corp/issues/13969. func (v DNSConfigView) TempCorpIssue13969() string { return v.ж.TempCorpIssue13969 } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -595,8 +1098,17 @@ func (v RegisterResponseView) AsStruct() *RegisterResponse { return v.ж.Clone() } -func (v RegisterResponseView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v RegisterResponseView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v RegisterResponseView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *RegisterResponseView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -605,21 +1117,46 @@ func (v *RegisterResponseView) UnmarshalJSON(b []byte) error { return nil } var x RegisterResponse - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v RegisterResponseView) User() User { return v.ж.User } -func (v RegisterResponseView) Login() Login { return v.ж.Login } -func (v RegisterResponseView) NodeKeyExpired() bool { return v.ж.NodeKeyExpired } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *RegisterResponseView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x RegisterResponse + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v RegisterResponseView) User() User { return v.ж.User } +func (v RegisterResponseView) Login() Login { return v.ж.Login } + +// if true, the NodeKey needs to be replaced +func (v RegisterResponseView) NodeKeyExpired() bool { return v.ж.NodeKeyExpired } + +// TODO(crawshaw): move to using MachineStatus func (v RegisterResponseView) MachineAuthorized() bool { return v.ж.MachineAuthorized } -func (v RegisterResponseView) AuthURL() string { return v.ж.AuthURL } + +// if set, authorization pending +func (v RegisterResponseView) AuthURL() string { return v.ж.AuthURL } + +// If set, this is the current node-key signature that needs to be +// re-signed for the node's new node-key. func (v RegisterResponseView) NodeKeySignature() views.ByteSlice[tkatype.MarshaledSignature] { return views.ByteSliceOf(v.ж.NodeKeySignature) } + +// Error indicates that authorization failed. If this is non-empty, +// other status fields should be ignored. func (v RegisterResponseView) Error() string { return v.ж.Error } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -661,8 +1198,17 @@ func (v RegisterResponseAuthView) AsStruct() *RegisterResponseAuth { return v.ж.Clone() } -func (v RegisterResponseAuthView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v RegisterResponseAuthView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v RegisterResponseAuthView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *RegisterResponseAuthView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -671,13 +1217,27 @@ func (v *RegisterResponseAuthView) UnmarshalJSON(b []byte) error { return nil } var x RegisterResponseAuth - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *RegisterResponseAuthView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x RegisterResponseAuth + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// used by pre-1.66 Android only func (v RegisterResponseAuthView) Oauth2Token() views.ValuePointer[Oauth2Token] { return views.ValuePointerOf(v.ж.Oauth2Token) } @@ -719,8 +1279,17 @@ func (v RegisterRequestView) AsStruct() *RegisterRequest { return v.ж.Clone() } -func (v RegisterRequestView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v RegisterRequestView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v RegisterRequestView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *RegisterRequestView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -729,36 +1298,89 @@ func (v *RegisterRequestView) UnmarshalJSON(b []byte) error { return nil } var x RegisterRequest - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *RegisterRequestView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x RegisterRequest + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Version is the client's capabilities when using the Noise +// transport. +// +// When using the original nacl crypto_box transport, the +// value must be 1. func (v RegisterRequestView) Version() CapabilityVersion { return v.ж.Version } func (v RegisterRequestView) NodeKey() key.NodePublic { return v.ж.NodeKey } func (v RegisterRequestView) OldNodeKey() key.NodePublic { return v.ж.OldNodeKey } func (v RegisterRequestView) NLKey() key.NLPublic { return v.ж.NLKey } func (v RegisterRequestView) Auth() RegisterResponseAuthView { return v.ж.Auth.View() } -func (v RegisterRequestView) Expiry() time.Time { return v.ж.Expiry } -func (v RegisterRequestView) Followup() string { return v.ж.Followup } -func (v RegisterRequestView) Hostinfo() HostinfoView { return v.ж.Hostinfo.View() } -func (v RegisterRequestView) Ephemeral() bool { return v.ж.Ephemeral } + +// Expiry optionally specifies the requested key expiry. +// The server policy may override. +// As a special case, if Expiry is in the past and NodeKey is +// the node's current key, the key is expired. +func (v RegisterRequestView) Expiry() time.Time { return v.ж.Expiry } + +// response waits until AuthURL is visited +func (v RegisterRequestView) Followup() string { return v.ж.Followup } +func (v RegisterRequestView) Hostinfo() HostinfoView { return v.ж.Hostinfo.View() } + +// Ephemeral is whether the client is requesting that this +// node be considered ephemeral and be automatically deleted +// when it stops being active. +func (v RegisterRequestView) Ephemeral() bool { return v.ж.Ephemeral } + +// NodeKeySignature is the node's own node-key signature, re-signed +// for its new node key using its network-lock key. +// +// This field is set when the client retries registration after learning +// its NodeKeySignature (which is in need of rotation). func (v RegisterRequestView) NodeKeySignature() views.ByteSlice[tkatype.MarshaledSignature] { return views.ByteSliceOf(v.ж.NodeKeySignature) } + +// The following fields are not used for SignatureNone and are required for +// SignatureV1: func (v RegisterRequestView) SignatureType() SignatureType { return v.ж.SignatureType } + +// creation time of request to prevent replay func (v RegisterRequestView) Timestamp() views.ValuePointer[time.Time] { return views.ValuePointerOf(v.ж.Timestamp) } +// X.509 certificate for client device func (v RegisterRequestView) DeviceCert() views.ByteSlice[[]byte] { return views.ByteSliceOf(v.ж.DeviceCert) } + +// as described by SignatureType func (v RegisterRequestView) Signature() views.ByteSlice[[]byte] { return views.ByteSliceOf(v.ж.Signature) } + +// Tailnet is an optional identifier specifying the name of the recommended or required +// network that the node should join. Its exact form should not be depended on; new +// forms are coming later. The identifier is generally a domain name (for an organization) +// or e-mail address (for a personal account on a shared e-mail provider). It is the same name +// used by the API, as described in /api.md#tailnet. +// If Tailnet begins with the prefix "required:" then the server should prevent logging in to a different +// network than the one specified. Otherwise, the server should recommend the specified network +// but still permit logging in to other networks. +// If empty, no recommendation is offered to the server and the login page should show all options. func (v RegisterRequestView) Tailnet() string { return v.ж.Tailnet } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -809,8 +1431,17 @@ func (v DERPHomeParamsView) AsStruct() *DERPHomeParams { return v.ж.Clone() } -func (v DERPHomeParamsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v DERPHomeParamsView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v DERPHomeParamsView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *DERPHomeParamsView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -819,13 +1450,39 @@ func (v *DERPHomeParamsView) UnmarshalJSON(b []byte) error { return nil } var x DERPHomeParams - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *DERPHomeParamsView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x DERPHomeParams + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// RegionScore scales latencies of DERP regions by a given scaling +// factor when determining which region to use as the home +// ("preferred") DERP. Scores in the range (0, 1) will cause this +// region to be proportionally more preferred, and scores in the range +// (1, ∞) will penalize a region. +// +// If a region is not present in this map, it is treated as having a +// score of 1.0. +// +// Scores should not be 0 or negative; such scores will be ignored. +// +// A nil map means no change from the previous value (if any); an empty +// non-nil map can be sent to reset all scores back to 1.0. func (v DERPHomeParamsView) RegionScore() views.Map[int, float64] { return views.MapOf(v.ж.RegionScore) } @@ -863,8 +1520,17 @@ func (v DERPRegionView) AsStruct() *DERPRegion { return v.ж.Clone() } -func (v DERPRegionView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v DERPRegionView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v DERPRegionView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *DERPRegionView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -873,20 +1539,91 @@ func (v *DERPRegionView) UnmarshalJSON(b []byte) error { return nil } var x DERPRegion - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v DERPRegionView) RegionID() int { return v.ж.RegionID } -func (v DERPRegionView) RegionCode() string { return v.ж.RegionCode } -func (v DERPRegionView) RegionName() string { return v.ж.RegionName } -func (v DERPRegionView) Latitude() float64 { return v.ж.Latitude } -func (v DERPRegionView) Longitude() float64 { return v.ж.Longitude } -func (v DERPRegionView) Avoid() bool { return v.ж.Avoid } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *DERPRegionView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x DERPRegion + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// RegionID is a unique integer for a geographic region. +// +// It corresponds to the legacy derpN.tailscale.com hostnames +// used by older clients. (Older clients will continue to resolve +// derpN.tailscale.com when contacting peers, rather than use +// the server-provided DERPMap) +// +// RegionIDs must be non-zero, positive, and guaranteed to fit +// in a JavaScript number. +// +// RegionIDs in range 900-999 are reserved for end users to run their +// own DERP nodes. +func (v DERPRegionView) RegionID() int { return v.ж.RegionID } + +// RegionCode is a short name for the region. It's usually a popular +// city or airport code in the region: "nyc", "sf", "sin", +// "fra", etc. +func (v DERPRegionView) RegionCode() string { return v.ж.RegionCode } + +// RegionName is a long English name for the region: "New York City", +// "San Francisco", "Singapore", "Frankfurt", etc. +func (v DERPRegionView) RegionName() string { return v.ж.RegionName } + +// Latitude, Longitude are optional geographical coordinates of the DERP region's city, in degrees. +func (v DERPRegionView) Latitude() float64 { return v.ж.Latitude } +func (v DERPRegionView) Longitude() float64 { return v.ж.Longitude } + +// Avoid is whether the client should avoid picking this as its home region. +// The region should only be used if a peer is there. Clients already using +// this region as their home should migrate away to a new region without +// Avoid set. +// +// Deprecated: because of bugs in past implementations combined with unclear +// docs that caused people to think the bugs were intentional, this field is +// deprecated. It was never supposed to cause STUN/DERP measurement probes, +// but due to bugs, it sometimes did. And then some parts of the code began +// to rely on that property. But then we were unable to use this field for +// its original purpose, nor its later imagined purpose, because various +// parts of the codebase thought it meant one thing and others thought it +// meant another. But it did something in the middle instead. So we're retiring +// it. Use NoMeasureNoHome instead. +func (v DERPRegionView) Avoid() bool { return v.ж.Avoid } + +// NoMeasureNoHome says that this regions should not be measured for its +// latency distance (STUN, HTTPS, etc) or availability (e.g. captive portal +// checks) and should never be selected as the node's home region. However, +// if a peer declares this region as its home, then this client is allowed +// to connect to it for the purpose of communicating with that peer. +// +// This is what the now deprecated Avoid bool was supposed to mean +// originally but had implementation bugs and documentation omissions. func (v DERPRegionView) NoMeasureNoHome() bool { return v.ж.NoMeasureNoHome } + +// Nodes are the DERP nodes running in this region, in +// priority order for the current client. Client TLS +// connections should ideally only go to the first entry +// (falling back to the second if necessary). STUN packets +// should go to the first 1 or 2. +// +// If nodes within a region route packets amongst themselves, +// but not to other regions. That said, each user/domain +// should get a the same preferred node order, so if all nodes +// for a user/network pick the first one (as they should, when +// things are healthy), the inter-cluster routing is minimal +// to zero. func (v DERPRegionView) Nodes() views.SliceView[*DERPNode, DERPNodeView] { return views.SliceOfViews[*DERPNode, DERPNodeView](v.ж.Nodes) } @@ -931,8 +1668,17 @@ func (v DERPMapView) AsStruct() *DERPMap { return v.ж.Clone() } -func (v DERPMapView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v DERPMapView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v DERPMapView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *DERPMapView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -941,20 +1687,46 @@ func (v *DERPMapView) UnmarshalJSON(b []byte) error { return nil } var x DERPMap - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *DERPMapView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x DERPMap + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// HomeParams, if non-nil, is a change in home parameters. +// +// The rest of the DEPRMap fields, if zero, means unchanged. func (v DERPMapView) HomeParams() DERPHomeParamsView { return v.ж.HomeParams.View() } +// Regions is the set of geographic regions running DERP node(s). +// +// It's keyed by the DERPRegion.RegionID. +// +// The numbers are not necessarily contiguous. func (v DERPMapView) Regions() views.MapFn[int, *DERPRegion, DERPRegionView] { return views.MapFnOf(v.ж.Regions, func(t *DERPRegion) DERPRegionView { return t.View() }) } + +// OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those +// specified in this DERPMap. If there are none set outside of the defaults, this is a noop. +// +// This field is only meaningful if the Regions map is non-nil (indicating a change). func (v DERPMapView) OmitDefaultRegions() bool { return v.ж.OmitDefaultRegions } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -992,8 +1764,17 @@ func (v DERPNodeView) AsStruct() *DERPNode { return v.ж.Clone() } -func (v DERPNodeView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v DERPNodeView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v DERPNodeView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *DERPNodeView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1002,25 +1783,94 @@ func (v *DERPNodeView) UnmarshalJSON(b []byte) error { return nil } var x DERPNode - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v DERPNodeView) Name() string { return v.ж.Name } -func (v DERPNodeView) RegionID() int { return v.ж.RegionID } -func (v DERPNodeView) HostName() string { return v.ж.HostName } -func (v DERPNodeView) CertName() string { return v.ж.CertName } -func (v DERPNodeView) IPv4() string { return v.ж.IPv4 } -func (v DERPNodeView) IPv6() string { return v.ж.IPv6 } -func (v DERPNodeView) STUNPort() int { return v.ж.STUNPort } -func (v DERPNodeView) STUNOnly() bool { return v.ж.STUNOnly } -func (v DERPNodeView) DERPPort() int { return v.ж.DERPPort } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *DERPNodeView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x DERPNode + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Name is a unique node name (across all regions). +// It is not a host name. +// It's typically of the form "1b", "2a", "3b", etc. (region +// ID + suffix within that region) +func (v DERPNodeView) Name() string { return v.ж.Name } + +// RegionID is the RegionID of the DERPRegion that this node +// is running in. +func (v DERPNodeView) RegionID() int { return v.ж.RegionID } + +// HostName is the DERP node's hostname. +// +// It is required but need not be unique; multiple nodes may +// have the same HostName but vary in configuration otherwise. +func (v DERPNodeView) HostName() string { return v.ж.HostName } + +// CertName optionally specifies the expected TLS cert common +// name. If empty, HostName is used. If CertName is non-empty, +// HostName is only used for the TCP dial (if IPv4/IPv6 are +// not present) + TLS ClientHello. +// +// As a special case, if CertName starts with "sha256-raw:", +// then the rest of the string is a hex-encoded SHA256 of the +// cert to expect. This is used for self-signed certs. +// In this case, the HostName field will typically be an IP +// address literal. +func (v DERPNodeView) CertName() string { return v.ж.CertName } + +// IPv4 optionally forces an IPv4 address to use, instead of using DNS. +// If empty, A record(s) from DNS lookups of HostName are used. +// If the string is not an IPv4 address, IPv4 is not used; the +// conventional string to disable IPv4 (and not use DNS) is +// "none". +func (v DERPNodeView) IPv4() string { return v.ж.IPv4 } + +// IPv6 optionally forces an IPv6 address to use, instead of using DNS. +// If empty, AAAA record(s) from DNS lookups of HostName are used. +// If the string is not an IPv6 address, IPv6 is not used; the +// conventional string to disable IPv6 (and not use DNS) is +// "none". +func (v DERPNodeView) IPv6() string { return v.ж.IPv6 } + +// Port optionally specifies a STUN port to use. +// Zero means 3478. +// To disable STUN on this node, use -1. +func (v DERPNodeView) STUNPort() int { return v.ж.STUNPort } + +// STUNOnly marks a node as only a STUN server and not a DERP +// server. +func (v DERPNodeView) STUNOnly() bool { return v.ж.STUNOnly } + +// DERPPort optionally provides an alternate TLS port number +// for the DERP HTTPS server. +// +// If zero, 443 is used. +func (v DERPNodeView) DERPPort() int { return v.ж.DERPPort } + +// InsecureForTests is used by unit tests to disable TLS verification. +// It should not be set by users. func (v DERPNodeView) InsecureForTests() bool { return v.ж.InsecureForTests } -func (v DERPNodeView) STUNTestIP() string { return v.ж.STUNTestIP } -func (v DERPNodeView) CanPort80() bool { return v.ж.CanPort80 } + +// STUNTestIP is used in tests to override the STUN server's IP. +// If empty, it's assumed to be the same as the DERP server. +func (v DERPNodeView) STUNTestIP() string { return v.ж.STUNTestIP } + +// CanPort80 specifies whether this DERP node is accessible over HTTP +// on port 80 specifically. This is used for captive portal checks. +func (v DERPNodeView) CanPort80() bool { return v.ж.CanPort80 } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _DERPNodeViewNeedsRegeneration = DERPNode(struct { @@ -1066,8 +1916,17 @@ func (v SSHRuleView) AsStruct() *SSHRule { return v.ж.Clone() } -func (v SSHRuleView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v SSHRuleView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v SSHRuleView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *SSHRuleView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1076,24 +1935,69 @@ func (v *SSHRuleView) UnmarshalJSON(b []byte) error { return nil } var x SSHRule - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *SSHRuleView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x SSHRule + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// RuleExpires, if non-nil, is when this rule expires. +// +// For example, a (principal,sshuser) tuple might be granted +// prompt-free SSH access for N minutes, so this rule would be +// before a expiration-free rule for the same principal that +// required an auth prompt. This permits the control plane to +// be out of the path for already-authorized SSH pairs. +// +// Once a rule matches, the lifetime of any accepting connection +// is subject to the SSHAction.SessionExpires time, if any. func (v SSHRuleView) RuleExpires() views.ValuePointer[time.Time] { return views.ValuePointerOf(v.ж.RuleExpires) } +// Principals matches an incoming connection. If the connection +// matches anything in this list and also matches SSHUsers, +// then Action is applied. func (v SSHRuleView) Principals() views.SliceView[*SSHPrincipal, SSHPrincipalView] { return views.SliceOfViews[*SSHPrincipal, SSHPrincipalView](v.ж.Principals) } +// SSHUsers are the SSH users that this rule matches. It is a +// map from either ssh-user|"*" => local-user. The map must +// contain a key for either ssh-user or, as a fallback, "*" to +// match anything. If it does, the map entry's value is the +// actual user that's logged in. +// If the map value is the empty string (for either the +// requested SSH user or "*"), the rule doesn't match. +// If the map value is "=", it means the ssh-user should map +// directly to the local-user. +// It may be nil if the Action is reject. func (v SSHRuleView) SSHUsers() views.Map[string, string] { return views.MapOf(v.ж.SSHUsers) } -func (v SSHRuleView) Action() SSHActionView { return v.ж.Action.View() } -func (v SSHRuleView) AcceptEnv() views.Slice[string] { return views.SliceOf(v.ж.AcceptEnv) } + +// Action is the outcome to task. +// A nil or invalid action means to deny. +func (v SSHRuleView) Action() SSHActionView { return v.ж.Action.View() } + +// AcceptEnv is a slice of environment variable names that are allowlisted +// for the SSH rule in the policy file. +// +// AcceptEnv values may contain * and ? wildcard characters which match against +// an arbitrary number of characters or a single character respectively. +func (v SSHRuleView) AcceptEnv() views.Slice[string] { return views.SliceOf(v.ж.AcceptEnv) } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _SSHRuleViewNeedsRegeneration = SSHRule(struct { @@ -1132,8 +2036,17 @@ func (v SSHActionView) AsStruct() *SSHAction { return v.ж.Clone() } -func (v SSHActionView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v SSHActionView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v SSHActionView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *SSHActionView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1142,22 +2055,81 @@ func (v *SSHActionView) UnmarshalJSON(b []byte) error { return nil } var x SSHAction - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v SSHActionView) Message() string { return v.ж.Message } -func (v SSHActionView) Reject() bool { return v.ж.Reject } -func (v SSHActionView) Accept() bool { return v.ж.Accept } -func (v SSHActionView) SessionDuration() time.Duration { return v.ж.SessionDuration } -func (v SSHActionView) AllowAgentForwarding() bool { return v.ж.AllowAgentForwarding } -func (v SSHActionView) HoldAndDelegate() string { return v.ж.HoldAndDelegate } -func (v SSHActionView) AllowLocalPortForwarding() bool { return v.ж.AllowLocalPortForwarding } -func (v SSHActionView) AllowRemotePortForwarding() bool { return v.ж.AllowRemotePortForwarding } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *SSHActionView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x SSHAction + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Message, if non-empty, is shown to the user before the +// action occurs. +func (v SSHActionView) Message() string { return v.ж.Message } + +// Reject, if true, terminates the connection. This action +// has higher priority that Accept, if given. +// The reason this is exists is primarily so a response +// from HoldAndDelegate has a way to stop the poll. +func (v SSHActionView) Reject() bool { return v.ж.Reject } + +// Accept, if true, accepts the connection immediately +// without further prompts. +func (v SSHActionView) Accept() bool { return v.ж.Accept } + +// SessionDuration, if non-zero, is how long the session can stay open +// before being forcefully terminated. +func (v SSHActionView) SessionDuration() time.Duration { return v.ж.SessionDuration } + +// AllowAgentForwarding, if true, allows accepted connections to forward +// the ssh agent if requested. +func (v SSHActionView) AllowAgentForwarding() bool { return v.ж.AllowAgentForwarding } + +// HoldAndDelegate, if non-empty, is a URL that serves an +// outcome verdict. The connection will be accepted and will +// block until the provided long-polling URL serves a new +// SSHAction JSON value. The URL must be fetched using the +// Noise transport (in package control/control{base,http}). +// If the long poll breaks before returning a complete HTTP +// response, it should be re-fetched as long as the SSH +// session is open. +// +// The following variables in the URL are expanded by tailscaled: +// +// - $SRC_NODE_IP (URL escaped) +// - $SRC_NODE_ID (Node.ID as int64 string) +// - $DST_NODE_IP (URL escaped) +// - $DST_NODE_ID (Node.ID as int64 string) +// - $SSH_USER (URL escaped, ssh user requested) +// - $LOCAL_USER (URL escaped, local user mapped) +func (v SSHActionView) HoldAndDelegate() string { return v.ж.HoldAndDelegate } + +// AllowLocalPortForwarding, if true, allows accepted connections +// to use local port forwarding if requested. +func (v SSHActionView) AllowLocalPortForwarding() bool { return v.ж.AllowLocalPortForwarding } + +// AllowRemotePortForwarding, if true, allows accepted connections +// to use remote port forwarding if requested. +func (v SSHActionView) AllowRemotePortForwarding() bool { return v.ж.AllowRemotePortForwarding } + +// Recorders defines the destinations of the SSH session recorders. +// The recording will be uploaded to http://addr:port/record. func (v SSHActionView) Recorders() views.Slice[netip.AddrPort] { return views.SliceOf(v.ж.Recorders) } + +// OnRecorderFailure is the action to take if recording fails. +// If nil, the default action is to fail open. func (v SSHActionView) OnRecordingFailure() views.ValuePointer[SSHRecorderFailureAction] { return views.ValuePointerOf(v.ж.OnRecordingFailure) } @@ -1204,8 +2176,17 @@ func (v SSHPrincipalView) AsStruct() *SSHPrincipal { return v.ж.Clone() } -func (v SSHPrincipalView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v SSHPrincipalView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v SSHPrincipalView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1214,7 +2195,20 @@ func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error { return nil } var x SSHPrincipal - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *SSHPrincipalView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x SSHPrincipal + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { return err } v.ж = &x @@ -1223,8 +2217,19 @@ func (v *SSHPrincipalView) UnmarshalJSON(b []byte) error { func (v SSHPrincipalView) Node() StableNodeID { return v.ж.Node } func (v SSHPrincipalView) NodeIP() string { return v.ж.NodeIP } -func (v SSHPrincipalView) UserLogin() string { return v.ж.UserLogin } -func (v SSHPrincipalView) Any() bool { return v.ж.Any } + +// email-ish: foo@example.com, bar@github +func (v SSHPrincipalView) UserLogin() string { return v.ж.UserLogin } + +// if true, match any connection +func (v SSHPrincipalView) Any() bool { return v.ж.Any } + +// UnusedPubKeys was public key support. It never became an official product +// feature and so as of 2024-12-12 is being removed. +// This stub exists to remind us not to re-use the JSON field name "pubKeys" +// in the future if we bring it back with different semantics. +// +// Deprecated: do not use. It does nothing. func (v SSHPrincipalView) UnusedPubKeys() views.Slice[string] { return views.SliceOf(v.ж.UnusedPubKeys) } @@ -1266,8 +2271,17 @@ func (v ControlDialPlanView) AsStruct() *ControlDialPlan { return v.ж.Clone() } -func (v ControlDialPlanView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ControlDialPlanView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ControlDialPlanView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *ControlDialPlanView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1276,13 +2290,27 @@ func (v *ControlDialPlanView) UnmarshalJSON(b []byte) error { return nil } var x ControlDialPlan - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ControlDialPlanView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x ControlDialPlan + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// An empty list means the default: use DNS (unspecified which DNS). func (v ControlDialPlanView) Candidates() views.Slice[ControlIPCandidate] { return views.SliceOf(v.ж.Candidates) } @@ -1320,8 +2348,17 @@ func (v LocationView) AsStruct() *Location { return v.ж.Clone() } -func (v LocationView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v LocationView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v LocationView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *LocationView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1330,20 +2367,55 @@ func (v *LocationView) UnmarshalJSON(b []byte) error { return nil } var x Location - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v LocationView) Country() string { return v.ж.Country } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *LocationView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Location + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// User friendly country name, with proper capitalization ("Canada") +func (v LocationView) Country() string { return v.ж.Country } + +// ISO 3166-1 alpha-2 in upper case ("CA") func (v LocationView) CountryCode() string { return v.ж.CountryCode } -func (v LocationView) City() string { return v.ж.City } -func (v LocationView) CityCode() string { return v.ж.CityCode } -func (v LocationView) Latitude() float64 { return v.ж.Latitude } -func (v LocationView) Longitude() float64 { return v.ж.Longitude } -func (v LocationView) Priority() int { return v.ж.Priority } + +// User friendly city name, with proper capitalization ("Squamish") +func (v LocationView) City() string { return v.ж.City } + +// CityCode is a short code representing the city in upper case. +// CityCode is used to disambiguate a city from another location +// with the same city name. It uniquely identifies a particular +// geographical location, within the tailnet. +// IATA, ICAO or ISO 3166-2 codes are recommended ("YSE") +func (v LocationView) CityCode() string { return v.ж.CityCode } + +// Latitude, Longitude are optional geographical coordinates of the node, in degrees. +// No particular accuracy level is promised; the coordinates may simply be the center of the city or country. +func (v LocationView) Latitude() float64 { return v.ж.Latitude } +func (v LocationView) Longitude() float64 { return v.ж.Longitude } + +// Priority determines the order of use of an exit node when a +// location based preference matches more than one exit node, +// the node with the highest priority wins. Nodes of equal +// probability may be selected arbitrarily. +// +// A value of 0 means the exit node does not have a priority +// preference. A negative int is not allowed. +func (v LocationView) Priority() int { return v.ж.Priority } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _LocationViewNeedsRegeneration = Location(struct { @@ -1384,8 +2456,17 @@ func (v UserProfileView) AsStruct() *UserProfile { return v.ж.Clone() } -func (v UserProfileView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v UserProfileView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v UserProfileView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *UserProfileView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -1394,15 +2475,32 @@ func (v *UserProfileView) UnmarshalJSON(b []byte) error { return nil } var x UserProfile - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v UserProfileView) ID() UserID { return v.ж.ID } -func (v UserProfileView) LoginName() string { return v.ж.LoginName } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *UserProfileView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x UserProfile + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v UserProfileView) ID() UserID { return v.ж.ID } + +// "alice@smith.com"; for display purposes only (provider is not listed) +func (v UserProfileView) LoginName() string { return v.ж.LoginName } + +// "Alice Smith" func (v UserProfileView) DisplayName() string { return v.ж.DisplayName } func (v UserProfileView) ProfilePicURL() string { return v.ж.ProfilePicURL } func (v UserProfileView) Equal(v2 UserProfileView) bool { return v.ж.Equal(v2.ж) } @@ -1414,3 +2512,181 @@ var _UserProfileViewNeedsRegeneration = UserProfile(struct { DisplayName string ProfilePicURL string }{}) + +// View returns a read-only view of VIPService. +func (p *VIPService) View() VIPServiceView { + return VIPServiceView{ж: p} +} + +// VIPServiceView provides a read-only view over VIPService. +// +// Its methods should only be called if `Valid()` returns true. +type VIPServiceView struct { + // ж is the underlying mutable value, named with a hard-to-type + // character that looks pointy like a pointer. + // It is named distinctively to make you think of how dangerous it is to escape + // to callers. You must not let callers be able to mutate it. + ж *VIPService +} + +// Valid reports whether v's underlying value is non-nil. +func (v VIPServiceView) Valid() bool { return v.ж != nil } + +// AsStruct returns a clone of the underlying value which aliases no memory with +// the original. +func (v VIPServiceView) AsStruct() *VIPService { + if v.ж == nil { + return nil + } + return v.ж.Clone() +} + +// MarshalJSON implements [jsonv1.Marshaler]. +func (v VIPServiceView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} + +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v VIPServiceView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +func (v *VIPServiceView) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } + if len(b) == 0 { + return nil + } + var x VIPService + if err := jsonv1.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *VIPServiceView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x VIPService + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Name is the name of the service. The Name uniquely identifies a service +// on a particular tailnet, and so also corresponds uniquely to the pair of +// IP addresses belonging to the VIP service. +func (v VIPServiceView) Name() ServiceName { return v.ж.Name } + +// Ports specify which ProtoPorts are made available by this node +// on the service's IPs. +func (v VIPServiceView) Ports() views.Slice[ProtoPortRange] { return views.SliceOf(v.ж.Ports) } + +// Active specifies whether new requests for the service should be +// sent to this node by control. +func (v VIPServiceView) Active() bool { return v.ж.Active } + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _VIPServiceViewNeedsRegeneration = VIPService(struct { + Name ServiceName + Ports []ProtoPortRange + Active bool +}{}) + +// View returns a read-only view of SSHPolicy. +func (p *SSHPolicy) View() SSHPolicyView { + return SSHPolicyView{ж: p} +} + +// SSHPolicyView provides a read-only view over SSHPolicy. +// +// Its methods should only be called if `Valid()` returns true. +type SSHPolicyView struct { + // ж is the underlying mutable value, named with a hard-to-type + // character that looks pointy like a pointer. + // It is named distinctively to make you think of how dangerous it is to escape + // to callers. You must not let callers be able to mutate it. + ж *SSHPolicy +} + +// Valid reports whether v's underlying value is non-nil. +func (v SSHPolicyView) Valid() bool { return v.ж != nil } + +// AsStruct returns a clone of the underlying value which aliases no memory with +// the original. +func (v SSHPolicyView) AsStruct() *SSHPolicy { + if v.ж == nil { + return nil + } + return v.ж.Clone() +} + +// MarshalJSON implements [jsonv1.Marshaler]. +func (v SSHPolicyView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} + +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v SSHPolicyView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +func (v *SSHPolicyView) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } + if len(b) == 0 { + return nil + } + var x SSHPolicy + if err := jsonv1.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *SSHPolicyView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x SSHPolicy + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Rules are the rules to process for an incoming SSH connection. The first +// matching rule takes its action and stops processing further rules. +// +// When an incoming connection first starts, all rules are evaluated in +// "none" auth mode, where the client hasn't even been asked to send a +// public key. All SSHRule.Principals requiring a public key won't match. If +// a rule matches on the first pass and its Action is reject, the +// authentication fails with that action's rejection message, if any. +// +// If the first pass rule evaluation matches nothing without matching an +// Action with Reject set, the rules are considered to see whether public +// keys might still result in a match. If not, "none" auth is terminated +// before proceeding to public key mode. If so, the client is asked to try +// public key authentication and the rules are evaluated again for each of +// the client's present keys. +func (v SSHPolicyView) Rules() views.SliceView[*SSHRule, SSHRuleView] { + return views.SliceOfViews[*SSHRule, SSHRuleView](v.ж.Rules) +} + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _SSHPolicyViewNeedsRegeneration = SSHPolicy(struct { + Rules []*SSHRule +}{}) diff --git a/vendor/tailscale.com/taildrop/delete.go b/vendor/tailscale.com/taildrop/delete.go deleted file mode 100644 index aaef34d..0000000 --- a/vendor/tailscale.com/taildrop/delete.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package taildrop - -import ( - "container/list" - "context" - "io/fs" - "os" - "path/filepath" - "strings" - "sync" - "time" - - "tailscale.com/ipn" - "tailscale.com/syncs" - "tailscale.com/tstime" - "tailscale.com/types/logger" -) - -// deleteDelay is the amount of time to wait before we delete a file. -// A shorter value ensures timely deletion of deleted and partial files, while -// a longer value provides more opportunity for partial files to be resumed. -const deleteDelay = time.Hour - -// fileDeleter manages asynchronous deletion of files after deleteDelay. -type fileDeleter struct { - logf logger.Logf - clock tstime.DefaultClock - dir string - event func(string) // called for certain events; for testing only - - mu sync.Mutex - queue list.List - byName map[string]*list.Element - - emptySignal chan struct{} // signal that the queue is empty - group syncs.WaitGroup - shutdownCtx context.Context - shutdown context.CancelFunc -} - -// deleteFile is a specific file to delete after deleteDelay. -type deleteFile struct { - name string - inserted time.Time -} - -func (d *fileDeleter) Init(m *Manager, eventHook func(string)) { - d.logf = m.opts.Logf - d.clock = m.opts.Clock - d.dir = m.opts.Dir - d.event = eventHook - - d.byName = make(map[string]*list.Element) - d.emptySignal = make(chan struct{}) - d.shutdownCtx, d.shutdown = context.WithCancel(context.Background()) - - // From a cold-start, load the list of partial and deleted files. - // - // Only run this if we have ever received at least one file - // to avoid ever touching the taildrop directory on systems (e.g., MacOS) - // that pop up a security dialog window upon first access. - if m.opts.State == nil { - return - } - if b, _ := m.opts.State.ReadState(ipn.TaildropReceivedKey); len(b) == 0 { - return - } - d.group.Go(func() { - d.event("start full-scan") - defer d.event("end full-scan") - rangeDir(d.dir, func(de fs.DirEntry) bool { - switch { - case d.shutdownCtx.Err() != nil: - return false // terminate early - case !de.Type().IsRegular(): - return true - case strings.HasSuffix(de.Name(), partialSuffix): - // Only enqueue the file for deletion if there is no active put. - nameID := strings.TrimSuffix(de.Name(), partialSuffix) - if i := strings.LastIndexByte(nameID, '.'); i > 0 { - key := incomingFileKey{ClientID(nameID[i+len("."):]), nameID[:i]} - m.incomingFiles.LoadFunc(key, func(_ *incomingFile, loaded bool) { - if !loaded { - d.Insert(de.Name()) - } - }) - } else { - d.Insert(de.Name()) - } - case strings.HasSuffix(de.Name(), deletedSuffix): - // Best-effort immediate deletion of deleted files. - name := strings.TrimSuffix(de.Name(), deletedSuffix) - if os.Remove(filepath.Join(d.dir, name)) == nil { - if os.Remove(filepath.Join(d.dir, de.Name())) == nil { - break - } - } - // Otherwise, enqueue the file for later deletion. - d.Insert(de.Name()) - } - return true - }) - }) -} - -// Insert enqueues baseName for eventual deletion. -func (d *fileDeleter) Insert(baseName string) { - d.mu.Lock() - defer d.mu.Unlock() - if d.shutdownCtx.Err() != nil { - return - } - if _, ok := d.byName[baseName]; ok { - return // already queued for deletion - } - d.byName[baseName] = d.queue.PushBack(&deleteFile{baseName, d.clock.Now()}) - if d.queue.Len() == 1 && d.shutdownCtx.Err() == nil { - d.group.Go(func() { d.waitAndDelete(deleteDelay) }) - } -} - -// waitAndDelete is an asynchronous deletion goroutine. -// At most one waitAndDelete routine is ever running at a time. -// It is not started unless there is at least one file in the queue. -func (d *fileDeleter) waitAndDelete(wait time.Duration) { - tc, ch := d.clock.NewTimer(wait) - defer tc.Stop() // cleanup the timer resource if we stop early - d.event("start waitAndDelete") - defer d.event("end waitAndDelete") - select { - case <-d.shutdownCtx.Done(): - case <-d.emptySignal: - case now := <-ch: - d.mu.Lock() - defer d.mu.Unlock() - - // Iterate over all files to delete, and delete anything old enough. - var next *list.Element - var failed []*list.Element - for elem := d.queue.Front(); elem != nil; elem = next { - next = elem.Next() - file := elem.Value.(*deleteFile) - if now.Sub(file.inserted) < deleteDelay { - break // everything after this is recently inserted - } - - // Delete the expired file. - if name, ok := strings.CutSuffix(file.name, deletedSuffix); ok { - if err := os.Remove(filepath.Join(d.dir, name)); err != nil && !os.IsNotExist(err) { - d.logf("could not delete: %v", redactError(err)) - failed = append(failed, elem) - continue - } - } - if err := os.Remove(filepath.Join(d.dir, file.name)); err != nil && !os.IsNotExist(err) { - d.logf("could not delete: %v", redactError(err)) - failed = append(failed, elem) - continue - } - d.queue.Remove(elem) - delete(d.byName, file.name) - d.event("deleted " + file.name) - } - for _, elem := range failed { - elem.Value.(*deleteFile).inserted = now // retry after deleteDelay - d.queue.MoveToBack(elem) - } - - // If there are still some files to delete, retry again later. - if d.queue.Len() > 0 && d.shutdownCtx.Err() == nil { - file := d.queue.Front().Value.(*deleteFile) - retryAfter := deleteDelay - now.Sub(file.inserted) - d.group.Go(func() { d.waitAndDelete(retryAfter) }) - } - } -} - -// Remove dequeues baseName from eventual deletion. -func (d *fileDeleter) Remove(baseName string) { - d.mu.Lock() - defer d.mu.Unlock() - if elem := d.byName[baseName]; elem != nil { - d.queue.Remove(elem) - delete(d.byName, baseName) - // Signal to terminate any waitAndDelete goroutines. - if d.queue.Len() == 0 { - select { - case <-d.shutdownCtx.Done(): - case d.emptySignal <- struct{}{}: - } - } - } -} - -// Shutdown shuts down the deleter. -// It blocks until all goroutines are stopped. -func (d *fileDeleter) Shutdown() { - d.mu.Lock() // acquire lock to ensure no new goroutines start after shutdown - d.shutdown() - d.mu.Unlock() - d.group.Wait() -} diff --git a/vendor/tailscale.com/taildrop/resume.go b/vendor/tailscale.com/taildrop/resume.go deleted file mode 100644 index f7bee3d..0000000 --- a/vendor/tailscale.com/taildrop/resume.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package taildrop - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "io/fs" - "os" - "strings" -) - -var ( - blockSize = int64(64 << 10) - hashAlgorithm = "sha256" -) - -// BlockChecksum represents the checksum for a single block. -type BlockChecksum struct { - Checksum Checksum `json:"checksum"` - Algorithm string `json:"algo"` // always "sha256" for now - Size int64 `json:"size"` // always (64<<10) for now -} - -// Checksum is an opaque checksum that is comparable. -type Checksum struct{ cs [sha256.Size]byte } - -func hash(b []byte) Checksum { - return Checksum{sha256.Sum256(b)} -} -func (cs Checksum) String() string { - return hex.EncodeToString(cs.cs[:]) -} -func (cs Checksum) AppendText(b []byte) ([]byte, error) { - return hex.AppendEncode(b, cs.cs[:]), nil -} -func (cs Checksum) MarshalText() ([]byte, error) { - return hex.AppendEncode(nil, cs.cs[:]), nil -} -func (cs *Checksum) UnmarshalText(b []byte) error { - if len(b) != 2*len(cs.cs) { - return fmt.Errorf("invalid hex length: %d", len(b)) - } - _, err := hex.Decode(cs.cs[:], b) - return err -} - -// PartialFiles returns a list of partial files in [Handler.Dir] -// that were sent (or is actively being sent) by the provided id. -func (m *Manager) PartialFiles(id ClientID) (ret []string, err error) { - if m == nil || m.opts.Dir == "" { - return nil, ErrNoTaildrop - } - - suffix := id.partialSuffix() - if err := rangeDir(m.opts.Dir, func(de fs.DirEntry) bool { - if name := de.Name(); strings.HasSuffix(name, suffix) { - ret = append(ret, name) - } - return true - }); err != nil { - return ret, redactError(err) - } - return ret, nil -} - -// HashPartialFile returns a function that hashes the next block in the file, -// starting from the beginning of the file. -// It returns (BlockChecksum{}, io.EOF) when the stream is complete. -// It is the caller's responsibility to call close. -func (m *Manager) HashPartialFile(id ClientID, baseName string) (next func() (BlockChecksum, error), close func() error, err error) { - if m == nil || m.opts.Dir == "" { - return nil, nil, ErrNoTaildrop - } - noopNext := func() (BlockChecksum, error) { return BlockChecksum{}, io.EOF } - noopClose := func() error { return nil } - - dstFile, err := joinDir(m.opts.Dir, baseName) - if err != nil { - return nil, nil, err - } - f, err := os.Open(dstFile + id.partialSuffix()) - if err != nil { - if os.IsNotExist(err) { - return noopNext, noopClose, nil - } - return nil, nil, redactError(err) - } - - b := make([]byte, blockSize) // TODO: Pool this? - next = func() (BlockChecksum, error) { - switch n, err := io.ReadFull(f, b); { - case err != nil && err != io.EOF && err != io.ErrUnexpectedEOF: - return BlockChecksum{}, redactError(err) - case n == 0: - return BlockChecksum{}, io.EOF - default: - return BlockChecksum{hash(b[:n]), hashAlgorithm, int64(n)}, nil - } - } - close = f.Close - return next, close, nil -} - -// ResumeReader reads and discards the leading content of r -// that matches the content based on the checksums that exist. -// It returns the number of bytes consumed, -// and returns an [io.Reader] representing the remaining content. -func ResumeReader(r io.Reader, hashNext func() (BlockChecksum, error)) (int64, io.Reader, error) { - if hashNext == nil { - return 0, r, nil - } - - var offset int64 - b := make([]byte, 0, blockSize) - for { - // Obtain the next block checksum from the remote peer. - cs, err := hashNext() - switch { - case err == io.EOF: - return offset, io.MultiReader(bytes.NewReader(b), r), nil - case err != nil: - return offset, io.MultiReader(bytes.NewReader(b), r), err - case cs.Algorithm != hashAlgorithm || cs.Size < 0 || cs.Size > blockSize: - return offset, io.MultiReader(bytes.NewReader(b), r), fmt.Errorf("invalid block size or hashing algorithm") - } - - // Read the contents of the next block. - n, err := io.ReadFull(r, b[:cs.Size]) - b = b[:n] - if err == io.EOF || err == io.ErrUnexpectedEOF { - err = nil - } - if len(b) == 0 || err != nil { - // This should not occur in practice. - // It implies that an error occurred reading r, - // or that the partial file on the remote side is fully complete. - return offset, io.MultiReader(bytes.NewReader(b), r), err - } - - // Compare the local and remote block checksums. - // If it mismatches, then resume from this point. - if cs.Checksum != hash(b) { - return offset, io.MultiReader(bytes.NewReader(b), r), nil - } - offset += int64(len(b)) - b = b[:0] - } -} diff --git a/vendor/tailscale.com/taildrop/retrieve.go b/vendor/tailscale.com/taildrop/retrieve.go deleted file mode 100644 index 3e37b49..0000000 --- a/vendor/tailscale.com/taildrop/retrieve.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package taildrop - -import ( - "context" - "errors" - "io" - "io/fs" - "os" - "path/filepath" - "runtime" - "sort" - "time" - - "tailscale.com/client/tailscale/apitype" - "tailscale.com/logtail/backoff" -) - -// HasFilesWaiting reports whether any files are buffered in [Handler.Dir]. -// This always returns false when [Handler.DirectFileMode] is false. -func (m *Manager) HasFilesWaiting() (has bool) { - if m == nil || m.opts.Dir == "" || m.opts.DirectFileMode { - return false - } - - // Optimization: this is usually empty, so avoid opening - // the directory and checking. We can't cache the actual - // has-files-or-not values as the macOS/iOS client might - // in the future use+delete the files directly. So only - // keep this negative cache. - totalReceived := m.totalReceived.Load() - if totalReceived == m.emptySince.Load() { - return false - } - - // Check whether there is at least one one waiting file. - err := rangeDir(m.opts.Dir, func(de fs.DirEntry) bool { - name := de.Name() - if isPartialOrDeleted(name) || !de.Type().IsRegular() { - return true - } - _, err := os.Stat(filepath.Join(m.opts.Dir, name+deletedSuffix)) - if os.IsNotExist(err) { - has = true - return false - } - return true - }) - - // If there are no more waiting files, record totalReceived as emptySince - // so that we can short-circuit the expensive directory traversal - // if no files have been received after the start of this call. - if err == nil && !has { - m.emptySince.Store(totalReceived) - } - return has -} - -// WaitingFiles returns the list of files that have been sent by a -// peer that are waiting in [Handler.Dir]. -// This always returns nil when [Handler.DirectFileMode] is false. -func (m *Manager) WaitingFiles() (ret []apitype.WaitingFile, err error) { - if m == nil || m.opts.Dir == "" { - return nil, ErrNoTaildrop - } - if m.opts.DirectFileMode { - return nil, nil - } - if err := rangeDir(m.opts.Dir, func(de fs.DirEntry) bool { - name := de.Name() - if isPartialOrDeleted(name) || !de.Type().IsRegular() { - return true - } - _, err := os.Stat(filepath.Join(m.opts.Dir, name+deletedSuffix)) - if os.IsNotExist(err) { - fi, err := de.Info() - if err != nil { - return true - } - ret = append(ret, apitype.WaitingFile{ - Name: filepath.Base(name), - Size: fi.Size(), - }) - } - return true - }); err != nil { - return nil, redactError(err) - } - sort.Slice(ret, func(i, j int) bool { return ret[i].Name < ret[j].Name }) - return ret, nil -} - -// DeleteFile deletes a file of the given baseName from [Handler.Dir]. -// This method is only allowed when [Handler.DirectFileMode] is false. -func (m *Manager) DeleteFile(baseName string) error { - if m == nil || m.opts.Dir == "" { - return ErrNoTaildrop - } - if m.opts.DirectFileMode { - return errors.New("deletes not allowed in direct mode") - } - path, err := joinDir(m.opts.Dir, baseName) - if err != nil { - return err - } - var bo *backoff.Backoff - logf := m.opts.Logf - t0 := m.opts.Clock.Now() - for { - err := os.Remove(path) - if err != nil && !os.IsNotExist(err) { - err = redactError(err) - // Put a retry loop around deletes on Windows. - // - // Windows file descriptor closes are effectively asynchronous, - // as a bunch of hooks run on/after close, - // and we can't necessarily delete the file for a while after close, - // as we need to wait for everybody to be done with it. - // On Windows, unlike Unix, a file can't be deleted if it's open anywhere. - // So try a few times but ultimately just leave a "foo.jpg.deleted" - // marker file to note that it's deleted and we clean it up later. - if runtime.GOOS == "windows" { - if bo == nil { - bo = backoff.NewBackoff("delete-retry", logf, 1*time.Second) - } - if m.opts.Clock.Since(t0) < 5*time.Second { - bo.BackOff(context.Background(), err) - continue - } - if err := touchFile(path + deletedSuffix); err != nil { - logf("peerapi: failed to leave deleted marker: %v", err) - } - m.deleter.Insert(baseName + deletedSuffix) - } - logf("peerapi: failed to DeleteFile: %v", err) - return err - } - return nil - } -} - -func touchFile(path string) error { - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0666) - if err != nil { - return redactError(err) - } - return f.Close() -} - -// OpenFile opens a file of the given baseName from [Handler.Dir]. -// This method is only allowed when [Handler.DirectFileMode] is false. -func (m *Manager) OpenFile(baseName string) (rc io.ReadCloser, size int64, err error) { - if m == nil || m.opts.Dir == "" { - return nil, 0, ErrNoTaildrop - } - if m.opts.DirectFileMode { - return nil, 0, errors.New("opens not allowed in direct mode") - } - path, err := joinDir(m.opts.Dir, baseName) - if err != nil { - return nil, 0, err - } - if _, err := os.Stat(path + deletedSuffix); err == nil { - return nil, 0, redactError(&fs.PathError{Op: "open", Path: path, Err: fs.ErrNotExist}) - } - f, err := os.Open(path) - if err != nil { - return nil, 0, redactError(err) - } - fi, err := f.Stat() - if err != nil { - f.Close() - return nil, 0, redactError(err) - } - return f, fi.Size(), nil -} diff --git a/vendor/tailscale.com/taildrop/send.go b/vendor/tailscale.com/taildrop/send.go deleted file mode 100644 index 0dff71b..0000000 --- a/vendor/tailscale.com/taildrop/send.go +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package taildrop - -import ( - "crypto/sha256" - "errors" - "io" - "os" - "path/filepath" - "sync" - "time" - - "tailscale.com/envknob" - "tailscale.com/ipn" - "tailscale.com/tstime" - "tailscale.com/version/distro" -) - -type incomingFileKey struct { - id ClientID - name string // e.g., "foo.jpeg" -} - -type incomingFile struct { - clock tstime.DefaultClock - - started time.Time - size int64 // or -1 if unknown; never 0 - w io.Writer // underlying writer - sendFileNotify func() // called when done - partialPath string // non-empty in direct mode - finalPath string // not used in direct mode - - mu sync.Mutex - copied int64 - done bool - lastNotify time.Time -} - -func (f *incomingFile) Write(p []byte) (n int, err error) { - n, err = f.w.Write(p) - - var needNotify bool - defer func() { - if needNotify { - f.sendFileNotify() - } - }() - if n > 0 { - f.mu.Lock() - defer f.mu.Unlock() - f.copied += int64(n) - now := f.clock.Now() - if f.lastNotify.IsZero() || now.Sub(f.lastNotify) > time.Second { - f.lastNotify = now - needNotify = true - } - } - return n, err -} - -// PutFile stores a file into [Manager.Dir] from a given client id. -// The baseName must be a base filename without any slashes. -// The length is the expected length of content to read from r, -// it may be negative to indicate that it is unknown. -// It returns the length of the entire file. -// -// If there is a failure reading from r, then the partial file is not deleted -// for some period of time. The [Manager.PartialFiles] and [Manager.HashPartialFile] -// methods may be used to list all partial files and to compute the hash for a -// specific partial file. This allows the client to determine whether to resume -// a partial file. While resuming, PutFile may be called again with a non-zero -// offset to specify where to resume receiving data at. -func (m *Manager) PutFile(id ClientID, baseName string, r io.Reader, offset, length int64) (int64, error) { - switch { - case m == nil || m.opts.Dir == "": - return 0, ErrNoTaildrop - case !envknob.CanTaildrop(): - return 0, ErrNoTaildrop - case distro.Get() == distro.Unraid && !m.opts.DirectFileMode: - return 0, ErrNotAccessible - } - dstPath, err := joinDir(m.opts.Dir, baseName) - if err != nil { - return 0, err - } - - redactAndLogError := func(action string, err error) error { - err = redactError(err) - m.opts.Logf("put %v error: %v", action, err) - return err - } - - // Check whether there is an in-progress transfer for the file. - partialPath := dstPath + id.partialSuffix() - inFileKey := incomingFileKey{id, baseName} - inFile, loaded := m.incomingFiles.LoadOrInit(inFileKey, func() *incomingFile { - inFile := &incomingFile{ - clock: m.opts.Clock, - started: m.opts.Clock.Now(), - size: length, - sendFileNotify: m.opts.SendFileNotify, - } - if m.opts.DirectFileMode { - inFile.partialPath = partialPath - inFile.finalPath = dstPath - } - return inFile - }) - if loaded { - return 0, ErrFileExists - } - defer m.incomingFiles.Delete(inFileKey) - m.deleter.Remove(filepath.Base(partialPath)) // avoid deleting the partial file while receiving - - // Create (if not already) the partial file with read-write permissions. - f, err := os.OpenFile(partialPath, os.O_CREATE|os.O_RDWR, 0666) - if err != nil { - return 0, redactAndLogError("Create", err) - } - defer func() { - f.Close() // best-effort to cleanup dangling file handles - if err != nil { - m.deleter.Insert(filepath.Base(partialPath)) // mark partial file for eventual deletion - } - }() - inFile.w = f - - // Record that we have started to receive at least one file. - // This is used by the deleter upon a cold-start to scan the directory - // for any files that need to be deleted. - if m.opts.State != nil { - if b, _ := m.opts.State.ReadState(ipn.TaildropReceivedKey); len(b) == 0 { - if err := m.opts.State.WriteState(ipn.TaildropReceivedKey, []byte{1}); err != nil { - m.opts.Logf("WriteState error: %v", err) // non-fatal error - } - } - } - - // A positive offset implies that we are resuming an existing file. - // Seek to the appropriate offset and truncate the file. - if offset != 0 { - currLength, err := f.Seek(0, io.SeekEnd) - if err != nil { - return 0, redactAndLogError("Seek", err) - } - if offset < 0 || offset > currLength { - return 0, redactAndLogError("Seek", err) - } - if _, err := f.Seek(offset, io.SeekStart); err != nil { - return 0, redactAndLogError("Seek", err) - } - if err := f.Truncate(offset); err != nil { - return 0, redactAndLogError("Truncate", err) - } - } - - // Copy the contents of the file. - copyLength, err := io.Copy(inFile, r) - if err != nil { - return 0, redactAndLogError("Copy", err) - } - if length >= 0 && copyLength != length { - return 0, redactAndLogError("Copy", errors.New("copied an unexpected number of bytes")) - } - if err := f.Close(); err != nil { - return 0, redactAndLogError("Close", err) - } - fileLength := offset + copyLength - - inFile.mu.Lock() - inFile.done = true - inFile.mu.Unlock() - - // File has been successfully received, rename the partial file - // to the final destination filename. If a file of that name already exists, - // then try multiple times with variations of the filename. - computePartialSum := sync.OnceValues(func() ([sha256.Size]byte, error) { - return sha256File(partialPath) - }) - maxRetries := 10 - for ; maxRetries > 0; maxRetries-- { - // Atomically rename the partial file as the destination file if it doesn't exist. - // Otherwise, it returns the length of the current destination file. - // The operation is atomic. - dstLength, err := func() (int64, error) { - m.renameMu.Lock() - defer m.renameMu.Unlock() - switch fi, err := os.Stat(dstPath); { - case os.IsNotExist(err): - return -1, os.Rename(partialPath, dstPath) - case err != nil: - return -1, err - default: - return fi.Size(), nil - } - }() - if err != nil { - return 0, redactAndLogError("Rename", err) - } - if dstLength < 0 { - break // we successfully renamed; so stop - } - - // Avoid the final rename if a destination file has the same contents. - // - // Note: this is best effort and copying files from iOS from the Media Library - // results in processing on the iOS side which means the size and shas of the - // same file can be different. - if dstLength == fileLength { - partialSum, err := computePartialSum() - if err != nil { - return 0, redactAndLogError("Rename", err) - } - dstSum, err := sha256File(dstPath) - if err != nil { - return 0, redactAndLogError("Rename", err) - } - if dstSum == partialSum { - if err := os.Remove(partialPath); err != nil { - return 0, redactAndLogError("Remove", err) - } - break // we successfully found a content match; so stop - } - } - - // Choose a new destination filename and try again. - dstPath = NextFilename(dstPath) - inFile.finalPath = dstPath - } - if maxRetries <= 0 { - return 0, errors.New("too many retries trying to rename partial file") - } - m.totalReceived.Add(1) - m.opts.SendFileNotify() - return fileLength, nil -} - -func sha256File(file string) (out [sha256.Size]byte, err error) { - h := sha256.New() - f, err := os.Open(file) - if err != nil { - return out, err - } - defer f.Close() - if _, err := io.Copy(h, f); err != nil { - return out, err - } - return [sha256.Size]byte(h.Sum(nil)), nil -} diff --git a/vendor/tailscale.com/taildrop/taildrop.go b/vendor/tailscale.com/taildrop/taildrop.go deleted file mode 100644 index 4d14787..0000000 --- a/vendor/tailscale.com/taildrop/taildrop.go +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package taildrop contains the implementation of the Taildrop -// functionality including sending and retrieving files. -// This package does not validate permissions, the caller should -// be responsible for ensuring correct authorization. -// -// For related documentation see: http://go/taildrop-how-does-it-work -package taildrop - -import ( - "errors" - "hash/adler32" - "io" - "io/fs" - "os" - "path" - "path/filepath" - "regexp" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode" - "unicode/utf8" - - "tailscale.com/ipn" - "tailscale.com/syncs" - "tailscale.com/tstime" - "tailscale.com/types/logger" - "tailscale.com/util/multierr" -) - -var ( - ErrNoTaildrop = errors.New("Taildrop disabled; no storage directory") - ErrInvalidFileName = errors.New("invalid filename") - ErrFileExists = errors.New("file already exists") - ErrNotAccessible = errors.New("Taildrop folder not configured or accessible") -) - -const ( - // partialSuffix is the suffix appended to files while they're - // still in the process of being transferred. - partialSuffix = ".partial" - - // deletedSuffix is the suffix for a deleted marker file - // that's placed next to a file (without the suffix) that we - // tried to delete, but Windows wouldn't let us. These are - // only written on Windows (and in tests), but they're not - // permitted to be uploaded directly on any platform, like - // partial files. - deletedSuffix = ".deleted" -) - -// ClientID is an opaque identifier for file resumption. -// A client can only list and resume partial files for its own ID. -// It must contain any filesystem specific characters (e.g., slashes). -type ClientID string // e.g., "n12345CNTRL" - -func (id ClientID) partialSuffix() string { - if id == "" { - return partialSuffix - } - return "." + string(id) + partialSuffix // e.g., ".n12345CNTRL.partial" -} - -// ManagerOptions are options to configure the [Manager]. -type ManagerOptions struct { - Logf logger.Logf // may be nil - Clock tstime.DefaultClock // may be nil - State ipn.StateStore // may be nil - - // Dir is the directory to store received files. - // This main either be the final location for the files - // or just a temporary staging directory (see DirectFileMode). - Dir string - - // DirectFileMode reports whether we are writing files - // directly to a download directory, rather than writing them to - // a temporary staging directory. - // - // The following methods: - // - HasFilesWaiting - // - WaitingFiles - // - DeleteFile - // - OpenFile - // have no purpose in DirectFileMode. - // They are only used to check whether files are in the staging directory, - // copy them out, and then delete them. - DirectFileMode bool - - // SendFileNotify is called periodically while a file is actively - // receiving the contents for the file. There is a final call - // to the function when reception completes. - // It is not called if nil. - SendFileNotify func() -} - -// Manager manages the state for receiving and managing taildropped files. -type Manager struct { - opts ManagerOptions - - // incomingFiles is a map of files actively being received. - incomingFiles syncs.Map[incomingFileKey, *incomingFile] - // deleter managers asynchronous deletion of files. - deleter fileDeleter - - // renameMu is used to protect os.Rename calls so that they are atomic. - renameMu sync.Mutex - - // totalReceived counts the cumulative total of received files. - totalReceived atomic.Int64 - // emptySince specifies that there were no waiting files - // since this value of totalReceived. - emptySince atomic.Int64 -} - -// New initializes a new taildrop manager. -// It may spawn asynchronous goroutines to delete files, -// so the Shutdown method must be called for resource cleanup. -func (opts ManagerOptions) New() *Manager { - if opts.Logf == nil { - opts.Logf = logger.Discard - } - if opts.SendFileNotify == nil { - opts.SendFileNotify = func() {} - } - m := &Manager{opts: opts} - m.deleter.Init(m, func(string) {}) - m.emptySince.Store(-1) // invalidate this cache - return m -} - -// Dir returns the directory. -func (m *Manager) Dir() string { - return m.opts.Dir -} - -// Shutdown shuts down the Manager. -// It blocks until all spawned goroutines have stopped running. -func (m *Manager) Shutdown() { - if m != nil { - m.deleter.shutdown() - m.deleter.group.Wait() - } -} - -func validFilenameRune(r rune) bool { - switch r { - case '/': - return false - case '\\', ':', '*', '"', '<', '>', '|': - // Invalid stuff on Windows, but we reject them everywhere - // for now. - // TODO(bradfitz): figure out a better plan. We initially just - // wrote things to disk URL path-escaped, but that's gross - // when debugging, and just moves the problem to callers. - // So now we put the UTF-8 filenames on disk directly as - // sent. - return false - } - return unicode.IsGraphic(r) -} - -func isPartialOrDeleted(s string) bool { - return strings.HasSuffix(s, deletedSuffix) || strings.HasSuffix(s, partialSuffix) -} - -func joinDir(dir, baseName string) (fullPath string, err error) { - if !utf8.ValidString(baseName) { - return "", ErrInvalidFileName - } - if strings.TrimSpace(baseName) != baseName { - return "", ErrInvalidFileName - } - if len(baseName) > 255 { - return "", ErrInvalidFileName - } - // TODO: validate unicode normalization form too? Varies by platform. - clean := path.Clean(baseName) - if clean != baseName || - clean == "." || clean == ".." || - isPartialOrDeleted(clean) { - return "", ErrInvalidFileName - } - for _, r := range baseName { - if !validFilenameRune(r) { - return "", ErrInvalidFileName - } - } - if !filepath.IsLocal(baseName) { - return "", ErrInvalidFileName - } - return filepath.Join(dir, baseName), nil -} - -// rangeDir iterates over the contents of a directory, calling fn for each entry. -// It continues iterating while fn returns true. -// It reports the number of entries seen. -func rangeDir(dir string, fn func(fs.DirEntry) bool) error { - f, err := os.Open(dir) - if err != nil { - return err - } - defer f.Close() - for { - des, err := f.ReadDir(10) - for _, de := range des { - if !fn(de) { - return nil - } - } - if err != nil { - if err == io.EOF { - return nil - } - return err - } - } -} - -// IncomingFiles returns a list of active incoming files. -func (m *Manager) IncomingFiles() []ipn.PartialFile { - // Make sure we always set n.IncomingFiles non-nil so it gets encoded - // in JSON to clients. They distinguish between empty and non-nil - // to know whether a Notify should be able about files. - files := make([]ipn.PartialFile, 0) - for k, f := range m.incomingFiles.All() { - f.mu.Lock() - files = append(files, ipn.PartialFile{ - Name: k.name, - Started: f.started, - DeclaredSize: f.size, - Received: f.copied, - PartialPath: f.partialPath, - FinalPath: f.finalPath, - Done: f.done, - }) - f.mu.Unlock() - } - return files -} - -type redactedError struct { - msg string - inner error -} - -func (re *redactedError) Error() string { - return re.msg -} - -func (re *redactedError) Unwrap() error { - return re.inner -} - -func redactString(s string) string { - hash := adler32.Checksum([]byte(s)) - - const redacted = "redacted" - var buf [len(redacted) + len(".12345678")]byte - b := append(buf[:0], []byte(redacted)...) - b = append(b, '.') - b = strconv.AppendUint(b, uint64(hash), 16) - return string(b) -} - -func redactError(root error) error { - // redactStrings is a list of sensitive strings that were redacted. - // It is not sufficient to just snub out sensitive fields in Go errors - // since some wrapper errors like fmt.Errorf pre-cache the error string, - // which would unfortunately remain unaffected. - var redactStrings []string - - // Redact sensitive fields in known Go error types. - var unknownErrors int - multierr.Range(root, func(err error) bool { - switch err := err.(type) { - case *os.PathError: - redactStrings = append(redactStrings, err.Path) - err.Path = redactString(err.Path) - case *os.LinkError: - redactStrings = append(redactStrings, err.New, err.Old) - err.New = redactString(err.New) - err.Old = redactString(err.Old) - default: - unknownErrors++ - } - return true - }) - - // If there are no redacted strings or no unknown error types, - // then we can return the possibly modified root error verbatim. - // Otherwise, we must replace redacted strings from any wrappers. - if len(redactStrings) == 0 || unknownErrors == 0 { - return root - } - - // Stringify and replace any paths that we found above, then return - // the error wrapped in a type that uses the newly-redacted string - // while also allowing Unwrap()-ing to the inner error type(s). - s := root.Error() - for _, toRedact := range redactStrings { - s = strings.ReplaceAll(s, toRedact, redactString(toRedact)) - } - return &redactedError{msg: s, inner: root} -} - -var ( - rxExtensionSuffix = regexp.MustCompile(`(\.[a-zA-Z0-9]{0,3}[a-zA-Z][a-zA-Z0-9]{0,3})*$`) - rxNumberSuffix = regexp.MustCompile(` \([0-9]+\)`) -) - -// NextFilename returns the next filename in a sequence. -// It is used for construction a new filename if there is a conflict. -// -// For example, "Foo.jpg" becomes "Foo (1).jpg" and -// "Foo (1).jpg" becomes "Foo (2).jpg". -func NextFilename(name string) string { - ext := rxExtensionSuffix.FindString(strings.TrimPrefix(name, ".")) - name = strings.TrimSuffix(name, ext) - var n uint64 - if rxNumberSuffix.MatchString(name) { - i := strings.LastIndex(name, " (") - if n, _ = strconv.ParseUint(name[i+len("( "):len(name)-len(")")], 10, 64); n > 0 { - name = name[:i] - } - } - return name + " (" + strconv.FormatUint(n+1, 10) + ")" + ext -} diff --git a/vendor/tailscale.com/tempfork/acme/acme.go b/vendor/tailscale.com/tempfork/acme/acme.go index 94234ef..bbddb95 100644 --- a/vendor/tailscale.com/tempfork/acme/acme.go +++ b/vendor/tailscale.com/tempfork/acme/acme.go @@ -270,10 +270,7 @@ func (c *Client) FetchRenewalInfo(ctx context.Context, leaf []byte) (*RenewalInf return nil, fmt.Errorf("parsing leaf certificate: %w", err) } - renewalURL, err := c.getRenewalURL(parsedLeaf) - if err != nil { - return nil, fmt.Errorf("generating renewal info URL: %w", err) - } + renewalURL := c.getRenewalURL(parsedLeaf) res, err := c.get(ctx, renewalURL, wantStatus(http.StatusOK)) if err != nil { @@ -288,16 +285,20 @@ func (c *Client) FetchRenewalInfo(ctx context.Context, leaf []byte) (*RenewalInf return &info, nil } -func (c *Client) getRenewalURL(cert *x509.Certificate) (string, error) { +func (c *Client) getRenewalURL(cert *x509.Certificate) string { // See https://www.ietf.org/archive/id/draft-ietf-acme-ari-04.html#name-the-renewalinfo-resource // for how the request URL is built. url := c.dir.RenewalInfoURL if !strings.HasSuffix(url, "/") { url += "/" } + return url + certRenewalIdentifier(cert) +} + +func certRenewalIdentifier(cert *x509.Certificate) string { aki := base64.RawURLEncoding.EncodeToString(cert.AuthorityKeyId) serial := base64.RawURLEncoding.EncodeToString(cert.SerialNumber.Bytes()) - return fmt.Sprintf("%s%s.%s", url, aki, serial), nil + return aki + "." + serial } // AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service diff --git a/vendor/tailscale.com/tempfork/acme/rfc8555.go b/vendor/tailscale.com/tempfork/acme/rfc8555.go index 3152e53..3eaf935 100644 --- a/vendor/tailscale.com/tempfork/acme/rfc8555.go +++ b/vendor/tailscale.com/tempfork/acme/rfc8555.go @@ -7,6 +7,7 @@ package acme import ( "context" "crypto" + "crypto/x509" "encoding/base64" "encoding/json" "encoding/pem" @@ -205,6 +206,7 @@ func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderO Identifiers []wireAuthzID `json:"identifiers"` NotBefore string `json:"notBefore,omitempty"` NotAfter string `json:"notAfter,omitempty"` + Replaces string `json:"replaces,omitempty"` }{} for _, v := range id { req.Identifiers = append(req.Identifiers, wireAuthzID{ @@ -218,6 +220,14 @@ func (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderO req.NotBefore = time.Time(o).Format(time.RFC3339) case orderNotAfterOpt: req.NotAfter = time.Time(o).Format(time.RFC3339) + case orderReplacesCert: + req.Replaces = certRenewalIdentifier(o.cert) + case orderReplacesCertDER: + cert, err := x509.ParseCertificate(o) + if err != nil { + return nil, fmt.Errorf("failed to parse certificate being replaced: %w", err) + } + req.Replaces = certRenewalIdentifier(cert) default: // Package's fault if we let this happen. panic(fmt.Sprintf("unsupported order option type %T", o)) diff --git a/vendor/tailscale.com/tempfork/acme/types.go b/vendor/tailscale.com/tempfork/acme/types.go index 518fa24..0142469 100644 --- a/vendor/tailscale.com/tempfork/acme/types.go +++ b/vendor/tailscale.com/tempfork/acme/types.go @@ -391,6 +391,30 @@ type orderNotAfterOpt time.Time func (orderNotAfterOpt) privateOrderOpt() {} +// WithOrderReplacesCert indicates that this Order is for a replacement of an +// existing certificate. +// See https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5 +func WithOrderReplacesCert(cert *x509.Certificate) OrderOption { + return orderReplacesCert{cert} +} + +type orderReplacesCert struct { + cert *x509.Certificate +} + +func (orderReplacesCert) privateOrderOpt() {} + +// WithOrderReplacesCertDER indicates that this Order is for a replacement of +// an existing DER-encoded certificate. +// See https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-5 +func WithOrderReplacesCertDER(der []byte) OrderOption { + return orderReplacesCertDER(der) +} + +type orderReplacesCertDER []byte + +func (orderReplacesCertDER) privateOrderOpt() {} + // Authorization encodes an authorization response. type Authorization struct { // URI uniquely identifies a authorization. diff --git a/vendor/tailscale.com/tempfork/httprec/httprec.go b/vendor/tailscale.com/tempfork/httprec/httprec.go index 13786aa..07ca673 100644 --- a/vendor/tailscale.com/tempfork/httprec/httprec.go +++ b/vendor/tailscale.com/tempfork/httprec/httprec.go @@ -14,9 +14,6 @@ import ( "net/http" "net/textproto" "strconv" - "strings" - - "golang.org/x/net/http/httpguts" ) // ResponseRecorder is an implementation of [http.ResponseWriter] that @@ -59,10 +56,6 @@ func NewRecorder() *ResponseRecorder { } } -// DefaultRemoteAddr is the default remote address to return in RemoteAddr if -// an explicit DefaultRemoteAddr isn't set on [ResponseRecorder]. -const DefaultRemoteAddr = "1.2.3.4" - // Header implements [http.ResponseWriter]. It returns the response // headers to mutate within a handler. To test the headers that were // written after a handler completes, use the [ResponseRecorder.Result] method and see @@ -206,37 +199,6 @@ func (rw *ResponseRecorder) Result() *http.Response { res.Body = http.NoBody } res.ContentLength = parseContentLength(res.Header.Get("Content-Length")) - - if trailers, ok := rw.snapHeader["Trailer"]; ok { - res.Trailer = make(http.Header, len(trailers)) - for _, k := range trailers { - for _, k := range strings.Split(k, ",") { - k = http.CanonicalHeaderKey(textproto.TrimString(k)) - if !httpguts.ValidTrailerHeader(k) { - // Ignore since forbidden by RFC 7230, section 4.1.2. - continue - } - vv, ok := rw.HeaderMap[k] - if !ok { - continue - } - vv2 := make([]string, len(vv)) - copy(vv2, vv) - res.Trailer[k] = vv2 - } - } - } - for k, vv := range rw.HeaderMap { - if !strings.HasPrefix(k, http.TrailerPrefix) { - continue - } - if res.Trailer == nil { - res.Trailer = make(http.Header) - } - for _, v := range vv { - res.Trailer.Add(strings.TrimPrefix(k, http.TrailerPrefix), v) - } - } return res } diff --git a/vendor/tailscale.com/tka/aum.go b/vendor/tailscale.com/tka/aum.go index 07a34b4..b8c4b6c 100644 --- a/vendor/tailscale.com/tka/aum.go +++ b/vendor/tailscale.com/tka/aum.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( @@ -29,8 +31,8 @@ func (h AUMHash) String() string { // UnmarshalText implements encoding.TextUnmarshaler. func (h *AUMHash) UnmarshalText(text []byte) error { - if l := base32StdNoPad.DecodedLen(len(text)); l != len(h) { - return fmt.Errorf("tka.AUMHash.UnmarshalText: text wrong length: %d, want %d", l, len(text)) + if ln := base32StdNoPad.DecodedLen(len(text)); ln != len(h) { + return fmt.Errorf("tka.AUMHash.UnmarshalText: text wrong length: %d, want %d", ln, len(text)) } if _, err := base32StdNoPad.Decode(h[:], text); err != nil { return fmt.Errorf("tka.AUMHash.UnmarshalText: %w", err) @@ -53,6 +55,17 @@ func (h AUMHash) IsZero() bool { return h == (AUMHash{}) } +// PrevAUMHash represents the BLAKE2s digest of an Authority Update Message (AUM). +// Unlike an AUMHash, this can be empty if there is no previous AUM hash +// (which occurs in the genesis AUM). +type PrevAUMHash []byte + +// String returns the PrevAUMHash encoded as base32. +// This is suitable for use as a filename, and for storing in text-preferred media. +func (h PrevAUMHash) String() string { + return base32StdNoPad.EncodeToString(h[:]) +} + // AUMKind describes valid AUM types. type AUMKind uint8 @@ -117,8 +130,8 @@ func (k AUMKind) String() string { // behavior of old clients (which will ignore the field). // - No floats! type AUM struct { - MessageKind AUMKind `cbor:"1,keyasint"` - PrevAUMHash []byte `cbor:"2,keyasint"` + MessageKind AUMKind `cbor:"1,keyasint"` + PrevAUMHash PrevAUMHash `cbor:"2,keyasint"` // Key encodes a public key to be added to the key authority. // This field is used for AddKey AUMs. @@ -224,7 +237,7 @@ func (a *AUM) Serialize() tkatype.MarshaledAUM { // Further, experience with other attempts (JWS/JWT,SAML,X509 etc) has // taught us that even subtle behaviors such as how you handle invalid // or unrecognized fields + any invariants in subsequent re-serialization - // can easily lead to security-relevant logic bugs. Its certainly possible + // can easily lead to security-relevant logic bugs. It's certainly possible // to invent a workable scheme by massaging a JSON parsing library, though // profoundly unwise. // diff --git a/vendor/tailscale.com/tka/builder.go b/vendor/tailscale.com/tka/builder.go index c14ba23..ab2364d 100644 --- a/vendor/tailscale.com/tka/builder.go +++ b/vendor/tailscale.com/tka/builder.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( @@ -67,6 +69,11 @@ func (b *UpdateBuilder) AddKey(key Key) error { if _, err := b.state.GetKey(keyID); err == nil { return fmt.Errorf("cannot add key %v: already exists", key) } + + if len(b.state.Keys) >= maxKeys { + return fmt.Errorf("cannot add key %v: maximum number of keys reached", key) + } + return b.mkUpdate(AUM{MessageKind: AUMAddKey, Key: &key}) } @@ -107,7 +114,7 @@ func (b *UpdateBuilder) generateCheckpoint() error { } } - // Checkpoints cant specify a parent AUM. + // Checkpoints can't specify a parent AUM. state.LastAUMHash = nil return b.mkUpdate(AUM{MessageKind: AUMCheckpoint, State: &state}) } @@ -129,7 +136,7 @@ func (b *UpdateBuilder) Finalize(storage Chonk) ([]AUM, error) { needCheckpoint = false break } - return nil, fmt.Errorf("reading AUM: %v", err) + return nil, fmt.Errorf("reading AUM (%v): %v", cursor, err) } if aum.MessageKind == AUMCheckpoint { diff --git a/vendor/tailscale.com/tka/deeplink.go b/vendor/tailscale.com/tka/deeplink.go index 5cf24fc..5570a19 100644 --- a/vendor/tailscale.com/tka/deeplink.go +++ b/vendor/tailscale.com/tka/deeplink.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( diff --git a/vendor/tailscale.com/tka/disabled_stub.go b/vendor/tailscale.com/tka/disabled_stub.go new file mode 100644 index 0000000..4c4afa3 --- /dev/null +++ b/vendor/tailscale.com/tka/disabled_stub.go @@ -0,0 +1,160 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_tailnetlock + +package tka + +import ( + "crypto/ed25519" + "errors" + + "tailscale.com/types/key" + "tailscale.com/types/logger" + "tailscale.com/types/tkatype" +) + +type Authority struct { + head AUM + oldestAncestor AUM + state State +} + +func (*Authority) Head() AUMHash { return AUMHash{} } + +// MarshalText returns a dummy value explaining that Tailnet Lock +// is not compiled in to this binary. +// +// We need to be able to marshal AUMHash to text because it's included +// in [netmap.NetworkMap], which gets serialised as JSON in the +// c2n /debug/netmap endpoint. +// +// We provide a basic marshaller so that endpoint works correctly +// with nodes that omit Tailnet Lock support, but we don't want the +// base32 dependency used for the regular marshaller, and we don't +// need unmarshalling support at time of writing (2025-11-18). +func (h AUMHash) MarshalText() ([]byte, error) { + return []byte(""), nil +} + +func (h *AUMHash) UnmarshalText(text []byte) error { + return errors.New("tailnet lock is not supported by this binary") +} + +type State struct{} + +// AUMKind describes valid AUM types. +type AUMKind uint8 + +type AUMHash [32]byte + +type AUM struct { + MessageKind AUMKind `cbor:"1,keyasint"` + PrevAUMHash []byte `cbor:"2,keyasint"` + + // Key encodes a public key to be added to the key authority. + // This field is used for AddKey AUMs. + Key *Key `cbor:"3,keyasint,omitempty"` + + // KeyID references a public key which is part of the key authority. + // This field is used for RemoveKey and UpdateKey AUMs. + KeyID tkatype.KeyID `cbor:"4,keyasint,omitempty"` + + // State describes the full state of the key authority. + // This field is used for Checkpoint AUMs. + State *State `cbor:"5,keyasint,omitempty"` + + // Votes and Meta describe properties of a key in the key authority. + // These fields are used for UpdateKey AUMs. + Votes *uint `cbor:"6,keyasint,omitempty"` + Meta map[string]string `cbor:"7,keyasint,omitempty"` + + // Signatures lists the signatures over this AUM. + // CBOR key 23 is the last key which can be encoded as a single byte. + Signatures []tkatype.Signature `cbor:"23,keyasint,omitempty"` +} + +type Chonk interface { + // AUM returns the AUM with the specified digest. + // + // If the AUM does not exist, then os.ErrNotExist is returned. + AUM(hash AUMHash) (AUM, error) + + // ChildAUMs returns all AUMs with a specified previous + // AUM hash. + ChildAUMs(prevAUMHash AUMHash) ([]AUM, error) + + // CommitVerifiedAUMs durably stores the provided AUMs. + // Callers MUST ONLY provide AUMs which are verified (specifically, + // a call to aumVerify() must return a nil error). + // as the implementation assumes that only verified AUMs are stored. + CommitVerifiedAUMs(updates []AUM) error + + // Heads returns AUMs for which there are no children. In other + // words, the latest AUM in all possible chains (the 'leaves'). + Heads() ([]AUM, error) + + // SetLastActiveAncestor is called to record the oldest-known AUM + // that contributed to the current state. This value is used as + // a hint on next startup to determine which chain to pick when computing + // the current state, if there are multiple distinct chains. + SetLastActiveAncestor(hash AUMHash) error + + // LastActiveAncestor returns the oldest-known AUM that was (in a + // previous run) an ancestor of the current state. This is used + // as a hint to pick the correct chain in the event that the Chonk stores + // multiple distinct chains. + LastActiveAncestor() (*AUMHash, error) +} + +// SigKind describes valid NodeKeySignature types. +type SigKind uint8 + +type NodeKeySignature struct { + // SigKind identifies the variety of signature. + SigKind SigKind `cbor:"1,keyasint"` + // Pubkey identifies the key.NodePublic which is being authorized. + // SigCredential signatures do not use this field. + Pubkey []byte `cbor:"2,keyasint,omitempty"` + + // KeyID identifies which key in the tailnet key authority should + // be used to verify this signature. Only set for SigDirect and + // SigCredential signature kinds. + KeyID []byte `cbor:"3,keyasint,omitempty"` + + // Signature is the packed (R, S) ed25519 signature over all other + // fields of the structure. + Signature []byte `cbor:"4,keyasint,omitempty"` + + // Nested describes a NodeKeySignature which authorizes the node-key + // used as Pubkey. Only used for SigRotation signatures. + Nested *NodeKeySignature `cbor:"5,keyasint,omitempty"` + + // WrappingPubkey specifies the ed25519 public key which must be used + // to sign a Signature which embeds this one. + // + // For SigRotation signatures multiple levels deep, intermediate + // signatures may omit this value, in which case the parent WrappingPubkey + // is used. + // + // SigCredential signatures use this field to specify the public key + // they are certifying, following the usual semanticsfor WrappingPubkey. + WrappingPubkey []byte `cbor:"6,keyasint,omitempty"` +} + +type DeeplinkValidationResult struct { +} + +func DecodeWrappedAuthkey(wrappedAuthKey string, logf logger.Logf) (authKey string, isWrapped bool, sig *NodeKeySignature, priv ed25519.PrivateKey) { + return wrappedAuthKey, false, nil, nil +} + +func ResignNKS(priv key.NLPrivate, nodeKey key.NodePublic, oldNKS tkatype.MarshaledSignature) (tkatype.MarshaledSignature, error) { + return nil, nil +} + +func SignByCredential(privKey []byte, wrapped *NodeKeySignature, nodeKey key.NodePublic) (tkatype.MarshaledSignature, error) { + return nil, nil +} + +func (s NodeKeySignature) String() string { return "" } diff --git a/vendor/tailscale.com/tka/key.go b/vendor/tailscale.com/tka/key.go index 0773679..dca1b44 100644 --- a/vendor/tailscale.com/tka/key.go +++ b/vendor/tailscale.com/tka/key.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" - "github.com/hdevalence/ed25519consensus" "tailscale.com/types/tkatype" ) @@ -136,24 +135,3 @@ func (k Key) StaticValidate() error { } return nil } - -// Verify returns a nil error if the signature is valid over the -// provided AUM BLAKE2s digest, using the given key. -func signatureVerify(s *tkatype.Signature, aumDigest tkatype.AUMSigHash, key Key) error { - // NOTE(tom): Even if we can compute the public from the KeyID, - // its possible for the KeyID to be attacker-controlled - // so we should use the public contained in the state machine. - switch key.Kind { - case Key25519: - if len(key.Public) != ed25519.PublicKeySize { - return fmt.Errorf("ed25519 key has wrong length: %d", len(key.Public)) - } - if ed25519consensus.Verify(ed25519.PublicKey(key.Public), aumDigest[:], s.Signature) { - return nil - } - return errors.New("invalid signature") - - default: - return fmt.Errorf("unhandled key type: %v", key.Kind) - } -} diff --git a/vendor/tailscale.com/tka/sig.go b/vendor/tailscale.com/tka/sig.go index c82f971..46d598a 100644 --- a/vendor/tailscale.com/tka/sig.go +++ b/vendor/tailscale.com/tka/sig.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( @@ -275,7 +277,7 @@ func (s *NodeKeySignature) verifySignature(nodeKey key.NodePublic, verificationK // Recurse to verify the signature on the nested structure. var nestedPub key.NodePublic // SigCredential signatures certify an indirection key rather than a node - // key, so theres no need to check the node key. + // key, so there's no need to check the node key. if s.Nested.SigKind != SigCredential { if err := nestedPub.UnmarshalBinary(s.Nested.Pubkey); err != nil { return fmt.Errorf("nested pubkey: %v", err) diff --git a/vendor/tailscale.com/tka/state.go b/vendor/tailscale.com/tka/state.go index 0a459bd..95a319b 100644 --- a/vendor/tailscale.com/tka/state.go +++ b/vendor/tailscale.com/tka/state.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( @@ -138,7 +140,7 @@ func (s State) checkDisablement(secret []byte) bool { // Specifically, the rules are: // - The last AUM hash must match (transitively, this implies that this // update follows the last update message applied to the state machine) -// - Or, the state machine knows no parent (its brand new). +// - Or, the state machine knows no parent (it's brand new). func (s State) parentMatches(update AUM) bool { if s.LastAUMHash == nil { return true diff --git a/vendor/tailscale.com/tka/sync.go b/vendor/tailscale.com/tka/sync.go index 6131f54..2dbfb7a 100644 --- a/vendor/tailscale.com/tka/sync.go +++ b/vendor/tailscale.com/tka/sync.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( @@ -30,6 +32,41 @@ type SyncOffer struct { Ancestors []AUMHash } +// ToSyncOffer creates a SyncOffer from the fields received in +// a [tailcfg.TKASyncOfferRequest]. +func ToSyncOffer(head string, ancestors []string) (SyncOffer, error) { + var out SyncOffer + if err := out.Head.UnmarshalText([]byte(head)); err != nil { + return SyncOffer{}, fmt.Errorf("head.UnmarshalText: %v", err) + } + out.Ancestors = make([]AUMHash, len(ancestors)) + for i, a := range ancestors { + if err := out.Ancestors[i].UnmarshalText([]byte(a)); err != nil { + return SyncOffer{}, fmt.Errorf("ancestor[%d].UnmarshalText: %v", i, err) + } + } + return out, nil +} + +// FromSyncOffer marshals the fields of a SyncOffer so they can be +// sent in a [tailcfg.TKASyncOfferRequest]. +func FromSyncOffer(offer SyncOffer) (head string, ancestors []string, err error) { + headBytes, err := offer.Head.MarshalText() + if err != nil { + return "", nil, fmt.Errorf("head.MarshalText: %v", err) + } + + ancestors = make([]string, len(offer.Ancestors)) + for i, ancestor := range offer.Ancestors { + hash, err := ancestor.MarshalText() + if err != nil { + return "", nil, fmt.Errorf("ancestor[%d].MarshalText: %v", i, err) + } + ancestors[i] = string(hash) + } + return string(headBytes), ancestors, nil +} + const ( // The starting number of AUMs to skip when listing // ancestors in a SyncOffer. @@ -52,7 +89,7 @@ const ( // can then be applied locally with Inform(). // // This SyncOffer + AUM exchange should be performed by both ends, -// because its possible that either end has AUMs that the other needs +// because it's possible that either end has AUMs that the other needs // to find out about. func (a *Authority) SyncOffer(storage Chonk) (SyncOffer, error) { oldest := a.oldestAncestor.Hash() @@ -121,7 +158,7 @@ func computeSyncIntersection(storage Chonk, localOffer, remoteOffer SyncOffer) ( } // Case: 'head intersection' - // If we have the remote's head, its more likely than not that + // If we have the remote's head, it's more likely than not that // we have updates that build on that head. To confirm this, // we iterate backwards through our chain to see if the given // head is an ancestor of our current chain. @@ -163,7 +200,7 @@ func computeSyncIntersection(storage Chonk, localOffer, remoteOffer SyncOffer) ( // Case: 'tail intersection' // So we don't have a clue what the remote's head is, but // if one of the ancestors they gave us is part of our chain, - // then theres an intersection, which is a starting point for + // then there's an intersection, which is a starting point for // the remote to send us AUMs from. // // We iterate the list of ancestors in order because the remote diff --git a/vendor/tailscale.com/tka/tailchonk.go b/vendor/tailscale.com/tka/tailchonk.go index 32d2215..13bdf6a 100644 --- a/vendor/tailscale.com/tka/tailchonk.go +++ b/vendor/tailscale.com/tka/tailchonk.go @@ -1,19 +1,26 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_tailnetlock + package tka import ( "bytes" "errors" "fmt" + "log" + "maps" "os" "path/filepath" + "slices" "sync" "time" "github.com/fxamacker/cbor/v2" "tailscale.com/atomicfile" + "tailscale.com/tstime" + "tailscale.com/util/testenv" ) // Chonk implementations provide durable storage for AUMs and other @@ -71,38 +78,69 @@ type CompactableChonk interface { // PurgeAUMs permanently and irrevocably deletes the specified // AUMs from storage. PurgeAUMs(hashes []AUMHash) error + + // RemoveAll permanently and completely clears the TKA state. This should + // be called when the user disables Tailnet Lock. + RemoveAll() error } // Mem implements in-memory storage of TKA state, suitable for -// tests. +// tests or cases where filesystem storage is unavailable. // // Mem implements the Chonk interface. +// +// Mem is thread-safe. type Mem struct { - l sync.RWMutex + mu sync.RWMutex aums map[AUMHash]AUM + commitTimes map[AUMHash]time.Time + clock tstime.Clock + + // parentIndex is a map of AUMs to the AUMs for which they are + // the parent. + // + // For example, if parent index is {1 -> {2, 3, 4}}, that means + // that AUMs 2, 3, 4 all have aum.PrevAUMHash = 1. parentIndex map[AUMHash][]AUMHash lastActiveAncestor *AUMHash } +// ChonkMem returns an implementation of Chonk which stores TKA state +// in-memory. +func ChonkMem() *Mem { + return &Mem{ + clock: tstime.DefaultClock{}, + } +} + +// SetClock sets the clock used by [Mem]. This is only for use in tests, +// and will panic if called from non-test code. +func (c *Mem) SetClock(clock tstime.Clock) { + if !testenv.InTest() { + panic("used SetClock in non-test code") + } + c.clock = clock +} + func (c *Mem) SetLastActiveAncestor(hash AUMHash) error { - c.l.Lock() - defer c.l.Unlock() + c.mu.Lock() + defer c.mu.Unlock() c.lastActiveAncestor = &hash return nil } func (c *Mem) LastActiveAncestor() (*AUMHash, error) { - c.l.RLock() - defer c.l.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() return c.lastActiveAncestor, nil } // Heads returns AUMs for which there are no children. In other // words, the latest AUM in all chains (the 'leaf'). func (c *Mem) Heads() ([]AUM, error) { - c.l.RLock() - defer c.l.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() out := make([]AUM, 0, 6) // An AUM is a 'head' if there are no nodes for which it is the parent. @@ -116,8 +154,8 @@ func (c *Mem) Heads() ([]AUM, error) { // AUM returns the AUM with the specified digest. func (c *Mem) AUM(hash AUMHash) (AUM, error) { - c.l.RLock() - defer c.l.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() aum, ok := c.aums[hash] if !ok { return AUM{}, os.ErrNotExist @@ -125,24 +163,11 @@ func (c *Mem) AUM(hash AUMHash) (AUM, error) { return aum, nil } -// Orphans returns all AUMs which do not have a parent. -func (c *Mem) Orphans() ([]AUM, error) { - c.l.RLock() - defer c.l.RUnlock() - out := make([]AUM, 0, 6) - for _, a := range c.aums { - if _, ok := a.Parent(); !ok { - out = append(out, a) - } - } - return out, nil -} - // ChildAUMs returns all AUMs with a specified previous // AUM hash. func (c *Mem) ChildAUMs(prevAUMHash AUMHash) ([]AUM, error) { - c.l.RLock() - defer c.l.RUnlock() + c.mu.RLock() + defer c.mu.RUnlock() out := make([]AUM, 0, 6) for _, entry := range c.parentIndex[prevAUMHash] { out = append(out, c.aums[entry]) @@ -156,17 +181,19 @@ func (c *Mem) ChildAUMs(prevAUMHash AUMHash) ([]AUM, error) { // as the rest of the TKA implementation assumes that only // verified AUMs are stored. func (c *Mem) CommitVerifiedAUMs(updates []AUM) error { - c.l.Lock() - defer c.l.Unlock() + c.mu.Lock() + defer c.mu.Unlock() if c.aums == nil { c.parentIndex = make(map[AUMHash][]AUMHash, 64) c.aums = make(map[AUMHash]AUM, 64) + c.commitTimes = make(map[AUMHash]time.Time, 64) } updateLoop: for _, aum := range updates { aumHash := aum.Hash() c.aums[aumHash] = aum + c.commitTimes[aumHash] = c.now() parent, ok := aum.Parent() if ok { @@ -182,6 +209,81 @@ updateLoop: return nil } +// now returns the current time, optionally using the overridden +// clock if set. +func (c *Mem) now() time.Time { + if c.clock == nil { + return time.Now() + } else { + return c.clock.Now() + } +} + +// RemoveAll permanently and completely clears the TKA state. +func (c *Mem) RemoveAll() error { + c.mu.Lock() + defer c.mu.Unlock() + c.aums = nil + c.commitTimes = nil + c.parentIndex = nil + c.lastActiveAncestor = nil + return nil +} + +// AllAUMs returns all AUMs stored in the chonk. +func (c *Mem) AllAUMs() ([]AUMHash, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + return slices.Collect(maps.Keys(c.aums)), nil +} + +// CommitTime returns the time at which the AUM was committed. +// +// If the AUM does not exist, then os.ErrNotExist is returned. +func (c *Mem) CommitTime(h AUMHash) (time.Time, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + t, ok := c.commitTimes[h] + if ok { + return t, nil + } else { + return time.Time{}, os.ErrNotExist + } +} + +// PurgeAUMs marks the specified AUMs for deletion from storage. +func (c *Mem) PurgeAUMs(hashes []AUMHash) error { + c.mu.Lock() + defer c.mu.Unlock() + + for _, h := range hashes { + // Remove the deleted AUM from the list of its parents' children. + // + // However, we leave the list of this AUM's children in parentIndex, + // so we can find them later in ChildAUMs(). + if aum, ok := c.aums[h]; ok { + parent, hasParent := aum.Parent() + if hasParent { + c.parentIndex[parent] = slices.DeleteFunc( + c.parentIndex[parent], + func(other AUMHash) bool { return bytes.Equal(h[:], other[:]) }, + ) + if len(c.parentIndex[parent]) == 0 { + delete(c.parentIndex, parent) + } + } + } + + // Delete this AUM from the list of AUMs and commit times. + delete(c.aums, h) + delete(c.commitTimes, h) + } + + return nil +} + // FS implements filesystem storage of TKA state. // // FS implements the Chonk interface. @@ -193,6 +295,10 @@ type FS struct { // ChonkDir returns an implementation of Chonk which uses the // given directory to store TKA state. func ChonkDir(dir string) (*FS, error) { + if err := os.MkdirAll(dir, 0755); err != nil && !os.IsExist(err) { + return nil, fmt.Errorf("creating chonk root dir: %v", err) + } + stat, err := os.Stat(dir) if err != nil { return nil, err @@ -217,10 +323,14 @@ func ChonkDir(dir string) (*FS, error) { // CBOR was chosen because we are already using it and it serializes // much smaller than JSON for AUMs. The 'keyasint' thing isn't essential // but again it saves a bunch of bytes. +// +// We have removed the following fields from fsHashInfo, but they may be +// present in data stored in existing deployments. Do not reuse these values, +// to avoid getting unexpected values from legacy data: +// - cbor:1, Children type fsHashInfo struct { - Children []AUMHash `cbor:"1,keyasint"` - AUM *AUM `cbor:"2,keyasint"` - CreatedUnix int64 `cbor:"3,keyasint,omitempty"` + AUM *AUM `cbor:"2,keyasint"` + CreatedUnix int64 `cbor:"3,keyasint,omitempty"` // PurgedUnix is set when the AUM is deleted. The value is // the unix epoch at the time it was deleted. @@ -296,32 +406,15 @@ func (c *FS) ChildAUMs(prevAUMHash AUMHash) ([]AUM, error) { c.mu.RLock() defer c.mu.RUnlock() - info, err := c.get(prevAUMHash) - if err != nil { - if os.IsNotExist(err) { - // not knowing about this hash is not an error - return nil, nil - } - return nil, err - } - // NOTE(tom): We don't check PurgedUnix here because 'purged' - // only applies to that specific AUM (i.e. info.AUM) and not to - // any information about children stored against that hash. + var out []AUM - out := make([]AUM, len(info.Children)) - for i, h := range info.Children { - c, err := c.get(h) - if err != nil { - // We expect any AUM recorded as a child on its parent to exist. - return nil, fmt.Errorf("reading child %d of %x: %v", i, h, err) + err := c.scanHashes(func(info *fsHashInfo) { + if info.AUM != nil && bytes.Equal(info.AUM.PrevAUMHash, prevAUMHash[:]) { + out = append(out, *info.AUM) } - if c.AUM == nil || c.PurgedUnix > 0 { - return nil, fmt.Errorf("child %d of %x: AUM not stored", i, h) - } - out[i] = *c.AUM - } + }) - return out, nil + return out, err } func (c *FS) get(h AUMHash) (*fsHashInfo, error) { @@ -357,13 +450,50 @@ func (c *FS) Heads() ([]AUM, error) { c.mu.RLock() defer c.mu.RUnlock() - out := make([]AUM, 0, 6) // 6 is arbitrary. - err := c.scanHashes(func(info *fsHashInfo) { - if len(info.Children) == 0 && info.AUM != nil && info.PurgedUnix == 0 { - out = append(out, *info.AUM) + // Scan the complete list of AUMs, and build a list of all parent hashes. + // This tells us which AUMs have children. + var parentHashes []AUMHash + + allAUMs, err := c.AllAUMs() + if err != nil { + return nil, err + } + + for _, h := range allAUMs { + aum, err := c.AUM(h) + if err != nil { + return nil, err } - }) - return out, err + parent, hasParent := aum.Parent() + if !hasParent { + continue + } + if !slices.Contains(parentHashes, parent) { + parentHashes = append(parentHashes, parent) + } + } + + // Now scan a second time, and only include AUMs which weren't marked as + // the parent of any other AUM. + out := make([]AUM, 0, 6) // 6 is arbitrary. + + for _, h := range allAUMs { + if slices.Contains(parentHashes, h) { + continue + } + aum, err := c.AUM(h) + if err != nil { + return nil, err + } + out = append(out, aum) + } + + return out, nil +} + +// RemoveAll permanently and completely clears the TKA state. +func (c *FS) RemoveAll() error { + return os.RemoveAll(c.base) } // AllAUMs returns all AUMs stored in the chonk. @@ -373,7 +503,7 @@ func (c *FS) AllAUMs() ([]AUMHash, error) { out := make([]AUMHash, 0, 6) // 6 is arbitrary. err := c.scanHashes(func(info *fsHashInfo) { - if info.AUM != nil && info.PurgedUnix == 0 { + if info.AUM != nil { out = append(out, info.AUM.Hash()) } }) @@ -394,14 +524,24 @@ func (c *FS) scanHashes(eachHashInfo func(*fsHashInfo)) error { return fmt.Errorf("reading prefix dir: %v", err) } for _, file := range files { + // Ignore files whose names aren't valid AUM hashes, which may be + // temporary files which are partway through being written, or other + // files added by the OS (like .DS_Store) which we can ignore. + // TODO(alexc): it might be useful to append a suffix like `.aum` to + // filenames, so we can more easily distinguish between AUMs and + // arbitrary other files. var h AUMHash if err := h.UnmarshalText([]byte(file.Name())); err != nil { - return fmt.Errorf("invalid aum file: %s: %w", file.Name(), err) + log.Printf("ignoring unexpected non-AUM: %s: %v", file.Name(), err) + continue } info, err := c.get(h) if err != nil { return fmt.Errorf("reading %x: %v", h, err) } + if info.PurgedUnix > 0 { + continue + } eachHashInfo(info) } @@ -456,24 +596,6 @@ func (c *FS) CommitVerifiedAUMs(updates []AUM) error { for i, aum := range updates { h := aum.Hash() - // We keep track of children against their parent so that - // ChildAUMs() do not need to scan all AUMs. - parent, hasParent := aum.Parent() - if hasParent { - err := c.commit(parent, func(info *fsHashInfo) { - // Only add it if its not already there. - for i := range info.Children { - if info.Children[i] == h { - return - } - } - info.Children = append(info.Children, h) - }) - if err != nil { - return fmt.Errorf("committing update[%d] to parent %x: %v", i, parent, err) - } - } - err := c.commit(h, func(info *fsHashInfo) { info.PurgedUnix = 0 // just in-case it was set for some reason info.AUM = &aum @@ -576,7 +698,7 @@ const ( ) // markActiveChain marks AUMs in the active chain. -// All AUMs that are within minChain ancestors of head are +// All AUMs that are within minChain ancestors of head, or are marked as young, are // marked retainStateActive, and all remaining ancestors are // marked retainStateCandidate. // @@ -602,27 +724,30 @@ func markActiveChain(storage Chonk, verdict map[AUMHash]retainState, minChain in // We've reached the end of the chain we have stored. return h, nil } - return AUMHash{}, fmt.Errorf("reading active chain (retainStateActive) (%d): %w", i, err) + return AUMHash{}, fmt.Errorf("reading active chain (retainStateActive) (%d, %v): %w", i, parent, err) } } // If we got this far, we have at least minChain AUMs stored, and minChain number // of ancestors have been marked for retention. We now continue to iterate backwards - // till we find an AUM which we can compact to (a Checkpoint AUM). + // till we find an AUM which we can compact to: either a Checkpoint AUM which is old + // enough, or the genesis AUM. for { h := next.Hash() verdict[h] |= retainStateActive - if next.MessageKind == AUMCheckpoint { - lastActiveAncestor = h - break - } parent, hasParent := next.Parent() - if !hasParent { - return AUMHash{}, errors.New("reached genesis AUM without finding an appropriate lastActiveAncestor") + isYoung := verdict[h]&retainStateYoung != 0 + + if next.MessageKind == AUMCheckpoint { + lastActiveAncestor = h + if !isYoung || !hasParent { + break + } } + if next, err = storage.AUM(parent); err != nil { - return AUMHash{}, fmt.Errorf("searching for compaction target: %w", err) + return AUMHash{}, fmt.Errorf("searching for compaction target (%v): %w", parent, err) } } @@ -638,7 +763,7 @@ func markActiveChain(storage Chonk, verdict map[AUMHash]retainState, minChain in // We've reached the end of the chain we have stored. break } - return AUMHash{}, fmt.Errorf("reading active chain (retainStateCandidate): %w", err) + return AUMHash{}, fmt.Errorf("reading active chain (retainStateCandidate, %v): %w", parent, err) } } @@ -676,7 +801,7 @@ func markAncestorIntersectionAUMs(storage Chonk, verdict map[AUMHash]retainState toScan := make([]AUMHash, 0, len(verdict)) for h, v := range verdict { if (v & retainAUMMask) == 0 { - continue // not marked for retention, so dont need to consider it + continue // not marked for retention, so don't need to consider it } if h == candidateAncestor { continue @@ -750,7 +875,7 @@ func markAncestorIntersectionAUMs(storage Chonk, verdict map[AUMHash]retainState if didAdjustCandidateAncestor { var next AUM if next, err = storage.AUM(candidateAncestor); err != nil { - return AUMHash{}, fmt.Errorf("searching for compaction target: %w", err) + return AUMHash{}, fmt.Errorf("searching for compaction target (%v): %w", candidateAncestor, err) } for { @@ -766,7 +891,7 @@ func markAncestorIntersectionAUMs(storage Chonk, verdict map[AUMHash]retainState return AUMHash{}, errors.New("reached genesis AUM without finding an appropriate candidateAncestor") } if next, err = storage.AUM(parent); err != nil { - return AUMHash{}, fmt.Errorf("searching for compaction target: %w", err) + return AUMHash{}, fmt.Errorf("searching for compaction target (%v): %w", parent, err) } } } @@ -779,7 +904,7 @@ func markDescendantAUMs(storage Chonk, verdict map[AUMHash]retainState) error { toScan := make([]AUMHash, 0, len(verdict)) for h, v := range verdict { if v&retainAUMMask == 0 { - continue // not marked, so dont need to mark descendants + continue // not marked, so don't need to mark descendants } toScan = append(toScan, h) } @@ -825,12 +950,12 @@ func Compact(storage CompactableChonk, head AUMHash, opts CompactionOptions) (la verdict[h] = 0 } - if lastActiveAncestor, err = markActiveChain(storage, verdict, opts.MinChain, head); err != nil { - return AUMHash{}, fmt.Errorf("marking active chain: %w", err) - } if err := markYoungAUMs(storage, verdict, opts.MinAge); err != nil { return AUMHash{}, fmt.Errorf("marking young AUMs: %w", err) } + if lastActiveAncestor, err = markActiveChain(storage, verdict, opts.MinChain, head); err != nil { + return AUMHash{}, fmt.Errorf("marking active chain: %w", err) + } if err := markDescendantAUMs(storage, verdict); err != nil { return AUMHash{}, fmt.Errorf("marking descendant AUMs: %w", err) } diff --git a/vendor/tailscale.com/tka/tka.go b/vendor/tailscale.com/tka/tka.go index 04b7126..ed029c8 100644 --- a/vendor/tailscale.com/tka/tka.go +++ b/vendor/tailscale.com/tka/tka.go @@ -1,7 +1,9 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -// Package tka (WIP) implements the Tailnet Key Authority. +//go:build !ts_omit_tailnetlock + +// Package tka implements the Tailnet Key Authority (TKA) for Tailnet Lock. package tka import ( @@ -92,7 +94,7 @@ func computeChainCandidates(storage Chonk, lastKnownOldest *AUMHash, maxIter int // candidates.Oldest needs to be computed by working backwards from // head as far as we can. - iterAgain := true // if theres still work to be done. + iterAgain := true // if there's still work to be done. for i := 0; iterAgain; i++ { if i >= maxIter { return nil, fmt.Errorf("iteration limit exceeded (%d)", maxIter) @@ -100,14 +102,14 @@ func computeChainCandidates(storage Chonk, lastKnownOldest *AUMHash, maxIter int iterAgain = false for j := range candidates { - parent, hasParent := candidates[j].Oldest.Parent() + parentHash, hasParent := candidates[j].Oldest.Parent() if hasParent { - parent, err := storage.AUM(parent) + parent, err := storage.AUM(parentHash) if err != nil { if err == os.ErrNotExist { continue } - return nil, fmt.Errorf("reading parent: %v", err) + return nil, fmt.Errorf("reading parent %s: %v", parentHash, err) } candidates[j].Oldest = parent if lastKnownOldest != nil && *lastKnownOldest == parent.Hash() { @@ -208,7 +210,7 @@ func fastForwardWithAdvancer( } nextAUM, err := storage.AUM(*startState.LastAUMHash) if err != nil { - return AUM{}, State{}, fmt.Errorf("reading next: %v", err) + return AUM{}, State{}, fmt.Errorf("reading next (%v): %v", *startState.LastAUMHash, err) } curs := nextAUM @@ -293,9 +295,9 @@ func computeStateAt(storage Chonk, maxIter int, wantHash AUMHash) (State, error) } // If we got here, the current state is dependent on the previous. - // Keep iterating backwards till thats not the case. + // Keep iterating backwards till that's not the case. if curs, err = storage.AUM(parent); err != nil { - return State{}, fmt.Errorf("reading parent: %v", err) + return State{}, fmt.Errorf("reading parent (%v): %v", parent, err) } } @@ -322,7 +324,7 @@ func computeStateAt(storage Chonk, maxIter int, wantHash AUMHash) (State, error) return curs.Hash() == wantHash }) // fastForward only terminates before the done condition if it - // doesnt have any later AUMs to process. This cant be the case + // doesn't have any later AUMs to process. This can't be the case // as we've already iterated through them above so they must exist, // but we check anyway to be super duper sure. if err == nil && *state.LastAUMHash != wantHash { @@ -334,13 +336,13 @@ func computeStateAt(storage Chonk, maxIter int, wantHash AUMHash) (State, error) // computeActiveAncestor determines which ancestor AUM to use as the // ancestor of the valid chain. // -// If all the chains end up having the same ancestor, then thats the +// If all the chains end up having the same ancestor, then that's the // only possible ancestor, ezpz. However if there are multiple distinct // ancestors, that means there are distinct chains, and we need some // hint to choose what to use. For that, we rely on the chainsThroughActive // bit, which signals to us that that ancestor was part of the // chain in a previous run. -func computeActiveAncestor(storage Chonk, chains []chain) (AUMHash, error) { +func computeActiveAncestor(chains []chain) (AUMHash, error) { // Dedupe possible ancestors, tracking if they were part of // the active chain on a previous run. ancestors := make(map[AUMHash]bool, len(chains)) @@ -355,7 +357,7 @@ func computeActiveAncestor(storage Chonk, chains []chain) (AUMHash, error) { } } - // Theres more than one, so we need to use the ancestor that was + // There's more than one, so we need to use the ancestor that was // part of the active chain in a previous iteration. // Note that there can only be one distinct ancestor that was // formerly part of the active chain, because AUMs can only have @@ -389,8 +391,12 @@ func computeActiveChain(storage Chonk, lastKnownOldest *AUMHash, maxIter int) (c return chain{}, fmt.Errorf("computing candidates: %v", err) } + if len(chains) == 0 { + return chain{}, errors.New("no chain candidates in AUM storage") + } + // Find the right ancestor. - oldestHash, err := computeActiveAncestor(storage, chains) + oldestHash, err := computeActiveAncestor(chains) if err != nil { return chain{}, fmt.Errorf("computing ancestor: %v", err) } @@ -440,6 +446,13 @@ func aumVerify(aum AUM, state State, isGenesisAUM bool) error { return fmt.Errorf("signature %d: %v", i, err) } } + + if aum.MessageKind == AUMRemoveKey && len(state.Keys) == 1 { + if kid, err := state.Keys[0].ID(); err == nil && bytes.Equal(aum.KeyID, kid) { + return errors.New("cannot remove the last key in the state") + } + } + return nil } @@ -466,7 +479,7 @@ func (a *Authority) Head() AUMHash { // Open initializes an existing TKA from the given tailchonk. // // Only use this if the current node has initialized an Authority before. -// If a TKA exists on other nodes but theres nothing locally, use Bootstrap(). +// If a TKA exists on other nodes but there's nothing locally, use Bootstrap(). // If no TKA exists anywhere and you are creating it for the first // time, use New(). func Open(storage Chonk) (*Authority, error) { @@ -579,14 +592,14 @@ func (a *Authority) InformIdempotent(storage Chonk, updates []AUM) (Authority, e toCommit := make([]AUM, 0, len(updates)) prevHash := a.Head() - // The state at HEAD is the current state of the authority. Its likely + // The state at HEAD is the current state of the authority. It's likely // to be needed, so we prefill it rather than computing it. stateAt[prevHash] = a.state // Optimization: If the set of updates is a chain building from // the current head, EG: // ==> updates[0] ==> updates[1] ... - // Then theres no need to recompute the resulting state from the + // Then there's no need to recompute the resulting state from the // stored ancestor, because the last state computed during iteration // is the new state. This should be the common case. // isHeadChain keeps track of this. @@ -766,8 +779,8 @@ func (a *Authority) findParentForRewrite(storage Chonk, removeKeys []tkatype.Key } } if !keyTrusted { - // Success: the revoked keys are not trusted! - // Lets check that our key was trusted to ensure + // Success: the revoked keys are not trusted. + // Check that our key was trusted to ensure // we can sign a fork from here. if _, err := state.GetKey(ourKey); err == nil { break diff --git a/vendor/tailscale.com/tka/verify.go b/vendor/tailscale.com/tka/verify.go new file mode 100644 index 0000000..ed0ecea --- /dev/null +++ b/vendor/tailscale.com/tka/verify.go @@ -0,0 +1,36 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_tailnetlock + +package tka + +import ( + "crypto/ed25519" + "errors" + "fmt" + + "github.com/hdevalence/ed25519consensus" + "tailscale.com/types/tkatype" +) + +// signatureVerify returns a nil error if the signature is valid over the +// provided AUM BLAKE2s digest, using the given key. +func signatureVerify(s *tkatype.Signature, aumDigest tkatype.AUMSigHash, key Key) error { + // NOTE(tom): Even if we can compute the public from the KeyID, + // it's possible for the KeyID to be attacker-controlled + // so we should use the public contained in the state machine. + switch key.Kind { + case Key25519: + if len(key.Public) != ed25519.PublicKeySize { + return fmt.Errorf("ed25519 key has wrong length: %d", len(key.Public)) + } + if ed25519consensus.Verify(ed25519.PublicKey(key.Public), aumDigest[:], s.Signature) { + return nil + } + return errors.New("invalid signature") + + default: + return fmt.Errorf("unhandled key type: %v", key.Kind) + } +} diff --git a/vendor/tailscale.com/tka/verify_disabled.go b/vendor/tailscale.com/tka/verify_disabled.go new file mode 100644 index 0000000..ba72f93 --- /dev/null +++ b/vendor/tailscale.com/tka/verify_disabled.go @@ -0,0 +1,18 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_tailnetlock + +package tka + +import ( + "errors" + + "tailscale.com/types/tkatype" +) + +// signatureVerify returns a nil error if the signature is valid over the +// provided AUM BLAKE2s digest, using the given key. +func signatureVerify(s *tkatype.Signature, aumDigest tkatype.AUMSigHash, key Key) error { + return errors.New("tailnetlock disabled in build") +} diff --git a/vendor/tailscale.com/tsconst/health.go b/vendor/tailscale.com/tsconst/health.go new file mode 100644 index 0000000..5db9b1f --- /dev/null +++ b/vendor/tailscale.com/tsconst/health.go @@ -0,0 +1,26 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsconst + +const ( + HealthWarnableUpdateAvailable = "update-available" + HealthWarnableSecurityUpdateAvailable = "security-update-available" + HealthWarnableIsUsingUnstableVersion = "is-using-unstable-version" + HealthWarnableNetworkStatus = "network-status" + HealthWarnableWantRunningFalse = "wantrunning-false" + HealthWarnableLocalLogConfigError = "local-log-config-error" + HealthWarnableLoginState = "login-state" + HealthWarnableNotInMapPoll = "not-in-map-poll" + HealthWarnableNoDERPHome = "no-derp-home" + HealthWarnableNoDERPConnection = "no-derp-connection" + HealthWarnableDERPTimedOut = "derp-timed-out" + HealthWarnableDERPRegionError = "derp-region-error" + HealthWarnableNoUDP4Bind = "no-udp4-bind" + HealthWarnableMapResponseTimeout = "mapresponse-timeout" + HealthWarnableTLSConnectionFailed = "tls-connection-failed" + HealthWarnableMagicsockReceiveFuncError = "magicsock-receive-func-error" + HealthWarnableTestWarnable = "test-warnable" + HealthWarnableApplyDiskConfig = "apply-disk-config" + HealthWarnableWarmingUp = "warming-up" +) diff --git a/vendor/tailscale.com/tsconst/linuxfw.go b/vendor/tailscale.com/tsconst/linuxfw.go new file mode 100644 index 0000000..ce571e4 --- /dev/null +++ b/vendor/tailscale.com/tsconst/linuxfw.go @@ -0,0 +1,43 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsconst + +// Linux firewall constants used by Tailscale. + +// The following bits are added to packet marks for Tailscale use. +// +// We tried to pick bits sufficiently out of the way that it's +// unlikely to collide with existing uses. We have 4 bytes of mark +// bits to play with. We leave the lower byte alone on the assumption +// that sysadmins would use those. Kubernetes uses a few bits in the +// second byte, so we steer clear of that too. +// +// Empirically, most of the documentation on packet marks on the +// internet gives the impression that the marks are 16 bits +// wide. Based on this, we theorize that the upper two bytes are +// relatively unused in the wild, and so we consume bits 16:23 (the +// third byte). +// +// The constants are in the iptables/iproute2 string format for +// matching and setting the bits, so they can be directly embedded in +// commands. +const ( + // The mask for reading/writing the 'firewall mask' bits on a packet. + // See the comment on the const block on why we only use the third byte. + // + // We claim bits 16:23 entirely. For now we only use the lower four + // bits, leaving the higher 4 bits for future use. + LinuxFwmarkMask = "0xff0000" + LinuxFwmarkMaskNum = 0xff0000 + + // Packet is from Tailscale and to a subnet route destination, so + // is allowed to be routed through this machine. + LinuxSubnetRouteMark = "0x40000" + LinuxSubnetRouteMarkNum = 0x40000 + + // Packet was originated by tailscaled itself, and must not be + // routed over the Tailscale network. + LinuxBypassMark = "0x80000" + LinuxBypassMarkNum = 0x80000 +) diff --git a/vendor/tailscale.com/tsconst/interface.go b/vendor/tailscale.com/tsconst/tsconst.go similarity index 100% rename from vendor/tailscale.com/tsconst/interface.go rename to vendor/tailscale.com/tsconst/tsconst.go diff --git a/vendor/tailscale.com/tsconst/webclient.go b/vendor/tailscale.com/tsconst/webclient.go new file mode 100644 index 0000000..d4b3c8d --- /dev/null +++ b/vendor/tailscale.com/tsconst/webclient.go @@ -0,0 +1,9 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsconst + +// WebListenPort is the static port used for the web client when run inside +// tailscaled. (5252 are the numbers above the letters "TSTS" on a qwerty +// keyboard.) +const WebListenPort = 5252 diff --git a/vendor/tailscale.com/tsd/tsd.go b/vendor/tailscale.com/tsd/tsd.go index 9ab35af..8dc0c14 100644 --- a/vendor/tailscale.com/tsd/tsd.go +++ b/vendor/tailscale.com/tsd/tsd.go @@ -25,15 +25,15 @@ import ( "tailscale.com/drive" "tailscale.com/health" "tailscale.com/ipn" - "tailscale.com/ipn/auditlog" "tailscale.com/ipn/conffile" - "tailscale.com/ipn/desktop" "tailscale.com/net/dns" "tailscale.com/net/netmon" "tailscale.com/net/tsdial" "tailscale.com/net/tstun" "tailscale.com/proxymap" "tailscale.com/types/netmap" + "tailscale.com/util/eventbus" + "tailscale.com/util/syspolicy/policyclient" "tailscale.com/util/usermetric" "tailscale.com/wgengine" "tailscale.com/wgengine/magicsock" @@ -41,7 +41,12 @@ import ( ) // System contains all the subsystems of a Tailscale node (tailscaled, etc.) +// +// A valid System value must always have a non-nil Bus populated. Callers must +// ensure this before using the value further. Call [NewSystem] to obtain a +// value ready to use. type System struct { + Bus SubSystem[*eventbus.Bus] Dialer SubSystem[*tsdial.Dialer] DNSManager SubSystem[*dns.Manager] // can get its *resolver.Resolver from DNSManager.Resolver Engine SubSystem[wgengine.Engine] @@ -51,11 +56,11 @@ type System struct { Router SubSystem[router.Router] Tun SubSystem[*tstun.Wrapper] StateStore SubSystem[ipn.StateStore] - AuditLogStore SubSystem[auditlog.LogStore] Netstack SubSystem[NetstackImpl] // actually a *netstack.Impl DriveForLocal SubSystem[drive.FileSystemForLocal] DriveForRemote SubSystem[drive.FileSystemForRemote] - SessionManager SubSystem[desktop.SessionManager] + PolicyClient SubSystem[policyclient.Client] + HealthTracker SubSystem[*health.Tracker] // InitialConfig is initial server config, if any. // It is nil if the node is not in declarative mode. @@ -63,6 +68,10 @@ type System struct { // LocalBackend tracks the current config after any reloads. InitialConfig *conffile.Config + // SocketPath is the path to the tailscaled Unix socket. + // It is used to prevent serve from proxying to our own socket. + SocketPath string + // onlyNetstack is whether the Tun value is a fake TUN device // and we're using netstack for everything. onlyNetstack bool @@ -70,14 +79,37 @@ type System struct { controlKnobs controlknobs.Knobs proxyMap proxymap.Mapper - healthTracker health.Tracker userMetricsRegistry usermetric.Registry } +// NewSystem constructs a new otherwise-empty [System] with a +// freshly-constructed event bus populated. +func NewSystem() *System { return NewSystemWithBus(eventbus.New()) } + +// NewSystemWithBus constructs a new otherwise-empty [System] with an +// eventbus provided by the caller. The provided bus must not be nil. +// This is mainly intended for testing; for production use call [NewBus]. +func NewSystemWithBus(bus *eventbus.Bus) *System { + if bus == nil { + panic("nil eventbus") + } + sys := new(System) + sys.Set(bus) + + tracker := health.NewTracker(bus) + sys.Set(tracker) + + return sys +} + +// LocalBackend is a fake name for *ipnlocal.LocalBackend to avoid an import cycle. +type LocalBackend = any + // NetstackImpl is the interface that *netstack.Impl implements. // It's an interface for circular dependency reasons: netstack.Impl // references LocalBackend, and LocalBackend has a tsd.System. type NetstackImpl interface { + Start(LocalBackend) error UpdateNetstackIPs(*netmap.NetworkMap) } @@ -86,6 +118,8 @@ type NetstackImpl interface { // has already been set. func (s *System) Set(v any) { switch v := v.(type) { + case *eventbus.Bus: + s.Bus.Set(v) case *netmon.Monitor: s.NetMon.Set(v) case *dns.Manager: @@ -108,16 +142,16 @@ func (s *System) Set(v any) { s.MagicSock.Set(v) case ipn.StateStore: s.StateStore.Set(v) - case auditlog.LogStore: - s.AuditLogStore.Set(v) case NetstackImpl: s.Netstack.Set(v) case drive.FileSystemForLocal: s.DriveForLocal.Set(v) case drive.FileSystemForRemote: s.DriveForRemote.Set(v) - case desktop.SessionManager: - s.SessionManager.Set(v) + case policyclient.Client: + s.PolicyClient.Set(v) + case *health.Tracker: + s.HealthTracker.Set(v) default: panic(fmt.Sprintf("unknown type %T", v)) } @@ -147,16 +181,20 @@ func (s *System) ProxyMapper() *proxymap.Mapper { return &s.proxyMap } -// HealthTracker returns the system health tracker. -func (s *System) HealthTracker() *health.Tracker { - return &s.healthTracker -} - // UserMetricsRegistry returns the system usermetrics. func (s *System) UserMetricsRegistry() *usermetric.Registry { return &s.userMetricsRegistry } +// PolicyClientOrDefault returns the policy client if set or a no-op default +// otherwise. It always returns a non-nil value. +func (s *System) PolicyClientOrDefault() policyclient.Client { + if client, ok := s.PolicyClient.GetOK(); ok { + return client + } + return policyclient.Get() +} + // SubSystem represents some subsystem of the Tailscale node daemon. // // A subsystem can be set to a value, and then later retrieved. A subsystem diff --git a/vendor/tailscale.com/tsnet/depaware.txt b/vendor/tailscale.com/tsnet/depaware.txt new file mode 100644 index 0000000..5b08200 --- /dev/null +++ b/vendor/tailscale.com/tsnet/depaware.txt @@ -0,0 +1,652 @@ +tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware) + + filippo.io/edwards25519 from github.com/hdevalence/ed25519consensus + filippo.io/edwards25519/field from filippo.io/edwards25519 + W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/internal/common+ + W github.com/alexbrainman/sspi/internal/common from github.com/alexbrainman/sspi/negotiate + W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy + github.com/aws/aws-sdk-go-v2/aws from github.com/aws/aws-sdk-go-v2/aws/defaults+ + github.com/aws/aws-sdk-go-v2/aws/defaults from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/aws/middleware from github.com/aws/aws-sdk-go-v2/aws/retry+ + github.com/aws/aws-sdk-go-v2/aws/protocol/query from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/aws-sdk-go-v2/aws/protocol/restjson from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/aws/protocol/xml from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/aws-sdk-go-v2/aws/ratelimit from github.com/aws/aws-sdk-go-v2/aws/retry + github.com/aws/aws-sdk-go-v2/aws/retry from github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client+ + github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4 from github.com/aws/aws-sdk-go-v2/aws/signer/v4 + github.com/aws/aws-sdk-go-v2/aws/signer/v4 from github.com/aws/aws-sdk-go-v2/internal/auth/smithy+ + github.com/aws/aws-sdk-go-v2/aws/transport/http from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/config from tailscale.com/wif + github.com/aws/aws-sdk-go-v2/credentials from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/credentials/endpointcreds from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client from github.com/aws/aws-sdk-go-v2/credentials/endpointcreds + github.com/aws/aws-sdk-go-v2/credentials/processcreds from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/credentials/ssocreds from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/credentials/stscreds from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/feature/ec2/imds from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config from github.com/aws/aws-sdk-go-v2/feature/ec2/imds + github.com/aws/aws-sdk-go-v2/internal/auth from github.com/aws/aws-sdk-go-v2/aws/signer/v4+ + github.com/aws/aws-sdk-go-v2/internal/auth/smithy from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/internal/configsources from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/internal/context from github.com/aws/aws-sdk-go-v2/aws/retry+ + github.com/aws/aws-sdk-go-v2/internal/endpoints from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 from github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints+ + github.com/aws/aws-sdk-go-v2/internal/ini from github.com/aws/aws-sdk-go-v2/config + github.com/aws/aws-sdk-go-v2/internal/middleware from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/aws-sdk-go-v2/internal/rand from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/aws-sdk-go-v2/internal/sdk from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/aws-sdk-go-v2/internal/sdkio from github.com/aws/aws-sdk-go-v2/credentials/processcreds + github.com/aws/aws-sdk-go-v2/internal/shareddefaults from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/internal/strings from github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4 + github.com/aws/aws-sdk-go-v2/internal/sync/singleflight from github.com/aws/aws-sdk-go-v2/aws + github.com/aws/aws-sdk-go-v2/internal/timeconv from github.com/aws/aws-sdk-go-v2/aws/retry + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/aws-sdk-go-v2/service/sso from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints from github.com/aws/aws-sdk-go-v2/service/sso + github.com/aws/aws-sdk-go-v2/service/sso/types from github.com/aws/aws-sdk-go-v2/service/sso + github.com/aws/aws-sdk-go-v2/service/ssooidc from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints from github.com/aws/aws-sdk-go-v2/service/ssooidc + github.com/aws/aws-sdk-go-v2/service/ssooidc/types from github.com/aws/aws-sdk-go-v2/service/ssooidc + github.com/aws/aws-sdk-go-v2/service/sts from github.com/aws/aws-sdk-go-v2/config+ + github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/aws-sdk-go-v2/service/sts/types from github.com/aws/aws-sdk-go-v2/credentials/stscreds+ + github.com/aws/smithy-go from github.com/aws/aws-sdk-go-v2/aws/protocol/restjson+ + github.com/aws/smithy-go/auth from github.com/aws/aws-sdk-go-v2/internal/auth+ + github.com/aws/smithy-go/auth/bearer from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/smithy-go/context from github.com/aws/smithy-go/auth/bearer + github.com/aws/smithy-go/document from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/smithy-go/encoding from github.com/aws/smithy-go/encoding/json+ + github.com/aws/smithy-go/encoding/httpbinding from github.com/aws/aws-sdk-go-v2/aws/protocol/query+ + github.com/aws/smithy-go/encoding/json from github.com/aws/aws-sdk-go-v2/service/ssooidc + github.com/aws/smithy-go/encoding/xml from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/smithy-go/endpoints from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/smithy-go/endpoints/private/rulesfn from github.com/aws/aws-sdk-go-v2/service/sts + github.com/aws/smithy-go/internal/sync/singleflight from github.com/aws/smithy-go/auth/bearer + github.com/aws/smithy-go/io from github.com/aws/aws-sdk-go-v2/feature/ec2/imds+ + github.com/aws/smithy-go/logging from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/smithy-go/metrics from github.com/aws/aws-sdk-go-v2/aws/retry+ + github.com/aws/smithy-go/middleware from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/smithy-go/private/requestcompression from github.com/aws/aws-sdk-go-v2/config + github.com/aws/smithy-go/ptr from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/smithy-go/rand from github.com/aws/aws-sdk-go-v2/aws/middleware + github.com/aws/smithy-go/time from github.com/aws/aws-sdk-go-v2/service/sso+ + github.com/aws/smithy-go/tracing from github.com/aws/aws-sdk-go-v2/aws/middleware+ + github.com/aws/smithy-go/transport/http from github.com/aws/aws-sdk-go-v2/aws+ + github.com/aws/smithy-go/transport/http/internal/io from github.com/aws/smithy-go/transport/http + LDW github.com/coder/websocket from tailscale.com/util/eventbus + LDW github.com/coder/websocket/internal/errd from github.com/coder/websocket + LDW github.com/coder/websocket/internal/util from github.com/coder/websocket + LDW github.com/coder/websocket/internal/xsync from github.com/coder/websocket + github.com/creachadair/msync/trigger from tailscale.com/logtail + W 💣 github.com/dblohm7/wingoes from tailscale.com/net/tshttpproxy+ + W 💣 github.com/dblohm7/wingoes/com from tailscale.com/util/osdiag+ + W 💣 github.com/dblohm7/wingoes/com/automation from tailscale.com/util/osdiag/internal/wsc + W github.com/dblohm7/wingoes/internal from github.com/dblohm7/wingoes/com + W 💣 github.com/dblohm7/wingoes/pe from tailscale.com/util/osdiag+ + github.com/fxamacker/cbor/v2 from tailscale.com/tka + github.com/gaissmai/bart from tailscale.com/net/ipset+ + github.com/gaissmai/bart/internal/bitset from github.com/gaissmai/bart+ + github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart + github.com/go-json-experiment/json from tailscale.com/types/opt+ + github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+ + github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+ + github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+ + github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+ + github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+ + L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns + github.com/golang/groupcache/lru from tailscale.com/net/dnscache + github.com/google/btree from gvisor.dev/gvisor/pkg/tcpip/header+ + DI github.com/google/uuid from github.com/prometheus-community/pro-bing + github.com/hdevalence/ed25519consensus from tailscale.com/tka + github.com/huin/goupnp from github.com/huin/goupnp/dcps/internetgateway2+ + github.com/huin/goupnp/dcps/internetgateway2 from tailscale.com/net/portmapper + github.com/huin/goupnp/httpu from github.com/huin/goupnp+ + github.com/huin/goupnp/scpd from github.com/huin/goupnp + github.com/huin/goupnp/soap from github.com/huin/goupnp+ + github.com/huin/goupnp/ssdp from github.com/huin/goupnp + L 💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/netmon + L github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink + github.com/klauspost/compress from github.com/klauspost/compress/zstd + github.com/klauspost/compress/fse from github.com/klauspost/compress/huff0 + github.com/klauspost/compress/huff0 from github.com/klauspost/compress/zstd + github.com/klauspost/compress/internal/cpuinfo from github.com/klauspost/compress/huff0+ + 💣 github.com/klauspost/compress/internal/le from github.com/klauspost/compress/huff0+ + github.com/klauspost/compress/internal/snapref from github.com/klauspost/compress/zstd + github.com/klauspost/compress/zstd from tailscale.com/util/zstdframe + github.com/klauspost/compress/zstd/internal/xxhash from github.com/klauspost/compress/zstd + L 💣 github.com/mdlayher/netlink from github.com/jsimonetti/rtnetlink+ + L 💣 github.com/mdlayher/netlink/nlenc from github.com/jsimonetti/rtnetlink+ + LA 💣 github.com/mdlayher/socket from github.com/mdlayher/netlink+ + LDW 💣 github.com/mitchellh/go-ps from tailscale.com/safesocket + github.com/pires/go-proxyproto from tailscale.com/ipn/ipnlocal + DI github.com/prometheus-community/pro-bing from tailscale.com/wgengine/netstack + L 💣 github.com/safchain/ethtool from tailscale.com/net/netkernelconf + W 💣 github.com/tailscale/certstore from tailscale.com/control/controlclient + W 💣 github.com/tailscale/go-winio from tailscale.com/safesocket + W 💣 github.com/tailscale/go-winio/internal/fs from github.com/tailscale/go-winio + W 💣 github.com/tailscale/go-winio/internal/socket from github.com/tailscale/go-winio + W github.com/tailscale/go-winio/internal/stringbuffer from github.com/tailscale/go-winio/internal/fs + W github.com/tailscale/go-winio/pkg/guid from github.com/tailscale/go-winio+ + LDW github.com/tailscale/hujson from tailscale.com/ipn/conffile + LDAI github.com/tailscale/peercred from tailscale.com/ipn/ipnauth + LDW github.com/tailscale/web-client-prebuilt from tailscale.com/client/web + 💣 github.com/tailscale/wireguard-go/conn from github.com/tailscale/wireguard-go/device+ + W 💣 github.com/tailscale/wireguard-go/conn/winrio from github.com/tailscale/wireguard-go/conn + 💣 github.com/tailscale/wireguard-go/device from tailscale.com/net/tstun+ + 💣 github.com/tailscale/wireguard-go/ipc from github.com/tailscale/wireguard-go/device + W 💣 github.com/tailscale/wireguard-go/ipc/namedpipe from github.com/tailscale/wireguard-go/ipc + github.com/tailscale/wireguard-go/ratelimiter from github.com/tailscale/wireguard-go/device + github.com/tailscale/wireguard-go/replay from github.com/tailscale/wireguard-go/device + github.com/tailscale/wireguard-go/rwcancel from github.com/tailscale/wireguard-go/device+ + github.com/tailscale/wireguard-go/tai64n from github.com/tailscale/wireguard-go/device + 💣 github.com/tailscale/wireguard-go/tun from github.com/tailscale/wireguard-go/device+ + github.com/x448/float16 from github.com/fxamacker/cbor/v2 + 💣 go4.org/mem from tailscale.com/client/local+ + go4.org/netipx from tailscale.com/ipn/ipnlocal+ + W 💣 golang.zx2c4.com/wintun from github.com/tailscale/wireguard-go/tun + W 💣 golang.zx2c4.com/wireguard/windows/tunnel/winipcfg from tailscale.com/net/dns+ + gvisor.dev/gvisor/pkg/atomicbitops from gvisor.dev/gvisor/pkg/buffer+ + gvisor.dev/gvisor/pkg/bits from gvisor.dev/gvisor/pkg/buffer + 💣 gvisor.dev/gvisor/pkg/buffer from gvisor.dev/gvisor/pkg/tcpip+ + gvisor.dev/gvisor/pkg/context from gvisor.dev/gvisor/pkg/refs + 💣 gvisor.dev/gvisor/pkg/gohacks from gvisor.dev/gvisor/pkg/state/wire+ + gvisor.dev/gvisor/pkg/linewriter from gvisor.dev/gvisor/pkg/log + gvisor.dev/gvisor/pkg/log from gvisor.dev/gvisor/pkg/context+ + gvisor.dev/gvisor/pkg/rand from gvisor.dev/gvisor/pkg/tcpip+ + gvisor.dev/gvisor/pkg/refs from gvisor.dev/gvisor/pkg/buffer+ + 💣 gvisor.dev/gvisor/pkg/sleep from gvisor.dev/gvisor/pkg/tcpip/transport/tcp + 💣 gvisor.dev/gvisor/pkg/state from gvisor.dev/gvisor/pkg/atomicbitops+ + gvisor.dev/gvisor/pkg/state/wire from gvisor.dev/gvisor/pkg/state + 💣 gvisor.dev/gvisor/pkg/sync from gvisor.dev/gvisor/pkg/atomicbitops+ + 💣 gvisor.dev/gvisor/pkg/sync/locking from gvisor.dev/gvisor/pkg/tcpip/stack + gvisor.dev/gvisor/pkg/tcpip from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+ + gvisor.dev/gvisor/pkg/tcpip/adapters/gonet from tailscale.com/wgengine/netstack + 💣 gvisor.dev/gvisor/pkg/tcpip/checksum from gvisor.dev/gvisor/pkg/buffer+ + gvisor.dev/gvisor/pkg/tcpip/hash/jenkins from gvisor.dev/gvisor/pkg/tcpip/stack+ + gvisor.dev/gvisor/pkg/tcpip/header from gvisor.dev/gvisor/pkg/tcpip/header/parse+ + gvisor.dev/gvisor/pkg/tcpip/header/parse from gvisor.dev/gvisor/pkg/tcpip/network/ipv4+ + gvisor.dev/gvisor/pkg/tcpip/internal/tcp from gvisor.dev/gvisor/pkg/tcpip/transport/tcp + gvisor.dev/gvisor/pkg/tcpip/network/hash from gvisor.dev/gvisor/pkg/tcpip/network/ipv4 + gvisor.dev/gvisor/pkg/tcpip/network/internal/fragmentation from gvisor.dev/gvisor/pkg/tcpip/network/ipv4+ + gvisor.dev/gvisor/pkg/tcpip/network/internal/ip from gvisor.dev/gvisor/pkg/tcpip/network/ipv4+ + gvisor.dev/gvisor/pkg/tcpip/network/internal/multicast from gvisor.dev/gvisor/pkg/tcpip/network/ipv4+ + gvisor.dev/gvisor/pkg/tcpip/network/ipv4 from tailscale.com/wgengine/netstack + gvisor.dev/gvisor/pkg/tcpip/network/ipv6 from tailscale.com/wgengine/netstack + gvisor.dev/gvisor/pkg/tcpip/ports from gvisor.dev/gvisor/pkg/tcpip/stack+ + gvisor.dev/gvisor/pkg/tcpip/seqnum from gvisor.dev/gvisor/pkg/tcpip/header+ + 💣 gvisor.dev/gvisor/pkg/tcpip/stack from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+ + LDWA gvisor.dev/gvisor/pkg/tcpip/stack/gro from tailscale.com/wgengine/netstack/gro + gvisor.dev/gvisor/pkg/tcpip/transport from gvisor.dev/gvisor/pkg/tcpip/transport/icmp+ + gvisor.dev/gvisor/pkg/tcpip/transport/icmp from tailscale.com/wgengine/netstack + gvisor.dev/gvisor/pkg/tcpip/transport/internal/network from gvisor.dev/gvisor/pkg/tcpip/transport/icmp+ + gvisor.dev/gvisor/pkg/tcpip/transport/internal/noop from gvisor.dev/gvisor/pkg/tcpip/transport/raw + gvisor.dev/gvisor/pkg/tcpip/transport/packet from gvisor.dev/gvisor/pkg/tcpip/transport/raw + gvisor.dev/gvisor/pkg/tcpip/transport/raw from gvisor.dev/gvisor/pkg/tcpip/transport/icmp+ + 💣 gvisor.dev/gvisor/pkg/tcpip/transport/tcp from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+ + gvisor.dev/gvisor/pkg/tcpip/transport/tcpconntrack from gvisor.dev/gvisor/pkg/tcpip/stack + gvisor.dev/gvisor/pkg/tcpip/transport/udp from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+ + gvisor.dev/gvisor/pkg/waiter from gvisor.dev/gvisor/pkg/context+ + tailscale.com from tailscale.com/version + tailscale.com/appc from tailscale.com/ipn/ipnlocal + 💣 tailscale.com/atomicfile from tailscale.com/ipn+ + tailscale.com/client/local from tailscale.com/client/web+ + tailscale.com/client/tailscale from tailscale.com/internal/client/tailscale + tailscale.com/client/tailscale/apitype from tailscale.com/client/local+ + LDW tailscale.com/client/web from tailscale.com/ipn/ipnlocal + tailscale.com/control/controlbase from tailscale.com/control/controlhttp+ + tailscale.com/control/controlclient from tailscale.com/ipn/ipnext+ + tailscale.com/control/controlhttp from tailscale.com/control/ts2021 + tailscale.com/control/controlhttp/controlhttpcommon from tailscale.com/control/controlhttp + tailscale.com/control/controlknobs from tailscale.com/control/controlclient+ + tailscale.com/control/ts2021 from tailscale.com/control/controlclient + tailscale.com/derp from tailscale.com/derp/derphttp+ + tailscale.com/derp/derpconst from tailscale.com/derp/derphttp+ + tailscale.com/derp/derphttp from tailscale.com/ipn/localapi+ + tailscale.com/disco from tailscale.com/net/tstun+ + tailscale.com/drive from tailscale.com/client/local+ + tailscale.com/envknob from tailscale.com/client/local+ + tailscale.com/envknob/featureknob from tailscale.com/client/web+ + tailscale.com/feature from tailscale.com/ipn/ipnext+ + tailscale.com/feature/buildfeatures from tailscale.com/wgengine/magicsock+ + tailscale.com/feature/c2n from tailscale.com/tsnet + tailscale.com/feature/condlite/expvar from tailscale.com/wgengine/magicsock + tailscale.com/feature/condregister/identityfederation from tailscale.com/tsnet + tailscale.com/feature/condregister/oauthkey from tailscale.com/tsnet + tailscale.com/feature/condregister/portmapper from tailscale.com/tsnet + tailscale.com/feature/condregister/useproxy from tailscale.com/tsnet + tailscale.com/feature/identityfederation from tailscale.com/feature/condregister/identityfederation + tailscale.com/feature/oauthkey from tailscale.com/feature/condregister/oauthkey + tailscale.com/feature/portmapper from tailscale.com/feature/condregister/portmapper + tailscale.com/feature/syspolicy from tailscale.com/logpolicy + tailscale.com/feature/useproxy from tailscale.com/feature/condregister/useproxy + tailscale.com/health from tailscale.com/control/controlclient+ + tailscale.com/health/healthmsg from tailscale.com/ipn/ipnlocal+ + tailscale.com/hostinfo from tailscale.com/client/web+ + tailscale.com/internal/client/tailscale from tailscale.com/tsnet+ + tailscale.com/ipn from tailscale.com/client/local+ + tailscale.com/ipn/conffile from tailscale.com/ipn/ipnlocal+ + 💣 tailscale.com/ipn/ipnauth from tailscale.com/ipn/ipnext+ + tailscale.com/ipn/ipnext from tailscale.com/ipn/ipnlocal + tailscale.com/ipn/ipnlocal from tailscale.com/ipn/localapi+ + tailscale.com/ipn/ipnstate from tailscale.com/client/local+ + tailscale.com/ipn/localapi from tailscale.com/tsnet + tailscale.com/ipn/store from tailscale.com/ipn/ipnlocal+ + tailscale.com/ipn/store/mem from tailscale.com/ipn/ipnlocal+ + tailscale.com/kube/kubetypes from tailscale.com/envknob + LDW tailscale.com/licenses from tailscale.com/client/web + tailscale.com/log/filelogger from tailscale.com/logpolicy + tailscale.com/log/sockstatlog from tailscale.com/ipn/ipnlocal + tailscale.com/logpolicy from tailscale.com/ipn/ipnlocal+ + tailscale.com/logtail from tailscale.com/control/controlclient+ + tailscale.com/logtail/filch from tailscale.com/log/sockstatlog+ + tailscale.com/metrics from tailscale.com/tsweb+ + tailscale.com/net/bakedroots from tailscale.com/ipn/ipnlocal+ + 💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock + tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+ + tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+ + tailscale.com/net/dns/publicdns from tailscale.com/net/dns+ + tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+ + tailscale.com/net/dns/resolver from tailscale.com/net/dns+ + tailscale.com/net/dnscache from tailscale.com/control/controlclient+ + tailscale.com/net/dnsfallback from tailscale.com/control/controlclient+ + tailscale.com/net/flowtrack from tailscale.com/wgengine+ + tailscale.com/net/ipset from tailscale.com/ipn/ipnlocal+ + tailscale.com/net/memnet from tailscale.com/tsnet + tailscale.com/net/netaddr from tailscale.com/ipn+ + tailscale.com/net/netcheck from tailscale.com/ipn/ipnlocal+ + tailscale.com/net/neterror from tailscale.com/net/dns/resolver+ + tailscale.com/net/netkernelconf from tailscale.com/ipn/ipnlocal + tailscale.com/net/netknob from tailscale.com/logpolicy+ + 💣 tailscale.com/net/netmon from tailscale.com/control/controlclient+ + 💣 tailscale.com/net/netns from tailscale.com/derp/derphttp+ + tailscale.com/net/netutil from tailscale.com/client/local+ + tailscale.com/net/netx from tailscale.com/control/controlclient+ + tailscale.com/net/packet from tailscale.com/ipn/ipnlocal+ + tailscale.com/net/packet/checksum from tailscale.com/net/tstun + tailscale.com/net/ping from tailscale.com/net/netcheck+ + tailscale.com/net/portmapper from tailscale.com/feature/portmapper + tailscale.com/net/portmapper/portmappertype from tailscale.com/net/netcheck+ + tailscale.com/net/proxymux from tailscale.com/tsnet + 💣 tailscale.com/net/sockopts from tailscale.com/wgengine/magicsock + tailscale.com/net/socks5 from tailscale.com/tsnet + tailscale.com/net/sockstats from tailscale.com/control/controlclient+ + tailscale.com/net/stun from tailscale.com/ipn/localapi+ + tailscale.com/net/tlsdial from tailscale.com/control/controlclient+ + tailscale.com/net/tlsdial/blockblame from tailscale.com/net/tlsdial + tailscale.com/net/tsaddr from tailscale.com/client/web+ + tailscale.com/net/tsdial from tailscale.com/control/controlclient+ + 💣 tailscale.com/net/tshttpproxy from tailscale.com/feature/useproxy + tailscale.com/net/tstun from tailscale.com/tsd+ + tailscale.com/net/udprelay/endpoint from tailscale.com/wgengine/magicsock + tailscale.com/net/udprelay/status from tailscale.com/client/local + tailscale.com/omit from tailscale.com/ipn/conffile + tailscale.com/paths from tailscale.com/client/local+ + tailscale.com/proxymap from tailscale.com/tsd+ + 💣 tailscale.com/safesocket from tailscale.com/client/local+ + tailscale.com/syncs from tailscale.com/control/controlhttp+ + tailscale.com/tailcfg from tailscale.com/client/local+ + tailscale.com/tempfork/acme from tailscale.com/ipn/ipnlocal + tailscale.com/tempfork/heap from tailscale.com/wgengine/magicsock + tailscale.com/tempfork/httprec from tailscale.com/feature/c2n + tailscale.com/tka from tailscale.com/client/local+ + tailscale.com/tsconst from tailscale.com/ipn/ipnlocal+ + tailscale.com/tsd from tailscale.com/ipn/ipnext+ + tailscale.com/tstime from tailscale.com/control/controlclient+ + tailscale.com/tstime/mono from tailscale.com/net/tstun+ + tailscale.com/tstime/rate from tailscale.com/wgengine/filter + LDW tailscale.com/tsweb from tailscale.com/util/eventbus + tailscale.com/tsweb/varz from tailscale.com/tsweb+ + tailscale.com/types/appctype from tailscale.com/ipn/ipnlocal+ + tailscale.com/types/bools from tailscale.com/tsnet+ + tailscale.com/types/dnstype from tailscale.com/client/local+ + tailscale.com/types/empty from tailscale.com/ipn+ + tailscale.com/types/ipproto from tailscale.com/ipn+ + tailscale.com/types/key from tailscale.com/client/local+ + tailscale.com/types/lazy from tailscale.com/hostinfo+ + tailscale.com/types/logger from tailscale.com/appc+ + tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+ + tailscale.com/types/mapx from tailscale.com/ipn/ipnext + tailscale.com/types/netlogfunc from tailscale.com/net/tstun+ + tailscale.com/types/netlogtype from tailscale.com/wgengine/netlog + tailscale.com/types/netmap from tailscale.com/control/controlclient+ + tailscale.com/types/nettype from tailscale.com/ipn/localapi+ + tailscale.com/types/opt from tailscale.com/control/controlknobs+ + tailscale.com/types/persist from tailscale.com/control/controlclient+ + tailscale.com/types/preftype from tailscale.com/ipn+ + tailscale.com/types/ptr from tailscale.com/control/controlclient+ + tailscale.com/types/result from tailscale.com/util/lineiter + tailscale.com/types/structs from tailscale.com/control/controlclient+ + tailscale.com/types/tkatype from tailscale.com/client/local+ + tailscale.com/types/views from tailscale.com/appc+ + tailscale.com/util/backoff from tailscale.com/control/controlclient+ + tailscale.com/util/checkchange from tailscale.com/ipn/ipnlocal+ + tailscale.com/util/cibuild from tailscale.com/health+ + tailscale.com/util/clientmetric from tailscale.com/appc+ + tailscale.com/util/cloudenv from tailscale.com/hostinfo+ + tailscale.com/util/cloudinfo from tailscale.com/wgengine/magicsock + LW tailscale.com/util/cmpver from tailscale.com/net/dns+ + tailscale.com/util/ctxkey from tailscale.com/client/tailscale/apitype+ + 💣 tailscale.com/util/deephash from tailscale.com/util/syspolicy/setting + LA 💣 tailscale.com/util/dirwalk from tailscale.com/metrics + tailscale.com/util/dnsname from tailscale.com/appc+ + tailscale.com/util/eventbus from tailscale.com/client/local+ + tailscale.com/util/execqueue from tailscale.com/appc+ + tailscale.com/util/goroutines from tailscale.com/ipn/ipnlocal + tailscale.com/util/groupmember from tailscale.com/client/web+ + 💣 tailscale.com/util/hashx from tailscale.com/util/deephash + tailscale.com/util/httpm from tailscale.com/client/web+ + tailscale.com/util/lineiter from tailscale.com/hostinfo+ + tailscale.com/util/mak from tailscale.com/appc+ + tailscale.com/util/must from tailscale.com/logpolicy+ + tailscale.com/util/nocasemaps from tailscale.com/types/ipproto + 💣 tailscale.com/util/osdiag from tailscale.com/ipn/localapi + W 💣 tailscale.com/util/osdiag/internal/wsc from tailscale.com/util/osdiag + tailscale.com/util/osuser from tailscale.com/ipn/ipnlocal + tailscale.com/util/race from tailscale.com/net/dns/resolver + tailscale.com/util/racebuild from tailscale.com/logpolicy + tailscale.com/util/rands from tailscale.com/ipn/ipnlocal+ + tailscale.com/util/ringlog from tailscale.com/wgengine/magicsock + tailscale.com/util/set from tailscale.com/control/controlclient+ + tailscale.com/util/singleflight from tailscale.com/control/controlclient+ + tailscale.com/util/slicesx from tailscale.com/appc+ + tailscale.com/util/syspolicy from tailscale.com/feature/syspolicy + tailscale.com/util/syspolicy/internal from tailscale.com/util/syspolicy+ + tailscale.com/util/syspolicy/internal/loggerx from tailscale.com/util/syspolicy+ + tailscale.com/util/syspolicy/internal/metrics from tailscale.com/util/syspolicy/source + tailscale.com/util/syspolicy/pkey from tailscale.com/control/controlclient+ + tailscale.com/util/syspolicy/policyclient from tailscale.com/control/controlclient+ + tailscale.com/util/syspolicy/ptype from tailscale.com/util/syspolicy+ + tailscale.com/util/syspolicy/rsop from tailscale.com/ipn/localapi+ + tailscale.com/util/syspolicy/setting from tailscale.com/client/local+ + tailscale.com/util/syspolicy/source from tailscale.com/util/syspolicy+ + tailscale.com/util/testenv from tailscale.com/control/controlclient+ + tailscale.com/util/truncate from tailscale.com/logtail + tailscale.com/util/usermetric from tailscale.com/health+ + tailscale.com/util/vizerror from tailscale.com/tailcfg+ + 💣 tailscale.com/util/winutil from tailscale.com/hostinfo+ + W 💣 tailscale.com/util/winutil/authenticode from tailscale.com/util/osdiag + W 💣 tailscale.com/util/winutil/gp from tailscale.com/net/dns+ + W tailscale.com/util/winutil/policy from tailscale.com/ipn/ipnlocal + W 💣 tailscale.com/util/winutil/winenv from tailscale.com/hostinfo+ + tailscale.com/util/zstdframe from tailscale.com/control/controlclient+ + tailscale.com/version from tailscale.com/client/web+ + tailscale.com/version/distro from tailscale.com/client/web+ + tailscale.com/wgengine from tailscale.com/ipn/ipnlocal+ + tailscale.com/wgengine/filter from tailscale.com/control/controlclient+ + tailscale.com/wgengine/filter/filtertype from tailscale.com/types/netmap+ + 💣 tailscale.com/wgengine/magicsock from tailscale.com/ipn/ipnlocal+ + tailscale.com/wgengine/netlog from tailscale.com/wgengine + tailscale.com/wgengine/netstack from tailscale.com/tsnet + tailscale.com/wgengine/netstack/gro from tailscale.com/net/tstun+ + tailscale.com/wgengine/router from tailscale.com/ipn/ipnlocal+ + tailscale.com/wgengine/wgcfg from tailscale.com/ipn/ipnlocal+ + tailscale.com/wgengine/wgcfg/nmcfg from tailscale.com/ipn/ipnlocal + 💣 tailscale.com/wgengine/wgint from tailscale.com/wgengine+ + tailscale.com/wgengine/wglog from tailscale.com/wgengine + tailscale.com/wif from tailscale.com/feature/identityfederation + golang.org/x/crypto/argon2 from tailscale.com/tka + golang.org/x/crypto/blake2b from golang.org/x/crypto/argon2+ + golang.org/x/crypto/blake2s from github.com/tailscale/wireguard-go/device+ + LD golang.org/x/crypto/blowfish from golang.org/x/crypto/ssh/internal/bcrypt_pbkdf + golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305+ + golang.org/x/crypto/chacha20poly1305 from github.com/tailscale/wireguard-go/device+ + golang.org/x/crypto/curve25519 from github.com/tailscale/wireguard-go/device+ + golang.org/x/crypto/hkdf from tailscale.com/control/controlbase + golang.org/x/crypto/internal/alias from golang.org/x/crypto/chacha20+ + golang.org/x/crypto/internal/poly1305 from golang.org/x/crypto/chacha20poly1305+ + golang.org/x/crypto/nacl/box from tailscale.com/types/key + golang.org/x/crypto/nacl/secretbox from golang.org/x/crypto/nacl/box + golang.org/x/crypto/poly1305 from github.com/tailscale/wireguard-go/device + golang.org/x/crypto/salsa20/salsa from golang.org/x/crypto/nacl/box+ + LD golang.org/x/crypto/ssh from tailscale.com/ipn/ipnlocal + LD golang.org/x/crypto/ssh/internal/bcrypt_pbkdf from golang.org/x/crypto/ssh + golang.org/x/exp/constraints from tailscale.com/tsweb/varz+ + golang.org/x/exp/maps from tailscale.com/ipn/store/mem+ + golang.org/x/net/bpf from github.com/mdlayher/netlink+ + golang.org/x/net/dns/dnsmessage from tailscale.com/appc+ + golang.org/x/net/http/httpguts from tailscale.com/ipn/ipnlocal + golang.org/x/net/http/httpproxy from tailscale.com/net/tshttpproxy + golang.org/x/net/icmp from github.com/prometheus-community/pro-bing+ + golang.org/x/net/idna from golang.org/x/net/http/httpguts+ + golang.org/x/net/internal/iana from golang.org/x/net/icmp+ + golang.org/x/net/internal/socket from golang.org/x/net/icmp+ + LDW golang.org/x/net/internal/socks from golang.org/x/net/proxy + golang.org/x/net/ipv4 from github.com/prometheus-community/pro-bing+ + golang.org/x/net/ipv6 from github.com/prometheus-community/pro-bing+ + LDW golang.org/x/net/proxy from tailscale.com/net/netns + DI golang.org/x/net/route from tailscale.com/net/netmon+ + golang.org/x/oauth2 from golang.org/x/oauth2/clientcredentials+ + golang.org/x/oauth2/clientcredentials from tailscale.com/feature/oauthkey + golang.org/x/oauth2/internal from golang.org/x/oauth2+ + golang.org/x/sync/errgroup from github.com/mdlayher/socket+ + golang.org/x/sys/cpu from github.com/tailscale/certstore+ + LDAI golang.org/x/sys/unix from github.com/jsimonetti/rtnetlink/internal/unix+ + W golang.org/x/sys/windows from github.com/dblohm7/wingoes+ + W golang.org/x/sys/windows/registry from github.com/dblohm7/wingoes+ + W golang.org/x/sys/windows/svc from golang.org/x/sys/windows/svc/mgr+ + W golang.org/x/sys/windows/svc/mgr from tailscale.com/util/winutil + golang.org/x/term from tailscale.com/logpolicy + golang.org/x/text/secure/bidirule from golang.org/x/net/idna + golang.org/x/text/transform from golang.org/x/text/secure/bidirule+ + golang.org/x/text/unicode/bidi from golang.org/x/net/idna+ + golang.org/x/text/unicode/norm from golang.org/x/net/idna + golang.org/x/time/rate from gvisor.dev/gvisor/pkg/log+ + vendor/golang.org/x/crypto/chacha20 from vendor/golang.org/x/crypto/chacha20poly1305 + vendor/golang.org/x/crypto/chacha20poly1305 from crypto/internal/hpke+ + vendor/golang.org/x/crypto/cryptobyte from crypto/ecdsa+ + vendor/golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+ + vendor/golang.org/x/crypto/internal/alias from vendor/golang.org/x/crypto/chacha20+ + vendor/golang.org/x/crypto/internal/poly1305 from vendor/golang.org/x/crypto/chacha20poly1305 + vendor/golang.org/x/net/dns/dnsmessage from net + vendor/golang.org/x/net/http/httpguts from net/http+ + vendor/golang.org/x/net/http/httpproxy from net/http + vendor/golang.org/x/net/http2/hpack from net/http+ + vendor/golang.org/x/net/idna from net/http+ + vendor/golang.org/x/sys/cpu from vendor/golang.org/x/crypto/chacha20poly1305 + vendor/golang.org/x/text/secure/bidirule from vendor/golang.org/x/net/idna + vendor/golang.org/x/text/transform from vendor/golang.org/x/text/secure/bidirule+ + vendor/golang.org/x/text/unicode/bidi from vendor/golang.org/x/net/idna+ + vendor/golang.org/x/text/unicode/norm from vendor/golang.org/x/net/idna + bufio from compress/flate+ + bytes from bufio+ + cmp from encoding/json+ + compress/flate from compress/gzip+ + compress/gzip from internal/profile+ + W compress/zlib from debug/pe + container/heap from gvisor.dev/gvisor/pkg/tcpip/transport/tcp + container/list from crypto/tls+ + context from crypto/tls+ + crypto from crypto/ecdh+ + crypto/aes from crypto/internal/hpke+ + crypto/cipher from crypto/aes+ + crypto/des from crypto/tls+ + crypto/dsa from crypto/x509+ + crypto/ecdh from crypto/ecdsa+ + crypto/ecdsa from crypto/tls+ + crypto/ed25519 from crypto/tls+ + crypto/elliptic from crypto/ecdsa+ + crypto/fips140 from crypto/tls/internal/fips140tls+ + crypto/hkdf from crypto/internal/hpke+ + crypto/hmac from crypto/tls+ + crypto/internal/boring from crypto/aes+ + crypto/internal/boring/bbig from crypto/ecdsa+ + crypto/internal/boring/sig from crypto/internal/boring + crypto/internal/entropy from crypto/internal/fips140/drbg + crypto/internal/fips140 from crypto/internal/fips140/aes+ + crypto/internal/fips140/aes from crypto/aes+ + crypto/internal/fips140/aes/gcm from crypto/cipher+ + crypto/internal/fips140/alias from crypto/cipher+ + crypto/internal/fips140/bigmod from crypto/internal/fips140/ecdsa+ + crypto/internal/fips140/check from crypto/internal/fips140/aes+ + crypto/internal/fips140/drbg from crypto/internal/fips140/aes/gcm+ + crypto/internal/fips140/ecdh from crypto/ecdh + crypto/internal/fips140/ecdsa from crypto/ecdsa + crypto/internal/fips140/ed25519 from crypto/ed25519 + crypto/internal/fips140/edwards25519 from crypto/internal/fips140/ed25519 + crypto/internal/fips140/edwards25519/field from crypto/ecdh+ + crypto/internal/fips140/hkdf from crypto/internal/fips140/tls13+ + crypto/internal/fips140/hmac from crypto/hmac+ + crypto/internal/fips140/mlkem from crypto/tls+ + crypto/internal/fips140/nistec from crypto/elliptic+ + crypto/internal/fips140/nistec/fiat from crypto/internal/fips140/nistec + crypto/internal/fips140/rsa from crypto/rsa + crypto/internal/fips140/sha256 from crypto/internal/fips140/check+ + crypto/internal/fips140/sha3 from crypto/internal/fips140/hmac+ + crypto/internal/fips140/sha512 from crypto/internal/fips140/ecdsa+ + crypto/internal/fips140/subtle from crypto/internal/fips140/aes+ + crypto/internal/fips140/tls12 from crypto/tls + crypto/internal/fips140/tls13 from crypto/tls + crypto/internal/fips140cache from crypto/ecdsa+ + crypto/internal/fips140deps/byteorder from crypto/internal/fips140/aes+ + crypto/internal/fips140deps/cpu from crypto/internal/fips140/aes+ + crypto/internal/fips140deps/godebug from crypto/internal/fips140+ + crypto/internal/fips140hash from crypto/ecdsa+ + crypto/internal/fips140only from crypto/cipher+ + crypto/internal/hpke from crypto/tls + crypto/internal/impl from crypto/internal/fips140/aes+ + crypto/internal/randutil from crypto/dsa+ + crypto/internal/sysrand from crypto/internal/entropy+ + crypto/md5 from crypto/tls+ + LD crypto/mlkem from golang.org/x/crypto/ssh + crypto/rand from crypto/ed25519+ + crypto/rc4 from crypto/tls+ + crypto/rsa from crypto/tls+ + crypto/sha1 from crypto/tls+ + crypto/sha256 from crypto/tls+ + crypto/sha3 from crypto/internal/fips140hash + crypto/sha512 from crypto/ecdsa+ + crypto/subtle from crypto/cipher+ + crypto/tls from github.com/prometheus-community/pro-bing+ + crypto/tls/internal/fips140tls from crypto/tls + crypto/x509 from crypto/tls+ + DI crypto/x509/internal/macos from crypto/x509 + crypto/x509/pkix from crypto/x509+ + DI database/sql/driver from github.com/google/uuid + W debug/dwarf from debug/pe + W debug/pe from github.com/dblohm7/wingoes/pe + embed from github.com/tailscale/web-client-prebuilt+ + encoding from encoding/json+ + encoding/asn1 from crypto/x509+ + encoding/base32 from github.com/fxamacker/cbor/v2+ + encoding/base64 from encoding/json+ + encoding/binary from compress/gzip+ + encoding/hex from crypto/x509+ + encoding/json from expvar+ + encoding/pem from crypto/tls+ + encoding/xml from github.com/huin/goupnp+ + errors from bufio+ + expvar from tailscale.com/health+ + flag from tailscale.com/util/testenv + fmt from compress/flate+ + hash from crypto+ + W hash/adler32 from compress/zlib + hash/crc32 from compress/gzip+ + hash/maphash from go4.org/mem + html from html/template+ + LDW html/template from tailscale.com/util/eventbus + internal/abi from crypto/x509/internal/macos+ + internal/asan from internal/runtime/maps+ + internal/bisect from internal/godebug + internal/bytealg from bytes+ + internal/byteorder from crypto/cipher+ + internal/chacha8rand from math/rand/v2+ + internal/coverage/rtcov from runtime + internal/cpu from crypto/internal/fips140deps/cpu+ + internal/filepathlite from os+ + internal/fmtsort from fmt+ + internal/goarch from crypto/internal/fips140deps/cpu+ + internal/godebug from crypto/internal/fips140deps/godebug+ + internal/godebugs from internal/godebug+ + internal/goexperiment from hash/maphash+ + internal/goos from crypto/x509+ + internal/itoa from internal/poll+ + internal/msan from internal/runtime/maps+ + internal/nettrace from net+ + internal/oserror from io/fs+ + internal/poll from net+ + LDW internal/profile from net/http/pprof + internal/profilerecord from runtime+ + internal/race from internal/poll+ + internal/reflectlite from context+ + DI internal/routebsd from net + internal/runtime/atomic from internal/runtime/exithook+ + LA internal/runtime/cgroup from runtime + internal/runtime/exithook from runtime + internal/runtime/gc from runtime + internal/runtime/maps from reflect+ + internal/runtime/math from internal/runtime/maps+ + internal/runtime/strconv from internal/runtime/cgroup+ + internal/runtime/sys from crypto/subtle+ + LA internal/runtime/syscall from runtime+ + internal/saferio from debug/pe+ + internal/singleflight from net + internal/stringslite from embed+ + internal/sync from sync+ + internal/synctest from sync + internal/syscall/execenv from os+ + LDAI internal/syscall/unix from crypto/internal/sysrand+ + W internal/syscall/windows from crypto/internal/sysrand+ + W internal/syscall/windows/registry from mime+ + W internal/syscall/windows/sysdll from internal/syscall/windows+ + internal/testlog from os + internal/trace/tracev2 from runtime+ + internal/unsafeheader from internal/reflectlite+ + io from bufio+ + io/fs from crypto/x509+ + io/ioutil from github.com/godbus/dbus/v5+ + iter from bytes+ + log from expvar+ + log/internal from log + maps from crypto/x509+ + math from compress/flate+ + math/big from crypto/dsa+ + math/bits from bytes+ + math/rand from github.com/fxamacker/cbor/v2+ + math/rand/v2 from crypto/ecdsa+ + mime from mime/multipart+ + mime/multipart from net/http + mime/quotedprintable from mime/multipart + net from crypto/tls+ + net/http from expvar+ + net/http/httptrace from github.com/prometheus-community/pro-bing+ + net/http/httputil from tailscale.com/client/web+ + net/http/internal from net/http+ + net/http/internal/ascii from net/http+ + net/http/internal/httpcommon from net/http + LDW net/http/pprof from tailscale.com/ipn/localapi+ + net/netip from crypto/x509+ + net/textproto from github.com/coder/websocket+ + net/url from crypto/x509+ + os from crypto/internal/sysrand+ + os/exec from github.com/godbus/dbus/v5+ + os/user from github.com/godbus/dbus/v5+ + path from debug/dwarf+ + path/filepath from crypto/x509+ + reflect from crypto/x509+ + regexp from github.com/huin/goupnp/httpu+ + regexp/syntax from regexp + runtime from crypto/internal/fips140+ + runtime/debug from github.com/coder/websocket/internal/xsync+ + runtime/pprof from net/http/pprof+ + LDW runtime/trace from net/http/pprof + slices from crypto/tls+ + sort from compress/flate+ + strconv from compress/flate+ + strings from bufio+ + W structs from internal/syscall/windows + sync from compress/flate+ + sync/atomic from context+ + syscall from crypto/internal/sysrand+ + text/tabwriter from runtime/pprof + LDW text/template from html/template + LDW text/template/parse from html/template+ + time from compress/gzip+ + unicode from bytes+ + unicode/utf16 from crypto/x509+ + unicode/utf8 from bufio+ + unique from net/netip + unsafe from bytes+ + weak from unique+ diff --git a/vendor/tailscale.com/tsnet/tsnet.go b/vendor/tailscale.com/tsnet/tsnet.go index 1e58b42..6c840c3 100644 --- a/vendor/tailscale.com/tsnet/tsnet.go +++ b/vendor/tailscale.com/tsnet/tsnet.go @@ -27,12 +27,16 @@ import ( "time" "tailscale.com/client/local" - "tailscale.com/client/tailscale" "tailscale.com/control/controlclient" "tailscale.com/envknob" - _ "tailscale.com/feature/condregister" + _ "tailscale.com/feature/c2n" + _ "tailscale.com/feature/condregister/identityfederation" + _ "tailscale.com/feature/condregister/oauthkey" + _ "tailscale.com/feature/condregister/portmapper" + _ "tailscale.com/feature/condregister/useproxy" "tailscale.com/health" "tailscale.com/hostinfo" + "tailscale.com/internal/client/tailscale" "tailscale.com/ipn" "tailscale.com/ipn/ipnauth" "tailscale.com/ipn/ipnlocal" @@ -48,6 +52,7 @@ import ( "tailscale.com/net/proxymux" "tailscale.com/net/socks5" "tailscale.com/net/tsdial" + "tailscale.com/tailcfg" "tailscale.com/tsd" "tailscale.com/types/bools" "tailscale.com/types/logger" @@ -112,6 +117,37 @@ type Server struct { // used. AuthKey string + // ClientSecret, if non-empty, is the OAuth client secret + // that will be used to generate authkeys via OAuth. It + // will be preferred over the TS_CLIENT_SECRET environment + // variable. If the node is already created (from state + // previously stored in Store), then this field is not + // used. + ClientSecret string + + // ClientID, if non-empty, is the client ID used to generate + // authkeys via workload identity federation. It will be + // preferred over the TS_CLIENT_ID environment variable. + // If the node is already created (from state previously + // stored in Store), then this field is not used. + ClientID string + + // IDToken, if non-empty, is the ID token from the identity + // provider to exchange with the control server for workload + // identity federation. It will be preferred over the + // TS_ID_TOKEN environment variable. If the node is already + // created (from state previously stored in Store), then this + // field is not used. + IDToken string + + // Audience, if non-empty, is the audience to use when requesting + // an ID token from a well-known identity provider to exchange + // with the control server for workload identity federation. It + // will be preferred over the TS_AUDIENCE environment variable. If + // the node is already created (from state previously stored in Store), + // then this field is not used. + Audience string + // ControlURL optionally specifies the coordination server URL. // If empty, the Tailscale default is used. ControlURL string @@ -125,27 +161,32 @@ type Server struct { // field at zero unless you know what you are doing. Port uint16 - getCertForTesting func(*tls.ClientHelloInfo) (*tls.Certificate, error) + // AdvertiseTags specifies tags that should be applied to this node, for + // purposes of ACL enforcement. These can be referenced from the ACL policy + // document. Note that advertising a tag on the client doesn't guarantee + // that the control server will allow the node to adopt that tag. + AdvertiseTags []string - initOnce sync.Once - initErr error - lb *ipnlocal.LocalBackend - sys *tsd.System - netstack *netstack.Impl - netMon *netmon.Monitor - rootPath string // the state directory - hostname string - shutdownCtx context.Context - shutdownCancel context.CancelFunc - proxyCred string // SOCKS5 proxy auth for loopbackListener - localAPICred string // basic auth password for loopbackListener - loopbackListener net.Listener // optional loopback for localapi and proxies - localAPIListener net.Listener // in-memory, used by localClient - localClient *local.Client // in-memory - localAPIServer *http.Server - logbuffer *filch.Filch - logtail *logtail.Logger - logid logid.PublicID + initOnce sync.Once + initErr error + lb *ipnlocal.LocalBackend + sys *tsd.System + netstack *netstack.Impl + netMon *netmon.Monitor + rootPath string // the state directory + hostname string + shutdownCtx context.Context + shutdownCancel context.CancelFunc + proxyCred string // SOCKS5 proxy auth for loopbackListener + localAPICred string // basic auth password for loopbackListener + loopbackListener net.Listener // optional loopback for localapi and proxies + localAPIListener net.Listener // in-memory, used by localClient + localClient *local.Client // in-memory + localAPIServer *http.Server + resetServeConfigOnce sync.Once + logbuffer *filch.Filch + logtail *logtail.Logger + logid logid.PublicID mu sync.Mutex listeners map[listenKey]*listener @@ -275,7 +316,13 @@ func (s *Server) Loopback() (addr string, proxyCred, localAPICred string, err er // out the CONNECT code from tailscaled/proxy.go that uses // httputil.ReverseProxy and adding auth support. go func() { - lah := localapi.NewHandler(ipnauth.Self, s.lb, s.logf, s.logid) + lah := localapi.NewHandler(localapi.HandlerConfig{ + Actor: ipnauth.Self, + Backend: s.lb, + Logf: s.logf, + LogID: s.logid, + EventBus: s.sys.Bus.Get(), + }) lah.PermitWrite = true lah.PermitRead = true lah.RequiredPassword = s.localAPICred @@ -335,7 +382,7 @@ func (s *Server) Up(ctx context.Context) (*ipnstate.Status, error) { return nil, fmt.Errorf("tsnet.Up: %w", err) } - watcher, err := lc.WatchIPNBus(ctx, ipn.NotifyInitialState|ipn.NotifyNoPrivateKeys) + watcher, err := lc.WatchIPNBus(ctx, ipn.NotifyInitialState) if err != nil { return nil, fmt.Errorf("tsnet.Up: %w", err) } @@ -349,8 +396,8 @@ func (s *Server) Up(ctx context.Context) (*ipnstate.Status, error) { if n.ErrMessage != nil { return nil, fmt.Errorf("tsnet.Up: backend: %s", *n.ErrMessage) } - if s := n.State; s != nil { - if *s == ipn.Running { + if st := n.State; st != nil { + if *st == ipn.Running { status, err := lc.Status(ctx) if err != nil { return nil, fmt.Errorf("tsnet.Up: %w", err) @@ -359,11 +406,15 @@ func (s *Server) Up(ctx context.Context) (*ipnstate.Status, error) { return nil, errors.New("tsnet.Up: running, but no ip") } - // Clear the persisted serve config state to prevent stale configuration - // from code changes. This is a temporary workaround until we have a better - // way to handle this. (2023-03-11) - if err := lc.SetServeConfig(ctx, new(ipn.ServeConfig)); err != nil { - return nil, fmt.Errorf("tsnet.Up: %w", err) + // The first time Up is run, clear the persisted serve config. + // We do this to prevent messy interactions with stale config in + // the face of code changes. + var srvResetErr error + s.resetServeConfigOnce.Do(func() { + srvResetErr = lc.SetServeConfig(ctx, new(ipn.ServeConfig)) + }) + if srvResetErr != nil { + return nil, fmt.Errorf("tsnet.Up: clearing serve config: %w", err) } return status, nil @@ -435,8 +486,8 @@ func (s *Server) Close() error { for _, ln := range s.listeners { ln.closeLocked() } - wg.Wait() + s.sys.Bus.Get().Close() s.closed = true return nil } @@ -482,6 +533,16 @@ func (s *Server) TailscaleIPs() (ip4, ip6 netip.Addr) { return ip4, ip6 } +// LogtailWriter returns an [io.Writer] that writes to Tailscale's logging service and will be only visible to Tailscale's +// support team. Logs written there cannot be retrieved by the user. This method always returns a non-nil value. +func (s *Server) LogtailWriter() io.Writer { + if s.logtail == nil { + return io.Discard + } + + return s.logtail +} + func (s *Server) getAuthKey() string { if v := s.AuthKey; v != "" { return v @@ -492,6 +553,34 @@ func (s *Server) getAuthKey() string { return os.Getenv("TS_AUTH_KEY") } +func (s *Server) getClientSecret() string { + if v := s.ClientSecret; v != "" { + return v + } + return os.Getenv("TS_CLIENT_SECRET") +} + +func (s *Server) getClientID() string { + if v := s.ClientID; v != "" { + return v + } + return os.Getenv("TS_CLIENT_ID") +} + +func (s *Server) getIDToken() string { + if v := s.IDToken; v != "" { + return v + } + return os.Getenv("TS_ID_TOKEN") +} + +func (s *Server) getAudience() string { + if v := s.Audience; v != "" { + return v + } + return os.Getenv("TS_AUDIENCE") +} + func (s *Server) start() (reterr error) { var closePool closeOnErrorPool defer closePool.closeAllIfError(&reterr) @@ -534,10 +623,7 @@ func (s *Server) start() (reterr error) { if err != nil { return err } - s.rootPath, err = getTSNetDir(s.logf, confDir, prog) - if err != nil { - return err - } + s.rootPath = filepath.Join(confDir, "tsnet-"+prog) } if err := os.MkdirAll(s.rootPath, 0700); err != nil { return err @@ -558,26 +644,28 @@ func (s *Server) start() (reterr error) { s.Logf(format, a...) } - sys := new(tsd.System) + sys := tsd.NewSystem() s.sys = sys - if err := s.startLogger(&closePool, sys.HealthTracker(), tsLogf); err != nil { + if err := s.startLogger(&closePool, sys.HealthTracker.Get(), tsLogf); err != nil { return err } - s.netMon, err = netmon.New(tsLogf) + s.netMon, err = netmon.New(sys.Bus.Get(), tsLogf) if err != nil { return err } closePool.add(s.netMon) s.dialer = &tsdial.Dialer{Logf: tsLogf} // mutated below (before used) + s.dialer.SetBus(sys.Bus.Get()) eng, err := wgengine.NewUserspaceEngine(tsLogf, wgengine.Config{ + EventBus: sys.Bus.Get(), ListenPort: s.Port, NetMon: s.netMon, Dialer: s.dialer, SetSubsystem: sys.Set, ControlKnobs: sys.ControlKnobs(), - HealthTracker: sys.HealthTracker(), + HealthTracker: sys.HealthTracker.Get(), Metrics: sys.UserMetricsRegistry(), }) if err != nil { @@ -585,7 +673,7 @@ func (s *Server) start() (reterr error) { } closePool.add(s.dialer) sys.Set(eng) - sys.HealthTracker().SetMetricsRegistry(sys.UserMetricsRegistry()) + sys.HealthTracker.Get().SetMetricsRegistry(sys.UserMetricsRegistry()) // TODO(oxtoacart): do we need to support Taildrive on tsnet, and if so, how? ns, err := netstack.Create(tsLogf, sys.Tun.Get(), eng, sys.MagicSock.Get(), s.dialer, sys.DNSManager.Get(), sys.ProxyMapper()) @@ -659,7 +747,11 @@ func (s *Server) start() (reterr error) { prefs.WantRunning = true prefs.ControlURL = s.ControlURL prefs.RunWebClient = s.RunWebClient - authKey := s.getAuthKey() + prefs.AdvertiseTags = s.AdvertiseTags + authKey, err := s.resolveAuthKey() + if err != nil { + return fmt.Errorf("error resolving auth key: %w", err) + } err = lb.Start(ipn.Options{ UpdatePrefs: prefs, AuthKey: authKey, @@ -679,7 +771,13 @@ func (s *Server) start() (reterr error) { go s.printAuthURLLoop() // Run the localapi handler, to allow fetching LetsEncrypt certs. - lah := localapi.NewHandler(ipnauth.Self, lb, tsLogf, s.logid) + lah := localapi.NewHandler(localapi.HandlerConfig{ + Actor: ipnauth.Self, + Backend: lb, + Logf: tsLogf, + LogID: s.logid, + EventBus: sys.Bus.Get(), + }) lah.PermitWrite = true lah.PermitRead = true @@ -699,6 +797,51 @@ func (s *Server) start() (reterr error) { return nil } +func (s *Server) resolveAuthKey() (string, error) { + authKey := s.getAuthKey() + var err error + // Try to use an OAuth secret to generate an auth key if that functionality + // is available. + resolveViaOAuth, oauthOk := tailscale.HookResolveAuthKey.GetOk() + if oauthOk { + clientSecret := authKey + if authKey == "" { + clientSecret = s.getClientSecret() + } + authKey, err = resolveViaOAuth(s.shutdownCtx, clientSecret, s.AdvertiseTags) + if err != nil { + return "", err + } + } + // Try to resolve the auth key via workload identity federation if that functionality + // is available and no auth key is yet determined. + resolveViaWIF, wifOk := tailscale.HookResolveAuthKeyViaWIF.GetOk() + if wifOk && authKey == "" { + clientID := s.getClientID() + idToken := s.getIDToken() + audience := s.getAudience() + if clientID != "" && idToken == "" && audience == "" { + return "", fmt.Errorf("client ID for workload identity federation found, but ID token and audience are empty") + } + if idToken != "" && audience != "" { + return "", fmt.Errorf("only one of ID token and audience should be for workload identity federation") + } + if clientID == "" { + if idToken != "" { + return "", fmt.Errorf("ID token for workload identity federation found, but client ID is empty") + } + if audience != "" { + return "", fmt.Errorf("audience for workload identity federation found, but client ID is empty") + } + } + authKey, err = resolveViaWIF(s.shutdownCtx, s.ControlURL, clientID, idToken, audience, s.AdvertiseTags) + if err != nil { + return "", err + } + } + return authKey, nil +} + func (s *Server) startLogger(closePool *closeOnErrorPool, health *health.Tracker, tsLogf logger.Logf) error { if testenv.InTest() { return nil @@ -730,6 +873,7 @@ func (s *Server) startLogger(closePool *closeOnErrorPool, health *health.Tracker Stderr: io.Discard, // log everything to Buffer Buffer: s.logbuffer, CompressLogs: true, + Bus: s.sys.Bus.Get(), HTTPC: &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, s.netMon, health, tsLogf)}, MetricsDelta: clientmetric.EncodeLogTailMetricsDelta, } @@ -894,103 +1038,6 @@ func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(net return func(c nettype.ConnPacketConn) { ln.handle(c) }, true } -// getTSNetDir usually just returns filepath.Join(confDir, "tsnet-"+prog) -// with no error. -// -// One special case is that it renames old "tslib-" directories to -// "tsnet-", and that rename might return an error. -// -// TODO(bradfitz): remove this maybe 6 months after 2022-03-17, -// once people (notably Tailscale corp services) have updated. -func getTSNetDir(logf logger.Logf, confDir, prog string) (string, error) { - oldPath := filepath.Join(confDir, "tslib-"+prog) - newPath := filepath.Join(confDir, "tsnet-"+prog) - - fi, err := os.Lstat(oldPath) - if os.IsNotExist(err) { - // Common path. - return newPath, nil - } - if err != nil { - return "", err - } - if !fi.IsDir() { - return "", fmt.Errorf("expected old tslib path %q to be a directory; got %v", oldPath, fi.Mode()) - } - - // At this point, oldPath exists and is a directory. But does - // the new path exist? - - fi, err = os.Lstat(newPath) - if err == nil && fi.IsDir() { - // New path already exists somehow. Ignore the old one and - // don't try to migrate it. - return newPath, nil - } - if err != nil && !os.IsNotExist(err) { - return "", err - } - if err := os.Rename(oldPath, newPath); err != nil { - return "", err - } - logf("renamed old tsnet state storage directory %q to %q", oldPath, newPath) - return newPath, nil -} - -// APIClient returns a tailscale.Client that can be used to make authenticated -// requests to the Tailscale control server. -// It requires the user to set tailscale.I_Acknowledge_This_API_Is_Unstable. -// -// Deprecated: use AuthenticatedAPITransport with tailscale.com/client/tailscale/v2 instead. -func (s *Server) APIClient() (*tailscale.Client, error) { - if !tailscale.I_Acknowledge_This_API_Is_Unstable { - return nil, errors.New("use of Client without setting I_Acknowledge_This_API_Is_Unstable") - } - if err := s.Start(); err != nil { - return nil, err - } - - c := tailscale.NewClient("-", nil) - c.UserAgent = "tailscale-tsnet" - c.HTTPClient = &http.Client{Transport: s.lb.KeyProvingNoiseRoundTripper()} - return c, nil -} - -// I_Acknowledge_This_API_Is_Experimental must be set true to use AuthenticatedAPITransport() -// for now. -var I_Acknowledge_This_API_Is_Experimental = false - -// AuthenticatedAPITransport provides an HTTP transport that can be used with -// the control server API without needing additional authentication details. It -// authenticates using the current client's nodekey. -// -// It requires the user to set I_Acknowledge_This_API_Is_Experimental. -// -// For example: -// -// import "net/http" -// import "tailscale.com/client/tailscale/v2" -// import "tailscale.com/tsnet" -// -// var s *tsnet.Server -// ... -// rt, err := s.AuthenticatedAPITransport() -// // handler err ... -// var client tailscale.Client{HTTP: http.Client{ -// Timeout: 1*time.Minute, -// UserAgent: "your-useragent-here", -// Transport: rt, -// }} -func (s *Server) AuthenticatedAPITransport() (http.RoundTripper, error) { - if !I_Acknowledge_This_API_Is_Experimental { - return nil, errors.New("use of AuthenticatedAPITransport without setting I_Acknowledge_This_API_Is_Experimental") - } - if err := s.Start(); err != nil { - return nil, err - } - return s.lb.KeyProvingNoiseRoundTripper(), nil -} - // Listen announces only on the Tailscale network. // It will start the server if it has not been started yet. // @@ -1082,9 +1129,6 @@ func (s *Server) RegisterFallbackTCPHandler(cb FallbackTCPHandler) func() { // It calls GetCertificate on the localClient, passing in the ClientHelloInfo. // For testing, if s.getCertForTesting is set, it will call that instead. func (s *Server) getCert(hi *tls.ClientHelloInfo) (*tls.Certificate, error) { - if s.getCertForTesting != nil { - return s.getCertForTesting(hi) - } lc, err := s.LocalClient() if err != nil { return nil, err @@ -1097,13 +1141,33 @@ type FunnelOption interface { funnelOption() } -type funnelOnly int +type funnelOnly struct{} func (funnelOnly) funnelOption() {} // FunnelOnly configures the listener to only respond to connections from Tailscale Funnel. // The local tailnet will not be able to connect to the listener. -func FunnelOnly() FunnelOption { return funnelOnly(1) } +func FunnelOnly() FunnelOption { return funnelOnly{} } + +type funnelTLSConfig struct{ conf *tls.Config } + +func (f funnelTLSConfig) funnelOption() {} + +// FunnelTLSConfig configures the TLS configuration for [Server.ListenFunnel] +// +// This is rarely needed but can permit requiring client certificates, specific +// ciphers suites, etc. +// +// The provided conf should at least be able to get a certificate, setting +// GetCertificate, Certificates or GetConfigForClient appropriately. +// The most common configuration is to set GetCertificate to +// Server.LocalClient's GetCertificate method. +// +// Unless [FunnelOnly] is also used, the configuration is also used for +// in-tailnet connections that don't arrive over Funnel. +func FunnelTLSConfig(conf *tls.Config) FunnelOption { + return funnelTLSConfig{conf: conf} +} // ListenFunnel announces on the public internet using Tailscale Funnel. // @@ -1136,6 +1200,26 @@ func (s *Server) ListenFunnel(network, addr string, opts ...FunnelOption) (net.L return nil, err } + // Process, validate opts. + lnOn := listenOnBoth + var tlsConfig *tls.Config + for _, opt := range opts { + switch v := opt.(type) { + case funnelTLSConfig: + if v.conf == nil { + return nil, errors.New("invalid nil FunnelTLSConfig") + } + tlsConfig = v.conf + case funnelOnly: + lnOn = listenOnFunnel + default: + return nil, fmt.Errorf("unknown opts FunnelOption type %T", v) + } + } + if tlsConfig == nil { + tlsConfig = &tls.Config{GetCertificate: s.getCert} + } + ctx := context.Background() st, err := s.Up(ctx) if err != nil { @@ -1164,28 +1248,288 @@ func (s *Server) ListenFunnel(network, addr string, opts ...FunnelOption) (net.L } domain := st.CertDomains[0] hp := ipn.HostPort(domain + ":" + portStr) + var cleanupOnClose func() error if !srvConfig.AllowFunnel[hp] { mak.Set(&srvConfig.AllowFunnel, hp, true) srvConfig.AllowFunnel[hp] = true if err := lc.SetServeConfig(ctx, srvConfig); err != nil { return nil, err } + cleanupOnClose = func() error { + sc, err := lc.GetServeConfig(ctx) + if err != nil { + return fmt.Errorf("cleaning config changes: %w", err) + } + if sc.AllowFunnel != nil { + delete(sc.AllowFunnel, hp) + } + if err := lc.SetServeConfig(ctx, sc); err != nil { + return fmt.Errorf("cleaning config changes: %w", err) + } + return nil + } } // Start a funnel listener. - lnOn := listenOnBoth - for _, opt := range opts { - if _, ok := opt.(funnelOnly); ok { - lnOn = listenOnFunnel - } - } ln, err := s.listen(network, addr, lnOn) if err != nil { return nil, err } - return tls.NewListener(ln, &tls.Config{ - GetCertificate: s.getCert, - }), nil + ln = &cleanupListener{Listener: ln, cleanup: cleanupOnClose} + return tls.NewListener(ln, tlsConfig), nil +} + +// ServiceMode defines how a Service is run. Currently supported modes are: +// - [ServiceModeTCP] +// - [ServiceModeHTTP] +// +// For more information, see [Server.ListenService]. +type ServiceMode interface { + // network is the network this Service will advertise on. Per Go convention, + // this should be lowercase, e.g. 'tcp'. + network() string +} + +// serviceModeWithPort is a convenience type to extract the port from +// ServiceMode types which have one. +type serviceModeWithPort interface { + ServiceMode + port() uint16 +} + +// ServiceModeTCP is used to configure a TCP Service via [Server.ListenService]. +type ServiceModeTCP struct { + // Port is the TCP port to advertise. If this Service needs to advertise + // multiple ports, call ListenService multiple times. + Port uint16 + + // TerminateTLS means that TLS connections will be terminated before being + // forwarded to the listener. In this case, the only server name indicator + // (SNI) permitted is the Service's fully-qualified domain name. + TerminateTLS bool + + // PROXYProtocolVersion indicates whether to send a PROXY protocol header + // before forwarding the connection to the listener and which version of the + // protocol to use. + // + // For more information, see + // https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt + PROXYProtocolVersion int +} + +func (ServiceModeTCP) network() string { return "tcp" } + +func (m ServiceModeTCP) port() uint16 { return m.Port } + +// ServiceModeHTTP is used to configure an HTTP Service via +// [Server.ListenService]. +type ServiceModeHTTP struct { + // Port is the TCP port to advertise. If this Service needs to advertise + // multiple ports, call ListenService multiple times. + Port uint16 + + // HTTPS, if true, means that the listener should handle connections as + // HTTPS connections. In this case, the only server name indicator (SNI) + // permitted is the Service's fully-qualified domain name. + HTTPS bool + + // AcceptAppCaps defines the app capabilities to forward to the server. The + // keys in this map are the mount points for each set of capabilities. + // + // By example, + // + // AcceptAppCaps: map[string][]string{ + // "/": {"example.com/cap/all-paths"}, + // "/foo": {"example.com/cap/all-paths", "example.com/cap/foo"}, + // } + // + // would forward example.com/cap/all-paths to all paths on the server and + // example.com/cap/foo only to paths beginning with /foo. + // + // For more information on app capabilities, see + // https://tailscale.com/kb/1537/grants-app-capabilities + AcceptAppCaps map[string][]string + + // PROXYProtocolVersion indicates whether to send a PROXY protocol header + // before forwarding the connection to the listener and which version of the + // protocol to use. + // + // For more information, see + // https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt + PROXYProtocol int +} + +func (ServiceModeHTTP) network() string { return "tcp" } + +func (m ServiceModeHTTP) port() uint16 { return m.Port } + +func (m ServiceModeHTTP) capsMap() map[string][]tailcfg.PeerCapability { + capsMap := map[string][]tailcfg.PeerCapability{} + for path, capNames := range m.AcceptAppCaps { + caps := make([]tailcfg.PeerCapability, 0, len(capNames)) + for _, c := range capNames { + caps = append(caps, tailcfg.PeerCapability(c)) + } + capsMap[path] = caps + } + return capsMap +} + +// A ServiceListener is a network listener for a Tailscale Service. For more +// information about Services, see +// https://tailscale.com/kb/1552/tailscale-services +type ServiceListener struct { + net.Listener + addr addr + + // FQDN is the fully-qualifed domain name of this Service. + FQDN string +} + +// Addr returns the listener's network address. This will be the Service's +// fully-qualified domain name (FQDN) and the port. +// +// A hostname is not truly a network address, but Services listen on multiple +// addresses (the IPv4 and IPv6 virtual IPs). +func (sl ServiceListener) Addr() net.Addr { + return sl.addr +} + +// ErrUntaggedServiceHost is returned by ListenService when run on a node +// without any ACL tags. A node must use a tag-based identity to act as a +// Service host. For more information, see: +// https://tailscale.com/kb/1552/tailscale-services#prerequisites +var ErrUntaggedServiceHost = errors.New("service hosts must be tagged nodes") + +// ListenService creates a network listener for a Tailscale Service. This will +// advertise this node as hosting the Service. Note that: +// - Approval must still be granted by an admin or by ACL auto-approval rules. +// - Service hosts must be tagged nodes. +// - A valid Service host must advertise all ports defined for the Service. +// +// To advertise a Service with multiple ports, run ListenService multiple times. +// For more information about Services, see +// https://tailscale.com/kb/1552/tailscale-services +func (s *Server) ListenService(name string, mode ServiceMode) (*ServiceListener, error) { + if err := tailcfg.ServiceName(name).Validate(); err != nil { + return nil, err + } + if mode == nil { + return nil, errors.New("mode may not be nil") + } + svcName := name + + // TODO(hwh33,tailscale/corp#35859): support TUN mode + + ctx := context.Background() + _, err := s.Up(ctx) + if err != nil { + return nil, err + } + + st := s.lb.StatusWithoutPeers() + if st.Self.Tags == nil || st.Self.Tags.Len() == 0 { + return nil, ErrUntaggedServiceHost + } + + advertisedServices := s.lb.Prefs().AdvertiseServices().AsSlice() + if !slices.Contains(advertisedServices, svcName) { + // TODO(hwh33,tailscale/corp#35860): clean these prefs up when (a) we + // exit early due to error or (b) when the returned listener is closed. + _, err = s.lb.EditPrefs(&ipn.MaskedPrefs{ + AdvertiseServicesSet: true, + Prefs: ipn.Prefs{ + AdvertiseServices: append(advertisedServices, svcName), + }, + }) + if err != nil { + return nil, fmt.Errorf("updating advertised Services: %w", err) + } + } + + srvConfig := new(ipn.ServeConfig) + sc, srvConfigETag, err := s.lb.ServeConfigETag() + if err != nil { + return nil, fmt.Errorf("fetching current serve config: %w", err) + } + if sc.Valid() { + srvConfig = sc.AsStruct() + } + + fqdn := tailcfg.ServiceName(svcName).WithoutPrefix() + "." + st.CurrentTailnet.MagicDNSSuffix + + // svcAddr is used to implement Addr() on the returned listener. + svcAddr := addr{ + network: mode.network(), + // A hostname is not a network address, but Services listen on + // multiple addresses (the IPv4 and IPv6 virtual IPs), and there's + // no clear winner here between the two. Therefore prefer the FQDN. + // + // In the case of TCP or HTTP Services, the port will be added below. + addr: fqdn, + } + if m, ok := mode.(serviceModeWithPort); ok { + if m.port() == 0 { + return nil, errors.New("must specify a port to advertise") + } + svcAddr.addr += ":" + strconv.Itoa(int(m.port())) + } + + // Start listening on a local TCP socket. + ln, err := net.Listen("tcp", "localhost:0") + if err != nil { + return nil, fmt.Errorf("starting local listener: %w", err) + } + + switch m := mode.(type) { + case ServiceModeTCP: + // Forward all connections from service-hostname:port to our socket. + srvConfig.SetTCPForwardingForService( + m.Port, ln.Addr().String(), m.TerminateTLS, + tailcfg.ServiceName(svcName), m.PROXYProtocolVersion, st.CurrentTailnet.MagicDNSSuffix) + case ServiceModeHTTP: + // For HTTP Services, proxy all connections to our socket. + mds := st.CurrentTailnet.MagicDNSSuffix + haveRootHandler := false + // We need to add a separate proxy for each mount point in the caps map. + for path, caps := range m.capsMap() { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + h := ipn.HTTPHandler{ + AcceptAppCaps: caps, + Proxy: ln.Addr().String(), + } + if path == "/" { + haveRootHandler = true + } else { + h.Proxy += path + } + srvConfig.SetWebHandler(&h, svcName, m.Port, path, m.HTTPS, mds) + } + // We always need a root handler. + if !haveRootHandler { + h := ipn.HTTPHandler{Proxy: ln.Addr().String()} + srvConfig.SetWebHandler(&h, svcName, m.Port, "/", m.HTTPS, mds) + } + default: + ln.Close() + return nil, fmt.Errorf("unknown ServiceMode type %T", m) + } + + if err := s.lb.SetServeConfig(srvConfig, srvConfigETag); err != nil { + ln.Close() + return nil, err + } + + // TODO(hwh33,tailscale/corp#35860): clean up state (advertising prefs, + // serve config changes) when the returned listener is closed. + + return &ServiceListener{ + Listener: ln, + FQDN: fqdn, + addr: svcAddr, + }, nil } type listenOn string @@ -1282,6 +1626,12 @@ func (s *Server) listen(network, addr string, lnOn listenOn) (net.Listener, erro return ln, nil } +// GetRootPath returns the root path of the tsnet server. +// This is where the state file and other data is stored. +func (s *Server) GetRootPath() string { + return s.rootPath +} + // CapturePcap can be called by the application code compiled with tsnet to save a pcap // of packets which the netstack within tsnet sees. This is expected to be useful during // debugging, probably not useful for production. @@ -1343,7 +1693,12 @@ func (ln *listener) Accept() (net.Conn, error) { } } -func (ln *listener) Addr() net.Addr { return addr{ln} } +func (ln *listener) Addr() net.Addr { + return addr{ + network: ln.keys[0].network, + addr: ln.addr, + } +} func (ln *listener) Close() error { ln.s.mu.Lock() @@ -1383,7 +1738,26 @@ func (ln *listener) handle(c net.Conn) { // Server returns the tsnet Server associated with the listener. func (ln *listener) Server() *Server { return ln.s } -type addr struct{ ln *listener } +type addr struct { + network, addr string +} -func (a addr) Network() string { return a.ln.keys[0].network } -func (a addr) String() string { return a.ln.addr } +func (a addr) Network() string { return a.network } +func (a addr) String() string { return a.addr } + +// cleanupListener wraps a net.Listener with a function to be run on Close. +type cleanupListener struct { + net.Listener + cleanupOnce sync.Once + cleanup func() error // nil if unused +} + +func (cl *cleanupListener) Close() error { + var cleanupErr error + cl.cleanupOnce.Do(func() { + if cl.cleanup != nil { + cleanupErr = cl.cleanup() + } + }) + return errors.Join(cl.Listener.Close(), cleanupErr) +} diff --git a/vendor/tailscale.com/tstime/tstime.go b/vendor/tailscale.com/tstime/tstime.go index 1c00635..6e5b7f9 100644 --- a/vendor/tailscale.com/tstime/tstime.go +++ b/vendor/tailscale.com/tstime/tstime.go @@ -6,6 +6,7 @@ package tstime import ( "context" + "encoding" "strconv" "strings" "time" @@ -183,3 +184,40 @@ func (StdClock) AfterFunc(d time.Duration, f func()) TimerController { func (StdClock) Since(t time.Time) time.Duration { return time.Since(t) } + +// GoDuration is a [time.Duration] but JSON serializes with [time.Duration.String]. +// +// Note that this format is specific to Go and non-standard, +// but excels in being most humanly readable compared to alternatives. +// The wider industry still lacks consensus for the representation +// of a time duration in humanly-readable text. +// See https://go.dev/issue/71631 for more discussion. +// +// Regardless of how the industry evolves into the future, +// this type explicitly uses the Go format. +type GoDuration struct{ time.Duration } + +var ( + _ encoding.TextAppender = (*GoDuration)(nil) + _ encoding.TextMarshaler = (*GoDuration)(nil) + _ encoding.TextUnmarshaler = (*GoDuration)(nil) +) + +func (d GoDuration) AppendText(b []byte) ([]byte, error) { + // The String method is inlineable (see https://go.dev/cl/520602), + // so this may not allocate since the string does not escape. + return append(b, d.String()...), nil +} + +func (d GoDuration) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +func (d *GoDuration) UnmarshalText(b []byte) error { + d2, err := time.ParseDuration(string(b)) + if err != nil { + return err + } + d.Duration = d2 + return nil +} diff --git a/vendor/tailscale.com/tsweb/debug.go b/vendor/tailscale.com/tsweb/debug.go new file mode 100644 index 0000000..4c0faba --- /dev/null +++ b/vendor/tailscale.com/tsweb/debug.go @@ -0,0 +1,193 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsweb + +import ( + "expvar" + "fmt" + "html" + "io" + "net/http" + "net/url" + "os" + "runtime" + + "tailscale.com/feature" + "tailscale.com/tsweb/varz" + "tailscale.com/version" +) + +// DebugHandler is an http.Handler that serves a debugging "homepage", +// and provides helpers to register more debug endpoints and reports. +// +// The rendered page consists of three sections: informational +// key/value pairs, links to other pages, and additional +// program-specific HTML. Callers can add to these sections using the +// KV, URL and Section helpers respectively. +// +// Additionally, the Handle method offers a shorthand for correctly +// registering debug handlers and cross-linking them from /debug/. +type DebugHandler struct { + mux *http.ServeMux // where this handler is registered + kvs []func(io.Writer) // output one
  • ...
  • each, see KV() + urls []string // one
  • ...
  • block with link each + sections []func(io.Writer, *http.Request) // invoked in registration order prior to outputting + title string // title displayed on index page +} + +// PrometheusHandler is an optional hook to enable native Prometheus +// support in the debug handler. It is disabled by default. Import the +// tailscale.com/tsweb/promvarz package to enable this feature. +var PrometheusHandler feature.Hook[func(*DebugHandler)] + +// Debugger returns the DebugHandler registered on mux at /debug/, +// creating it if necessary. +func Debugger(mux *http.ServeMux) *DebugHandler { + h, pat := mux.Handler(&http.Request{URL: &url.URL{Path: "/debug/"}}) + if d, ok := h.(*DebugHandler); ok && pat == "/debug/" { + return d + } + ret := &DebugHandler{ + mux: mux, + title: fmt.Sprintf("%s debug", version.CmdName()), + } + mux.Handle("/debug/", ret) + + ret.KVFunc("Uptime", func() any { return varz.Uptime() }) + ret.KV("Version", version.Long()) + ret.Handle("vars", "Metrics (Go)", expvar.Handler()) + if PrometheusHandler.IsSet() { + PrometheusHandler.Get()(ret) + } else { + ret.Handle("varz", "Metrics (Prometheus)", http.HandlerFunc(varz.Handler)) + } + + addProfilingHandlers(ret) + ret.Handle("gc", "force GC", http.HandlerFunc(gcHandler)) + hostname, err := os.Hostname() + if err == nil { + ret.KV("Machine", hostname) + } + return ret +} + +// ServeHTTP implements http.Handler. +func (d *DebugHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !AllowDebugAccess(r) { + http.Error(w, "debug access denied", http.StatusForbidden) + return + } + if r.URL.Path != "/debug/" { + // Sub-handlers are handled by the parent mux directly. + http.NotFound(w, r) + return + } + + AddBrowserHeaders(w) + f := func(format string, args ...any) { fmt.Fprintf(w, format, args...) } + f("

    %s

      ", html.EscapeString(d.title)) + for _, kv := range d.kvs { + kv(w) + } + for _, url := range d.urls { + io.WriteString(w, url) + } + for _, section := range d.sections { + section(w, r) + } +} + +func (d *DebugHandler) handle(slug string, handler http.Handler) string { + href := "/debug/" + slug + d.mux.Handle(href, Protected(debugBrowserHeaderHandler(handler))) + return href +} + +// Handle registers handler at /debug/ and adds a link to it +// on /debug/ with the provided description. +func (d *DebugHandler) Handle(slug, desc string, handler http.Handler) { + href := d.handle(slug, handler) + d.URL(href, desc) +} + +// Handle registers handler at /debug/ and adds a link to it +// on /debug/ with the provided description. +func (d *DebugHandler) HandleFunc(slug, desc string, handler http.HandlerFunc) { + d.Handle(slug, desc, handler) +} + +// HandleSilent registers handler at /debug/. It does not add +// a descriptive entry in /debug/ for it. This should be used +// sparingly, for things that need to be registered but would pollute +// the list of debug links. +func (d *DebugHandler) HandleSilent(slug string, handler http.Handler) { + d.handle(slug, handler) +} + +// HandleSilent registers handler at /debug/. It does not add +// a descriptive entry in /debug/ for it. This should be used +// sparingly, for things that need to be registered but would pollute +// the list of debug links. +func (d *DebugHandler) HandleSilentFunc(slug string, handler http.HandlerFunc) { + d.HandleSilent(slug, handler) +} + +// KV adds a key/value list item to /debug/. +func (d *DebugHandler) KV(k string, v any) { + val := html.EscapeString(fmt.Sprintf("%v", v)) + d.kvs = append(d.kvs, func(w io.Writer) { + fmt.Fprintf(w, "
    • %s: %s
    • ", k, val) + }) +} + +// KVFunc adds a key/value list item to /debug/. v is called on every +// render of /debug/. +func (d *DebugHandler) KVFunc(k string, v func() any) { + d.kvs = append(d.kvs, func(w io.Writer) { + val := html.EscapeString(fmt.Sprintf("%v", v())) + fmt.Fprintf(w, "
    • %s: %s
    • ", k, val) + }) +} + +// URL adds a URL and description list item to /debug/. +func (d *DebugHandler) URL(url, desc string) { + if desc != "" { + desc = " (" + desc + ")" + } + d.urls = append(d.urls, fmt.Sprintf(`
    • %s%s
    • `, url, url, html.EscapeString(desc))) +} + +// Section invokes f on every render of /debug/ to add supplemental +// HTML to the page body. +func (d *DebugHandler) Section(f func(w io.Writer, r *http.Request)) { + d.sections = append(d.sections, f) +} + +// Title sets the title at the top of the debug page. +func (d *DebugHandler) Title(title string) { + d.title = title +} + +func gcHandler(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("running GC...\n")) + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + runtime.GC() + w.Write([]byte("Done.\n")) +} + +// debugBrowserHeaderHandler is a wrapper around BrowserHeaderHandler with a +// more relaxed Content-Security-Policy that's acceptable for internal debug +// pages. It should not be used on any public-facing handlers! +func debugBrowserHeaderHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + AddBrowserHeaders(w) + // The only difference from AddBrowserHeaders is that this policy + // allows inline CSS styles. They make debug pages much easier to + // prototype, while the risk of user-injected CSS is relatively low. + w.Header().Set("Content-Security-Policy", "default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; block-all-mixed-content; object-src 'none'; style-src 'self' 'unsafe-inline'") + h.ServeHTTP(w, r) + }) +} diff --git a/vendor/tailscale.com/tsweb/log.go b/vendor/tailscale.com/tsweb/log.go new file mode 100644 index 0000000..51f95e9 --- /dev/null +++ b/vendor/tailscale.com/tsweb/log.go @@ -0,0 +1,64 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsweb + +import ( + "encoding/json" + "strings" + "time" +) + +// AccessLogRecord is a record of one HTTP request served. +type AccessLogRecord struct { + // Timestamp at which request processing started. + Time time.Time `json:"time"` + // Time it took to finish processing the request. It does not + // include the entire lifetime of the underlying connection in + // cases like connection hijacking, only the lifetime of the HTTP + // request handler. + Seconds float64 `json:"duration,omitempty"` + + // The client's ip:port. + RemoteAddr string `json:"remote_addr,omitempty"` + // The HTTP protocol version, usually "HTTP/1.1 or HTTP/2". + Proto string `json:"proto,omitempty"` + // Whether the request was received over TLS. + TLS bool `json:"tls,omitempty"` + // The target hostname in the request. + Host string `json:"host,omitempty"` + // The HTTP method invoked. + Method string `json:"method,omitempty"` + // The unescaped request URI, including query parameters. + RequestURI string `json:"request_uri,omitempty"` + + // The client's user-agent + UserAgent string `json:"user_agent,omitempty"` + // Where the client was before making this request. + Referer string `json:"referer,omitempty"` + + // The HTTP response code sent to the client. + Code int `json:"code,omitempty"` + // Number of bytes sent in response body to client. If the request + // was hijacked, only includes bytes sent up to the point of + // hijacking. + Bytes int `json:"bytes,omitempty"` + // Error encountered during request processing. + Err string `json:"err,omitempty"` + // RequestID is a unique ID for this request. If the *http.Request context + // carries this value via SetRequestID, then it will be displayed to the + // client immediately after the error text, as well as logged here. This + // makes it easier to correlate support requests with server logs. If a + // RequestID generator is not configured, RequestID will be empty. + RequestID RequestID `json:"request_id,omitempty"` +} + +// String returns m as a JSON string. +func (m AccessLogRecord) String() string { + if m.Time.IsZero() { + m.Time = time.Now() + } + var buf strings.Builder + json.NewEncoder(&buf).Encode(m) + return strings.TrimRight(buf.String(), "\n") +} diff --git a/vendor/tailscale.com/tsweb/pprof_default.go b/vendor/tailscale.com/tsweb/pprof_default.go new file mode 100644 index 0000000..7d22a61 --- /dev/null +++ b/vendor/tailscale.com/tsweb/pprof_default.go @@ -0,0 +1,24 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !js && !wasm + +package tsweb + +import ( + "net/http" + "net/http/pprof" +) + +func addProfilingHandlers(d *DebugHandler) { + // pprof.Index serves everything that runtime/pprof.Lookup finds: + // goroutine, threadcreate, heap, allocs, block, mutex + d.Handle("pprof/", "pprof (index)", http.HandlerFunc(pprof.Index)) + // But register the other ones from net/http/pprof directly: + d.HandleSilent("pprof/cmdline", http.HandlerFunc(pprof.Cmdline)) + d.HandleSilent("pprof/profile", http.HandlerFunc(pprof.Profile)) + d.HandleSilent("pprof/symbol", http.HandlerFunc(pprof.Symbol)) + d.HandleSilent("pprof/trace", http.HandlerFunc(pprof.Trace)) + d.URL("/debug/pprof/goroutine?debug=1", "Goroutines (collapsed)") + d.URL("/debug/pprof/goroutine?debug=2", "Goroutines (full)") +} diff --git a/vendor/tailscale.com/tsweb/pprof_js.go b/vendor/tailscale.com/tsweb/pprof_js.go new file mode 100644 index 0000000..1212b37 --- /dev/null +++ b/vendor/tailscale.com/tsweb/pprof_js.go @@ -0,0 +1,10 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build js && wasm + +package tsweb + +func addProfilingHandlers(d *DebugHandler) { + // No pprof in js builds, pprof doesn't work and bloats the build. +} diff --git a/vendor/tailscale.com/tsweb/request_id.go b/vendor/tailscale.com/tsweb/request_id.go new file mode 100644 index 0000000..46e5238 --- /dev/null +++ b/vendor/tailscale.com/tsweb/request_id.go @@ -0,0 +1,77 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package tsweb + +import ( + "context" + "net/http" + "time" + + "tailscale.com/util/ctxkey" + "tailscale.com/util/rands" +) + +// RequestID is an opaque identifier for a HTTP request, used to correlate +// user-visible errors with backend server logs. The RequestID is typically +// threaded through an HTTP Middleware (WithRequestID) and then can be extracted +// by HTTP Handlers to include in their logs. +// +// RequestID is an opaque identifier for a HTTP request, used to correlate +// user-visible errors with backend server logs. If present in the context, the +// RequestID will be printed alongside the message text and logged in the +// AccessLogRecord. +// +// A RequestID has the format "REQ-1{ID}", and the ID should be treated as an +// opaque string. The current implementation uses a UUID. +type RequestID string + +// String returns the string format of the request ID, for use in e.g. setting +// a [http.Header]. +func (r RequestID) String() string { + return string(r) +} + +// RequestIDKey stores and loads [RequestID] values within a [context.Context]. +var RequestIDKey ctxkey.Key[RequestID] + +// RequestIDHeader is a custom HTTP header that the WithRequestID middleware +// uses to determine whether to re-use a given request ID from the client +// or generate a new one. +const RequestIDHeader = "X-Tailscale-Request-Id" + +// GenerateRequestID generates a new request ID with the current format. +func GenerateRequestID() RequestID { + // Return a string of the form "REQ-<...>" + // Previously we returned "REQ-1". + // Now we return "REQ-2" version, where the "2" doubles as the year 2YYY + // in a leading date. + now := time.Now().UTC() + return RequestID("REQ-" + now.Format("20060102150405") + rands.HexString(16)) +} + +// SetRequestID is an HTTP middleware that injects a RequestID in the +// *http.Request Context. The value of that request id is either retrieved from +// the RequestIDHeader or a randomly generated one if not exists. Inner +// handlers can retrieve this ID from the RequestIDFromContext function. +func SetRequestID(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var rid RequestID + if id := r.Header.Get(RequestIDHeader); id != "" { + rid = RequestID(id) + } else { + rid = GenerateRequestID() + } + ctx := RequestIDKey.WithValue(r.Context(), rid) + r = r.WithContext(ctx) + h.ServeHTTP(w, r) + }) +} + +// RequestIDFromContext retrieves the RequestID from context that can be set by +// the SetRequestID function. +// +// Deprecated: Use [RequestIDKey.Value] instead. +func RequestIDFromContext(ctx context.Context) RequestID { + return RequestIDKey.Value(ctx) +} diff --git a/vendor/tailscale.com/tsweb/tsweb.go b/vendor/tailscale.com/tsweb/tsweb.go new file mode 100644 index 0000000..f619617 --- /dev/null +++ b/vendor/tailscale.com/tsweb/tsweb.go @@ -0,0 +1,1003 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package tsweb contains code used in various Tailscale webservers. +package tsweb + +import ( + "bufio" + "bytes" + "cmp" + "context" + "errors" + "expvar" + "fmt" + "io" + "net" + "net/http" + "net/netip" + "net/url" + "os" + "path/filepath" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "go4.org/mem" + "tailscale.com/envknob" + "tailscale.com/metrics" + "tailscale.com/net/tsaddr" + "tailscale.com/tsweb/varz" + "tailscale.com/types/logger" + "tailscale.com/util/ctxkey" + "tailscale.com/util/vizerror" +) + +// DevMode controls whether extra output in shown, for when the binary is being run in dev mode. +var DevMode bool + +func DefaultCertDir(leafDir string) string { + cacheDir, err := os.UserCacheDir() + if err == nil { + return filepath.Join(cacheDir, "tailscale", leafDir) + } + return "" +} + +// IsProd443 reports whether addr is a Go listen address for port 443. +func IsProd443(addr string) bool { + _, port, _ := net.SplitHostPort(addr) + return port == "443" || port == "https" +} + +// AllowDebugAccess reports whether r should be permitted to access +// various debug endpoints. +func AllowDebugAccess(r *http.Request) bool { + if allowDebugAccessWithKey(r) { + return true + } + if r.Header.Get("X-Forwarded-For") != "" { + // TODO if/when needed. For now, conservative: + return false + } + ipStr, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return false + } + ip, err := netip.ParseAddr(ipStr) + if err != nil { + return false + } + if tsaddr.IsTailscaleIP(ip) || ip.IsLoopback() || ipStr == envknob.String("TS_ALLOW_DEBUG_IP") { + return true + } + return false +} + +func allowDebugAccessWithKey(r *http.Request) bool { + if r.Method != "GET" { + return false + } + urlKey := r.FormValue("debugkey") + keyPath := envknob.String("TS_DEBUG_KEY_PATH") + if urlKey != "" && keyPath != "" { + slurp, err := os.ReadFile(keyPath) + if err == nil && string(bytes.TrimSpace(slurp)) == urlKey { + return true + } + } + return false +} + +// AcceptsEncoding reports whether r accepts the named encoding +// ("gzip", "br", etc). +func AcceptsEncoding(r *http.Request, enc string) bool { + h := r.Header.Get("Accept-Encoding") + if h == "" { + return false + } + if !strings.Contains(h, enc) && !mem.ContainsFold(mem.S(h), mem.S(enc)) { + return false + } + remain := h + for len(remain) > 0 { + var part string + part, remain, _ = strings.Cut(remain, ",") + part = strings.TrimSpace(part) + part, _, _ = strings.Cut(part, ";") + if part == enc { + return true + } + } + return false +} + +// Protected wraps a provided debug handler, h, returning a Handler +// that enforces AllowDebugAccess and returns forbidden replies for +// unauthorized requests. +func Protected(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !AllowDebugAccess(r) { + msg := "debug access denied" + if DevMode { + ipStr, _, _ := net.SplitHostPort(r.RemoteAddr) + msg += fmt.Sprintf("; to permit access, set TS_ALLOW_DEBUG_IP=%v", ipStr) + } + http.Error(w, msg, http.StatusForbidden) + return + } + h.ServeHTTP(w, r) + }) +} + +// Port80Handler is the handler to be given to +// autocert.Manager.HTTPHandler. The inner handler is the mux +// returned by NewMux containing registered /debug handlers. +type Port80Handler struct { + Main http.Handler + // FQDN is used to redirect incoming requests to https://. + // If it is not set, the hostname is calculated from the incoming + // request. + FQDN string +} + +func (h Port80Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + path := r.RequestURI + if path == "/debug" || strings.HasPrefix(path, "/debug") { + h.Main.ServeHTTP(w, r) + return + } + if r.Method != "GET" && r.Method != "HEAD" { + http.Error(w, "Use HTTPS", http.StatusBadRequest) + return + } + if path == "/" && AllowDebugAccess(r) { + // Redirect authorized user to the debug handler. + path = "/debug/" + } + host := cmp.Or(h.FQDN, r.Host) + target := "https://" + host + path + http.Redirect(w, r, target, http.StatusFound) +} + +// ReturnHandler is like net/http.Handler, but the handler can return an +// error instead of writing to its ResponseWriter. +type ReturnHandler interface { + // ServeHTTPReturn is like http.Handler.ServeHTTP, except that + // it can choose to return an error instead of writing to its + // http.ResponseWriter. + // + // If ServeHTTPReturn returns an error, it caller should handle + // an error by serving an HTTP 500 response to the user. The + // error details should not be sent to the client, as they may + // contain sensitive information. If the error is an + // HTTPError, though, callers should use the HTTP response + // code and message as the response to the client. + ServeHTTPReturn(http.ResponseWriter, *http.Request) error +} + +// BucketedStatsOptions describes tsweb handler options surrounding +// the generation of metrics, grouped into buckets. +type BucketedStatsOptions struct { + // Bucket returns which bucket the given request is in. + // If nil, [NormalizedPath] is used to compute the bucket. + Bucket func(req *http.Request) string + + // If non-nil, Started maintains a counter of all requests which + // have begun processing. + Started *metrics.LabelMap + + // If non-nil, Finished maintains a counter of all requests which + // have finished processing with success (that is, the HTTP handler has + // returned). + Finished *metrics.LabelMap +} + +// normalizePathRegex matches components in a HTTP request path +// that should be replaced. +// +// See: https://regex101.com/r/WIfpaR/3 for the explainer and test cases. +var normalizePathRegex = regexp.MustCompile("([a-fA-F0-9]{9,}|([^\\/])+\\.([^\\/]){2,}|((n|k|u|L|t|S)[a-zA-Z0-9]{5,}(CNTRL|Djz1H|LV5CY|mxgaY|jNy1b))|(([^\\/])+\\@passkey))") + +// NormalizedPath returns the given path with the following modifications: +// +// - any query parameters are removed +// - any path component with a hex string of 9 or more characters is +// replaced by an ellipsis +// - any path component containing a period with at least two characters +// after the period (i.e. an email or domain) +// - any path component consisting of a common Tailscale Stable ID +// - any path segment *@passkey. +func NormalizedPath(p string) string { + // Fastpath: No hex sequences in there we might have to trim. + // Avoids allocating. + if normalizePathRegex.FindStringIndex(p) == nil { + b, _, _ := strings.Cut(p, "?") + return b + } + + // If we got here, there's at least one hex sequences we need to + // replace with an ellipsis. + replaced := normalizePathRegex.ReplaceAllString(p, "…") + b, _, _ := strings.Cut(replaced, "?") + return b +} + +func (o *BucketedStatsOptions) bucketForRequest(r *http.Request) string { + if o.Bucket != nil { + return o.Bucket(r) + } + + return NormalizedPath(r.URL.Path) +} + +// HandlerOptions are options used by [StdHandler], containing both [LogOptions] +// used by [LogHandler] and [ErrorOptions] used by [ErrorHandler]. +type HandlerOptions struct { + QuietLoggingIfSuccessful bool // if set, do not log successfully handled HTTP requests (200 and 304 status codes) + Logf logger.Logf + Now func() time.Time // if nil, defaults to time.Now + + // If non-nil, StatusCodeCounters maintains counters + // of status codes for handled responses. + // The keys are "1xx", "2xx", "3xx", "4xx", and "5xx". + StatusCodeCounters *expvar.Map + // If non-nil, StatusCodeCountersFull maintains counters of status + // codes for handled responses. + // The keys are HTTP numeric response codes e.g. 200, 404, ... + StatusCodeCountersFull *expvar.Map + + // If non-nil, BucketedStats computes and exposes statistics + // for each bucket based on the contained parameters. + BucketedStats *BucketedStatsOptions + + // OnStart is called inline before ServeHTTP is called. Optional. + OnStart OnStartFunc + + // OnError is called if the handler returned a HTTPError. This + // is intended to be used to present pretty error pages if + // the user agent is determined to be a browser. + OnError ErrorHandlerFunc + + // OnCompletion is called inline when ServeHTTP is finished and gets + // useful data that the implementor can use for metrics. Optional. + OnCompletion OnCompletionFunc +} + +// LogOptions are the options used by [LogHandler]. +// These options are a subset of [HandlerOptions]. +type LogOptions struct { + // Logf is used to log HTTP requests and responses. + Logf logger.Logf + // Now is a function giving the current time. Defaults to [time.Now]. + Now func() time.Time + + // QuietLogging suppresses all logging of handled HTTP requests, even if + // there are errors or status codes considered unsuccessful. Use this option + // to add your own logging in OnCompletion. + QuietLogging bool + // QuietLoggingIfSuccessful suppresses logging of handled HTTP requests + // where the request's response status code is 200 or 304. + QuietLoggingIfSuccessful bool + + // StatusCodeCounters maintains counters of status code classes. + // The keys are "1xx", "2xx", "3xx", "4xx", and "5xx". + // If nil, no counting is done. + StatusCodeCounters *expvar.Map + // StatusCodeCountersFull maintains counters of status codes. + // The keys are HTTP numeric response codes e.g. 200, 404, ... + // If nil, no counting is done. + StatusCodeCountersFull *expvar.Map + // BucketedStats computes and exposes statistics for each bucket based on + // the contained parameters. If nil, no counting is done. + BucketedStats *BucketedStatsOptions + + // OnStart is called inline before ServeHTTP is called. Optional. + OnStart OnStartFunc + // OnCompletion is called inline when ServeHTTP is finished and gets + // useful data that the implementor can use for metrics. Optional. + OnCompletion OnCompletionFunc +} + +func (o HandlerOptions) logOptions() LogOptions { + return LogOptions{ + QuietLoggingIfSuccessful: o.QuietLoggingIfSuccessful, + Logf: o.Logf, + Now: o.Now, + StatusCodeCounters: o.StatusCodeCounters, + StatusCodeCountersFull: o.StatusCodeCountersFull, + BucketedStats: o.BucketedStats, + OnStart: o.OnStart, + OnCompletion: o.OnCompletion, + } +} + +func (opts LogOptions) withDefaults() LogOptions { + if opts.Logf == nil { + opts.Logf = logger.Discard + } + if opts.Now == nil { + opts.Now = time.Now + } + return opts +} + +// ErrorOptions are options used by [ErrorHandler]. +type ErrorOptions struct { + // Logf is used to record unexpected behaviours when returning HTTPError but + // different error codes have already been written to the client. + Logf logger.Logf + // OnError is called if the handler returned a HTTPError. This + // is intended to be used to present pretty error pages if + // the user agent is determined to be a browser. + OnError ErrorHandlerFunc +} + +func (opts ErrorOptions) withDefaults() ErrorOptions { + if opts.Logf == nil { + opts.Logf = logger.Discard + } + if opts.OnError == nil { + opts.OnError = WriteHTTPError + } + return opts +} + +func (opts HandlerOptions) errorOptions() ErrorOptions { + return ErrorOptions{ + OnError: opts.OnError, + } +} + +// ErrorHandlerFunc is called to present a error response. +type ErrorHandlerFunc func(http.ResponseWriter, *http.Request, HTTPError) + +// OnStartFunc is called before ServeHTTP is called. +type OnStartFunc func(*http.Request, AccessLogRecord) + +// OnCompletionFunc is called when ServeHTTP is finished and gets +// useful data that the implementor can use for metrics. +type OnCompletionFunc func(*http.Request, AccessLogRecord) + +// ReturnHandlerFunc is an adapter to allow the use of ordinary +// functions as ReturnHandlers. If f is a function with the +// appropriate signature, ReturnHandlerFunc(f) is a ReturnHandler that +// calls f. +type ReturnHandlerFunc func(http.ResponseWriter, *http.Request) error + +// A Middleware is a function that wraps an http.Handler to extend or modify +// its behaviour. +// +// The implementation of the wrapper is responsible for delegating its input +// request to the underlying handler, if appropriate. +type Middleware func(h http.Handler) http.Handler + +// MiddlewareStack combines multiple middleware into a single middleware for +// decorating a [http.Handler]. The first middleware argument will be the first +// to process an incoming request, before passing the request onto subsequent +// middleware and eventually the wrapped handler. +// +// For example: +// +// MiddlewareStack(A, B)(h).ServeHTTP(w, r) +// +// calls in sequence: +// +// a.ServeHTTP(w, r) +// -> b.ServeHTTP(w, r) +// -> h.ServeHTTP(w, r) +// +// (where the lowercase handlers were generated by the uppercase middleware). +func MiddlewareStack(mw ...Middleware) Middleware { + if len(mw) == 1 { + return mw[0] + } + return func(h http.Handler) http.Handler { + for i := len(mw) - 1; i >= 0; i-- { + h = mw[i](h) + } + return h + } +} + +// ServeHTTPReturn calls f(w, r). +func (f ReturnHandlerFunc) ServeHTTPReturn(w http.ResponseWriter, r *http.Request) error { + return f(w, r) +} + +// StdHandler converts a ReturnHandler into a standard http.Handler. +// Handled requests are logged using opts.Logf, as are any errors. +// Errors are handled as specified by the ReturnHandler interface. +// Short-hand for LogHandler(ErrorHandler()). +func StdHandler(h ReturnHandler, opts HandlerOptions) http.Handler { + return LogHandler(ErrorHandler(h, opts.errorOptions()), opts.logOptions()) +} + +// LogHandler returns an http.Handler that logs to opts.Logf. +// It logs both successful and failing requests. +// The log line includes the first error returned to [ErrorHandler] within. +// The outer-most LogHandler(LogHandler(...)) does all of the logging. +// Inner LogHandler instance do nothing. +// Panics are swallowed and their stack traces are put in the error. +func LogHandler(h http.Handler, opts LogOptions) http.Handler { + return logHandler{h, opts.withDefaults()} +} + +// ErrorHandler converts a [ReturnHandler] into a standard [http.Handler]. +// Errors are handled as specified by the [ReturnHandler.ServeHTTPReturn] method. +// When wrapped in a [LogHandler], panics are added to the [AccessLogRecord]; +// otherwise, panics continue up the stack. +func ErrorHandler(h ReturnHandler, opts ErrorOptions) http.Handler { + return errorHandler{h, opts.withDefaults()} +} + +// errCallback is added to logHandler's request context so that errorHandler can +// pass errors back up the stack to logHandler. +var errCallback = ctxkey.New[func(HTTPError)]("tailscale.com/tsweb.errCallback", nil) + +// logHandler is a http.Handler which logs the HTTP request. +// It injects an errCallback for errorHandler to augment the log message with +// a specific error. +type logHandler struct { + h http.Handler + opts LogOptions +} + +func (h logHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // If there's already a logHandler up the chain, skip this one. + ctx := r.Context() + if errCallback.Has(ctx) { + h.h.ServeHTTP(w, r) + return + } + + msg := AccessLogRecord{ + Time: h.opts.Now(), + RemoteAddr: r.RemoteAddr, + Proto: r.Proto, + TLS: r.TLS != nil, + Host: r.Host, + Method: r.Method, + RequestURI: r.URL.RequestURI(), + UserAgent: r.UserAgent(), + Referer: r.Referer(), + RequestID: RequestIDFromContext(r.Context()), + } + + if bs := h.opts.BucketedStats; bs != nil && bs.Started != nil && bs.Finished != nil { + bucket := bs.bucketForRequest(r) + var startRecorded bool + switch v := bs.Started.Map.Get(bucket).(type) { + case *expvar.Int: + // If we've already seen this bucket for, count it immediately. + // Otherwise, for newly seen paths, only count retroactively + // (so started-finished doesn't go negative) so we don't fill + // this LabelMap up with internet scanning spam. + v.Add(1) + startRecorded = true + } + defer func() { + // Only increment metrics for buckets that result in good HTTP statuses + // or when we know the start was already counted. + // Otherwise they get full of internet scanning noise. Only filtering 404 + // gets most of the way there but there are also plenty of URLs that are + // almost right but result in 400s too. Seem easier to just only ignore + // all 4xx and 5xx. + if startRecorded { + bs.Finished.Add(bucket, 1) + } else if msg.Code < 400 { + // This is the first non-error request for this bucket, + // so count it now retroactively. + bs.Started.Add(bucket, 1) + bs.Finished.Add(bucket, 1) + } + }() + } + + if fn := h.opts.OnStart; fn != nil { + fn(r, msg) + } + + // Let errorHandler tell us what error it wrote to the client. + r = r.WithContext(errCallback.WithValue(ctx, func(e HTTPError) { + // Keep the deepest error. + if msg.Err != "" { + return + } + + // Log the error. + if e.Msg != "" && e.Err != nil { + msg.Err = e.Msg + ": " + e.Err.Error() + } else if e.Err != nil { + msg.Err = e.Err.Error() + } else if e.Msg != "" { + msg.Err = e.Msg + } + + // We log the code from the loggingResponseWriter, except for + // cancellation where we override with 499. + if reqCancelled(r, e.Err) { + msg.Code = 499 + } + })) + + lw := newLogResponseWriter(h.opts.Logf, w, r) + + defer func() { + // If the handler panicked then make sure we include that in our error. + // Panics caught up errorHandler shouldn't appear here, unless the panic + // originates in one of its callbacks. + recovered := recover() + if recovered != nil { + if msg.Err == "" { + msg.Err = panic2err(recovered).Error() + } else { + msg.Err += "\n\nthen " + panic2err(recovered).Error() + } + } + h.logRequest(r, lw, msg) + }() + + h.h.ServeHTTP(lw, r) +} + +func (h logHandler) logRequest(r *http.Request, lw *loggingResponseWriter, msg AccessLogRecord) { + // Complete our access log from the loggingResponseWriter. + msg.Bytes = lw.bytes + msg.Seconds = h.opts.Now().Sub(msg.Time).Seconds() + switch { + case msg.Code != 0: + // Keep explicit codes from a few particular errors. + case lw.hijacked: + // Connection no longer belongs to us, just log that we + // switched protocols away from HTTP. + msg.Code = http.StatusSwitchingProtocols + case lw.code == 0: + // If the handler didn't write and didn't send a header, that still means 200. + // (See https://play.golang.org/p/4P7nx_Tap7p) + msg.Code = 200 + default: + msg.Code = lw.code + } + + // Keep track of the original response code when we've overridden it. + if lw.code != 0 && msg.Code != lw.code { + if msg.Err == "" { + msg.Err = fmt.Sprintf("(original code %d)", lw.code) + } else { + msg.Err = fmt.Sprintf("%s (original code %d)", msg.Err, lw.code) + } + } + + if !h.opts.QuietLogging && !(h.opts.QuietLoggingIfSuccessful && (msg.Code == http.StatusOK || msg.Code == http.StatusNotModified)) { + h.opts.Logf("%s", msg) + } + + if h.opts.OnCompletion != nil { + h.opts.OnCompletion(r, msg) + } + + // Closing metrics. + if h.opts.StatusCodeCounters != nil { + h.opts.StatusCodeCounters.Add(responseCodeString(msg.Code/100), 1) + } + if h.opts.StatusCodeCountersFull != nil { + h.opts.StatusCodeCountersFull.Add(responseCodeString(msg.Code), 1) + } +} + +func responseCodeString(code int) string { + if v, ok := responseCodeCache.Load(code); ok { + return v.(string) + } + + var ret string + if code < 10 { + ret = fmt.Sprintf("%dxx", code) + } else { + ret = strconv.Itoa(code) + } + responseCodeCache.Store(code, ret) + return ret +} + +// responseCodeCache memoizes the string form of HTTP response codes, +// so that the hot request-handling codepath doesn't have to allocate +// in strconv/fmt for every request. +// +// Keys are either full HTTP response code ints (200, 404) or "family" +// ints representing entire families (e.g. 2 for 2xx codes). Values +// are the string form of that code/family. +var responseCodeCache sync.Map + +// loggingResponseWriter wraps a ResponseWriter and record the HTTP +// response code that gets sent, if any. +type loggingResponseWriter struct { + http.ResponseWriter + ctx context.Context + code int + bytes int + hijacked bool + logf logger.Logf +} + +// newLogResponseWriter returns a loggingResponseWriter which uses's the logger +// from r, or falls back to logf. If a nil logger is given, the logs are +// discarded. +func newLogResponseWriter(logf logger.Logf, w http.ResponseWriter, r *http.Request) *loggingResponseWriter { + if lg, ok := logger.LogfKey.ValueOk(r.Context()); ok && lg != nil { + logf = lg + } + if logf == nil { + logf = logger.Discard + } + return &loggingResponseWriter{ + ResponseWriter: w, + ctx: r.Context(), + logf: logf, + } +} + +// WriteHeader implements [http.ResponseWriter]. +func (lg *loggingResponseWriter) WriteHeader(statusCode int) { + if lg.code != 0 { + lg.logf("[unexpected] HTTP handler set statusCode twice (%d and %d)", lg.code, statusCode) + return + } + if lg.ctx.Err() == nil { + lg.code = statusCode + } + lg.ResponseWriter.WriteHeader(statusCode) +} + +// Write implements [http.ResponseWriter]. +func (lg *loggingResponseWriter) Write(bs []byte) (int, error) { + if lg.code == 0 { + lg.code = 200 + } + n, err := lg.ResponseWriter.Write(bs) + lg.bytes += n + return n, err +} + +// Hijack implements http.Hijacker. Note that hijacking can still fail +// because the wrapped ResponseWriter is not required to implement +// Hijacker, as this breaks HTTP/2. +func (lg *loggingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + h, ok := lg.ResponseWriter.(http.Hijacker) + if !ok { + return nil, nil, errors.New("ResponseWriter is not a Hijacker") + } + conn, buf, err := h.Hijack() + if err == nil { + lg.hijacked = true + } + return conn, buf, err +} + +func (lg loggingResponseWriter) Flush() { + f, _ := lg.ResponseWriter.(http.Flusher) + if f == nil { + lg.logf("[unexpected] tried to Flush a ResponseWriter that can't flush") + return + } + f.Flush() +} + +func (lg *loggingResponseWriter) Unwrap() http.ResponseWriter { + return lg.ResponseWriter +} + +// errorHandler is an http.Handler that wraps a ReturnHandler to render the +// returned errors to the client and pass them back to any logHandlers. +type errorHandler struct { + rh ReturnHandler + opts ErrorOptions +} + +// ServeHTTP implements the http.Handler interface. +func (h errorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Keep track of whether a response gets written. + lw, ok := w.(*loggingResponseWriter) + if !ok { + lw = newLogResponseWriter(h.opts.Logf, w, r) + } + + var err error + defer func() { + // In case the handler panics, we want to recover and continue logging + // the error before logging it (or re-panicking if we couldn't log). + rec := recover() + if rec != nil { + err = panic2err(rec) + } + if err == nil { + return + } + if h.handleError(w, r, lw, err) { + return + } + if rec != nil { + // If we weren't able to log the panic somewhere, throw it up the + // stack to someone who can. + panic(rec) + } + }() + err = h.rh.ServeHTTPReturn(lw, r) +} + +func (h errorHandler) handleError(w http.ResponseWriter, r *http.Request, lw *loggingResponseWriter, err error) bool { + var logged bool + + // Extract a presentable, loggable error. + var hOK bool + var hErr HTTPError + if errors.As(err, &hErr) { + hOK = true + if hErr.Code == 0 { + lw.logf("[unexpected] HTTPError %v did not contain an HTTP status code, sending internal server error", hErr) + hErr.Code = http.StatusInternalServerError + } + } else if v, ok := vizerror.As(err); ok { + hErr = Error(http.StatusInternalServerError, v.Error(), nil) + } else if reqCancelled(r, err) { + // 499 is the Nginx convention meaning "Client Closed Connection". + if errors.Is(err, context.Canceled) || errors.Is(err, http.ErrAbortHandler) { + hErr = Error(499, "", err) + } else { + hErr = Error(499, "", fmt.Errorf("%w: %w", context.Canceled, err)) + } + } else { + // Omit the friendly message so HTTP logs show the bare error that was + // returned and we know it's not a HTTPError. + hErr = Error(http.StatusInternalServerError, "", err) + } + + // Tell the logger what error we wrote back to the client. + if pb := errCallback.Value(r.Context()); pb != nil { + pb(hErr) + logged = true + } + + if r.Context().Err() != nil { + return logged + } + + if lw.code != 0 { + if hOK && hErr.Code != lw.code { + lw.logf("[unexpected] handler returned HTTPError %v, but already sent response with code %d", hErr, lw.code) + } + return logged + } + + // Set a default error message from the status code. Do this after we pass + // the error back to the logger so that `return errors.New("oh")` logs as + // `"err": "oh"`, not `"err": "Internal Server Error: oh"`. + if hErr.Msg == "" { + switch hErr.Code { + case 499: + hErr.Msg = "Client Closed Request" + default: + hErr.Msg = http.StatusText(hErr.Code) + } + } + + // If OnError panics before a response is written, write a bare 500 back. + // OnError panics are thrown further up the stack. + defer func() { + if lw.code == 0 { + if rec := recover(); rec != nil { + w.WriteHeader(http.StatusInternalServerError) + panic(rec) + } + } + }() + + h.opts.OnError(w, r, hErr) + return logged +} + +// panic2err converts a recovered value to an error containing the panic stack trace. +func panic2err(recovered any) error { + if recovered == nil { + return nil + } + if recovered == http.ErrAbortHandler { + return http.ErrAbortHandler + } + + // Even if r is an error, do not wrap it as an error here as + // that would allow things like panic(vizerror.New("foo")) + // which is really hard to define the behavior of. + var stack [10000]byte + n := runtime.Stack(stack[:], false) + return &panicError{ + rec: recovered, + stack: stack[:n], + } +} + +// panicError is an error that contains a panic. +type panicError struct { + rec any + stack []byte +} + +func (e *panicError) Error() string { + return fmt.Sprintf("panic: %v\n\n%s", e.rec, e.stack) +} + +func (e *panicError) Unwrap() error { + err, _ := e.rec.(error) + return err +} + +// reqCancelled returns true if err is http.ErrAbortHandler or r.Context.Err() +// is context.Canceled. +func reqCancelled(r *http.Request, err error) bool { + return errors.Is(err, http.ErrAbortHandler) || r.Context().Err() == context.Canceled +} + +// WriteHTTPError is the default error response formatter. +func WriteHTTPError(w http.ResponseWriter, r *http.Request, e HTTPError) { + // Don't write a response if we've hit a cancellation/abort. + if r.Context().Err() != nil || errors.Is(e.Err, http.ErrAbortHandler) { + return + } + + // Default headers set by http.Error. + h := w.Header() + h.Set("Content-Type", "text/plain; charset=utf-8") + h.Set("X-Content-Type-Options", "nosniff") + + // Custom headers from the error. + for k, vs := range e.Header { + h[k] = vs + } + + // Write the msg back to the user. + w.WriteHeader(e.Code) + fmt.Fprint(w, e.Msg) + + // If it's a plaintext message, add line breaks and RequestID. + if strings.HasPrefix(h.Get("Content-Type"), "text/plain") { + io.WriteString(w, "\n") + if id := RequestIDFromContext(r.Context()); id != "" { + io.WriteString(w, id.String()) + io.WriteString(w, "\n") + } + } +} + +// HTTPError is an error with embedded HTTP response information. +// +// It is the error type to be (optionally) used by Handler.ServeHTTPReturn. +type HTTPError struct { + Code int // HTTP response code to send to client; 0 means 500 + Msg string // Response body to send to client + Err error // Detailed error to log on the server + Header http.Header // Optional set of HTTP headers to set in the response +} + +// Error implements the error interface. +func (e HTTPError) Error() string { return fmt.Sprintf("httperror{%d, %q, %v}", e.Code, e.Msg, e.Err) } +func (e HTTPError) Unwrap() error { return e.Err } + +// Error returns an HTTPError containing the given information. +func Error(code int, msg string, err error) HTTPError { + return HTTPError{Code: code, Msg: msg, Err: err} +} + +// VarzHandler writes expvar values as Prometheus metrics. +// TODO: migrate all users to varz.Handler or promvarz.Handler and remove this. +func VarzHandler(w http.ResponseWriter, r *http.Request) { + varz.Handler(w, r) +} + +// CleanRedirectURL ensures that urlStr is a valid redirect URL to the +// current server, or one of allowedHosts. Returns the cleaned URL or +// a validation error. +func CleanRedirectURL(urlStr string, allowedHosts []string) (*url.URL, error) { + if urlStr == "" { + return &url.URL{}, nil + } + // In some places, we unfortunately query-escape the redirect URL + // too many times, and end up needing to redirect to a URL that's + // still escaped by one level. Try to unescape the input. + unescaped, err := url.QueryUnescape(urlStr) + if err == nil && unescaped != urlStr { + urlStr = unescaped + } + + // Go's URL parser and browser URL parsers disagree on the meaning + // of malformed HTTP URLs. Given the input https:/evil.com, Go + // parses it as hostname="", path="/evil.com". Browsers parse it + // as hostname="evil.com", path="". This means that, using + // malformed URLs, an attacker could trick us into approving of a + // "local" redirect that in fact sends people elsewhere. + // + // This very blunt check enforces that we'll only process + // redirects that are definitely well-formed URLs. + // + // Note that the check for just / also allows URLs of the form + // "//foo.com/bar", which are scheme-relative redirects. These + // must be handled with care below when determining whether a + // redirect is relative to the current host. Notably, + // url.URL.IsAbs reports // URLs as relative, whereas we want to + // treat them as absolute redirects and verify the target host. + if !hasSafeRedirectPrefix(urlStr) { + return nil, fmt.Errorf("invalid redirect URL %q", urlStr) + } + + url, err := url.Parse(urlStr) + if err != nil { + return nil, fmt.Errorf("invalid redirect URL %q: %w", urlStr, err) + } + // Redirects to self are always allowed. A self redirect must + // start with url.Path, all prior URL sections must be empty. + isSelfRedirect := url.Scheme == "" && url.Opaque == "" && url.User == nil && url.Host == "" + if isSelfRedirect { + return url, nil + } + for _, allowed := range allowedHosts { + if strings.EqualFold(allowed, url.Hostname()) { + return url, nil + } + } + + return nil, fmt.Errorf("disallowed target host %q in redirect URL %q", url.Hostname(), urlStr) +} + +// hasSafeRedirectPrefix reports whether url starts with a slash, or +// one of the case-insensitive strings "http://" or "https://". +func hasSafeRedirectPrefix(url string) bool { + if len(url) >= 1 && url[0] == '/' { + return true + } + const http = "http://" + if len(url) >= len(http) && strings.EqualFold(url[:len(http)], http) { + return true + } + const https = "https://" + if len(url) >= len(https) && strings.EqualFold(url[:len(https)], https) { + return true + } + return false +} + +// AddBrowserHeaders sets various HTTP security headers for browser-facing endpoints. +// +// The specific headers: +// - require HTTPS access (HSTS) +// - disallow iframe embedding +// - mitigate MIME confusion attacks +// +// These headers are based on +// https://infosec.mozilla.org/guidelines/web_security +func AddBrowserHeaders(w http.ResponseWriter) { + w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains") + w.Header().Set("Content-Security-Policy", "default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; block-all-mixed-content; object-src 'none'") + w.Header().Set("X-Frame-Options", "DENY") + w.Header().Set("X-Content-Type-Options", "nosniff") +} + +// BrowserHeaderHandler wraps the provided http.Handler with a call to +// AddBrowserHeaders. +func BrowserHeaderHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + AddBrowserHeaders(w) + h.ServeHTTP(w, r) + }) +} + +// BrowserHeaderHandlerFunc wraps the provided http.HandlerFunc with a call to +// AddBrowserHeaders. +func BrowserHeaderHandlerFunc(h http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + AddBrowserHeaders(w) + h.ServeHTTP(w, r) + } +} diff --git a/vendor/tailscale.com/tsweb/varz/varz.go b/vendor/tailscale.com/tsweb/varz/varz.go index 952ebc2..b1c66b8 100644 --- a/vendor/tailscale.com/tsweb/varz/varz.go +++ b/vendor/tailscale.com/tsweb/varz/varz.go @@ -5,21 +5,28 @@ package varz import ( + "bufio" "cmp" "expvar" "fmt" "io" "net/http" + "os" + "path/filepath" "reflect" "runtime" "sort" + "strconv" "strings" "sync" "time" "unicode" "unicode/utf8" + "golang.org/x/exp/constraints" "tailscale.com/metrics" + "tailscale.com/syncs" + "tailscale.com/types/logger" "tailscale.com/version" ) @@ -130,6 +137,9 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) { case *expvar.Int: fmt.Fprintf(w, "# TYPE %s %s\n%s %v\n", name, cmp.Or(typ, "counter"), name, v.Value()) return + case *syncs.ShardedInt: + fmt.Fprintf(w, "# TYPE %s %s\n%s %v\n", name, cmp.Or(typ, "counter"), name, v.Value()) + return case *expvar.Float: fmt.Fprintf(w, "# TYPE %s %s\n%s %v\n", name, cmp.Or(typ, "gauge"), name, v.Value()) return @@ -185,7 +195,11 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) { return } if vs, ok := v.(string); ok && strings.HasSuffix(name, "version") { - fmt.Fprintf(w, "%s{version=%q} 1\n", name, vs) + if name == "version" { + fmt.Fprintf(w, "%s{version=%q,binary=%q} 1\n", name, vs, binaryName()) + } else { + fmt.Fprintf(w, "%s{version=%q} 1\n", name, vs) + } return } switch v := v.(type) { @@ -304,6 +318,18 @@ func ExpvarDoHandler(expvarDoFunc func(f func(expvar.KeyValue))) func(http.Respo } } +var binaryName = sync.OnceValue(func() string { + exe, err := os.Executable() + if err != nil { + return "" + } + exe2, err := filepath.EvalSymlinks(exe) + if err != nil { + return filepath.Base(exe) + } + return filepath.Base(exe2) +}) + // PrometheusMetricsReflectRooter is an optional interface that expvar.Var implementations // can implement to indicate that they should be walked recursively with reflect to find // sets of fields to export. @@ -316,21 +342,52 @@ type PrometheusMetricsReflectRooter interface { var expvarDo = expvar.Do // pulled out for tests -func writeMemstats(w io.Writer, ms *runtime.MemStats) { - out := func(name, typ string, v uint64, help string) { - if help != "" { - fmt.Fprintf(w, "# HELP memstats_%s %s\n", name, help) - } - fmt.Fprintf(w, "# TYPE memstats_%s %s\nmemstats_%s %v\n", name, typ, name, v) +func writeMemstat[V constraints.Integer | constraints.Float](bw *bufio.Writer, typ, name string, v V, help string) { + if help != "" { + bw.WriteString("# HELP memstats_") + bw.WriteString(name) + bw.WriteString(" ") + bw.WriteString(help) + bw.WriteByte('\n') } - g := func(name string, v uint64, help string) { out(name, "gauge", v, help) } - c := func(name string, v uint64, help string) { out(name, "counter", v, help) } - g("heap_alloc", ms.HeapAlloc, "current bytes of allocated heap objects (up/down smoothly)") - c("total_alloc", ms.TotalAlloc, "cumulative bytes allocated for heap objects") - g("sys", ms.Sys, "total bytes of memory obtained from the OS") - c("mallocs", ms.Mallocs, "cumulative count of heap objects allocated") - c("frees", ms.Frees, "cumulative count of heap objects freed") - c("num_gc", uint64(ms.NumGC), "number of completed GC cycles") + bw.WriteString("# TYPE memstats_") + bw.WriteString(name) + bw.WriteString(" ") + bw.WriteString(typ) + bw.WriteByte('\n') + bw.WriteString("memstats_") + bw.WriteString(name) + bw.WriteByte(' ') + rt := reflect.TypeOf(v) + switch { + case rt == reflect.TypeFor[int]() || + rt == reflect.TypeFor[uint]() || + rt == reflect.TypeFor[int8]() || + rt == reflect.TypeFor[uint8]() || + rt == reflect.TypeFor[int16]() || + rt == reflect.TypeFor[uint16]() || + rt == reflect.TypeFor[int32]() || + rt == reflect.TypeFor[uint32]() || + rt == reflect.TypeFor[int64]() || + rt == reflect.TypeFor[uint64]() || + rt == reflect.TypeFor[uintptr](): + bw.Write(strconv.AppendInt(bw.AvailableBuffer(), int64(v), 10)) + case rt == reflect.TypeFor[float32]() || rt == reflect.TypeFor[float64](): + bw.Write(strconv.AppendFloat(bw.AvailableBuffer(), float64(v), 'f', -1, 64)) + } + bw.WriteByte('\n') +} + +func writeMemstats(w io.Writer, ms *runtime.MemStats) { + fmt.Fprintf(w, "%v", logger.ArgWriter(func(bw *bufio.Writer) { + writeMemstat(bw, "gauge", "heap_alloc", ms.HeapAlloc, "current bytes of allocated heap objects (up/down smoothly)") + writeMemstat(bw, "counter", "total_alloc", ms.TotalAlloc, "cumulative bytes allocated for heap objects") + writeMemstat(bw, "gauge", "sys", ms.Sys, "total bytes of memory obtained from the OS") + writeMemstat(bw, "counter", "mallocs", ms.Mallocs, "cumulative count of heap objects allocated") + writeMemstat(bw, "counter", "frees", ms.Frees, "cumulative count of heap objects freed") + writeMemstat(bw, "counter", "num_gc", ms.NumGC, "number of completed GC cycles") + writeMemstat(bw, "gauge", "gc_cpu_fraction", ms.GCCPUFraction, "fraction of CPU time used by GC") + })) } // sortedStructField is metadata about a struct field used both for sorting once diff --git a/vendor/tailscale.com/types/appctype/appconnector.go b/vendor/tailscale.com/types/appctype/appconnector.go index f4ced65..567ab75 100644 --- a/vendor/tailscale.com/types/appctype/appconnector.go +++ b/vendor/tailscale.com/types/appctype/appconnector.go @@ -73,3 +73,23 @@ type AppConnectorAttr struct { // tag of the form tag:. Connectors []string `json:"connectors,omitempty"` } + +// RouteInfo is a data structure used to persist the in memory state of an AppConnector +// so that we can know, even after a restart, which routes came from ACLs and which were +// learned from domains. +type RouteInfo struct { + // Control is the routes from the 'routes' section of an app connector acl. + Control []netip.Prefix `json:",omitempty"` + // Domains are the routes discovered by observing DNS lookups for configured domains. + Domains map[string][]netip.Addr `json:",omitempty"` + // Wildcards are the configured DNS lookup domains to observe. When a DNS query matches Wildcards, + // its result is added to Domains. + Wildcards []string `json:",omitempty"` +} + +// RouteUpdate records a set of routes that should be advertised and a set of +// routes that should be unadvertised in event bus updates. +type RouteUpdate struct { + Advertise []netip.Prefix + Unadvertise []netip.Prefix +} diff --git a/vendor/tailscale.com/types/dnstype/dnstype.go b/vendor/tailscale.com/types/dnstype/dnstype.go index b7f5b9d..a3ba1b0 100644 --- a/vendor/tailscale.com/types/dnstype/dnstype.go +++ b/vendor/tailscale.com/types/dnstype/dnstype.go @@ -35,6 +35,12 @@ type Resolver struct { // // As of 2022-09-08, BootstrapResolution is not yet used. BootstrapResolution []netip.Addr `json:",omitempty"` + + // UseWithExitNode designates that this resolver should continue to be used when an + // exit node is in use. Normally, DNS resolution is delegated to the exit node but + // there are situations where it is preferable to still use a Split DNS server and/or + // global DNS server instead of the exit node. + UseWithExitNode bool `json:",omitempty"` } // IPPort returns r.Addr as an IP address and port if either @@ -64,5 +70,7 @@ func (r *Resolver) Equal(other *Resolver) bool { return true } - return r.Addr == other.Addr && slices.Equal(r.BootstrapResolution, other.BootstrapResolution) + return r.Addr == other.Addr && + slices.Equal(r.BootstrapResolution, other.BootstrapResolution) && + r.UseWithExitNode == other.UseWithExitNode } diff --git a/vendor/tailscale.com/types/dnstype/dnstype_clone.go b/vendor/tailscale.com/types/dnstype/dnstype_clone.go index 86ca053..3985704 100644 --- a/vendor/tailscale.com/types/dnstype/dnstype_clone.go +++ b/vendor/tailscale.com/types/dnstype/dnstype_clone.go @@ -25,6 +25,7 @@ func (src *Resolver) Clone() *Resolver { var _ResolverCloneNeedsRegeneration = Resolver(struct { Addr string BootstrapResolution []netip.Addr + UseWithExitNode bool }{}) // Clone duplicates src into dst and reports whether it succeeded. diff --git a/vendor/tailscale.com/types/dnstype/dnstype_view.go b/vendor/tailscale.com/types/dnstype/dnstype_view.go index c77ff9a..a983864 100644 --- a/vendor/tailscale.com/types/dnstype/dnstype_view.go +++ b/vendor/tailscale.com/types/dnstype/dnstype_view.go @@ -6,10 +6,12 @@ package dnstype import ( - "encoding/json" + jsonv1 "encoding/json" "errors" "net/netip" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "tailscale.com/types/views" ) @@ -43,8 +45,17 @@ func (v ResolverView) AsStruct() *Resolver { return v.ж.Clone() } -func (v ResolverView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ResolverView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ResolverView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *ResolverView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -53,21 +64,61 @@ func (v *ResolverView) UnmarshalJSON(b []byte) error { return nil } var x Resolver - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *ResolverView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Resolver + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +// Addr is the address of the DNS resolver, one of: +// - A plain IP address for a "classic" UDP+TCP DNS resolver. +// This is the common format as sent by the control plane. +// - An IP:port, for tests. +// - "https://resolver.com/path" for DNS over HTTPS; currently +// as of 2022-09-08 only used for certain well-known resolvers +// (see the publicdns package) for which the IP addresses to dial DoH are +// known ahead of time, so bootstrap DNS resolution is not required. +// - "http://node-address:port/path" for DNS over HTTP over WireGuard. This +// is implemented in the PeerAPI for exit nodes and app connectors. +// - [TODO] "tls://resolver.com" for DNS over TCP+TLS func (v ResolverView) Addr() string { return v.ж.Addr } + +// BootstrapResolution is an optional suggested resolution for the +// DoT/DoH resolver, if the resolver URL does not reference an IP +// address directly. +// BootstrapResolution may be empty, in which case clients should +// look up the DoT/DoH server using their local "classic" DNS +// resolver. +// +// As of 2022-09-08, BootstrapResolution is not yet used. func (v ResolverView) BootstrapResolution() views.Slice[netip.Addr] { return views.SliceOf(v.ж.BootstrapResolution) } + +// UseWithExitNode designates that this resolver should continue to be used when an +// exit node is in use. Normally, DNS resolution is delegated to the exit node but +// there are situations where it is preferable to still use a Split DNS server and/or +// global DNS server instead of the exit node. +func (v ResolverView) UseWithExitNode() bool { return v.ж.UseWithExitNode } func (v ResolverView) Equal(v2 ResolverView) bool { return v.ж.Equal(v2.ж) } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _ResolverViewNeedsRegeneration = Resolver(struct { Addr string BootstrapResolution []netip.Addr + UseWithExitNode bool }{}) diff --git a/vendor/tailscale.com/types/dnstype/messagetypes-string.go b/vendor/tailscale.com/types/dnstype/messagetypes-string.go deleted file mode 100644 index 34abea1..0000000 --- a/vendor/tailscale.com/types/dnstype/messagetypes-string.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package dnstype - -import ( - "errors" - "strings" - - "golang.org/x/net/dns/dnsmessage" -) - -// StringForType returns the string representation of a dnsmessage.Type. -// For example, StringForType(dnsmessage.TypeA) returns "A". -func StringForDNSMessageType(t dnsmessage.Type) string { - switch t { - case dnsmessage.TypeAAAA: - return "AAAA" - case dnsmessage.TypeALL: - return "ALL" - case dnsmessage.TypeA: - return "A" - case dnsmessage.TypeCNAME: - return "CNAME" - case dnsmessage.TypeHINFO: - return "HINFO" - case dnsmessage.TypeMINFO: - return "MINFO" - case dnsmessage.TypeMX: - return "MX" - case dnsmessage.TypeNS: - return "NS" - case dnsmessage.TypeOPT: - return "OPT" - case dnsmessage.TypePTR: - return "PTR" - case dnsmessage.TypeSOA: - return "SOA" - case dnsmessage.TypeSRV: - return "SRV" - case dnsmessage.TypeTXT: - return "TXT" - case dnsmessage.TypeWKS: - return "WKS" - } - return "UNKNOWN" -} - -// DNSMessageTypeForString returns the dnsmessage.Type for the given string. -// For example, DNSMessageTypeForString("A") returns dnsmessage.TypeA. -func DNSMessageTypeForString(s string) (t dnsmessage.Type, err error) { - s = strings.TrimSpace(strings.ToUpper(s)) - switch s { - case "AAAA": - return dnsmessage.TypeAAAA, nil - case "ALL": - return dnsmessage.TypeALL, nil - case "A": - return dnsmessage.TypeA, nil - case "CNAME": - return dnsmessage.TypeCNAME, nil - case "HINFO": - return dnsmessage.TypeHINFO, nil - case "MINFO": - return dnsmessage.TypeMINFO, nil - case "MX": - return dnsmessage.TypeMX, nil - case "NS": - return dnsmessage.TypeNS, nil - case "OPT": - return dnsmessage.TypeOPT, nil - case "PTR": - return dnsmessage.TypePTR, nil - case "SOA": - return dnsmessage.TypeSOA, nil - case "SRV": - return dnsmessage.TypeSRV, nil - case "TXT": - return dnsmessage.TypeTXT, nil - case "WKS": - return dnsmessage.TypeWKS, nil - } - return 0, errors.New("unknown DNS message type: " + s) -} diff --git a/vendor/tailscale.com/types/key/derp.go b/vendor/tailscale.com/types/key/derp.go new file mode 100644 index 0000000..1466b85 --- /dev/null +++ b/vendor/tailscale.com/types/key/derp.go @@ -0,0 +1,90 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package key + +import ( + "crypto/subtle" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "strings" + + "go4.org/mem" + "tailscale.com/types/structs" +) + +var ErrInvalidMeshKey = errors.New("invalid mesh key") + +// DERPMesh is a mesh key, used for inter-DERP-node communication and for +// privileged DERP clients. +type DERPMesh struct { + _ structs.Incomparable // == isn't constant-time + k [32]byte // 64-digit hexadecimal numbers fit in 32 bytes +} + +// MarshalJSON implements the [encoding/json.Marshaler] interface. +func (k DERPMesh) MarshalJSON() ([]byte, error) { + return json.Marshal(k.String()) +} + +// UnmarshalJSON implements the [encoding/json.Unmarshaler] interface. +func (k *DERPMesh) UnmarshalJSON(data []byte) error { + var s string + json.Unmarshal(data, &s) + + if hex.DecodedLen(len(s)) != len(k.k) { + return fmt.Errorf("types/key/derp: cannot unmarshal, incorrect size mesh key len: %d, must be %d, %w", hex.DecodedLen(len(s)), len(k.k), ErrInvalidMeshKey) + } + _, err := hex.Decode(k.k[:], []byte(s)) + if err != nil { + return fmt.Errorf("types/key/derp: cannot unmarshal, invalid mesh key: %w", err) + } + + return nil +} + +// DERPMeshFromRaw32 parses a 32-byte raw value as a DERP mesh key. +func DERPMeshFromRaw32(raw mem.RO) DERPMesh { + if raw.Len() != 32 { + panic("input has wrong size") + } + var ret DERPMesh + raw.Copy(ret.k[:]) + return ret +} + +// ParseDERPMesh parses a DERP mesh key from a string. +// This function trims whitespace around the string. +// If the key is not a 64-digit hexadecimal number, ErrInvalidMeshKey is returned. +func ParseDERPMesh(key string) (DERPMesh, error) { + key = strings.TrimSpace(key) + if len(key) != 64 { + return DERPMesh{}, fmt.Errorf("%w: must be 64-digit hexadecimal number", ErrInvalidMeshKey) + } + decoded, err := hex.DecodeString(key) + if err != nil { + return DERPMesh{}, fmt.Errorf("%w: %v", ErrInvalidMeshKey, err) + } + return DERPMeshFromRaw32(mem.B(decoded)), nil +} + +// IsZero reports whether k is the zero value. +func (k DERPMesh) IsZero() bool { + return k.Equal(DERPMesh{}) +} + +// Equal reports whether k and other are the same key. +func (k DERPMesh) Equal(other DERPMesh) bool { + // Compare mesh keys in constant time to prevent timing attacks. + // Since mesh keys are a fixed length, we don’t need to be concerned + // about timing attacks on client mesh keys that are the wrong length. + // See https://github.com/tailscale/corp/issues/28720 + return subtle.ConstantTimeCompare(k.k[:], other.k[:]) == 1 +} + +// String returns k as a hex-encoded 64-digit number. +func (k DERPMesh) String() string { + return hex.EncodeToString(k.k[:]) +} diff --git a/vendor/tailscale.com/types/key/disco.go b/vendor/tailscale.com/types/key/disco.go index 1013ce5..52b40c7 100644 --- a/vendor/tailscale.com/types/key/disco.go +++ b/vendor/tailscale.com/types/key/disco.go @@ -73,6 +73,44 @@ func (k DiscoPrivate) Shared(p DiscoPublic) DiscoShared { return ret } +// SortedPairOfDiscoPublic is a lexicographically sorted container of two +// [DiscoPublic] keys. +type SortedPairOfDiscoPublic struct { + k [2]DiscoPublic +} + +// Get returns the underlying keys. +func (s SortedPairOfDiscoPublic) Get() [2]DiscoPublic { + return s.k +} + +// NewSortedPairOfDiscoPublic returns a SortedPairOfDiscoPublic from a and b. +func NewSortedPairOfDiscoPublic(a, b DiscoPublic) SortedPairOfDiscoPublic { + s := SortedPairOfDiscoPublic{} + if a.Compare(b) < 0 { + s.k[0] = a + s.k[1] = b + } else { + s.k[0] = b + s.k[1] = a + } + return s +} + +func (s SortedPairOfDiscoPublic) String() string { + return fmt.Sprintf("%s <=> %s", s.k[0].ShortString(), s.k[1].ShortString()) +} + +// Equal returns true if s and b are equal, otherwise it returns false. +func (s SortedPairOfDiscoPublic) Equal(b SortedPairOfDiscoPublic) bool { + for i := range s.k { + if s.k[i].Compare(b.k[i]) != 0 { + return false + } + } + return true +} + // DiscoPublic is the public portion of a DiscoPrivate. type DiscoPublic struct { k [32]byte @@ -129,11 +167,11 @@ func (k DiscoPublic) String() string { } // Compare returns an integer comparing DiscoPublic k and l lexicographically. -// The result will be 0 if k == l, -1 if k < l, and +1 if k > l. This is useful -// for situations requiring only one node in a pair to perform some operation, -// e.g. probing UDP path lifetime. -func (k DiscoPublic) Compare(l DiscoPublic) int { - return bytes.Compare(k.k[:], l.k[:]) +// The result will be 0 if k == other, -1 if k < other, and +1 if k > other. +// This is useful for situations requiring only one node in a pair to perform +// some operation, e.g. probing UDP path lifetime. +func (k DiscoPublic) Compare(other DiscoPublic) int { + return bytes.Compare(k.k[:], other.k[:]) } // AppendText implements encoding.TextAppender. diff --git a/vendor/tailscale.com/types/key/hardware_attestation.go b/vendor/tailscale.com/types/key/hardware_attestation.go new file mode 100644 index 0000000..9d4a21e --- /dev/null +++ b/vendor/tailscale.com/types/key/hardware_attestation.go @@ -0,0 +1,181 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package key + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/subtle" + "encoding/json" + "fmt" + "io" + + "go4.org/mem" +) + +var ErrUnsupported = fmt.Errorf("key type not supported on this platform") + +const hardwareAttestPublicHexPrefix = "hwattestpub:" + +const pubkeyLength = 65 // uncompressed P-256 + +// HardwareAttestationKey describes a hardware-backed key that is used to +// identify a node. Implementation details will +// vary based on the platform in use (SecureEnclave for Apple, TPM for +// Windows/Linux, Android Hardware-backed Keystore). +// This key can only be marshalled and unmarshaled on the same machine. +type HardwareAttestationKey interface { + crypto.Signer + json.Marshaler + json.Unmarshaler + io.Closer + Clone() HardwareAttestationKey + IsZero() bool +} + +// HardwareAttestationPublicFromPlatformKey creates a HardwareAttestationPublic +// for communicating the public component of the hardware attestation key +// with control and other nodes. +func HardwareAttestationPublicFromPlatformKey(k HardwareAttestationKey) HardwareAttestationPublic { + if k == nil { + return HardwareAttestationPublic{} + } + pub := k.Public() + ecdsaPub, ok := pub.(*ecdsa.PublicKey) + if !ok { + panic("hardware attestation key is not ECDSA") + } + bytes, err := ecdsaPub.Bytes() + if err != nil { + panic(err) + } + if len(bytes) != pubkeyLength { + panic("hardware attestation key is not uncompressed ECDSA P-256") + } + var ecdsaPubArr [pubkeyLength]byte + copy(ecdsaPubArr[:], bytes) + return HardwareAttestationPublic{k: ecdsaPubArr} +} + +// HardwareAttestationPublic is the public key counterpart to +// HardwareAttestationKey. +type HardwareAttestationPublic struct { + k [pubkeyLength]byte +} + +func (k *HardwareAttestationPublic) Clone() *HardwareAttestationPublic { + if k == nil { + return nil + } + var out HardwareAttestationPublic + copy(out.k[:], k.k[:]) + return &out +} + +func (k HardwareAttestationPublic) Equal(o HardwareAttestationPublic) bool { + return subtle.ConstantTimeCompare(k.k[:], o.k[:]) == 1 +} + +// IsZero reports whether k is the zero value. +func (k HardwareAttestationPublic) IsZero() bool { + var zero [pubkeyLength]byte + return k.k == zero +} + +// String returns the hex-encoded public key with a type prefix. +func (k HardwareAttestationPublic) String() string { + bs, err := k.MarshalText() + if err != nil { + panic(err) + } + return string(bs) +} + +// MarshalText implements encoding.TextMarshaler. +func (k HardwareAttestationPublic) MarshalText() ([]byte, error) { + if k.IsZero() { + return nil, nil + } + return k.AppendText(nil) +} + +// UnmarshalText implements encoding.TextUnmarshaler. It expects a typed prefix +// followed by a hex encoded representation of k. +func (k *HardwareAttestationPublic) UnmarshalText(b []byte) error { + if len(b) == 0 { + *k = HardwareAttestationPublic{} + return nil + } + + kb := make([]byte, pubkeyLength) + if err := parseHex(kb, mem.B(b), mem.S(hardwareAttestPublicHexPrefix)); err != nil { + return err + } + + _, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), kb) + if err != nil { + return err + } + copy(k.k[:], kb) + return nil +} + +func (k HardwareAttestationPublic) AppendText(dst []byte) ([]byte, error) { + return appendHexKey(dst, hardwareAttestPublicHexPrefix, k.k[:]), nil +} + +// Verifier returns the ECDSA public key for verifying signatures made by k. +func (k HardwareAttestationPublic) Verifier() *ecdsa.PublicKey { + pk, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), k.k[:]) + if err != nil { + panic(err) + } + return pk +} + +// emptyHardwareAttestationKey is a function that returns an empty +// HardwareAttestationKey suitable for use with JSON unmarshaling. +var emptyHardwareAttestationKey func() HardwareAttestationKey + +// createHardwareAttestationKey is a function that creates a new +// HardwareAttestationKey for the current platform. +var createHardwareAttestationKey func() (HardwareAttestationKey, error) + +// HardwareAttestationKeyFn is a callback function type that returns a HardwareAttestationKey +// and an error. It is used to register platform-specific implementations of +// HardwareAttestationKey. +type HardwareAttestationKeyFn func() (HardwareAttestationKey, error) + +// RegisterHardwareAttestationKeyFns registers a hardware attestation +// key implementation for the current platform. +func RegisterHardwareAttestationKeyFns(emptyFn func() HardwareAttestationKey, createFn HardwareAttestationKeyFn) { + if emptyHardwareAttestationKey != nil { + panic("emptyPlatformHardwareAttestationKey already registered") + } + emptyHardwareAttestationKey = emptyFn + + if createHardwareAttestationKey != nil { + panic("createPlatformHardwareAttestationKey already registered") + } + createHardwareAttestationKey = createFn +} + +// NewEmptyHardwareAttestationKey returns an empty HardwareAttestationKey +// suitable for JSON unmarshaling. +func NewEmptyHardwareAttestationKey() (HardwareAttestationKey, error) { + if emptyHardwareAttestationKey == nil { + return nil, ErrUnsupported + } + return emptyHardwareAttestationKey(), nil +} + +// NewHardwareAttestationKey returns a newly created HardwareAttestationKey for +// the current platform. +func NewHardwareAttestationKey() (HardwareAttestationKey, error) { + if createHardwareAttestationKey == nil { + return nil, ErrUnsupported + } + return createHardwareAttestationKey() +} diff --git a/vendor/tailscale.com/types/key/util.go b/vendor/tailscale.com/types/key/util.go index bdb2a06..50fac82 100644 --- a/vendor/tailscale.com/types/key/util.go +++ b/vendor/tailscale.com/types/key/util.go @@ -10,9 +10,12 @@ import ( "errors" "fmt" "io" + "reflect" "slices" "go4.org/mem" + "tailscale.com/util/set" + "tailscale.com/util/testenv" ) // rand fills b with cryptographically strong random bytes. Panics if @@ -115,3 +118,18 @@ func debug32(k [32]byte) string { dst[6] = ']' return string(dst[:7]) } + +// PrivateTypesForTest returns the set of private key types +// in this package, for testing purposes. +func PrivateTypesForTest() set.Set[reflect.Type] { + testenv.AssertInTest() + return set.Of( + reflect.TypeFor[ChallengePrivate](), + reflect.TypeFor[ControlPrivate](), + reflect.TypeFor[DiscoPrivate](), + reflect.TypeFor[MachinePrivate](), + reflect.TypeFor[NodePrivate](), + reflect.TypeFor[NLPrivate](), + reflect.TypeFor[HardwareAttestationKey](), + ) +} diff --git a/vendor/tailscale.com/types/lazy/lazy.go b/vendor/tailscale.com/types/lazy/lazy.go index c29a03d..f537758 100644 --- a/vendor/tailscale.com/types/lazy/lazy.go +++ b/vendor/tailscale.com/types/lazy/lazy.go @@ -23,6 +23,9 @@ var nilErrPtr = ptr.To[error](nil) // Recursive use of a SyncValue from its own fill function will deadlock. // // SyncValue is safe for concurrent use. +// +// Unlike [sync.OnceValue], the linker can do better dead code elimination +// with SyncValue. See https://github.com/golang/go/issues/62202. type SyncValue[T any] struct { once sync.Once v T @@ -120,9 +123,9 @@ func (z *SyncValue[T]) PeekErr() (v T, err error, ok bool) { return zero, nil, false } -// TB is a subset of testing.TB that we use to set up test helpers. +// testing_TB is a subset of testing.TB that we use to set up test helpers. // It's defined here to avoid pulling in the testing package. -type TB interface { +type testing_TB interface { Helper() Cleanup(func()) } @@ -132,7 +135,9 @@ type TB interface { // subtests complete. // It is not safe for concurrent use and must not be called concurrently with // any SyncValue methods, including another call to itself. -func (z *SyncValue[T]) SetForTest(tb TB, val T, err error) { +// +// The provided tb should be a [*testing.T] or [*testing.B]. +func (z *SyncValue[T]) SetForTest(tb testing_TB, val T, err error) { tb.Helper() oldErr, oldVal := z.err.Load(), z.v diff --git a/vendor/tailscale.com/types/lazy/map.go b/vendor/tailscale.com/types/lazy/map.go new file mode 100644 index 0000000..75a1dd7 --- /dev/null +++ b/vendor/tailscale.com/types/lazy/map.go @@ -0,0 +1,62 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package lazy + +import "tailscale.com/util/mak" + +// GMap is a map of lazily computed [GValue] pointers, keyed by a comparable +// type. +// +// Use either Get or GetErr, depending on whether your fill function returns an +// error. +// +// GMap is not safe for concurrent use. +type GMap[K comparable, V any] struct { + store map[K]*GValue[V] +} + +// Len returns the number of entries in the map. +func (s *GMap[K, V]) Len() int { + return len(s.store) +} + +// Set attempts to set the value of k to v, and reports whether it succeeded. +// Set only succeeds if k has never been called with Get/GetErr/Set before. +func (s *GMap[K, V]) Set(k K, v V) bool { + z, ok := s.store[k] + if !ok { + z = new(GValue[V]) + mak.Set(&s.store, k, z) + } + return z.Set(v) +} + +// MustSet sets the value of k to v, or panics if k already has a value. +func (s *GMap[K, V]) MustSet(k K, v V) { + if !s.Set(k, v) { + panic("Set after already filled") + } +} + +// Get returns the value for k, computing it with fill if it's not already +// present. +func (s *GMap[K, V]) Get(k K, fill func() V) V { + z, ok := s.store[k] + if !ok { + z = new(GValue[V]) + mak.Set(&s.store, k, z) + } + return z.Get(fill) +} + +// GetErr returns the value for k, computing it with fill if it's not already +// present. +func (s *GMap[K, V]) GetErr(k K, fill func() (V, error)) (V, error) { + z, ok := s.store[k] + if !ok { + z = new(GValue[V]) + mak.Set(&s.store, k, z) + } + return z.GetErr(fill) +} diff --git a/vendor/tailscale.com/types/logger/logger.go b/vendor/tailscale.com/types/logger/logger.go index 11596b3..6c4edf6 100644 --- a/vendor/tailscale.com/types/logger/logger.go +++ b/vendor/tailscale.com/types/logger/logger.go @@ -14,6 +14,7 @@ import ( "fmt" "io" "log" + "runtime" "strings" "sync" "time" @@ -23,6 +24,7 @@ import ( "go4.org/mem" "tailscale.com/envknob" "tailscale.com/util/ctxkey" + "tailscale.com/util/testenv" ) // Logf is the basic Tailscale logger type: a printf-like func. @@ -162,6 +164,10 @@ func RateLimitedFnWithClock(logf Logf, f time.Duration, burst int, maxCache int, if envknob.String("TS_DEBUG_LOG_RATE") == "all" { return logf } + if runtime.GOOS == "plan9" { + // To ease bring-up. + return logf + } var ( mu sync.Mutex msgLim = make(map[string]*limitData) // keyed by logf format @@ -317,6 +323,7 @@ func (fn ArgWriter) Format(f fmt.State, _ rune) { bw.Reset(f) fn(bw) bw.Flush() + bw.Reset(io.Discard) argBufioPool.Put(bw) } @@ -379,16 +386,10 @@ func (a asJSONResult) Format(s fmt.State, verb rune) { s.Write(v) } -// TBLogger is the testing.TB subset needed by TestLogger. -type TBLogger interface { - Helper() - Logf(format string, args ...any) -} - // TestLogger returns a logger that logs to tb.Logf // with a prefix to make it easier to distinguish spam // from explicit test failures. -func TestLogger(tb TBLogger) Logf { +func TestLogger(tb testenv.TB) Logf { return func(format string, args ...any) { tb.Helper() tb.Logf(" ... "+format, args...) diff --git a/vendor/tailscale.com/types/mapx/ordered.go b/vendor/tailscale.com/types/mapx/ordered.go new file mode 100644 index 0000000..1991f03 --- /dev/null +++ b/vendor/tailscale.com/types/mapx/ordered.go @@ -0,0 +1,111 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package mapx contains extra map types and functions. +package mapx + +import ( + "iter" + "slices" +) + +// OrderedMap is a map that maintains the order of its keys. +// +// It is meant for maps that only grow or that are small; +// is it not optimized for deleting keys. +// +// The zero value is ready to use. +// +// Locking-wise, it has the same rules as a regular Go map: +// concurrent reads are safe, but not writes. +type OrderedMap[K comparable, V any] struct { + // m is the underlying map. + m map[K]V + + // keys is the order of keys in the map. + keys []K +} + +func (m *OrderedMap[K, V]) init() { + if m.m == nil { + m.m = make(map[K]V) + } +} + +// Set sets the value for the given key in the map. +// +// If the key already exists, it updates the value and keeps the order. +func (m *OrderedMap[K, V]) Set(key K, value V) { + m.init() + len0 := len(m.keys) + m.m[key] = value + if len(m.m) > len0 { + // New key (not an update) + m.keys = append(m.keys, key) + } +} + +// Get returns the value for the given key in the map. +// If the key does not exist, it returns the zero value for V. +func (m *OrderedMap[K, V]) Get(key K) V { + return m.m[key] +} + +// GetOk returns the value for the given key in the map +// and whether it was present in the map. +func (m *OrderedMap[K, V]) GetOk(key K) (_ V, ok bool) { + v, ok := m.m[key] + return v, ok +} + +// Contains reports whether the map contains the given key. +func (m *OrderedMap[K, V]) Contains(key K) bool { + _, ok := m.m[key] + return ok +} + +// Delete removes the key from the map. +// +// The cost is O(n) in the number of keys in the map. +func (m *OrderedMap[K, V]) Delete(key K) { + len0 := len(m.m) + delete(m.m, key) + if len(m.m) == len0 { + // Wasn't present; no need to adjust keys. + return + } + was := m.keys + m.keys = m.keys[:0] + for _, k := range was { + if k != key { + m.keys = append(m.keys, k) + } + } +} + +// All yields all the keys and values, in the order they were inserted. +func (m *OrderedMap[K, V]) All() iter.Seq2[K, V] { + return func(yield func(K, V) bool) { + for _, k := range m.keys { + if !yield(k, m.m[k]) { + return + } + } + } +} + +// Keys yields the map keys, in the order they were inserted. +func (m *OrderedMap[K, V]) Keys() iter.Seq[K] { + return slices.Values(m.keys) +} + +// Values yields the map values, in the order they were inserted. +func (m *OrderedMap[K, V]) Values() iter.Seq[V] { + return func(yield func(V) bool) { + for _, k := range m.keys { + if !yield(m.m[k]) { + return + } + } + } +} diff --git a/vendor/tailscale.com/types/netlogfunc/netlogfunc.go b/vendor/tailscale.com/types/netlogfunc/netlogfunc.go new file mode 100644 index 0000000..6185fcb --- /dev/null +++ b/vendor/tailscale.com/types/netlogfunc/netlogfunc.go @@ -0,0 +1,15 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package netlogfunc defines types for network logging. +package netlogfunc + +import ( + "net/netip" + + "tailscale.com/types/ipproto" +) + +// ConnectionCounter is a function for counting packets and bytes +// for a particular connection. +type ConnectionCounter func(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, recv bool) diff --git a/vendor/tailscale.com/types/netlogtype/netlogtype.go b/vendor/tailscale.com/types/netlogtype/netlogtype.go index f2fa2bd..cc38684 100644 --- a/vendor/tailscale.com/types/netlogtype/netlogtype.go +++ b/vendor/tailscale.com/types/netlogtype/netlogtype.go @@ -5,38 +5,44 @@ package netlogtype import ( + "maps" "net/netip" + "sync" "time" "tailscale.com/tailcfg" "tailscale.com/types/ipproto" ) -// TODO(joetsai): Remove "omitempty" if "omitzero" is ever supported in both -// the v1 and v2 "json" packages. - // Message is the log message that captures network traffic. type Message struct { - NodeID tailcfg.StableNodeID `json:"nodeId" cbor:"0,keyasint"` // e.g., "n123456CNTRL" + NodeID tailcfg.StableNodeID `json:"nodeId"` // e.g., "n123456CNTRL" - Start time.Time `json:"start" cbor:"12,keyasint"` // inclusive - End time.Time `json:"end" cbor:"13,keyasint"` // inclusive + Start time.Time `json:"start"` // inclusive + End time.Time `json:"end"` // inclusive - VirtualTraffic []ConnectionCounts `json:"virtualTraffic,omitempty" cbor:"14,keyasint,omitempty"` - SubnetTraffic []ConnectionCounts `json:"subnetTraffic,omitempty" cbor:"15,keyasint,omitempty"` - ExitTraffic []ConnectionCounts `json:"exitTraffic,omitempty" cbor:"16,keyasint,omitempty"` - PhysicalTraffic []ConnectionCounts `json:"physicalTraffic,omitempty" cbor:"17,keyasint,omitempty"` + SrcNode Node `json:"srcNode,omitzero"` + DstNodes []Node `json:"dstNodes,omitempty"` + + VirtualTraffic []ConnectionCounts `json:"virtualTraffic,omitempty"` + SubnetTraffic []ConnectionCounts `json:"subnetTraffic,omitempty"` + ExitTraffic []ConnectionCounts `json:"exitTraffic,omitempty"` + PhysicalTraffic []ConnectionCounts `json:"physicalTraffic,omitempty"` } const ( - messageJSON = `{"nodeId":"n0123456789abcdefCNTRL",` + maxJSONTimeRange + `,` + minJSONTraffic + `}` + messageJSON = `{"nodeId":` + maxJSONStableID + `,` + minJSONNodes + `,` + maxJSONTimeRange + `,` + minJSONTraffic + `}` + maxJSONStableID = `"n0123456789abcdefCNTRL"` + minJSONNodes = `"srcNode":{},"dstNodes":[]` maxJSONTimeRange = `"start":` + maxJSONRFC3339 + `,"end":` + maxJSONRFC3339 maxJSONRFC3339 = `"0001-01-01T00:00:00.000000000Z"` minJSONTraffic = `"virtualTraffic":{},"subnetTraffic":{},"exitTraffic":{},"physicalTraffic":{}` - // MaxMessageJSONSize is the overhead size of Message when it is - // serialized as JSON assuming that each traffic map is populated. - MaxMessageJSONSize = len(messageJSON) + // MinMessageJSONSize is the overhead size of Message when it is + // serialized as JSON assuming that each field is minimally populated. + // Each [Node] occupies at least [MinNodeJSONSize]. + // Each [ConnectionCounts] occupies at most [MaxConnectionCountsJSONSize]. + MinMessageJSONSize = len(messageJSON) maxJSONConnCounts = `{` + maxJSONConn + `,` + maxJSONCounts + `}` maxJSONConn = `"proto":` + maxJSONProto + `,"src":` + maxJSONAddrPort + `,"dst":` + maxJSONAddrPort @@ -51,20 +57,31 @@ const ( // this object is nested within an array. // It assumes that netip.Addr never has IPv6 zones. MaxConnectionCountsJSONSize = len(maxJSONConnCounts) - - maxCBORConnCounts = "\xbf" + maxCBORConn + maxCBORCounts + "\xff" - maxCBORConn = "\x00" + maxCBORProto + "\x01" + maxCBORAddrPort + "\x02" + maxCBORAddrPort - maxCBORProto = "\x18\xff" - maxCBORAddrPort = "\x52\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - maxCBORCounts = "\x0c" + maxCBORCount + "\x0d" + maxCBORCount + "\x0e" + maxCBORCount + "\x0f" + maxCBORCount - maxCBORCount = "\x1b\xff\xff\xff\xff\xff\xff\xff\xff" - - // MaxConnectionCountsCBORSize is the maximum size of a ConnectionCounts - // when it is serialized as CBOR. - // It assumes that netip.Addr never has IPv6 zones. - MaxConnectionCountsCBORSize = len(maxCBORConnCounts) ) +// Node is information about a node. +type Node struct { + // NodeID is the stable ID of the node. + NodeID tailcfg.StableNodeID `json:"nodeId"` + + // Name is the fully-qualified name of the node. + Name string `json:"name,omitzero"` // e.g., "carbonite.example.ts.net" + + // Addresses are the Tailscale IP addresses of the node. + Addresses []netip.Addr `json:"addresses,omitempty"` + + // OS is the operating system of the node. + OS string `json:"os,omitzero"` // e.g., "linux" + + // User is the user that owns the node. + // It is not populated if the node is tagged. + User string `json:"user,omitzero"` // e.g., "johndoe@example.com" + + // Tags are the tags of the node. + // It is not populated if the node is owned by a user. + Tags []string `json:"tags,omitempty"` // e.g., ["tag:prod","tag:logs"] +} + // ConnectionCounts is a flattened struct of both a connection and counts. type ConnectionCounts struct { Connection @@ -73,19 +90,19 @@ type ConnectionCounts struct { // Connection is a 5-tuple of proto, source and destination IP and port. type Connection struct { - Proto ipproto.Proto `json:"proto,omitzero,omitempty" cbor:"0,keyasint,omitempty"` - Src netip.AddrPort `json:"src,omitzero,omitempty" cbor:"1,keyasint,omitempty"` - Dst netip.AddrPort `json:"dst,omitzero,omitempty" cbor:"2,keyasint,omitempty"` + Proto ipproto.Proto `json:"proto,omitzero"` + Src netip.AddrPort `json:"src,omitzero"` + Dst netip.AddrPort `json:"dst,omitzero"` } func (c Connection) IsZero() bool { return c == Connection{} } // Counts are statistics about a particular connection. type Counts struct { - TxPackets uint64 `json:"txPkts,omitzero,omitempty" cbor:"12,keyasint,omitempty"` - TxBytes uint64 `json:"txBytes,omitzero,omitempty" cbor:"13,keyasint,omitempty"` - RxPackets uint64 `json:"rxPkts,omitzero,omitempty" cbor:"14,keyasint,omitempty"` - RxBytes uint64 `json:"rxBytes,omitzero,omitempty" cbor:"15,keyasint,omitempty"` + TxPackets uint64 `json:"txPkts,omitzero"` + TxBytes uint64 `json:"txBytes,omitzero"` + RxPackets uint64 `json:"rxPkts,omitzero"` + RxBytes uint64 `json:"rxBytes,omitzero"` } func (c Counts) IsZero() bool { return c == Counts{} } @@ -98,3 +115,43 @@ func (c1 Counts) Add(c2 Counts) Counts { c1.RxBytes += c2.RxBytes return c1 } + +// CountsByConnection is a count of packets and bytes for each connection. +// All methods are safe for concurrent calls. +type CountsByConnection struct { + mu sync.Mutex + m map[Connection]Counts +} + +// Add adds packets and bytes for the specified connection. +func (c *CountsByConnection) Add(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, recv bool) { + conn := Connection{Proto: proto, Src: src, Dst: dst} + c.mu.Lock() + defer c.mu.Unlock() + if c.m == nil { + c.m = make(map[Connection]Counts) + } + cnts := c.m[conn] + if recv { + cnts.RxPackets += uint64(packets) + cnts.RxBytes += uint64(bytes) + } else { + cnts.TxPackets += uint64(packets) + cnts.TxBytes += uint64(bytes) + } + c.m[conn] = cnts +} + +// Clone deep copies the map. +func (c *CountsByConnection) Clone() map[Connection]Counts { + c.mu.Lock() + defer c.mu.Unlock() + return maps.Clone(c.m) +} + +// Reset clear the map. +func (c *CountsByConnection) Reset() { + c.mu.Lock() + defer c.mu.Unlock() + clear(c.m) +} diff --git a/vendor/tailscale.com/types/netmap/netmap.go b/vendor/tailscale.com/types/netmap/netmap.go index b1eecaa..18abd1c 100644 --- a/vendor/tailscale.com/types/netmap/netmap.go +++ b/vendor/tailscale.com/types/netmap/netmap.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "tailscale.com/net/tsaddr" "tailscale.com/tailcfg" "tailscale.com/tka" "tailscale.com/types/key" @@ -26,14 +27,9 @@ import ( // The fields should all be considered read-only. They might // alias parts of previous NetworkMap values. type NetworkMap struct { - SelfNode tailcfg.NodeView - AllCaps set.Set[tailcfg.NodeCapability] // set version of SelfNode.Capabilities + SelfNode.CapMap - NodeKey key.NodePublic - PrivateKey key.NodePrivate - Expiry time.Time - // Name is the DNS name assigned to this node. - // It is the MapResponse.Node.Name value and ends with a period. - Name string + SelfNode tailcfg.NodeView + AllCaps set.Set[tailcfg.NodeCapability] // set version of SelfNode.Capabilities + SelfNode.CapMap + NodeKey key.NodePublic MachineKey key.MachinePublic @@ -54,12 +50,12 @@ type NetworkMap struct { // between updates and should not be modified. DERPMap *tailcfg.DERPMap - // ControlHealth are the list of health check problems for this + // DisplayMessages are the list of health check problems for this // node from the perspective of the control plane. // If empty, there are no known problems from the control plane's // point of view, but the node might know about its own health // check problems. - ControlHealth []string + DisplayMessages map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage // TKAEnabled indicates whether the tailnet key authority should be // enabled, from the perspective of the control plane. @@ -148,11 +144,22 @@ func (nm *NetworkMap) GetIPVIPServiceMap() IPServiceMappings { return res } +// SelfNodeOrZero returns the self node, or a zero value if nm is nil. +func (nm *NetworkMap) SelfNodeOrZero() tailcfg.NodeView { + if nm == nil { + return tailcfg.NodeView{} + } + return nm.SelfNode +} + // AnyPeersAdvertiseRoutes reports whether any peer is advertising non-exit node routes. func (nm *NetworkMap) AnyPeersAdvertiseRoutes() bool { for _, p := range nm.Peers { - if p.PrimaryRoutes().Len() > 0 { - return true + // NOTE: (ChaosInTheCRD) if the peer being advertised is a tailscale ip, we ignore it in this check + for _, r := range p.PrimaryRoutes().All() { + if !tsaddr.IsTailscaleIP(r.Addr()) || !r.IsSingleIP() { + return true + } } } return false @@ -228,10 +235,25 @@ func MagicDNSSuffixOfNodeName(nodeName string) string { // // It will neither start nor end with a period. func (nm *NetworkMap) MagicDNSSuffix() string { - if nm == nil { + return MagicDNSSuffixOfNodeName(nm.SelfName()) +} + +// SelfName returns nm.SelfNode.Name, or the empty string +// if nm is nil or nm.SelfNode is invalid. +func (nm *NetworkMap) SelfName() string { + if nm == nil || !nm.SelfNode.Valid() { return "" } - return MagicDNSSuffixOfNodeName(nm.Name) + return nm.SelfNode.Name() +} + +// SelfKeyExpiry returns nm.SelfNode.KeyExpiry, or the zero +// value if nil or nm.SelfNode is invalid. +func (nm *NetworkMap) SelfKeyExpiry() time.Time { + if nm == nil || !nm.SelfNode.Valid() { + return time.Time{} + } + return nm.SelfNode.KeyExpiry() } // DomainName returns the name of the NetworkMap's @@ -244,6 +266,22 @@ func (nm *NetworkMap) DomainName() string { return nm.Domain } +// TailnetDisplayName returns the admin-editable name contained in +// NodeAttrTailnetDisplayName. If the capability is not present it +// returns an empty string. +func (nm *NetworkMap) TailnetDisplayName() string { + if nm == nil || !nm.SelfNode.Valid() { + return "" + } + + tailnetDisplayNames, err := tailcfg.UnmarshalNodeCapViewJSON[string](nm.SelfNode.CapMap(), tailcfg.NodeAttrTailnetDisplayName) + if err != nil || len(tailnetDisplayNames) == 0 { + return "" + } + + return tailnetDisplayNames[0] +} + // HasSelfCapability reports whether nm.SelfNode contains capability c. // // It exists to satisify an unused (as of 2025-01-04) interface in the logknob package. diff --git a/vendor/tailscale.com/types/netmap/nodemut.go b/vendor/tailscale.com/types/netmap/nodemut.go index e31c731..4f93be2 100644 --- a/vendor/tailscale.com/types/netmap/nodemut.go +++ b/vendor/tailscale.com/types/netmap/nodemut.go @@ -37,7 +37,7 @@ func (m NodeMutationDERPHome) Apply(n *tailcfg.Node) { n.HomeDERP = m.DERPRegion } -// NodeMutation is a NodeMutation that says a node's endpoints have changed. +// NodeMutationEndpoints is a NodeMutation that says a node's endpoints have changed. type NodeMutationEndpoints struct { mutatingNodeID Endpoints []netip.AddrPort @@ -163,6 +163,7 @@ func mapResponseContainsNonPatchFields(res *tailcfg.MapResponse) bool { res.PacketFilters != nil || res.UserProfiles != nil || res.Health != nil || + res.DisplayMessages != nil || res.SSHPolicy != nil || res.TKAInfo != nil || res.DomainDataPlaneAuditLogID != "" || @@ -176,5 +177,5 @@ func mapResponseContainsNonPatchFields(res *tailcfg.MapResponse) bool { // function is called, so it should never be set anyway. But for // completedness, and for tests, check it too: res.PeersChanged != nil || - res.DefaultAutoUpdate != "" + res.DeprecatedDefaultAutoUpdate != "" } diff --git a/vendor/tailscale.com/types/opt/bool.go b/vendor/tailscale.com/types/opt/bool.go index 0a3ee67..fbc39e1 100644 --- a/vendor/tailscale.com/types/opt/bool.go +++ b/vendor/tailscale.com/types/opt/bool.go @@ -18,6 +18,22 @@ import ( // field without it being dropped. type Bool string +const ( + // True is the encoding of an explicit true. + True = Bool("true") + + // False is the encoding of an explicit false. + False = Bool("false") + + // ExplicitlyUnset is the encoding used by a null + // JSON value. It is a synonym for the empty string. + ExplicitlyUnset = Bool("unset") + + // Empty means the Bool is unset and it's neither + // true nor false. + Empty = Bool("") +) + // NewBool constructs a new Bool value equal to b. The returned Bool is set, // unless Set("") or Clear() methods are called. func NewBool(b bool) Bool { @@ -50,16 +66,16 @@ func (b *Bool) Scan(src any) error { switch src := src.(type) { case bool: if src { - *b = "true" + *b = True } else { - *b = "false" + *b = False } return nil case int64: if src == 0 { - *b = "false" + *b = False } else { - *b = "true" + *b = True } return nil default: @@ -67,6 +83,17 @@ func (b *Bool) Scan(src any) error { } } +// Normalized returns the normalized form of b, mapping "unset" to "" +// and leaving other values unchanged. +func (b Bool) Normalized() Bool { + switch b { + case ExplicitlyUnset: + return Empty + default: + return b + } +} + // EqualBool reports whether b is equal to v. // If b is empty or not a valid bool, it reports false. func (b Bool) EqualBool(v bool) bool { @@ -75,18 +102,18 @@ func (b Bool) EqualBool(v bool) bool { } var ( - trueBytes = []byte("true") - falseBytes = []byte("false") + trueBytes = []byte(True) + falseBytes = []byte(False) nullBytes = []byte("null") ) func (b Bool) MarshalJSON() ([]byte, error) { switch b { - case "true": + case True: return trueBytes, nil - case "false": + case False: return falseBytes, nil - case "", "unset": + case Empty, ExplicitlyUnset: return nullBytes, nil } return nil, fmt.Errorf("invalid opt.Bool value %q", string(b)) @@ -95,11 +122,11 @@ func (b Bool) MarshalJSON() ([]byte, error) { func (b *Bool) UnmarshalJSON(j []byte) error { switch string(j) { case "true": - *b = "true" + *b = True case "false": - *b = "false" + *b = False case "null": - *b = "unset" + *b = ExplicitlyUnset default: return fmt.Errorf("invalid opt.Bool value %q", j) } diff --git a/vendor/tailscale.com/types/persist/persist.go b/vendor/tailscale.com/types/persist/persist.go index d888a6a..80bac9b 100644 --- a/vendor/tailscale.com/types/persist/persist.go +++ b/vendor/tailscale.com/types/persist/persist.go @@ -26,6 +26,7 @@ type Persist struct { UserProfile tailcfg.UserProfile NetworkLockKey key.NLPrivate NodeID tailcfg.StableNodeID + AttestationKey key.HardwareAttestationKey `json:",omitzero"` // DisallowedTKAStateIDs stores the tka.State.StateID values which // this node will not operate network lock on. This is used to @@ -84,11 +85,20 @@ func (p *Persist) Equals(p2 *Persist) bool { return false } + var pub, p2Pub key.HardwareAttestationPublic + if p.AttestationKey != nil && !p.AttestationKey.IsZero() { + pub = key.HardwareAttestationPublicFromPlatformKey(p.AttestationKey) + } + if p2.AttestationKey != nil && !p2.AttestationKey.IsZero() { + p2Pub = key.HardwareAttestationPublicFromPlatformKey(p2.AttestationKey) + } + return p.PrivateNodeKey.Equal(p2.PrivateNodeKey) && p.OldPrivateNodeKey.Equal(p2.OldPrivateNodeKey) && p.UserProfile.Equal(&p2.UserProfile) && p.NetworkLockKey.Equal(p2.NetworkLockKey) && p.NodeID == p2.NodeID && + pub.Equal(p2Pub) && reflect.DeepEqual(nilIfEmpty(p.DisallowedTKAStateIDs), nilIfEmpty(p2.DisallowedTKAStateIDs)) } @@ -96,12 +106,16 @@ func (p *Persist) Pretty() string { var ( ok, nk key.NodePublic ) + akString := "-" if !p.OldPrivateNodeKey.IsZero() { ok = p.OldPrivateNodeKey.Public() } if !p.PrivateNodeKey.IsZero() { nk = p.PublicNodeKey() } - return fmt.Sprintf("Persist{o=%v, n=%v u=%#v}", - ok.ShortString(), nk.ShortString(), p.UserProfile.LoginName) + if p.AttestationKey != nil && !p.AttestationKey.IsZero() { + akString = fmt.Sprintf("%v", p.AttestationKey.Public()) + } + return fmt.Sprintf("Persist{o=%v, n=%v u=%#v ak=%s}", + ok.ShortString(), nk.ShortString(), p.UserProfile.LoginName, akString) } diff --git a/vendor/tailscale.com/types/persist/persist_clone.go b/vendor/tailscale.com/types/persist/persist_clone.go index 680419f..9dbe7e0 100644 --- a/vendor/tailscale.com/types/persist/persist_clone.go +++ b/vendor/tailscale.com/types/persist/persist_clone.go @@ -19,6 +19,9 @@ func (src *Persist) Clone() *Persist { } dst := new(Persist) *dst = *src + if src.AttestationKey != nil { + dst.AttestationKey = src.AttestationKey.Clone() + } dst.DisallowedTKAStateIDs = append(src.DisallowedTKAStateIDs[:0:0], src.DisallowedTKAStateIDs...) return dst } @@ -31,5 +34,6 @@ var _PersistCloneNeedsRegeneration = Persist(struct { UserProfile tailcfg.UserProfile NetworkLockKey key.NLPrivate NodeID tailcfg.StableNodeID + AttestationKey key.HardwareAttestationKey DisallowedTKAStateIDs []string }{}) diff --git a/vendor/tailscale.com/types/persist/persist_view.go b/vendor/tailscale.com/types/persist/persist_view.go index 55eb40c..dbf8294 100644 --- a/vendor/tailscale.com/types/persist/persist_view.go +++ b/vendor/tailscale.com/types/persist/persist_view.go @@ -6,9 +6,11 @@ package persist import ( - "encoding/json" + jsonv1 "encoding/json" "errors" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/structs" @@ -45,8 +47,17 @@ func (v PersistView) AsStruct() *Persist { return v.ж.Clone() } -func (v PersistView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v PersistView) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v PersistView) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. func (v *PersistView) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") @@ -55,18 +66,39 @@ func (v *PersistView) UnmarshalJSON(b []byte) error { return nil } var x Persist - if err := json.Unmarshal(b, &x); err != nil { + if err := jsonv1.Unmarshal(b, &x); err != nil { return err } v.ж = &x return nil } -func (v PersistView) PrivateNodeKey() key.NodePrivate { return v.ж.PrivateNodeKey } -func (v PersistView) OldPrivateNodeKey() key.NodePrivate { return v.ж.OldPrivateNodeKey } -func (v PersistView) UserProfile() tailcfg.UserProfile { return v.ж.UserProfile } -func (v PersistView) NetworkLockKey() key.NLPrivate { return v.ж.NetworkLockKey } -func (v PersistView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID } +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +func (v *PersistView) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + var x Persist + if err := jsonv2.UnmarshalDecode(dec, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v PersistView) PrivateNodeKey() key.NodePrivate { return v.ж.PrivateNodeKey } + +// needed to request key rotation +func (v PersistView) OldPrivateNodeKey() key.NodePrivate { return v.ж.OldPrivateNodeKey } +func (v PersistView) UserProfile() tailcfg.UserProfile { return v.ж.UserProfile } +func (v PersistView) NetworkLockKey() key.NLPrivate { return v.ж.NetworkLockKey } +func (v PersistView) NodeID() tailcfg.StableNodeID { return v.ж.NodeID } +func (v PersistView) AttestationKey() tailcfg.StableNodeID { panic("unsupported") } + +// DisallowedTKAStateIDs stores the tka.State.StateID values which +// this node will not operate network lock on. This is used to +// prevent bootstrapping TKA onto a key authority which was forcibly +// disabled. func (v PersistView) DisallowedTKAStateIDs() views.Slice[string] { return views.SliceOf(v.ж.DisallowedTKAStateIDs) } @@ -79,5 +111,6 @@ var _PersistViewNeedsRegeneration = Persist(struct { UserProfile tailcfg.UserProfile NetworkLockKey key.NLPrivate NodeID tailcfg.StableNodeID + AttestationKey key.HardwareAttestationKey DisallowedTKAStateIDs []string }{}) diff --git a/vendor/tailscale.com/types/views/views.go b/vendor/tailscale.com/types/views/views.go index 3911f11..252f126 100644 --- a/vendor/tailscale.com/types/views/views.go +++ b/vendor/tailscale.com/types/views/views.go @@ -7,7 +7,8 @@ package views import ( "bytes" - "encoding/json" + "cmp" + jsonv1 "encoding/json" "errors" "fmt" "iter" @@ -15,20 +16,12 @@ import ( "reflect" "slices" + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" "go4.org/mem" "tailscale.com/types/ptr" ) -func unmarshalSliceFromJSON[T any](b []byte, x *[]T) error { - if *x != nil { - return errors.New("already initialized") - } - if len(b) == 0 { - return nil - } - return json.Unmarshal(b, x) -} - // ByteSlice is a read-only accessor for types that are backed by a []byte. type ByteSlice[T ~[]byte] struct { // ж is the underlying mutable value, named with a hard-to-type @@ -93,15 +86,32 @@ func (v ByteSlice[T]) SliceTo(i int) ByteSlice[T] { return ByteSlice[T]{v.ж[:i] // Slice returns v[i:j] func (v ByteSlice[T]) Slice(i, j int) ByteSlice[T] { return ByteSlice[T]{v.ж[i:j]} } -// MarshalJSON implements json.Marshaler. -func (v ByteSlice[T]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v ByteSlice[T]) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} -// UnmarshalJSON implements json.Unmarshaler. +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v ByteSlice[T]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +// It must only be called on an uninitialized ByteSlice. func (v *ByteSlice[T]) UnmarshalJSON(b []byte) error { if v.ж != nil { return errors.New("already initialized") } - return json.Unmarshal(b, &v.ж) + return jsonv1.Unmarshal(b, &v.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It must only be called on an uninitialized ByteSlice. +func (v *ByteSlice[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &v.ж) } // StructView represents the corresponding StructView of a Viewable. The concrete types are @@ -159,11 +169,35 @@ func (v SliceView[T, V]) All() iter.Seq2[int, V] { } } -// MarshalJSON implements json.Marshaler. -func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } +// MarshalJSON implements [jsonv1.Marshaler]. +func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { + return jsonv1.Marshal(v.ж) +} -// UnmarshalJSON implements json.Unmarshaler. -func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { return unmarshalSliceFromJSON(b, &v.ж) } +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v SliceView[T, V]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +// It must only be called on an uninitialized SliceView. +func (v *SliceView[T, V]) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } else if len(b) == 0 { + return nil + } + return jsonv1.Unmarshal(b, &v.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It must only be called on an uninitialized SliceView. +func (v *SliceView[T, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &v.ж) +} // IsNil reports whether the underlying slice is nil. func (v SliceView[T, V]) IsNil() bool { return v.ж == nil } @@ -252,14 +286,34 @@ func SliceOf[T any](x []T) Slice[T] { return Slice[T]{x} } -// MarshalJSON implements json.Marshaler. +// MarshalJSON implements [jsonv1.Marshaler]. func (v Slice[T]) MarshalJSON() ([]byte, error) { - return json.Marshal(v.ж) + return jsonv1.Marshal(v.ж) } -// UnmarshalJSON implements json.Unmarshaler. +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (v Slice[T]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, v.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +// It must only be called on an uninitialized Slice. func (v *Slice[T]) UnmarshalJSON(b []byte) error { - return unmarshalSliceFromJSON(b, &v.ж) + if v.ж != nil { + return errors.New("already initialized") + } else if len(b) == 0 { + return nil + } + return jsonv1.Unmarshal(b, &v.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It must only be called on an uninitialized Slice. +func (v *Slice[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if v.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &v.ж) } // IsNil reports whether the underlying slice is nil. @@ -310,6 +364,20 @@ func (v Slice[T]) ContainsFunc(f func(T) bool) bool { return slices.ContainsFunc(v.ж, f) } +// MaxFunc returns the maximal value in v, using cmp to compare elements. It +// panics if v is empty. If there is more than one maximal element according to +// the cmp function, MaxFunc returns the first one. See also [slices.MaxFunc]. +func (v Slice[T]) MaxFunc(cmp func(a, b T) int) T { + return slices.MaxFunc(v.ж, cmp) +} + +// MinFunc returns the minimal value in v, using cmp to compare elements. It +// panics if v is empty. If there is more than one minimal element according to +// the cmp function, MinFunc returns the first one. See also [slices.MinFunc]. +func (v Slice[T]) MinFunc(cmp func(a, b T) int) T { + return slices.MinFunc(v.ж, cmp) +} + // AppendStrings appends the string representation of each element in v to dst. func AppendStrings[T fmt.Stringer](dst []string, v Slice[T]) []string { for _, x := range v.ж { @@ -330,6 +398,20 @@ func SliceEqual[T comparable](a, b Slice[T]) bool { return slices.Equal(a.ж, b.ж) } +// SliceMax returns the maximal value in v. It panics if v is empty. For +// floating point T, SliceMax propagates NaNs (any NaN value in v forces the +// output to be NaN). See also [slices.Max]. +func SliceMax[T cmp.Ordered](v Slice[T]) T { + return slices.Max(v.ж) +} + +// SliceMin returns the minimal value in v. It panics if v is empty. For +// floating point T, SliceMin propagates NaNs (any NaN value in v forces the +// output to be NaN). See also [slices.Min]. +func SliceMin[T cmp.Ordered](v Slice[T]) T { + return slices.Min(v.ж) +} + // shortOOOLen (short Out-of-Order length) is the slice length at or // under which we attempt to compare two slices quadratically rather // than allocating memory for a map in SliceEqualAnyOrder and @@ -512,18 +594,32 @@ func (m MapSlice[K, V]) GetOk(k K) (Slice[V], bool) { return SliceOf(v), ok } -// MarshalJSON implements json.Marshaler. +// MarshalJSON implements [jsonv1.Marshaler]. func (m MapSlice[K, V]) MarshalJSON() ([]byte, error) { - return json.Marshal(m.ж) + return jsonv1.Marshal(m.ж) } -// UnmarshalJSON implements json.Unmarshaler. +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (m MapSlice[K, V]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, m.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. // It should only be called on an uninitialized Map. func (m *MapSlice[K, V]) UnmarshalJSON(b []byte) error { if m.ж != nil { return errors.New("already initialized") } - return json.Unmarshal(b, &m.ж) + return jsonv1.Unmarshal(b, &m.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It should only be called on an uninitialized MapSlice. +func (m *MapSlice[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if m.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &m.ж) } // AsMap returns a shallow-clone of the underlying map. @@ -600,18 +696,32 @@ func (m Map[K, V]) GetOk(k K) (V, bool) { return v, ok } -// MarshalJSON implements json.Marshaler. +// MarshalJSON implements [jsonv1.Marshaler]. func (m Map[K, V]) MarshalJSON() ([]byte, error) { - return json.Marshal(m.ж) + return jsonv1.Marshal(m.ж) } -// UnmarshalJSON implements json.Unmarshaler. +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (m Map[K, V]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, m.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. // It should only be called on an uninitialized Map. func (m *Map[K, V]) UnmarshalJSON(b []byte) error { if m.ж != nil { return errors.New("already initialized") } - return json.Unmarshal(b, &m.ж) + return jsonv1.Unmarshal(b, &m.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It must only be called on an uninitialized Map. +func (m *Map[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if m.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &m.ж) } // AsMap returns a shallow-clone of the underlying map. @@ -809,17 +919,32 @@ func ValuePointerOf[T any](v *T) ValuePointer[T] { return ValuePointer[T]{v} } -// MarshalJSON implements [json.Marshaler]. +// MarshalJSON implements [jsonv1.Marshaler]. func (p ValuePointer[T]) MarshalJSON() ([]byte, error) { - return json.Marshal(p.ж) + return jsonv1.Marshal(p.ж) } -// UnmarshalJSON implements [json.Unmarshaler]. +// MarshalJSONTo implements [jsonv2.MarshalerTo]. +func (p ValuePointer[T]) MarshalJSONTo(enc *jsontext.Encoder) error { + return jsonv2.MarshalEncode(enc, p.ж) +} + +// UnmarshalJSON implements [jsonv1.Unmarshaler]. +// It must only be called on an uninitialized ValuePointer. func (p *ValuePointer[T]) UnmarshalJSON(b []byte) error { if p.ж != nil { return errors.New("already initialized") } - return json.Unmarshal(b, &p.ж) + return jsonv1.Unmarshal(b, &p.ж) +} + +// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. +// It must only be called on an uninitialized ValuePointer. +func (p *ValuePointer[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + if p.ж != nil { + return errors.New("already initialized") + } + return jsonv2.UnmarshalDecode(dec, &p.ж) } // ContainsPointers reports whether T contains any pointers, diff --git a/vendor/tailscale.com/update-flake.sh b/vendor/tailscale.com/update-flake.sh index 4561183..c22572b 100644 --- a/vendor/tailscale.com/update-flake.sh +++ b/vendor/tailscale.com/update-flake.sh @@ -10,6 +10,14 @@ rm -rf "$OUT" ./tool/go run tailscale.com/cmd/nardump --sri "$OUT" >go.mod.sri rm -rf "$OUT" +GOOUT=$(mktemp -d -t gocross-XXXXXX) +GOREV=$(xargs < ./go.toolchain.rev) +TARBALL="$GOOUT/go-$GOREV.tar.gz" +curl -Ls -o "$TARBALL" "https://github.com/tailscale/go/archive/$GOREV.tar.gz" +tar -xzf "$TARBALL" -C "$GOOUT" +./tool/go run tailscale.com/cmd/nardump --sri "$GOOUT/go-$GOREV" > go.toolchain.rev.sri +rm -rf "$GOOUT" + # nix-direnv only watches the top-level nix file for changes. As a # result, when we change a referenced SRI file, we have to cause some # change to shell.nix and flake.nix as well, so that nix-direnv diff --git a/vendor/tailscale.com/logtail/backoff/backoff.go b/vendor/tailscale.com/util/backoff/backoff.go similarity index 94% rename from vendor/tailscale.com/logtail/backoff/backoff.go rename to vendor/tailscale.com/util/backoff/backoff.go index c6aeae9..95089fc 100644 --- a/vendor/tailscale.com/logtail/backoff/backoff.go +++ b/vendor/tailscale.com/util/backoff/backoff.go @@ -78,3 +78,9 @@ func (b *Backoff) BackOff(ctx context.Context, err error) { case <-tChannel: } } + +// Reset resets the backoff schedule, equivalent to calling BackOff with a nil +// error. +func (b *Backoff) Reset() { + b.n = 0 +} diff --git a/vendor/tailscale.com/util/checkchange/checkchange.go b/vendor/tailscale.com/util/checkchange/checkchange.go new file mode 100644 index 0000000..8ba6472 --- /dev/null +++ b/vendor/tailscale.com/util/checkchange/checkchange.go @@ -0,0 +1,25 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package checkchange defines a utility for determining whether a value +// has changed since the last time it was checked. +package checkchange + +// EqualCloner is an interface for types that can be compared for equality +// and can be cloned. +type EqualCloner[T any] interface { + Equal(T) bool + Clone() T +} + +// Update sets *old to a clone of new if they are not equal, returning whether +// they were different. +// +// It only modifies *old if they are different. old must be non-nil. +func Update[T EqualCloner[T]](old *T, new T) (changed bool) { + if (*old).Equal(new) { + return false + } + *old = new.Clone() + return true +} diff --git a/vendor/tailscale.com/util/clientmetric/clientmetric.go b/vendor/tailscale.com/util/clientmetric/clientmetric.go index 5c11160..50cf3b2 100644 --- a/vendor/tailscale.com/util/clientmetric/clientmetric.go +++ b/vendor/tailscale.com/util/clientmetric/clientmetric.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_clientmetrics + // Package clientmetric provides client-side metrics whose values // get occasionally logged. package clientmetric @@ -18,6 +20,7 @@ import ( "sync/atomic" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/util/set" ) @@ -55,6 +58,20 @@ const ( TypeCounter ) +// MetricUpdate requests that a client metric value be updated. +// +// This is the request body sent to /localapi/v0/upload-client-metrics. +type MetricUpdate struct { + Name string `json:"name"` + Type string `json:"type"` // one of "counter" or "gauge" + Value int `json:"value"` // amount to increment by or set + + // Op indicates if Value is added to the existing metric value, + // or if the metric is set to Value. + // One of "add" or "set". If empty, defaults to "add". + Op string `json:"op"` +} + // Metric is an integer metric value that's tracked over time. // // It's safe for concurrent use. @@ -130,15 +147,20 @@ func (m *Metric) Publish() { metrics[m.name] = m sortedDirty = true - if m.f != nil { - lastLogVal = append(lastLogVal, scanEntry{f: m.f}) - } else { + if m.f == nil { if len(valFreeList) == 0 { valFreeList = make([]int64, 256) } m.v = &valFreeList[0] valFreeList = valFreeList[1:] - lastLogVal = append(lastLogVal, scanEntry{v: m.v}) + } + + if buildfeatures.HasLogTail { + if m.f != nil { + lastLogVal = append(lastLogVal, scanEntry{f: m.f}) + } else { + lastLogVal = append(lastLogVal, scanEntry{v: m.v}) + } } m.regIdx = len(unsorted) @@ -319,6 +341,9 @@ const ( // - increment a metric: (decrements if negative) // 'I' + hex(varint(wireid)) + hex(varint(value)) func EncodeLogTailMetricsDelta() string { + if !buildfeatures.HasLogTail { + return "" + } mu.Lock() defer mu.Unlock() diff --git a/vendor/tailscale.com/util/clientmetric/omit.go b/vendor/tailscale.com/util/clientmetric/omit.go new file mode 100644 index 0000000..6d678cf --- /dev/null +++ b/vendor/tailscale.com/util/clientmetric/omit.go @@ -0,0 +1,31 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_clientmetrics + +package clientmetric + +type Metric struct{} + +func (*Metric) Add(int64) {} +func (*Metric) Set(int64) {} +func (*Metric) Value() int64 { return 0 } +func (*Metric) Register(expvarInt any) {} +func (*Metric) UnregisterAll() {} + +type MetricUpdate struct { + Name string `json:"name"` + Type string `json:"type"` + Value int `json:"value"` + Op string `json:"op"` +} + +func HasPublished(string) bool { panic("unreachable") } +func EncodeLogTailMetricsDelta() string { return "" } +func WritePrometheusExpositionFormat(any) {} + +var zeroMetric Metric + +func NewCounter(string) *Metric { return &zeroMetric } +func NewGauge(string) *Metric { return &zeroMetric } +func NewAggregateCounter(string) *Metric { return &zeroMetric } diff --git a/vendor/tailscale.com/util/cloudenv/cloudenv.go b/vendor/tailscale.com/util/cloudenv/cloudenv.go index be60ca0..f55f7df 100644 --- a/vendor/tailscale.com/util/cloudenv/cloudenv.go +++ b/vendor/tailscale.com/util/cloudenv/cloudenv.go @@ -16,6 +16,7 @@ import ( "strings" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/syncs" "tailscale.com/types/lazy" ) @@ -51,6 +52,9 @@ const ( // ResolverIP returns the cloud host's recursive DNS server or the // empty string if not available. func (c Cloud) ResolverIP() string { + if !buildfeatures.HasCloud { + return "" + } switch c { case GCP: return GoogleMetadataAndDNSIP @@ -92,6 +96,9 @@ var cloudAtomic syncs.AtomicValue[Cloud] // Get returns the current cloud, or the empty string if unknown. func Get() Cloud { + if !buildfeatures.HasCloud { + return "" + } if c, ok := cloudAtomic.LoadOk(); ok { return c } diff --git a/vendor/tailscale.com/wgengine/magicsock/cloudinfo.go b/vendor/tailscale.com/util/cloudinfo/cloudinfo.go similarity index 87% rename from vendor/tailscale.com/wgengine/magicsock/cloudinfo.go rename to vendor/tailscale.com/util/cloudinfo/cloudinfo.go index 1de3696..2c4a32c 100644 --- a/vendor/tailscale.com/wgengine/magicsock/cloudinfo.go +++ b/vendor/tailscale.com/util/cloudinfo/cloudinfo.go @@ -3,7 +3,8 @@ //go:build !(ios || android || js) -package magicsock +// Package cloudinfo provides cloud metadata utilities. +package cloudinfo import ( "context" @@ -17,13 +18,15 @@ import ( "strings" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/types/logger" "tailscale.com/util/cloudenv" ) const maxCloudInfoWait = 2 * time.Second -type cloudInfo struct { +// CloudInfo holds state used in querying instance metadata (IMDS) endpoints. +type CloudInfo struct { client http.Client logf logger.Logf @@ -33,7 +36,11 @@ type cloudInfo struct { endpoint string } -func newCloudInfo(logf logger.Logf) *cloudInfo { +// New constructs a new [*CloudInfo] that will log to the provided logger instance. +func New(logf logger.Logf) *CloudInfo { + if !buildfeatures.HasCloud { + return nil + } tr := &http.Transport{ DisableKeepAlives: true, Dial: (&net.Dialer{ @@ -41,7 +48,7 @@ func newCloudInfo(logf logger.Logf) *cloudInfo { }).Dial, } - return &cloudInfo{ + return &CloudInfo{ client: http.Client{Transport: tr}, logf: logf, cloud: cloudenv.Get(), @@ -52,7 +59,12 @@ func newCloudInfo(logf logger.Logf) *cloudInfo { // GetPublicIPs returns any public IPs attached to the current cloud instance, // if the tailscaled process is running in a known cloud and there are any such // IPs present. -func (ci *cloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) { +// +// Currently supports only AWS. +func (ci *CloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) { + if !buildfeatures.HasCloud { + return nil, nil + } switch ci.cloud { case cloudenv.AWS: ret, err := ci.getAWS(ctx) @@ -66,7 +78,7 @@ func (ci *cloudInfo) GetPublicIPs(ctx context.Context) ([]netip.Addr, error) { // getAWSMetadata makes a request to the AWS metadata service at the given // path, authenticating with the provided IMDSv2 token. The returned metadata // is split by newline and returned as a slice. -func (ci *cloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([]string, error) { +func (ci *CloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([]string, error) { req, err := http.NewRequestWithContext(ctx, "GET", ci.endpoint+path, nil) if err != nil { return nil, fmt.Errorf("creating request to %q: %w", path, err) @@ -98,7 +110,7 @@ func (ci *cloudInfo) getAWSMetadata(ctx context.Context, token, path string) ([] } // getAWS returns all public IPv4 and IPv6 addresses present in the AWS instance metadata. -func (ci *cloudInfo) getAWS(ctx context.Context) ([]netip.Addr, error) { +func (ci *CloudInfo) getAWS(ctx context.Context) ([]netip.Addr, error) { ctx, cancel := context.WithTimeout(ctx, maxCloudInfoWait) defer cancel() diff --git a/vendor/tailscale.com/util/cloudinfo/cloudinfo_nocloud.go b/vendor/tailscale.com/util/cloudinfo/cloudinfo_nocloud.go new file mode 100644 index 0000000..6a525cd --- /dev/null +++ b/vendor/tailscale.com/util/cloudinfo/cloudinfo_nocloud.go @@ -0,0 +1,26 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ios || android || js + +package cloudinfo + +import ( + "context" + "net/netip" + + "tailscale.com/types/logger" +) + +// CloudInfo is not available in mobile and JS targets. +type CloudInfo struct{} + +// New construct a no-op CloudInfo stub. +func New(_ logger.Logf) *CloudInfo { + return &CloudInfo{} +} + +// GetPublicIPs always returns nil slice and error. +func (ci *CloudInfo) GetPublicIPs(_ context.Context) ([]netip.Addr, error) { + return nil, nil +} diff --git a/vendor/tailscale.com/util/dnsname/dnsname.go b/vendor/tailscale.com/util/dnsname/dnsname.go index 6404a9a..ef898eb 100644 --- a/vendor/tailscale.com/util/dnsname/dnsname.go +++ b/vendor/tailscale.com/util/dnsname/dnsname.go @@ -14,7 +14,7 @@ const ( // maxLabelLength is the maximum length of a label permitted by RFC 1035. maxLabelLength = 63 // maxNameLength is the maximum length of a DNS name. - maxNameLength = 253 + maxNameLength = 254 ) // A FQDN is a fully-qualified DNS name or name suffix. diff --git a/vendor/tailscale.com/util/eventbus/assets/event.html b/vendor/tailscale.com/util/eventbus/assets/event.html new file mode 100644 index 0000000..8e016f5 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/assets/event.html @@ -0,0 +1,6 @@ +
    • +
      + {{.Count}}: {{.Type}} from {{.Event.From.Name}}, {{len .Event.To}} recipients + {{.Event.Event}} +
      +
    • diff --git a/vendor/tailscale.com/util/eventbus/assets/htmx-websocket.min.js.gz b/vendor/tailscale.com/util/eventbus/assets/htmx-websocket.min.js.gz new file mode 100644 index 0000000..4ed53be Binary files /dev/null and b/vendor/tailscale.com/util/eventbus/assets/htmx-websocket.min.js.gz differ diff --git a/vendor/tailscale.com/util/eventbus/assets/htmx.min.js.gz b/vendor/tailscale.com/util/eventbus/assets/htmx.min.js.gz new file mode 100644 index 0000000..b75fea8 Binary files /dev/null and b/vendor/tailscale.com/util/eventbus/assets/htmx.min.js.gz differ diff --git a/vendor/tailscale.com/util/eventbus/assets/main.html b/vendor/tailscale.com/util/eventbus/assets/main.html new file mode 100644 index 0000000..51d6b22 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/assets/main.html @@ -0,0 +1,97 @@ + + + + + + + + +

      Event bus

      + +
      +

      General

      + {{with $.PublishQueue}} + {{len .}} pending + {{end}} + + +
      + +
      +

      Clients

      + + + + + + + + + + + {{range .Clients}} + + + + + + + {{end}} +
      NamePublishingSubscribingPending
      {{.Name}} +
        + {{range .Publish}} +
      • {{.}}
      • + {{end}} +
      +
      +
        + {{range .Subscribe}} +
      • {{.}}
      • + {{end}} +
      +
      + {{len ($.SubscribeQueue .Client)}} +
      +
      + +
      +

      Types

      + + {{range .Types}} + +
      +

      {{.Name}}

      +

      Definition

      + {{prettyPrintStruct .}} + +

      Published by:

      + {{if len (.Publish)}} +
        + {{range .Publish}} +
      • {{.Name}}
      • + {{end}} +
      + {{else}} +
        +
      • No publishers.
      • +
      + {{end}} + +

      Received by:

      + {{if len (.Subscribe)}} +
        + {{range .Subscribe}} +
      • {{.Name}}
      • + {{end}} +
      + {{else}} +
        +
      • No subscribers.
      • +
      + {{end}} +
      + {{end}} + +
      + + diff --git a/vendor/tailscale.com/util/eventbus/assets/monitor.html b/vendor/tailscale.com/util/eventbus/assets/monitor.html new file mode 100644 index 0000000..1af5bdc --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/assets/monitor.html @@ -0,0 +1,5 @@ +
      +
        +
      + +
      diff --git a/vendor/tailscale.com/util/eventbus/assets/style.css b/vendor/tailscale.com/util/eventbus/assets/style.css new file mode 100644 index 0000000..690bd4f --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/assets/style.css @@ -0,0 +1,90 @@ +/* CSS reset, thanks Josh Comeau: https://www.joshwcomeau.com/css/custom-css-reset/ */ +*, *::before, *::after { box-sizing: border-box; } +* { margin: 0; } +input, button, textarea, select { font: inherit; } +p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } +p { text-wrap: pretty; } +h1, h2, h3, h4, h5, h6 { text-wrap: balance; } +#root, #__next { isolation: isolate; } +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} +img, picture, video, canvas, svg { + display: block; + max-width: 100%; +} + +/* Local styling begins */ + +body { + padding: 12px; +} + +div { + width: 100%; +} + +section { + display: flex; + flex-direction: column; + flex-gap: 6px; + align-items: flex-start; + padding: 12px 0; +} + +section > * { + margin-left: 24px; +} + +section > h2, section > h3 { + margin-left: 0; + padding-bottom: 6px; + padding-top: 12px; +} + +details { + padding-bottom: 12px; +} + +table { + table-layout: fixed; + width: calc(100% - 48px); + border-collapse: collapse; + border: 1px solid black; +} + +th, td { + padding: 12px; + border: 1px solid black; +} + +td.list { + vertical-align: top; +} + +ul { + list-style: none; +} + +td ul { + margin: 0; + padding: 0; +} + +code { + padding: 12px; + white-space: pre; +} + +#monitor { + width: calc(100% - 48px); + resize: vertical; + padding: 12px; + overflow: scroll; + height: 15lh; + border: 1px inset; + min-height: 1em; + display: flex; + flex-direction: column-reverse; +} diff --git a/vendor/tailscale.com/util/eventbus/bus.go b/vendor/tailscale.com/util/eventbus/bus.go new file mode 100644 index 0000000..880e075 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/bus.go @@ -0,0 +1,345 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "context" + "log" + "reflect" + "slices" + + "tailscale.com/syncs" + "tailscale.com/types/logger" + "tailscale.com/util/set" +) + +type PublishedEvent struct { + Event any + From *Client +} + +type RoutedEvent struct { + Event any + From *Client + To []*Client +} + +// Bus is an event bus that distributes published events to interested +// subscribers. +type Bus struct { + router *worker + write chan PublishedEvent + snapshot chan chan []PublishedEvent + routeDebug hook[RoutedEvent] + logf logger.Logf + + topicsMu syncs.Mutex + topics map[reflect.Type][]*subscribeState + + // Used for introspection/debugging only, not in the normal event + // publishing path. + clientsMu syncs.Mutex + clients set.Set[*Client] +} + +// New returns a new bus with default options. It is equivalent to +// calling [NewWithOptions] with zero [BusOptions]. +func New() *Bus { return NewWithOptions(BusOptions{}) } + +// NewWithOptions returns a new [Bus] with the specified [BusOptions]. +// Use [Bus.Client] to construct clients on the bus. +// Use [Publish] to make event publishers. +// Use [Subscribe] and [SubscribeFunc] to make event subscribers. +func NewWithOptions(opts BusOptions) *Bus { + ret := &Bus{ + write: make(chan PublishedEvent), + snapshot: make(chan chan []PublishedEvent), + topics: map[reflect.Type][]*subscribeState{}, + clients: set.Set[*Client]{}, + logf: opts.logger(), + } + ret.router = runWorker(ret.pump) + return ret +} + +// BusOptions are optional parameters for a [Bus]. A zero value is ready for +// use and provides defaults as described. +type BusOptions struct { + // Logf, if non-nil, is used for debug logs emitted by the bus and clients, + // publishers, and subscribers under its care. If it is nil, logs are sent + // to [log.Printf]. + Logf logger.Logf +} + +func (o BusOptions) logger() logger.Logf { + if o.Logf == nil { + return log.Printf + } + return o.Logf +} + +// Client returns a new client with no subscriptions. Use [Subscribe] +// to receive events, and [Publish] to emit events. +// +// The client's name is used only for debugging, to tell humans what +// piece of code a publisher/subscriber belongs to. Aim for something +// short but unique, for example "kernel-route-monitor" or "taildrop", +// not "watcher". +func (b *Bus) Client(name string) *Client { + ret := &Client{ + name: name, + bus: b, + pub: set.Set[publisher]{}, + } + b.clientsMu.Lock() + defer b.clientsMu.Unlock() + b.clients.Add(ret) + return ret +} + +// Debugger returns the debugging facility for the bus. +func (b *Bus) Debugger() *Debugger { + return &Debugger{b} +} + +// Close closes the bus. It implicitly closes all clients, publishers and +// subscribers attached to the bus. +// +// Close blocks until the bus is fully shut down. The bus is +// permanently unusable after closing. +func (b *Bus) Close() { + b.router.StopAndWait() + + b.clientsMu.Lock() + defer b.clientsMu.Unlock() + for c := range b.clients { + c.Close() + } + b.clients = nil +} + +func (b *Bus) pump(ctx context.Context) { + // Limit how many published events we can buffer in the PublishedEvent queue. + // + // Subscribers have unbounded DeliveredEvent queues (see tailscale/tailscale#18020), + // so this queue doesn't need to be unbounded. Keeping it bounded may also help + // catch cases where subscribers stop pumping events completely, such as due to a bug + // in [subscribeState.pump], [Subscriber.dispatch], or [SubscriberFunc.dispatch]). + const maxPublishedEvents = 16 + vals := queue[PublishedEvent]{capacity: maxPublishedEvents} + acceptCh := func() chan PublishedEvent { + if vals.Full() { + return nil + } + return b.write + } + for { + // Drain all pending events. Note that while we're draining + // events into subscriber queues, we continue to + // opportunistically accept more incoming events, if we have + // queue space for it. + for !vals.Empty() { + val := vals.Peek() + dests := b.dest(reflect.TypeOf(val.Event)) + + if b.routeDebug.active() { + clients := make([]*Client, len(dests)) + for i := range len(dests) { + clients[i] = dests[i].client + } + b.routeDebug.run(RoutedEvent{ + Event: val.Event, + From: val.From, + To: clients, + }) + } + + for _, d := range dests { + evt := DeliveredEvent{ + Event: val.Event, + From: val.From, + To: d.client, + } + deliverOne: + for { + select { + case d.write <- evt: + break deliverOne + case <-d.closed(): + // Queue closed, don't block but continue + // delivering to others. + break deliverOne + case in := <-acceptCh(): + vals.Add(in) + in.From.publishDebug.run(in) + case <-ctx.Done(): + return + case ch := <-b.snapshot: + ch <- vals.Snapshot() + } + } + } + vals.Drop() + } + + // Inbound queue empty, wait for at least 1 work item before + // resuming. + for vals.Empty() { + select { + case <-ctx.Done(): + return + case in := <-b.write: + vals.Add(in) + in.From.publishDebug.run(in) + case ch := <-b.snapshot: + ch <- nil + } + } + } +} + +// logger returns a [logger.Logf] to which logs related to bus activity should be written. +func (b *Bus) logger() logger.Logf { return b.logf } + +func (b *Bus) dest(t reflect.Type) []*subscribeState { + b.topicsMu.Lock() + defer b.topicsMu.Unlock() + return b.topics[t] +} + +func (b *Bus) shouldPublish(t reflect.Type) bool { + if b.routeDebug.active() { + return true + } + + b.topicsMu.Lock() + defer b.topicsMu.Unlock() + return len(b.topics[t]) > 0 +} + +func (b *Bus) listClients() []*Client { + b.clientsMu.Lock() + defer b.clientsMu.Unlock() + return b.clients.Slice() +} + +func (b *Bus) snapshotPublishQueue() []PublishedEvent { + resp := make(chan []PublishedEvent) + select { + case b.snapshot <- resp: + return <-resp + case <-b.router.Done(): + return nil + } +} + +func (b *Bus) subscribe(t reflect.Type, q *subscribeState) (cancel func()) { + b.topicsMu.Lock() + defer b.topicsMu.Unlock() + b.topics[t] = append(b.topics[t], q) + return func() { + b.unsubscribe(t, q) + } +} + +func (b *Bus) unsubscribe(t reflect.Type, q *subscribeState) { + b.topicsMu.Lock() + defer b.topicsMu.Unlock() + // Topic slices are accessed by pump without holding a lock, so we + // have to replace the entire slice when unsubscribing. + // Unsubscribing should be infrequent enough that this won't + // matter. + i := slices.Index(b.topics[t], q) + if i < 0 { + return + } + b.topics[t] = slices.Delete(slices.Clone(b.topics[t]), i, i+1) +} + +// A worker runs a worker goroutine and helps coordinate its shutdown. +type worker struct { + ctx context.Context + stop context.CancelFunc + stopped chan struct{} +} + +// runWorker creates a worker goroutine running fn. The context passed +// to fn is canceled by [worker.Stop]. +func runWorker(fn func(context.Context)) *worker { + ctx, stop := context.WithCancel(context.Background()) + ret := &worker{ + ctx: ctx, + stop: stop, + stopped: make(chan struct{}), + } + go ret.run(fn) + return ret +} + +func (w *worker) run(fn func(context.Context)) { + defer close(w.stopped) + fn(w.ctx) +} + +// Stop signals the worker goroutine to shut down. +func (w *worker) Stop() { w.stop() } + +// Done returns a channel that is closed when the worker goroutine +// exits. +func (w *worker) Done() <-chan struct{} { return w.stopped } + +// Wait waits until the worker goroutine has exited. +func (w *worker) Wait() { <-w.stopped } + +// StopAndWait signals the worker goroutine to shut down, then waits +// for it to exit. +func (w *worker) StopAndWait() { + w.stop() + <-w.stopped +} + +// stopFlag is a value that can be watched for a notification. The +// zero value is ready for use. +// +// The flag is notified by running [stopFlag.Stop]. Stop can be called +// multiple times. Upon the first call to Stop, [stopFlag.Done] is +// closed, all pending [stopFlag.Wait] calls return, and future Wait +// calls return immediately. +// +// A stopFlag can only notify once, and is intended for use as a +// one-way shutdown signal that's lighter than a cancellable +// context.Context. +type stopFlag struct { + // guards the lazy construction of stopped, and the value of + // alreadyStopped. + mu syncs.Mutex + stopped chan struct{} + alreadyStopped bool +} + +func (s *stopFlag) Stop() { + s.mu.Lock() + defer s.mu.Unlock() + if s.alreadyStopped { + return + } + s.alreadyStopped = true + if s.stopped == nil { + s.stopped = make(chan struct{}) + } + close(s.stopped) +} + +func (s *stopFlag) Done() <-chan struct{} { + s.mu.Lock() + defer s.mu.Unlock() + if s.stopped == nil { + s.stopped = make(chan struct{}) + } + return s.stopped +} + +func (s *stopFlag) Wait() { + <-s.Done() +} diff --git a/vendor/tailscale.com/util/eventbus/client.go b/vendor/tailscale.com/util/eventbus/client.go new file mode 100644 index 0000000..a7a5ab6 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/client.go @@ -0,0 +1,182 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "reflect" + + "tailscale.com/syncs" + "tailscale.com/types/logger" + "tailscale.com/util/set" +) + +// A Client can publish and subscribe to events on its attached +// bus. See [Publish] to publish events, and [Subscribe] to receive +// events. +// +// Subscribers that share the same client receive events one at a +// time, in the order they were published. +type Client struct { + name string + bus *Bus + publishDebug hook[PublishedEvent] + + mu syncs.Mutex + pub set.Set[publisher] + sub *subscribeState // Lazily created on first subscribe + stop stopFlag // signaled on Close +} + +func (c *Client) Name() string { return c.name } + +func (c *Client) logger() logger.Logf { return c.bus.logger() } + +// Close closes the client. It implicitly closes all publishers and +// subscribers obtained from this client. +func (c *Client) Close() { + var ( + pub set.Set[publisher] + sub *subscribeState + ) + + c.mu.Lock() + pub, c.pub = c.pub, nil + sub, c.sub = c.sub, nil + c.mu.Unlock() + + if sub != nil { + sub.close() + } + for p := range pub { + p.Close() + } + c.stop.Stop() +} + +func (c *Client) isClosed() bool { return c.pub == nil && c.sub == nil } + +// Done returns a channel that is closed when [Client.Close] is called. +// The channel is closed after all the publishers and subscribers governed by +// the client have been closed. +func (c *Client) Done() <-chan struct{} { return c.stop.Done() } + +func (c *Client) snapshotSubscribeQueue() []DeliveredEvent { + return c.peekSubscribeState().snapshotQueue() +} + +func (c *Client) peekSubscribeState() *subscribeState { + c.mu.Lock() + defer c.mu.Unlock() + return c.sub +} + +func (c *Client) publishTypes() []reflect.Type { + c.mu.Lock() + defer c.mu.Unlock() + ret := make([]reflect.Type, 0, len(c.pub)) + for pub := range c.pub { + ret = append(ret, pub.publishType()) + } + return ret +} + +func (c *Client) subscribeTypes() []reflect.Type { + return c.peekSubscribeState().subscribeTypes() +} + +func (c *Client) subscribeState() *subscribeState { + c.mu.Lock() + defer c.mu.Unlock() + return c.subscribeStateLocked() +} + +func (c *Client) subscribeStateLocked() *subscribeState { + if c.sub == nil { + c.sub = newSubscribeState(c) + } + return c.sub +} + +func (c *Client) addPublisher(pub publisher) { + c.mu.Lock() + defer c.mu.Unlock() + if c.isClosed() { + panic("cannot Publish on a closed client") + } + c.pub.Add(pub) +} + +func (c *Client) deletePublisher(pub publisher) { + c.mu.Lock() + defer c.mu.Unlock() + c.pub.Delete(pub) +} + +func (c *Client) addSubscriber(t reflect.Type, s *subscribeState) { + c.bus.subscribe(t, s) +} + +func (c *Client) deleteSubscriber(t reflect.Type, s *subscribeState) { + c.bus.unsubscribe(t, s) +} + +func (c *Client) publish() chan<- PublishedEvent { + return c.bus.write +} + +func (c *Client) shouldPublish(t reflect.Type) bool { + return c.publishDebug.active() || c.bus.shouldPublish(t) +} + +// Subscribe requests delivery of events of type T through the given client. +// It panics if c already has a subscriber for type T, or if c is closed. +func Subscribe[T any](c *Client) *Subscriber[T] { + // Hold the client lock throughout the subscription process so that a caller + // attempting to subscribe on a closed client will get a useful diagnostic + // instead of a random panic from inside the subscriber plumbing. + c.mu.Lock() + defer c.mu.Unlock() + + // The caller should not race subscriptions with close, give them a useful + // diagnostic at the call site. + if c.isClosed() { + panic("cannot Subscribe on a closed client") + } + + r := c.subscribeStateLocked() + s := newSubscriber[T](r, logfForCaller(c.logger())) + r.addSubscriber(s) + return s +} + +// SubscribeFunc is like [Subscribe], but calls the provided func for each +// event of type T. +// +// A SubscriberFunc calls f synchronously from the client's goroutine. +// This means the callback must not block for an extended period of time, +// as this will block the subscriber and slow event processing for all +// subscriptions on c. +func SubscribeFunc[T any](c *Client, f func(T)) *SubscriberFunc[T] { + c.mu.Lock() + defer c.mu.Unlock() + + // The caller should not race subscriptions with close, give them a useful + // diagnostic at the call site. + if c.isClosed() { + panic("cannot SubscribeFunc on a closed client") + } + + r := c.subscribeStateLocked() + s := newSubscriberFunc[T](r, f, logfForCaller(c.logger())) + r.addSubscriber(s) + return s +} + +// Publish returns a publisher for event type T using the given client. +// It panics if c is closed. +func Publish[T any](c *Client) *Publisher[T] { + p := newPublisher[T](c) + c.addPublisher(p) + return p +} diff --git a/vendor/tailscale.com/util/eventbus/debug.go b/vendor/tailscale.com/util/eventbus/debug.go new file mode 100644 index 0000000..0453def --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/debug.go @@ -0,0 +1,242 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "cmp" + "fmt" + "path/filepath" + "reflect" + "runtime" + "slices" + "strings" + "sync/atomic" + "time" + + "tailscale.com/syncs" + "tailscale.com/types/logger" +) + +// slowSubscriberTimeout is a timeout after which a subscriber that does not +// accept a pending event will be flagged as being slow. +const slowSubscriberTimeout = 5 * time.Second + +// A Debugger offers access to a bus's privileged introspection and +// debugging facilities. +// +// The debugger's functionality is intended for humans and their tools +// to examine and troubleshoot bus clients, and should not be used in +// normal codepaths. +// +// In particular, the debugger provides access to information that is +// deliberately withheld from bus clients to encourage more robust and +// maintainable code - for example, the sender of an event, or the +// event streams of other clients. Please don't use the debugger to +// circumvent these restrictions for purposes other than debugging. +type Debugger struct { + bus *Bus +} + +// Clients returns a list of all clients attached to the bus. +func (d *Debugger) Clients() []*Client { + ret := d.bus.listClients() + slices.SortFunc(ret, func(a, b *Client) int { + return cmp.Compare(a.Name(), b.Name()) + }) + return ret +} + +// PublishQueue returns the contents of the publish queue. +// +// The publish queue contains events that have been accepted by the +// bus from Publish() calls, but have not yet been routed to relevant +// subscribers. +// +// This queue is expected to be almost empty in normal operation. A +// full publish queue indicates that a slow subscriber downstream is +// causing backpressure and stalling the bus. +func (d *Debugger) PublishQueue() []PublishedEvent { + return d.bus.snapshotPublishQueue() +} + +// checkClient verifies that client is attached to the same bus as the +// Debugger, and panics if not. +func (d *Debugger) checkClient(client *Client) { + if client.bus != d.bus { + panic(fmt.Errorf("SubscribeQueue given client belonging to wrong bus")) + } +} + +// SubscribeQueue returns the contents of the given client's subscribe +// queue. +// +// The subscribe queue contains events that are to be delivered to the +// client, but haven't yet been handed off to the relevant +// [Subscriber]. +// +// This queue is expected to be almost empty in normal operation. A +// full subscribe queue indicates that the client is accepting events +// too slowly, and may be causing the rest of the bus to stall. +func (d *Debugger) SubscribeQueue(client *Client) []DeliveredEvent { + d.checkClient(client) + return client.snapshotSubscribeQueue() +} + +// WatchBus streams information about all events passing through the +// bus. +// +// Monitored events are delivered in the bus's global publication +// order (see "Concurrency properties" in the package docs). +// +// The caller must consume monitoring events promptly to avoid +// stalling the bus (see "Expected subscriber behavior" in the package +// docs). +func (d *Debugger) WatchBus() *Subscriber[RoutedEvent] { + return newMonitor(d.bus.routeDebug.add) +} + +// WatchPublish streams information about all events published by the +// given client. +// +// Monitored events are delivered in the bus's global publication +// order (see "Concurrency properties" in the package docs). +// +// The caller must consume monitoring events promptly to avoid +// stalling the bus (see "Expected subscriber behavior" in the package +// docs). +func (d *Debugger) WatchPublish(client *Client) *Subscriber[PublishedEvent] { + d.checkClient(client) + return newMonitor(client.publishDebug.add) +} + +// WatchSubscribe streams information about all events received by the +// given client. +// +// Monitored events are delivered in the bus's global publication +// order (see "Concurrency properties" in the package docs). +// +// The caller must consume monitoring events promptly to avoid +// stalling the bus (see "Expected subscriber behavior" in the package +// docs). +func (d *Debugger) WatchSubscribe(client *Client) *Subscriber[DeliveredEvent] { + d.checkClient(client) + return newMonitor(client.subscribeState().debug.add) +} + +// PublishTypes returns the list of types being published by client. +// +// The returned types are those for which the client has obtained a +// [Publisher]. The client may not have ever sent the type in +// question. +func (d *Debugger) PublishTypes(client *Client) []reflect.Type { + d.checkClient(client) + return client.publishTypes() +} + +// SubscribeTypes returns the list of types being subscribed to by +// client. +// +// The returned types are those for which the client has obtained a +// [Subscriber]. The client may not have ever received the type in +// question, and here may not be any publishers of the type. +func (d *Debugger) SubscribeTypes(client *Client) []reflect.Type { + d.checkClient(client) + return client.subscribeTypes() +} + +// A hook collects hook functions that can be run as a group. +type hook[T any] struct { + syncs.Mutex + fns []hookFn[T] +} + +var hookID atomic.Uint64 + +// add registers fn to be called when the hook is run. Returns an +// unregistration function that removes fn from the hook when called. +func (h *hook[T]) add(fn func(T)) (remove func()) { + id := hookID.Add(1) + h.Lock() + defer h.Unlock() + h.fns = append(h.fns, hookFn[T]{id, fn}) + return func() { h.remove(id) } +} + +// remove removes the function with the given ID from the hook. +func (h *hook[T]) remove(id uint64) { + h.Lock() + defer h.Unlock() + h.fns = slices.DeleteFunc(h.fns, func(f hookFn[T]) bool { return f.ID == id }) +} + +// active reports whether any functions are registered with the +// hook. This can be used to skip expensive work when the hook is +// inactive. +func (h *hook[T]) active() bool { + h.Lock() + defer h.Unlock() + return len(h.fns) > 0 +} + +// run calls all registered functions with the value v. +func (h *hook[T]) run(v T) { + h.Lock() + defer h.Unlock() + for _, fn := range h.fns { + fn.Fn(v) + } +} + +type hookFn[T any] struct { + ID uint64 + Fn func(T) +} + +// DebugEvent is a representation of an event used for debug clients. +type DebugEvent struct { + Count int + Type string + From string + To []string + Event any +} + +// DebugTopics provides the JSON encoding as a wrapper for a collection of [DebugTopic]. +type DebugTopics struct { + Topics []DebugTopic +} + +// DebugTopic provides the JSON encoding of publishers and subscribers for a +// given topic. +type DebugTopic struct { + Name string + Publisher string + Subscribers []string +} + +// logfForCaller returns a [logger.Logf] that prefixes its output with the +// package, filename, and line number of the caller's caller. +// If logf == nil, it returns [logger.Discard]. +// If the caller location could not be determined, it returns logf unmodified. +func logfForCaller(logf logger.Logf) logger.Logf { + if logf == nil { + return logger.Discard + } + pc, fpath, line, _ := runtime.Caller(2) // +1 for my caller, +1 for theirs + if f := runtime.FuncForPC(pc); f != nil { + return logger.WithPrefix(logf, fmt.Sprintf("%s %s:%d: ", funcPackageName(f.Name()), filepath.Base(fpath), line)) + } + return logf +} + +func funcPackageName(funcName string) string { + ls := max(strings.LastIndex(funcName, "/"), 0) + for { + i := strings.LastIndex(funcName, ".") + if i <= ls { + return funcName + } + funcName = funcName[:i] + } +} diff --git a/vendor/tailscale.com/util/eventbus/debughttp.go b/vendor/tailscale.com/util/eventbus/debughttp.go new file mode 100644 index 0000000..9e03676 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/debughttp.go @@ -0,0 +1,240 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ios && !android && !ts_omit_debugeventbus + +package eventbus + +import ( + "bytes" + "cmp" + "embed" + "fmt" + "html/template" + "io" + "io/fs" + "log" + "net/http" + "path/filepath" + "reflect" + "slices" + "strings" + "sync" + + "github.com/coder/websocket" + "tailscale.com/tsweb" +) + +type httpDebugger struct { + *Debugger +} + +func (d *Debugger) RegisterHTTP(td *tsweb.DebugHandler) { + dh := httpDebugger{d} + td.Handle("bus", "Event bus", dh) + td.HandleSilent("bus/monitor", http.HandlerFunc(dh.serveMonitor)) + td.HandleSilent("bus/style.css", serveStatic("style.css")) + td.HandleSilent("bus/htmx.min.js", serveStatic("htmx.min.js.gz")) + td.HandleSilent("bus/htmx-websocket.min.js", serveStatic("htmx-websocket.min.js.gz")) +} + +//go:embed assets/*.html +var templatesSrc embed.FS + +var templates = sync.OnceValue(func() *template.Template { + d, err := fs.Sub(templatesSrc, "assets") + if err != nil { + panic(fmt.Errorf("getting eventbus debughttp templates subdir: %w", err)) + } + ret := template.New("").Funcs(map[string]any{ + "prettyPrintStruct": prettyPrintStruct, + }) + return template.Must(ret.ParseFS(d, "*")) +}) + +//go:generate go run fetch-htmx.go + +//go:embed assets/*.css assets/*.min.js.gz +var static embed.FS + +func serveStatic(name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case strings.HasSuffix(name, ".css"): + w.Header().Set("Content-Type", "text/css") + case strings.HasSuffix(name, ".min.js.gz"): + w.Header().Set("Content-Type", "text/javascript") + w.Header().Set("Content-Encoding", "gzip") + case strings.HasSuffix(name, ".js"): + w.Header().Set("Content-Type", "text/javascript") + default: + http.Error(w, "not found", http.StatusNotFound) + return + } + + f, err := static.Open(filepath.Join("assets", name)) + if err != nil { + http.Error(w, fmt.Sprintf("opening asset: %v", err), http.StatusInternalServerError) + return + } + defer f.Close() + if _, err := io.Copy(w, f); err != nil { + http.Error(w, fmt.Sprintf("serving asset: %v", err), http.StatusInternalServerError) + return + } + }) +} + +func render(w http.ResponseWriter, name string, data any) { + err := templates().ExecuteTemplate(w, name+".html", data) + if err != nil { + err := fmt.Errorf("rendering template: %v", err) + log.Print(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func (h httpDebugger) ServeHTTP(w http.ResponseWriter, r *http.Request) { + type clientInfo struct { + *Client + Publish []reflect.Type + Subscribe []reflect.Type + } + type typeInfo struct { + reflect.Type + Publish []*Client + Subscribe []*Client + } + type info struct { + *Debugger + Clients map[string]*clientInfo + Types map[string]*typeInfo + } + + data := info{ + Debugger: h.Debugger, + Clients: map[string]*clientInfo{}, + Types: map[string]*typeInfo{}, + } + + getTypeInfo := func(t reflect.Type) *typeInfo { + if data.Types[t.Name()] == nil { + data.Types[t.Name()] = &typeInfo{ + Type: t, + } + } + return data.Types[t.Name()] + } + + for _, c := range h.Clients() { + ci := &clientInfo{ + Client: c, + Publish: h.PublishTypes(c), + Subscribe: h.SubscribeTypes(c), + } + slices.SortFunc(ci.Publish, func(a, b reflect.Type) int { return cmp.Compare(a.Name(), b.Name()) }) + slices.SortFunc(ci.Subscribe, func(a, b reflect.Type) int { return cmp.Compare(a.Name(), b.Name()) }) + data.Clients[c.Name()] = ci + + for _, t := range ci.Publish { + ti := getTypeInfo(t) + ti.Publish = append(ti.Publish, c) + } + for _, t := range ci.Subscribe { + ti := getTypeInfo(t) + ti.Subscribe = append(ti.Subscribe, c) + } + } + + render(w, "main", data) +} + +func (h httpDebugger) serveMonitor(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("Upgrade") == "websocket" { + h.serveMonitorStream(w, r) + return + } + + render(w, "monitor", nil) +} + +func (h httpDebugger) serveMonitorStream(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, nil) + if err != nil { + return + } + defer conn.CloseNow() + wsCtx := conn.CloseRead(r.Context()) + + mon := h.WatchBus() + defer mon.Close() + + i := 0 + for { + select { + case <-r.Context().Done(): + return + case <-wsCtx.Done(): + return + case <-mon.Done(): + return + case event := <-mon.Events(): + msg, err := conn.Writer(r.Context(), websocket.MessageText) + if err != nil { + return + } + data := map[string]any{ + "Count": i, + "Type": reflect.TypeOf(event.Event), + "Event": event, + } + i++ + if err := templates().ExecuteTemplate(msg, "event.html", data); err != nil { + log.Println(err) + return + } + if err := msg.Close(); err != nil { + return + } + } + } +} + +func prettyPrintStruct(t reflect.Type) string { + if t.Kind() != reflect.Struct { + return t.String() + } + var rec func(io.Writer, int, reflect.Type) + rec = func(out io.Writer, indent int, t reflect.Type) { + ind := strings.Repeat(" ", indent) + fmt.Fprintf(out, "%s", t.String()) + fs := collectFields(t) + if len(fs) > 0 { + io.WriteString(out, " {\n") + for _, f := range fs { + fmt.Fprintf(out, "%s %s ", ind, f.Name) + if f.Type.Kind() == reflect.Struct { + rec(out, indent+1, f.Type) + } else { + fmt.Fprint(out, f.Type) + } + io.WriteString(out, "\n") + } + fmt.Fprintf(out, "%s}", ind) + } + } + + var ret bytes.Buffer + rec(&ret, 0, t) + return ret.String() +} + +func collectFields(t reflect.Type) (ret []reflect.StructField) { + for _, f := range reflect.VisibleFields(t) { + if !f.IsExported() { + continue + } + ret = append(ret, f) + } + return ret +} diff --git a/vendor/tailscale.com/util/eventbus/debughttp_off.go b/vendor/tailscale.com/util/eventbus/debughttp_off.go new file mode 100644 index 0000000..3325252 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/debughttp_off.go @@ -0,0 +1,10 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ios || android || ts_omit_debugeventbus + +package eventbus + +type tswebDebugHandler = any // actually *tsweb.DebugHandler; any to avoid import tsweb with ts_omit_debugeventbus + +func (*Debugger) RegisterHTTP(td tswebDebugHandler) {} diff --git a/vendor/tailscale.com/util/eventbus/doc.go b/vendor/tailscale.com/util/eventbus/doc.go new file mode 100644 index 0000000..f95f939 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/doc.go @@ -0,0 +1,102 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package eventbus provides an in-process event bus. +// +// An event bus connects publishers of typed events with subscribers +// interested in those events. Typically, there is one global event +// bus per process. +// +// # Usage +// +// To send or receive events, first use [Bus.Client] to register with +// the bus. Clients should register with a human-readable name that +// identifies the code using the client, to aid in debugging. +// +// To publish events, use [Publish] on a Client to get a typed +// publisher for your event type, then call [Publisher.Publish] as +// needed. If your event is expensive to construct, you can optionally +// use [Publisher.ShouldPublish] to skip the work if nobody is +// listening for the event. +// +// To receive events, use [Subscribe] to get a typed subscriber for +// each event type you're interested in. Receive the events themselves +// by selecting over all your [Subscriber.Events] channels, as well as +// [Subscriber.Done] for shutdown notifications. +// +// # Concurrency properties +// +// The bus serializes all published events across all publishers, and +// preserves that ordering when delivering to subscribers that are +// attached to the same Client. In more detail: +// +// - An event is published to the bus at some instant between the +// start and end of the call to [Publisher.Publish]. +// - Two events cannot be published at the same instant, and so are +// totally ordered by their publication time. Given two events E1 +// and E2, either E1 happens before E2, or E2 happens before E1. +// - Clients dispatch events to their Subscribers in publication +// order: if E1 happens before E2, the client always delivers E1 +// before E2. +// - Clients do not synchronize subscriptions with each other: given +// clients C1 and C2, both subscribed to events E1 and E2, C1 may +// deliver both E1 and E2 before C2 delivers E1. +// +// Less formally: there is one true timeline of all published events. +// If you make a Client and subscribe to events, you will receive +// events one at a time, in the same order as the one true +// timeline. You will "skip over" events you didn't subscribe to, but +// your view of the world always moves forward in time, never +// backwards, and you will observe events in the same order as +// everyone else. +// +// However, you cannot assume that what your client see as "now" is +// the same as what other clients. They may be further behind you in +// working through the timeline, or running ahead of you. This means +// you should be careful about reaching out to another component +// directly after receiving an event, as its view of the world may not +// yet (or ever) be exactly consistent with yours. +// +// To make your code more testable and understandable, you should try +// to structure it following the actor model: you have some local +// state over which you have authority, but your only way to interact +// with state elsewhere in the program is to receive and process +// events coming from elsewhere, or to emit events of your own. +// +// # Expected subscriber behavior +// +// Subscribers are expected to promptly receive their events on +// [Subscriber.Events]. The bus has a small, fixed amount of internal +// buffering, meaning that a slow subscriber will eventually cause +// backpressure and block publication of all further events. +// +// In general, you should receive from your subscriber(s) in a loop, +// and only do fast state updates within that loop. Any heavier work +// should be offloaded to another goroutine. +// +// Causing publishers to block from backpressure is considered a bug +// in the slow subscriber causing the backpressure, and should be +// addressed there. Publishers should assume that Publish will not +// block for extended periods of time, and should not make exceptional +// effort to behave gracefully if they do get blocked. +// +// These blocking semantics are provisional and subject to +// change. Please speak up if this causes development pain, so that we +// can adapt the semantics to better suit our needs. +// +// # Debugging facilities +// +// The [Debugger], obtained through [Bus.Debugger], provides +// introspection facilities to monitor events flowing through the bus, +// and inspect publisher and subscriber state. +// +// Additionally, a debug command exists for monitoring the eventbus: +// +// tailscale debug daemon-bus-events +// +// # Testing facilities +// +// Helpers for testing code with the eventbus can be found in: +// +// eventbus/eventbustest +package eventbus diff --git a/vendor/tailscale.com/util/eventbus/monitor.go b/vendor/tailscale.com/util/eventbus/monitor.go new file mode 100644 index 0000000..db6fe1b --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/monitor.go @@ -0,0 +1,54 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import "tailscale.com/syncs" + +// A Monitor monitors the execution of a goroutine processing events from a +// [Client], allowing the caller to block until it is complete. The zero value +// of m is valid; its Close and Wait methods return immediately, and its Done +// method returns an already-closed channel. +type Monitor struct { + // These fields are immutable after initialization + cli *Client + done <-chan struct{} +} + +// Close closes the client associated with m and blocks until the processing +// goroutine is complete. +func (m Monitor) Close() { + if m.cli == nil { + return + } + m.cli.Close() + <-m.done +} + +// Wait blocks until the goroutine monitored by m has finished executing, but +// does not close the associated client. It is safe to call Wait repeatedly, +// and from multiple concurrent goroutines. +func (m Monitor) Wait() { + if m.done == nil { + return + } + <-m.done +} + +// Done returns a channel that is closed when the monitored goroutine has +// finished executing. +func (m Monitor) Done() <-chan struct{} { + if m.done == nil { + return syncs.ClosedChan() + } + return m.done +} + +// Monitor executes f in a new goroutine attended by a [Monitor]. The caller +// is responsible for waiting for the goroutine to complete, by calling either +// [Monitor.Close] or [Monitor.Wait]. +func (c *Client) Monitor(f func(*Client)) Monitor { + done := make(chan struct{}) + go func() { defer close(done); f(c) }() + return Monitor{cli: c, done: done} +} diff --git a/vendor/tailscale.com/util/eventbus/publish.go b/vendor/tailscale.com/util/eventbus/publish.go new file mode 100644 index 0000000..348bb9d --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/publish.go @@ -0,0 +1,74 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "reflect" +) + +// publisher is a uniformly typed wrapper around Publisher[T], so that +// debugging facilities can look at active publishers. +type publisher interface { + publishType() reflect.Type + Close() +} + +// A Publisher publishes typed events on a bus. +type Publisher[T any] struct { + client *Client + stop stopFlag +} + +func newPublisher[T any](c *Client) *Publisher[T] { + return &Publisher[T]{client: c} +} + +// Close closes the publisher. +// +// Calls to Publish after Close silently do nothing. +// +// If the Bus or Client from which the Publisher was created is closed, +// the Publisher is implicitly closed and does not need to be closed +// separately. +func (p *Publisher[T]) Close() { + // Just unblocks any active calls to Publish, no other + // synchronization needed. + p.stop.Stop() + p.client.deletePublisher(p) +} + +func (p *Publisher[T]) publishType() reflect.Type { + return reflect.TypeFor[T]() +} + +// Publish publishes event v on the bus. +func (p *Publisher[T]) Publish(v T) { + // Check for just a stopped publisher or bus before trying to + // write, so that once closed Publish consistently does nothing. + select { + case <-p.stop.Done(): + return + default: + } + + evt := PublishedEvent{ + Event: v, + From: p.client, + } + + select { + case p.client.publish() <- evt: + case <-p.stop.Done(): + } +} + +// ShouldPublish reports whether anyone is subscribed to the events +// that this publisher emits. +// +// ShouldPublish can be used to skip expensive event construction if +// nobody seems to care. Publishers must not assume that someone will +// definitely receive an event if ShouldPublish returns true. +func (p *Publisher[T]) ShouldPublish() bool { + return p.client.shouldPublish(reflect.TypeFor[T]()) +} diff --git a/vendor/tailscale.com/util/eventbus/queue.go b/vendor/tailscale.com/util/eventbus/queue.go new file mode 100644 index 0000000..2589b75 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/queue.go @@ -0,0 +1,85 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "slices" +) + +// queue is an ordered queue of length up to capacity, +// if capacity is non-zero. Otherwise it is unbounded. +type queue[T any] struct { + vals []T + start int + capacity int // zero means unbounded +} + +// canAppend reports whether a value can be appended to q.vals without +// shifting values around. +func (q *queue[T]) canAppend() bool { + return q.capacity == 0 || cap(q.vals) < q.capacity || len(q.vals) < cap(q.vals) +} + +func (q *queue[T]) Full() bool { + return q.start == 0 && !q.canAppend() +} + +func (q *queue[T]) Empty() bool { + return q.start == len(q.vals) +} + +func (q *queue[T]) Len() int { + return len(q.vals) - q.start +} + +// Add adds v to the end of the queue. Blocks until append can be +// done. +func (q *queue[T]) Add(v T) { + if !q.canAppend() { + if q.start == 0 { + panic("Add on a full queue") + } + + // Slide remaining values back to the start of the array. + n := copy(q.vals, q.vals[q.start:]) + toClear := len(q.vals) - n + clear(q.vals[len(q.vals)-toClear:]) + q.vals = q.vals[:n] + q.start = 0 + } + + q.vals = append(q.vals, v) +} + +// Peek returns the first value in the queue, without removing it from +// the queue, or nil if the queue is empty. +func (q *queue[T]) Peek() T { + if q.Empty() { + var zero T + return zero + } + + return q.vals[q.start] +} + +// Drop discards the first value in the queue, if any. +func (q *queue[T]) Drop() { + if q.Empty() { + return + } + + var zero T + q.vals[q.start] = zero + q.start++ + if q.Empty() { + // Reset cursor to start of array, it's free to do. + q.start = 0 + q.vals = q.vals[:0] + } +} + +// Snapshot returns a copy of the queue's contents. +func (q *queue[T]) Snapshot() []T { + return slices.Clone(q.vals[q.start:]) +} diff --git a/vendor/tailscale.com/util/eventbus/subscribe.go b/vendor/tailscale.com/util/eventbus/subscribe.go new file mode 100644 index 0000000..b0348e1 --- /dev/null +++ b/vendor/tailscale.com/util/eventbus/subscribe.go @@ -0,0 +1,356 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package eventbus + +import ( + "context" + "fmt" + "reflect" + "runtime" + "time" + + "tailscale.com/syncs" + "tailscale.com/types/logger" + "tailscale.com/util/cibuild" +) + +type DeliveredEvent struct { + Event any + From *Client + To *Client +} + +// subscriber is a uniformly typed wrapper around Subscriber[T], so +// that debugging facilities can look at active subscribers. +type subscriber interface { + subscribeType() reflect.Type + // dispatch is a function that dispatches the head value in vals to + // a subscriber, while also handling stop and incoming queue write + // events. + // + // dispatch exists because of the strongly typed Subscriber[T] + // wrapper around subscriptions: within the bus events are boxed in an + // 'any', and need to be unpacked to their full type before delivery + // to the subscriber. This involves writing to a strongly-typed + // channel, so subscribeState cannot handle that dispatch by itself - + // but if that strongly typed send blocks, we also need to keep + // processing other potential sources of wakeups, which is how we end + // up at this awkward type signature and sharing of internal state + // through dispatch. + dispatch(ctx context.Context, vals *queue[DeliveredEvent], acceptCh func() chan DeliveredEvent, snapshot chan chan []DeliveredEvent) bool + Close() +} + +// subscribeState handles dispatching of events received from a Bus. +type subscribeState struct { + client *Client + + dispatcher *worker + write chan DeliveredEvent + snapshot chan chan []DeliveredEvent + debug hook[DeliveredEvent] + + outputsMu syncs.Mutex + outputs map[reflect.Type]subscriber +} + +func newSubscribeState(c *Client) *subscribeState { + ret := &subscribeState{ + client: c, + write: make(chan DeliveredEvent), + snapshot: make(chan chan []DeliveredEvent), + outputs: map[reflect.Type]subscriber{}, + } + ret.dispatcher = runWorker(ret.pump) + return ret +} + +func (s *subscribeState) pump(ctx context.Context) { + var vals queue[DeliveredEvent] + acceptCh := func() chan DeliveredEvent { + if vals.Full() { + return nil + } + return s.write + } + for { + if !vals.Empty() { + val := vals.Peek() + sub := s.subscriberFor(val.Event) + if sub == nil { + // Raced with unsubscribe. + vals.Drop() + continue + } + if !sub.dispatch(ctx, &vals, acceptCh, s.snapshot) { + return + } + + if s.debug.active() { + s.debug.run(DeliveredEvent{ + Event: val.Event, + From: val.From, + To: s.client, + }) + } + } else { + // Keep the cases in this select in sync with + // Subscriber.dispatch and SubscriberFunc.dispatch below. + // The only difference should be that this select doesn't deliver + // queued values to anyone, and unconditionally accepts new values. + select { + case val := <-s.write: + vals.Add(val) + case <-ctx.Done(): + return + case ch := <-s.snapshot: + ch <- vals.Snapshot() + } + } + } +} + +func (s *subscribeState) snapshotQueue() []DeliveredEvent { + if s == nil { + return nil + } + + resp := make(chan []DeliveredEvent) + select { + case s.snapshot <- resp: + return <-resp + case <-s.dispatcher.Done(): + return nil + } +} + +func (s *subscribeState) subscribeTypes() []reflect.Type { + if s == nil { + return nil + } + + s.outputsMu.Lock() + defer s.outputsMu.Unlock() + ret := make([]reflect.Type, 0, len(s.outputs)) + for t := range s.outputs { + ret = append(ret, t) + } + return ret +} + +func (s *subscribeState) addSubscriber(sub subscriber) { + s.outputsMu.Lock() + defer s.outputsMu.Unlock() + t := sub.subscribeType() + if s.outputs[t] != nil { + panic(fmt.Errorf("double subscription for event %s", t)) + } + s.outputs[t] = sub + s.client.addSubscriber(t, s) +} + +func (s *subscribeState) deleteSubscriber(t reflect.Type) { + s.outputsMu.Lock() + defer s.outputsMu.Unlock() + delete(s.outputs, t) + s.client.deleteSubscriber(t, s) +} + +func (s *subscribeState) subscriberFor(val any) subscriber { + s.outputsMu.Lock() + defer s.outputsMu.Unlock() + return s.outputs[reflect.TypeOf(val)] +} + +// Close closes the subscribeState. It implicitly closes all Subscribers +// linked to this state, and any pending events are discarded. +func (s *subscribeState) close() { + s.dispatcher.StopAndWait() + + var subs map[reflect.Type]subscriber + s.outputsMu.Lock() + subs, s.outputs = s.outputs, nil + s.outputsMu.Unlock() + for _, sub := range subs { + sub.Close() + } +} + +func (s *subscribeState) closed() <-chan struct{} { + return s.dispatcher.Done() +} + +// A Subscriber delivers one type of event from a [Client]. +// Events are sent to the [Subscriber.Events] channel. +type Subscriber[T any] struct { + stop stopFlag + read chan T + unregister func() + logf logger.Logf + slow *time.Timer // used to detect slow subscriber service +} + +func newSubscriber[T any](r *subscribeState, logf logger.Logf) *Subscriber[T] { + slow := time.NewTimer(0) + slow.Stop() // reset in dispatch + return &Subscriber[T]{ + read: make(chan T), + unregister: func() { r.deleteSubscriber(reflect.TypeFor[T]()) }, + logf: logf, + slow: slow, + } +} + +func newMonitor[T any](attach func(fn func(T)) (cancel func())) *Subscriber[T] { + ret := &Subscriber[T]{ + read: make(chan T, 100), // arbitrary, large + } + ret.unregister = attach(ret.monitor) + return ret +} + +func (s *Subscriber[T]) subscribeType() reflect.Type { + return reflect.TypeFor[T]() +} + +func (s *Subscriber[T]) monitor(debugEvent T) { + select { + case s.read <- debugEvent: + case <-s.stop.Done(): + } +} + +func (s *Subscriber[T]) dispatch(ctx context.Context, vals *queue[DeliveredEvent], acceptCh func() chan DeliveredEvent, snapshot chan chan []DeliveredEvent) bool { + t := vals.Peek().Event.(T) + + start := time.Now() + s.slow.Reset(slowSubscriberTimeout) + defer s.slow.Stop() + + for { + // Keep the cases in this select in sync with subscribeState.pump + // above. The only difference should be that this select + // delivers a value on s.read. + select { + case s.read <- t: + vals.Drop() + return true + case val := <-acceptCh(): + vals.Add(val) + case <-ctx.Done(): + return false + case ch := <-snapshot: + ch <- vals.Snapshot() + case <-s.slow.C: + s.logf("subscriber for %T is slow (%v elapsed)", t, time.Since(start)) + s.slow.Reset(slowSubscriberTimeout) + } + } +} + +// Events returns a channel on which the subscriber's events are +// delivered. +func (s *Subscriber[T]) Events() <-chan T { + return s.read +} + +// Done returns a channel that is closed when the subscriber is +// closed. +func (s *Subscriber[T]) Done() <-chan struct{} { + return s.stop.Done() +} + +// Close closes the Subscriber, indicating the caller no longer wishes +// to receive this event type. After Close, receives on +// [Subscriber.Events] block for ever. +// +// If the Bus from which the Subscriber was created is closed, +// the Subscriber is implicitly closed and does not need to be closed +// separately. +func (s *Subscriber[T]) Close() { + s.stop.Stop() // unblock receivers + s.unregister() +} + +// A SubscriberFunc delivers one type of event from a [Client]. +// Events are forwarded synchronously to a function provided at construction. +type SubscriberFunc[T any] struct { + stop stopFlag + read func(T) + unregister func() + logf logger.Logf + slow *time.Timer // used to detect slow subscriber service +} + +func newSubscriberFunc[T any](r *subscribeState, f func(T), logf logger.Logf) *SubscriberFunc[T] { + slow := time.NewTimer(0) + slow.Stop() // reset in dispatch + return &SubscriberFunc[T]{ + read: f, + unregister: func() { r.deleteSubscriber(reflect.TypeFor[T]()) }, + logf: logf, + slow: slow, + } +} + +// Close closes the SubscriberFunc, indicating the caller no longer wishes to +// receive this event type. After Close, no further events will be passed to +// the callback. +// +// If the [Bus] from which s was created is closed, s is implicitly closed and +// does not need to be closed separately. +func (s *SubscriberFunc[T]) Close() { s.stop.Stop(); s.unregister() } + +// subscribeType implements part of the subscriber interface. +func (s *SubscriberFunc[T]) subscribeType() reflect.Type { return reflect.TypeFor[T]() } + +// dispatch implements part of the subscriber interface. +func (s *SubscriberFunc[T]) dispatch(ctx context.Context, vals *queue[DeliveredEvent], acceptCh func() chan DeliveredEvent, snapshot chan chan []DeliveredEvent) bool { + t := vals.Peek().Event.(T) + callDone := make(chan struct{}) + go s.runCallback(t, callDone) + + start := time.Now() + s.slow.Reset(slowSubscriberTimeout) + defer s.slow.Stop() + + // Keep the cases in this select in sync with subscribeState.pump + // above. The only difference should be that this select + // delivers a value by calling s.read. + for { + select { + case <-callDone: + vals.Drop() + return true + case val := <-acceptCh(): + vals.Add(val) + case <-ctx.Done(): + // Wait for the callback to be complete, but not forever. + s.slow.Reset(5 * slowSubscriberTimeout) + select { + case <-s.slow.C: + s.logf("giving up on subscriber for %T after %v at close", t, time.Since(start)) + if cibuild.On() { + all := make([]byte, 2<<20) + n := runtime.Stack(all, true) + s.logf("goroutine stacks:\n%s", all[:n]) + } + case <-callDone: + } + return false + case ch := <-snapshot: + ch <- vals.Snapshot() + case <-s.slow.C: + s.logf("subscriber for %T is slow (%v elapsed)", t, time.Since(start)) + s.slow.Reset(slowSubscriberTimeout) + } + } +} + +// runCallback invokes the callback on v and closes ch when it returns. +// This should be run in a goroutine. +func (s *SubscriberFunc[T]) runCallback(v T, ch chan struct{}) { + defer close(ch) + s.read(v) +} diff --git a/vendor/tailscale.com/util/execqueue/execqueue.go b/vendor/tailscale.com/util/execqueue/execqueue.go index 889cea2..87616a6 100644 --- a/vendor/tailscale.com/util/execqueue/execqueue.go +++ b/vendor/tailscale.com/util/execqueue/execqueue.go @@ -7,11 +7,14 @@ package execqueue import ( "context" "errors" - "sync" + + "tailscale.com/syncs" ) type ExecQueue struct { - mu sync.Mutex + mu syncs.Mutex + ctx context.Context // context.Background + closed on Shutdown + cancel context.CancelFunc // closes ctx closed bool inFlight bool // whether a goroutine is running q.run doneWaiter chan struct{} // non-nil if waiter is waiting, then closed @@ -24,6 +27,7 @@ func (q *ExecQueue) Add(f func()) { if q.closed { return } + q.initCtxLocked() if q.inFlight { q.queue = append(q.queue, f) } else { @@ -35,21 +39,21 @@ func (q *ExecQueue) Add(f func()) { // RunSync waits for the queue to be drained and then synchronously runs f. // It returns an error if the queue is closed before f is run or ctx expires. func (q *ExecQueue) RunSync(ctx context.Context, f func()) error { - for { - if err := q.Wait(ctx); err != nil { - return err - } - q.mu.Lock() - if q.inFlight { - q.mu.Unlock() - continue - } - defer q.mu.Unlock() - if q.closed { - return errors.New("closed") - } - f() + q.mu.Lock() + q.initCtxLocked() + shutdownCtx := q.ctx + q.mu.Unlock() + + ch := make(chan struct{}) + q.Add(f) + q.Add(func() { close(ch) }) + select { + case <-ch: return nil + case <-ctx.Done(): + return ctx.Err() + case <-shutdownCtx.Done(): + return errExecQueueShutdown } } @@ -79,18 +83,35 @@ func (q *ExecQueue) Shutdown() { q.mu.Lock() defer q.mu.Unlock() q.closed = true + if q.cancel != nil { + q.cancel() + } } -// Wait waits for the queue to be empty. +func (q *ExecQueue) initCtxLocked() { + if q.ctx == nil { + q.ctx, q.cancel = context.WithCancel(context.Background()) + } +} + +var errExecQueueShutdown = errors.New("execqueue shut down") + +// Wait waits for the queue to be empty or shut down. func (q *ExecQueue) Wait(ctx context.Context) error { q.mu.Lock() + q.initCtxLocked() waitCh := q.doneWaiter if q.inFlight && waitCh == nil { waitCh = make(chan struct{}) q.doneWaiter = waitCh } + closed := q.closed + shutdownCtx := q.ctx q.mu.Unlock() + if closed { + return errExecQueueShutdown + } if waitCh == nil { return nil } @@ -98,6 +119,8 @@ func (q *ExecQueue) Wait(ctx context.Context) error { select { case <-waitCh: return nil + case <-shutdownCtx.Done(): + return errExecQueueShutdown case <-ctx.Done(): return ctx.Err() } diff --git a/vendor/tailscale.com/util/goroutines/tracker.go b/vendor/tailscale.com/util/goroutines/tracker.go index 044843d..c2a0cb8 100644 --- a/vendor/tailscale.com/util/goroutines/tracker.go +++ b/vendor/tailscale.com/util/goroutines/tracker.go @@ -4,9 +4,9 @@ package goroutines import ( - "sync" "sync/atomic" + "tailscale.com/syncs" "tailscale.com/util/set" ) @@ -15,7 +15,7 @@ type Tracker struct { started atomic.Int64 // counter running atomic.Int64 // gauge - mu sync.Mutex + mu syncs.Mutex onDone set.HandleSet[func()] } diff --git a/vendor/tailscale.com/util/httphdr/httphdr.go b/vendor/tailscale.com/util/httphdr/httphdr.go deleted file mode 100644 index 852e28b..0000000 --- a/vendor/tailscale.com/util/httphdr/httphdr.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package httphdr implements functionality for parsing and formatting -// standard HTTP headers. -package httphdr - -import ( - "bytes" - "strconv" - "strings" -) - -// Range is a range of bytes within some content. -type Range struct { - // Start is the starting offset. - // It is zero if Length is negative; it must not be negative. - Start int64 - // Length is the length of the content. - // It is zero if the length extends to the end of the content. - // It is negative if the length is relative to the end (e.g., last 5 bytes). - Length int64 -} - -// ows is optional whitespace. -const ows = " \t" // per RFC 7230, section 3.2.3 - -// ParseRange parses a "Range" header per RFC 7233, section 3. -// It only handles "Range" headers where the units is "bytes". -// The "Range" header is usually only specified in GET requests. -func ParseRange(hdr string) (ranges []Range, ok bool) { - // Grammar per RFC 7233, appendix D: - // Range = byte-ranges-specifier | other-ranges-specifier - // byte-ranges-specifier = bytes-unit "=" byte-range-set - // bytes-unit = "bytes" - // byte-range-set = - // *("," OWS) - // (byte-range-spec | suffix-byte-range-spec) - // *(OWS "," [OWS ( byte-range-spec | suffix-byte-range-spec )]) - // byte-range-spec = first-byte-pos "-" [last-byte-pos] - // suffix-byte-range-spec = "-" suffix-length - // We do not support other-ranges-specifier. - // All other identifiers are 1*DIGIT. - hdr = strings.Trim(hdr, ows) // per RFC 7230, section 3.2 - units, elems, hasUnits := strings.Cut(hdr, "=") - elems = strings.TrimLeft(elems, ","+ows) - for _, elem := range strings.Split(elems, ",") { - elem = strings.Trim(elem, ows) // per RFC 7230, section 7 - switch { - case strings.HasPrefix(elem, "-"): // i.e., "-" suffix-length - n, ok := parseNumber(strings.TrimPrefix(elem, "-")) - if !ok { - return ranges, false - } - ranges = append(ranges, Range{0, -n}) - case strings.HasSuffix(elem, "-"): // i.e., first-byte-pos "-" - n, ok := parseNumber(strings.TrimSuffix(elem, "-")) - if !ok { - return ranges, false - } - ranges = append(ranges, Range{n, 0}) - default: // i.e., first-byte-pos "-" last-byte-pos - prefix, suffix, hasDash := strings.Cut(elem, "-") - n, ok2 := parseNumber(prefix) - m, ok3 := parseNumber(suffix) - if !hasDash || !ok2 || !ok3 || m < n { - return ranges, false - } - ranges = append(ranges, Range{n, m - n + 1}) - } - } - return ranges, units == "bytes" && hasUnits && len(ranges) > 0 // must see at least one element per RFC 7233, section 2.1 -} - -// FormatRange formats a "Range" header per RFC 7233, section 3. -// It only handles "Range" headers where the units is "bytes". -// The "Range" header is usually only specified in GET requests. -func FormatRange(ranges []Range) (hdr string, ok bool) { - b := []byte("bytes=") - for _, r := range ranges { - switch { - case r.Length > 0: // i.e., first-byte-pos "-" last-byte-pos - if r.Start < 0 { - return string(b), false - } - b = strconv.AppendUint(b, uint64(r.Start), 10) - b = append(b, '-') - b = strconv.AppendUint(b, uint64(r.Start+r.Length-1), 10) - b = append(b, ',') - case r.Length == 0: // i.e., first-byte-pos "-" - if r.Start < 0 { - return string(b), false - } - b = strconv.AppendUint(b, uint64(r.Start), 10) - b = append(b, '-') - b = append(b, ',') - case r.Length < 0: // i.e., "-" suffix-length - if r.Start != 0 { - return string(b), false - } - b = append(b, '-') - b = strconv.AppendUint(b, uint64(-r.Length), 10) - b = append(b, ',') - default: - return string(b), false - } - } - return string(bytes.TrimRight(b, ",")), len(ranges) > 0 -} - -// ParseContentRange parses a "Content-Range" header per RFC 7233, section 4.2. -// It only handles "Content-Range" headers where the units is "bytes". -// The "Content-Range" header is usually only specified in HTTP responses. -// -// If only the completeLength is specified, then start and length are both zero. -// -// Otherwise, the parses the start and length and the optional completeLength, -// which is -1 if unspecified. The start is non-negative and the length is positive. -func ParseContentRange(hdr string) (start, length, completeLength int64, ok bool) { - // Grammar per RFC 7233, appendix D: - // Content-Range = byte-content-range | other-content-range - // byte-content-range = bytes-unit SP (byte-range-resp | unsatisfied-range) - // bytes-unit = "bytes" - // byte-range-resp = byte-range "/" (complete-length | "*") - // unsatisfied-range = "*/" complete-length - // byte-range = first-byte-pos "-" last-byte-pos - // We do not support other-content-range. - // All other identifiers are 1*DIGIT. - hdr = strings.Trim(hdr, ows) // per RFC 7230, section 3.2 - suffix, hasUnits := strings.CutPrefix(hdr, "bytes ") - suffix, unsatisfied := strings.CutPrefix(suffix, "*/") - if unsatisfied { // i.e., unsatisfied-range - n, ok := parseNumber(suffix) - if !ok { - return start, length, completeLength, false - } - completeLength = n - } else { // i.e., byte-range "/" (complete-length | "*") - prefix, suffix, hasDash := strings.Cut(suffix, "-") - middle, suffix, hasSlash := strings.Cut(suffix, "/") - n, ok0 := parseNumber(prefix) - m, ok1 := parseNumber(middle) - o, ok2 := parseNumber(suffix) - if suffix == "*" { - o, ok2 = -1, true - } - if !hasDash || !hasSlash || !ok0 || !ok1 || !ok2 || m < n || (o >= 0 && o <= m) { - return start, length, completeLength, false - } - start = n - length = m - n + 1 - completeLength = o - } - return start, length, completeLength, hasUnits -} - -// FormatContentRange parses a "Content-Range" header per RFC 7233, section 4.2. -// It only handles "Content-Range" headers where the units is "bytes". -// The "Content-Range" header is usually only specified in HTTP responses. -// -// If start and length are non-positive, then it encodes just the completeLength, -// which must be a non-negative value. -// -// Otherwise, it encodes the start and length as a byte-range, -// and optionally emits the complete length if it is non-negative. -// The length must be positive (as RFC 7233 uses inclusive end offsets). -func FormatContentRange(start, length, completeLength int64) (hdr string, ok bool) { - b := []byte("bytes ") - switch { - case start <= 0 && length <= 0 && completeLength >= 0: // i.e., unsatisfied-range - b = append(b, "*/"...) - b = strconv.AppendUint(b, uint64(completeLength), 10) - ok = true - case start >= 0 && length > 0: // i.e., byte-range "/" (complete-length | "*") - b = strconv.AppendUint(b, uint64(start), 10) - b = append(b, '-') - b = strconv.AppendUint(b, uint64(start+length-1), 10) - b = append(b, '/') - if completeLength >= 0 { - b = strconv.AppendUint(b, uint64(completeLength), 10) - ok = completeLength >= start+length && start+length > 0 - } else { - b = append(b, '*') - ok = true - } - } - return string(b), ok -} - -// parseNumber parses s as an unsigned decimal integer. -// It parses according to the 1*DIGIT grammar, which allows leading zeros. -func parseNumber(s string) (int64, bool) { - suffix := strings.TrimLeft(s, "0123456789") - prefix := s[:len(s)-len(suffix)] - n, err := strconv.ParseInt(prefix, 10, 64) - return n, suffix == "" && err == nil -} diff --git a/vendor/tailscale.com/util/linuxfw/detector.go b/vendor/tailscale.com/util/linuxfw/detector.go deleted file mode 100644 index f3ee4aa..0000000 --- a/vendor/tailscale.com/util/linuxfw/detector.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "errors" - "os/exec" - - "tailscale.com/envknob" - "tailscale.com/hostinfo" - "tailscale.com/types/logger" - "tailscale.com/version/distro" -) - -func detectFirewallMode(logf logger.Logf, prefHint string) FirewallMode { - if distro.Get() == distro.Gokrazy { - // Reduce startup logging on gokrazy. There's no way to do iptables on - // gokrazy anyway. - logf("GoKrazy should use nftables.") - hostinfo.SetFirewallMode("nft-gokrazy") - return FirewallModeNfTables - } - - mode := envknob.String("TS_DEBUG_FIREWALL_MODE") - // If the envknob isn't set, fall back to the pref suggested by c2n or - // nodeattrs. - if mode == "" { - mode = prefHint - logf("using firewall mode pref %s", prefHint) - } else if prefHint != "" { - logf("TS_DEBUG_FIREWALL_MODE set, overriding firewall mode from %s to %s", prefHint, mode) - } - - var det linuxFWDetector - if mode == "" { - // We have no preference, so check if `iptables` is even available. - _, err := det.iptDetect() - if err != nil && errors.Is(err, exec.ErrNotFound) { - logf("iptables not found: %v; falling back to nftables", err) - mode = "nftables" - } - } - - // We now use iptables as default and have "auto" and "nftables" as - // options for people to test further. - switch mode { - case "auto": - return pickFirewallModeFromInstalledRules(logf, det) - case "nftables": - hostinfo.SetFirewallMode("nft-forced") - return FirewallModeNfTables - case "iptables": - hostinfo.SetFirewallMode("ipt-forced") - default: - logf("default choosing iptables") - hostinfo.SetFirewallMode("ipt-default") - } - return FirewallModeIPTables -} - -// tableDetector abstracts helpers to detect the firewall mode. -// It is implemented for testing purposes. -type tableDetector interface { - iptDetect() (int, error) - nftDetect() (int, error) -} - -type linuxFWDetector struct{} - -// iptDetect returns the number of iptables rules in the current namespace. -func (l linuxFWDetector) iptDetect() (int, error) { - return detectIptables() -} - -// nftDetect returns the number of nftables rules in the current namespace. -func (l linuxFWDetector) nftDetect() (int, error) { - return detectNetfilter() -} - -// pickFirewallModeFromInstalledRules returns the firewall mode to use based on -// the environment and the system's capabilities. -func pickFirewallModeFromInstalledRules(logf logger.Logf, det tableDetector) FirewallMode { - if distro.Get() == distro.Gokrazy { - // Reduce startup logging on gokrazy. There's no way to do iptables on - // gokrazy anyway. - return FirewallModeNfTables - } - iptAva, nftAva := true, true - iptRuleCount, err := det.iptDetect() - if err != nil { - logf("detect iptables rule: %v", err) - iptAva = false - } - nftRuleCount, err := det.nftDetect() - if err != nil { - logf("detect nftables rule: %v", err) - nftAva = false - } - logf("nftables rule count: %d, iptables rule count: %d", nftRuleCount, iptRuleCount) - switch { - case nftRuleCount > 0 && iptRuleCount == 0: - logf("nftables is currently in use") - hostinfo.SetFirewallMode("nft-inuse") - return FirewallModeNfTables - case iptRuleCount > 0 && nftRuleCount == 0: - logf("iptables is currently in use") - hostinfo.SetFirewallMode("ipt-inuse") - return FirewallModeIPTables - case nftAva: - // if both iptables and nftables are available but - // neither/both are currently used, use nftables. - logf("nftables is available") - hostinfo.SetFirewallMode("nft") - return FirewallModeNfTables - case iptAva: - logf("iptables is available") - hostinfo.SetFirewallMode("ipt") - return FirewallModeIPTables - default: - // if neither iptables nor nftables are available, use iptablesRunner as a dummy - // runner which exists but won't do anything. Creating iptablesRunner errors only - // if the iptables command is missing or doesn’t support "--version", as long as it - // can determine a version then it’ll carry on. - hostinfo.SetFirewallMode("ipt-fb") - return FirewallModeIPTables - } -} diff --git a/vendor/tailscale.com/util/linuxfw/fake.go b/vendor/tailscale.com/util/linuxfw/fake.go deleted file mode 100644 index 63a728d..0000000 --- a/vendor/tailscale.com/util/linuxfw/fake.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "errors" - "fmt" - "os" - "strconv" - "strings" -) - -type fakeIPTables struct { - n map[string][]string -} - -type fakeRule struct { - table, chain string - args []string -} - -func newFakeIPTables() *fakeIPTables { - return &fakeIPTables{ - n: map[string][]string{ - "filter/INPUT": nil, - "filter/OUTPUT": nil, - "filter/FORWARD": nil, - "nat/PREROUTING": nil, - "nat/OUTPUT": nil, - "nat/POSTROUTING": nil, - "mangle/FORWARD": nil, - }, - } -} - -func (n *fakeIPTables) Insert(table, chain string, pos int, args ...string) error { - k := table + "/" + chain - if rules, ok := n.n[k]; ok { - if pos > len(rules)+1 { - return fmt.Errorf("bad position %d in %s", pos, k) - } - rules = append(rules, "") - copy(rules[pos:], rules[pos-1:]) - rules[pos-1] = strings.Join(args, " ") - n.n[k] = rules - } else { - return fmt.Errorf("unknown table/chain %s", k) - } - return nil -} - -func (n *fakeIPTables) Append(table, chain string, args ...string) error { - k := table + "/" + chain - return n.Insert(table, chain, len(n.n[k])+1, args...) -} - -func (n *fakeIPTables) Exists(table, chain string, args ...string) (bool, error) { - k := table + "/" + chain - if rules, ok := n.n[k]; ok { - for _, rule := range rules { - if rule == strings.Join(args, " ") { - return true, nil - } - } - return false, nil - } else { - return false, fmt.Errorf("unknown table/chain %s", k) - } -} - -func (n *fakeIPTables) Delete(table, chain string, args ...string) error { - k := table + "/" + chain - if rules, ok := n.n[k]; ok { - for i, rule := range rules { - if rule == strings.Join(args, " ") { - rules = append(rules[:i], rules[i+1:]...) - n.n[k] = rules - return nil - } - } - return fmt.Errorf("delete of unknown rule %q from %s", strings.Join(args, " "), k) - } else { - return fmt.Errorf("unknown table/chain %s", k) - } -} - -func (n *fakeIPTables) List(table, chain string) ([]string, error) { - k := table + "/" + chain - if rules, ok := n.n[k]; ok { - return rules, nil - } else { - return nil, fmt.Errorf("unknown table/chain %s", k) - } -} - -func (n *fakeIPTables) ClearChain(table, chain string) error { - k := table + "/" + chain - if _, ok := n.n[k]; ok { - n.n[k] = nil - return nil - } else { - return errors.New("exitcode:1") - } -} - -func (n *fakeIPTables) NewChain(table, chain string) error { - k := table + "/" + chain - if _, ok := n.n[k]; ok { - return fmt.Errorf("table/chain %s already exists", k) - } - n.n[k] = nil - return nil -} - -func (n *fakeIPTables) DeleteChain(table, chain string) error { - k := table + "/" + chain - if rules, ok := n.n[k]; ok { - if len(rules) != 0 { - return fmt.Errorf("table/chain %s is not empty", k) - } - delete(n.n, k) - return nil - } else { - return fmt.Errorf("unknown table/chain %s", k) - } -} - -func NewFakeIPTablesRunner() *iptablesRunner { - ipt4 := newFakeIPTables() - v6Available := false - var ipt6 iptablesInterface - if use6, err := strconv.ParseBool(os.Getenv("TS_TEST_FAKE_NETFILTER_6")); use6 || err != nil { - ipt6 = newFakeIPTables() - v6Available = true - } - - iptr := &iptablesRunner{ipt4, ipt6, v6Available, v6Available, v6Available} - return iptr -} diff --git a/vendor/tailscale.com/util/linuxfw/helpers.go b/vendor/tailscale.com/util/linuxfw/helpers.go deleted file mode 100644 index a4b9fdf..0000000 --- a/vendor/tailscale.com/util/linuxfw/helpers.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "encoding/hex" - "fmt" - "strings" - "unicode" - - "tailscale.com/util/slicesx" -) - -func formatMaybePrintable(b []byte) string { - // Remove a single trailing null, if any. - if slicesx.LastEqual(b, 0) { - b = b[:len(b)-1] - } - - nonprintable := strings.IndexFunc(string(b), func(r rune) bool { - return r > unicode.MaxASCII || !unicode.IsPrint(r) - }) - if nonprintable >= 0 { - return "" + hex.EncodeToString(b) - } - return string(b) -} - -func formatPortRange(r [2]uint16) string { - if r == [2]uint16{0, 65535} { - return fmt.Sprintf(`any`) - } else if r[0] == r[1] { - return fmt.Sprintf(`%d`, r[0]) - } - return fmt.Sprintf(`%d-%d`, r[0], r[1]) -} diff --git a/vendor/tailscale.com/util/linuxfw/iptables.go b/vendor/tailscale.com/util/linuxfw/iptables.go deleted file mode 100644 index 234fa52..0000000 --- a/vendor/tailscale.com/util/linuxfw/iptables.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// TODO(#8502): add support for more architectures -//go:build linux && (arm64 || amd64) - -package linuxfw - -import ( - "fmt" - "os/exec" - "strings" - "unicode" - - "tailscale.com/types/logger" - "tailscale.com/util/multierr" -) - -// DebugNetfilter prints debug information about iptables rules to the -// provided log function. -func DebugIptables(logf logger.Logf) error { - // unused. - return nil -} - -// detectIptables returns the number of iptables rules that are present in the -// system, ignoring the default "ACCEPT" rule present in the standard iptables -// chains. -// -// It only returns an error when there is no iptables binary, or when iptables -S -// fails. In all other cases, it returns the number of non-default rules. -// -// If the iptables binary is not found, it returns an underlying exec.ErrNotFound -// error. -func detectIptables() (int, error) { - // run "iptables -S" to get the list of rules using iptables - // exec.Command returns an error if the binary is not found - cmd := exec.Command("iptables", "-S") - output, err := cmd.Output() - ip6cmd := exec.Command("ip6tables", "-S") - ip6output, ip6err := ip6cmd.Output() - var allLines []string - outputStr := string(output) - lines := strings.Split(outputStr, "\n") - ip6outputStr := string(ip6output) - ip6lines := strings.Split(ip6outputStr, "\n") - switch { - case err == nil && ip6err == nil: - allLines = append(lines, ip6lines...) - case err == nil && ip6err != nil: - allLines = lines - case err != nil && ip6err == nil: - allLines = ip6lines - default: - return 0, FWModeNotSupportedError{ - Mode: FirewallModeIPTables, - Err: fmt.Errorf("iptables command run fail: %w", multierr.New(err, ip6err)), - } - } - - // count the number of non-default rules - count := 0 - for _, line := range allLines { - trimmedLine := strings.TrimLeftFunc(line, unicode.IsSpace) - if line != "" && strings.HasPrefix(trimmedLine, "-A") { - // if the line is not empty and starts with "-A", it is a rule appended not default - count++ - } - } - - // return the count of non-default rules - return count, nil -} diff --git a/vendor/tailscale.com/util/linuxfw/iptables_for_svcs.go b/vendor/tailscale.com/util/linuxfw/iptables_for_svcs.go deleted file mode 100644 index 8e0f5d4..0000000 --- a/vendor/tailscale.com/util/linuxfw/iptables_for_svcs.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "fmt" - "net/netip" -) - -// This file contains functionality to insert portmapping rules for a 'service'. -// These are currently only used by the Kubernetes operator proxies. -// An iptables rule for such a service contains a comment with the service name. - -// EnsurePortMapRuleForSvc adds a prerouting rule that forwards traffic received -// on match port and NOT on the provided interface to target IP and target port. -// Rule will only be added if it does not already exists. -func (i *iptablesRunner) EnsurePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error { - table := i.getIPTByAddr(targetIP) - args := argsForPortMapRule(svc, tun, targetIP, pm) - exists, err := table.Exists("nat", "PREROUTING", args...) - if err != nil { - return fmt.Errorf("error checking if rule exists: %w", err) - } - if !exists { - return table.Append("nat", "PREROUTING", args...) - } - return nil -} - -// DeleteMapRuleForSvc constructs a prerouting rule as would be created by -// EnsurePortMapRuleForSvc with the provided args and, if such a rule exists, -// deletes it. -func (i *iptablesRunner) DeletePortMapRuleForSvc(svc, excludeI string, targetIP netip.Addr, pm PortMap) error { - table := i.getIPTByAddr(targetIP) - args := argsForPortMapRule(svc, excludeI, targetIP, pm) - exists, err := table.Exists("nat", "PREROUTING", args...) - if err != nil { - return fmt.Errorf("error checking if rule exists: %w", err) - } - if exists { - return table.Delete("nat", "PREROUTING", args...) - } - return nil -} - -// DeleteSvc constructs all possible rules that would have been created by -// EnsurePortMapRuleForSvc from the provided args and ensures that each one that -// exists is deleted. -func (i *iptablesRunner) DeleteSvc(svc, tun string, targetIPs []netip.Addr, pms []PortMap) error { - for _, tip := range targetIPs { - for _, pm := range pms { - if err := i.DeletePortMapRuleForSvc(svc, tun, tip, pm); err != nil { - return fmt.Errorf("error deleting rule: %w", err) - } - } - } - return nil -} - -func argsForPortMapRule(svc, excludeI string, targetIP netip.Addr, pm PortMap) []string { - c := commentForSvc(svc, pm) - return []string{ - "!", "-i", excludeI, - "-p", pm.Protocol, - "--dport", fmt.Sprintf("%d", pm.MatchPort), - "-m", "comment", "--comment", c, - "-j", "DNAT", - "--to-destination", fmt.Sprintf("%v:%v", targetIP, pm.TargetPort), - } -} - -// commentForSvc generates a comment to be added to an iptables DNAT rule for a -// service. This is for iptables debugging/readability purposes only. -func commentForSvc(svc string, pm PortMap) string { - return fmt.Sprintf("%s:%s:%d -> %s:%d", svc, pm.Protocol, pm.MatchPort, pm.Protocol, pm.TargetPort) -} diff --git a/vendor/tailscale.com/util/linuxfw/iptables_runner.go b/vendor/tailscale.com/util/linuxfw/iptables_runner.go deleted file mode 100644 index 9a6fc02..0000000 --- a/vendor/tailscale.com/util/linuxfw/iptables_runner.go +++ /dev/null @@ -1,774 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "bytes" - "errors" - "fmt" - "log" - "net/netip" - "os" - "os/exec" - "slices" - "strconv" - "strings" - - "github.com/coreos/go-iptables/iptables" - "tailscale.com/net/tsaddr" - "tailscale.com/types/logger" - "tailscale.com/util/multierr" - "tailscale.com/version/distro" -) - -// isNotExistError needs to be overridden in tests that rely on distinguishing -// this error, because we don't have a good way how to create a new -// iptables.Error of that type. -var isNotExistError = func(err error) bool { - var e *iptables.Error - return errors.As(err, &e) && e.IsNotExist() -} - -type iptablesInterface interface { - // Adding this interface for testing purposes so we can mock out - // the iptables library, in reality this is a wrapper to *iptables.IPTables. - Insert(table, chain string, pos int, args ...string) error - Append(table, chain string, args ...string) error - Exists(table, chain string, args ...string) (bool, error) - Delete(table, chain string, args ...string) error - List(table, chain string) ([]string, error) - ClearChain(table, chain string) error - NewChain(table, chain string) error - DeleteChain(table, chain string) error -} - -type iptablesRunner struct { - ipt4 iptablesInterface - ipt6 iptablesInterface - - v6Available bool - v6NATAvailable bool - v6FilterAvailable bool -} - -func checkIP6TablesExists() error { - // Some distros ship ip6tables separately from iptables. - if _, err := exec.LookPath("ip6tables"); err != nil { - return fmt.Errorf("path not found: %w", err) - } - return nil -} - -// newIPTablesRunner constructs a NetfilterRunner that programs iptables rules. -// If the underlying iptables library fails to initialize, that error is -// returned. The runner probes for IPv6 support once at initialization time and -// if not found, no IPv6 rules will be modified for the lifetime of the runner. -func newIPTablesRunner(logf logger.Logf) (*iptablesRunner, error) { - ipt4, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) - if err != nil { - return nil, err - } - - supportsV6, supportsV6NAT, supportsV6Filter := false, false, false - v6err := CheckIPv6(logf) - ip6terr := checkIP6TablesExists() - var ipt6 *iptables.IPTables - switch { - case v6err != nil: - logf("disabling tunneled IPv6 due to system IPv6 config: %v", v6err) - case ip6terr != nil: - logf("disabling tunneled IPv6 due to missing ip6tables: %v", ip6terr) - default: - supportsV6 = true - ipt6, err = iptables.NewWithProtocol(iptables.ProtocolIPv6) - if err != nil { - return nil, err - } - supportsV6Filter = checkSupportsV6Filter(ipt6, logf) - supportsV6NAT = checkSupportsV6NAT(ipt6, logf) - logf("netfilter running in iptables mode v6 = %v, v6filter = %v, v6nat = %v", supportsV6, supportsV6Filter, supportsV6NAT) - } - return &iptablesRunner{ - ipt4: ipt4, - ipt6: ipt6, - v6Available: supportsV6, - v6NATAvailable: supportsV6NAT, - v6FilterAvailable: supportsV6Filter}, nil -} - -// checkSupportsV6Filter returns whether the system has a "filter" table in the -// IPv6 tables. Some container environments such as GitHub codespaces have -// limited local IPv6 support, and containers containing ip6tables, but do not -// have kernel support for IPv6 filtering. -// We will not set ip6tables rules in these instances. -func checkSupportsV6Filter(ipt *iptables.IPTables, logf logger.Logf) bool { - if ipt == nil { - return false - } - _, filterListErr := ipt.ListChains("filter") - if filterListErr == nil { - return true - } - logf("ip6tables filtering is not supported on this host: %v", filterListErr) - return false -} - -// checkSupportsV6NAT returns whether the system has a "nat" table in the -// IPv6 netfilter stack. -// -// The nat table was added after the initial release of ipv6 -// netfilter, so some older distros ship a kernel that can't NAT IPv6 -// traffic. -// ipt must be initialized for IPv6. -func checkSupportsV6NAT(ipt *iptables.IPTables, logf logger.Logf) bool { - if ipt == nil || ipt.Proto() != iptables.ProtocolIPv6 { - return false - } - _, natListErr := ipt.ListChains("nat") - if natListErr == nil { - return true - } - - // TODO (irbekrm): the following two checks were added before the check - // above that verifies that nat chains can be listed. It is a - // container-friendly check (see - // https://github.com/tailscale/tailscale/issues/11344), but also should - // be good enough on its own in other environments. If we never observe - // it falsely succeed, let's remove the other two checks. - - bs, err := os.ReadFile("/proc/net/ip6_tables_names") - if err != nil { - return false - } - if bytes.Contains(bs, []byte("nat\n")) { - logf("[unexpected] listing nat chains failed, but /proc/net/ip6_tables_name reports a nat table existing") - return true - } - if exec.Command("modprobe", "ip6table_nat").Run() == nil { - logf("[unexpected] listing nat chains failed, but modprobe ip6table_nat succeeded") - return true - } - return false -} - -// HasIPV6 reports true if the system supports IPv6. -func (i *iptablesRunner) HasIPV6() bool { - return i.v6Available -} - -// HasIPV6Filter reports true if the system supports ip6tables filter table. -func (i *iptablesRunner) HasIPV6Filter() bool { - return i.v6FilterAvailable -} - -// HasIPV6NAT reports true if the system supports IPv6 NAT. -func (i *iptablesRunner) HasIPV6NAT() bool { - return i.v6NATAvailable -} - -// getIPTByAddr returns the iptablesInterface with correct IP family -// that we will be using for the given address. -func (i *iptablesRunner) getIPTByAddr(addr netip.Addr) iptablesInterface { - nf := i.ipt4 - if addr.Is6() { - nf = i.ipt6 - } - return nf -} - -// AddLoopbackRule adds an iptables rule to permit loopback traffic to -// a local Tailscale IP. -func (i *iptablesRunner) AddLoopbackRule(addr netip.Addr) error { - if err := i.getIPTByAddr(addr).Insert("filter", "ts-input", 1, "-i", "lo", "-s", addr.String(), "-j", "ACCEPT"); err != nil { - return fmt.Errorf("adding loopback allow rule for %q: %w", addr, err) - } - - return nil -} - -// tsChain returns the name of the tailscale sub-chain corresponding -// to the given "parent" chain (e.g. INPUT, FORWARD, ...). -func tsChain(chain string) string { - return "ts-" + strings.ToLower(chain) -} - -// DelLoopbackRule removes the iptables rule permitting loopback -// traffic to a Tailscale IP. -func (i *iptablesRunner) DelLoopbackRule(addr netip.Addr) error { - if err := i.getIPTByAddr(addr).Delete("filter", "ts-input", "-i", "lo", "-s", addr.String(), "-j", "ACCEPT"); err != nil { - return fmt.Errorf("deleting loopback allow rule for %q: %w", addr, err) - } - - return nil -} - -// getTables gets the available iptablesInterface in iptables runner. -func (i *iptablesRunner) getTables() []iptablesInterface { - if i.HasIPV6Filter() { - return []iptablesInterface{i.ipt4, i.ipt6} - } - return []iptablesInterface{i.ipt4} -} - -// getNATTables gets the available iptablesInterface in iptables runner. -// If the system does not support IPv6 NAT, only the IPv4 iptablesInterface -// is returned. -func (i *iptablesRunner) getNATTables() []iptablesInterface { - if i.HasIPV6NAT() { - return i.getTables() - } - return []iptablesInterface{i.ipt4} -} - -// AddHooks inserts calls to tailscale's netfilter chains in -// the relevant main netfilter chains. The tailscale chains must -// already exist. If they do not, an error is returned. -func (i *iptablesRunner) AddHooks() error { - // divert inserts a jump to the tailscale chain in the given table/chain. - // If the jump already exists, it is a no-op. - divert := func(ipt iptablesInterface, table, chain string) error { - tsChain := tsChain(chain) - - args := []string{"-j", tsChain} - exists, err := ipt.Exists(table, chain, args...) - if err != nil { - return fmt.Errorf("checking for %v in %s/%s: %w", args, table, chain, err) - } - if exists { - return nil - } - if err := ipt.Insert(table, chain, 1, args...); err != nil { - return fmt.Errorf("adding %v in %s/%s: %w", args, table, chain, err) - } - return nil - } - - for _, ipt := range i.getTables() { - if err := divert(ipt, "filter", "INPUT"); err != nil { - return err - } - if err := divert(ipt, "filter", "FORWARD"); err != nil { - return err - } - } - - for _, ipt := range i.getNATTables() { - if err := divert(ipt, "nat", "POSTROUTING"); err != nil { - return err - } - } - return nil -} - -// AddChains creates custom Tailscale chains in netfilter via iptables -// if the ts-chain doesn't already exist. -func (i *iptablesRunner) AddChains() error { - // create creates a chain in the given table if it doesn't already exist. - // If the chain already exists, it is a no-op. - create := func(ipt iptablesInterface, table, chain string) error { - err := ipt.ClearChain(table, chain) - if isNotExistError(err) { - // nonexistent chain. let's create it! - return ipt.NewChain(table, chain) - } - if err != nil { - return fmt.Errorf("setting up %s/%s: %w", table, chain, err) - } - return nil - } - - for _, ipt := range i.getTables() { - if err := create(ipt, "filter", "ts-input"); err != nil { - return err - } - if err := create(ipt, "filter", "ts-forward"); err != nil { - return err - } - } - - for _, ipt := range i.getNATTables() { - if err := create(ipt, "nat", "ts-postrouting"); err != nil { - return err - } - } - - return nil -} - -// AddBase adds some basic processing rules to be supplemented by -// later calls to other helpers. -func (i *iptablesRunner) AddBase(tunname string) error { - if err := i.addBase4(tunname); err != nil { - return err - } - if i.HasIPV6Filter() { - if err := i.addBase6(tunname); err != nil { - return err - } - } - return nil -} - -// addBase4 adds some basic IPv4 processing rules to be -// supplemented by later calls to other helpers. -func (i *iptablesRunner) addBase4(tunname string) error { - // Only allow CGNAT range traffic to come from tailscale0. There - // is an exception carved out for ranges used by ChromeOS, for - // which we fall out of the Tailscale chain. - // - // Note, this will definitely break nodes that end up using the - // CGNAT range for other purposes :(. - args := []string{"!", "-i", tunname, "-s", tsaddr.ChromeOSVMRange().String(), "-j", "RETURN"} - if err := i.ipt4.Append("filter", "ts-input", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-input: %w", args, err) - } - args = []string{"!", "-i", tunname, "-s", tsaddr.CGNATRange().String(), "-j", "DROP"} - if err := i.ipt4.Append("filter", "ts-input", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-input: %w", args, err) - } - - // Explicitly allow all other inbound traffic to the tun interface - args = []string{"-i", tunname, "-j", "ACCEPT"} - if err := i.ipt4.Append("filter", "ts-input", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-input: %w", args, err) - } - - // Forward all traffic from the Tailscale interface, and drop - // traffic to the tailscale interface by default. We use packet - // marks here so both filter/FORWARD and nat/POSTROUTING can match - // on these packets of interest. - // - // In particular, we only want to apply SNAT rules in - // nat/POSTROUTING to packets that originated from the Tailscale - // interface, but we can't match on the inbound interface in - // POSTROUTING. So instead, we match on the inbound interface in - // filter/FORWARD, and set a packet mark that nat/POSTROUTING can - // use to effectively run that same test again. - args = []string{"-i", tunname, "-j", "MARK", "--set-mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask} - if err := i.ipt4.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-forward: %w", args, err) - } - args = []string{"-m", "mark", "--mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask, "-j", "ACCEPT"} - if err := i.ipt4.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-forward: %w", args, err) - } - args = []string{"-o", tunname, "-s", tsaddr.CGNATRange().String(), "-j", "DROP"} - if err := i.ipt4.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-forward: %w", args, err) - } - args = []string{"-o", tunname, "-j", "ACCEPT"} - if err := i.ipt4.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v4/filter/ts-forward: %w", args, err) - } - - return nil -} - -func (i *iptablesRunner) AddDNATRule(origDst, dst netip.Addr) error { - table := i.getIPTByAddr(dst) - return table.Insert("nat", "PREROUTING", 1, "--destination", origDst.String(), "-j", "DNAT", "--to-destination", dst.String()) -} - -// EnsureSNATForDst sets up firewall to ensure that all traffic aimed for dst, has its source ip set to src: -// - creates a SNAT rule if not already present -// - ensures that any no longer valid SNAT rules for the same dst are removed -func (i *iptablesRunner) EnsureSNATForDst(src, dst netip.Addr) error { - table := i.getIPTByAddr(dst) - rules, err := table.List("nat", "POSTROUTING") - if err != nil { - return fmt.Errorf("error listing rules: %v", err) - } - // iptables accept either address or a CIDR value for the --destination flag, but converts an address to /32 - // CIDR. Explicitly passing a /32 CIDR made it possible to test this rule. - dstPrefix, err := dst.Prefix(32) - if err != nil { - return fmt.Errorf("error calculating prefix of dst %v: %v", dst, err) - } - - // wantsArgsPrefix is the prefix of the SNAT rule for the provided destination. - // We should only have one POSTROUTING rule with this prefix. - wantsArgsPrefix := fmt.Sprintf("-d %s -j SNAT --to-source", dstPrefix.String()) - // wantsArgs is the actual SNAT rule that we want. - wantsArgs := fmt.Sprintf("%s %s", wantsArgsPrefix, src.String()) - for _, r := range rules { - args := argsFromPostRoutingRule(r) - if strings.HasPrefix(args, wantsArgsPrefix) { - if strings.HasPrefix(args, wantsArgs) { - return nil - } - // SNAT rule matching the destination, but for a different source - delete. - if err := table.Delete("nat", "POSTROUTING", strings.Split(args, " ")...); err != nil { - // If we failed to delete don't crash the node- the proxy should still be functioning. - log.Printf("[unexpected] error deleting rule %s: %v, please report it.", r, err) - } - break - } - } - return table.Insert("nat", "POSTROUTING", 1, "-d", dstPrefix.String(), "-j", "SNAT", "--to-source", src.String()) -} - -func (i *iptablesRunner) DNATNonTailscaleTraffic(tun string, dst netip.Addr) error { - table := i.getIPTByAddr(dst) - return table.Insert("nat", "PREROUTING", 1, "!", "-i", tun, "-j", "DNAT", "--to-destination", dst.String()) -} - -// DNATWithLoadBalancer adds iptables rules to forward all traffic received for -// originDst to the backend dsts. Traffic will be load balanced using round robin. -func (i *iptablesRunner) DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error { - table := i.getIPTByAddr(dsts[0]) - if err := table.ClearChain("nat", "PREROUTING"); err != nil && !isNotExistError(err) { - // If clearing the PREROUTING chain fails, fail the whole operation. This - // rule is currently only used in Kubernetes containers where a - // failed container gets restarted which should hopefully fix things. - return fmt.Errorf("error clearing nat PREROUTING chain: %w", err) - } - // If dsts contain more than one address, for n := n in range(len(dsts)..2) route packets for every nth connection to dsts[n]. - for i := len(dsts); i >= 2; i-- { - dst := dsts[i-1] // the order in which rules for addrs are installed does not matter - if err := table.Append("nat", "PREROUTING", "--destination", origDst.String(), "-m", "statistic", "--mode", "nth", "--every", fmt.Sprint(i), "--packet", "0", "-j", "DNAT", "--to-destination", dst.String()); err != nil { - return fmt.Errorf("error adding DNAT rule for %s: %w", dst.String(), err) - } - } - // If the packet falls through to this rule, we route to the first destination in the list unconditionally. - return table.Append("nat", "PREROUTING", "--destination", origDst.String(), "-j", "DNAT", "--to-destination", dsts[0].String()) -} - -func (i *iptablesRunner) ClampMSSToPMTU(tun string, addr netip.Addr) error { - table := i.getIPTByAddr(addr) - return table.Append("mangle", "FORWARD", "-o", tun, "-p", "tcp", "--tcp-flags", "SYN,RST", "SYN", "-j", "TCPMSS", "--clamp-mss-to-pmtu") -} - -// addBase6 adds some basic IPv6 processing rules to be -// supplemented by later calls to other helpers. -func (i *iptablesRunner) addBase6(tunname string) error { - // TODO: only allow traffic from Tailscale's ULA range to come - // from tailscale0. - - // Explicitly allow all other inbound traffic to the tun interface - args := []string{"-i", tunname, "-j", "ACCEPT"} - if err := i.ipt6.Append("filter", "ts-input", args...); err != nil { - return fmt.Errorf("adding %v in v6/filter/ts-input: %w", args, err) - } - - args = []string{"-i", tunname, "-j", "MARK", "--set-mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask} - if err := i.ipt6.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v6/filter/ts-forward: %w", args, err) - } - args = []string{"-m", "mark", "--mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask, "-j", "ACCEPT"} - if err := i.ipt6.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v6/filter/ts-forward: %w", args, err) - } - // TODO: drop forwarded traffic to tailscale0 from tailscale's ULA - // (see corresponding IPv4 CGNAT rule). - args = []string{"-o", tunname, "-j", "ACCEPT"} - if err := i.ipt6.Append("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("adding %v in v6/filter/ts-forward: %w", args, err) - } - - return nil -} - -// DelChains removes the custom Tailscale chains from netfilter via iptables. -func (i *iptablesRunner) DelChains() error { - for _, ipt := range i.getTables() { - if err := delChain(ipt, "filter", "ts-input"); err != nil { - return err - } - if err := delChain(ipt, "filter", "ts-forward"); err != nil { - return err - } - } - - for _, ipt := range i.getNATTables() { - if err := delChain(ipt, "nat", "ts-postrouting"); err != nil { - return err - } - } - - return nil -} - -// DelBase empties but does not remove custom Tailscale chains from -// netfilter via iptables. -func (i *iptablesRunner) DelBase() error { - del := func(ipt iptablesInterface, table, chain string) error { - if err := ipt.ClearChain(table, chain); err != nil { - if isNotExistError(err) { - // nonexistent chain. That's fine, since it's - // the desired state anyway. - return nil - } - return fmt.Errorf("flushing %s/%s: %w", table, chain, err) - } - return nil - } - - for _, ipt := range i.getTables() { - if err := del(ipt, "filter", "ts-input"); err != nil { - return err - } - if err := del(ipt, "filter", "ts-forward"); err != nil { - return err - } - } - for _, ipt := range i.getNATTables() { - if err := del(ipt, "nat", "ts-postrouting"); err != nil { - return err - } - } - - return nil -} - -// DelHooks deletes the calls to tailscale's netfilter chains -// in the relevant main netfilter chains. -func (i *iptablesRunner) DelHooks(logf logger.Logf) error { - for _, ipt := range i.getTables() { - if err := delTSHook(ipt, "filter", "INPUT", logf); err != nil { - return err - } - if err := delTSHook(ipt, "filter", "FORWARD", logf); err != nil { - return err - } - } - for _, ipt := range i.getNATTables() { - if err := delTSHook(ipt, "nat", "POSTROUTING", logf); err != nil { - return err - } - } - - return nil -} - -// AddSNATRule adds a netfilter rule to SNAT traffic destined for -// local subnets. -func (i *iptablesRunner) AddSNATRule() error { - args := []string{"-m", "mark", "--mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask, "-j", "MASQUERADE"} - for _, ipt := range i.getNATTables() { - if err := ipt.Append("nat", "ts-postrouting", args...); err != nil { - return fmt.Errorf("adding %v in nat/ts-postrouting: %w", args, err) - } - } - return nil -} - -// DelSNATRule removes the netfilter rule to SNAT traffic destined for -// local subnets. An error is returned if the rule does not exist. -func (i *iptablesRunner) DelSNATRule() error { - args := []string{"-m", "mark", "--mark", TailscaleSubnetRouteMark + "/" + TailscaleFwmarkMask, "-j", "MASQUERADE"} - for _, ipt := range i.getNATTables() { - if err := ipt.Delete("nat", "ts-postrouting", args...); err != nil { - return fmt.Errorf("deleting %v in nat/ts-postrouting: %w", args, err) - } - } - return nil -} - -func statefulRuleArgs(tunname string) []string { - return []string{"-o", tunname, "-m", "conntrack", "!", "--ctstate", "ESTABLISHED,RELATED", "-j", "DROP"} -} - -// AddStatefulRule adds a netfilter rule for stateful packet filtering using -// conntrack. -func (i *iptablesRunner) AddStatefulRule(tunname string) error { - // Drop packets that are destined for the tailscale interface if - // they're a new connection, per conntrack, to prevent hosts on the - // same subnet from being able to use this device as a way to forward - // packets on to the Tailscale network. - // - // The conntrack states are: - // NEW A packet which creates a new connection. - // ESTABLISHED A packet which belongs to an existing connection - // (i.e., a reply packet, or outgoing packet on a - // connection which has seen replies). - // RELATED A packet which is related to, but not part of, an - // existing connection, such as an ICMP error. - // INVALID A packet which could not be identified for some - // reason: this includes running out of memory and ICMP - // errors which don't correspond to any known - // connection. Generally these packets should be - // dropped. - // - // We drop NEW packets to prevent connections from coming "into" - // Tailscale from other hosts on the same network segment; we drop - // INVALID packets as well. - args := statefulRuleArgs(tunname) - for _, ipt := range i.getTables() { - // First, find the final "accept" rule. - rules, err := ipt.List("filter", "ts-forward") - if err != nil { - return fmt.Errorf("listing rules in filter/ts-forward: %w", err) - } - want := fmt.Sprintf("-A %s -o %s -j ACCEPT", "ts-forward", tunname) - - pos := slices.Index(rules, want) - if pos < 0 { - return fmt.Errorf("couldn't find final ACCEPT rule in filter/ts-forward") - } - - if err := ipt.Insert("filter", "ts-forward", pos, args...); err != nil { - return fmt.Errorf("adding %v in filter/ts-forward: %w", args, err) - } - } - return nil -} - -// DelStatefulRule removes the netfilter rule for stateful packet filtering -// using conntrack. -func (i *iptablesRunner) DelStatefulRule(tunname string) error { - args := statefulRuleArgs(tunname) - for _, ipt := range i.getTables() { - if err := ipt.Delete("filter", "ts-forward", args...); err != nil { - return fmt.Errorf("deleting %v in filter/ts-forward: %w", args, err) - } - } - return nil -} - -// buildMagicsockPortRule generates the string slice containing the arguments -// to describe a rule accepting traffic on a particular port to iptables. It is -// separated out here to avoid repetition in AddMagicsockPortRule and -// RemoveMagicsockPortRule, since it is important that the same rule is passed -// to Append() and Delete(). -func buildMagicsockPortRule(port uint16) []string { - return []string{"-p", "udp", "--dport", strconv.FormatUint(uint64(port), 10), "-j", "ACCEPT"} -} - -// AddMagicsockPortRule adds a rule to iptables to allow incoming traffic on -// the specified UDP port, so magicsock can accept incoming connections. -// network must be either "udp4" or "udp6" - this determines whether the rule -// is added for IPv4 or IPv6. -func (i *iptablesRunner) AddMagicsockPortRule(port uint16, network string) error { - var ipt iptablesInterface - switch network { - case "udp4": - ipt = i.ipt4 - case "udp6": - ipt = i.ipt6 - default: - return fmt.Errorf("unsupported network %s", network) - } - - args := buildMagicsockPortRule(port) - - if err := ipt.Append("filter", "ts-input", args...); err != nil { - return fmt.Errorf("adding %v in filter/ts-input: %w", args, err) - } - - return nil -} - -// DelMagicsockPortRule removes a rule added by AddMagicsockPortRule to accept -// incoming traffic on a particular UDP port. -// network must be either "udp4" or "udp6" - this determines whether the rule -// is removed for IPv4 or IPv6. -func (i *iptablesRunner) DelMagicsockPortRule(port uint16, network string) error { - var ipt iptablesInterface - switch network { - case "udp4": - ipt = i.ipt4 - case "udp6": - ipt = i.ipt6 - default: - return fmt.Errorf("unsupported network %s", network) - } - - args := buildMagicsockPortRule(port) - - if err := ipt.Delete("filter", "ts-input", args...); err != nil { - return fmt.Errorf("removing %v in filter/ts-input: %w", args, err) - } - - return nil -} - -// IPTablesCleanUp removes all Tailscale added iptables rules. -// Any errors that occur are logged to the provided logf. -func IPTablesCleanUp(logf logger.Logf) { - if distro.Get() == distro.Gokrazy { - // Gokrazy uses nftables and doesn't have the "iptables" command. - // Avoid log spam on cleanup. (#12277) - return - } - err := clearRules(iptables.ProtocolIPv4, logf) - if err != nil { - logf("linuxfw: clear iptables: %v", err) - } - - err = clearRules(iptables.ProtocolIPv6, logf) - if err != nil { - logf("linuxfw: clear ip6tables: %v", err) - } -} - -// delTSHook deletes hook in a chain that jumps to a ts-chain. If the hook does not -// exist, it's a no-op since the desired state is already achieved but we log the -// error because error code from the iptables module resists unwrapping. -func delTSHook(ipt iptablesInterface, table, chain string, logf logger.Logf) error { - tsChain := tsChain(chain) - args := []string{"-j", tsChain} - if err := ipt.Delete(table, chain, args...); err != nil && !isNotExistError(err) { - return fmt.Errorf("deleting %v in %s/%s: %v", args, table, chain, err) - } - return nil -} - -// delChain flushes and deletes a chain. If the chain does not exist, it's a no-op -// since the desired state is already achieved. otherwise, it returns an error. -func delChain(ipt iptablesInterface, table, chain string) error { - if err := ipt.ClearChain(table, chain); err != nil { - if isNotExistError(err) { - // nonexistent chain. nothing to do. - return nil - } - return fmt.Errorf("flushing %s/%s: %w", table, chain, err) - } - if err := ipt.DeleteChain(table, chain); err != nil { - return fmt.Errorf("deleting %s/%s: %w", table, chain, err) - } - return nil -} - -// clearRules clears all the iptables rules created by Tailscale -// for the given protocol. If error occurs, it's logged but not returned. -func clearRules(proto iptables.Protocol, logf logger.Logf) error { - ipt, err := iptables.NewWithProtocol(proto) - if err != nil { - return err - } - - var errs []error - - if err := delTSHook(ipt, "filter", "INPUT", logf); err != nil { - errs = append(errs, err) - } - if err := delTSHook(ipt, "filter", "FORWARD", logf); err != nil { - errs = append(errs, err) - } - if err := delTSHook(ipt, "nat", "POSTROUTING", logf); err != nil { - errs = append(errs, err) - } - - if err := delChain(ipt, "filter", "ts-input"); err != nil { - errs = append(errs, err) - } - if err := delChain(ipt, "filter", "ts-forward"); err != nil { - errs = append(errs, err) - } - - if err := delChain(ipt, "nat", "ts-postrouting"); err != nil { - errs = append(errs, err) - } - - return multierr.New(errs...) -} - -// argsFromPostRoutingRule accepts a rule as returned by iptables.List and, if it is a rule from POSTROUTING chain, -// returns the args part, else returns the original rule. -func argsFromPostRoutingRule(r string) string { - args, _ := strings.CutPrefix(r, "-A POSTROUTING ") - return args -} diff --git a/vendor/tailscale.com/util/linuxfw/linuxfw.go b/vendor/tailscale.com/util/linuxfw/linuxfw.go deleted file mode 100644 index be520e7..0000000 --- a/vendor/tailscale.com/util/linuxfw/linuxfw.go +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -// Package linuxfw returns the kind of firewall being used by the kernel. -package linuxfw - -import ( - "errors" - "fmt" - "os" - "strconv" - "strings" - - "github.com/tailscale/netlink" - "tailscale.com/types/logger" -) - -// MatchDecision is the decision made by the firewall for a packet matched by a rule. -// It is used to decide whether to accept or masquerade a packet in addMatchSubnetRouteMarkRule. -type MatchDecision int - -const ( - Accept MatchDecision = iota - Masq -) - -type FWModeNotSupportedError struct { - Mode FirewallMode - Err error -} - -func (e FWModeNotSupportedError) Error() string { - return fmt.Sprintf("firewall mode %q not supported: %v", e.Mode, e.Err) -} - -func (e FWModeNotSupportedError) Is(target error) bool { - _, ok := target.(FWModeNotSupportedError) - return ok -} - -func (e FWModeNotSupportedError) Unwrap() error { - return e.Err -} - -type FirewallMode string - -const ( - FirewallModeIPTables FirewallMode = "iptables" - FirewallModeNfTables FirewallMode = "nftables" -) - -// The following bits are added to packet marks for Tailscale use. -// -// We tried to pick bits sufficiently out of the way that it's -// unlikely to collide with existing uses. We have 4 bytes of mark -// bits to play with. We leave the lower byte alone on the assumption -// that sysadmins would use those. Kubernetes uses a few bits in the -// second byte, so we steer clear of that too. -// -// Empirically, most of the documentation on packet marks on the -// internet gives the impression that the marks are 16 bits -// wide. Based on this, we theorize that the upper two bytes are -// relatively unused in the wild, and so we consume bits 16:23 (the -// third byte). -// -// The constants are in the iptables/iproute2 string format for -// matching and setting the bits, so they can be directly embedded in -// commands. -const ( - // The mask for reading/writing the 'firewall mask' bits on a packet. - // See the comment on the const block on why we only use the third byte. - // - // We claim bits 16:23 entirely. For now we only use the lower four - // bits, leaving the higher 4 bits for future use. - TailscaleFwmarkMask = "0xff0000" - TailscaleFwmarkMaskNum = 0xff0000 - - // Packet is from Tailscale and to a subnet route destination, so - // is allowed to be routed through this machine. - TailscaleSubnetRouteMark = "0x40000" - TailscaleSubnetRouteMarkNum = 0x40000 - - // Packet was originated by tailscaled itself, and must not be - // routed over the Tailscale network. - TailscaleBypassMark = "0x80000" - TailscaleBypassMarkNum = 0x80000 -) - -// getTailscaleFwmarkMaskNeg returns the negation of TailscaleFwmarkMask in bytes. -func getTailscaleFwmarkMaskNeg() []byte { - return []byte{0xff, 0x00, 0xff, 0xff} -} - -// getTailscaleFwmarkMask returns the TailscaleFwmarkMask in bytes. -func getTailscaleFwmarkMask() []byte { - return []byte{0x00, 0xff, 0x00, 0x00} -} - -// getTailscaleSubnetRouteMark returns the TailscaleSubnetRouteMark in bytes. -func getTailscaleSubnetRouteMark() []byte { - return []byte{0x00, 0x04, 0x00, 0x00} -} - -// checkIPv6ForTest can be set in tests. -var checkIPv6ForTest func(logger.Logf) error - -// checkIPv6 checks whether the system appears to have a working IPv6 -// network stack. It returns an error explaining what looks wrong or -// missing. It does not check that IPv6 is currently functional or -// that there's a global address, just that the system would support -// IPv6 if it were on an IPv6 network. -func CheckIPv6(logf logger.Logf) error { - if f := checkIPv6ForTest; f != nil { - return f(logf) - } - - _, err := os.Stat("/proc/sys/net/ipv6") - if os.IsNotExist(err) { - return err - } - bs, err := os.ReadFile("/proc/sys/net/ipv6/conf/all/disable_ipv6") - if err != nil { - // Be conservative if we can't find the IPv6 configuration knob. - return err - } - disabled, err := strconv.ParseBool(strings.TrimSpace(string(bs))) - if err != nil { - return errors.New("disable_ipv6 has invalid bool") - } - if disabled { - return errors.New("disable_ipv6 is set") - } - - // Older kernels don't support IPv6 policy routing. Some kernels - // support policy routing but don't have this knob, so absence of - // the knob is not fatal. - bs, err = os.ReadFile("/proc/sys/net/ipv6/conf/all/disable_policy") - if err == nil { - disabled, err = strconv.ParseBool(strings.TrimSpace(string(bs))) - if err != nil { - return errors.New("disable_policy has invalid bool") - } - if disabled { - return errors.New("disable_policy is set") - } - } - - if err := CheckIPRuleSupportsV6(logf); err != nil { - return fmt.Errorf("kernel doesn't support IPv6 policy routing: %w", err) - } - - return nil -} - -func CheckIPRuleSupportsV6(logf logger.Logf) error { - // First try just a read-only operation to ideally avoid - // having to modify any state. - if rules, err := netlink.RuleList(netlink.FAMILY_V6); err != nil { - return fmt.Errorf("querying IPv6 policy routing rules: %w", err) - } else { - if len(rules) > 0 { - logf("[v1] kernel supports IPv6 policy routing (found %d rules)", len(rules)) - return nil - } - } - - // Try to actually create & delete one as a test. - rule := netlink.NewRule() - rule.Priority = 1234 - rule.Mark = TailscaleBypassMarkNum - rule.Table = 52 - rule.Family = netlink.FAMILY_V6 - // First delete the rule unconditionally, and don't check for - // errors. This is just cleaning up anything that might be already - // there. - netlink.RuleDel(rule) - // And clean up on exit. - defer netlink.RuleDel(rule) - return netlink.RuleAdd(rule) -} diff --git a/vendor/tailscale.com/util/linuxfw/linuxfw_unsupported.go b/vendor/tailscale.com/util/linuxfw/linuxfw_unsupported.go deleted file mode 100644 index 7bfb4fd..0000000 --- a/vendor/tailscale.com/util/linuxfw/linuxfw_unsupported.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// NOTE: linux_{arm64, amd64} are the only two currently supported archs due to missing -// support in upstream dependencies. - -// TODO(#8502): add support for more architectures -//go:build linux && !(arm64 || amd64) - -package linuxfw - -import ( - "errors" - - "tailscale.com/types/logger" -) - -// ErrUnsupported is the error returned from all functions on non-Linux -// platforms. -var ErrUnsupported = errors.New("linuxfw:unsupported") - -// DebugNetfilter is not supported on non-Linux platforms. -func DebugNetfilter(logf logger.Logf) error { - return ErrUnsupported -} - -// DetectNetfilter is not supported on non-Linux platforms. -func detectNetfilter() (int, error) { - return 0, ErrUnsupported -} - -// DebugIptables is not supported on non-Linux platforms. -func debugIptables(logf logger.Logf) error { - return ErrUnsupported -} - -// DetectIptables is not supported on non-Linux platforms. -func detectIptables() (int, error) { - return 0, ErrUnsupported -} diff --git a/vendor/tailscale.com/util/linuxfw/nftables.go b/vendor/tailscale.com/util/linuxfw/nftables.go deleted file mode 100644 index e8b267b..0000000 --- a/vendor/tailscale.com/util/linuxfw/nftables.go +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// TODO(#8502): add support for more architectures -//go:build linux && (arm64 || amd64) - -package linuxfw - -import ( - "cmp" - "encoding/binary" - "fmt" - "sort" - "strings" - - "github.com/google/nftables" - "github.com/google/nftables/expr" - "github.com/google/nftables/xt" - "golang.org/x/sys/unix" - "tailscale.com/types/logger" -) - -// DebugNetfilter prints debug information about netfilter rules to the -// provided log function. -func DebugNetfilter(logf logger.Logf) error { - conn, err := nftables.New() - if err != nil { - return err - } - - chains, err := conn.ListChains() - if err != nil { - return fmt.Errorf("cannot list chains: %w", err) - } - - if len(chains) == 0 { - logf("netfilter: no chains") - return nil - } - - for _, chain := range chains { - logf("netfilter: table=%s chain=%s", chain.Table.Name, chain.Name) - - rules, err := conn.GetRules(chain.Table, chain) - if err != nil { - continue - } - sort.Slice(rules, func(i, j int) bool { - return rules[i].Position < rules[j].Position - }) - - for i, rule := range rules { - logf("netfilter: rule[%d]: pos=%d flags=%d", i, rule.Position, rule.Flags) - for _, ex := range rule.Exprs { - switch v := ex.(type) { - case *expr.Meta: - key := cmp.Or(metaKeyNames[v.Key], "UNKNOWN") - logf("netfilter: Meta: key=%s source_register=%v register=%d", key, v.SourceRegister, v.Register) - - case *expr.Cmp: - op := cmp.Or(cmpOpNames[v.Op], "UNKNOWN") - logf("netfilter: Cmp: op=%s register=%d data=%s", op, v.Register, formatMaybePrintable(v.Data)) - - case *expr.Counter: - // don't print - - case *expr.Verdict: - kind := cmp.Or(verdictNames[v.Kind], "UNKNOWN") - logf("netfilter: Verdict: kind=%s data=%s", kind, v.Chain) - - case *expr.Target: - logf("netfilter: Target: name=%s info=%s", v.Name, printTargetInfo(v.Name, v.Info)) - - case *expr.Match: - logf("netfilter: Match: name=%s info=%+v", v.Name, printMatchInfo(v.Name, v.Info)) - - case *expr.Payload: - logf("netfilter: Payload: op=%s src=%d dst=%d base=%s offset=%d len=%d", - payloadOperationTypeNames[v.OperationType], - v.SourceRegister, v.DestRegister, - payloadBaseNames[v.Base], - v.Offset, v.Len) - // TODO(andrew): csum - - case *expr.Bitwise: - var xor string - for _, b := range v.Xor { - if b != 0 { - xor = fmt.Sprintf(" xor=%v", v.Xor) - break - } - } - logf("netfilter: Bitwise: src=%d dst=%d len=%d mask=%v%s", - v.SourceRegister, v.DestRegister, v.Len, v.Mask, xor) - - default: - logf("netfilter: unknown %T: %+v", v, v) - } - } - } - } - - return nil -} - -// detectNetfilter returns the number of nftables rules present in the system. -func detectNetfilter() (int, error) { - // Frist try creating a dummy postrouting chain. Emperically, we have - // noticed that on some devices there is partial nftables support and the - // kernel rejects some chains that are valid on other devices. This is a - // workaround to detect that case. - // - // This specifically allows us to run in on GKE nodes using COS images which - // have partial nftables support (as of 2023-10-18). When we try to create a - // dummy postrouting chain, we get an error like: - // add chain: conn.Receive: netlink receive: no such file or directory - nft, err := newNfTablesRunner(logger.Discard) - if err != nil { - return 0, FWModeNotSupportedError{ - Mode: FirewallModeNfTables, - Err: fmt.Errorf("cannot create nftables runner: %w", err), - } - } - if err := nft.createDummyPostroutingChains(); err != nil { - return 0, FWModeNotSupportedError{ - Mode: FirewallModeNfTables, - Err: err, - } - } - - conn, err := nftables.New() - if err != nil { - return 0, FWModeNotSupportedError{ - Mode: FirewallModeNfTables, - Err: err, - } - } - - chains, err := conn.ListChains() - if err != nil { - return 0, FWModeNotSupportedError{ - Mode: FirewallModeNfTables, - Err: fmt.Errorf("cannot list chains: %w", err), - } - } - - var validRules int - for _, chain := range chains { - rules, err := conn.GetRules(chain.Table, chain) - if err != nil { - continue - } - validRules += len(rules) - } - - return validRules, nil -} - -func printMatchInfo(name string, info xt.InfoAny) string { - var sb strings.Builder - sb.WriteString(`{`) - - var handled bool = true - switch v := info.(type) { - // TODO(andrew): we should support these common types - //case *xt.ConntrackMtinfo3: - //case *xt.ConntrackMtinfo2: - case *xt.Tcp: - fmt.Fprintf(&sb, "Src:%s Dst:%s", formatPortRange(v.SrcPorts), formatPortRange(v.DstPorts)) - if v.Option != 0 { - fmt.Fprintf(&sb, " Option:%d", v.Option) - } - if v.FlagsMask != 0 { - fmt.Fprintf(&sb, " FlagsMask:%d", v.FlagsMask) - } - if v.FlagsCmp != 0 { - fmt.Fprintf(&sb, " FlagsCmp:%d", v.FlagsCmp) - } - if v.InvFlags != 0 { - fmt.Fprintf(&sb, " InvFlags:%d", v.InvFlags) - } - - case *xt.Udp: - fmt.Fprintf(&sb, "Src:%s Dst:%s", formatPortRange(v.SrcPorts), formatPortRange(v.DstPorts)) - if v.InvFlags != 0 { - fmt.Fprintf(&sb, " InvFlags:%d", v.InvFlags) - } - - case *xt.AddrType: - var sprefix, dprefix string - if v.InvertSource { - sprefix = "!" - } - if v.InvertDest { - dprefix = "!" - } - // TODO(andrew): translate source/dest - fmt.Fprintf(&sb, "Source:%s%d Dest:%s%d", sprefix, v.Source, dprefix, v.Dest) - - case *xt.AddrTypeV1: - // TODO(andrew): translate source/dest - fmt.Fprintf(&sb, "Source:%d Dest:%d", v.Source, v.Dest) - - var flags []string - for flag, name := range addrTypeFlagNames { - if v.Flags&flag != 0 { - flags = append(flags, name) - } - } - if len(flags) > 0 { - sort.Strings(flags) - fmt.Fprintf(&sb, "Flags:%s", strings.Join(flags, ",")) - } - - default: - handled = false - } - if handled { - sb.WriteString(`}`) - return sb.String() - } - - unknown, ok := info.(*xt.Unknown) - if !ok { - return fmt.Sprintf("(%T)%+v", info, info) - } - data := []byte(*unknown) - - // Things where upstream has no type - handled = true - switch name { - case "pkttype": - if len(data) != 8 { - handled = false - break - } - - pkttype := int(binary.NativeEndian.Uint32(data[0:4])) - invert := int(binary.NativeEndian.Uint32(data[4:8])) - var invertPrefix string - if invert != 0 { - invertPrefix = "!" - } - - pkttypeName := packetTypeNames[pkttype] - if pkttypeName != "" { - fmt.Fprintf(&sb, "PktType:%s%s", invertPrefix, pkttypeName) - } else { - fmt.Fprintf(&sb, "PktType:%s%d", invertPrefix, pkttype) - } - - default: - handled = true - } - - if !handled { - return fmt.Sprintf("(%T)%+v", info, info) - } - - sb.WriteString(`}`) - return sb.String() -} - -func printTargetInfo(name string, info xt.InfoAny) string { - var sb strings.Builder - sb.WriteString(`{`) - - unknown, ok := info.(*xt.Unknown) - if !ok { - return fmt.Sprintf("(%T)%+v", info, info) - } - data := []byte(*unknown) - - // Things where upstream has no type - switch name { - case "LOG": - if len(data) != 32 { - fmt.Fprintf(&sb, `Error:"bad size; want 32, got %d"`, len(data)) - break - } - - level := data[0] - logflags := data[1] - prefix := unix.ByteSliceToString(data[2:]) - fmt.Fprintf(&sb, "Level:%d LogFlags:%d Prefix:%q", level, logflags, prefix) - default: - return fmt.Sprintf("(%T)%+v", info, info) - } - - sb.WriteString(`}`) - return sb.String() -} diff --git a/vendor/tailscale.com/util/linuxfw/nftables_for_svcs.go b/vendor/tailscale.com/util/linuxfw/nftables_for_svcs.go deleted file mode 100644 index 130585b..0000000 --- a/vendor/tailscale.com/util/linuxfw/nftables_for_svcs.go +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "errors" - "fmt" - "net/netip" - "reflect" - "strings" - - "github.com/google/nftables" - "github.com/google/nftables/binaryutil" - "github.com/google/nftables/expr" - "golang.org/x/sys/unix" -) - -// This file contains functionality that is currently (09/2024) used to set up -// routing for the Tailscale Kubernetes operator egress proxies. A tailnet -// service (identified by tailnet IP or FQDN) that gets exposed to cluster -// workloads gets a separate prerouting chain created for it for each IP family -// of the chain's target addresses. Each service's prerouting chain contains one -// or more portmapping rules. A portmapping rule DNATs traffic received on a -// particular port to a port of the tailnet service. Creating a chain per -// service makes it easier to delete a service when no longer needed and helps -// with readability. - -// EnsurePortMapRuleForSvc: -// - ensures that nat table exists -// - ensures that there is a prerouting chain for the given service and IP family of the target address in the nat table -// - ensures that there is a portmapping rule mathcing the given portmap (only creates the rule if it does not already exist) -func (n *nftablesRunner) EnsurePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error { - t, ch, err := n.ensureChainForSvc(svc, targetIP) - if err != nil { - return fmt.Errorf("error ensuring chain for %s: %w", svc, err) - } - meta := svcPortMapRuleMeta(svc, targetIP, pm) - rule, err := n.findRuleByMetadata(t, ch, meta) - if err != nil { - return fmt.Errorf("error looking up rule: %w", err) - } - if rule != nil { - return nil - } - p, err := protoFromString(pm.Protocol) - if err != nil { - return fmt.Errorf("error converting protocol %s: %w", pm.Protocol, err) - } - - rule = portMapRule(t, ch, tun, targetIP, pm.MatchPort, pm.TargetPort, p, meta) - n.conn.InsertRule(rule) - return n.conn.Flush() -} - -// DeletePortMapRuleForSvc deletes a portmapping rule in the given service/IP family chain. -// It finds the matching rule using metadata attached to the rule. -// The caller is expected to call DeleteSvc if the whole service (the chain) -// needs to be deleted, so we don't deal with the case where this is the only -// rule in the chain here. -func (n *nftablesRunner) DeletePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error { - table, err := n.getNFTByAddr(targetIP) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %s: %w", targetIP, err) - } - t, err := getTableIfExists(n.conn, table.Proto, "nat") - if err != nil { - return fmt.Errorf("error checking if nat table exists: %w", err) - } - if t == nil { - return nil - } - ch, err := getChainFromTable(n.conn, t, svc) - if err != nil && !errors.Is(err, errorChainNotFound{t.Name, svc}) { - return fmt.Errorf("error checking if chain %s exists: %w", svc, err) - } - if errors.Is(err, errorChainNotFound{t.Name, svc}) { - return nil // service chain does not exist, so neither does the portmapping rule - } - meta := svcPortMapRuleMeta(svc, targetIP, pm) - rule, err := n.findRuleByMetadata(t, ch, meta) - if err != nil { - return fmt.Errorf("error checking if rule exists: %w", err) - } - if rule == nil { - return nil - } - if err := n.conn.DelRule(rule); err != nil { - return fmt.Errorf("error deleting rule: %w", err) - } - return n.conn.Flush() -} - -// DeleteSvc deletes the chains for the given service if any exist. -func (n *nftablesRunner) DeleteSvc(svc, tun string, targetIPs []netip.Addr, pm []PortMap) error { - for _, tip := range targetIPs { - table, err := n.getNFTByAddr(tip) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %s: %w", tip, err) - } - t, err := getTableIfExists(n.conn, table.Proto, "nat") - if err != nil { - return fmt.Errorf("error checking if nat table exists: %w", err) - } - if t == nil { - return nil - } - ch, err := getChainFromTable(n.conn, t, svc) - if err != nil && !errors.Is(err, errorChainNotFound{t.Name, svc}) { - return fmt.Errorf("error checking if chain %s exists: %w", svc, err) - } - if errors.Is(err, errorChainNotFound{t.Name, svc}) { - return nil - } - n.conn.DelChain(ch) - } - return n.conn.Flush() -} - -func portMapRule(t *nftables.Table, ch *nftables.Chain, tun string, targetIP netip.Addr, matchPort, targetPort uint16, proto uint8, meta []byte) *nftables.Rule { - var fam uint32 - if targetIP.Is4() { - fam = unix.NFPROTO_IPV4 - } else { - fam = unix.NFPROTO_IPV6 - } - rule := &nftables.Rule{ - Table: t, - Chain: ch, - UserData: meta, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpNeq, - Register: 1, - Data: []byte(tun), - }, - &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte{proto}, - }, - &expr.Payload{ - DestRegister: 1, - Base: expr.PayloadBaseTransportHeader, - Offset: 2, - Len: 2, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: binaryutil.BigEndian.PutUint16(matchPort), - }, - &expr.Immediate{ - Register: 1, - Data: targetIP.AsSlice(), - }, - &expr.Immediate{ - Register: 2, - Data: binaryutil.BigEndian.PutUint16(targetPort), - }, - &expr.NAT{ - Type: expr.NATTypeDestNAT, - Family: fam, - RegAddrMin: 1, - RegAddrMax: 1, - RegProtoMin: 2, - RegProtoMax: 2, - }, - }, - } - return rule -} - -// svcPortMapRuleMeta generates metadata for a rule. -// This metadata can then be used to find the rule. -// https://github.com/google/nftables/issues/48 -func svcPortMapRuleMeta(svcName string, targetIP netip.Addr, pm PortMap) []byte { - return []byte(fmt.Sprintf("svc:%s,targetIP:%s:matchPort:%v,targetPort:%v,proto:%v", svcName, targetIP.String(), pm.MatchPort, pm.TargetPort, pm.Protocol)) -} - -func (n *nftablesRunner) findRuleByMetadata(t *nftables.Table, ch *nftables.Chain, meta []byte) (*nftables.Rule, error) { - if n.conn == nil || t == nil || ch == nil || len(meta) == 0 { - return nil, nil - } - rules, err := n.conn.GetRules(t, ch) - if err != nil { - return nil, fmt.Errorf("error listing rules: %w", err) - } - for _, rule := range rules { - if reflect.DeepEqual(rule.UserData, meta) { - return rule, nil - } - } - return nil, nil -} - -func (n *nftablesRunner) ensureChainForSvc(svc string, targetIP netip.Addr) (*nftables.Table, *nftables.Chain, error) { - polAccept := nftables.ChainPolicyAccept - table, err := n.getNFTByAddr(targetIP) - if err != nil { - return nil, nil, fmt.Errorf("error setting up nftables for IP family of %v: %w", targetIP, err) - } - nat, err := createTableIfNotExist(n.conn, table.Proto, "nat") - if err != nil { - return nil, nil, fmt.Errorf("error ensuring nat table: %w", err) - } - svcCh, err := getOrCreateChain(n.conn, chainInfo{ - table: nat, - name: svc, - chainType: nftables.ChainTypeNAT, - chainHook: nftables.ChainHookPrerouting, - chainPriority: nftables.ChainPriorityNATDest, - chainPolicy: &polAccept, - }) - if err != nil { - return nil, nil, fmt.Errorf("error ensuring prerouting chain: %w", err) - } - return nat, svcCh, nil -} - -// // PortMap is the port mapping for a service rule. -type PortMap struct { - // MatchPort is the local port to which the rule should apply. - MatchPort uint16 - // TargetPort is the port to which the traffic should be forwarded. - TargetPort uint16 - // Protocol is the protocol to match packets on. Only TCP and UDP are - // supported. - Protocol string -} - -func protoFromString(s string) (uint8, error) { - switch strings.ToLower(s) { - case "tcp": - return unix.IPPROTO_TCP, nil - case "udp": - return unix.IPPROTO_UDP, nil - default: - return 0, fmt.Errorf("unrecognized protocol: %q", s) - } -} diff --git a/vendor/tailscale.com/util/linuxfw/nftables_runner.go b/vendor/tailscale.com/util/linuxfw/nftables_runner.go deleted file mode 100644 index 0f41152..0000000 --- a/vendor/tailscale.com/util/linuxfw/nftables_runner.go +++ /dev/null @@ -1,2055 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package linuxfw - -import ( - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "net" - "net/netip" - "reflect" - "strings" - - "github.com/google/nftables" - "github.com/google/nftables/expr" - "golang.org/x/sys/unix" - "tailscale.com/net/tsaddr" - "tailscale.com/types/logger" - "tailscale.com/types/ptr" -) - -const ( - chainNameForward = "ts-forward" - chainNameInput = "ts-input" - chainNamePostrouting = "ts-postrouting" -) - -// chainTypeRegular is an nftables chain that does not apply to a hook. -const chainTypeRegular = "" - -type chainInfo struct { - table *nftables.Table - name string - chainType nftables.ChainType - chainHook *nftables.ChainHook - chainPriority *nftables.ChainPriority - chainPolicy *nftables.ChainPolicy -} - -// nftable contains nat and filter tables for the given IP family (Proto). -type nftable struct { - Proto nftables.TableFamily // IPv4 or IPv6 - Filter *nftables.Table - Nat *nftables.Table -} - -// nftablesRunner implements a netfilterRunner using the netlink based nftables -// library. As nftables allows for arbitrary tables and chains, there is a need -// to follow conventions in order to integrate well with a surrounding -// ecosystem. The rules installed by nftablesRunner have the following -// properties: -// - Install rules that intend to take precedence over rules installed by -// other software. Tailscale provides packet filtering for tailnet traffic -// inside the daemon based on the tailnet ACL rules. -// - As nftables "accept" is not final, rules from high priority tables (low -// numbers) will fall through to lower priority tables (high numbers). In -// order to effectively be 'final', we install "jump" rules into conventional -// tables and chains that will reach an accept verdict inside those tables. -// - The table and chain conventions followed here are those used by -// `iptables-nft` and `ufw`, so that those tools co-exist and do not -// negatively affect Tailscale function. -// - Be mindful that 1) all chains attached to a given hook (i.e the forward hook) -// will be processed in priority order till either a rule in one of the chains issues a drop verdict -// or there are no more chains for that hook -// 2) processing of individual rules within a chain will stop once one of them issues a final verdict (accept, drop). -// https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains -type nftablesRunner struct { - conn *nftables.Conn - nft4 *nftable // IPv4 tables, never nil - nft6 *nftable // IPv6 tables or nil if the system does not support IPv6 - - v6Available bool // whether the host supports IPv6 -} - -func (n *nftablesRunner) ensurePreroutingChain(dst netip.Addr) (*nftables.Table, *nftables.Chain, error) { - polAccept := nftables.ChainPolicyAccept - table, err := n.getNFTByAddr(dst) - if err != nil { - return nil, nil, fmt.Errorf("error setting up nftables for IP family of %v: %w", dst, err) - } - nat, err := createTableIfNotExist(n.conn, table.Proto, "nat") - if err != nil { - return nil, nil, fmt.Errorf("error ensuring nat table: %w", err) - } - - // ensure prerouting chain exists - preroutingCh, err := getOrCreateChain(n.conn, chainInfo{ - table: nat, - name: "PREROUTING", - chainType: nftables.ChainTypeNAT, - chainHook: nftables.ChainHookPrerouting, - chainPriority: nftables.ChainPriorityNATDest, - chainPolicy: &polAccept, - }) - if err != nil { - return nil, nil, fmt.Errorf("error ensuring prerouting chain: %w", err) - } - return nat, preroutingCh, nil -} - -func (n *nftablesRunner) AddDNATRule(origDst netip.Addr, dst netip.Addr) error { - nat, preroutingCh, err := n.ensurePreroutingChain(dst) - if err != nil { - return err - } - var daddrOffset, fam, dadderLen uint32 - if origDst.Is4() { - daddrOffset = 16 - dadderLen = 4 - fam = unix.NFPROTO_IPV4 - } else { - daddrOffset = 24 - dadderLen = 16 - fam = unix.NFPROTO_IPV6 - } - dnatRule := &nftables.Rule{ - Table: nat, - Chain: preroutingCh, - Exprs: []expr.Any{ - &expr.Payload{ - DestRegister: 1, - Base: expr.PayloadBaseNetworkHeader, - Offset: daddrOffset, - Len: dadderLen, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: origDst.AsSlice(), - }, - &expr.Immediate{ - Register: 1, - Data: dst.AsSlice(), - }, - &expr.NAT{ - Type: expr.NATTypeDestNAT, - Family: fam, - RegAddrMin: 1, - }, - }, - } - n.conn.InsertRule(dnatRule) - return n.conn.Flush() -} - -// DNATWithLoadBalancer currently just forwards all traffic destined for origDst -// to the first IP address from the backend targets. -// TODO (irbekrm): instead of doing this load balance traffic evenly to all -// backend destinations. -// https://github.com/tailscale/tailscale/commit/d37f2f508509c6c35ad724fd75a27685b90b575b#diff-a3bcbcd1ca198799f4f768dc56fea913e1945a6b3ec9dbec89325a84a19a85e7R148-R232 -func (n *nftablesRunner) DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error { - return n.AddDNATRule(origDst, dsts[0]) -} - -func (n *nftablesRunner) DNATNonTailscaleTraffic(tunname string, dst netip.Addr) error { - nat, preroutingCh, err := n.ensurePreroutingChain(dst) - if err != nil { - return err - } - var famConst uint32 - if dst.Is4() { - famConst = unix.NFPROTO_IPV4 - } else { - famConst = unix.NFPROTO_IPV6 - } - - dnatRule := &nftables.Rule{ - Table: nat, - Chain: preroutingCh, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpNeq, - Register: 1, - Data: []byte(tunname), - }, - &expr.Immediate{ - Register: 1, - Data: dst.AsSlice(), - }, - &expr.NAT{ - Type: expr.NATTypeDestNAT, - Family: famConst, - RegAddrMin: 1, - }, - }, - } - n.conn.InsertRule(dnatRule) - return n.conn.Flush() -} - -func (n *nftablesRunner) EnsureSNATForDst(src, dst netip.Addr) error { - polAccept := nftables.ChainPolicyAccept - table, err := n.getNFTByAddr(dst) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %v: %w", dst, err) - } - nat, err := createTableIfNotExist(n.conn, table.Proto, "nat") - if err != nil { - return fmt.Errorf("error ensuring nat table exists: %w", err) - } - - // ensure postrouting chain exists - postRoutingCh, err := getOrCreateChain(n.conn, chainInfo{ - table: nat, - name: "POSTROUTING", - chainType: nftables.ChainTypeNAT, - chainHook: nftables.ChainHookPostrouting, - chainPriority: nftables.ChainPriorityNATSource, - chainPolicy: &polAccept, - }) - if err != nil { - return fmt.Errorf("error ensuring postrouting chain: %w", err) - } - - rules, err := n.conn.GetRules(nat, postRoutingCh) - if err != nil { - return fmt.Errorf("error listing rules: %w", err) - } - snatRulePrefixMatch := fmt.Sprintf("dst:%s,src:", dst.String()) - snatRuleFullMatch := fmt.Sprintf("%s%s", snatRulePrefixMatch, src.String()) - for _, rule := range rules { - current := string(rule.UserData) - if strings.HasPrefix(string(rule.UserData), snatRulePrefixMatch) { - if strings.EqualFold(current, snatRuleFullMatch) { - return nil // already exists, do nothing - } - if err := n.conn.DelRule(rule); err != nil { - return fmt.Errorf("error deleting SNAT rule: %w", err) - } - } - } - rule := snatRule(nat, postRoutingCh, src, dst, []byte(snatRuleFullMatch)) - n.conn.AddRule(rule) - return n.conn.Flush() -} - -// ClampMSSToPMTU ensures that all packets with TCP flags (SYN, ACK, RST) set -// being forwarded via the given interface (tun) have MSS set to - 40 (IP and TCP headers). This can be useful if this tailscale -// instance is expected to run as a forwarding proxy, forwarding packets from an -// endpoint with higher MTU in an environment where path MTU discovery is -// expected to not work (such as the proxies created by the Tailscale Kubernetes -// operator). ClamMSSToPMTU creates a new base-chain ts-clamp in the filter -// table with accept policy and priority -150. In practice, this means that for -// SYN packets the clamp rule in this chain will likely run first and accept the -// packet. This is fine because 1) nftables run ALL chains with the same hook -// type unless a rule in one of them drops the packet and 2) this chain does not -// have functionality to drop the packet- so in practice a matching clamp rule -// will always be followed by the custom tailscale filtering rules in the other -// chains attached to the filter hook (FORWARD, ts-forward). -// We do not want to place the clamping rule into FORWARD/ts-forward chains -// because wgengine populates those chains with rules that contain accept -// verdicts that would cause no further procesing within that chain. This -// functionality is currently invoked from outside wgengine (containerboot), so -// we don't want to race with wgengine for rule ordering within chains. -func (n *nftablesRunner) ClampMSSToPMTU(tun string, addr netip.Addr) error { - polAccept := nftables.ChainPolicyAccept - table, err := n.getNFTByAddr(addr) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %v: %w", addr, err) - } - filterTable, err := createTableIfNotExist(n.conn, table.Proto, "filter") - if err != nil { - return fmt.Errorf("error ensuring filter table: %w", err) - } - - // ensure ts-clamp chain exists - fwChain, err := getOrCreateChain(n.conn, chainInfo{ - table: filterTable, - name: "ts-clamp", - chainType: nftables.ChainTypeFilter, - chainHook: nftables.ChainHookForward, - chainPriority: nftables.ChainPriorityMangle, - chainPolicy: &polAccept, - }) - if err != nil { - return fmt.Errorf("error ensuring forward chain: %w", err) - } - - clampRule := &nftables.Rule{ - Table: filterTable, - Chain: fwChain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tun), - }, - &expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte{unix.IPPROTO_TCP}, - }, - &expr.Payload{ - DestRegister: 1, - Base: expr.PayloadBaseTransportHeader, - Offset: 13, - Len: 1, - }, - &expr.Bitwise{ - DestRegister: 1, - SourceRegister: 1, - Len: 1, - Mask: []byte{0x02}, - Xor: []byte{0x00}, - }, - &expr.Cmp{ - Op: expr.CmpOpNeq, // match any packet with a TCP flag set (SYN, ACK, RST) - Register: 1, - Data: []byte{0x00}, - }, - &expr.Rt{ - Register: 1, - Key: expr.RtTCPMSS, - }, - &expr.Byteorder{ - DestRegister: 1, - SourceRegister: 1, - Op: expr.ByteorderHton, - Len: 2, - Size: 2, - }, - &expr.Exthdr{ - SourceRegister: 1, - Type: 2, - Offset: 2, - Len: 2, - Op: expr.ExthdrOpTcpopt, - }, - }, - } - n.conn.AddRule(clampRule) - return n.conn.Flush() -} - -// deleteTableIfExists deletes a nftables table via connection c if it exists -// within the given family. -func deleteTableIfExists(c *nftables.Conn, family nftables.TableFamily, name string) error { - t, err := getTableIfExists(c, family, name) - if err != nil { - return fmt.Errorf("get table: %w", err) - } - if t == nil { - // Table does not exist, so nothing to delete. - return nil - } - c.DelTable(t) - if err := c.Flush(); err != nil { - if t, err = getTableIfExists(c, family, name); t == nil && err == nil { - // Check if the table still exists. If it does not, then the error - // is due to the table not existing, so we can ignore it. Maybe a - // concurrent process deleted the table. - return nil - } - return fmt.Errorf("del table: %w", err) - } - return nil -} - -// getTableIfExists returns the table with the given name from the given family -// if it exists. If none match, it returns (nil, nil). -func getTableIfExists(c *nftables.Conn, family nftables.TableFamily, name string) (*nftables.Table, error) { - tables, err := c.ListTables() - if err != nil { - return nil, fmt.Errorf("get tables: %w", err) - } - for _, table := range tables { - if table.Name == name && table.Family == family { - return table, nil - } - } - return nil, nil -} - -// createTableIfNotExist creates a nftables table via connection c if it does -// not exist within the given family. -func createTableIfNotExist(c *nftables.Conn, family nftables.TableFamily, name string) (*nftables.Table, error) { - if t, err := getTableIfExists(c, family, name); err != nil { - return nil, fmt.Errorf("get table: %w", err) - } else if t != nil { - return t, nil - } - t := c.AddTable(&nftables.Table{ - Family: family, - Name: name, - }) - if err := c.Flush(); err != nil { - return nil, fmt.Errorf("add table: %w", err) - } - return t, nil -} - -type errorChainNotFound struct { - chainName string - tableName string -} - -func (e errorChainNotFound) Error() string { - return fmt.Sprintf("chain %s not found in table %s", e.chainName, e.tableName) -} - -// getChainFromTable returns the chain with the given name from the given table. -// Note that a chain name is unique within a table. -func getChainFromTable(c *nftables.Conn, table *nftables.Table, name string) (*nftables.Chain, error) { - chains, err := c.ListChainsOfTableFamily(table.Family) - if err != nil { - return nil, fmt.Errorf("list chains: %w", err) - } - - for _, chain := range chains { - // Table family is already checked so table name is unique - if chain.Table.Name == table.Name && chain.Name == name { - return chain, nil - } - } - - return nil, errorChainNotFound{table.Name, name} -} - -// isTSChain reports whether `name` begins with "ts-" (and is thus a -// Tailscale-managed chain). -func isTSChain(name string) bool { - return strings.HasPrefix(name, "ts-") -} - -// createChainIfNotExist creates a chain with the given name in the given table -// if it does not exist. -func createChainIfNotExist(c *nftables.Conn, cinfo chainInfo) error { - _, err := getOrCreateChain(c, cinfo) - return err -} - -func getOrCreateChain(c *nftables.Conn, cinfo chainInfo) (*nftables.Chain, error) { - chain, err := getChainFromTable(c, cinfo.table, cinfo.name) - if err != nil && !errors.Is(err, errorChainNotFound{cinfo.table.Name, cinfo.name}) { - return nil, fmt.Errorf("get chain: %w", err) - } else if err == nil { - // The chain already exists. If it is a TS chain, check the - // type/hook/priority, but for "conventional chains" assume they're what - // we expect (in case iptables-nft/ufw make minor behavior changes in - // the future). - if isTSChain(chain.Name) && (chain.Type != cinfo.chainType || *chain.Hooknum != *cinfo.chainHook || *chain.Priority != *cinfo.chainPriority) { - return nil, fmt.Errorf("chain %s already exists with different type/hook/priority", cinfo.name) - } - return chain, nil - } - - chain = c.AddChain(&nftables.Chain{ - Name: cinfo.name, - Table: cinfo.table, - Type: cinfo.chainType, - Hooknum: cinfo.chainHook, - Priority: cinfo.chainPriority, - Policy: cinfo.chainPolicy, - }) - - if err := c.Flush(); err != nil { - return nil, fmt.Errorf("add chain: %w", err) - } - - return chain, nil -} - -// NetfilterRunner abstracts helpers to run netfilter commands. It is -// implemented by linuxfw.IPTablesRunner and linuxfw.NfTablesRunner. -type NetfilterRunner interface { - // AddLoopbackRule adds a rule to permit loopback traffic to addr. This rule - // is added only if it does not already exist. - AddLoopbackRule(addr netip.Addr) error - - // DelLoopbackRule removes the rule added by AddLoopbackRule. - DelLoopbackRule(addr netip.Addr) error - - // AddHooks adds rules to conventional chains like "FORWARD", "INPUT" and - // "POSTROUTING" to jump from those chains to tailscale chains. - AddHooks() error - - // DelHooks deletes rules added by AddHooks. - DelHooks(logf logger.Logf) error - - // AddChains creates custom Tailscale chains. - AddChains() error - - // DelChains removes chains added by AddChains. - DelChains() error - - // AddBase adds rules reused by different other rules. - AddBase(tunname string) error - - // DelBase removes rules added by AddBase. - DelBase() error - - // AddSNATRule adds the netfilter rule to SNAT incoming traffic over - // the Tailscale interface destined for local subnets. An error is - // returned if the rule already exists. - AddSNATRule() error - - // DelSNATRule removes the rule added by AddSNATRule. - DelSNATRule() error - - // AddStatefulRule adds a netfilter rule for stateful packet filtering - // using conntrack. - AddStatefulRule(tunname string) error - - // DelStatefulRule removes a netfilter rule for stateful packet filtering - // using conntrack. - DelStatefulRule(tunname string) error - - // HasIPV6 reports true if the system supports IPv6. - HasIPV6() bool - - // HasIPV6NAT reports true if the system supports IPv6 NAT. - HasIPV6NAT() bool - - // HasIPV6Filter reports true if the system supports IPv6 filter tables - // This is only meaningful for iptables implementation, where hosts have - // partial ipables support (i.e missing filter table). For nftables - // implementation, this will default to the value of HasIPv6(). - HasIPV6Filter() bool - - // AddDNATRule adds a rule to the nat/PREROUTING chain to DNAT traffic - // destined for the given original destination to the given new destination. - // This is used to forward all traffic destined for the Tailscale interface - // to the provided destination, as used in the Kubernetes ingress proxies. - AddDNATRule(origDst, dst netip.Addr) error - - // DNATWithLoadBalancer adds a rule to the nat/PREROUTING chain to DNAT - // traffic destined for the given original destination to the given new - // destination(s) using round robin to load balance if more than one - // destination is provided. This is used to forward all traffic destined - // for the Tailscale interface to the provided destination(s), as used - // in the Kubernetes ingress proxies. - DNATWithLoadBalancer(origDst netip.Addr, dsts []netip.Addr) error - - // EnsureSNATForDst sets up firewall to mask the source for traffic destined for dst to src: - // - creates a SNAT rule if it doesn't already exist - // - deletes any pre-existing rules matching the destination - // This is used to forward traffic destined for the local machine over - // the Tailscale interface, as used in the Kubernetes egress proxies. - EnsureSNATForDst(src, dst netip.Addr) error - - // DNATNonTailscaleTraffic adds a rule to the nat/PREROUTING chain to DNAT - // all traffic inbound from any interface except exemptInterface to dst. - // This is used to forward traffic destined for the local machine over - // the Tailscale interface, as used in the Kubernetes egress proxies. - DNATNonTailscaleTraffic(exemptInterface string, dst netip.Addr) error - - EnsurePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error - - DeletePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error - - DeleteSvc(svc, tun string, targetIPs []netip.Addr, pm []PortMap) error - - // ClampMSSToPMTU adds a rule to the mangle/FORWARD chain to clamp MSS for - // traffic destined for the provided tun interface. - ClampMSSToPMTU(tun string, addr netip.Addr) error - - // AddMagicsockPortRule adds a rule to the ts-input chain to accept - // incoming traffic on the specified port, to allow magicsock to - // communicate. - AddMagicsockPortRule(port uint16, network string) error - - // DelMagicsockPortRule removes the rule created by AddMagicsockPortRule, - // if it exists. - DelMagicsockPortRule(port uint16, network string) error -} - -// New creates a NetfilterRunner, auto-detecting whether to use -// nftables or iptables. -// As nftables is still experimental, iptables will be used unless -// either the TS_DEBUG_FIREWALL_MODE environment variable, or the prefHint -// parameter, is set to one of "nftables" or "auto". -func New(logf logger.Logf, prefHint string) (NetfilterRunner, error) { - mode := detectFirewallMode(logf, prefHint) - switch mode { - case FirewallModeIPTables: - // Note that we don't simply return an newIPTablesRunner here because it - // would return a `nil` iptablesRunner which is different from returning - // a nil NetfilterRunner. - ipr, err := newIPTablesRunner(logf) - if err != nil { - return nil, err - } - return ipr, nil - case FirewallModeNfTables: - // Note that we don't simply return an newNfTablesRunner here because it - // would return a `nil` nftablesRunner which is different from returning - // a nil NetfilterRunner. - nfr, err := newNfTablesRunner(logf) - if err != nil { - return nil, err - } - return nfr, nil - default: - return nil, fmt.Errorf("unknown firewall mode %v", mode) - } -} - -// newNfTablesRunner creates a new nftablesRunner without guaranteeing -// the existence of the tables and chains. -func newNfTablesRunner(logf logger.Logf) (*nftablesRunner, error) { - conn, err := nftables.New() - if err != nil { - return nil, fmt.Errorf("nftables connection: %w", err) - } - return newNfTablesRunnerWithConn(logf, conn), nil -} - -func newNfTablesRunnerWithConn(logf logger.Logf, conn *nftables.Conn) *nftablesRunner { - nft4 := &nftable{Proto: nftables.TableFamilyIPv4} - - v6err := CheckIPv6(logf) - if v6err != nil { - logf("disabling tunneled IPv6 due to system IPv6 config: %v", v6err) - } - supportsV6 := v6err == nil - var nft6 *nftable - - if supportsV6 { - nft6 = &nftable{Proto: nftables.TableFamilyIPv6} - } - logf("netfilter running in nftables mode, v6 = %v", supportsV6) - - // TODO(KevinLiang10): convert iptables rule to nftable rules if they exist in the iptables - - return &nftablesRunner{ - conn: conn, - nft4: nft4, - nft6: nft6, - v6Available: supportsV6, - } -} - -// newLoadSaddrExpr creates a new nftables expression that loads the source -// address of the packet into the given register. -func newLoadSaddrExpr(proto nftables.TableFamily, destReg uint32) (expr.Any, error) { - switch proto { - case nftables.TableFamilyIPv4: - return &expr.Payload{ - DestRegister: destReg, - Base: expr.PayloadBaseNetworkHeader, - Offset: 12, - Len: 4, - }, nil - case nftables.TableFamilyIPv6: - return &expr.Payload{ - DestRegister: destReg, - Base: expr.PayloadBaseNetworkHeader, - Offset: 8, - Len: 16, - }, nil - default: - return nil, fmt.Errorf("table family %v is neither IPv4 nor IPv6", proto) - } -} - -// newLoadDportExpr creates a new nftables express that loads the desination port -// of a TCP/UDP packet into the given register. -func newLoadDportExpr(destReg uint32) expr.Any { - return &expr.Payload{ - DestRegister: destReg, - Base: expr.PayloadBaseTransportHeader, - Offset: 2, - Len: 2, - } -} - -// HasIPV6 reports true if the system supports IPv6. -func (n *nftablesRunner) HasIPV6() bool { - return n.v6Available -} - -// HasIPV6NAT returns true if the system supports IPv6. -// Kernel support for nftables was added after support for IPv6 -// NAT, so no need for a separate IPv6 NAT support check like we do for iptables. -// https://tldp.org/HOWTO/Linux+IPv6-HOWTO/ch18s04.html -// https://wiki.nftables.org/wiki-nftables/index.php/Building_and_installing_nftables_from_sources -func (n *nftablesRunner) HasIPV6NAT() bool { - return n.v6Available -} - -// HasIPV6Filter returns true if system supports IPv6. There are no known edge -// cases where nftables running on a host that supports IPv6 would not support -// filter table. -func (n *nftablesRunner) HasIPV6Filter() bool { - return n.v6Available -} - -// findRule iterates through the rules to find the rule with matching expressions. -func findRule(conn *nftables.Conn, rule *nftables.Rule) (*nftables.Rule, error) { - rules, err := conn.GetRules(rule.Table, rule.Chain) - if err != nil { - return nil, fmt.Errorf("get nftables rules: %w", err) - } - if len(rules) == 0 { - return nil, nil - } - -ruleLoop: - for _, r := range rules { - if len(r.Exprs) != len(rule.Exprs) { - continue - } - - for i, e := range r.Exprs { - // Skip counter expressions, as they will not match. - if _, ok := e.(*expr.Counter); ok { - continue - } - if !reflect.DeepEqual(e, rule.Exprs[i]) { - continue ruleLoop - } - } - return r, nil - } - - return nil, nil -} - -func createLoopbackRule( - proto nftables.TableFamily, - table *nftables.Table, - chain *nftables.Chain, - addr netip.Addr, -) (*nftables.Rule, error) { - saddrExpr, err := newLoadSaddrExpr(proto, 1) - if err != nil { - return nil, fmt.Errorf("newLoadSaddrExpr: %w", err) - } - loopBackRule := &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{ - Key: expr.MetaKeyIIFNAME, - Register: 1, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte("lo"), - }, - saddrExpr, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: addr.AsSlice(), - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictAccept, - }, - }, - } - return loopBackRule, nil -} - -// insertLoopbackRule inserts the TS loop back rule into -// the given chain as the first rule if it does not exist. -func insertLoopbackRule( - conn *nftables.Conn, proto nftables.TableFamily, - table *nftables.Table, chain *nftables.Chain, addr netip.Addr) error { - - loopBackRule, err := createLoopbackRule(proto, table, chain, addr) - if err != nil { - return fmt.Errorf("create loopback rule: %w", err) - } - - // If TestDial is set, we are running in test mode and we should not - // find rule because header will mismatch. - if conn.TestDial == nil { - // Check if the rule already exists. - rule, err := findRule(conn, loopBackRule) - if err != nil { - return fmt.Errorf("find rule: %w", err) - } - if rule != nil { - // Rule already exists, no need to insert. - return nil - } - } - - // This inserts the rule to the top of the chain - _ = conn.InsertRule(loopBackRule) - - if err = conn.Flush(); err != nil { - return fmt.Errorf("insert rule: %w", err) - } - return nil -} - -// getNFTByAddr returns the nftables with correct IP family -// that we will be using for the given address. -func (n *nftablesRunner) getNFTByAddr(addr netip.Addr) (*nftable, error) { - if addr.Is6() && !n.v6Available { - return nil, fmt.Errorf("nftables for IPv6 are not available on this host") - } - if addr.Is6() { - return n.nft6, nil - } - return n.nft4, nil -} - -// AddLoopbackRule adds an nftables rule to permit loopback traffic to -// a local Tailscale IP. This rule is added only if it does not already exist. -func (n *nftablesRunner) AddLoopbackRule(addr netip.Addr) error { - nf, err := n.getNFTByAddr(addr) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %v: %w", addr, err) - } - - inputChain, err := getChainFromTable(n.conn, nf.Filter, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain: %w", err) - } - - if err := insertLoopbackRule(n.conn, nf.Proto, nf.Filter, inputChain, addr); err != nil { - return fmt.Errorf("add loopback rule: %w", err) - } - - return nil -} - -// DelLoopbackRule removes the nftables rule permitting loopback -// traffic to a Tailscale IP. -func (n *nftablesRunner) DelLoopbackRule(addr netip.Addr) error { - nf, err := n.getNFTByAddr(addr) - if err != nil { - return fmt.Errorf("error setting up nftables for IP family of %v: %w", addr, err) - } - - inputChain, err := getChainFromTable(n.conn, nf.Filter, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain: %w", err) - } - - loopBackRule, err := createLoopbackRule(nf.Proto, nf.Filter, inputChain, addr) - if err != nil { - return fmt.Errorf("create loopback rule: %w", err) - } - - existingLoopBackRule, err := findRule(n.conn, loopBackRule) - if err != nil { - return fmt.Errorf("find loop back rule: %w", err) - } - if existingLoopBackRule == nil { - // Rule does not exist, no need to delete. - return nil - } - - if err := n.conn.DelRule(existingLoopBackRule); err != nil { - return fmt.Errorf("delete rule: %w", err) - } - - return n.conn.Flush() -} - -// getTables returns tables for IP families that this host was determined to -// support (either IPv4 and IPv6 or just IPv4). -func (n *nftablesRunner) getTables() []*nftable { - if n.HasIPV6() { - return []*nftable{n.nft4, n.nft6} - } - return []*nftable{n.nft4} -} - -// AddChains creates custom Tailscale chains in netfilter via nftables -// if the ts-chain doesn't already exist. -func (n *nftablesRunner) AddChains() error { - polAccept := nftables.ChainPolicyAccept - for _, table := range n.getTables() { - // Create the filter table if it doesn't exist, this table name is the same - // as the name used by iptables-nft and ufw. We install rules into the - // same conventional table so that `accept` verdicts from our jump - // chains are conclusive. - filter, err := createTableIfNotExist(n.conn, table.Proto, "filter") - if err != nil { - return fmt.Errorf("create table: %w", err) - } - table.Filter = filter - // Adding the "conventional chains" that are used by iptables-nft and ufw. - if err = createChainIfNotExist(n.conn, chainInfo{filter, "FORWARD", nftables.ChainTypeFilter, nftables.ChainHookForward, nftables.ChainPriorityFilter, &polAccept}); err != nil { - return fmt.Errorf("create forward chain: %w", err) - } - if err = createChainIfNotExist(n.conn, chainInfo{filter, "INPUT", nftables.ChainTypeFilter, nftables.ChainHookInput, nftables.ChainPriorityFilter, &polAccept}); err != nil { - return fmt.Errorf("create input chain: %w", err) - } - // Adding the tailscale chains that contain our rules. - if err = createChainIfNotExist(n.conn, chainInfo{filter, chainNameForward, chainTypeRegular, nil, nil, nil}); err != nil { - return fmt.Errorf("create forward chain: %w", err) - } - if err = createChainIfNotExist(n.conn, chainInfo{filter, chainNameInput, chainTypeRegular, nil, nil, nil}); err != nil { - return fmt.Errorf("create input chain: %w", err) - } - - // Create the nat table if it doesn't exist, this table name is the same - // as the name used by iptables-nft and ufw. We install rules into the - // same conventional table so that `accept` verdicts from our jump - // chains are conclusive. - nat, err := createTableIfNotExist(n.conn, table.Proto, "nat") - if err != nil { - return fmt.Errorf("create table: %w", err) - } - table.Nat = nat - // Adding the "conventional chains" that are used by iptables-nft and ufw. - if err = createChainIfNotExist(n.conn, chainInfo{nat, "POSTROUTING", nftables.ChainTypeNAT, nftables.ChainHookPostrouting, nftables.ChainPriorityNATSource, &polAccept}); err != nil { - return fmt.Errorf("create postrouting chain: %w", err) - } - // Adding the tailscale chain that contains our rules. - if err = createChainIfNotExist(n.conn, chainInfo{nat, chainNamePostrouting, chainTypeRegular, nil, nil, nil}); err != nil { - return fmt.Errorf("create postrouting chain: %w", err) - } - } - - return n.conn.Flush() -} - -// These are dummy chains and tables we create to detect if nftables is -// available. We create them, then delete them. If we can create and delete -// them, then we can use nftables. If we can't, then we assume that we're -// running on a system that doesn't support nftables. See -// createDummyPostroutingChains. -const ( - tsDummyChainName = "ts-test-postrouting" - tsDummyTableName = "ts-test-nat" -) - -// createDummyPostroutingChains creates dummy postrouting chains in netfilter -// via netfilter via nftables, as a last resort measure to detect that nftables -// can be used. It cleans up the dummy chains after creation. -func (n *nftablesRunner) createDummyPostroutingChains() (retErr error) { - polAccept := ptr.To(nftables.ChainPolicyAccept) - for _, table := range n.getTables() { - nat, err := createTableIfNotExist(n.conn, table.Proto, tsDummyTableName) - if err != nil { - return fmt.Errorf("create nat table: %w", err) - } - defer func(fm nftables.TableFamily) { - if err := deleteTableIfExists(n.conn, fm, tsDummyTableName); err != nil && retErr == nil { - retErr = fmt.Errorf("delete %q table: %w", tsDummyTableName, err) - } - }(table.Proto) - - table.Nat = nat - if err = createChainIfNotExist(n.conn, chainInfo{nat, tsDummyChainName, nftables.ChainTypeNAT, nftables.ChainHookPostrouting, nftables.ChainPriorityNATSource, polAccept}); err != nil { - return fmt.Errorf("create %q chain: %w", tsDummyChainName, err) - } - if err := deleteChainIfExists(n.conn, nat, tsDummyChainName); err != nil { - return fmt.Errorf("delete %q chain: %w", tsDummyChainName, err) - } - } - return nil -} - -// deleteChainIfExists deletes a chain if it exists. -func deleteChainIfExists(c *nftables.Conn, table *nftables.Table, name string) error { - chain, err := getChainFromTable(c, table, name) - if err != nil && !errors.Is(err, errorChainNotFound{table.Name, name}) { - return fmt.Errorf("get chain: %w", err) - } else if err != nil { - // If the chain doesn't exist, we don't need to delete it. - return nil - } - - c.FlushChain(chain) - c.DelChain(chain) - - if err := c.Flush(); err != nil { - return fmt.Errorf("flush and delete chain: %w", err) - } - - return nil -} - -// DelChains removes the custom Tailscale chains from netfilter via nftables. -func (n *nftablesRunner) DelChains() error { - for _, table := range n.getTables() { - if err := deleteChainIfExists(n.conn, table.Filter, chainNameForward); err != nil { - return fmt.Errorf("delete chain: %w", err) - } - if err := deleteChainIfExists(n.conn, table.Filter, chainNameInput); err != nil { - return fmt.Errorf("delete chain: %w", err) - } - } - - if err := deleteChainIfExists(n.conn, n.nft4.Nat, chainNamePostrouting); err != nil { - return fmt.Errorf("delete chain: %w", err) - } - - if n.HasIPV6NAT() { - if err := deleteChainIfExists(n.conn, n.nft6.Nat, chainNamePostrouting); err != nil { - return fmt.Errorf("delete chain: %w", err) - } - } - - if err := n.conn.Flush(); err != nil { - return fmt.Errorf("flush: %w", err) - } - - return nil -} - -// createHookRule creates a rule to jump from a hooked chain to a regular chain. -func createHookRule(table *nftables.Table, fromChain *nftables.Chain, toChainName string) *nftables.Rule { - exprs := []expr.Any{ - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictJump, - Chain: toChainName, - }, - } - - rule := &nftables.Rule{ - Table: table, - Chain: fromChain, - Exprs: exprs, - } - - return rule -} - -// addHookRule adds a rule to jump from a hooked chain to a regular chain at top of the hooked chain. -func addHookRule(conn *nftables.Conn, table *nftables.Table, fromChain *nftables.Chain, toChainName string) error { - rule := createHookRule(table, fromChain, toChainName) - _ = conn.InsertRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add rule: %w", err) - } - - return nil -} - -// AddHooks is adding rules to conventional chains like "FORWARD", "INPUT" and "POSTROUTING" -// in tables and jump from those chains to tailscale chains. -func (n *nftablesRunner) AddHooks() error { - conn := n.conn - - for _, table := range n.getTables() { - inputChain, err := getChainFromTable(conn, table.Filter, "INPUT") - if err != nil { - return fmt.Errorf("get INPUT chain: %w", err) - } - err = addHookRule(conn, table.Filter, inputChain, chainNameInput) - if err != nil { - return fmt.Errorf("Addhook: %w", err) - } - forwardChain, err := getChainFromTable(conn, table.Filter, "FORWARD") - if err != nil { - return fmt.Errorf("get FORWARD chain: %w", err) - } - err = addHookRule(conn, table.Filter, forwardChain, chainNameForward) - if err != nil { - return fmt.Errorf("Addhook: %w", err) - } - - postroutingChain, err := getChainFromTable(conn, table.Nat, "POSTROUTING") - if err != nil { - return fmt.Errorf("get INPUT chain: %w", err) - } - err = addHookRule(conn, table.Nat, postroutingChain, chainNamePostrouting) - if err != nil { - return fmt.Errorf("Addhook: %w", err) - } - } - return nil -} - -// delHookRule deletes a rule that jumps from a hooked chain to a regular chain. -func delHookRule(conn *nftables.Conn, table *nftables.Table, fromChain *nftables.Chain, toChainName string) error { - rule := createHookRule(table, fromChain, toChainName) - existingRule, err := findRule(conn, rule) - if err != nil { - return fmt.Errorf("Failed to find hook rule: %w", err) - } - - if existingRule == nil { - return nil - } - - _ = conn.DelRule(existingRule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush del hook rule: %w", err) - } - return nil -} - -// DelHooks is deleting the rules added to conventional chains to jump to tailscale chains. -func (n *nftablesRunner) DelHooks(logf logger.Logf) error { - conn := n.conn - - for _, table := range n.getTables() { - inputChain, err := getChainFromTable(conn, table.Filter, "INPUT") - if err != nil { - return fmt.Errorf("get INPUT chain: %w", err) - } - err = delHookRule(conn, table.Filter, inputChain, chainNameInput) - if err != nil { - return fmt.Errorf("delhook: %w", err) - } - forwardChain, err := getChainFromTable(conn, table.Filter, "FORWARD") - if err != nil { - return fmt.Errorf("get FORWARD chain: %w", err) - } - err = delHookRule(conn, table.Filter, forwardChain, chainNameForward) - if err != nil { - return fmt.Errorf("delhook: %w", err) - } - - postroutingChain, err := getChainFromTable(conn, table.Nat, "POSTROUTING") - if err != nil { - return fmt.Errorf("get INPUT chain: %w", err) - } - err = delHookRule(conn, table.Nat, postroutingChain, chainNamePostrouting) - if err != nil { - return fmt.Errorf("delhook: %w", err) - } - } - - return nil -} - -// maskof returns the mask of the given prefix in big endian bytes. -func maskof(pfx netip.Prefix) []byte { - mask := make([]byte, 4) - binary.BigEndian.PutUint32(mask, ^(uint32(0xffff_ffff) >> pfx.Bits())) - return mask -} - -// createRangeRule creates a rule that matches packets with source IP from the give -// range (like CGNAT range or ChromeOSVM range) and the interface is not the tunname, -// and makes the given decision. Only IPv4 is supported. -func createRangeRule( - table *nftables.Table, chain *nftables.Chain, - tunname string, rng netip.Prefix, decision expr.VerdictKind, -) (*nftables.Rule, error) { - if rng.Addr().Is6() { - return nil, errors.New("IPv6 is not supported") - } - saddrExpr, err := newLoadSaddrExpr(nftables.TableFamilyIPv4, 1) - if err != nil { - return nil, fmt.Errorf("newLoadSaddrExpr: %w", err) - } - netip := rng.Addr().AsSlice() - mask := maskof(rng) - rule := &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpNeq, - Register: 1, - Data: []byte(tunname), - }, - saddrExpr, - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: mask, - Xor: []byte{0x00, 0x00, 0x00, 0x00}, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: netip, - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: decision, - }, - }, - } - return rule, nil - -} - -// addReturnChromeOSVMRangeRule adds a rule to return if the source IP -// is in the ChromeOS VM range. -func addReturnChromeOSVMRangeRule(c *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule, err := createRangeRule(table, chain, tunname, tsaddr.ChromeOSVMRange(), expr.VerdictReturn) - if err != nil { - return fmt.Errorf("create rule: %w", err) - } - _ = c.AddRule(rule) - if err = c.Flush(); err != nil { - return fmt.Errorf("add rule: %w", err) - } - return nil -} - -// addDropCGNATRangeRule adds a rule to drop if the source IP is in the -// CGNAT range. -func addDropCGNATRangeRule(c *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule, err := createRangeRule(table, chain, tunname, tsaddr.CGNATRange(), expr.VerdictDrop) - if err != nil { - return fmt.Errorf("create rule: %w", err) - } - _ = c.AddRule(rule) - if err = c.Flush(); err != nil { - return fmt.Errorf("add rule: %w", err) - } - return nil -} - -// createSetSubnetRouteMarkRule creates a rule to set the subnet route -// mark if the packet is from the given interface. -func createSetSubnetRouteMarkRule(table *nftables.Table, chain *nftables.Chain, tunname string) (*nftables.Rule, error) { - hexTsFwmarkMaskNeg := getTailscaleFwmarkMaskNeg() - hexTSSubnetRouteMark := getTailscaleSubnetRouteMark() - - rule := &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tunname), - }, - &expr.Counter{}, - &expr.Meta{Key: expr.MetaKeyMARK, Register: 1}, - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: hexTsFwmarkMaskNeg, - Xor: hexTSSubnetRouteMark, - }, - &expr.Meta{ - Key: expr.MetaKeyMARK, - SourceRegister: true, - Register: 1, - }, - }, - } - return rule, nil -} - -// addSetSubnetRouteMarkRule adds a rule to set the subnet route mark -// if the packet is from the given interface. -func addSetSubnetRouteMarkRule(c *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule, err := createSetSubnetRouteMarkRule(table, chain, tunname) - if err != nil { - return fmt.Errorf("create rule: %w", err) - } - _ = c.AddRule(rule) - - if err := c.Flush(); err != nil { - return fmt.Errorf("add rule: %w", err) - } - - return nil -} - -// createDropOutgoingPacketFromCGNATRangeRuleWithTunname creates a rule to drop -// outgoing packets from the CGNAT range. -func createDropOutgoingPacketFromCGNATRangeRuleWithTunname(table *nftables.Table, chain *nftables.Chain, tunname string) (*nftables.Rule, error) { - _, ipNet, err := net.ParseCIDR(tsaddr.CGNATRange().String()) - if err != nil { - return nil, fmt.Errorf("parse cidr: %v", err) - } - mask, err := hex.DecodeString(ipNet.Mask.String()) - if err != nil { - return nil, fmt.Errorf("decode mask: %v", err) - } - netip := ipNet.IP.Mask(ipNet.Mask).To4() - saddrExpr, err := newLoadSaddrExpr(nftables.TableFamilyIPv4, 1) - if err != nil { - return nil, fmt.Errorf("newLoadSaddrExpr: %v", err) - } - rule := &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tunname), - }, - saddrExpr, - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: mask, - Xor: []byte{0x00, 0x00, 0x00, 0x00}, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: netip, - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictDrop, - }, - }, - } - return rule, nil -} - -// addDropOutgoingPacketFromCGNATRangeRuleWithTunname adds a rule to drop -// outgoing packets from the CGNAT range. -func addDropOutgoingPacketFromCGNATRangeRuleWithTunname(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule, err := createDropOutgoingPacketFromCGNATRangeRuleWithTunname(table, chain, tunname) - if err != nil { - return fmt.Errorf("create rule: %w", err) - } - _ = conn.AddRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("add rule: %w", err) - } - return nil -} - -// createAcceptOutgoingPacketRule creates a rule to accept outgoing packets -// from the given interface. -func createAcceptOutgoingPacketRule(table *nftables.Table, chain *nftables.Chain, tunname string) *nftables.Rule { - return &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tunname), - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictAccept, - }, - }, - } -} - -// addAcceptOutgoingPacketRule adds a rule to accept outgoing packets -// from the given interface. -func addAcceptOutgoingPacketRule(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule := createAcceptOutgoingPacketRule(table, chain, tunname) - _ = conn.AddRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add rule: %w", err) - } - - return nil -} - -// createAcceptOnPortRule creates a rule to accept incoming packets to -// a given destination UDP port. -func createAcceptOnPortRule(table *nftables.Table, chain *nftables.Chain, port uint16) *nftables.Rule { - portBytes := make([]byte, 2) - binary.BigEndian.PutUint16(portBytes, port) - return &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{ - Key: expr.MetaKeyL4PROTO, - Register: 1, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte{unix.IPPROTO_UDP}, - }, - newLoadDportExpr(1), - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: portBytes, - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictAccept, - }, - }, - } -} - -// addAcceptOnPortRule adds a rule to accept incoming packets to -// a given destination UDP port. -func addAcceptOnPortRule(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, port uint16) error { - rule := createAcceptOnPortRule(table, chain, port) - _ = conn.AddRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add rule: %w", err) - } - - return nil -} - -// addAcceptOnPortRule removes a rule to accept incoming packets to -// a given destination UDP port. -func removeAcceptOnPortRule(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, port uint16) error { - rule := createAcceptOnPortRule(table, chain, port) - rule, err := findRule(conn, rule) - if err != nil { - return fmt.Errorf("find rule: %v", err) - } - - _ = conn.DelRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush del rule: %w", err) - } - - return nil -} - -// AddMagicsockPortRule adds a rule to nftables to allow incoming traffic on -// the specified UDP port, so magicsock can accept incoming connections. -// network must be either "udp4" or "udp6" - this determines whether the rule -// is added for IPv4 or IPv6. -func (n *nftablesRunner) AddMagicsockPortRule(port uint16, network string) error { - var filterTable *nftables.Table - switch network { - case "udp4": - filterTable = n.nft4.Filter - case "udp6": - filterTable = n.nft6.Filter - default: - return fmt.Errorf("unsupported network %s", network) - } - - inputChain, err := getChainFromTable(n.conn, filterTable, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain: %v", err) - } - - err = addAcceptOnPortRule(n.conn, filterTable, inputChain, port) - if err != nil { - return fmt.Errorf("add accept on port rule: %v", err) - } - - return nil -} - -// DelMagicsockPortRule removes a rule added by AddMagicsockPortRule to accept -// incoming traffic on a particular UDP port. -// network must be either "udp4" or "udp6" - this determines whether the rule -// is removed for IPv4 or IPv6. -func (n *nftablesRunner) DelMagicsockPortRule(port uint16, network string) error { - var filterTable *nftables.Table - switch network { - case "udp4": - filterTable = n.nft4.Filter - case "udp6": - filterTable = n.nft6.Filter - default: - return fmt.Errorf("unsupported network %s", network) - } - - inputChain, err := getChainFromTable(n.conn, filterTable, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain: %v", err) - } - - err = removeAcceptOnPortRule(n.conn, filterTable, inputChain, port) - if err != nil { - return fmt.Errorf("add accept on port rule: %v", err) - } - - return nil -} - -// createAcceptIncomingPacketRule creates a rule to accept incoming packets to -// the given interface. -func createAcceptIncomingPacketRule(table *nftables.Table, chain *nftables.Chain, tunname string) *nftables.Rule { - return &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: []expr.Any{ - &expr.Meta{Key: expr.MetaKeyIIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tunname), - }, - &expr.Counter{}, - &expr.Verdict{ - Kind: expr.VerdictAccept, - }, - }, - } -} - -func addAcceptIncomingPacketRule(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, tunname string) error { - rule := createAcceptIncomingPacketRule(table, chain, tunname) - _ = conn.AddRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add rule: %w", err) - } - - return nil -} - -// AddBase adds some basic processing rules. -func (n *nftablesRunner) AddBase(tunname string) error { - if err := n.addBase4(tunname); err != nil { - return fmt.Errorf("add base v4: %w", err) - } - if n.HasIPV6() { - if err := n.addBase6(tunname); err != nil { - return fmt.Errorf("add base v6: %w", err) - } - } - return nil -} - -// addBase4 adds some basic IPv4 processing rules. -func (n *nftablesRunner) addBase4(tunname string) error { - conn := n.conn - - inputChain, err := getChainFromTable(conn, n.nft4.Filter, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain v4: %v", err) - } - if err = addReturnChromeOSVMRangeRule(conn, n.nft4.Filter, inputChain, tunname); err != nil { - return fmt.Errorf("add return chromeos vm range rule v4: %w", err) - } - if err = addDropCGNATRangeRule(conn, n.nft4.Filter, inputChain, tunname); err != nil { - return fmt.Errorf("add drop cgnat range rule v4: %w", err) - } - if err = addAcceptIncomingPacketRule(conn, n.nft4.Filter, inputChain, tunname); err != nil { - return fmt.Errorf("add accept incoming packet rule v4: %w", err) - } - - forwardChain, err := getChainFromTable(conn, n.nft4.Filter, chainNameForward) - if err != nil { - return fmt.Errorf("get forward chain v4: %v", err) - } - - if err = addSetSubnetRouteMarkRule(conn, n.nft4.Filter, forwardChain, tunname); err != nil { - return fmt.Errorf("add set subnet route mark rule v4: %w", err) - } - - if err = addMatchSubnetRouteMarkRule(conn, n.nft4.Filter, forwardChain, Accept); err != nil { - return fmt.Errorf("add match subnet route mark rule v4: %w", err) - } - - if err = addDropOutgoingPacketFromCGNATRangeRuleWithTunname(conn, n.nft4.Filter, forwardChain, tunname); err != nil { - return fmt.Errorf("add drop outgoing packet from cgnat range rule v4: %w", err) - } - - if err = addAcceptOutgoingPacketRule(conn, n.nft4.Filter, forwardChain, tunname); err != nil { - return fmt.Errorf("add accept outgoing packet rule v4: %w", err) - } - - if err = conn.Flush(); err != nil { - return fmt.Errorf("flush base v4: %w", err) - } - - return nil -} - -// addBase6 adds some basic IPv6 processing rules. -func (n *nftablesRunner) addBase6(tunname string) error { - conn := n.conn - - inputChain, err := getChainFromTable(conn, n.nft6.Filter, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain v4: %v", err) - } - if err = addAcceptIncomingPacketRule(conn, n.nft6.Filter, inputChain, tunname); err != nil { - return fmt.Errorf("add accept incoming packet rule v6: %w", err) - } - - forwardChain, err := getChainFromTable(conn, n.nft6.Filter, chainNameForward) - if err != nil { - return fmt.Errorf("get forward chain v6: %w", err) - } - - if err = addSetSubnetRouteMarkRule(conn, n.nft6.Filter, forwardChain, tunname); err != nil { - return fmt.Errorf("add set subnet route mark rule v6: %w", err) - } - - if err = addMatchSubnetRouteMarkRule(conn, n.nft6.Filter, forwardChain, Accept); err != nil { - return fmt.Errorf("add match subnet route mark rule v6: %w", err) - } - - if err = addAcceptOutgoingPacketRule(conn, n.nft6.Filter, forwardChain, tunname); err != nil { - return fmt.Errorf("add accept outgoing packet rule v6: %w", err) - } - - if err = conn.Flush(); err != nil { - return fmt.Errorf("flush base v6: %w", err) - } - - return nil -} - -// DelBase empties, but does not remove, custom Tailscale chains from -// netfilter via iptables. -func (n *nftablesRunner) DelBase() error { - conn := n.conn - - for _, table := range n.getTables() { - inputChain, err := getChainFromTable(conn, table.Filter, chainNameInput) - if err != nil { - return fmt.Errorf("get input chain: %v", err) - } - conn.FlushChain(inputChain) - forwardChain, err := getChainFromTable(conn, table.Filter, chainNameForward) - if err != nil { - return fmt.Errorf("get forward chain: %v", err) - } - conn.FlushChain(forwardChain) - - postrouteChain, err := getChainFromTable(conn, table.Nat, chainNamePostrouting) - if err != nil { - return fmt.Errorf("get postrouting chain v4: %v", err) - } - conn.FlushChain(postrouteChain) - } - - return conn.Flush() -} - -// createMatchSubnetRouteMarkRule creates a rule that matches packets -// with the subnet route mark and takes the specified action. -func createMatchSubnetRouteMarkRule(table *nftables.Table, chain *nftables.Chain, action MatchDecision) (*nftables.Rule, error) { - hexTSFwmarkMask := getTailscaleFwmarkMask() - hexTSSubnetRouteMark := getTailscaleSubnetRouteMark() - - var endAction expr.Any - endAction = &expr.Verdict{Kind: expr.VerdictAccept} - if action == Masq { - endAction = &expr.Masq{} - } - - exprs := []expr.Any{ - &expr.Meta{Key: expr.MetaKeyMARK, Register: 1}, - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: hexTSFwmarkMask, - Xor: []byte{0x00, 0x00, 0x00, 0x00}, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: hexTSSubnetRouteMark, - }, - &expr.Counter{}, - endAction, - } - - rule := &nftables.Rule{ - Table: table, - Chain: chain, - Exprs: exprs, - } - return rule, nil -} - -// addMatchSubnetRouteMarkRule adds a rule that matches packets with -// the subnet route mark and takes the specified action. -func addMatchSubnetRouteMarkRule(conn *nftables.Conn, table *nftables.Table, chain *nftables.Chain, action MatchDecision) error { - rule, err := createMatchSubnetRouteMarkRule(table, chain, action) - if err != nil { - return fmt.Errorf("create match subnet route mark rule: %w", err) - } - _ = conn.AddRule(rule) - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add rule: %w", err) - } - - return nil -} - -// AddSNATRule adds a netfilter rule to SNAT traffic destined for -// local subnets. -func (n *nftablesRunner) AddSNATRule() error { - conn := n.conn - - for _, table := range n.getTables() { - chain, err := getChainFromTable(conn, table.Nat, chainNamePostrouting) - if err != nil { - return fmt.Errorf("get postrouting chain v4: %w", err) - } - - if err = addMatchSubnetRouteMarkRule(conn, table.Nat, chain, Masq); err != nil { - return fmt.Errorf("add match subnet route mark rule v4: %w", err) - } - } - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add SNAT rule: %w", err) - } - - return nil -} - -// DelSNATRule removes the netfilter rule to SNAT traffic destined for -// local subnets. An error is returned if the rule does not exist. -func (n *nftablesRunner) DelSNATRule() error { - conn := n.conn - - hexTSFwmarkMask := getTailscaleFwmarkMask() - hexTSSubnetRouteMark := getTailscaleSubnetRouteMark() - - exprs := []expr.Any{ - &expr.Meta{Key: expr.MetaKeyMARK, Register: 1}, - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: hexTSFwmarkMask, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: hexTSSubnetRouteMark, - }, - &expr.Counter{}, - &expr.Masq{}, - } - - for _, table := range n.getTables() { - chain, err := getChainFromTable(conn, table.Nat, chainNamePostrouting) - if err != nil { - return fmt.Errorf("get postrouting chain v4: %w", err) - } - - rule := &nftables.Rule{ - Table: table.Nat, - Chain: chain, - Exprs: exprs, - } - - SNATRule, err := findRule(conn, rule) - if err != nil { - return fmt.Errorf("find SNAT rule v4: %w", err) - } - - if SNATRule != nil { - _ = conn.DelRule(SNATRule) - } - } - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush del SNAT rule: %w", err) - } - - return nil -} - -func nativeUint32(v uint32) []byte { - b := make([]byte, 4) - binary.NativeEndian.PutUint32(b, v) - return b -} - -func makeStatefulRuleExprs(tunname string) []expr.Any { - return []expr.Any{ - // Check if the output interface is the Tailscale interface by - // first loding the OIFNAME into register 1 and comparing it - // against our tunname. - // - // 'cmp' implicitly breaks from a rule if a comparison fails, - // so if we continue past this rule we know that the packet is - // going to our TUN. - &expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1}, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: []byte(tunname), - }, - - // Store the conntrack state in register 1 - &expr.Ct{ - Register: 1, - Key: expr.CtKeySTATE, - }, - // Mask the state in register 1 to "hide" the ESTABLISHED and - // RELATED bits (which are expected and fine); if there are any - // other bits, we want them to remain. - // - // This operation is, in the kernel: - // dst[i] = (src[i] & mask[i]) ^ xor[i] - // - // So, we can mask by setting the inverse of the bits we want - // to remove; i.e. ESTABLISHED = 0b00000010, RELATED = - // 0b00000100, so, if we assume an 8-bit state (in reality, - // it's 32-bit), we can mask with 0b11111001 to clear those - // bits and keep everything else (e.g. the INVALID bit which is - // 0b00000001). - // - // TODO(andrew-d): for now, let's also allow - // CtStateBitUNTRACKED, which is a state for packets that are not - // tracked (marked so explicitly with an iptables rule using - // --notrack); we should figure out if we want to allow this or not. - &expr.Bitwise{ - SourceRegister: 1, - DestRegister: 1, - Len: 4, - Mask: nativeUint32(^(0 | - expr.CtStateBitESTABLISHED | - expr.CtStateBitRELATED | - expr.CtStateBitUNTRACKED)), - - // Xor is unused but must be specified - Xor: nativeUint32(0), - }, - // Compare against the expected state (0, i.e. no bits set - // other than maybe ESTABLISHED and RELATED). We want this - // comparison to fail if there are no bits set, so that this - // rule's evaluation stops and we don't fall through to the - // "Drop" verdict. - // - // For example, if the state is ESTABLISHED (and we want to - // break from this rule/accept this packet): - // state = ESTABLISHED - // register1 = 0b0 (since the bitwise operation cleared the ESTABLISHED bit) - // - // compare register1 (0b0) != 0: false - // -> comparison implicitly breaks - // -> continue to the next rule - // - // For example, if the state is NEW (and we want to continue to - // the next expression and thus drop this packet): - // state = NEW - // register1 = 0b1000 - // - // compare register1 (0b1000) != 0: true - // -> comparison continues to next expr - &expr.Cmp{ - Op: expr.CmpOpNeq, - Register: 1, - Data: []byte{0, 0, 0, 0}, - }, - // If we get here, we know that this packet is going to our TUN - // device, and has a conntrack state set other than ESTABLISHED - // or RELATED. We thus count and drop the packet. - &expr.Counter{}, - &expr.Verdict{Kind: expr.VerdictDrop}, - } - - // TODO(andrew-d): iptables-nft writes a rule that dumps as: - // - // match name conntrack rev 3 - // - // I think this is using expr.Match against the following struct - // (xt_conntrack_mtinfo3): - // - // https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/xt_conntrack.h#L64-L77 - // - // We could probably do something similar here, but I'm not sure if - // there's any advantage. Below is an example Match statement if we - // decide to do that, based on dumping the rule that iptables-nft - // generates: - // - // _ = expr.Match{ - // Name: "conntrack", - // Rev: 3, - // Info: &xt.ConntrackMtinfo3{ - // ConntrackMtinfo2: xt.ConntrackMtinfo2{ - // ConntrackMtinfoBase: xt.ConntrackMtinfoBase{ - // MatchFlags: xt.ConntrackState, - // InvertFlags: xt.ConntrackState, - // }, - // // Mask the state to remove ESTABLISHED and - // // RELATED before comparing. - // StateMask: expr.CtStateBitESTABLISHED | expr.CtStateBitRELATED, - // }, - // }, - // } -} - -// AddStatefulRule adds a netfilter rule for stateful packet filtering using -// conntrack. -func (n *nftablesRunner) AddStatefulRule(tunname string) error { - conn := n.conn - - exprs := makeStatefulRuleExprs(tunname) - for _, table := range n.getTables() { - chain, err := getChainFromTable(conn, table.Filter, chainNameForward) - if err != nil { - return fmt.Errorf("get forward chain: %w", err) - } - - // First, find the 'accept' rule that we want to insert our rule before. - acceptRule := createAcceptOutgoingPacketRule(table.Filter, chain, tunname) - rule, err := findRule(conn, acceptRule) - if err != nil { - return fmt.Errorf("find accept rule: %w", err) - } - - conn.InsertRule(&nftables.Rule{ - Table: table.Filter, - Chain: chain, - Exprs: exprs, - - // Specifying Position in an Insert operation means to - // insert this rule before the specified rule. - Position: rule.Handle, - }) - } - - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush add stateful rule: %w", err) - } - return nil -} - -// DelStatefulRule removes the netfilter rule for stateful packet filtering -// using conntrack. -func (n *nftablesRunner) DelStatefulRule(tunname string) error { - conn := n.conn - - exprs := makeStatefulRuleExprs(tunname) - for _, table := range n.getTables() { - chain, err := getChainFromTable(conn, table.Filter, chainNameForward) - if err != nil { - return fmt.Errorf("get forward chain: %w", err) - } - rule, err := findRule(conn, &nftables.Rule{ - Table: table.Filter, - Chain: chain, - Exprs: exprs, - }) - if err != nil { - return fmt.Errorf("find stateful rule: %w", err) - } - - if rule != nil { - conn.DelRule(rule) - } - } - if err := conn.Flush(); err != nil { - return fmt.Errorf("flush del stateful rule: %w", err) - } - return nil -} - -// cleanupChain removes a jump rule from hookChainName to tsChainName, and then -// the entire chain tsChainName. Errors are logged, but attempts to remove both -// the jump rule and chain continue even if one errors. -func cleanupChain(logf logger.Logf, conn *nftables.Conn, table *nftables.Table, hookChainName, tsChainName string) { - // remove the jump first, before removing the jump destination. - defaultChain, err := getChainFromTable(conn, table, hookChainName) - if err != nil && !errors.Is(err, errorChainNotFound{table.Name, hookChainName}) { - logf("cleanup: did not find default chain: %s", err) - } - if !errors.Is(err, errorChainNotFound{table.Name, hookChainName}) { - // delete hook in convention chain - _ = delHookRule(conn, table, defaultChain, tsChainName) - } - - tsChain, err := getChainFromTable(conn, table, tsChainName) - if err != nil && !errors.Is(err, errorChainNotFound{table.Name, tsChainName}) { - logf("cleanup: did not find ts-chain: %s", err) - } - - if tsChain != nil { - // flush and delete ts-chain - conn.FlushChain(tsChain) - conn.DelChain(tsChain) - err = conn.Flush() - logf("cleanup: delete and flush chain %s: %s", tsChainName, err) - } -} - -// NfTablesCleanUp removes all Tailscale added nftables rules. -// Any errors that occur are logged to the provided logf. -func NfTablesCleanUp(logf logger.Logf) { - conn, err := nftables.New() - if err != nil { - logf("cleanup: nftables connection: %s", err) - } - - tables, err := conn.ListTables() // both v4 and v6 - if err != nil { - logf("cleanup: list tables: %s", err) - } - - for _, table := range tables { - // These table names were used briefly in 1.48.0. - if table.Name == "ts-filter" || table.Name == "ts-nat" { - conn.DelTable(table) - if err := conn.Flush(); err != nil { - logf("cleanup: flush delete table %s: %s", table.Name, err) - } - } - - if table.Name == "filter" { - cleanupChain(logf, conn, table, "INPUT", chainNameInput) - cleanupChain(logf, conn, table, "FORWARD", chainNameForward) - } - if table.Name == "nat" { - cleanupChain(logf, conn, table, "POSTROUTING", chainNamePostrouting) - } - } -} - -func snatRule(t *nftables.Table, ch *nftables.Chain, src, dst netip.Addr, meta []byte) *nftables.Rule { - var daddrOffset, fam, daddrLen uint32 - if dst.Is4() { - daddrOffset = 16 - daddrLen = 4 - fam = unix.NFPROTO_IPV4 - } else { - daddrOffset = 24 - daddrLen = 16 - fam = unix.NFPROTO_IPV6 - } - - return &nftables.Rule{ - Table: t, - Chain: ch, - Exprs: []expr.Any{ - &expr.Payload{ - DestRegister: 1, - Base: expr.PayloadBaseNetworkHeader, - Offset: daddrOffset, - Len: daddrLen, - }, - &expr.Cmp{ - Op: expr.CmpOpEq, - Register: 1, - Data: dst.AsSlice(), - }, - &expr.Immediate{ - Register: 1, - Data: src.AsSlice(), - }, - &expr.NAT{ - Type: expr.NATTypeSourceNAT, - Family: fam, - RegAddrMin: 1, - RegAddrMax: 1, - }, - }, - UserData: meta, - } -} diff --git a/vendor/tailscale.com/util/linuxfw/nftables_types.go b/vendor/tailscale.com/util/linuxfw/nftables_types.go deleted file mode 100644 index b6e24d2..0000000 --- a/vendor/tailscale.com/util/linuxfw/nftables_types.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// TODO(#8502): add support for more architectures -//go:build linux && (arm64 || amd64) - -package linuxfw - -import ( - "github.com/google/nftables/expr" - "github.com/google/nftables/xt" -) - -var metaKeyNames = map[expr.MetaKey]string{ - expr.MetaKeyLEN: "LEN", - expr.MetaKeyPROTOCOL: "PROTOCOL", - expr.MetaKeyPRIORITY: "PRIORITY", - expr.MetaKeyMARK: "MARK", - expr.MetaKeyIIF: "IIF", - expr.MetaKeyOIF: "OIF", - expr.MetaKeyIIFNAME: "IIFNAME", - expr.MetaKeyOIFNAME: "OIFNAME", - expr.MetaKeyIIFTYPE: "IIFTYPE", - expr.MetaKeyOIFTYPE: "OIFTYPE", - expr.MetaKeySKUID: "SKUID", - expr.MetaKeySKGID: "SKGID", - expr.MetaKeyNFTRACE: "NFTRACE", - expr.MetaKeyRTCLASSID: "RTCLASSID", - expr.MetaKeySECMARK: "SECMARK", - expr.MetaKeyNFPROTO: "NFPROTO", - expr.MetaKeyL4PROTO: "L4PROTO", - expr.MetaKeyBRIIIFNAME: "BRIIIFNAME", - expr.MetaKeyBRIOIFNAME: "BRIOIFNAME", - expr.MetaKeyPKTTYPE: "PKTTYPE", - expr.MetaKeyCPU: "CPU", - expr.MetaKeyIIFGROUP: "IIFGROUP", - expr.MetaKeyOIFGROUP: "OIFGROUP", - expr.MetaKeyCGROUP: "CGROUP", - expr.MetaKeyPRANDOM: "PRANDOM", -} - -var cmpOpNames = map[expr.CmpOp]string{ - expr.CmpOpEq: "EQ", - expr.CmpOpNeq: "NEQ", - expr.CmpOpLt: "LT", - expr.CmpOpLte: "LTE", - expr.CmpOpGt: "GT", - expr.CmpOpGte: "GTE", -} - -var verdictNames = map[expr.VerdictKind]string{ - expr.VerdictReturn: "RETURN", - expr.VerdictGoto: "GOTO", - expr.VerdictJump: "JUMP", - expr.VerdictBreak: "BREAK", - expr.VerdictContinue: "CONTINUE", - expr.VerdictDrop: "DROP", - expr.VerdictAccept: "ACCEPT", - expr.VerdictStolen: "STOLEN", - expr.VerdictQueue: "QUEUE", - expr.VerdictRepeat: "REPEAT", - expr.VerdictStop: "STOP", -} - -var payloadOperationTypeNames = map[expr.PayloadOperationType]string{ - expr.PayloadLoad: "LOAD", - expr.PayloadWrite: "WRITE", -} - -var payloadBaseNames = map[expr.PayloadBase]string{ - expr.PayloadBaseLLHeader: "ll-header", - expr.PayloadBaseNetworkHeader: "network-header", - expr.PayloadBaseTransportHeader: "transport-header", -} - -var packetTypeNames = map[int]string{ - 0 /* PACKET_HOST */ : "unicast", - 1 /* PACKET_BROADCAST */ : "broadcast", - 2 /* PACKET_MULTICAST */ : "multicast", -} - -var addrTypeFlagNames = map[xt.AddrTypeFlags]string{ - xt.AddrTypeUnspec: "unspec", - xt.AddrTypeUnicast: "unicast", - xt.AddrTypeLocal: "local", - xt.AddrTypeBroadcast: "broadcast", - xt.AddrTypeAnycast: "anycast", - xt.AddrTypeMulticast: "multicast", - xt.AddrTypeBlackhole: "blackhole", - xt.AddrTypeUnreachable: "unreachable", - xt.AddrTypeProhibit: "prohibit", - xt.AddrTypeThrow: "throw", - xt.AddrTypeNat: "nat", - xt.AddrTypeXresolve: "xresolve", -} diff --git a/vendor/tailscale.com/util/mak/mak.go b/vendor/tailscale.com/util/mak/mak.go index b421fb0..fbdb40b 100644 --- a/vendor/tailscale.com/util/mak/mak.go +++ b/vendor/tailscale.com/util/mak/mak.go @@ -5,11 +5,6 @@ // things, notably to maps, but also slices. package mak -import ( - "fmt" - "reflect" -) - // Set populates an entry in a map, making the map if necessary. // // That is, it assigns (*m)[k] = v, making *m if it was nil. @@ -20,35 +15,6 @@ func Set[K comparable, V any, T ~map[K]V](m *T, k K, v V) { (*m)[k] = v } -// NonNil takes a pointer to a Go data structure -// (currently only a slice or a map) and makes sure it's non-nil for -// JSON serialization. (In particular, JavaScript clients usually want -// the field to be defined after they decode the JSON.) -// -// Deprecated: use NonNilSliceForJSON or NonNilMapForJSON instead. -func NonNil(ptr any) { - if ptr == nil { - panic("nil interface") - } - rv := reflect.ValueOf(ptr) - if rv.Kind() != reflect.Ptr { - panic(fmt.Sprintf("kind %v, not Ptr", rv.Kind())) - } - if rv.Pointer() == 0 { - panic("nil pointer") - } - rv = rv.Elem() - if rv.Pointer() != 0 { - return - } - switch rv.Type().Kind() { - case reflect.Slice: - rv.Set(reflect.MakeSlice(rv.Type(), 0, 0)) - case reflect.Map: - rv.Set(reflect.MakeMap(rv.Type())) - } -} - // NonNilSliceForJSON makes sure that *slicePtr is non-nil so it will // won't be omitted from JSON serialization and possibly confuse JavaScript // clients expecting it to be present. diff --git a/vendor/tailscale.com/util/multierr/multierr.go b/vendor/tailscale.com/util/multierr/multierr.go deleted file mode 100644 index 93ca068..0000000 --- a/vendor/tailscale.com/util/multierr/multierr.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package multierr provides a simple multiple-error type. -// It was inspired by github.com/go-multierror/multierror. -package multierr - -import ( - "errors" - "slices" - "strings" -) - -// An Error represents multiple errors. -type Error struct { - errs []error -} - -// Error implements the error interface. -func (e Error) Error() string { - s := new(strings.Builder) - s.WriteString("multiple errors:") - for _, err := range e.errs { - s.WriteString("\n\t") - s.WriteString(err.Error()) - } - return s.String() -} - -// Errors returns a slice containing all errors in e. -func (e Error) Errors() []error { - return slices.Clone(e.errs) -} - -// Unwrap returns the underlying errors as-is. -func (e Error) Unwrap() []error { - // Do not clone since Unwrap requires callers to not mutate the slice. - // See the documentation in the Go "errors" package. - return e.errs -} - -// New returns an error composed from errs. -// Some errors in errs get special treatment: -// - nil errors are discarded -// - errors of type Error are expanded into the top level -// -// If the resulting slice has length 0, New returns nil. -// If the resulting slice has length 1, New returns that error. -// If the resulting slice has length > 1, New returns that slice as an Error. -func New(errs ...error) error { - // First count the number of errors to avoid allocating. - var n int - var errFirst error - for _, e := range errs { - switch e := e.(type) { - case nil: - continue - case Error: - n += len(e.errs) - if errFirst == nil && len(e.errs) > 0 { - errFirst = e.errs[0] - } - default: - n++ - if errFirst == nil { - errFirst = e - } - } - } - if n <= 1 { - return errFirst // nil if n == 0 - } - - // More than one error, allocate slice and construct the multi-error. - dst := make([]error, 0, n) - for _, e := range errs { - switch e := e.(type) { - case nil: - continue - case Error: - dst = append(dst, e.errs...) - default: - dst = append(dst, e) - } - } - return Error{errs: dst} -} - -// Is reports whether any error in e matches target. -func (e Error) Is(target error) bool { - for _, err := range e.errs { - if errors.Is(err, target) { - return true - } - } - return false -} - -// As finds the first error in e that matches target, and if any is found, -// sets target to that error value and returns true. Otherwise, it returns false. -func (e Error) As(target any) bool { - for _, err := range e.errs { - if ok := errors.As(err, target); ok { - return true - } - } - return false -} - -// Range performs a pre-order, depth-first iteration of the error tree -// by successively unwrapping all error values. -// For each iteration it calls fn with the current error value and -// stops iteration if it ever reports false. -func Range(err error, fn func(error) bool) bool { - if err == nil { - return true - } - if !fn(err) { - return false - } - switch err := err.(type) { - case interface{ Unwrap() error }: - if err := err.Unwrap(); err != nil { - if !Range(err, fn) { - return false - } - } - case interface{ Unwrap() []error }: - for _, err := range err.Unwrap() { - if !Range(err, fn) { - return false - } - } - } - return true -} diff --git a/vendor/tailscale.com/util/must/must.go b/vendor/tailscale.com/util/must/must.go index 21965da..a292da2 100644 --- a/vendor/tailscale.com/util/must/must.go +++ b/vendor/tailscale.com/util/must/must.go @@ -23,3 +23,11 @@ func Get[T any](v T, err error) T { } return v } + +// Get2 returns v1 and v2 as is. It panics if err is non-nil. +func Get2[T any, U any](v1 T, v2 U, err error) (T, U) { + if err != nil { + panic(err) + } + return v1, v2 +} diff --git a/vendor/tailscale.com/util/osdiag/zsyscall_windows.go b/vendor/tailscale.com/util/osdiag/zsyscall_windows.go index ab0d18d..2a11b46 100644 --- a/vendor/tailscale.com/util/osdiag/zsyscall_windows.go +++ b/vendor/tailscale.com/util/osdiag/zsyscall_windows.go @@ -51,7 +51,7 @@ var ( ) func regEnumValue(key registry.Key, index uint32, valueName *uint16, valueNameLen *uint32, reserved *uint32, valueType *uint32, pData *byte, cbData *uint32) (ret error) { - r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(valueName)), uintptr(unsafe.Pointer(valueNameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valueType)), uintptr(unsafe.Pointer(pData)), uintptr(unsafe.Pointer(cbData)), 0) + r0, _, _ := syscall.SyscallN(procRegEnumValueW.Addr(), uintptr(key), uintptr(index), uintptr(unsafe.Pointer(valueName)), uintptr(unsafe.Pointer(valueNameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valueType)), uintptr(unsafe.Pointer(pData)), uintptr(unsafe.Pointer(cbData))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -59,7 +59,7 @@ func regEnumValue(key registry.Key, index uint32, valueName *uint16, valueNameLe } func globalMemoryStatusEx(memStatus *_MEMORYSTATUSEX) (err error) { - r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(memStatus)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGlobalMemoryStatusEx.Addr(), uintptr(unsafe.Pointer(memStatus))) if int32(r1) == 0 { err = errnoErr(e1) } @@ -67,19 +67,19 @@ func globalMemoryStatusEx(memStatus *_MEMORYSTATUSEX) (err error) { } func wscEnumProtocols(iProtocols *int32, protocolBuffer *wsaProtocolInfo, bufLen *uint32, errno *int32) (ret int32) { - r0, _, _ := syscall.Syscall6(procWSCEnumProtocols.Addr(), 4, uintptr(unsafe.Pointer(iProtocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufLen)), uintptr(unsafe.Pointer(errno)), 0, 0) + r0, _, _ := syscall.SyscallN(procWSCEnumProtocols.Addr(), uintptr(unsafe.Pointer(iProtocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufLen)), uintptr(unsafe.Pointer(errno))) ret = int32(r0) return } func wscGetProviderInfo(providerId *windows.GUID, infoType _WSC_PROVIDER_INFO_TYPE, info unsafe.Pointer, infoSize *uintptr, flags uint32, errno *int32) (ret int32) { - r0, _, _ := syscall.Syscall6(procWSCGetProviderInfo.Addr(), 6, uintptr(unsafe.Pointer(providerId)), uintptr(infoType), uintptr(info), uintptr(unsafe.Pointer(infoSize)), uintptr(flags), uintptr(unsafe.Pointer(errno))) + r0, _, _ := syscall.SyscallN(procWSCGetProviderInfo.Addr(), uintptr(unsafe.Pointer(providerId)), uintptr(infoType), uintptr(info), uintptr(unsafe.Pointer(infoSize)), uintptr(flags), uintptr(unsafe.Pointer(errno))) ret = int32(r0) return } func wscGetProviderPath(providerId *windows.GUID, providerDllPath *uint16, providerDllPathLen *int32, errno *int32) (ret int32) { - r0, _, _ := syscall.Syscall6(procWSCGetProviderPath.Addr(), 4, uintptr(unsafe.Pointer(providerId)), uintptr(unsafe.Pointer(providerDllPath)), uintptr(unsafe.Pointer(providerDllPathLen)), uintptr(unsafe.Pointer(errno)), 0, 0) + r0, _, _ := syscall.SyscallN(procWSCGetProviderPath.Addr(), uintptr(unsafe.Pointer(providerId)), uintptr(unsafe.Pointer(providerDllPath)), uintptr(unsafe.Pointer(providerDllPathLen)), uintptr(unsafe.Pointer(errno))) ret = int32(r0) return } diff --git a/vendor/tailscale.com/util/osshare/filesharingstatus_noop.go b/vendor/tailscale.com/util/osshare/filesharingstatus_noop.go deleted file mode 100644 index 7f2b131..0000000 --- a/vendor/tailscale.com/util/osshare/filesharingstatus_noop.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !windows - -package osshare - -import ( - "tailscale.com/types/logger" -) - -func SetFileSharingEnabled(enabled bool, logf logger.Logf) {} diff --git a/vendor/tailscale.com/util/osshare/filesharingstatus_windows.go b/vendor/tailscale.com/util/osshare/filesharingstatus_windows.go deleted file mode 100644 index 999fc1c..0000000 --- a/vendor/tailscale.com/util/osshare/filesharingstatus_windows.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package osshare provides utilities for enabling/disabling Taildrop file -// sharing on Windows. -package osshare - -import ( - "fmt" - "os" - "path/filepath" - "sync" - - "golang.org/x/sys/windows/registry" - "tailscale.com/types/logger" -) - -const ( - sendFileShellKey = `*\shell\tailscale` -) - -var ipnExePath struct { - sync.Mutex - cache string // absolute path of tailscale-ipn.exe, populated lazily on first use -} - -func getIpnExePath(logf logger.Logf) string { - ipnExePath.Lock() - defer ipnExePath.Unlock() - - if ipnExePath.cache != "" { - return ipnExePath.cache - } - - // Find the absolute path of tailscale-ipn.exe assuming that it's in the same - // directory as this executable (tailscaled.exe). - p, err := os.Executable() - if err != nil { - logf("os.Executable error: %v", err) - return "" - } - if p, err = filepath.EvalSymlinks(p); err != nil { - logf("filepath.EvalSymlinks error: %v", err) - return "" - } - p = filepath.Join(filepath.Dir(p), "tailscale-ipn.exe") - if p, err = filepath.Abs(p); err != nil { - logf("filepath.Abs error: %v", err) - return "" - } - ipnExePath.cache = p - - return p -} - -// SetFileSharingEnabled adds/removes "Send with Tailscale" from the Windows shell menu. -func SetFileSharingEnabled(enabled bool, logf logger.Logf) { - logf = logger.WithPrefix(logf, fmt.Sprintf("SetFileSharingEnabled(%v) error: ", enabled)) - if enabled { - enableFileSharing(logf) - } else { - disableFileSharing(logf) - } -} - -func enableFileSharing(logf logger.Logf) { - path := getIpnExePath(logf) - if path == "" { - return - } - - k, _, err := registry.CreateKey(registry.CLASSES_ROOT, sendFileShellKey, registry.WRITE) - if err != nil { - logf("failed to create HKEY_CLASSES_ROOT\\%s reg key: %v", sendFileShellKey, err) - return - } - defer k.Close() - if err := k.SetStringValue("", "Send with Tailscale..."); err != nil { - logf("k.SetStringValue error: %v", err) - return - } - if err := k.SetStringValue("Icon", path+",0"); err != nil { - logf("k.SetStringValue error: %v", err) - return - } - c, _, err := registry.CreateKey(k, "command", registry.WRITE) - if err != nil { - logf("failed to create HKEY_CLASSES_ROOT\\%s\\command reg key: %v", sendFileShellKey, err) - return - } - defer c.Close() - if err := c.SetStringValue("", "\""+path+"\" /push \"%1\""); err != nil { - logf("c.SetStringValue error: %v", err) - } -} - -func disableFileSharing(logf logger.Logf) { - if err := registry.DeleteKey(registry.CLASSES_ROOT, sendFileShellKey+"\\command"); err != nil && - err != registry.ErrNotExist { - logf("registry.DeleteKey error: %v\n", err) - return - } - if err := registry.DeleteKey(registry.CLASSES_ROOT, sendFileShellKey); err != nil && err != registry.ErrNotExist { - logf("registry.DeleteKey error: %v\n", err) - } -} diff --git a/vendor/tailscale.com/util/osuser/group_ids.go b/vendor/tailscale.com/util/osuser/group_ids.go index f25861d..7c2b5b0 100644 --- a/vendor/tailscale.com/util/osuser/group_ids.go +++ b/vendor/tailscale.com/util/osuser/group_ids.go @@ -19,6 +19,10 @@ import ( // an error. It will first try to use the 'id' command to get the group IDs, // and if that fails, it will fall back to the user.GroupIds method. func GetGroupIds(user *user.User) ([]string, error) { + if runtime.GOOS == "plan9" { + return nil, nil + } + if runtime.GOOS != "linux" { return user.GroupIds() } diff --git a/vendor/tailscale.com/util/osuser/user.go b/vendor/tailscale.com/util/osuser/user.go index 2c7f2e2..8b96194 100644 --- a/vendor/tailscale.com/util/osuser/user.go +++ b/vendor/tailscale.com/util/osuser/user.go @@ -54,9 +54,18 @@ func lookup(usernameOrUID string, std lookupStd, wantShell bool) (*user.User, st // Skip getent entirely on Non-Unix platforms that won't ever have it. // (Using HasPrefix for "wasip1", anticipating that WASI support will // move beyond "preview 1" some day.) - if runtime.GOOS == "windows" || runtime.GOOS == "js" || runtime.GOARCH == "wasm" { + if runtime.GOOS == "windows" || runtime.GOOS == "js" || runtime.GOARCH == "wasm" || runtime.GOOS == "plan9" { + var shell string + if wantShell && runtime.GOOS == "plan9" { + shell = "/bin/rc" + } + if runtime.GOOS == "plan9" { + if u, err := user.Current(); err == nil { + return u, shell, nil + } + } u, err := std(usernameOrUID) - return u, "", err + return u, shell, err } // No getent on Gokrazy. So hard-code the login shell. @@ -78,6 +87,16 @@ func lookup(usernameOrUID string, std lookupStd, wantShell bool) (*user.User, st return u, shell, nil } + if runtime.GOOS == "plan9" { + return &user.User{ + Uid: "0", + Gid: "0", + Username: "glenda", + Name: "Glenda", + HomeDir: "/", + }, "/bin/rc", nil + } + // Start with getent if caller wants to get the user shell. if wantShell { return userLookupGetent(usernameOrUID, std) diff --git a/vendor/tailscale.com/util/progresstracking/progresstracking.go b/vendor/tailscale.com/util/progresstracking/progresstracking.go deleted file mode 100644 index a9411fb..0000000 --- a/vendor/tailscale.com/util/progresstracking/progresstracking.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package progresstracking provides wrappers around io.Reader and io.Writer -// that track progress. -package progresstracking - -import ( - "io" - "time" -) - -// NewReader wraps the given Reader with a progress tracking Reader that -// reports progress at the following points: -// -// - First read -// - Every read spaced at least interval since the prior read -// - Last read -func NewReader(r io.Reader, interval time.Duration, onProgress func(totalRead int, err error)) io.Reader { - return &reader{Reader: r, interval: interval, onProgress: onProgress} -} - -type reader struct { - io.Reader - interval time.Duration - onProgress func(int, error) - lastTracked time.Time - totalRead int -} - -func (r *reader) Read(p []byte) (int, error) { - n, err := r.Reader.Read(p) - r.totalRead += n - if time.Since(r.lastTracked) > r.interval || err != nil { - r.onProgress(r.totalRead, err) - r.lastTracked = time.Now() - } - return n, err -} diff --git a/vendor/tailscale.com/util/ringbuffer/ringbuffer.go b/vendor/tailscale.com/util/ringbuffer/ringbuffer.go deleted file mode 100644 index baca2af..0000000 --- a/vendor/tailscale.com/util/ringbuffer/ringbuffer.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package ringbuffer contains a fixed-size concurrency-safe generic ring -// buffer. -package ringbuffer - -import "sync" - -// New creates a new RingBuffer containing at most max items. -func New[T any](max int) *RingBuffer[T] { - return &RingBuffer[T]{ - max: max, - } -} - -// RingBuffer is a concurrency-safe ring buffer. -type RingBuffer[T any] struct { - mu sync.Mutex - pos int - buf []T - max int -} - -// Add appends a new item to the RingBuffer, possibly overwriting the oldest -// item in the buffer if it is already full. -// -// It does nothing if rb is nil. -func (rb *RingBuffer[T]) Add(t T) { - if rb == nil { - return - } - rb.mu.Lock() - defer rb.mu.Unlock() - if len(rb.buf) < rb.max { - rb.buf = append(rb.buf, t) - } else { - rb.buf[rb.pos] = t - rb.pos = (rb.pos + 1) % rb.max - } -} - -// GetAll returns a copy of all the entries in the ring buffer in the order they -// were added. -// -// It returns nil if rb is nil. -func (rb *RingBuffer[T]) GetAll() []T { - if rb == nil { - return nil - } - rb.mu.Lock() - defer rb.mu.Unlock() - out := make([]T, len(rb.buf)) - for i := range len(rb.buf) { - x := (rb.pos + i) % rb.max - out[i] = rb.buf[x] - } - return out -} - -// Len returns the number of elements in the ring buffer. Note that this value -// could change immediately after being returned if a concurrent caller -// modifies the buffer. -func (rb *RingBuffer[T]) Len() int { - if rb == nil { - return 0 - } - rb.mu.Lock() - defer rb.mu.Unlock() - return len(rb.buf) -} - -// Clear will empty the ring buffer. -func (rb *RingBuffer[T]) Clear() { - rb.mu.Lock() - defer rb.mu.Unlock() - rb.pos = 0 - rb.buf = nil -} diff --git a/vendor/tailscale.com/util/ringlog/ringlog.go b/vendor/tailscale.com/util/ringlog/ringlog.go new file mode 100644 index 0000000..62dfbae --- /dev/null +++ b/vendor/tailscale.com/util/ringlog/ringlog.go @@ -0,0 +1,78 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package ringlog contains a limited-size concurrency-safe generic ring log. +package ringlog + +import "tailscale.com/syncs" + +// New creates a new [RingLog] containing at most max items. +func New[T any](max int) *RingLog[T] { + return &RingLog[T]{ + max: max, + } +} + +// RingLog is a concurrency-safe fixed size log window containing entries of [T]. +type RingLog[T any] struct { + mu syncs.Mutex + pos int + buf []T + max int +} + +// Add appends a new item to the [RingLog], possibly overwriting the oldest +// item in the log if it is already full. +// +// It does nothing if rb is nil. +func (rb *RingLog[T]) Add(t T) { + if rb == nil { + return + } + rb.mu.Lock() + defer rb.mu.Unlock() + if len(rb.buf) < rb.max { + rb.buf = append(rb.buf, t) + } else { + rb.buf[rb.pos] = t + rb.pos = (rb.pos + 1) % rb.max + } +} + +// GetAll returns a copy of all the entries in the ring log in the order they +// were added. +// +// It returns nil if rb is nil. +func (rb *RingLog[T]) GetAll() []T { + if rb == nil { + return nil + } + rb.mu.Lock() + defer rb.mu.Unlock() + out := make([]T, len(rb.buf)) + for i := range len(rb.buf) { + x := (rb.pos + i) % rb.max + out[i] = rb.buf[x] + } + return out +} + +// Len returns the number of elements in the ring log. Note that this value +// could change immediately after being returned if a concurrent caller +// modifies the log. +func (rb *RingLog[T]) Len() int { + if rb == nil { + return 0 + } + rb.mu.Lock() + defer rb.mu.Unlock() + return len(rb.buf) +} + +// Clear will empty the ring log. +func (rb *RingLog[T]) Clear() { + rb.mu.Lock() + defer rb.mu.Unlock() + rb.pos = 0 + rb.buf = nil +} diff --git a/vendor/tailscale.com/util/set/handle.go b/vendor/tailscale.com/util/set/handle.go index 471ceeb..9c6b6da 100644 --- a/vendor/tailscale.com/util/set/handle.go +++ b/vendor/tailscale.com/util/set/handle.go @@ -9,20 +9,28 @@ package set type HandleSet[T any] map[Handle]T // Handle is an opaque comparable value that's used as the map key in a -// HandleSet. The only way to get one is to call HandleSet.Add. +// HandleSet. type Handle struct { v *byte } +// NewHandle returns a new handle value. +func NewHandle() Handle { + return Handle{new(byte)} +} + // Add adds the element (map value) e to the set. // -// It returns the handle (map key) with which e can be removed, using a map -// delete. +// It returns a new handle (map key) with which e can be removed, using a map +// delete or the [HandleSet.Delete] method. func (s *HandleSet[T]) Add(e T) Handle { - h := Handle{new(byte)} + h := NewHandle() if *s == nil { *s = make(HandleSet[T]) } (*s)[h] = e return h } + +// Delete removes the element with handle h from the set. +func (s HandleSet[T]) Delete(h Handle) { delete(s, h) } diff --git a/vendor/tailscale.com/util/set/intset.go b/vendor/tailscale.com/util/set/intset.go new file mode 100644 index 0000000..d325246 --- /dev/null +++ b/vendor/tailscale.com/util/set/intset.go @@ -0,0 +1,198 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package set + +import ( + "iter" + "maps" + "math/bits" + "math/rand/v2" + + "golang.org/x/exp/constraints" + "tailscale.com/util/mak" +) + +// IntSet is a set optimized for integer values close to zero +// or set of integers that are close in value. +type IntSet[T constraints.Integer] struct { + // bits is a [bitSet] for numbers less than [bits.UintSize]. + bits bitSet + + // extra is a mapping of [bitSet] for numbers not in bits, + // where the key is a number modulo [bits.UintSize]. + extra map[uint64]bitSet + + // extraLen is the count of numbers in extra since len(extra) + // does not reflect that each bitSet may have multiple numbers. + extraLen int +} + +// IntsOf constructs an [IntSet] with the provided elements. +func IntsOf[T constraints.Integer](slice ...T) IntSet[T] { + var s IntSet[T] + for _, e := range slice { + s.Add(e) + } + return s +} + +// Values returns an iterator over the elements of the set. +// The iterator will yield the elements in no particular order. +func (s IntSet[T]) Values() iter.Seq[T] { + return func(yield func(T) bool) { + if s.bits != 0 { + for i := range s.bits.values() { + if !yield(decodeZigZag[T](i)) { + return + } + } + } + if s.extra != nil { + for hi, bs := range s.extra { + for lo := range bs.values() { + if !yield(decodeZigZag[T](hi*bits.UintSize + lo)) { + return + } + } + } + } + } +} + +// Contains reports whether e is in the set. +func (s IntSet[T]) Contains(e T) bool { + if v := encodeZigZag(e); v < bits.UintSize { + return s.bits.contains(v) + } else { + hi, lo := v/uint64(bits.UintSize), v%uint64(bits.UintSize) + return s.extra[hi].contains(lo) + } +} + +// Add adds e to the set. +// +// When storing a IntSet in a map as a value type, +// it is important to re-assign the map entry after calling Add or Delete, +// as the IntSet's representation may change. +func (s *IntSet[T]) Add(e T) { + if v := encodeZigZag(e); v < bits.UintSize { + s.bits.add(v) + } else { + hi, lo := v/uint64(bits.UintSize), v%uint64(bits.UintSize) + if bs := s.extra[hi]; !bs.contains(lo) { + bs.add(lo) + mak.Set(&s.extra, hi, bs) + s.extra[hi] = bs + s.extraLen++ + } + } +} + +// AddSeq adds the values from seq to the set. +func (s *IntSet[T]) AddSeq(seq iter.Seq[T]) { + for e := range seq { + s.Add(e) + } +} + +// Len reports the number of elements in the set. +func (s IntSet[T]) Len() int { + return s.bits.len() + s.extraLen +} + +// Delete removes e from the set. +// +// When storing a IntSet in a map as a value type, +// it is important to re-assign the map entry after calling Add or Delete, +// as the IntSet's representation may change. +func (s *IntSet[T]) Delete(e T) { + if v := encodeZigZag(e); v < bits.UintSize { + s.bits.delete(v) + } else { + hi, lo := v/uint64(bits.UintSize), v%uint64(bits.UintSize) + if bs := s.extra[hi]; bs.contains(lo) { + bs.delete(lo) + mak.Set(&s.extra, hi, bs) + s.extra[hi] = bs + s.extraLen-- + } + } +} + +// DeleteSeq deletes the values in seq from the set. +func (s *IntSet[T]) DeleteSeq(seq iter.Seq[T]) { + for e := range seq { + s.Delete(e) + } +} + +// Equal reports whether s is equal to other. +func (s IntSet[T]) Equal(other IntSet[T]) bool { + for hi, bits := range s.extra { + if other.extra[hi] != bits { + return false + } + } + return s.extraLen == other.extraLen && s.bits == other.bits +} + +// Clone returns a copy of s that doesn't alias the original. +func (s IntSet[T]) Clone() IntSet[T] { + return IntSet[T]{ + bits: s.bits, + extra: maps.Clone(s.extra), + extraLen: s.extraLen, + } +} + +type bitSet uint + +func (s bitSet) values() iter.Seq[uint64] { + return func(yield func(uint64) bool) { + // Hyrum-proofing: randomly iterate in forwards or reverse. + if rand.Uint64()%2 == 0 { + for i := 0; i < bits.UintSize; i++ { + if s.contains(uint64(i)) && !yield(uint64(i)) { + return + } + } + } else { + for i := bits.UintSize; i >= 0; i-- { + if s.contains(uint64(i)) && !yield(uint64(i)) { + return + } + } + } + } +} +func (s bitSet) len() int { return bits.OnesCount(uint(s)) } +func (s bitSet) contains(i uint64) bool { return s&(1< 0 } +func (s *bitSet) add(i uint64) { *s |= 1 << i } +func (s *bitSet) delete(i uint64) { *s &= ^(1 << i) } + +// encodeZigZag encodes an integer as an unsigned integer ensuring that +// negative integers near zero still have a near zero positive value. +// For unsigned integers, it returns the value verbatim. +func encodeZigZag[T constraints.Integer](v T) uint64 { + var zero T + if ^zero >= 0 { // must be constraints.Unsigned + return uint64(v) + } else { // must be constraints.Signed + // See [google.golang.org/protobuf/encoding/protowire.EncodeZigZag] + return uint64(int64(v)<<1) ^ uint64(int64(v)>>63) + } +} + +// decodeZigZag decodes an unsigned integer as an integer ensuring that +// negative integers near zero still have a near zero positive value. +// For unsigned integers, it returns the value verbatim. +func decodeZigZag[T constraints.Integer](v uint64) T { + var zero T + if ^zero >= 0 { // must be constraints.Unsigned + return T(v) + } else { // must be constraints.Signed + // See [google.golang.org/protobuf/encoding/protowire.DecodeZigZag] + return T(int64(v>>1) ^ int64(v)<<63>>63) + } +} diff --git a/vendor/tailscale.com/util/set/smallset.go b/vendor/tailscale.com/util/set/smallset.go new file mode 100644 index 0000000..1b77419 --- /dev/null +++ b/vendor/tailscale.com/util/set/smallset.go @@ -0,0 +1,148 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package set + +import ( + "iter" + "maps" + + "tailscale.com/types/structs" +) + +// SmallSet is a set that is optimized for reducing memory overhead when the +// expected size of the set is 0 or 1 elements. +// +// The zero value of SmallSet is a usable empty set. +// +// When storing a SmallSet in a map as a value type, it is important to re-assign +// the map entry after calling Add or Delete, as the SmallSet's representation +// may change. +// +// Copying a SmallSet by value may alias the previous value. Use the Clone method +// to create a new SmallSet with the same contents. +type SmallSet[T comparable] struct { + _ structs.Incomparable // to prevent == mistakes + one T // if non-zero, then single item in set + m Set[T] // if non-nil, the set of items, which might be size 1 if it's the zero value of T +} + +// Values returns an iterator over the elements of the set. +// The iterator will yield the elements in no particular order. +func (s SmallSet[T]) Values() iter.Seq[T] { + if s.m != nil { + return maps.Keys(s.m) + } + var zero T + return func(yield func(T) bool) { + if s.one != zero { + yield(s.one) + } + } +} + +// Contains reports whether e is in the set. +func (s SmallSet[T]) Contains(e T) bool { + if s.m != nil { + return s.m.Contains(e) + } + var zero T + return e != zero && s.one == e +} + +// SoleElement returns the single value in the set, if the set has exactly one +// element. +// +// If the set is empty or has more than one element, ok will be false and e will +// be the zero value of T. +func (s SmallSet[T]) SoleElement() (e T, ok bool) { + return s.one, s.Len() == 1 +} + +// Add adds e to the set. +// +// When storing a SmallSet in a map as a value type, it is important to +// re-assign the map entry after calling Add or Delete, as the SmallSet's +// representation may change. +func (s *SmallSet[T]) Add(e T) { + var zero T + if s.m != nil { + s.m.Add(e) + return + } + // Non-zero elements can go into s.one. + if e != zero { + if s.one == zero { + s.one = e // Len 0 to Len 1 + return + } + if s.one == e { + return // dup + } + } + // Need to make a multi map, either + // because we now have two items, or + // because e is the zero value. + s.m = Set[T]{} + if s.one != zero { + s.m.Add(s.one) // move single item to multi + } + s.m.Add(e) // add new item, possibly zero + s.one = zero +} + +// Len reports the number of elements in the set. +func (s SmallSet[T]) Len() int { + var zero T + if s.m != nil { + return s.m.Len() + } + if s.one != zero { + return 1 + } + return 0 +} + +// Delete removes e from the set. +// +// When storing a SmallSet in a map as a value type, it is important to +// re-assign the map entry after calling Add or Delete, as the SmallSet's +// representation may change. +func (s *SmallSet[T]) Delete(e T) { + var zero T + if s.m == nil { + if s.one == e { + s.one = zero + } + return + } + s.m.Delete(e) + + // If the map size drops to zero, that means + // it only contained the zero value of T. + if s.m.Len() == 0 { + s.m = nil + return + } + + // If the map size drops to one element and doesn't + // contain the zero value, we can switch back to the + // single-item representation. + if s.m.Len() == 1 { + for v := range s.m { + if v != zero { + s.one = v + s.m = nil + } + } + } + return +} + +// Clone returns a copy of s that doesn't alias the original. +func (s SmallSet[T]) Clone() SmallSet[T] { + return SmallSet[T]{ + one: s.one, + m: maps.Clone(s.m), // preserves nilness + } +} diff --git a/vendor/tailscale.com/util/syspolicy/handler.go b/vendor/tailscale.com/util/syspolicy/handler.go deleted file mode 100644 index f511f0a..0000000 --- a/vendor/tailscale.com/util/syspolicy/handler.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package syspolicy - -import ( - "tailscale.com/util/syspolicy/internal" - "tailscale.com/util/syspolicy/rsop" - "tailscale.com/util/syspolicy/setting" - "tailscale.com/util/syspolicy/source" -) - -// TODO(nickkhyl): delete this file once other repos are updated. - -// Handler reads system policies from OS-specific storage. -// -// Deprecated: implementing a [source.Store] should be preferred. -type Handler interface { - // ReadString reads the policy setting's string value for the given key. - // It should return ErrNoSuchKey if the key does not have a value set. - ReadString(key string) (string, error) - // ReadUInt64 reads the policy setting's uint64 value for the given key. - // It should return ErrNoSuchKey if the key does not have a value set. - ReadUInt64(key string) (uint64, error) - // ReadBool reads the policy setting's boolean value for the given key. - // It should return ErrNoSuchKey if the key does not have a value set. - ReadBoolean(key string) (bool, error) - // ReadStringArray reads the policy setting's string array value for the given key. - // It should return ErrNoSuchKey if the key does not have a value set. - ReadStringArray(key string) ([]string, error) -} - -// RegisterHandler wraps and registers the specified handler as the device's -// policy [source.Store] for the program's lifetime. -// -// Deprecated: using [RegisterStore] should be preferred. -func RegisterHandler(h Handler) { - rsop.RegisterStore("DeviceHandler", setting.DeviceScope, WrapHandler(h)) -} - -// TB is a subset of testing.TB that we use to set up test helpers. -// It's defined here to avoid pulling in the testing package. -type TB = internal.TB - -// SetHandlerForTest wraps and sets the specified handler as the device's policy -// [source.Store] for the duration of tb. -// -// Deprecated: using [MustRegisterStoreForTest] should be preferred. -func SetHandlerForTest(tb TB, h Handler) { - RegisterWellKnownSettingsForTest(tb) - MustRegisterStoreForTest(tb, "DeviceHandler-TestOnly", setting.DefaultScope(), WrapHandler(h)) -} - -var _ source.Store = (*handlerStore)(nil) - -// handlerStore is a [source.Store] that calls the underlying [Handler]. -// -// TODO(nickkhyl): remove it when the corp and android repos are updated. -type handlerStore struct { - h Handler -} - -// WrapHandler returns a [source.Store] that wraps the specified [Handler]. -func WrapHandler(h Handler) source.Store { - return handlerStore{h} -} - -// Lock implements [source.Lockable]. -func (s handlerStore) Lock() error { - if lockable, ok := s.h.(source.Lockable); ok { - return lockable.Lock() - } - return nil -} - -// Unlock implements [source.Lockable]. -func (s handlerStore) Unlock() { - if lockable, ok := s.h.(source.Lockable); ok { - lockable.Unlock() - } -} - -// RegisterChangeCallback implements [source.Changeable]. -func (s handlerStore) RegisterChangeCallback(callback func()) (unregister func(), err error) { - if changeable, ok := s.h.(source.Changeable); ok { - return changeable.RegisterChangeCallback(callback) - } - return func() {}, nil -} - -// ReadString implements [source.Store]. -func (s handlerStore) ReadString(key setting.Key) (string, error) { - return s.h.ReadString(string(key)) -} - -// ReadUInt64 implements [source.Store]. -func (s handlerStore) ReadUInt64(key setting.Key) (uint64, error) { - return s.h.ReadUInt64(string(key)) -} - -// ReadBoolean implements [source.Store]. -func (s handlerStore) ReadBoolean(key setting.Key) (bool, error) { - return s.h.ReadBoolean(string(key)) -} - -// ReadStringArray implements [source.Store]. -func (s handlerStore) ReadStringArray(key setting.Key) ([]string, error) { - return s.h.ReadStringArray(string(key)) -} - -// Done implements [source.Expirable]. -func (s handlerStore) Done() <-chan struct{} { - if expirable, ok := s.h.(source.Expirable); ok { - return expirable.Done() - } - return nil -} diff --git a/vendor/tailscale.com/util/syspolicy/internal/internal.go b/vendor/tailscale.com/util/syspolicy/internal/internal.go index 2e1737e..6ab147d 100644 --- a/vendor/tailscale.com/util/syspolicy/internal/internal.go +++ b/vendor/tailscale.com/util/syspolicy/internal/internal.go @@ -10,6 +10,7 @@ import ( "github.com/go-json-experiment/json/jsontext" "tailscale.com/types/lazy" + "tailscale.com/util/testenv" "tailscale.com/version" ) @@ -25,22 +26,10 @@ func OS() string { return OSForTesting.Get(version.OS) } -// TB is a subset of testing.TB that we use to set up test helpers. -// It's defined here to avoid pulling in the testing package. -type TB interface { - Helper() - Cleanup(func()) - Logf(format string, args ...any) - Error(args ...any) - Errorf(format string, args ...any) - Fatal(args ...any) - Fatalf(format string, args ...any) -} - // EqualJSONForTest compares the JSON in j1 and j2 for semantic equality. // It returns "", "", true if j1 and j2 are equal. Otherwise, it returns // indented versions of j1 and j2 and false. -func EqualJSONForTest(tb TB, j1, j2 jsontext.Value) (s1, s2 string, equal bool) { +func EqualJSONForTest(tb testenv.TB, j1, j2 jsontext.Value) (s1, s2 string, equal bool) { tb.Helper() j1 = j1.Clone() j2 = j2.Clone() diff --git a/vendor/tailscale.com/util/syspolicy/internal/loggerx/logger.go b/vendor/tailscale.com/util/syspolicy/internal/loggerx/logger.go index c29a5f0..d1f48cb 100644 --- a/vendor/tailscale.com/util/syspolicy/internal/loggerx/logger.go +++ b/vendor/tailscale.com/util/syspolicy/internal/loggerx/logger.go @@ -10,7 +10,7 @@ import ( "tailscale.com/types/lazy" "tailscale.com/types/logger" - "tailscale.com/util/syspolicy/internal" + "tailscale.com/util/testenv" ) const ( @@ -58,7 +58,7 @@ func verbosef(format string, args ...any) { // SetForTest sets the specified printf and verbosef functions for the duration // of tb and its subtests. -func SetForTest(tb internal.TB, printf, verbosef logger.Logf) { +func SetForTest(tb testenv.TB, printf, verbosef logger.Logf) { lazyPrintf.SetForTest(tb, printf, nil) lazyVerbosef.SetForTest(tb, verbosef, nil) } diff --git a/vendor/tailscale.com/util/syspolicy/internal/metrics/metrics.go b/vendor/tailscale.com/util/syspolicy/internal/metrics/metrics.go index 770a34d..8f27456 100644 --- a/vendor/tailscale.com/util/syspolicy/internal/metrics/metrics.go +++ b/vendor/tailscale.com/util/syspolicy/internal/metrics/metrics.go @@ -17,6 +17,7 @@ import ( "tailscale.com/util/slicesx" "tailscale.com/util/syspolicy/internal" "tailscale.com/util/syspolicy/internal/loggerx" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" "tailscale.com/util/testenv" ) @@ -209,7 +210,7 @@ func scopeMetrics(origin *setting.Origin) *policyScopeMetrics { var ( settingMetricsMu sync.RWMutex - settingMetricsMap map[setting.Key]*settingMetrics + settingMetricsMap map[pkey.Key]*settingMetrics ) func settingMetricsFor(setting *setting.Definition) *settingMetrics { @@ -259,7 +260,7 @@ var addMetricTestHook, setMetricTestHook syncs.AtomicValue[metricFn] // SetHooksForTest sets the specified addMetric and setMetric functions // as the metric functions for the duration of tb and all its subtests. -func SetHooksForTest(tb internal.TB, addMetric, setMetric metricFn) { +func SetHooksForTest(tb testenv.TB, addMetric, setMetric metricFn) { oldAddMetric := addMetricTestHook.Swap(addMetric) oldSetMetric := setMetricTestHook.Swap(setMetric) tb.Cleanup(func() { @@ -283,8 +284,8 @@ func SetHooksForTest(tb internal.TB, addMetric, setMetric metricFn) { lazyUserMetrics.SetForTest(tb, newScopeMetrics(setting.UserSetting), nil) } -func newSettingMetric(key setting.Key, scope setting.Scope, suffix string, typ clientmetric.Type) metric { - name := strings.ReplaceAll(string(key), string(setting.KeyPathSeparator), "_") +func newSettingMetric(key pkey.Key, scope setting.Scope, suffix string, typ clientmetric.Type) metric { + name := strings.ReplaceAll(string(key), string(pkey.KeyPathSeparator), "_") name = strings.ReplaceAll(name, ".", "_") // dots are not allowed in metric names return newMetric([]string{name, metricScopeName(scope), suffix}, typ) } diff --git a/vendor/tailscale.com/util/syspolicy/internal/metrics/test_handler.go b/vendor/tailscale.com/util/syspolicy/internal/metrics/test_handler.go index f9e4846..36c3f2c 100644 --- a/vendor/tailscale.com/util/syspolicy/internal/metrics/test_handler.go +++ b/vendor/tailscale.com/util/syspolicy/internal/metrics/test_handler.go @@ -9,6 +9,7 @@ import ( "tailscale.com/util/clientmetric" "tailscale.com/util/set" "tailscale.com/util/syspolicy/internal" + "tailscale.com/util/testenv" ) // TestState represents a metric name and its expected value. @@ -19,13 +20,13 @@ type TestState struct { // TestHandler facilitates testing of the code that uses metrics. type TestHandler struct { - t internal.TB + t testenv.TB m map[string]int64 } // NewTestHandler returns a new TestHandler. -func NewTestHandler(t internal.TB) *TestHandler { +func NewTestHandler(t testenv.TB) *TestHandler { return &TestHandler{t, make(map[string]int64)} } diff --git a/vendor/tailscale.com/util/syspolicy/pkey/pkey.go b/vendor/tailscale.com/util/syspolicy/pkey/pkey.go new file mode 100644 index 0000000..e450625 --- /dev/null +++ b/vendor/tailscale.com/util/syspolicy/pkey/pkey.go @@ -0,0 +1,190 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package pkey defines the keys used to store system policies in the registry. +// +// This is a leaf package meant to only contain string constants, not code. +package pkey + +// Key is a string that uniquely identifies a policy and must remain unchanged +// once established and documented for a given policy setting. It may contain +// alphanumeric characters and zero or more [KeyPathSeparator]s to group +// individual policy settings into categories. +type Key string + +// KeyPathSeparator allows logical grouping of policy settings into categories. +const KeyPathSeparator = '/' + +// The const block below lists known policy keys. +// When adding a key to this list, remember to add a corresponding +// [setting.Definition] to [implicitDefinitions] in util/syspolicy/policy_keys.go. +// Otherwise, the [TestKnownKeysRegistered] test will fail as a reminder. + +const ( + // Keys with a string value + ControlURL Key = "LoginURL" // default ""; if blank, ipn uses ipn.DefaultControlURL. + LogTarget Key = "LogTarget" // default ""; if blank logging uses logtail.DefaultHost. + Tailnet Key = "Tailnet" // default ""; if blank, no tailnet name is sent to the server. + + // AlwaysOn is a boolean key that controls whether Tailscale + // should always remain in a connected state, and the user should + // not be able to disconnect at their discretion. + // + // Warning: This policy setting is experimental and may change or be removed in the future. + // It may also not be fully supported by all Tailscale clients until it is out of experimental status. + // See tailscale/corp#26247, tailscale/corp#26248 and tailscale/corp#26249 for more information. + AlwaysOn Key = "AlwaysOn.Enabled" + + // AlwaysOnOverrideWithReason is a boolean key that alters the behavior + // of [AlwaysOn]. When true, the user is allowed to disconnect Tailscale + // by providing a reason. The reason is logged and sent to the control + // for auditing purposes. It has no effect when [AlwaysOn] is false. + AlwaysOnOverrideWithReason Key = "AlwaysOn.OverrideWithReason" + + // ReconnectAfter is a string value formatted for use with time.ParseDuration() + // that defines the duration after which the client should automatically reconnect + // to the Tailscale network following a user-initiated disconnect. + // An empty string or a zero duration disables automatic reconnection. + ReconnectAfter Key = "ReconnectAfter" + + // AllowTailscaledRestart is a boolean key that controls whether users with write access + // to the LocalAPI are allowed to shutdown tailscaled with the intention of restarting it. + // On Windows, tailscaled will be restarted automatically by the service process + // (see babysitProc in cmd/tailscaled/tailscaled_windows.go). + // On other platforms, it is the client's responsibility to restart tailscaled. + AllowTailscaledRestart Key = "AllowTailscaledRestart" + + // ExitNodeID is the exit node's node id. default ""; if blank, no exit node is forced. + // Exit node ID takes precedence over exit node IP. + // To find the node ID, go to /api.md#device. + ExitNodeID Key = "ExitNodeID" + ExitNodeIP Key = "ExitNodeIP" // default ""; if blank, no exit node is forced. Value is exit node IP. + + // AllowExitNodeOverride is a boolean key that allows the user to override exit node policy settings + // and manually select an exit node. It does not allow disabling exit node usage entirely. + // It is typically used in conjunction with [ExitNodeID] set to "auto:any". + // + // Warning: This policy setting is experimental and may change, be renamed or removed in the future. + // It may also not be fully supported by all Tailscale clients until it is out of experimental status. + // See tailscale/corp#29969. + AllowExitNodeOverride Key = "ExitNode.AllowOverride" + + // Keys with a string value that specifies an option: "always", "never", "user-decides". + // The default is "user-decides" unless otherwise stated. Enforcement of + // these policies is typically performed in ipnlocal.applySysPolicy(). GUIs + // typically hide menu items related to policies that are enforced. + EnableIncomingConnections Key = "AllowIncomingConnections" + EnableServerMode Key = "UnattendedMode" + ExitNodeAllowLANAccess Key = "ExitNodeAllowLANAccess" + EnableTailscaleDNS Key = "UseTailscaleDNSSettings" + EnableTailscaleSubnets Key = "UseTailscaleSubnets" + + // EnableDNSRegistration is a string value that can be set to "always", "never" + // or "user-decides". It controls whether DNS registration and dynamic DNS + // updates are enabled for the Tailscale interface. For historical reasons + // and to maintain compatibility with existing setups, the default is "never". + // It is only used on Windows. + EnableDNSRegistration Key = "EnableDNSRegistration" + + // CheckUpdates is the key to signal if the updater should periodically + // check for updates. + CheckUpdates Key = "CheckUpdates" + // ApplyUpdates is the key to signal if updates should be automatically + // installed. Its value is "InstallUpdates" because of an awkwardly-named + // visibility option "ApplyUpdates" on MacOS. + ApplyUpdates Key = "InstallUpdates" + // EnableRunExitNode controls if the device acts as an exit node. Even when + // running as an exit node, the device must be approved by a tailnet + // administrator. Its name is slightly awkward because RunExitNodeVisibility + // predates this option but is preserved for backwards compatibility. + EnableRunExitNode Key = "AdvertiseExitNode" + + // Keys with a string value that controls visibility: "show", "hide". + // The default is "show" unless otherwise stated. Enforcement of these + // policies is typically performed by the UI code for the relevant operating + // system. + AdminConsoleVisibility Key = "AdminConsole" + NetworkDevicesVisibility Key = "NetworkDevices" + TestMenuVisibility Key = "TestMenu" + UpdateMenuVisibility Key = "UpdateMenu" + ResetToDefaultsVisibility Key = "ResetToDefaults" + // RunExitNodeVisibility controls if the "run as exit node" menu item is + // visible, without controlling the setting itself. This is preserved for + // backwards compatibility but prefer EnableRunExitNode in new deployments. + RunExitNodeVisibility Key = "RunExitNode" + PreferencesMenuVisibility Key = "PreferencesMenu" + ExitNodeMenuVisibility Key = "ExitNodesPicker" + // AutoUpdateVisibility is the key to signal if the menu item for automatic + // installation of updates should be visible. It is only used by macsys + // installations and uses the Sparkle naming convention, even though it does + // not actually control updates, merely the UI for that setting. + AutoUpdateVisibility Key = "ApplyUpdates" + // SuggestedExitNodeVisibility controls the visibility of suggested exit nodes in the client GUI. + // When this system policy is set to 'hide', an exit node suggestion won't be presented to the user as part of the exit nodes picker. + SuggestedExitNodeVisibility Key = "SuggestedExitNode" + // OnboardingFlowVisibility controls the visibility of the onboarding flow in the client GUI. + // When this system policy is set to 'hide', the onboarding flow is never shown to the user. + OnboardingFlowVisibility Key = "OnboardingFlow" + + // Keys with a string value formatted for use with time.ParseDuration(). + KeyExpirationNoticeTime Key = "KeyExpirationNotice" // default 24 hours + + // Boolean Keys that are only applicable on Windows. Booleans are stored in the registry as + // DWORD or QWORD (either is acceptable). 0 means false, and anything else means true. + // The default is 0 unless otherwise stated. + LogSCMInteractions Key = "LogSCMInteractions" + FlushDNSOnSessionUnlock Key = "FlushDNSOnSessionUnlock" + + // EncryptState is a boolean setting that specifies whether to encrypt the + // tailscaled state file. + // Windows and Linux use a TPM device, Apple uses the Keychain. + // It's a noop on other platforms. + EncryptState Key = "EncryptState" + + // HardwareAttestation is a boolean key that controls whether to use a + // hardware-backed key to bind the node identity to this device. + HardwareAttestation Key = "HardwareAttestation" + + // PostureChecking indicates if posture checking is enabled and the client shall gather + // posture data. + // Key is a string value that specifies an option: "always", "never", "user-decides". + // The default is "user-decides" unless otherwise stated. + PostureChecking Key = "PostureChecking" + // DeviceSerialNumber is the serial number of the device that is running Tailscale. + // This is used on Android, iOS and tvOS to allow IT administrators to manually give us a serial number via MDM. + // We are unable to programmatically get the serial number on mobile due to sandboxing restrictions. + DeviceSerialNumber Key = "DeviceSerialNumber" + + // ManagedByOrganizationName indicates the name of the organization managing the Tailscale + // install. It is displayed inside the client UI in a prominent location. + ManagedByOrganizationName Key = "ManagedByOrganizationName" + // ManagedByCaption is an info message displayed inside the client UI as a caption when + // ManagedByOrganizationName is set. It can be used to provide a pointer to support resources + // for Tailscale within the organization. + ManagedByCaption Key = "ManagedByCaption" + // ManagedByURL is a valid URL pointing to a support help desk for Tailscale within the + // organization. A button in the client UI provides easy access to this URL. + ManagedByURL Key = "ManagedByURL" + + // AuthKey is an auth key that will be used to login whenever the backend starts. This can be used to + // automatically authenticate managed devices, without requiring user interaction. + AuthKey Key = "AuthKey" + + // MachineCertificateSubject is the exact name of a Subject that needs + // to be present in an identity's certificate chain to sign a RegisterRequest, + // formatted as per pkix.Name.String(). The Subject may be that of the identity + // itself, an intermediate CA or the root CA. + // + // Example: "CN=Tailscale Inc Test Root CA,OU=Tailscale Inc Test Certificate Authority,O=Tailscale Inc,ST=ON,C=CA" + MachineCertificateSubject Key = "MachineCertificateSubject" + + // Hostname is the hostname of the device that is running Tailscale. + // When this policy is set, it overrides the hostname that the client + // would otherwise obtain from the OS, e.g. by calling os.Hostname(). + Hostname Key = "Hostname" + + // Keys with a string array value. + + // AllowedSuggestedExitNodes's string array value is a list of exit node IDs that restricts which exit nodes are considered when generating suggestions for exit nodes. + AllowedSuggestedExitNodes Key = "AllowedSuggestedExitNodes" +) diff --git a/vendor/tailscale.com/util/syspolicy/policy_keys.go b/vendor/tailscale.com/util/syspolicy/policy_keys.go index a81c1e5..3a54f9d 100644 --- a/vendor/tailscale.com/util/syspolicy/policy_keys.go +++ b/vendor/tailscale.com/util/syspolicy/policy_keys.go @@ -4,203 +4,63 @@ package syspolicy import ( - "tailscale.com/types/lazy" "tailscale.com/util/syspolicy/internal" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" "tailscale.com/util/testenv" ) -// Key is a string that uniquely identifies a policy and must remain unchanged -// once established and documented for a given policy setting. It may contain -// alphanumeric characters and zero or more [KeyPathSeparator]s to group -// individual policy settings into categories. -type Key = setting.Key - -// The const block below lists known policy keys. -// When adding a key to this list, remember to add a corresponding -// [setting.Definition] to [implicitDefinitions] below. -// Otherwise, the [TestKnownKeysRegistered] test will fail as a reminder. - -const ( - // Keys with a string value - ControlURL Key = "LoginURL" // default ""; if blank, ipn uses ipn.DefaultControlURL. - LogTarget Key = "LogTarget" // default ""; if blank logging uses logtail.DefaultHost. - Tailnet Key = "Tailnet" // default ""; if blank, no tailnet name is sent to the server. - - // AlwaysOn is a boolean key that controls whether Tailscale - // should always remain in a connected state, and the user should - // not be able to disconnect at their discretion. - // - // Warning: This policy setting is experimental and may change or be removed in the future. - // It may also not be fully supported by all Tailscale clients until it is out of experimental status. - // See tailscale/corp#26247, tailscale/corp#26248 and tailscale/corp#26249 for more information. - AlwaysOn Key = "AlwaysOn.Enabled" - - // AlwaysOnOverrideWithReason is a boolean key that alters the behavior - // of [AlwaysOn]. When true, the user is allowed to disconnect Tailscale - // by providing a reason. The reason is logged and sent to the control - // for auditing purposes. It has no effect when [AlwaysOn] is false. - AlwaysOnOverrideWithReason Key = "AlwaysOn.OverrideWithReason" - - // ReconnectAfter is a string value formatted for use with time.ParseDuration() - // that defines the duration after which the client should automatically reconnect - // to the Tailscale network following a user-initiated disconnect. - // An empty string or a zero duration disables automatic reconnection. - ReconnectAfter Key = "ReconnectAfter" - - // ExitNodeID is the exit node's node id. default ""; if blank, no exit node is forced. - // Exit node ID takes precedence over exit node IP. - // To find the node ID, go to /api.md#device. - ExitNodeID Key = "ExitNodeID" - ExitNodeIP Key = "ExitNodeIP" // default ""; if blank, no exit node is forced. Value is exit node IP. - - // Keys with a string value that specifies an option: "always", "never", "user-decides". - // The default is "user-decides" unless otherwise stated. Enforcement of - // these policies is typically performed in ipnlocal.applySysPolicy(). GUIs - // typically hide menu items related to policies that are enforced. - EnableIncomingConnections Key = "AllowIncomingConnections" - EnableServerMode Key = "UnattendedMode" - ExitNodeAllowLANAccess Key = "ExitNodeAllowLANAccess" - EnableTailscaleDNS Key = "UseTailscaleDNSSettings" - EnableTailscaleSubnets Key = "UseTailscaleSubnets" - // CheckUpdates is the key to signal if the updater should periodically - // check for updates. - CheckUpdates Key = "CheckUpdates" - // ApplyUpdates is the key to signal if updates should be automatically - // installed. Its value is "InstallUpdates" because of an awkwardly-named - // visibility option "ApplyUpdates" on MacOS. - ApplyUpdates Key = "InstallUpdates" - // EnableRunExitNode controls if the device acts as an exit node. Even when - // running as an exit node, the device must be approved by a tailnet - // administrator. Its name is slightly awkward because RunExitNodeVisibility - // predates this option but is preserved for backwards compatibility. - EnableRunExitNode Key = "AdvertiseExitNode" - - // Keys with a string value that controls visibility: "show", "hide". - // The default is "show" unless otherwise stated. Enforcement of these - // policies is typically performed by the UI code for the relevant operating - // system. - AdminConsoleVisibility Key = "AdminConsole" - NetworkDevicesVisibility Key = "NetworkDevices" - TestMenuVisibility Key = "TestMenu" - UpdateMenuVisibility Key = "UpdateMenu" - ResetToDefaultsVisibility Key = "ResetToDefaults" - // RunExitNodeVisibility controls if the "run as exit node" menu item is - // visible, without controlling the setting itself. This is preserved for - // backwards compatibility but prefer EnableRunExitNode in new deployments. - RunExitNodeVisibility Key = "RunExitNode" - PreferencesMenuVisibility Key = "PreferencesMenu" - ExitNodeMenuVisibility Key = "ExitNodesPicker" - // AutoUpdateVisibility is the key to signal if the menu item for automatic - // installation of updates should be visible. It is only used by macsys - // installations and uses the Sparkle naming convention, even though it does - // not actually control updates, merely the UI for that setting. - AutoUpdateVisibility Key = "ApplyUpdates" - // SuggestedExitNodeVisibility controls the visibility of suggested exit nodes in the client GUI. - // When this system policy is set to 'hide', an exit node suggestion won't be presented to the user as part of the exit nodes picker. - SuggestedExitNodeVisibility Key = "SuggestedExitNode" - // OnboardingFlowVisibility controls the visibility of the onboarding flow in the client GUI. - // When this system policy is set to 'hide', the onboarding flow is never shown to the user. - OnboardingFlowVisibility Key = "OnboardingFlow" - - // Keys with a string value formatted for use with time.ParseDuration(). - KeyExpirationNoticeTime Key = "KeyExpirationNotice" // default 24 hours - - // Boolean Keys that are only applicable on Windows. Booleans are stored in the registry as - // DWORD or QWORD (either is acceptable). 0 means false, and anything else means true. - // The default is 0 unless otherwise stated. - LogSCMInteractions Key = "LogSCMInteractions" - FlushDNSOnSessionUnlock Key = "FlushDNSOnSessionUnlock" - - // PostureChecking indicates if posture checking is enabled and the client shall gather - // posture data. - // Key is a string value that specifies an option: "always", "never", "user-decides". - // The default is "user-decides" unless otherwise stated. - PostureChecking Key = "PostureChecking" - // DeviceSerialNumber is the serial number of the device that is running Tailscale. - // This is used on iOS/tvOS to allow IT administrators to manually give us a serial number via MDM. - // We are unable to programmatically get the serial number from IOKit due to sandboxing restrictions. - DeviceSerialNumber Key = "DeviceSerialNumber" - - // ManagedByOrganizationName indicates the name of the organization managing the Tailscale - // install. It is displayed inside the client UI in a prominent location. - ManagedByOrganizationName Key = "ManagedByOrganizationName" - // ManagedByCaption is an info message displayed inside the client UI as a caption when - // ManagedByOrganizationName is set. It can be used to provide a pointer to support resources - // for Tailscale within the organization. - ManagedByCaption Key = "ManagedByCaption" - // ManagedByURL is a valid URL pointing to a support help desk for Tailscale within the - // organization. A button in the client UI provides easy access to this URL. - ManagedByURL Key = "ManagedByURL" - - // AuthKey is an auth key that will be used to login whenever the backend starts. This can be used to - // automatically authenticate managed devices, without requiring user interaction. - AuthKey Key = "AuthKey" - - // MachineCertificateSubject is the exact name of a Subject that needs - // to be present in an identity's certificate chain to sign a RegisterRequest, - // formatted as per pkix.Name.String(). The Subject may be that of the identity - // itself, an intermediate CA or the root CA. - // - // Example: "CN=Tailscale Inc Test Root CA,OU=Tailscale Inc Test Certificate Authority,O=Tailscale Inc,ST=ON,C=CA" - MachineCertificateSubject Key = "MachineCertificateSubject" - - // Hostname is the hostname of the device that is running Tailscale. - // When this policy is set, it overrides the hostname that the client - // would otherwise obtain from the OS, e.g. by calling os.Hostname(). - Hostname Key = "Hostname" - - // Keys with a string array value. - // AllowedSuggestedExitNodes's string array value is a list of exit node IDs that restricts which exit nodes are considered when generating suggestions for exit nodes. - AllowedSuggestedExitNodes Key = "AllowedSuggestedExitNodes" -) - // implicitDefinitions is a list of [setting.Definition] that will be registered // automatically when the policy setting definitions are first used by the syspolicy package hierarchy. // This includes the first time a policy needs to be read from any source. var implicitDefinitions = []*setting.Definition{ // Device policy settings (can only be configured on a per-device basis): - setting.NewDefinition(AllowedSuggestedExitNodes, setting.DeviceSetting, setting.StringListValue), - setting.NewDefinition(AlwaysOn, setting.DeviceSetting, setting.BooleanValue), - setting.NewDefinition(AlwaysOnOverrideWithReason, setting.DeviceSetting, setting.BooleanValue), - setting.NewDefinition(ApplyUpdates, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(AuthKey, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(CheckUpdates, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(ControlURL, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(DeviceSerialNumber, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(EnableIncomingConnections, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(EnableRunExitNode, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(EnableServerMode, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(EnableTailscaleDNS, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(EnableTailscaleSubnets, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(ExitNodeAllowLANAccess, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(ExitNodeID, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(ExitNodeIP, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(FlushDNSOnSessionUnlock, setting.DeviceSetting, setting.BooleanValue), - setting.NewDefinition(Hostname, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(LogSCMInteractions, setting.DeviceSetting, setting.BooleanValue), - setting.NewDefinition(LogTarget, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(MachineCertificateSubject, setting.DeviceSetting, setting.StringValue), - setting.NewDefinition(PostureChecking, setting.DeviceSetting, setting.PreferenceOptionValue), - setting.NewDefinition(ReconnectAfter, setting.DeviceSetting, setting.DurationValue), - setting.NewDefinition(Tailnet, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.AllowedSuggestedExitNodes, setting.DeviceSetting, setting.StringListValue), + setting.NewDefinition(pkey.AllowExitNodeOverride, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.AllowTailscaledRestart, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.AlwaysOn, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.AlwaysOnOverrideWithReason, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.ApplyUpdates, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.AuthKey, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.CheckUpdates, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.ControlURL, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.DeviceSerialNumber, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.EnableDNSRegistration, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.EnableIncomingConnections, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.EnableRunExitNode, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.EnableServerMode, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.EnableTailscaleDNS, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.EnableTailscaleSubnets, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.ExitNodeAllowLANAccess, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.ExitNodeID, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.ExitNodeIP, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.FlushDNSOnSessionUnlock, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.EncryptState, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.Hostname, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.LogSCMInteractions, setting.DeviceSetting, setting.BooleanValue), + setting.NewDefinition(pkey.LogTarget, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.MachineCertificateSubject, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.PostureChecking, setting.DeviceSetting, setting.PreferenceOptionValue), + setting.NewDefinition(pkey.ReconnectAfter, setting.DeviceSetting, setting.DurationValue), + setting.NewDefinition(pkey.Tailnet, setting.DeviceSetting, setting.StringValue), + setting.NewDefinition(pkey.HardwareAttestation, setting.DeviceSetting, setting.BooleanValue), // User policy settings (can be configured on a user- or device-basis): - setting.NewDefinition(AdminConsoleVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(AutoUpdateVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(ExitNodeMenuVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(KeyExpirationNoticeTime, setting.UserSetting, setting.DurationValue), - setting.NewDefinition(ManagedByCaption, setting.UserSetting, setting.StringValue), - setting.NewDefinition(ManagedByOrganizationName, setting.UserSetting, setting.StringValue), - setting.NewDefinition(ManagedByURL, setting.UserSetting, setting.StringValue), - setting.NewDefinition(NetworkDevicesVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(PreferencesMenuVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(ResetToDefaultsVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(RunExitNodeVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(SuggestedExitNodeVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(TestMenuVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(UpdateMenuVisibility, setting.UserSetting, setting.VisibilityValue), - setting.NewDefinition(OnboardingFlowVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.AdminConsoleVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.AutoUpdateVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.ExitNodeMenuVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.KeyExpirationNoticeTime, setting.UserSetting, setting.DurationValue), + setting.NewDefinition(pkey.ManagedByCaption, setting.UserSetting, setting.StringValue), + setting.NewDefinition(pkey.ManagedByOrganizationName, setting.UserSetting, setting.StringValue), + setting.NewDefinition(pkey.ManagedByURL, setting.UserSetting, setting.StringValue), + setting.NewDefinition(pkey.NetworkDevicesVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.PreferencesMenuVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.ResetToDefaultsVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.RunExitNodeVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.SuggestedExitNodeVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.TestMenuVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.UpdateMenuVisibility, setting.UserSetting, setting.VisibilityValue), + setting.NewDefinition(pkey.OnboardingFlowVisibility, setting.UserSetting, setting.VisibilityValue), } func init() { @@ -218,31 +78,3 @@ func init() { return nil }) } - -var implicitDefinitionMap lazy.SyncValue[setting.DefinitionMap] - -// WellKnownSettingDefinition returns a well-known, implicit setting definition by its key, -// or an [ErrNoSuchKey] if a policy setting with the specified key does not exist -// among implicit policy definitions. -func WellKnownSettingDefinition(k Key) (*setting.Definition, error) { - m, err := implicitDefinitionMap.GetErr(func() (setting.DefinitionMap, error) { - return setting.DefinitionMapOf(implicitDefinitions) - }) - if err != nil { - return nil, err - } - if d, ok := m[k]; ok { - return d, nil - } - return nil, ErrNoSuchKey -} - -// RegisterWellKnownSettingsForTest registers all implicit setting definitions -// for the duration of the test. -func RegisterWellKnownSettingsForTest(tb TB) { - tb.Helper() - err := setting.SetDefinitionsForTest(tb, implicitDefinitions...) - if err != nil { - tb.Fatalf("Failed to register well-known settings: %v", err) - } -} diff --git a/vendor/tailscale.com/util/syspolicy/policyclient/policyclient.go b/vendor/tailscale.com/util/syspolicy/policyclient/policyclient.go new file mode 100644 index 0000000..728a167 --- /dev/null +++ b/vendor/tailscale.com/util/syspolicy/policyclient/policyclient.go @@ -0,0 +1,145 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package policyclient contains the minimal syspolicy interface as needed by +// client code using syspolicy. It's the part that's always linked in, even if the rest +// of syspolicy is omitted from the build. +package policyclient + +import ( + "time" + + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/ptype" + "tailscale.com/util/testenv" +) + +// Client is the interface between code making questions about the system policy +// and the actual implementation. +type Client interface { + // GetString returns a string policy setting with the specified key, + // or defaultValue (and a nil error) if it does not exist. + GetString(key pkey.Key, defaultValue string) (string, error) + + // GetStringArray returns a string array policy setting with the specified key, + // or defaultValue (and a nil error) if it does not exist. + GetStringArray(key pkey.Key, defaultValue []string) ([]string, error) + + // GetBoolean returns a boolean policy setting with the specified key, + // or defaultValue (and a nil error) if it does not exist. + GetBoolean(key pkey.Key, defaultValue bool) (bool, error) + + // GetUint64 returns a numeric policy setting with the specified key, + // or defaultValue (and a nil error) if it does not exist. + GetUint64(key pkey.Key, defaultValue uint64) (uint64, error) + + // GetDuration loads a policy from the registry that can be managed by an + // enterprise policy management system and describes a duration for some + // action. The registry value should be a string that time.ParseDuration + // understands. If the registry value is "" or can not be processed, + // defaultValue (and a nil error) is returned instead. + GetDuration(key pkey.Key, defaultValue time.Duration) (time.Duration, error) + + // GetPreferenceOption loads a policy from the registry that can be + // managed by an enterprise policy management system and allows administrative + // overrides of users' choices in a way that we do not want tailcontrol to have + // the authority to set. It describes user-decides/always/never options, where + // "always" and "never" remove the user's ability to make a selection. If not + // present or set to a different value, defaultValue (and a nil error) is returned. + GetPreferenceOption(key pkey.Key, defaultValue ptype.PreferenceOption) (ptype.PreferenceOption, error) + + // GetVisibility returns whether a UI element should be visible based on + // the system's configuration. + // If unconfigured, implementations should return [ptype.VisibleByPolicy] + // and a nil error. + GetVisibility(key pkey.Key) (ptype.Visibility, error) + + // SetDebugLoggingEnabled enables or disables debug logging for the policy client. + SetDebugLoggingEnabled(enabled bool) + + // HasAnyOf returns whether at least one of the specified policy settings is + // configured, or an error if no keys are provided or the check fails. + HasAnyOf(keys ...pkey.Key) (bool, error) + + // RegisterChangeCallback registers a callback function that will be called + // whenever a policy change is detected. It returns a function to unregister + // the callback and an error if the registration fails. + RegisterChangeCallback(cb func(PolicyChange)) (unregister func(), err error) +} + +// Get returns a non-nil [Client] implementation as a function of the +// build tags. It returns a no-op implementation if the full syspolicy +// package is omitted from the build, or in tests. +func Get() Client { + if testenv.InTest() { + // This is a little redundant (the Windows implementation at least + // already does this) but it's here for redundancy and clarity, that we + // don't want to accidentally use the real system policy when running + // tests. + return NoPolicyClient{} + } + return client +} + +// RegisterClientImpl registers a [Client] implementation to be returned by +// [Get]. +func RegisterClientImpl(c Client) { + client = c +} + +var client Client = NoPolicyClient{} + +// PolicyChange is the interface representing a change in policy settings. +type PolicyChange interface { + // HasChanged reports whether the policy setting identified by the given key + // has changed. + HasChanged(pkey.Key) bool + + // HasChangedAnyOf reports whether any of the provided policy settings + // changed in this change. + HasChangedAnyOf(keys ...pkey.Key) bool +} + +// NoPolicyClient is a no-op implementation of [Client] that only +// returns default values. +type NoPolicyClient struct{} + +var _ Client = NoPolicyClient{} + +func (NoPolicyClient) GetBoolean(key pkey.Key, defaultValue bool) (bool, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetString(key pkey.Key, defaultValue string) (string, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetStringArray(key pkey.Key, defaultValue []string) ([]string, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetUint64(key pkey.Key, defaultValue uint64) (uint64, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetDuration(name pkey.Key, defaultValue time.Duration) (time.Duration, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetPreferenceOption(name pkey.Key, defaultValue ptype.PreferenceOption) (ptype.PreferenceOption, error) { + return defaultValue, nil +} + +func (NoPolicyClient) GetVisibility(name pkey.Key) (ptype.Visibility, error) { + return ptype.VisibleByPolicy, nil +} + +func (NoPolicyClient) HasAnyOf(keys ...pkey.Key) (bool, error) { + return false, nil +} + +func (NoPolicyClient) SetDebugLoggingEnabled(enabled bool) {} + +func (NoPolicyClient) RegisterChangeCallback(cb func(PolicyChange)) (unregister func(), err error) { + return func() {}, nil +} diff --git a/vendor/tailscale.com/util/syspolicy/setting/types.go b/vendor/tailscale.com/util/syspolicy/ptype/ptype.go similarity index 88% rename from vendor/tailscale.com/util/syspolicy/setting/types.go rename to vendor/tailscale.com/util/syspolicy/ptype/ptype.go index 9f110ab..65ca9e6 100644 --- a/vendor/tailscale.com/util/syspolicy/setting/types.go +++ b/vendor/tailscale.com/util/syspolicy/ptype/ptype.go @@ -1,11 +1,11 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -package setting - -import ( - "encoding" -) +// Package ptype contains types used by syspolicy. +// +// It's a leaf package for dependency reasons and should not contain much if any +// code, and should not import much (or anything). +package ptype // PreferenceOption is a policy that governs whether a boolean variable // is forcibly assigned an administrator-defined value, or allowed to receive @@ -18,9 +18,10 @@ const ( AlwaysByPolicy ) -// Show returns if the UI option that controls the choice administered by this -// policy should be shown. Currently this is true if and only if the policy is -// [ShowChoiceByPolicy]. +// Show reports whether the UI option that controls the choice administered by +// this policy should be shown (that is, available for users to change). +// +// Currently this is true if and only if the policy is [ShowChoiceByPolicy]. func (p PreferenceOption) Show() bool { return p == ShowChoiceByPolicy } @@ -91,11 +92,6 @@ func (p *PreferenceOption) UnmarshalText(text []byte) error { // component of a user interface is to be shown. type Visibility byte -var ( - _ encoding.TextMarshaler = (*Visibility)(nil) - _ encoding.TextUnmarshaler = (*Visibility)(nil) -) - const ( VisibleByPolicy Visibility = 'v' HiddenByPolicy Visibility = 'h' diff --git a/vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go b/vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go index b962f30..71135bb 100644 --- a/vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go +++ b/vendor/tailscale.com/util/syspolicy/rsop/change_callbacks.go @@ -9,8 +9,12 @@ import ( "sync" "time" + "tailscale.com/syncs" "tailscale.com/util/set" "tailscale.com/util/syspolicy/internal/loggerx" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/util/syspolicy/ptype" "tailscale.com/util/syspolicy/setting" ) @@ -20,7 +24,7 @@ type Change[T any] struct { } // PolicyChangeCallback is a function called whenever a policy changes. -type PolicyChangeCallback func(*PolicyChange) +type PolicyChangeCallback func(policyclient.PolicyChange) // PolicyChange describes a policy change. type PolicyChange struct { @@ -37,8 +41,8 @@ func (c PolicyChange) Old() *setting.Snapshot { return c.snapshots.Old } -// HasChanged reports whether a policy setting with the specified [setting.Key], has changed. -func (c PolicyChange) HasChanged(key setting.Key) bool { +// HasChanged reports whether a policy setting with the specified [pkey.Key], has changed. +func (c PolicyChange) HasChanged(key pkey.Key) bool { new, newErr := c.snapshots.New.GetErr(key) old, oldErr := c.snapshots.Old.GetErr(key) if newErr != nil && oldErr != nil { @@ -48,7 +52,7 @@ func (c PolicyChange) HasChanged(key setting.Key) bool { return true } switch newVal := new.(type) { - case bool, uint64, string, setting.Visibility, setting.PreferenceOption, time.Duration: + case bool, uint64, string, ptype.Visibility, ptype.PreferenceOption, time.Duration: return newVal != old case []string: oldVal, ok := old.([]string) @@ -59,10 +63,15 @@ func (c PolicyChange) HasChanged(key setting.Key) bool { } } +// HasChangedAnyOf reports whether any of the specified policy settings has changed. +func (c PolicyChange) HasChangedAnyOf(keys ...pkey.Key) bool { + return slices.ContainsFunc(keys, c.HasChanged) +} + // policyChangeCallbacks are the callbacks to invoke when the effective policy changes. // It is safe for concurrent use. type policyChangeCallbacks struct { - mu sync.Mutex + mu syncs.Mutex cbs set.HandleSet[PolicyChangeCallback] } diff --git a/vendor/tailscale.com/util/syspolicy/rsop/resultant_policy.go b/vendor/tailscale.com/util/syspolicy/rsop/resultant_policy.go index b811a00..bdda909 100644 --- a/vendor/tailscale.com/util/syspolicy/rsop/resultant_policy.go +++ b/vendor/tailscale.com/util/syspolicy/rsop/resultant_policy.go @@ -7,13 +7,13 @@ import ( "errors" "fmt" "slices" - "sync" "sync/atomic" "time" - "tailscale.com/util/syspolicy/internal" + "tailscale.com/syncs" "tailscale.com/util/syspolicy/internal/loggerx" "tailscale.com/util/syspolicy/setting" + "tailscale.com/util/testenv" "tailscale.com/util/syspolicy/source" ) @@ -58,7 +58,7 @@ type Policy struct { changeCallbacks policyChangeCallbacks - mu sync.Mutex + mu syncs.Mutex watcherStarted bool // whether [Policy.watchReload] was started sources source.ReadableSources closing bool // whether [Policy.Close] was called (even if we're still closing) @@ -449,7 +449,7 @@ func (p *Policy) Close() { } } -func setForTest[T any](tb internal.TB, target *T, newValue T) { +func setForTest[T any](tb testenv.TB, target *T, newValue T) { oldValue := *target tb.Cleanup(func() { *target = oldValue }) *target = newValue diff --git a/vendor/tailscale.com/util/syspolicy/rsop/rsop.go b/vendor/tailscale.com/util/syspolicy/rsop/rsop.go index 429b9b1..333dca6 100644 --- a/vendor/tailscale.com/util/syspolicy/rsop/rsop.go +++ b/vendor/tailscale.com/util/syspolicy/rsop/rsop.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "slices" - "sync" "tailscale.com/syncs" "tailscale.com/util/slicesx" @@ -20,7 +19,7 @@ import ( ) var ( - policyMu sync.Mutex // protects [policySources] and [effectivePolicies] + policyMu syncs.Mutex // protects [policySources] and [effectivePolicies] policySources []*source.Source // all registered policy sources effectivePolicies []*Policy // all active (non-closed) effective policies returned by [PolicyFor] diff --git a/vendor/tailscale.com/util/syspolicy/rsop/store_registration.go b/vendor/tailscale.com/util/syspolicy/rsop/store_registration.go index f983684..a7c354b 100644 --- a/vendor/tailscale.com/util/syspolicy/rsop/store_registration.go +++ b/vendor/tailscale.com/util/syspolicy/rsop/store_registration.go @@ -9,9 +9,9 @@ import ( "sync/atomic" "time" - "tailscale.com/util/syspolicy/internal" "tailscale.com/util/syspolicy/setting" "tailscale.com/util/syspolicy/source" + "tailscale.com/util/testenv" ) // ErrAlreadyConsumed is the error returned when [StoreRegistration.ReplaceStore] @@ -33,7 +33,7 @@ func RegisterStore(name string, scope setting.PolicyScope, store source.Store) ( // RegisterStoreForTest is like [RegisterStore], but unregisters the store when // tb and all its subtests complete. -func RegisterStoreForTest(tb internal.TB, name string, scope setting.PolicyScope, store source.Store) (*StoreRegistration, error) { +func RegisterStoreForTest(tb testenv.TB, name string, scope setting.PolicyScope, store source.Store) (*StoreRegistration, error) { setForTest(tb, &policyReloadMinDelay, 10*time.Millisecond) setForTest(tb, &policyReloadMaxDelay, 500*time.Millisecond) diff --git a/vendor/tailscale.com/util/syspolicy/setting/key.go b/vendor/tailscale.com/util/syspolicy/setting/key.go deleted file mode 100644 index aa7606d..0000000 --- a/vendor/tailscale.com/util/syspolicy/setting/key.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package setting - -// Key is a string that uniquely identifies a policy and must remain unchanged -// once established and documented for a given policy setting. It may contain -// alphanumeric characters and zero or more [KeyPathSeparator]s to group -// individual policy settings into categories. -type Key string - -// KeyPathSeparator allows logical grouping of policy settings into categories. -const KeyPathSeparator = '/' diff --git a/vendor/tailscale.com/util/syspolicy/setting/raw_item.go b/vendor/tailscale.com/util/syspolicy/setting/raw_item.go index 9a96073..ea97865 100644 --- a/vendor/tailscale.com/util/syspolicy/setting/raw_item.go +++ b/vendor/tailscale.com/util/syspolicy/setting/raw_item.go @@ -11,6 +11,7 @@ import ( "github.com/go-json-experiment/json/jsontext" "tailscale.com/types/opt" "tailscale.com/types/structs" + "tailscale.com/util/syspolicy/pkey" ) // RawItem contains a raw policy setting value as read from a policy store, or an @@ -169,4 +170,4 @@ func (v *RawValue) UnmarshalJSON(b []byte) error { } // RawValues is a map of keyed setting values that can be read from a JSON. -type RawValues map[Key]RawValue +type RawValues map[pkey.Key]RawValue diff --git a/vendor/tailscale.com/util/syspolicy/setting/setting.go b/vendor/tailscale.com/util/syspolicy/setting/setting.go index 70fb0a9..97362b1 100644 --- a/vendor/tailscale.com/util/syspolicy/setting/setting.go +++ b/vendor/tailscale.com/util/syspolicy/setting/setting.go @@ -11,11 +11,14 @@ import ( "fmt" "slices" "strings" - "sync" "time" + "tailscale.com/syncs" "tailscale.com/types/lazy" "tailscale.com/util/syspolicy/internal" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/ptype" + "tailscale.com/util/testenv" ) // Scope indicates the broadest scope at which a policy setting may apply, @@ -128,12 +131,12 @@ func (t Type) String() string { // ValueType is a constraint that allows Go types corresponding to [Type]. type ValueType interface { - bool | uint64 | string | []string | Visibility | PreferenceOption | time.Duration + bool | uint64 | string | []string | ptype.Visibility | ptype.PreferenceOption | time.Duration } // Definition defines policy key, scope and value type. type Definition struct { - key Key + key pkey.Key scope Scope typ Type platforms PlatformList @@ -141,12 +144,12 @@ type Definition struct { // NewDefinition returns a new [Definition] with the specified // key, scope, type and supported platforms (see [PlatformList]). -func NewDefinition(k Key, s Scope, t Type, platforms ...string) *Definition { +func NewDefinition(k pkey.Key, s Scope, t Type, platforms ...string) *Definition { return &Definition{key: k, scope: s, typ: t, platforms: platforms} } // Key returns a policy setting's identifier. -func (d *Definition) Key() Key { +func (d *Definition) Key() pkey.Key { if d == nil { return "" } @@ -207,12 +210,12 @@ func (d *Definition) Equal(d2 *Definition) bool { } // DefinitionMap is a map of setting [Definition] by [Key]. -type DefinitionMap map[Key]*Definition +type DefinitionMap map[pkey.Key]*Definition var ( definitions lazy.SyncValue[DefinitionMap] - definitionsMu sync.Mutex + definitionsMu syncs.Mutex definitionsList []*Definition definitionsUsed bool ) @@ -223,7 +226,7 @@ var ( // invoking any functions that use the registered policy definitions. This // includes calling [Definitions] or [DefinitionOf] directly, or reading any // policy settings via syspolicy. -func Register(k Key, s Scope, t Type, platforms ...string) { +func Register(k pkey.Key, s Scope, t Type, platforms ...string) { RegisterDefinition(NewDefinition(k, s, t, platforms...)) } @@ -277,7 +280,7 @@ func DefinitionMapOf(settings []*Definition) (DefinitionMap, error) { // for the test duration. It is not concurrency-safe, but unlike [Register], // it does not panic and can be called anytime. // It returns an error if ds contains two different settings with the same [Key]. -func SetDefinitionsForTest(tb lazy.TB, ds ...*Definition) error { +func SetDefinitionsForTest(tb testenv.TB, ds ...*Definition) error { m, err := DefinitionMapOf(ds) if err != nil { return err @@ -289,7 +292,7 @@ func SetDefinitionsForTest(tb lazy.TB, ds ...*Definition) error { // DefinitionOf returns a setting definition by key, // or [ErrNoSuchKey] if the specified key does not exist, // or an error if there are conflicting policy definitions. -func DefinitionOf(k Key) (*Definition, error) { +func DefinitionOf(k pkey.Key) (*Definition, error) { ds, err := settingDefinitions() if err != nil { return nil, err @@ -319,33 +322,33 @@ func Definitions() ([]*Definition, error) { type PlatformList []string // Has reports whether l contains the target platform. -func (l PlatformList) Has(target string) bool { - if len(l) == 0 { +func (ls PlatformList) Has(target string) bool { + if len(ls) == 0 { return true } - return slices.ContainsFunc(l, func(os string) bool { + return slices.ContainsFunc(ls, func(os string) bool { return strings.EqualFold(os, target) }) } // HasCurrent is like Has, but for the current platform. -func (l PlatformList) HasCurrent() bool { - return l.Has(internal.OS()) +func (ls PlatformList) HasCurrent() bool { + return ls.Has(internal.OS()) } // mergeFrom merges l2 into l. Since an empty list indicates no platform restrictions, // if either l or l2 is empty, the merged result in l will also be empty. -func (l *PlatformList) mergeFrom(l2 PlatformList) { +func (ls *PlatformList) mergeFrom(l2 PlatformList) { switch { - case len(*l) == 0: + case len(*ls) == 0: // No-op. An empty list indicates no platform restrictions. case len(l2) == 0: // Merging with an empty list results in an empty list. - *l = l2 + *ls = l2 default: // Append, sort and dedup. - *l = append(*l, l2...) - slices.Sort(*l) - *l = slices.Compact(*l) + *ls = append(*ls, l2...) + slices.Sort(*ls) + *ls = slices.Compact(*ls) } } diff --git a/vendor/tailscale.com/util/syspolicy/setting/snapshot.go b/vendor/tailscale.com/util/syspolicy/setting/snapshot.go index 087325a..94c7eca 100644 --- a/vendor/tailscale.com/util/syspolicy/setting/snapshot.go +++ b/vendor/tailscale.com/util/syspolicy/setting/snapshot.go @@ -9,39 +9,41 @@ import ( "maps" "slices" "strings" + "time" jsonv2 "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" xmaps "golang.org/x/exp/maps" "tailscale.com/util/deephash" + "tailscale.com/util/syspolicy/pkey" ) // Snapshot is an immutable collection of ([Key], [RawItem]) pairs, representing // a set of policy settings applied at a specific moment in time. // A nil pointer to [Snapshot] is valid. type Snapshot struct { - m map[Key]RawItem + m map[pkey.Key]RawItem sig deephash.Sum // of m summary Summary } // NewSnapshot returns a new [Snapshot] with the specified items and options. -func NewSnapshot(items map[Key]RawItem, opts ...SummaryOption) *Snapshot { +func NewSnapshot(items map[pkey.Key]RawItem, opts ...SummaryOption) *Snapshot { return &Snapshot{m: xmaps.Clone(items), sig: deephash.Hash(&items), summary: SummaryWith(opts...)} } // All returns an iterator over policy settings in s. The iteration order is not // specified and is not guaranteed to be the same from one call to the next. -func (s *Snapshot) All() iter.Seq2[Key, RawItem] { +func (s *Snapshot) All() iter.Seq2[pkey.Key, RawItem] { if s == nil { - return func(yield func(Key, RawItem) bool) {} + return func(yield func(pkey.Key, RawItem) bool) {} } return maps.All(s.m) } // Get returns the value of the policy setting with the specified key // or nil if it is not configured or has an error. -func (s *Snapshot) Get(k Key) any { +func (s *Snapshot) Get(k pkey.Key) any { v, _ := s.GetErr(k) return v } @@ -49,7 +51,7 @@ func (s *Snapshot) Get(k Key) any { // GetErr returns the value of the policy setting with the specified key, // [ErrNotConfigured] if it is not configured, or an error returned by // the policy Store if the policy setting could not be read. -func (s *Snapshot) GetErr(k Key) (any, error) { +func (s *Snapshot) GetErr(k pkey.Key) (any, error) { if s != nil { if s, ok := s.m[k]; ok { return s.Value(), s.Error() @@ -61,7 +63,7 @@ func (s *Snapshot) GetErr(k Key) (any, error) { // GetSetting returns the untyped policy setting with the specified key and true // if a policy setting with such key has been configured; // otherwise, it returns zero, false. -func (s *Snapshot) GetSetting(k Key) (setting RawItem, ok bool) { +func (s *Snapshot) GetSetting(k pkey.Key) (setting RawItem, ok bool) { setting, ok = s.m[k] return setting, ok } @@ -93,9 +95,9 @@ func (s *Snapshot) EqualItems(s2 *Snapshot) bool { // Keys return an iterator over keys in s. The iteration order is not specified // and is not guaranteed to be the same from one call to the next. -func (s *Snapshot) Keys() iter.Seq[Key] { +func (s *Snapshot) Keys() iter.Seq[pkey.Key] { if s.m == nil { - return func(yield func(Key) bool) {} + return func(yield func(pkey.Key) bool) {} } return maps.Keys(s.m) } @@ -143,8 +145,8 @@ func (s *Snapshot) String() string { // snapshotJSON holds JSON-marshallable data for [Snapshot]. type snapshotJSON struct { - Summary Summary `json:",omitzero"` - Settings map[Key]RawItem `json:",omitempty"` + Summary Summary `json:",omitzero"` + Settings map[pkey.Key]RawItem `json:",omitempty"` } var ( @@ -152,6 +154,24 @@ var ( _ jsonv2.UnmarshalerFrom = (*Snapshot)(nil) ) +// As of 2025-07-28, jsonv2 no longer has a default representation for [time.Duration], +// so we need to provide a custom marshaler. +// +// This is temporary until the decision on the default representation is made +// (see https://github.com/golang/go/issues/71631#issuecomment-2981670799). +// +// In the future, we might either use the default representation (if compatible with +// [time.Duration.String]) or specify something like json.WithFormat[time.Duration]("units") +// when golang/go#71664 is implemented. +// +// TODO(nickkhyl): revisit this when the decision on the default [time.Duration] +// representation is made in golang/go#71631 and/or golang/go#71664 is implemented. +var formatDurationAsUnits = jsonv2.JoinOptions( + jsonv2.WithMarshalers(jsonv2.MarshalToFunc(func(e *jsontext.Encoder, t time.Duration) error { + return e.WriteToken(jsontext.String(t.String())) + })), +) + // MarshalJSONTo implements [jsonv2.MarshalerTo]. func (s *Snapshot) MarshalJSONTo(out *jsontext.Encoder) error { data := &snapshotJSON{} @@ -159,7 +179,7 @@ func (s *Snapshot) MarshalJSONTo(out *jsontext.Encoder) error { data.Summary = s.summary data.Settings = s.m } - return jsonv2.MarshalEncode(out, data) + return jsonv2.MarshalEncode(out, data, formatDurationAsUnits) } // UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom]. @@ -213,7 +233,7 @@ func MergeSnapshots(snapshot1, snapshot2 *Snapshot) *Snapshot { } return &Snapshot{snapshot2.m, snapshot2.sig, SummaryWith(summaryOpts...)} } - m := make(map[Key]RawItem, snapshot1.Len()+snapshot2.Len()) + m := make(map[pkey.Key]RawItem, snapshot1.Len()+snapshot2.Len()) xmaps.Copy(m, snapshot1.m) xmaps.Copy(m, snapshot2.m) // snapshot2 has higher precedence return &Snapshot{m, deephash.Hash(&m), SummaryWith(summaryOpts...)} diff --git a/vendor/tailscale.com/util/syspolicy/source/env_policy_store.go b/vendor/tailscale.com/util/syspolicy/source/env_policy_store.go index 299132b..be363b7 100644 --- a/vendor/tailscale.com/util/syspolicy/source/env_policy_store.go +++ b/vendor/tailscale.com/util/syspolicy/source/env_policy_store.go @@ -11,6 +11,7 @@ import ( "strings" "unicode/utf8" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" ) @@ -22,7 +23,7 @@ var _ Store = (*EnvPolicyStore)(nil) type EnvPolicyStore struct{} // ReadString implements [Store]. -func (s *EnvPolicyStore) ReadString(key setting.Key) (string, error) { +func (s *EnvPolicyStore) ReadString(key pkey.Key) (string, error) { _, str, err := s.lookupSettingVariable(key) if err != nil { return "", err @@ -31,7 +32,7 @@ func (s *EnvPolicyStore) ReadString(key setting.Key) (string, error) { } // ReadUInt64 implements [Store]. -func (s *EnvPolicyStore) ReadUInt64(key setting.Key) (uint64, error) { +func (s *EnvPolicyStore) ReadUInt64(key pkey.Key) (uint64, error) { name, str, err := s.lookupSettingVariable(key) if err != nil { return 0, err @@ -47,7 +48,7 @@ func (s *EnvPolicyStore) ReadUInt64(key setting.Key) (uint64, error) { } // ReadBoolean implements [Store]. -func (s *EnvPolicyStore) ReadBoolean(key setting.Key) (bool, error) { +func (s *EnvPolicyStore) ReadBoolean(key pkey.Key) (bool, error) { name, str, err := s.lookupSettingVariable(key) if err != nil { return false, err @@ -63,7 +64,7 @@ func (s *EnvPolicyStore) ReadBoolean(key setting.Key) (bool, error) { } // ReadStringArray implements [Store]. -func (s *EnvPolicyStore) ReadStringArray(key setting.Key) ([]string, error) { +func (s *EnvPolicyStore) ReadStringArray(key pkey.Key) ([]string, error) { _, str, err := s.lookupSettingVariable(key) if err != nil || str == "" { return nil, err @@ -79,7 +80,7 @@ func (s *EnvPolicyStore) ReadStringArray(key setting.Key) ([]string, error) { return res[0:dst], nil } -func (s *EnvPolicyStore) lookupSettingVariable(key setting.Key) (name, value string, err error) { +func (s *EnvPolicyStore) lookupSettingVariable(key pkey.Key) (name, value string, err error) { name, err = keyToEnvVarName(key) if err != nil { return "", "", err @@ -103,7 +104,7 @@ var ( // // It's fine to use this in [EnvPolicyStore] without caching variable names since it's not a hot path. // [EnvPolicyStore] is not a [Changeable] policy store, so the conversion will only happen once. -func keyToEnvVarName(key setting.Key) (string, error) { +func keyToEnvVarName(key pkey.Key) (string, error) { if len(key) == 0 { return "", errEmptyKey } @@ -135,7 +136,7 @@ func keyToEnvVarName(key setting.Key) (string, error) { } case isDigit(c): split = currentWord.Len() > 0 && !isDigit(key[i-1]) - case c == setting.KeyPathSeparator: + case c == pkey.KeyPathSeparator: words = append(words, currentWord.String()) currentWord.Reset() continue diff --git a/vendor/tailscale.com/util/syspolicy/source/policy_reader.go b/vendor/tailscale.com/util/syspolicy/source/policy_reader.go index a1bd314..33ef229 100644 --- a/vendor/tailscale.com/util/syspolicy/source/policy_reader.go +++ b/vendor/tailscale.com/util/syspolicy/source/policy_reader.go @@ -16,6 +16,8 @@ import ( "tailscale.com/util/set" "tailscale.com/util/syspolicy/internal/loggerx" "tailscale.com/util/syspolicy/internal/metrics" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/ptype" "tailscale.com/util/syspolicy/setting" ) @@ -138,9 +140,9 @@ func (r *Reader) reload(force bool) (*setting.Snapshot, error) { metrics.Reset(r.origin) - var m map[setting.Key]setting.RawItem + var m map[pkey.Key]setting.RawItem if lastPolicyCount := r.lastPolicy.Len(); lastPolicyCount > 0 { - m = make(map[setting.Key]setting.RawItem, lastPolicyCount) + m = make(map[pkey.Key]setting.RawItem, lastPolicyCount) } for _, s := range r.settings { if !r.origin.Scope().IsConfigurableSetting(s) { @@ -364,21 +366,21 @@ func readPolicySettingValue(store Store, s *setting.Definition) (value any, err case setting.PreferenceOptionValue: s, err := store.ReadString(key) if err == nil { - var value setting.PreferenceOption + var value ptype.PreferenceOption if err = value.UnmarshalText([]byte(s)); err == nil { return value, nil } } - return setting.ShowChoiceByPolicy, err + return ptype.ShowChoiceByPolicy, err case setting.VisibilityValue: s, err := store.ReadString(key) if err == nil { - var value setting.Visibility + var value ptype.Visibility if err = value.UnmarshalText([]byte(s)); err == nil { return value, nil } } - return setting.VisibleByPolicy, err + return ptype.VisibleByPolicy, err case setting.DurationValue: s, err := store.ReadString(key) if err == nil { diff --git a/vendor/tailscale.com/util/syspolicy/source/policy_source.go b/vendor/tailscale.com/util/syspolicy/source/policy_source.go index 7f2821b..c477421 100644 --- a/vendor/tailscale.com/util/syspolicy/source/policy_source.go +++ b/vendor/tailscale.com/util/syspolicy/source/policy_source.go @@ -13,6 +13,7 @@ import ( "io" "tailscale.com/types/lazy" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" ) @@ -31,19 +32,19 @@ type Store interface { // ReadString returns the value of a [setting.StringValue] with the specified key, // an [setting.ErrNotConfigured] if the policy setting is not configured, or // an error on failure. - ReadString(key setting.Key) (string, error) + ReadString(key pkey.Key) (string, error) // ReadUInt64 returns the value of a [setting.IntegerValue] with the specified key, // an [setting.ErrNotConfigured] if the policy setting is not configured, or // an error on failure. - ReadUInt64(key setting.Key) (uint64, error) + ReadUInt64(key pkey.Key) (uint64, error) // ReadBoolean returns the value of a [setting.BooleanValue] with the specified key, // an [setting.ErrNotConfigured] if the policy setting is not configured, or // an error on failure. - ReadBoolean(key setting.Key) (bool, error) + ReadBoolean(key pkey.Key) (bool, error) // ReadStringArray returns the value of a [setting.StringListValue] with the specified key, // an [setting.ErrNotConfigured] if the policy setting is not configured, or // an error on failure. - ReadStringArray(key setting.Key) ([]string, error) + ReadStringArray(key pkey.Key) ([]string, error) } // Lockable is an optional interface that [Store] implementations may support. diff --git a/vendor/tailscale.com/util/syspolicy/source/policy_store_windows.go b/vendor/tailscale.com/util/syspolicy/source/policy_store_windows.go index 621701e..f97b17f 100644 --- a/vendor/tailscale.com/util/syspolicy/source/policy_store_windows.go +++ b/vendor/tailscale.com/util/syspolicy/source/policy_store_windows.go @@ -13,6 +13,7 @@ import ( "golang.org/x/sys/windows/registry" "tailscale.com/util/set" "tailscale.com/util/syspolicy/internal/loggerx" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" "tailscale.com/util/winutil/gp" ) @@ -251,7 +252,7 @@ func (ps *PlatformPolicyStore) onChange() { // ReadString retrieves a string policy with the specified key. // It returns [setting.ErrNotConfigured] if the policy setting does not exist. -func (ps *PlatformPolicyStore) ReadString(key setting.Key) (val string, err error) { +func (ps *PlatformPolicyStore) ReadString(key pkey.Key) (val string, err error) { return getPolicyValue(ps, key, func(key registry.Key, valueName string) (string, error) { val, _, err := key.GetStringValue(valueName) @@ -261,7 +262,7 @@ func (ps *PlatformPolicyStore) ReadString(key setting.Key) (val string, err erro // ReadUInt64 retrieves an integer policy with the specified key. // It returns [setting.ErrNotConfigured] if the policy setting does not exist. -func (ps *PlatformPolicyStore) ReadUInt64(key setting.Key) (uint64, error) { +func (ps *PlatformPolicyStore) ReadUInt64(key pkey.Key) (uint64, error) { return getPolicyValue(ps, key, func(key registry.Key, valueName string) (uint64, error) { val, _, err := key.GetIntegerValue(valueName) @@ -271,7 +272,7 @@ func (ps *PlatformPolicyStore) ReadUInt64(key setting.Key) (uint64, error) { // ReadBoolean retrieves a boolean policy with the specified key. // It returns [setting.ErrNotConfigured] if the policy setting does not exist. -func (ps *PlatformPolicyStore) ReadBoolean(key setting.Key) (bool, error) { +func (ps *PlatformPolicyStore) ReadBoolean(key pkey.Key) (bool, error) { return getPolicyValue(ps, key, func(key registry.Key, valueName string) (bool, error) { val, _, err := key.GetIntegerValue(valueName) @@ -283,8 +284,8 @@ func (ps *PlatformPolicyStore) ReadBoolean(key setting.Key) (bool, error) { } // ReadString retrieves a multi-string policy with the specified key. -// It returns [setting.ErrNotConfigured] if the policy setting does not exist. -func (ps *PlatformPolicyStore) ReadStringArray(key setting.Key) ([]string, error) { +// It returns [pkey.ErrNotConfigured] if the policy setting does not exist. +func (ps *PlatformPolicyStore) ReadStringArray(key pkey.Key) ([]string, error) { return getPolicyValue(ps, key, func(key registry.Key, valueName string) ([]string, error) { val, _, err := key.GetStringsValue(valueName) @@ -322,25 +323,25 @@ func (ps *PlatformPolicyStore) ReadStringArray(key setting.Key) ([]string, error }) } -// splitSettingKey extracts the registry key name and value name from a [setting.Key]. -// The [setting.Key] format allows grouping settings into nested categories using one -// or more [setting.KeyPathSeparator]s in the path. How individual policy settings are +// splitSettingKey extracts the registry key name and value name from a [pkey.Key]. +// The [pkey.Key] format allows grouping settings into nested categories using one +// or more [pkey.KeyPathSeparator]s in the path. How individual policy settings are // stored is an implementation detail of each [Store]. In the [PlatformPolicyStore] // for Windows, we map nested policy categories onto the Registry key hierarchy. -// The last component after a [setting.KeyPathSeparator] is treated as the value name, +// The last component after a [pkey.KeyPathSeparator] is treated as the value name, // while everything preceding it is considered a subpath (relative to the {HKLM,HKCU}\Software\Policies\Tailscale key). -// If there are no [setting.KeyPathSeparator]s in the key, the policy setting value +// If there are no [pkey.KeyPathSeparator]s in the key, the policy setting value // is meant to be stored directly under {HKLM,HKCU}\Software\Policies\Tailscale. -func splitSettingKey(key setting.Key) (path, valueName string) { - if idx := strings.LastIndexByte(string(key), setting.KeyPathSeparator); idx != -1 { - path = strings.ReplaceAll(string(key[:idx]), string(setting.KeyPathSeparator), `\`) +func splitSettingKey(key pkey.Key) (path, valueName string) { + if idx := strings.LastIndexByte(string(key), pkey.KeyPathSeparator); idx != -1 { + path = strings.ReplaceAll(string(key[:idx]), string(pkey.KeyPathSeparator), `\`) valueName = string(key[idx+1:]) return path, valueName } return "", string(key) } -func getPolicyValue[T any](ps *PlatformPolicyStore, key setting.Key, getter registryValueGetter[T]) (T, error) { +func getPolicyValue[T any](ps *PlatformPolicyStore, key pkey.Key, getter registryValueGetter[T]) (T, error) { var zero T ps.mu.Lock() diff --git a/vendor/tailscale.com/util/syspolicy/source/test_store.go b/vendor/tailscale.com/util/syspolicy/source/test_store.go index e6c09d6..ddec9ef 100644 --- a/vendor/tailscale.com/util/syspolicy/source/test_store.go +++ b/vendor/tailscale.com/util/syspolicy/source/test_store.go @@ -12,8 +12,9 @@ import ( "tailscale.com/util/mak" "tailscale.com/util/set" "tailscale.com/util/slicesx" - "tailscale.com/util/syspolicy/internal" + "tailscale.com/util/syspolicy/pkey" "tailscale.com/util/syspolicy/setting" + "tailscale.com/util/testenv" ) var ( @@ -31,7 +32,7 @@ type TestValueType interface { // TestSetting is a policy setting in a [TestStore]. type TestSetting[T TestValueType] struct { // Key is the setting's unique identifier. - Key setting.Key + Key pkey.Key // Error is the error to be returned by the [TestStore] when reading // a policy setting with the specified key. Error error @@ -43,20 +44,20 @@ type TestSetting[T TestValueType] struct { // TestSettingOf returns a [TestSetting] representing a policy setting // configured with the specified key and value. -func TestSettingOf[T TestValueType](key setting.Key, value T) TestSetting[T] { +func TestSettingOf[T TestValueType](key pkey.Key, value T) TestSetting[T] { return TestSetting[T]{Key: key, Value: value} } // TestSettingWithError returns a [TestSetting] representing a policy setting // with the specified key and error. -func TestSettingWithError[T TestValueType](key setting.Key, err error) TestSetting[T] { +func TestSettingWithError[T TestValueType](key pkey.Key, err error) TestSetting[T] { return TestSetting[T]{Key: key, Error: err} } // testReadOperation describes a single policy setting read operation. type testReadOperation struct { // Key is the setting's unique identifier. - Key setting.Key + Key pkey.Key // Type is a value type of a read operation. // [setting.BooleanValue], [setting.IntegerValue], [setting.StringValue] or [setting.StringListValue] Type setting.Type @@ -65,7 +66,7 @@ type testReadOperation struct { // TestExpectedReads is the number of read operations with the specified details. type TestExpectedReads struct { // Key is the setting's unique identifier. - Key setting.Key + Key pkey.Key // Type is a value type of a read operation. // [setting.BooleanValue], [setting.IntegerValue], [setting.StringValue] or [setting.StringListValue] Type setting.Type @@ -79,7 +80,7 @@ func (r TestExpectedReads) operation() testReadOperation { // TestStore is a [Store] that can be used in tests. type TestStore struct { - tb internal.TB + tb testenv.TB done chan struct{} @@ -87,8 +88,8 @@ type TestStore struct { storeLockCount atomic.Int32 mu sync.RWMutex - suspendCount int // change callback are suspended if > 0 - mr, mw map[setting.Key]any // maps for reading and writing; they're the same unless the store is suspended. + suspendCount int // change callback are suspended if > 0 + mr, mw map[pkey.Key]any // maps for reading and writing; they're the same unless the store is suspended. cbs set.HandleSet[func()] closed bool @@ -98,8 +99,8 @@ type TestStore struct { // NewTestStore returns a new [TestStore]. // The tb will be used to report coding errors detected by the [TestStore]. -func NewTestStore(tb internal.TB) *TestStore { - m := make(map[setting.Key]any) +func NewTestStore(tb testenv.TB) *TestStore { + m := make(map[pkey.Key]any) store := &TestStore{ tb: tb, done: make(chan struct{}), @@ -112,7 +113,7 @@ func NewTestStore(tb internal.TB) *TestStore { // NewTestStoreOf is a shorthand for [NewTestStore] followed by [TestStore.SetBooleans], // [TestStore.SetUInt64s], [TestStore.SetStrings] or [TestStore.SetStringLists]. -func NewTestStoreOf[T TestValueType](tb internal.TB, settings ...TestSetting[T]) *TestStore { +func NewTestStoreOf[T TestValueType](tb testenv.TB, settings ...TestSetting[T]) *TestStore { store := NewTestStore(tb) switch settings := any(settings).(type) { case []TestSetting[bool]: @@ -154,8 +155,15 @@ func (s *TestStore) RegisterChangeCallback(callback func()) (unregister func(), }, nil } +// IsEmpty reports whether the store does not contain any settings. +func (s *TestStore) IsEmpty() bool { + s.mu.RLock() + defer s.mu.RUnlock() + return len(s.mr) == 0 +} + // ReadString implements [Store]. -func (s *TestStore) ReadString(key setting.Key) (string, error) { +func (s *TestStore) ReadString(key pkey.Key) (string, error) { defer s.recordRead(key, setting.StringValue) s.mu.RLock() defer s.mu.RUnlock() @@ -174,7 +182,7 @@ func (s *TestStore) ReadString(key setting.Key) (string, error) { } // ReadUInt64 implements [Store]. -func (s *TestStore) ReadUInt64(key setting.Key) (uint64, error) { +func (s *TestStore) ReadUInt64(key pkey.Key) (uint64, error) { defer s.recordRead(key, setting.IntegerValue) s.mu.RLock() defer s.mu.RUnlock() @@ -193,7 +201,7 @@ func (s *TestStore) ReadUInt64(key setting.Key) (uint64, error) { } // ReadBoolean implements [Store]. -func (s *TestStore) ReadBoolean(key setting.Key) (bool, error) { +func (s *TestStore) ReadBoolean(key pkey.Key) (bool, error) { defer s.recordRead(key, setting.BooleanValue) s.mu.RLock() defer s.mu.RUnlock() @@ -212,7 +220,7 @@ func (s *TestStore) ReadBoolean(key setting.Key) (bool, error) { } // ReadStringArray implements [Store]. -func (s *TestStore) ReadStringArray(key setting.Key) ([]string, error) { +func (s *TestStore) ReadStringArray(key pkey.Key) ([]string, error) { defer s.recordRead(key, setting.StringListValue) s.mu.RLock() defer s.mu.RUnlock() @@ -230,7 +238,7 @@ func (s *TestStore) ReadStringArray(key setting.Key) ([]string, error) { return slice, nil } -func (s *TestStore) recordRead(key setting.Key, typ setting.Type) { +func (s *TestStore) recordRead(key pkey.Key, typ setting.Type) { s.readsMu.Lock() op := testReadOperation{key, typ} num := s.reads[op] @@ -392,7 +400,7 @@ func (s *TestStore) SetStringLists(settings ...TestSetting[[]string]) { } // Delete deletes the specified settings from s. -func (s *TestStore) Delete(keys ...setting.Key) { +func (s *TestStore) Delete(keys ...pkey.Key) { s.storeLock.Lock() for _, key := range keys { s.mu.Lock() diff --git a/vendor/tailscale.com/util/syspolicy/syspolicy.go b/vendor/tailscale.com/util/syspolicy/syspolicy.go index d925731..48e430b 100644 --- a/vendor/tailscale.com/util/syspolicy/syspolicy.go +++ b/vendor/tailscale.com/util/syspolicy/syspolicy.go @@ -1,13 +1,9 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -// Package syspolicy facilitates retrieval of the current policy settings -// applied to the device or user and receiving notifications when the policy -// changes. -// -// It provides functions that return specific policy settings by their unique -// [setting.Key]s, such as [GetBoolean], [GetUint64], [GetString], -// [GetStringArray], [GetPreferenceOption], [GetVisibility] and [GetDuration]. +// Package syspolicy contains the implementation of system policy management. +// Calling code should use the client interface in +// tailscale.com/util/syspolicy/policyclient. package syspolicy import ( @@ -17,6 +13,9 @@ import ( "time" "tailscale.com/util/syspolicy/internal/loggerx" + "tailscale.com/util/syspolicy/pkey" + "tailscale.com/util/syspolicy/policyclient" + "tailscale.com/util/syspolicy/ptype" "tailscale.com/util/syspolicy/rsop" "tailscale.com/util/syspolicy/setting" "tailscale.com/util/syspolicy/source" @@ -45,65 +44,79 @@ func RegisterStore(name string, scope setting.PolicyScope, store source.Store) ( return rsop.RegisterStore(name, scope, store) } -// MustRegisterStoreForTest is like [rsop.RegisterStoreForTest], but it fails the test if the store could not be registered. -func MustRegisterStoreForTest(tb TB, name string, scope setting.PolicyScope, store source.Store) *rsop.StoreRegistration { - tb.Helper() - reg, err := rsop.RegisterStoreForTest(tb, name, scope, store) - if err != nil { - tb.Fatalf("Failed to register policy store %q as a %v policy source: %v", name, scope, err) +// hasAnyOf returns whether at least one of the specified policy settings is configured, +// or an error if no keys are provided or the check fails. +func hasAnyOf(keys ...pkey.Key) (bool, error) { + if len(keys) == 0 { + return false, errors.New("at least one key must be specified") } - return reg + policy, err := rsop.PolicyFor(setting.DefaultScope()) + if err != nil { + return false, err + } + effective := policy.Get() + for _, k := range keys { + _, err := effective.GetErr(k) + if errors.Is(err, setting.ErrNotConfigured) || errors.Is(err, setting.ErrNoSuchKey) { + continue + } + if err != nil { + return false, err + } + return true, nil + } + return false, nil } -// GetString returns a string policy setting with the specified key, +// getString returns a string policy setting with the specified key, // or defaultValue if it does not exist. -func GetString(key Key, defaultValue string) (string, error) { +func getString(key pkey.Key, defaultValue string) (string, error) { return getCurrentPolicySettingValue(key, defaultValue) } -// GetUint64 returns a numeric policy setting with the specified key, +// getUint64 returns a numeric policy setting with the specified key, // or defaultValue if it does not exist. -func GetUint64(key Key, defaultValue uint64) (uint64, error) { +func getUint64(key pkey.Key, defaultValue uint64) (uint64, error) { return getCurrentPolicySettingValue(key, defaultValue) } -// GetBoolean returns a boolean policy setting with the specified key, +// getBoolean returns a boolean policy setting with the specified key, // or defaultValue if it does not exist. -func GetBoolean(key Key, defaultValue bool) (bool, error) { +func getBoolean(key pkey.Key, defaultValue bool) (bool, error) { return getCurrentPolicySettingValue(key, defaultValue) } -// GetStringArray returns a multi-string policy setting with the specified key, +// getStringArray returns a multi-string policy setting with the specified key, // or defaultValue if it does not exist. -func GetStringArray(key Key, defaultValue []string) ([]string, error) { +func getStringArray(key pkey.Key, defaultValue []string) ([]string, error) { return getCurrentPolicySettingValue(key, defaultValue) } -// GetPreferenceOption loads a policy from the registry that can be +// getPreferenceOption loads a policy from the registry that can be // managed by an enterprise policy management system and allows administrative // overrides of users' choices in a way that we do not want tailcontrol to have // the authority to set. It describes user-decides/always/never options, where // "always" and "never" remove the user's ability to make a selection. If not -// present or set to a different value, "user-decides" is the default. -func GetPreferenceOption(name Key) (setting.PreferenceOption, error) { - return getCurrentPolicySettingValue(name, setting.ShowChoiceByPolicy) +// present or set to a different value, defaultValue (and a nil error) is returned. +func getPreferenceOption(name pkey.Key, defaultValue ptype.PreferenceOption) (ptype.PreferenceOption, error) { + return getCurrentPolicySettingValue(name, defaultValue) } -// GetVisibility loads a policy from the registry that can be managed +// getVisibility loads a policy from the registry that can be managed // by an enterprise policy management system and describes show/hide decisions // for UI elements. The registry value should be a string set to "show" (return // true) or "hide" (return true). If not present or set to a different value, // "show" (return false) is the default. -func GetVisibility(name Key) (setting.Visibility, error) { - return getCurrentPolicySettingValue(name, setting.VisibleByPolicy) +func getVisibility(name pkey.Key) (ptype.Visibility, error) { + return getCurrentPolicySettingValue(name, ptype.VisibleByPolicy) } -// GetDuration loads a policy from the registry that can be managed +// getDuration loads a policy from the registry that can be managed // by an enterprise policy management system and describes a duration for some // action. The registry value should be a string that time.ParseDuration // understands. If the registry value is "" or can not be processed, // defaultValue is returned instead. -func GetDuration(name Key, defaultValue time.Duration) (time.Duration, error) { +func getDuration(name pkey.Key, defaultValue time.Duration) (time.Duration, error) { d, err := getCurrentPolicySettingValue(name, defaultValue) if err != nil { return d, err @@ -114,9 +127,9 @@ func GetDuration(name Key, defaultValue time.Duration) (time.Duration, error) { return d, nil } -// RegisterChangeCallback adds a function that will be called whenever the effective policy +// registerChangeCallback adds a function that will be called whenever the effective policy // for the default scope changes. The returned function can be used to unregister the callback. -func RegisterChangeCallback(cb rsop.PolicyChangeCallback) (unregister func(), err error) { +func registerChangeCallback(cb rsop.PolicyChangeCallback) (unregister func(), err error) { effective, err := rsop.PolicyFor(setting.DefaultScope()) if err != nil { return nil, err @@ -128,7 +141,7 @@ func RegisterChangeCallback(cb rsop.PolicyChangeCallback) (unregister func(), er // specified by its key from the [rsop.Policy] of the [setting.DefaultScope]. It // returns def if the policy setting is not configured, or an error if it has // an error or could not be converted to the specified type T. -func getCurrentPolicySettingValue[T setting.ValueType](key Key, def T) (T, error) { +func getCurrentPolicySettingValue[T setting.ValueType](key pkey.Key, def T) (T, error) { effective, err := rsop.PolicyFor(setting.DefaultScope()) if err != nil { return def, err @@ -199,7 +212,53 @@ func SelectControlURL(reg, disk string) string { return def } -// SetDebugLoggingEnabled controls whether spammy debug logging is enabled. -func SetDebugLoggingEnabled(v bool) { - loggerx.SetDebugLoggingEnabled(v) +func init() { + policyclient.RegisterClientImpl(globalSyspolicy{}) +} + +// globalSyspolicy implements [policyclient.Client] using the syspolicy global +// functions and global registrations. +// +// TODO: de-global-ify. This implementation using the old global functions +// is an intermediate stage while changing policyclient to be modular. +type globalSyspolicy struct{} + +func (globalSyspolicy) GetBoolean(key pkey.Key, defaultValue bool) (bool, error) { + return getBoolean(key, defaultValue) +} + +func (globalSyspolicy) GetString(key pkey.Key, defaultValue string) (string, error) { + return getString(key, defaultValue) +} + +func (globalSyspolicy) GetStringArray(key pkey.Key, defaultValue []string) ([]string, error) { + return getStringArray(key, defaultValue) +} + +func (globalSyspolicy) SetDebugLoggingEnabled(enabled bool) { + loggerx.SetDebugLoggingEnabled(enabled) +} + +func (globalSyspolicy) GetUint64(key pkey.Key, defaultValue uint64) (uint64, error) { + return getUint64(key, defaultValue) +} + +func (globalSyspolicy) GetDuration(name pkey.Key, defaultValue time.Duration) (time.Duration, error) { + return getDuration(name, defaultValue) +} + +func (globalSyspolicy) GetPreferenceOption(name pkey.Key, defaultValue ptype.PreferenceOption) (ptype.PreferenceOption, error) { + return getPreferenceOption(name, defaultValue) +} + +func (globalSyspolicy) GetVisibility(name pkey.Key) (ptype.Visibility, error) { + return getVisibility(name) +} + +func (globalSyspolicy) HasAnyOf(keys ...pkey.Key) (bool, error) { + return hasAnyOf(keys...) +} + +func (globalSyspolicy) RegisterChangeCallback(cb func(policyclient.PolicyChange)) (unregister func(), err error) { + return registerChangeCallback(cb) } diff --git a/vendor/tailscale.com/util/syspolicy/syspolicy_windows.go b/vendor/tailscale.com/util/syspolicy/syspolicy_windows.go index 9d57e24..ca0fd32 100644 --- a/vendor/tailscale.com/util/syspolicy/syspolicy_windows.go +++ b/vendor/tailscale.com/util/syspolicy/syspolicy_windows.go @@ -43,7 +43,7 @@ func init() { // configureSyspolicy configures syspolicy for use on Windows, // either in test or regular builds depending on whether tb has a non-nil value. -func configureSyspolicy(tb internal.TB) error { +func configureSyspolicy(tb testenv.TB) error { const localSystemSID = "S-1-5-18" // Always create and register a machine policy store that reads // policy settings from the HKEY_LOCAL_MACHINE registry hive. diff --git a/vendor/tailscale.com/util/sysresources/memory.go b/vendor/tailscale.com/util/sysresources/memory.go deleted file mode 100644 index 7363155..0000000 --- a/vendor/tailscale.com/util/sysresources/memory.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package sysresources - -// TotalMemory returns the total accessible system memory, in bytes. If the -// value cannot be determined, then 0 will be returned. -func TotalMemory() uint64 { - return totalMemoryImpl() -} diff --git a/vendor/tailscale.com/util/sysresources/memory_bsd.go b/vendor/tailscale.com/util/sysresources/memory_bsd.go deleted file mode 100644 index 26850dc..0000000 --- a/vendor/tailscale.com/util/sysresources/memory_bsd.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build freebsd || openbsd || dragonfly || netbsd - -package sysresources - -import "golang.org/x/sys/unix" - -func totalMemoryImpl() uint64 { - val, err := unix.SysctlUint64("hw.physmem") - if err != nil { - return 0 - } - return val -} diff --git a/vendor/tailscale.com/util/sysresources/memory_darwin.go b/vendor/tailscale.com/util/sysresources/memory_darwin.go deleted file mode 100644 index e07bac0..0000000 --- a/vendor/tailscale.com/util/sysresources/memory_darwin.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin - -package sysresources - -import "golang.org/x/sys/unix" - -func totalMemoryImpl() uint64 { - val, err := unix.SysctlUint64("hw.memsize") - if err != nil { - return 0 - } - return val -} diff --git a/vendor/tailscale.com/util/sysresources/memory_linux.go b/vendor/tailscale.com/util/sysresources/memory_linux.go deleted file mode 100644 index 0239b0e..0000000 --- a/vendor/tailscale.com/util/sysresources/memory_linux.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package sysresources - -import "golang.org/x/sys/unix" - -func totalMemoryImpl() uint64 { - var info unix.Sysinfo_t - - if err := unix.Sysinfo(&info); err != nil { - return 0 - } - - // uint64 casts are required since these might be uint32s - return uint64(info.Totalram) * uint64(info.Unit) -} diff --git a/vendor/tailscale.com/util/sysresources/memory_unsupported.go b/vendor/tailscale.com/util/sysresources/memory_unsupported.go deleted file mode 100644 index 0fde256..0000000 --- a/vendor/tailscale.com/util/sysresources/memory_unsupported.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !(linux || darwin || freebsd || openbsd || dragonfly || netbsd) - -package sysresources - -func totalMemoryImpl() uint64 { return 0 } diff --git a/vendor/tailscale.com/util/sysresources/sysresources.go b/vendor/tailscale.com/util/sysresources/sysresources.go deleted file mode 100644 index 32d972a..0000000 --- a/vendor/tailscale.com/util/sysresources/sysresources.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package sysresources provides OS-independent methods of determining the -// resources available to the current system. -package sysresources diff --git a/vendor/tailscale.com/util/systemd/doc.go b/vendor/tailscale.com/util/systemd/doc.go deleted file mode 100644 index 0c28e18..0000000 --- a/vendor/tailscale.com/util/systemd/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -/* -Package systemd contains a minimal wrapper around systemd-notify to enable -applications to signal readiness and status to systemd. - -This package will only have effect on Linux systems running Tailscale in a -systemd unit with the Type=notify flag set. On other operating systems (or -when running in a Linux distro without being run from inside systemd) this -package will become a no-op. -*/ -package systemd diff --git a/vendor/tailscale.com/util/systemd/systemd_linux.go b/vendor/tailscale.com/util/systemd/systemd_linux.go deleted file mode 100644 index 909cfcb..0000000 --- a/vendor/tailscale.com/util/systemd/systemd_linux.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package systemd - -import ( - "errors" - "log" - "os" - "sync" - - "github.com/mdlayher/sdnotify" -) - -var getNotifyOnce struct { - sync.Once - v *sdnotify.Notifier -} - -type logOnce struct { - sync.Once -} - -func (l *logOnce) logf(format string, args ...any) { - l.Once.Do(func() { - log.Printf(format, args...) - }) -} - -var ( - readyOnce = &logOnce{} - statusOnce = &logOnce{} -) - -func notifier() *sdnotify.Notifier { - getNotifyOnce.Do(func() { - var err error - getNotifyOnce.v, err = sdnotify.New() - // Not exist means probably not running under systemd, so don't log. - if err != nil && !errors.Is(err, os.ErrNotExist) { - log.Printf("systemd: systemd-notifier error: %v", err) - } - }) - return getNotifyOnce.v -} - -// Ready signals readiness to systemd. This will unblock service dependents from starting. -func Ready() { - err := notifier().Notify(sdnotify.Ready) - if err != nil { - readyOnce.logf("systemd: error notifying: %v", err) - } -} - -// Status sends a single line status update to systemd so that information shows up -// in systemctl output. For example: -// -// $ systemctl status tailscale -// ● tailscale.service - Tailscale client daemon -// Loaded: loaded (/nix/store/qc312qcy907wz80fqrgbbm8a9djafmlg-unit-tailscale.service/tailscale.service; enabled; vendor preset: enabled) -// Active: active (running) since Tue 2020-11-24 17:54:07 EST; 13h ago -// Main PID: 26741 (.tailscaled-wra) -// Status: "Connected; user@host.domain.tld; 100.101.102.103" -// IP: 0B in, 0B out -// Tasks: 22 (limit: 4915) -// Memory: 30.9M -// CPU: 2min 38.469s -// CGroup: /system.slice/tailscale.service -// └─26741 /nix/store/sv6cj4mw2jajm9xkbwj07k29dj30lh0n-tailscale-date.20200727/bin/tailscaled --port 41641 -func Status(format string, args ...any) { - err := notifier().Notify(sdnotify.Statusf(format, args...)) - if err != nil { - statusOnce.logf("systemd: error notifying: %v", err) - } -} diff --git a/vendor/tailscale.com/util/systemd/systemd_nonlinux.go b/vendor/tailscale.com/util/systemd/systemd_nonlinux.go deleted file mode 100644 index 3621402..0000000 --- a/vendor/tailscale.com/util/systemd/systemd_nonlinux.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package systemd - -func Ready() {} -func Status(string, ...any) {} diff --git a/vendor/tailscale.com/util/testenv/testenv.go b/vendor/tailscale.com/util/testenv/testenv.go index 12ada90..aa66604 100644 --- a/vendor/tailscale.com/util/testenv/testenv.go +++ b/vendor/tailscale.com/util/testenv/testenv.go @@ -6,6 +6,7 @@ package testenv import ( + "context" "flag" "tailscale.com/types/lazy" @@ -19,3 +20,48 @@ func InTest() bool { return flag.Lookup("test.v") != nil }) } + +// TB is testing.TB, to avoid importing "testing" in non-test code. +type TB interface { + Cleanup(func()) + Error(args ...any) + Errorf(format string, args ...any) + Fail() + FailNow() + Failed() bool + Fatal(args ...any) + Fatalf(format string, args ...any) + Helper() + Log(args ...any) + Logf(format string, args ...any) + Name() string + Setenv(key, value string) + Chdir(dir string) + Skip(args ...any) + SkipNow() + Skipf(format string, args ...any) + Skipped() bool + TempDir() string + Context() context.Context +} + +// InParallelTest reports whether t is running as a parallel test. +// +// Use of this function taints t such that its Parallel method (assuming t is an +// actual *testing.T) will panic if called after this function. +func InParallelTest(t TB) (isParallel bool) { + defer func() { + if r := recover(); r != nil { + isParallel = true + } + }() + t.Chdir(".") // panics in a t.Parallel test + return false +} + +// AssertInTest panics if called outside of a test binary. +func AssertInTest() { + if !InTest() { + panic("func called outside of test binary") + } +} diff --git a/vendor/tailscale.com/util/usermetric/metrics.go b/vendor/tailscale.com/util/usermetric/metrics.go index 044b4d6..be425fb 100644 --- a/vendor/tailscale.com/util/usermetric/metrics.go +++ b/vendor/tailscale.com/util/usermetric/metrics.go @@ -10,15 +10,15 @@ package usermetric import ( "sync" - "tailscale.com/metrics" + "tailscale.com/feature/buildfeatures" ) // Metrics contains user-facing metrics that are used by multiple packages. type Metrics struct { initOnce sync.Once - droppedPacketsInbound *metrics.MultiLabelMap[DropLabels] - droppedPacketsOutbound *metrics.MultiLabelMap[DropLabels] + droppedPacketsInbound *MultiLabelMap[DropLabels] + droppedPacketsOutbound *MultiLabelMap[DropLabels] } // DropReason is the reason why a packet was dropped. @@ -55,6 +55,9 @@ type DropLabels struct { // initOnce initializes the common metrics. func (r *Registry) initOnce() { + if !buildfeatures.HasUserMetrics { + return + } r.m.initOnce.Do(func() { r.m.droppedPacketsInbound = NewMultiLabelMapWithRegistry[DropLabels]( r, @@ -73,13 +76,13 @@ func (r *Registry) initOnce() { // DroppedPacketsOutbound returns the outbound dropped packet metric, creating it // if necessary. -func (r *Registry) DroppedPacketsOutbound() *metrics.MultiLabelMap[DropLabels] { +func (r *Registry) DroppedPacketsOutbound() *MultiLabelMap[DropLabels] { r.initOnce() return r.m.droppedPacketsOutbound } // DroppedPacketsInbound returns the inbound dropped packet metric. -func (r *Registry) DroppedPacketsInbound() *metrics.MultiLabelMap[DropLabels] { +func (r *Registry) DroppedPacketsInbound() *MultiLabelMap[DropLabels] { r.initOnce() return r.m.droppedPacketsInbound } diff --git a/vendor/tailscale.com/util/usermetric/omit.go b/vendor/tailscale.com/util/usermetric/omit.go new file mode 100644 index 0000000..0611990 --- /dev/null +++ b/vendor/tailscale.com/util/usermetric/omit.go @@ -0,0 +1,29 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_usermetrics + +package usermetric + +type Registry struct { + m Metrics +} + +func (*Registry) NewGauge(name, help string) *Gauge { return nil } + +type MultiLabelMap[T comparable] = noopMap[T] + +type noopMap[T comparable] struct{} + +type Gauge struct{} + +func (*Gauge) Set(float64) {} + +func NewMultiLabelMapWithRegistry[T comparable](m *Registry, name string, promType, helpText string) *MultiLabelMap[T] { + return nil +} + +func (*noopMap[T]) Add(T, int64) {} +func (*noopMap[T]) Set(T, any) {} + +func (r *Registry) Handler(any, any) {} // no-op HTTP handler diff --git a/vendor/tailscale.com/util/usermetric/usermetric.go b/vendor/tailscale.com/util/usermetric/usermetric.go index 74e9447..1805a5d 100644 --- a/vendor/tailscale.com/util/usermetric/usermetric.go +++ b/vendor/tailscale.com/util/usermetric/usermetric.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_usermetrics + // Package usermetric provides a container and handler // for user-facing metrics. package usermetric @@ -25,6 +27,10 @@ type Registry struct { m Metrics } +// MultiLabelMap is an alias for metrics.MultiLabelMap in the common case, +// or an alias to a lighter type when usermetrics are omitted from the build. +type MultiLabelMap[T comparable] = metrics.MultiLabelMap[T] + // NewMultiLabelMapWithRegistry creates and register a new // MultiLabelMap[T] variable with the given name and returns it. // The variable is registered with the userfacing metrics package. diff --git a/vendor/tailscale.com/util/winutil/authenticode/zsyscall_windows.go b/vendor/tailscale.com/util/winutil/authenticode/zsyscall_windows.go index 643721e..f1fba28 100644 --- a/vendor/tailscale.com/util/winutil/authenticode/zsyscall_windows.go +++ b/vendor/tailscale.com/util/winutil/authenticode/zsyscall_windows.go @@ -56,7 +56,7 @@ var ( ) func cryptMsgClose(cryptMsg windows.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCryptMsgClose.Addr(), 1, uintptr(cryptMsg), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptMsgClose.Addr(), uintptr(cryptMsg)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -64,7 +64,7 @@ func cryptMsgClose(cryptMsg windows.Handle) (err error) { } func cryptMsgGetParam(cryptMsg windows.Handle, paramType uint32, index uint32, data unsafe.Pointer, dataLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptMsgGetParam.Addr(), 5, uintptr(cryptMsg), uintptr(paramType), uintptr(index), uintptr(data), uintptr(unsafe.Pointer(dataLen)), 0) + r1, _, e1 := syscall.SyscallN(procCryptMsgGetParam.Addr(), uintptr(cryptMsg), uintptr(paramType), uintptr(index), uintptr(data), uintptr(unsafe.Pointer(dataLen))) if int32(r1) == 0 { err = errnoErr(e1) } @@ -72,7 +72,7 @@ func cryptMsgGetParam(cryptMsg windows.Handle, paramType uint32, index uint32, d } func cryptVerifyMessageSignature(pVerifyPara *_CRYPT_VERIFY_MESSAGE_PARA, signerIndex uint32, pbSignedBlob *byte, cbSignedBlob uint32, pbDecoded *byte, pdbDecoded *uint32, ppSignerCert **windows.CertContext) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptVerifyMessageSignature.Addr(), 7, uintptr(unsafe.Pointer(pVerifyPara)), uintptr(signerIndex), uintptr(unsafe.Pointer(pbSignedBlob)), uintptr(cbSignedBlob), uintptr(unsafe.Pointer(pbDecoded)), uintptr(unsafe.Pointer(pdbDecoded)), uintptr(unsafe.Pointer(ppSignerCert)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptVerifyMessageSignature.Addr(), uintptr(unsafe.Pointer(pVerifyPara)), uintptr(signerIndex), uintptr(unsafe.Pointer(pbSignedBlob)), uintptr(cbSignedBlob), uintptr(unsafe.Pointer(pbDecoded)), uintptr(unsafe.Pointer(pdbDecoded)), uintptr(unsafe.Pointer(ppSignerCert))) if int32(r1) == 0 { err = errnoErr(e1) } @@ -80,13 +80,13 @@ func cryptVerifyMessageSignature(pVerifyPara *_CRYPT_VERIFY_MESSAGE_PARA, signer } func msiGetFileSignatureInformation(signedObjectPath *uint16, flags uint32, certCtx **windows.CertContext, pbHashData *byte, cbHashData *uint32) (ret wingoes.HRESULT) { - r0, _, _ := syscall.Syscall6(procMsiGetFileSignatureInformationW.Addr(), 5, uintptr(unsafe.Pointer(signedObjectPath)), uintptr(flags), uintptr(unsafe.Pointer(certCtx)), uintptr(unsafe.Pointer(pbHashData)), uintptr(unsafe.Pointer(cbHashData)), 0) + r0, _, _ := syscall.SyscallN(procMsiGetFileSignatureInformationW.Addr(), uintptr(unsafe.Pointer(signedObjectPath)), uintptr(flags), uintptr(unsafe.Pointer(certCtx)), uintptr(unsafe.Pointer(pbHashData)), uintptr(unsafe.Pointer(cbHashData))) ret = wingoes.HRESULT(r0) return } func cryptCATAdminAcquireContext2(hCatAdmin *_HCATADMIN, pgSubsystem *windows.GUID, hashAlgorithm *uint16, strongHashPolicy *windows.CertStrongSignPara, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptCATAdminAcquireContext2.Addr(), 5, uintptr(unsafe.Pointer(hCatAdmin)), uintptr(unsafe.Pointer(pgSubsystem)), uintptr(unsafe.Pointer(hashAlgorithm)), uintptr(unsafe.Pointer(strongHashPolicy)), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptCATAdminAcquireContext2.Addr(), uintptr(unsafe.Pointer(hCatAdmin)), uintptr(unsafe.Pointer(pgSubsystem)), uintptr(unsafe.Pointer(hashAlgorithm)), uintptr(unsafe.Pointer(strongHashPolicy)), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -94,7 +94,7 @@ func cryptCATAdminAcquireContext2(hCatAdmin *_HCATADMIN, pgSubsystem *windows.GU } func cryptCATAdminCalcHashFromFileHandle2(hCatAdmin _HCATADMIN, file windows.Handle, pcbHash *uint32, pbHash *byte, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptCATAdminCalcHashFromFileHandle2.Addr(), 5, uintptr(hCatAdmin), uintptr(file), uintptr(unsafe.Pointer(pcbHash)), uintptr(unsafe.Pointer(pbHash)), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptCATAdminCalcHashFromFileHandle2.Addr(), uintptr(hCatAdmin), uintptr(file), uintptr(unsafe.Pointer(pcbHash)), uintptr(unsafe.Pointer(pbHash)), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -102,7 +102,7 @@ func cryptCATAdminCalcHashFromFileHandle2(hCatAdmin _HCATADMIN, file windows.Han } func cryptCATAdminEnumCatalogFromHash(hCatAdmin _HCATADMIN, pbHash *byte, cbHash uint32, flags uint32, prevCatInfo *_HCATINFO) (ret _HCATINFO, err error) { - r0, _, e1 := syscall.Syscall6(procCryptCATAdminEnumCatalogFromHash.Addr(), 5, uintptr(hCatAdmin), uintptr(unsafe.Pointer(pbHash)), uintptr(cbHash), uintptr(flags), uintptr(unsafe.Pointer(prevCatInfo)), 0) + r0, _, e1 := syscall.SyscallN(procCryptCATAdminEnumCatalogFromHash.Addr(), uintptr(hCatAdmin), uintptr(unsafe.Pointer(pbHash)), uintptr(cbHash), uintptr(flags), uintptr(unsafe.Pointer(prevCatInfo))) ret = _HCATINFO(r0) if ret == 0 { err = errnoErr(e1) @@ -111,7 +111,7 @@ func cryptCATAdminEnumCatalogFromHash(hCatAdmin _HCATADMIN, pbHash *byte, cbHash } func cryptCATAdminReleaseCatalogContext(hCatAdmin _HCATADMIN, hCatInfo _HCATINFO, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptCATAdminReleaseCatalogContext.Addr(), 3, uintptr(hCatAdmin), uintptr(hCatInfo), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procCryptCATAdminReleaseCatalogContext.Addr(), uintptr(hCatAdmin), uintptr(hCatInfo), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -119,7 +119,7 @@ func cryptCATAdminReleaseCatalogContext(hCatAdmin _HCATADMIN, hCatInfo _HCATINFO } func cryptCATAdminReleaseContext(hCatAdmin _HCATADMIN, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptCATAdminReleaseContext.Addr(), 2, uintptr(hCatAdmin), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptCATAdminReleaseContext.Addr(), uintptr(hCatAdmin), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -127,7 +127,7 @@ func cryptCATAdminReleaseContext(hCatAdmin _HCATADMIN, flags uint32) (err error) } func cryptCATAdminCatalogInfoFromContext(hCatInfo _HCATINFO, catInfo *_CATALOG_INFO, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptCATCatalogInfoFromContext.Addr(), 3, uintptr(hCatInfo), uintptr(unsafe.Pointer(catInfo)), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procCryptCATCatalogInfoFromContext.Addr(), uintptr(hCatInfo), uintptr(unsafe.Pointer(catInfo)), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } diff --git a/vendor/tailscale.com/util/winutil/gp/policylock_windows.go b/vendor/tailscale.com/util/winutil/gp/policylock_windows.go index 69c5ff0..6c3ca0b 100644 --- a/vendor/tailscale.com/util/winutil/gp/policylock_windows.go +++ b/vendor/tailscale.com/util/winutil/gp/policylock_windows.go @@ -127,32 +127,32 @@ func NewUserPolicyLock(token windows.Token) (*PolicyLock, error) { return lock, nil } -// Lock locks l. -// It returns [ErrInvalidLockState] if l has a zero value or has already been closed, +// Lock locks lk. +// It returns [ErrInvalidLockState] if lk has a zero value or has already been closed, // [ErrLockRestricted] if the lock cannot be acquired due to a restriction in place, // or a [syscall.Errno] if the underlying Group Policy lock cannot be acquired. // // As a special case, it fails with [windows.ERROR_ACCESS_DENIED] -// if l is a user policy lock, and the corresponding user is not logged in +// if lk is a user policy lock, and the corresponding user is not logged in // interactively at the time of the call. -func (l *PolicyLock) Lock() error { +func (lk *PolicyLock) Lock() error { if policyLockRestricted.Load() > 0 { return ErrLockRestricted } - l.mu.Lock() - defer l.mu.Unlock() - if l.lockCnt.Add(2)&1 == 0 { + lk.mu.Lock() + defer lk.mu.Unlock() + if lk.lockCnt.Add(2)&1 == 0 { // The lock cannot be acquired because it has either never been properly // created or its Close method has already been called. However, we need // to call Unlock to both decrement lockCnt and leave the underlying // CriticalPolicySection if we won the race with another goroutine and // now own the lock. - l.Unlock() + lk.Unlock() return ErrInvalidLockState } - if l.handle != 0 { + if lk.handle != 0 { // The underlying CriticalPolicySection is already acquired. // It is an R-Lock (with the W-counterpart owned by the Group Policy service), // meaning that it can be acquired by multiple readers simultaneously. @@ -160,20 +160,20 @@ func (l *PolicyLock) Lock() error { return nil } - return l.lockSlow() + return lk.lockSlow() } // lockSlow calls enterCriticalPolicySection to acquire the underlying GP read lock. // It waits for either the lock to be acquired, or for the Close method to be called. // // l.mu must be held. -func (l *PolicyLock) lockSlow() (err error) { +func (lk *PolicyLock) lockSlow() (err error) { defer func() { if err != nil { // Decrement the counter if the lock cannot be acquired, // and complete the pending close request if we're the last owner. - if l.lockCnt.Add(-2) == 0 { - l.closeInternal() + if lk.lockCnt.Add(-2) == 0 { + lk.closeInternal() } } }() @@ -190,12 +190,12 @@ func (l *PolicyLock) lockSlow() (err error) { resultCh := make(chan policyLockResult) go func() { - closing := l.closing - if l.scope == UserPolicy && l.token != 0 { + closing := lk.closing + if lk.scope == UserPolicy && lk.token != 0 { // Impersonate the user whose critical policy section we want to acquire. runtime.LockOSThread() defer runtime.UnlockOSThread() - if err := impersonateLoggedOnUser(l.token); err != nil { + if err := impersonateLoggedOnUser(lk.token); err != nil { initCh <- err return } @@ -209,10 +209,10 @@ func (l *PolicyLock) lockSlow() (err error) { close(initCh) var machine bool - if l.scope == MachinePolicy { + if lk.scope == MachinePolicy { machine = true } - handle, err := l.enterFn(machine) + handle, err := lk.enterFn(machine) send_result: for { @@ -226,7 +226,7 @@ func (l *PolicyLock) lockSlow() (err error) { // The lock is being closed, and we lost the race to l.closing // it the calling goroutine. if err == nil { - l.leaveFn(handle) + lk.leaveFn(handle) } break send_result default: @@ -247,21 +247,21 @@ func (l *PolicyLock) lockSlow() (err error) { select { case result := <-resultCh: if result.err == nil { - l.handle = result.handle + lk.handle = result.handle } return result.err - case <-l.closing: + case <-lk.closing: return ErrInvalidLockState } } // Unlock unlocks l. // It panics if l is not locked on entry to Unlock. -func (l *PolicyLock) Unlock() { - l.mu.Lock() - defer l.mu.Unlock() +func (lk *PolicyLock) Unlock() { + lk.mu.Lock() + defer lk.mu.Unlock() - lockCnt := l.lockCnt.Add(-2) + lockCnt := lk.lockCnt.Add(-2) if lockCnt < 0 { panic("negative lockCnt") } @@ -273,33 +273,33 @@ func (l *PolicyLock) Unlock() { return } - if l.handle != 0 { + if lk.handle != 0 { // Impersonation is not required to unlock a critical policy section. // The handle we pass determines which mutex will be unlocked. - leaveCriticalPolicySection(l.handle) - l.handle = 0 + leaveCriticalPolicySection(lk.handle) + lk.handle = 0 } if lockCnt == 0 { // Complete the pending close request if there's no more readers. - l.closeInternal() + lk.closeInternal() } } // Close releases resources associated with l. // It is a no-op for the machine policy lock. -func (l *PolicyLock) Close() error { - lockCnt := l.lockCnt.Load() +func (lk *PolicyLock) Close() error { + lockCnt := lk.lockCnt.Load() if lockCnt&1 == 0 { // The lock has never been initialized, or close has already been called. return nil } - close(l.closing) + close(lk.closing) // Unset the LSB to indicate a pending close request. - for !l.lockCnt.CompareAndSwap(lockCnt, lockCnt&^int32(1)) { - lockCnt = l.lockCnt.Load() + for !lk.lockCnt.CompareAndSwap(lockCnt, lockCnt&^int32(1)) { + lockCnt = lk.lockCnt.Load() } if lockCnt != 0 { @@ -307,16 +307,16 @@ func (l *PolicyLock) Close() error { return nil } - return l.closeInternal() + return lk.closeInternal() } -func (l *PolicyLock) closeInternal() error { - if l.token != 0 { - if err := l.token.Close(); err != nil { +func (lk *PolicyLock) closeInternal() error { + if lk.token != 0 { + if err := lk.token.Close(); err != nil { return err } - l.token = 0 + lk.token = 0 } - l.closing = nil + lk.closing = nil return nil } diff --git a/vendor/tailscale.com/util/winutil/gp/zsyscall_windows.go b/vendor/tailscale.com/util/winutil/gp/zsyscall_windows.go index 5e40ec3..41c240c 100644 --- a/vendor/tailscale.com/util/winutil/gp/zsyscall_windows.go +++ b/vendor/tailscale.com/util/winutil/gp/zsyscall_windows.go @@ -50,7 +50,7 @@ var ( ) func impersonateLoggedOnUser(token windows.Token) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateLoggedOnUser.Addr(), 1, uintptr(token), 0, 0) + r1, _, e1 := syscall.SyscallN(procImpersonateLoggedOnUser.Addr(), uintptr(token)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -62,7 +62,7 @@ func enterCriticalPolicySection(machine bool) (handle policyLockHandle, err erro if machine { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procEnterCriticalPolicySection.Addr(), 1, uintptr(_p0), 0, 0) + r0, _, e1 := syscall.SyscallN(procEnterCriticalPolicySection.Addr(), uintptr(_p0)) handle = policyLockHandle(r0) if int32(handle) == 0 { err = errnoErr(e1) @@ -71,7 +71,7 @@ func enterCriticalPolicySection(machine bool) (handle policyLockHandle, err erro } func leaveCriticalPolicySection(handle policyLockHandle) (err error) { - r1, _, e1 := syscall.Syscall(procLeaveCriticalPolicySection.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procLeaveCriticalPolicySection.Addr(), uintptr(handle)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -83,7 +83,7 @@ func refreshPolicyEx(machine bool, flags uint32) (err error) { if machine { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procRefreshPolicyEx.Addr(), 2, uintptr(_p0), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procRefreshPolicyEx.Addr(), uintptr(_p0), uintptr(flags)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -95,7 +95,7 @@ func registerGPNotification(event windows.Handle, machine bool) (err error) { if machine { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procRegisterGPNotification.Addr(), 2, uintptr(event), uintptr(_p0), 0) + r1, _, e1 := syscall.SyscallN(procRegisterGPNotification.Addr(), uintptr(event), uintptr(_p0)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -103,7 +103,7 @@ func registerGPNotification(event windows.Handle, machine bool) (err error) { } func unregisterGPNotification(event windows.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procUnregisterGPNotification.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procUnregisterGPNotification.Addr(), uintptr(event)) if int32(r1) == 0 { err = errnoErr(e1) } diff --git a/vendor/tailscale.com/util/winutil/restartmgr_windows.go b/vendor/tailscale.com/util/winutil/restartmgr_windows.go index a52e2fe..6f549de 100644 --- a/vendor/tailscale.com/util/winutil/restartmgr_windows.go +++ b/vendor/tailscale.com/util/winutil/restartmgr_windows.go @@ -19,7 +19,6 @@ import ( "github.com/dblohm7/wingoes" "golang.org/x/sys/windows" "tailscale.com/types/logger" - "tailscale.com/util/multierr" ) var ( @@ -538,7 +537,7 @@ func (rps RestartableProcesses) Terminate(logf logger.Logf, exitCode uint32, tim } if len(errs) != 0 { - return multierr.New(errs...) + return errors.Join(errs...) } return nil } diff --git a/vendor/tailscale.com/util/winutil/startupinfo_windows.go b/vendor/tailscale.com/util/winutil/startupinfo_windows.go index e04e9ea..edf48fa 100644 --- a/vendor/tailscale.com/util/winutil/startupinfo_windows.go +++ b/vendor/tailscale.com/util/winutil/startupinfo_windows.go @@ -83,8 +83,8 @@ func (sib *StartupInfoBuilder) Resolve() (startupInfo *windows.StartupInfo, inhe // Always create a Unicode environment. createProcessFlags = windows.CREATE_UNICODE_ENVIRONMENT - if l := uint32(len(sib.attrs)); l > 0 { - attrCont, err := windows.NewProcThreadAttributeList(l) + if ln := uint32(len(sib.attrs)); ln > 0 { + attrCont, err := windows.NewProcThreadAttributeList(ln) if err != nil { return nil, false, 0, err } diff --git a/vendor/tailscale.com/util/winutil/winenv/zsyscall_windows.go b/vendor/tailscale.com/util/winutil/winenv/zsyscall_windows.go index 2bdfdd9..7e93c79 100644 --- a/vendor/tailscale.com/util/winutil/winenv/zsyscall_windows.go +++ b/vendor/tailscale.com/util/winutil/winenv/zsyscall_windows.go @@ -55,7 +55,7 @@ func isDeviceRegisteredWithManagement(isMDMRegistered *bool, upnBufLen uint32, u if *isMDMRegistered { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procIsDeviceRegisteredWithManagement.Addr(), 3, uintptr(unsafe.Pointer(&_p0)), uintptr(upnBufLen), uintptr(unsafe.Pointer(upnBuf))) + r0, _, e1 := syscall.SyscallN(procIsDeviceRegisteredWithManagement.Addr(), uintptr(unsafe.Pointer(&_p0)), uintptr(upnBufLen), uintptr(unsafe.Pointer(upnBuf))) *isMDMRegistered = _p0 != 0 hr = int32(r0) if hr == 0 { @@ -65,13 +65,13 @@ func isDeviceRegisteredWithManagement(isMDMRegistered *bool, upnBufLen uint32, u } func verSetConditionMask(condMask verCondMask, typ verTypeMask, cond verCond) (res verCondMask) { - r0, _, _ := syscall.Syscall(procVerSetConditionMask.Addr(), 3, uintptr(condMask), uintptr(typ), uintptr(cond)) + r0, _, _ := syscall.SyscallN(procVerSetConditionMask.Addr(), uintptr(condMask), uintptr(typ), uintptr(cond)) res = verCondMask(r0) return } func verifyVersionInfo(verInfo *osVersionInfoEx, typ verTypeMask, cond verCondMask) (res bool) { - r0, _, _ := syscall.Syscall(procVerifyVersionInfoW.Addr(), 3, uintptr(unsafe.Pointer(verInfo)), uintptr(typ), uintptr(cond)) + r0, _, _ := syscall.SyscallN(procVerifyVersionInfoW.Addr(), uintptr(unsafe.Pointer(verInfo)), uintptr(typ), uintptr(cond)) res = r0 != 0 return } diff --git a/vendor/tailscale.com/util/winutil/winutil_windows.go b/vendor/tailscale.com/util/winutil/winutil_windows.go index 5dde9a3..c935b21 100644 --- a/vendor/tailscale.com/util/winutil/winutil_windows.go +++ b/vendor/tailscale.com/util/winutil/winutil_windows.go @@ -8,8 +8,10 @@ import ( "fmt" "log" "math" + "os" "os/exec" "os/user" + "path/filepath" "reflect" "runtime" "strings" @@ -33,6 +35,10 @@ var ErrNoShell = errors.New("no Shell process is present") // ErrNoValue is returned when the value doesn't exist in the registry. var ErrNoValue = registry.ErrNotExist +// ErrBadRegValueFormat is returned when a string value does not match the +// expected format. +var ErrBadRegValueFormat = errors.New("registry value formatted incorrectly") + // GetDesktopPID searches the PID of the process that's running the // currently active desktop. Returns ErrNoShell if the shell is not present. // Usually the PID will be for explorer.exe. @@ -947,3 +953,22 @@ func IsDomainName(name string) (bool, error) { return isDomainName(name16) } + +// GUIPathFromReg obtains the path to the client GUI executable from the +// registry value that was written during installation. +func GUIPathFromReg() (string, error) { + regPath, err := GetRegString("GUIPath") + if err != nil { + return "", err + } + + if !filepath.IsAbs(regPath) { + return "", ErrBadRegValueFormat + } + + if _, err := os.Stat(regPath); err != nil { + return "", err + } + + return regPath, nil +} diff --git a/vendor/tailscale.com/util/winutil/zsyscall_windows.go b/vendor/tailscale.com/util/winutil/zsyscall_windows.go index b4674df..56aedb4 100644 --- a/vendor/tailscale.com/util/winutil/zsyscall_windows.go +++ b/vendor/tailscale.com/util/winutil/zsyscall_windows.go @@ -62,7 +62,7 @@ var ( ) func queryServiceConfig2(hService windows.Handle, infoLevel uint32, buf *byte, bufLen uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(hService), uintptr(infoLevel), uintptr(unsafe.Pointer(buf)), uintptr(bufLen), uintptr(unsafe.Pointer(bytesNeeded)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceConfig2W.Addr(), uintptr(hService), uintptr(infoLevel), uintptr(unsafe.Pointer(buf)), uintptr(bufLen), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -70,19 +70,19 @@ func queryServiceConfig2(hService windows.Handle, infoLevel uint32, buf *byte, b } func getApplicationRestartSettings(process windows.Handle, commandLine *uint16, commandLineLen *uint32, flags *uint32) (ret wingoes.HRESULT) { - r0, _, _ := syscall.Syscall6(procGetApplicationRestartSettings.Addr(), 4, uintptr(process), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(commandLineLen)), uintptr(unsafe.Pointer(flags)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetApplicationRestartSettings.Addr(), uintptr(process), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(commandLineLen)), uintptr(unsafe.Pointer(flags))) ret = wingoes.HRESULT(r0) return } func registerApplicationRestart(cmdLineExclExeName *uint16, flags uint32) (ret wingoes.HRESULT) { - r0, _, _ := syscall.Syscall(procRegisterApplicationRestart.Addr(), 2, uintptr(unsafe.Pointer(cmdLineExclExeName)), uintptr(flags), 0) + r0, _, _ := syscall.SyscallN(procRegisterApplicationRestart.Addr(), uintptr(unsafe.Pointer(cmdLineExclExeName)), uintptr(flags)) ret = wingoes.HRESULT(r0) return } func dsGetDcName(computerName *uint16, domainName *uint16, domainGuid *windows.GUID, siteName *uint16, flags dsGetDcNameFlag, dcInfo **_DOMAIN_CONTROLLER_INFO) (ret error) { - r0, _, _ := syscall.Syscall6(procDsGetDcNameW.Addr(), 6, uintptr(unsafe.Pointer(computerName)), uintptr(unsafe.Pointer(domainName)), uintptr(unsafe.Pointer(domainGuid)), uintptr(unsafe.Pointer(siteName)), uintptr(flags), uintptr(unsafe.Pointer(dcInfo))) + r0, _, _ := syscall.SyscallN(procDsGetDcNameW.Addr(), uintptr(unsafe.Pointer(computerName)), uintptr(unsafe.Pointer(domainName)), uintptr(unsafe.Pointer(domainGuid)), uintptr(unsafe.Pointer(siteName)), uintptr(flags), uintptr(unsafe.Pointer(dcInfo))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -90,7 +90,7 @@ func dsGetDcName(computerName *uint16, domainName *uint16, domainGuid *windows.G } func netValidateName(server *uint16, name *uint16, account *uint16, password *uint16, nameType _NETSETUP_NAME_TYPE) (ret error) { - r0, _, _ := syscall.Syscall6(procNetValidateName.Addr(), 5, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(account)), uintptr(unsafe.Pointer(password)), uintptr(nameType), 0) + r0, _, _ := syscall.SyscallN(procNetValidateName.Addr(), uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(account)), uintptr(unsafe.Pointer(password)), uintptr(nameType)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -98,7 +98,7 @@ func netValidateName(server *uint16, name *uint16, account *uint16, password *ui } func rmEndSession(session _RMHANDLE) (ret error) { - r0, _, _ := syscall.Syscall(procRmEndSession.Addr(), 1, uintptr(session), 0, 0) + r0, _, _ := syscall.SyscallN(procRmEndSession.Addr(), uintptr(session)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -106,7 +106,7 @@ func rmEndSession(session _RMHANDLE) (ret error) { } func rmGetList(session _RMHANDLE, nProcInfoNeeded *uint32, nProcInfo *uint32, rgAffectedApps *_RM_PROCESS_INFO, pRebootReasons *uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procRmGetList.Addr(), 5, uintptr(session), uintptr(unsafe.Pointer(nProcInfoNeeded)), uintptr(unsafe.Pointer(nProcInfo)), uintptr(unsafe.Pointer(rgAffectedApps)), uintptr(unsafe.Pointer(pRebootReasons)), 0) + r0, _, _ := syscall.SyscallN(procRmGetList.Addr(), uintptr(session), uintptr(unsafe.Pointer(nProcInfoNeeded)), uintptr(unsafe.Pointer(nProcInfo)), uintptr(unsafe.Pointer(rgAffectedApps)), uintptr(unsafe.Pointer(pRebootReasons))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -114,7 +114,7 @@ func rmGetList(session _RMHANDLE, nProcInfoNeeded *uint32, nProcInfo *uint32, rg } func rmJoinSession(pSession *_RMHANDLE, sessionKey *uint16) (ret error) { - r0, _, _ := syscall.Syscall(procRmJoinSession.Addr(), 2, uintptr(unsafe.Pointer(pSession)), uintptr(unsafe.Pointer(sessionKey)), 0) + r0, _, _ := syscall.SyscallN(procRmJoinSession.Addr(), uintptr(unsafe.Pointer(pSession)), uintptr(unsafe.Pointer(sessionKey))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -122,7 +122,7 @@ func rmJoinSession(pSession *_RMHANDLE, sessionKey *uint16) (ret error) { } func rmRegisterResources(session _RMHANDLE, nFiles uint32, rgsFileNames **uint16, nApplications uint32, rgApplications *_RM_UNIQUE_PROCESS, nServices uint32, rgsServiceNames **uint16) (ret error) { - r0, _, _ := syscall.Syscall9(procRmRegisterResources.Addr(), 7, uintptr(session), uintptr(nFiles), uintptr(unsafe.Pointer(rgsFileNames)), uintptr(nApplications), uintptr(unsafe.Pointer(rgApplications)), uintptr(nServices), uintptr(unsafe.Pointer(rgsServiceNames)), 0, 0) + r0, _, _ := syscall.SyscallN(procRmRegisterResources.Addr(), uintptr(session), uintptr(nFiles), uintptr(unsafe.Pointer(rgsFileNames)), uintptr(nApplications), uintptr(unsafe.Pointer(rgApplications)), uintptr(nServices), uintptr(unsafe.Pointer(rgsServiceNames))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -130,7 +130,7 @@ func rmRegisterResources(session _RMHANDLE, nFiles uint32, rgsFileNames **uint16 } func rmStartSession(pSession *_RMHANDLE, flags uint32, sessionKey *uint16) (ret error) { - r0, _, _ := syscall.Syscall(procRmStartSession.Addr(), 3, uintptr(unsafe.Pointer(pSession)), uintptr(flags), uintptr(unsafe.Pointer(sessionKey))) + r0, _, _ := syscall.SyscallN(procRmStartSession.Addr(), uintptr(unsafe.Pointer(pSession)), uintptr(flags), uintptr(unsafe.Pointer(sessionKey))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -138,7 +138,7 @@ func rmStartSession(pSession *_RMHANDLE, flags uint32, sessionKey *uint16) (ret } func expandEnvironmentStringsForUser(token windows.Token, src *uint16, dst *uint16, dstLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procExpandEnvironmentStringsForUserW.Addr(), 4, uintptr(token), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(dstLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procExpandEnvironmentStringsForUserW.Addr(), uintptr(token), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(dstLen)) if int32(r1) == 0 { err = errnoErr(e1) } @@ -146,7 +146,7 @@ func expandEnvironmentStringsForUser(token windows.Token, src *uint16, dst *uint } func loadUserProfile(token windows.Token, profileInfo *_PROFILEINFO) (err error) { - r1, _, e1 := syscall.Syscall(procLoadUserProfileW.Addr(), 2, uintptr(token), uintptr(unsafe.Pointer(profileInfo)), 0) + r1, _, e1 := syscall.SyscallN(procLoadUserProfileW.Addr(), uintptr(token), uintptr(unsafe.Pointer(profileInfo))) if int32(r1) == 0 { err = errnoErr(e1) } @@ -154,7 +154,7 @@ func loadUserProfile(token windows.Token, profileInfo *_PROFILEINFO) (err error) } func unloadUserProfile(token windows.Token, profile registry.Key) (err error) { - r1, _, e1 := syscall.Syscall(procUnloadUserProfile.Addr(), 2, uintptr(token), uintptr(profile), 0) + r1, _, e1 := syscall.SyscallN(procUnloadUserProfile.Addr(), uintptr(token), uintptr(profile)) if int32(r1) == 0 { err = errnoErr(e1) } diff --git a/vendor/tailscale.com/version/cmdname.go b/vendor/tailscale.com/version/cmdname.go index 51e0654..c38544c 100644 --- a/vendor/tailscale.com/version/cmdname.go +++ b/vendor/tailscale.com/version/cmdname.go @@ -12,7 +12,7 @@ import ( "io" "os" "path" - "path/filepath" + "runtime" "strings" ) @@ -30,7 +30,7 @@ func CmdName() string { func cmdName(exe string) string { // fallbackName, the lowercase basename of the executable, is what we return if // we can't find the Go module metadata embedded in the file. - fallbackName := filepath.Base(strings.TrimSuffix(strings.ToLower(exe), ".exe")) + fallbackName := prepExeNameForCmp(exe, runtime.GOARCH) var ret string info, err := findModuleInfo(exe) @@ -45,10 +45,10 @@ func cmdName(exe string) string { break } } - if strings.HasPrefix(ret, "wg") && fallbackName == "tailscale-ipn" { - // The tailscale-ipn.exe binary for internal build system packaging reasons - // has a path of "tailscale.io/win/wg64", "tailscale.io/win/wg32", etc. - // Ignore that name and use "tailscale-ipn" instead. + if runtime.GOOS == "windows" && strings.HasPrefix(ret, "gui") && checkPreppedExeNameForGUI(fallbackName) { + // The GUI binary for internal build system packaging reasons + // has a path of "tailscale.io/win/gui". + // Ignore that name and use fallbackName instead. return fallbackName } if ret == "" { diff --git a/vendor/tailscale.com/version/distro/distro.go b/vendor/tailscale.com/version/distro/distro.go index f7997e1..0e88bdd 100644 --- a/vendor/tailscale.com/version/distro/distro.go +++ b/vendor/tailscale.com/version/distro/distro.go @@ -9,6 +9,7 @@ import ( "os" "runtime" "strconv" + "strings" "tailscale.com/types/lazy" "tailscale.com/util/lineiter" @@ -31,6 +32,7 @@ const ( Unraid = Distro("unraid") Alpine = Distro("alpine") UBNT = Distro("ubnt") // Ubiquiti Networks + JetKVM = Distro("jetkvm") ) var distro lazy.SyncValue[Distro] @@ -102,10 +104,20 @@ func linuxDistro() Distro { return Unraid case have("/etc/alpine-release"): return Alpine + case runtime.GOARCH == "arm" && isDeviceModel("JetKVM"): + return JetKVM } return "" } +func isDeviceModel(want string) bool { + if runtime.GOOS != "linux" { + return false + } + v, _ := os.ReadFile("/sys/firmware/devicetree/base/model") + return want == strings.Trim(string(v), "\x00\r\n\t ") +} + func freebsdDistro() Distro { switch { case have("/etc/pfSense-rc"): diff --git a/vendor/tailscale.com/version/exename.go b/vendor/tailscale.com/version/exename.go new file mode 100644 index 0000000..d5047c2 --- /dev/null +++ b/vendor/tailscale.com/version/exename.go @@ -0,0 +1,25 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package version + +import ( + "path/filepath" + "strings" +) + +// prepExeNameForCmp strips any extension and arch suffix from exe, and +// lowercases it. +func prepExeNameForCmp(exe, arch string) string { + baseNoExt := strings.ToLower(strings.TrimSuffix(filepath.Base(exe), filepath.Ext(exe))) + archSuffix := "-" + arch + return strings.TrimSuffix(baseNoExt, archSuffix) +} + +func checkPreppedExeNameForGUI(preppedExeName string) bool { + return preppedExeName == "tailscale-ipn" || preppedExeName == "tailscale-gui" +} + +func isGUIExeName(exe, arch string) bool { + return checkPreppedExeNameForGUI(prepExeNameForCmp(exe, arch)) +} diff --git a/vendor/tailscale.com/version/print.go b/vendor/tailscale.com/version/print.go index be90432..43ee2b5 100644 --- a/vendor/tailscale.com/version/print.go +++ b/vendor/tailscale.com/version/print.go @@ -20,6 +20,7 @@ var stringLazy = sync.OnceValue(func() string { if gitCommit() != "" { fmt.Fprintf(&ret, " tailscale commit: %s%s\n", gitCommit(), dirtyString()) } + fmt.Fprintf(&ret, " long version: %s\n", Long()) if extraGitCommitStamp != "" { fmt.Fprintf(&ret, " other commit: %s\n", extraGitCommitStamp) } diff --git a/vendor/tailscale.com/version/prop.go b/vendor/tailscale.com/version/prop.go index 9327e6f..0d6a5c0 100644 --- a/vendor/tailscale.com/version/prop.go +++ b/vendor/tailscale.com/version/prop.go @@ -159,7 +159,9 @@ func IsWindowsGUI() bool { if err != nil { return false } - return strings.EqualFold(exe, "tailscale-ipn.exe") || strings.EqualFold(exe, "tailscale-ipn") + // It is okay to use GOARCH here because we're checking whether our + // _own_ process is the GUI. + return isGUIExeName(exe, runtime.GOARCH) }) } diff --git a/vendor/tailscale.com/wgengine/magicsock/batching_conn.go b/vendor/tailscale.com/wgengine/magicsock/batching_conn.go deleted file mode 100644 index 5320d1c..0000000 --- a/vendor/tailscale.com/wgengine/magicsock/batching_conn.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package magicsock - -import ( - "net/netip" - - "golang.org/x/net/ipv4" - "golang.org/x/net/ipv6" - "tailscale.com/types/nettype" -) - -var ( - // This acts as a compile-time check for our usage of ipv6.Message in - // batchingConn for both IPv6 and IPv4 operations. - _ ipv6.Message = ipv4.Message{} -) - -// batchingConn is a nettype.PacketConn that provides batched i/o. -type batchingConn interface { - nettype.PacketConn - ReadBatch(msgs []ipv6.Message, flags int) (n int, err error) - WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error -} diff --git a/vendor/tailscale.com/wgengine/magicsock/batching_conn_default.go b/vendor/tailscale.com/wgengine/magicsock/batching_conn_default.go deleted file mode 100644 index 519cf80..0000000 --- a/vendor/tailscale.com/wgengine/magicsock/batching_conn_default.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !linux - -package magicsock - -import ( - "tailscale.com/types/nettype" -) - -func tryUpgradeToBatchingConn(pconn nettype.PacketConn, _ string, _ int) nettype.PacketConn { - return pconn -} diff --git a/vendor/tailscale.com/wgengine/magicsock/blockforever_conn.go b/vendor/tailscale.com/wgengine/magicsock/blockforever_conn.go index f2e85dc..272a125 100644 --- a/vendor/tailscale.com/wgengine/magicsock/blockforever_conn.go +++ b/vendor/tailscale.com/wgengine/magicsock/blockforever_conn.go @@ -10,11 +10,13 @@ import ( "sync" "syscall" "time" + + "tailscale.com/syncs" ) // blockForeverConn is a net.PacketConn whose reads block until it is closed. type blockForeverConn struct { - mu sync.Mutex + mu syncs.Mutex cond *sync.Cond closed bool } diff --git a/vendor/tailscale.com/wgengine/magicsock/cloudinfo_nocloud.go b/vendor/tailscale.com/wgengine/magicsock/cloudinfo_nocloud.go deleted file mode 100644 index b4414d3..0000000 --- a/vendor/tailscale.com/wgengine/magicsock/cloudinfo_nocloud.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build ios || android || js - -package magicsock - -import ( - "context" - "net/netip" - - "tailscale.com/types/logger" -) - -type cloudInfo struct{} - -func newCloudInfo(_ logger.Logf) *cloudInfo { - return &cloudInfo{} -} - -func (ci *cloudInfo) GetPublicIPs(_ context.Context) ([]netip.Addr, error) { - return nil, nil -} diff --git a/vendor/tailscale.com/wgengine/magicsock/debughttp.go b/vendor/tailscale.com/wgengine/magicsock/debughttp.go index aa109c2..9aecab7 100644 --- a/vendor/tailscale.com/wgengine/magicsock/debughttp.go +++ b/vendor/tailscale.com/wgengine/magicsock/debughttp.go @@ -13,6 +13,8 @@ import ( "strings" "time" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/tailcfg" "tailscale.com/tstime/mono" "tailscale.com/types/key" @@ -24,6 +26,11 @@ import ( // /debug/magicsock) or via peerapi to a peer that's owned by the same // user (so they can e.g. inspect their phones). func (c *Conn) ServeHTTPDebug(w http.ResponseWriter, r *http.Request) { + if !buildfeatures.HasDebug { + http.Error(w, feature.ErrUnavailable.Error(), http.StatusNotImplemented) + return + } + c.mu.Lock() defer c.mu.Unlock() @@ -72,18 +79,18 @@ func (c *Conn) ServeHTTPDebug(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "

      # ip:port to endpoint

        ") { type kv struct { - ipp netip.AddrPort - pi *peerInfo + addr epAddr + pi *peerInfo } - ent := make([]kv, 0, len(c.peerMap.byIPPort)) - for k, v := range c.peerMap.byIPPort { + ent := make([]kv, 0, len(c.peerMap.byEpAddr)) + for k, v := range c.peerMap.byEpAddr { ent = append(ent, kv{k, v}) } - sort.Slice(ent, func(i, j int) bool { return ipPortLess(ent[i].ipp, ent[j].ipp) }) + sort.Slice(ent, func(i, j int) bool { return epAddrLess(ent[i].addr, ent[j].addr) }) for _, e := range ent { ep := e.pi.ep shortStr := ep.publicKey.ShortString() - fmt.Fprintf(w, "
      • %v: %v
      • \n", e.ipp, strings.Trim(shortStr, "[]"), shortStr) + fmt.Fprintf(w, "
      • %v: %v
      • \n", e.addr, strings.Trim(shortStr, "[]"), shortStr) } } @@ -148,11 +155,11 @@ func printEndpointHTML(w io.Writer, ep *endpoint) { for ipp := range ep.endpointState { eps = append(eps, ipp) } - sort.Slice(eps, func(i, j int) bool { return ipPortLess(eps[i], eps[j]) }) + sort.Slice(eps, func(i, j int) bool { return addrPortLess(eps[i], eps[j]) }) io.WriteString(w, "

        Endpoints:

          ") for _, ipp := range eps { s := ep.endpointState[ipp] - if ipp == ep.bestAddr.AddrPort { + if ipp == ep.bestAddr.ap && !ep.bestAddr.vni.IsSet() { fmt.Fprintf(w, "
        • %s: (best)
            ", ipp) } else { fmt.Fprintf(w, "
          • %s: ...
              ", ipp) @@ -196,9 +203,19 @@ func peerDebugName(p tailcfg.NodeView) string { return p.Hostinfo().Hostname() } -func ipPortLess(a, b netip.AddrPort) bool { +func addrPortLess(a, b netip.AddrPort) bool { if v := a.Addr().Compare(b.Addr()); v != 0 { return v < 0 } return a.Port() < b.Port() } + +func epAddrLess(a, b epAddr) bool { + if v := a.ap.Addr().Compare(b.ap.Addr()); v != 0 { + return v < 0 + } + if a.ap.Port() == b.ap.Port() { + return a.vni.Get() < b.vni.Get() + } + return a.ap.Port() < b.ap.Port() +} diff --git a/vendor/tailscale.com/wgengine/magicsock/debugknobs.go b/vendor/tailscale.com/wgengine/magicsock/debugknobs.go index f8fd9f0..b0a47ff 100644 --- a/vendor/tailscale.com/wgengine/magicsock/debugknobs.go +++ b/vendor/tailscale.com/wgengine/magicsock/debugknobs.go @@ -62,6 +62,9 @@ var ( // //lint:ignore U1000 used on Linux/Darwin only debugPMTUD = envknob.RegisterBool("TS_DEBUG_PMTUD") + // debugNeverDirectUDP disables the use of direct UDP connections, forcing + // all peer communication over DERP or peer relay. + debugNeverDirectUDP = envknob.RegisterBool("TS_DEBUG_NEVER_DIRECT_UDP") // Hey you! Adding a new debugknob? Make sure to stub it out in the // debugknobs_stubs.go file too. ) diff --git a/vendor/tailscale.com/wgengine/magicsock/debugknobs_stubs.go b/vendor/tailscale.com/wgengine/magicsock/debugknobs_stubs.go index 336d7ba..7dee1d6 100644 --- a/vendor/tailscale.com/wgengine/magicsock/debugknobs_stubs.go +++ b/vendor/tailscale.com/wgengine/magicsock/debugknobs_stubs.go @@ -31,3 +31,4 @@ func debugRingBufferMaxSizeBytes() int { return 0 } func inTest() bool { return false } func debugPeerMap() bool { return false } func pretendpoints() []netip.AddrPort { return []netip.AddrPort{} } +func debugNeverDirectUDP() bool { return false } diff --git a/vendor/tailscale.com/wgengine/magicsock/derp.go b/vendor/tailscale.com/wgengine/magicsock/derp.go index ffdff14..1c5225e 100644 --- a/vendor/tailscale.com/wgengine/magicsock/derp.go +++ b/vendor/tailscale.com/wgengine/magicsock/derp.go @@ -11,9 +11,7 @@ import ( "net" "net/netip" "reflect" - "runtime" "slices" - "sync" "time" "unsafe" @@ -21,7 +19,6 @@ import ( "tailscale.com/derp" "tailscale.com/derp/derphttp" "tailscale.com/health" - "tailscale.com/logtail/backoff" "tailscale.com/net/dnscache" "tailscale.com/net/netcheck" "tailscale.com/net/tsaddr" @@ -30,9 +27,9 @@ import ( "tailscale.com/tstime/mono" "tailscale.com/types/key" "tailscale.com/types/logger" + "tailscale.com/util/backoff" "tailscale.com/util/mak" "tailscale.com/util/rands" - "tailscale.com/util/sysresources" "tailscale.com/util/testenv" ) @@ -94,7 +91,7 @@ func (c *Conn) fallbackDERPRegionForPeer(peer key.NodePublic) (regionID int) { type activeDerp struct { c *derphttp.Client cancel context.CancelFunc - writeCh chan<- derpWriteRequest + writeCh chan derpWriteRequest // lastWrite is the time of the last request for its write // channel (currently even if there was no write). // It is always non-nil and initialized to a non-zero Time. @@ -219,17 +216,28 @@ func (c *Conn) derpRegionCodeLocked(regionID int) string { return "" } +// setHomeDERPGaugeLocked updates the home DERP gauge metric. +// +// c.mu must be held. +func (c *Conn) setHomeDERPGaugeLocked(derpNum int) { + if c.homeDERPGauge != nil { + c.homeDERPGauge.Set(float64(derpNum)) + } +} + // c.mu must NOT be held. func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) { c.mu.Lock() defer c.mu.Unlock() if !c.wantDerpLocked() { c.myDerp = 0 + c.setHomeDERPGaugeLocked(0) c.health.SetMagicSockDERPHome(0, c.homeless) return false } if c.homeless { c.myDerp = 0 + c.setHomeDERPGaugeLocked(0) c.health.SetMagicSockDERPHome(0, c.homeless) return false } @@ -241,6 +249,7 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) { metricDERPHomeChange.Add(1) } c.myDerp = derpNum + c.setHomeDERPGaugeLocked(derpNum) c.health.SetMagicSockDERPHome(derpNum, c.homeless) if c.privateKey.IsZero() { @@ -282,59 +291,20 @@ func (c *Conn) goDerpConnect(regionID int) { go c.derpWriteChanForRegion(regionID, key.NodePublic{}) } -var ( - bufferedDerpWrites int - bufferedDerpWritesOnce sync.Once -) - -// bufferedDerpWritesBeforeDrop returns how many packets writes can be queued -// up the DERP client to write on the wire before we start dropping. -func bufferedDerpWritesBeforeDrop() int { - // For mobile devices, always return the previous minimum value of 32; - // we can do this outside the sync.Once to avoid that overhead. - if runtime.GOOS == "ios" || runtime.GOOS == "android" { - return 32 - } - - bufferedDerpWritesOnce.Do(func() { - // Some rough sizing: for the previous fixed value of 32, the - // total consumed memory can be: - // = numDerpRegions * messages/region * sizeof(message) - // - // For sake of this calculation, assume 100 DERP regions; at - // time of writing (2023-04-03), we have 24. - // - // A reasonable upper bound for the worst-case average size of - // a message is a *disco.CallMeMaybe message with 16 endpoints; - // since sizeof(netip.AddrPort) = 32, that's 512 bytes. Thus: - // = 100 * 32 * 512 - // = 1638400 (1.6MiB) - // - // On a reasonably-small node with 4GiB of memory that's - // connected to each region and handling a lot of load, 1.6MiB - // is about 0.04% of the total system memory. - // - // For sake of this calculation, then, let's double that memory - // usage to 0.08% and scale based on total system memory. - // - // For a 16GiB Linux box, this should buffer just over 256 - // messages. - systemMemory := sysresources.TotalMemory() - memoryUsable := float64(systemMemory) * 0.0008 - - const ( - theoreticalDERPRegions = 100 - messageMaximumSizeBytes = 512 - ) - bufferedDerpWrites = int(memoryUsable / (theoreticalDERPRegions * messageMaximumSizeBytes)) - - // Never drop below the previous minimum value. - if bufferedDerpWrites < 32 { - bufferedDerpWrites = 32 - } - }) - return bufferedDerpWrites -} +// derpWriteQueueDepth is the depth of the in-process write queue to a single +// DERP region. DERP connections are TCP, and so the actual write queue depth is +// substantially larger than this suggests - often scaling into megabytes +// depending on dynamic TCP parameters and platform TCP tuning. This queue is +// excess of the TCP buffer depth, which means it's almost pure buffer bloat, +// and does not want to be deep - if there are key situations where a node can't +// keep up, either the TCP link to DERP is too slow, or there is a +// synchronization issue in the write path, fixes should be focused on those +// paths, rather than extending this queue. +// TODO(raggi): make this even shorter, ideally this should be a fairly direct +// line into a socket TCP buffer. The challenge at present is that connect and +// reconnect are in the write path and we don't want to block other write +// operations on those. +const derpWriteQueueDepth = 32 // derpWriteChanForRegion returns a channel to which to send DERP packet write // requests. It creates a new DERP connection to regionID if necessary. @@ -344,7 +314,7 @@ func bufferedDerpWritesBeforeDrop() int { // // It returns nil if the network is down, the Conn is closed, or the regionID is // not known. -func (c *Conn) derpWriteChanForRegion(regionID int, peer key.NodePublic) chan<- derpWriteRequest { +func (c *Conn) derpWriteChanForRegion(regionID int, peer key.NodePublic) chan derpWriteRequest { if c.networkDown() { return nil } @@ -429,7 +399,7 @@ func (c *Conn) derpWriteChanForRegion(regionID int, peer key.NodePublic) chan<- dc.DNSCache = dnscache.Get() ctx, cancel := context.WithCancel(c.connCtx) - ch := make(chan derpWriteRequest, bufferedDerpWritesBeforeDrop()) + ch := make(chan derpWriteRequest, derpWriteQueueDepth) ad.c = dc ad.writeCh = ch @@ -740,8 +710,11 @@ func (c *Conn) processDERPReadResult(dm derpReadResult, b []byte) (n int, ep *en return 0, nil } - ipp := netip.AddrPortFrom(tailcfg.DerpMagicIPAddr, uint16(regionID)) - if c.handleDiscoMessage(b[:n], ipp, dm.src, discoRXPathDERP) { + srcAddr := epAddr{ap: netip.AddrPortFrom(tailcfg.DerpMagicIPAddr, uint16(regionID))} + pt, isGeneveEncap := packetLooksLike(b[:n]) + if pt == packetLooksLikeDisco && + !isGeneveEncap { // We should never receive Geneve-encapsulated disco over DERP. + c.handleDiscoMessage(b[:n], srcAddr, false, dm.src, discoRXPathDERP) return 0, nil } @@ -755,9 +728,9 @@ func (c *Conn) processDERPReadResult(dm derpReadResult, b []byte) (n int, ep *en return 0, nil } - ep.noteRecvActivity(ipp, mono.Now()) - if stats := c.stats.Load(); stats != nil { - stats.UpdateRxPhysical(ep.nodeAddr, ipp, 1, dm.n) + ep.noteRecvActivity(srcAddr, mono.Now()) + if update := c.connCounter.Load(); update != nil { + update(0, netip.AddrPortFrom(ep.nodeAddr, 0), srcAddr.ap, 1, dm.n, true) } c.metrics.inboundPacketsDERPTotal.Add(1) @@ -875,7 +848,6 @@ func (c *Conn) maybeCloseDERPsOnRebind(okayLocalIPs []netip.Prefix) { c.closeOrReconnectDERPLocked(regionID, "rebind-default-route-change") continue } - regionID := regionID dc := ad.c go func() { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) diff --git a/vendor/tailscale.com/wgengine/magicsock/disco_atomic.go b/vendor/tailscale.com/wgengine/magicsock/disco_atomic.go new file mode 100644 index 0000000..5b765fb --- /dev/null +++ b/vendor/tailscale.com/wgengine/magicsock/disco_atomic.go @@ -0,0 +1,58 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package magicsock + +import ( + "sync/atomic" + + "tailscale.com/types/key" +) + +type discoKeyPair struct { + private key.DiscoPrivate + public key.DiscoPublic + short string // public.ShortString() +} + +// discoAtomic is an atomic container for a disco private key, public key, and +// the public key's ShortString. The private and public keys are always kept +// synchronized. +// +// The zero value is not ready for use. Use [Set] to provide a usable value. +type discoAtomic struct { + pair atomic.Pointer[discoKeyPair] +} + +// Pair returns the private and public keys together atomically. +// Code that needs both the private and public keys synchronized should +// use Pair instead of calling Private and Public separately. +func (dk *discoAtomic) Pair() (key.DiscoPrivate, key.DiscoPublic) { + p := dk.pair.Load() + return p.private, p.public +} + +// Private returns the private key. +func (dk *discoAtomic) Private() key.DiscoPrivate { + return dk.pair.Load().private +} + +// Public returns the public key. +func (dk *discoAtomic) Public() key.DiscoPublic { + return dk.pair.Load().public +} + +// Short returns the short string of the public key (see [DiscoPublic.ShortString]). +func (dk *discoAtomic) Short() string { + return dk.pair.Load().short +} + +// Set updates the private key (and the cached public key and short string). +func (dk *discoAtomic) Set(private key.DiscoPrivate) { + public := private.Public() + dk.pair.Store(&discoKeyPair{ + private: private, + public: public, + short: public.ShortString(), + }) +} diff --git a/vendor/tailscale.com/wgengine/magicsock/discopingpurpose_string.go b/vendor/tailscale.com/wgengine/magicsock/discopingpurpose_string.go index 3dc327d..8eebf97 100644 --- a/vendor/tailscale.com/wgengine/magicsock/discopingpurpose_string.go +++ b/vendor/tailscale.com/wgengine/magicsock/discopingpurpose_string.go @@ -22,8 +22,9 @@ const _discoPingPurpose_name = "DiscoveryHeartbeatCLIHeartbeatForUDPLifetime" var _discoPingPurpose_index = [...]uint8{0, 9, 18, 21, 44} func (i discoPingPurpose) String() string { - if i < 0 || i >= discoPingPurpose(len(_discoPingPurpose_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_discoPingPurpose_index)-1 { return "discoPingPurpose(" + strconv.FormatInt(int64(i), 10) + ")" } - return _discoPingPurpose_name[_discoPingPurpose_index[i]:_discoPingPurpose_index[i+1]] + return _discoPingPurpose_name[_discoPingPurpose_index[idx]:_discoPingPurpose_index[idx+1]] } diff --git a/vendor/tailscale.com/wgengine/magicsock/endpoint.go b/vendor/tailscale.com/wgengine/magicsock/endpoint.go index 0c48acd..eda589e 100644 --- a/vendor/tailscale.com/wgengine/magicsock/endpoint.go +++ b/vendor/tailscale.com/wgengine/magicsock/endpoint.go @@ -17,7 +17,6 @@ import ( "reflect" "runtime" "slices" - "sync" "sync/atomic" "time" @@ -25,14 +24,16 @@ import ( "golang.org/x/net/ipv6" "tailscale.com/disco" "tailscale.com/ipn/ipnstate" + "tailscale.com/net/packet" "tailscale.com/net/stun" "tailscale.com/net/tstun" + "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tstime/mono" "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/util/mak" - "tailscale.com/util/ringbuffer" + "tailscale.com/util/ringlog" "tailscale.com/util/slicesx" ) @@ -59,7 +60,7 @@ type endpoint struct { lastRecvWG mono.Time // last time there were incoming packets from this peer destined for wireguard-go (e.g. not disco) lastRecvUDPAny mono.Time // last time there were incoming UDP packets from this peer of any kind numStopAndResetAtomic int64 - debugUpdates *ringbuffer.RingBuffer[EndpointChange] + debugUpdates *ringlog.RingLog[EndpointChange] // These fields are initialized once and never modified. c *Conn @@ -72,19 +73,20 @@ type endpoint struct { disco atomic.Pointer[endpointDisco] // if the peer supports disco, the key and short string // mu protects all following fields. - mu sync.Mutex // Lock ordering: Conn.mu, then endpoint.mu + mu syncs.Mutex // Lock ordering: Conn.mu, then endpoint.mu - heartBeatTimer *time.Timer // nil when idle - lastSendExt mono.Time // last time there were outgoing packets sent to this peer from an external trigger (e.g. wireguard-go or disco pingCLI) - lastSendAny mono.Time // last time there were outgoing packets sent this peer from any trigger, internal or external to magicsock - lastFullPing mono.Time // last time we pinged all disco or wireguard only endpoints - derpAddr netip.AddrPort // fallback/bootstrap path, if non-zero (non-zero for well-behaved clients) + heartBeatTimer *time.Timer // nil when idle + lastSendExt mono.Time // last time there were outgoing packets sent to this peer from an external trigger (e.g. wireguard-go or disco pingCLI) + lastSendAny mono.Time // last time there were outgoing packets sent this peer from any trigger, internal or external to magicsock + lastFullPing mono.Time // last time we pinged all disco or wireguard only endpoints + lastUDPRelayPathDiscovery mono.Time // last time we ran UDP relay path discovery + derpAddr netip.AddrPort // fallback/bootstrap path, if non-zero (non-zero for well-behaved clients) bestAddr addrQuality // best non-DERP path; zero if none; mutate via setBestAddrLocked() bestAddrAt mono.Time // time best address re-confirmed trustBestAddrUntil mono.Time // time when bestAddr expires sentPing map[stun.TxID]sentPing - endpointState map[netip.AddrPort]*endpointState + endpointState map[netip.AddrPort]*endpointState // netip.AddrPort type for key (instead of [epAddr]) as [endpointState] is irrelevant for Geneve-encapsulated paths isCallMeMaybeEP map[netip.AddrPort]bool // The following fields are related to the new "silent disco" @@ -95,10 +97,40 @@ type endpoint struct { expired bool // whether the node has expired isWireguardOnly bool // whether the endpoint is WireGuard only + relayCapable bool // whether the node is capable of speaking via a [tailscale.com/net/udprelay.Server] +} + +// udpRelayEndpointReady determines whether the given relay [addrQuality] should +// be installed as de.bestAddr. It is only called by [relayManager] once it has +// determined maybeBest is functional via [disco.Pong] reception. +func (de *endpoint) udpRelayEndpointReady(maybeBest addrQuality) { + de.mu.Lock() + defer de.mu.Unlock() + now := mono.Now() + curBestAddrTrusted := now.Before(de.trustBestAddrUntil) + sameRelayServer := de.bestAddr.vni.IsSet() && maybeBest.relayServerDisco.Compare(de.bestAddr.relayServerDisco) == 0 + + if !curBestAddrTrusted || + sameRelayServer || + betterAddr(maybeBest, de.bestAddr) { + // We must set maybeBest as de.bestAddr if: + // 1. de.bestAddr is untrusted. betterAddr does not consider + // time-based trust. + // 2. maybeBest & de.bestAddr are on the same relay. If the maybeBest + // handshake happened to use a different source address/transport, + // the relay will drop packets from the 'old' de.bestAddr's. + // 3. maybeBest is a 'betterAddr'. + // + // TODO(jwhited): add observability around !curBestAddrTrusted and sameRelayServer + // TODO(jwhited): collapse path change logging with endpoint.handlePongConnLocked() + de.c.logf("magicsock: disco: node %v %v now using %v mtu=%v", de.publicKey.ShortString(), de.discoShort(), maybeBest.epAddr, maybeBest.wireMTU) + de.setBestAddrLocked(maybeBest) + de.trustBestAddrUntil = now.Add(trustUDPAddrDuration) + } } func (de *endpoint) setBestAddrLocked(v addrQuality) { - if v.AddrPort != de.bestAddr.AddrPort { + if v.epAddr != de.bestAddr.epAddr { de.probeUDPLifetime.resetCycleEndpointLocked() } de.bestAddr = v @@ -134,11 +166,11 @@ type probeUDPLifetime struct { // timeout cliff in the future. timer *time.Timer - // bestAddr contains the endpoint.bestAddr.AddrPort at the time a cycle was + // bestAddr contains the endpoint.bestAddr.epAddr at the time a cycle was // scheduled to start. A probing cycle is 1:1 with the current - // endpoint.bestAddr.AddrPort in the interest of simplicity. When - // endpoint.bestAddr.AddrPort changes, any active probing cycle will reset. - bestAddr netip.AddrPort + // endpoint.bestAddr.epAddr in the interest of simplicity. When + // endpoint.bestAddr.epAddr changes, any active probing cycle will reset. + bestAddr epAddr // cycleStartedAt contains the time at which the first cliff // (ProbeUDPLifetimeConfig.Cliffs[0]) was pinged for the current/last cycle. cycleStartedAt time.Time @@ -190,7 +222,7 @@ func (p *probeUDPLifetime) resetCycleEndpointLocked() { } p.cycleActive = false p.currentCliff = 0 - p.bestAddr = netip.AddrPort{} + p.bestAddr = epAddr{} } // ProbeUDPLifetimeConfig represents the configuration for probing UDP path @@ -333,7 +365,7 @@ type endpointDisco struct { } type sentPing struct { - to netip.AddrPort + to epAddr at mono.Time timer *time.Timer // timeout timer purpose discoPingPurpose @@ -445,7 +477,8 @@ func (de *endpoint) deleteEndpointLocked(why string, ep netip.AddrPort) { From: ep, }) delete(de.endpointState, ep) - if de.bestAddr.AddrPort == ep { + asEpAddr := epAddr{ap: ep} + if de.bestAddr.epAddr == asEpAddr { de.debugUpdates.Add(EndpointChange{ When: time.Now(), What: "deleteEndpointLocked-bestAddr-" + why, @@ -467,11 +500,12 @@ func (de *endpoint) initFakeUDPAddr() { } // noteRecvActivity records receive activity on de, and invokes -// Conn.noteRecvActivity no more than once every 10s. -func (de *endpoint) noteRecvActivity(ipp netip.AddrPort, now mono.Time) { +// Conn.noteRecvActivity no more than once every 10s, returning true if it +// was called, otherwise false. +func (de *endpoint) noteRecvActivity(src epAddr, now mono.Time) bool { if de.isWireguardOnly { de.mu.Lock() - de.bestAddr.AddrPort = ipp + de.bestAddr.ap = src.ap de.bestAddrAt = now de.trustBestAddrUntil = now.Add(5 * time.Second) de.mu.Unlock() @@ -481,7 +515,7 @@ func (de *endpoint) noteRecvActivity(ipp netip.AddrPort, now mono.Time) { // kick off discovery disco pings every trustUDPAddrDuration and mirror // to DERP. de.mu.Lock() - if de.heartbeatDisabled && de.bestAddr.AddrPort == ipp { + if de.heartbeatDisabled && de.bestAddr.epAddr == src { de.trustBestAddrUntil = now.Add(trustUDPAddrDuration) } de.mu.Unlock() @@ -492,10 +526,12 @@ func (de *endpoint) noteRecvActivity(ipp netip.AddrPort, now mono.Time) { de.lastRecvWG.StoreAtomic(now) if de.c.noteRecvActivity == nil { - return + return false } de.c.noteRecvActivity(de.publicKey) + return true } + return false } func (de *endpoint) discoShort() string { @@ -529,10 +565,10 @@ func (de *endpoint) DstToBytes() []byte { return packIPPort(de.fakeWGAddr) } // de.mu must be held. // // TODO(val): Rewrite the addrFor*Locked() variations to share code. -func (de *endpoint) addrForSendLocked(now mono.Time) (udpAddr, derpAddr netip.AddrPort, sendWGPing bool) { - udpAddr = de.bestAddr.AddrPort +func (de *endpoint) addrForSendLocked(now mono.Time) (udpAddr epAddr, derpAddr netip.AddrPort, sendWGPing bool) { + udpAddr = de.bestAddr.epAddr - if udpAddr.IsValid() && !now.After(de.trustBestAddrUntil) { + if udpAddr.ap.IsValid() && !now.After(de.trustBestAddrUntil) { return udpAddr, netip.AddrPort{}, false } @@ -551,12 +587,12 @@ func (de *endpoint) addrForSendLocked(now mono.Time) (udpAddr, derpAddr netip.Ad // addrForWireGuardSendLocked returns the address that should be used for // sending the next packet. If a packet has never or not recently been sent to // the endpoint, then a randomly selected address for the endpoint is returned, -// as well as a bool indiciating that WireGuard discovery pings should be started. +// as well as a bool indicating that WireGuard discovery pings should be started. // If the addresses have latency information available, then the address with the // best latency is used. // // de.mu must be held. -func (de *endpoint) addrForWireGuardSendLocked(now mono.Time) (udpAddr netip.AddrPort, shouldPing bool) { +func (de *endpoint) addrForWireGuardSendLocked(now mono.Time) (udpAddr epAddr, shouldPing bool) { if len(de.endpointState) == 0 { de.c.logf("magicsock: addrForSendWireguardLocked: [unexpected] no candidates available for endpoint") return udpAddr, false @@ -580,22 +616,22 @@ func (de *endpoint) addrForWireGuardSendLocked(now mono.Time) (udpAddr netip.Add // TODO(catzkorn): Consider a small increase in latency to use // IPv6 in comparison to IPv4, when possible. lowestLatency = latency - udpAddr = ipp + udpAddr.ap = ipp } } } needPing := len(de.endpointState) > 1 && now.Sub(oldestPing) > wireguardPingInterval - if !udpAddr.IsValid() { + if !udpAddr.ap.IsValid() { candidates := slicesx.MapKeys(de.endpointState) // Randomly select an address to use until we retrieve latency information // and give it a short trustBestAddrUntil time so we avoid flapping between // addresses while waiting on latency information to be populated. - udpAddr = candidates[rand.IntN(len(candidates))] + udpAddr.ap = candidates[rand.IntN(len(candidates))] } - de.bestAddr.AddrPort = udpAddr + de.bestAddr.epAddr = epAddr{ap: udpAddr.ap} // Only extend trustBestAddrUntil by one second to avoid packet // reordering and/or CPU usage from random selection during the first // second. We should receive a response due to a WireGuard handshake in @@ -613,18 +649,18 @@ func (de *endpoint) addrForWireGuardSendLocked(now mono.Time) (udpAddr netip.Add // both of the returned UDP address and DERP address may be non-zero. // // de.mu must be held. -func (de *endpoint) addrForPingSizeLocked(now mono.Time, size int) (udpAddr, derpAddr netip.AddrPort) { +func (de *endpoint) addrForPingSizeLocked(now mono.Time, size int) (udpAddr epAddr, derpAddr netip.AddrPort) { if size == 0 { udpAddr, derpAddr, _ = de.addrForSendLocked(now) return } - udpAddr = de.bestAddr.AddrPort + udpAddr = de.bestAddr.epAddr pathMTU := de.bestAddr.wireMTU - requestedMTU := pingSizeToPktLen(size, udpAddr.Addr().Is6()) + requestedMTU := pingSizeToPktLen(size, udpAddr) mtuOk := requestedMTU <= pathMTU - if udpAddr.IsValid() && mtuOk { + if udpAddr.ap.IsValid() && mtuOk { if !now.After(de.trustBestAddrUntil) { return udpAddr, netip.AddrPort{} } @@ -637,7 +673,7 @@ func (de *endpoint) addrForPingSizeLocked(now mono.Time, size int) (udpAddr, der // for the packet. Return a zero-value udpAddr to signal that we should // keep probing the path MTU to all addresses for this endpoint, and a // valid DERP addr to signal that we should also send via DERP. - return netip.AddrPort{}, de.derpAddr + return epAddr{}, de.derpAddr } // maybeProbeUDPLifetimeLocked returns an afterInactivityFor duration and true @@ -648,7 +684,7 @@ func (de *endpoint) maybeProbeUDPLifetimeLocked() (afterInactivityFor time.Durat if p == nil { return afterInactivityFor, false } - if !de.bestAddr.IsValid() { + if !de.bestAddr.ap.IsValid() { return afterInactivityFor, false } epDisco := de.disco.Load() @@ -661,7 +697,7 @@ func (de *endpoint) maybeProbeUDPLifetimeLocked() (afterInactivityFor time.Durat // shuffling probing probability where the local node ends up with a large // key value lexicographically relative to the other nodes it tends to // communicate with. If de's disco key changes, the cycle will reset. - if de.c.discoPublic.Compare(epDisco.key) >= 0 { + if de.c.discoAtomic.Public().Compare(epDisco.key) >= 0 { // lower disco pub key node probes higher return afterInactivityFor, false } @@ -700,7 +736,7 @@ func (de *endpoint) scheduleHeartbeatForLifetimeLocked(after time.Duration, via } de.c.dlogf("[v1] magicsock: disco: scheduling UDP lifetime probe for cliff=%v via=%v to %v (%v)", p.currentCliffDurationEndpointLocked(), via, de.publicKey.ShortString(), de.discoShort()) - p.bestAddr = de.bestAddr.AddrPort + p.bestAddr = de.bestAddr.epAddr p.timer = time.AfterFunc(after, de.heartbeatForLifetime) if via == heartbeatForLifetimeViaSelf { metricUDPLifetimeCliffsRescheduled.Add(1) @@ -728,7 +764,7 @@ func (de *endpoint) heartbeatForLifetime() { return } p.timer = nil - if !p.bestAddr.IsValid() || de.bestAddr.AddrPort != p.bestAddr { + if !p.bestAddr.ap.IsValid() || de.bestAddr.epAddr != p.bestAddr { // best path changed p.resetCycleEndpointLocked() return @@ -760,7 +796,7 @@ func (de *endpoint) heartbeatForLifetime() { } de.c.dlogf("[v1] magicsock: disco: sending disco ping for UDP lifetime probe cliff=%v to %v (%v)", p.currentCliffDurationEndpointLocked(), de.publicKey.ShortString(), de.discoShort()) - de.startDiscoPingLocked(de.bestAddr.AddrPort, mono.Now(), pingHeartbeatForUDPLifetime, 0, nil) + de.startDiscoPingLocked(de.bestAddr.epAddr, mono.Now(), pingHeartbeatForUDPLifetime, 0, nil) } // heartbeat is called every heartbeatInterval to keep the best UDP path alive, @@ -818,8 +854,8 @@ func (de *endpoint) heartbeat() { } udpAddr, _, _ := de.addrForSendLocked(now) - if udpAddr.IsValid() { - // We have a preferred path. Ping that every 2 seconds. + if udpAddr.ap.IsValid() { + // We have a preferred path. Ping that every 'heartbeatInterval'. de.startDiscoPingLocked(udpAddr, now, pingHeartbeat, 0, nil) } @@ -827,6 +863,10 @@ func (de *endpoint) heartbeat() { de.sendDiscoPingsLocked(now, true) } + if de.wantUDPRelayPathDiscoveryLocked(now) { + de.discoverUDPRelayPathsLocked(now) + } + de.heartBeatTimer = time.AfterFunc(heartbeatInterval, de.heartbeat) } @@ -837,6 +877,53 @@ func (de *endpoint) setHeartbeatDisabled(v bool) { de.heartbeatDisabled = v } +// discoverUDPRelayPathsLocked starts UDP relay path discovery. +func (de *endpoint) discoverUDPRelayPathsLocked(now mono.Time) { + de.lastUDPRelayPathDiscovery = now + lastBest := de.bestAddr + lastBestIsTrusted := mono.Now().Before(de.trustBestAddrUntil) + de.c.relayManager.startUDPRelayPathDiscoveryFor(de, lastBest, lastBestIsTrusted) +} + +// wantUDPRelayPathDiscoveryLocked reports whether we should kick off UDP relay +// path discovery. +func (de *endpoint) wantUDPRelayPathDiscoveryLocked(now mono.Time) bool { + if runtime.GOOS == "js" { + return false + } + if !de.c.hasPeerRelayServers.Load() { + // Changes in this value between its access and a call to + // [endpoint.discoverUDPRelayPathsLocked] are fine, we will eventually + // do the "right" thing during future path discovery. The worst case is + // we suppress path discovery for the current cycle, or we unnecessarily + // call into [relayManager] and do some wasted work. + return false + } + if !de.relayCapable { + return false + } + if de.bestAddr.isDirect() && now.Before(de.trustBestAddrUntil) { + return false + } + if !de.lastUDPRelayPathDiscovery.IsZero() && now.Sub(de.lastUDPRelayPathDiscovery) < discoverUDPRelayPathsInterval { + return false + } + // TODO(jwhited): consider applying 'goodEnoughLatency' suppression here, + // but not until we have a strategy for triggering CallMeMaybeVia regularly + // and/or enabling inbound packets to act as a UDP relay path discovery + // trigger, otherwise clients without relay servers may fall off a UDP + // relay path and never come back. They are dependent on the remote side + // regularly TX'ing CallMeMaybeVia, which currently only happens as part + // of full UDP relay path discovery. + if now.After(de.trustBestAddrUntil) { + return true + } + if !de.lastUDPRelayPathDiscovery.IsZero() && now.Sub(de.lastUDPRelayPathDiscovery) >= upgradeUDPRelayInterval { + return true + } + return false +} + // wantFullPingLocked reports whether we should ping to all our peers looking for // a better path. // @@ -845,7 +932,7 @@ func (de *endpoint) wantFullPingLocked(now mono.Time) bool { if runtime.GOOS == "js" { return false } - if !de.bestAddr.IsValid() || de.lastFullPing.IsZero() { + if !de.bestAddr.isDirect() || de.lastFullPing.IsZero() { return true } if now.After(de.trustBestAddrUntil) { @@ -854,7 +941,7 @@ func (de *endpoint) wantFullPingLocked(now mono.Time) bool { if de.bestAddr.latency <= goodEnoughLatency { return false } - if now.Sub(de.lastFullPing) >= upgradeInterval { + if now.Sub(de.lastFullPing) >= upgradeUDPDirectInterval { return true } return false @@ -905,17 +992,38 @@ func (de *endpoint) discoPing(res *ipnstate.PingResult, size int, cb func(*ipnst udpAddr, derpAddr := de.addrForPingSizeLocked(now, size) if derpAddr.IsValid() { - de.startDiscoPingLocked(derpAddr, now, pingCLI, size, resCB) + de.startDiscoPingLocked(epAddr{ap: derpAddr}, now, pingCLI, size, resCB) } - if udpAddr.IsValid() && now.Before(de.trustBestAddrUntil) { - // Already have an active session, so just ping the address we're using. - // Otherwise "tailscale ping" results to a node on the local network - // can look like they're bouncing between, say 10.0.0.0/9 and the peer's - // IPv6 address, both 1ms away, and it's random who replies first. + + switch { + case udpAddr.ap.IsValid() && now.Before(de.trustBestAddrUntil): + // We have a "trusted" direct OR peer relay address, ping it. de.startDiscoPingLocked(udpAddr, now, pingCLI, size, resCB) - } else { + if !udpAddr.vni.IsSet() { + // If the path is direct we do not want to fallthrough to pinging + // all candidate direct paths, otherwise "tailscale ping" results to + // a node on the local network can look like they're bouncing + // between, say 10.0.0.0/8 and the peer's IPv6 address, both 1ms + // away, and it's random who replies first. cb() is called with the + // first reply, vs background path discovery that is subject to + // betterAddr() comparison and hysteresis + break + } + // If the trusted path is via a peer relay we want to fallthrough in + // order to also try all candidate direct paths. + fallthrough + default: + // Ping all candidate direct paths and start peer relay path discovery, + // if appropriate. This work overlaps with what [de.heartbeat] will + // periodically fire when it calls [de.sendDiscoPingsLocked] and + // [de.discoveryUDPRelayPathsLocked], but a user-initiated [pingCLI] is + // a "do it now" operation that should not be subject to + // [heartbeatInterval] tick or [discoPingInterval] rate-limiting. for ep := range de.endpointState { - de.startDiscoPingLocked(ep, now, pingCLI, size, resCB) + de.startDiscoPingLocked(epAddr{ap: ep}, now, pingCLI, size, resCB) + } + if de.wantUDPRelayPathDiscoveryLocked(now) { + de.discoverUDPRelayPathsLocked(now) } } } @@ -926,7 +1034,7 @@ var ( errPingTooBig = errors.New("ping size too big") ) -func (de *endpoint) send(buffs [][]byte) error { +func (de *endpoint) send(buffs [][]byte, offset int) error { de.mu.Lock() if de.expired { de.mu.Unlock() @@ -940,14 +1048,17 @@ func (de *endpoint) send(buffs [][]byte) error { if startWGPing { de.sendWireGuardOnlyPingsLocked(now) } - } else if !udpAddr.IsValid() || now.After(de.trustBestAddrUntil) { + } else if !udpAddr.isDirect() || now.After(de.trustBestAddrUntil) { de.sendDiscoPingsLocked(now, true) + if de.wantUDPRelayPathDiscoveryLocked(now) { + de.discoverUDPRelayPathsLocked(now) + } } de.noteTxActivityExtTriggerLocked(now) de.lastSendAny = now de.mu.Unlock() - if !udpAddr.IsValid() && !derpAddr.IsValid() { + if !udpAddr.ap.IsValid() && !derpAddr.IsValid() { // Make a last ditch effort to see if we have a DERP route for them. If // they contacted us over DERP and we don't know their UDP endpoints or // their DERP home, we can at least assume they're reachable over the @@ -959,8 +1070,8 @@ func (de *endpoint) send(buffs [][]byte) error { } } var err error - if udpAddr.IsValid() { - _, err = de.c.sendUDPBatch(udpAddr, buffs) + if udpAddr.ap.IsValid() { + _, err = de.c.sendUDPBatch(udpAddr, buffs, offset) // If the error is known to indicate that the endpoint is no longer // usable, clear the endpoint statistics so that the next send will @@ -971,37 +1082,49 @@ func (de *endpoint) send(buffs [][]byte) error { var txBytes int for _, b := range buffs { - txBytes += len(b) + txBytes += len(b[offset:]) } switch { - case udpAddr.Addr().Is4(): - de.c.metrics.outboundPacketsIPv4Total.Add(int64(len(buffs))) - de.c.metrics.outboundBytesIPv4Total.Add(int64(txBytes)) - case udpAddr.Addr().Is6(): - de.c.metrics.outboundPacketsIPv6Total.Add(int64(len(buffs))) - de.c.metrics.outboundBytesIPv6Total.Add(int64(txBytes)) + case udpAddr.ap.Addr().Is4(): + if udpAddr.vni.IsSet() { + de.c.metrics.outboundPacketsPeerRelayIPv4Total.Add(int64(len(buffs))) + de.c.metrics.outboundBytesPeerRelayIPv4Total.Add(int64(txBytes)) + } else { + de.c.metrics.outboundPacketsIPv4Total.Add(int64(len(buffs))) + de.c.metrics.outboundBytesIPv4Total.Add(int64(txBytes)) + } + case udpAddr.ap.Addr().Is6(): + if udpAddr.vni.IsSet() { + de.c.metrics.outboundPacketsPeerRelayIPv6Total.Add(int64(len(buffs))) + de.c.metrics.outboundBytesPeerRelayIPv6Total.Add(int64(txBytes)) + } else { + de.c.metrics.outboundPacketsIPv6Total.Add(int64(len(buffs))) + de.c.metrics.outboundBytesIPv6Total.Add(int64(txBytes)) + } } // TODO(raggi): needs updating for accuracy, as in error conditions we may have partial sends. - if stats := de.c.stats.Load(); err == nil && stats != nil { - stats.UpdateTxPhysical(de.nodeAddr, udpAddr, len(buffs), txBytes) + if update := de.c.connCounter.Load(); err == nil && update != nil { + update(0, netip.AddrPortFrom(de.nodeAddr, 0), udpAddr.ap, len(buffs), txBytes, false) } } if derpAddr.IsValid() { allOk := true var txBytes int for _, buff := range buffs { + buff = buff[offset:] const isDisco = false - ok, _ := de.c.sendAddr(derpAddr, de.publicKey, buff, isDisco) + const isGeneveEncap = false + ok, _ := de.c.sendAddr(derpAddr, de.publicKey, buff, isDisco, isGeneveEncap) txBytes += len(buff) if !ok { allOk = false } } - if stats := de.c.stats.Load(); stats != nil { - stats.UpdateTxPhysical(de.nodeAddr, derpAddr, len(buffs), txBytes) + if update := de.c.connCounter.Load(); update != nil { + update(0, netip.AddrPortFrom(de.nodeAddr, 0), derpAddr, len(buffs), txBytes, false) } if allOk { return nil @@ -1053,7 +1176,12 @@ func (de *endpoint) discoPingTimeout(txid stun.TxID) { if !ok { return } - if debugDisco() || !de.bestAddr.IsValid() || mono.Now().After(de.trustBestAddrUntil) { + bestUntrusted := mono.Now().After(de.trustBestAddrUntil) + if sp.to == de.bestAddr.epAddr && sp.to.vni.IsSet() && bestUntrusted { + // TODO(jwhited): consider applying this to direct UDP paths as well + de.clearBestAddrLocked() + } + if debugDisco() || !de.bestAddr.ap.IsValid() || bestUntrusted { de.c.dlogf("[v1] magicsock: disco: timeout waiting for pong %x from %v (%v, %v)", txid[:6], sp.to, de.publicKey.ShortString(), de.discoShort()) } de.removeSentDiscoPingLocked(txid, sp, discoPingTimedOut) @@ -1107,7 +1235,7 @@ const discoPingSize = len(disco.Magic) + key.DiscoPublicRawLen + disco.NonceLen // // The caller should use de.discoKey as the discoKey argument. // It is passed in so that sendDiscoPing doesn't need to lock de.mu. -func (de *endpoint) sendDiscoPing(ep netip.AddrPort, discoKey key.DiscoPublic, txid stun.TxID, size int, logLevel discoLogLevel) { +func (de *endpoint) sendDiscoPing(ep epAddr, discoKey key.DiscoPublic, txid stun.TxID, size int, logLevel discoLogLevel) { size = min(size, MaxDiscoPingSize) padding := max(size-discoPingSize, 0) @@ -1123,7 +1251,7 @@ func (de *endpoint) sendDiscoPing(ep netip.AddrPort, discoKey key.DiscoPublic, t if size != 0 { metricSentDiscoPeerMTUProbes.Add(1) - metricSentDiscoPeerMTUProbeBytes.Add(int64(pingSizeToPktLen(size, ep.Addr().Is6()))) + metricSentDiscoPeerMTUProbeBytes.Add(int64(pingSizeToPktLen(size, ep))) } } @@ -1154,16 +1282,20 @@ const ( // if non-nil, means that a caller external to the magicsock package internals // is interested in the result (such as a CLI "tailscale ping" or a c2n ping // request, etc) -func (de *endpoint) startDiscoPingLocked(ep netip.AddrPort, now mono.Time, purpose discoPingPurpose, size int, resCB *pingResultAndCallback) { +func (de *endpoint) startDiscoPingLocked(ep epAddr, now mono.Time, purpose discoPingPurpose, size int, resCB *pingResultAndCallback) { if runtime.GOOS == "js" { return } + if debugNeverDirectUDP() && !ep.vni.IsSet() && ep.ap.Addr() != tailcfg.DerpMagicIPAddr { + return + } epDisco := de.disco.Load() if epDisco == nil { return } - if purpose != pingCLI { - st, ok := de.endpointState[ep] + if purpose != pingCLI && + !ep.vni.IsSet() { // de.endpointState is only relevant for direct/non-vni epAddr's + st, ok := de.endpointState[ep.ap] if !ok { // Shouldn't happen. But don't ping an endpoint that's // not active for us. @@ -1180,11 +1312,11 @@ func (de *endpoint) startDiscoPingLocked(ep netip.AddrPort, now mono.Time, purpo // Default to sending a single ping of the specified size sizes := []int{size} if de.c.PeerMTUEnabled() { - isDerp := ep.Addr() == tailcfg.DerpMagicIPAddr + isDerp := ep.ap.Addr() == tailcfg.DerpMagicIPAddr if !isDerp && ((purpose == pingDiscovery) || (purpose == pingCLI && size == 0)) { de.c.dlogf("[v1] magicsock: starting MTU probe") sizes = mtuProbePingSizesV4 - if ep.Addr().Is6() { + if ep.ap.Addr().Is6() { sizes = mtuProbePingSizesV6 } } @@ -1239,7 +1371,7 @@ func (de *endpoint) sendDiscoPingsLocked(now mono.Time, sendCallMeMaybe bool) { de.c.dlogf("[v1] magicsock: disco: send, starting discovery for %v (%v)", de.publicKey.ShortString(), de.discoShort()) } - de.startDiscoPingLocked(ep, now, pingDiscovery, 0, nil) + de.startDiscoPingLocked(epAddr{ap: ep}, now, pingDiscovery, 0, nil) } derpAddr := de.derpAddr if sentAny && sendCallMeMaybe && derpAddr.IsValid() { @@ -1253,7 +1385,7 @@ func (de *endpoint) sendDiscoPingsLocked(now mono.Time, sendCallMeMaybe bool) { } // sendWireGuardOnlyPingsLocked evaluates all available addresses for -// a WireGuard only endpoint and initates an ICMP ping for useable +// a WireGuard only endpoint and initiates an ICMP ping for useable // addresses. func (de *endpoint) sendWireGuardOnlyPingsLocked(now mono.Time) { if runtime.GOOS == "js" { @@ -1390,6 +1522,8 @@ func (de *endpoint) updateFromNode(n tailcfg.NodeView, heartbeatDisabled bool, p } de.setEndpointsLocked(n.Endpoints()) + + de.relayCapable = capVerIsRelayCapable(n.Cap()) } func (de *endpoint) setEndpointsLocked(eps interface { @@ -1472,7 +1606,7 @@ func (de *endpoint) addCandidateEndpoint(ep netip.AddrPort, forRxPingTxID stun.T } } size2 := len(de.endpointState) - de.c.dlogf("[v1] magicsock: disco: addCandidateEndpoint pruned %v candidate set from %v to %v entries", size, size2) + de.c.dlogf("[v1] magicsock: disco: addCandidateEndpoint pruned %v (%s) candidate set from %v to %v entries", de.discoShort(), de.publicKey.ShortString(), size, size2) } return false } @@ -1487,17 +1621,19 @@ func (de *endpoint) clearBestAddrLocked() { de.trustBestAddrUntil = 0 } -// noteBadEndpoint marks ipp as a bad endpoint that would need to be +// noteBadEndpoint marks udpAddr as a bad endpoint that would need to be // re-evaluated before future use, this should be called for example if a send -// to ipp fails due to a host unreachable error or similar. -func (de *endpoint) noteBadEndpoint(ipp netip.AddrPort) { +// to udpAddr fails due to a host unreachable error or similar. +func (de *endpoint) noteBadEndpoint(udpAddr epAddr) { de.mu.Lock() defer de.mu.Unlock() de.clearBestAddrLocked() - if st, ok := de.endpointState[ipp]; ok { - st.clear() + if !udpAddr.vni.IsSet() { + if st, ok := de.endpointState[udpAddr.ap]; ok { + st.clear() + } } } @@ -1517,17 +1653,20 @@ func (de *endpoint) noteConnectivityChange() { // pingSizeToPktLen calculates the minimum path MTU that would permit // a disco ping message of length size to reach its target at -// addr. size is the length of the entire disco message including +// udpAddr. size is the length of the entire disco message including // disco headers. If size is zero, assume it is the safe wire MTU. -func pingSizeToPktLen(size int, is6 bool) tstun.WireMTU { +func pingSizeToPktLen(size int, udpAddr epAddr) tstun.WireMTU { if size == 0 { return tstun.SafeWireMTU() } headerLen := ipv4.HeaderLen - if is6 { + if udpAddr.ap.Addr().Is6() { headerLen = ipv6.HeaderLen } headerLen += 8 // UDP header length + if udpAddr.vni.IsSet() { + headerLen += packet.GeneveFixedHeaderLength + } return tstun.WireMTU(size + headerLen) } @@ -1554,11 +1693,11 @@ func pktLenToPingSize(mtu tstun.WireMTU, is6 bool) int { // It should be called with the Conn.mu held. // // It reports whether m.TxID corresponds to a ping that this endpoint sent. -func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip.AddrPort) (knownTxID bool) { +func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src epAddr) (knownTxID bool) { de.mu.Lock() defer de.mu.Unlock() - isDerp := src.Addr() == tailcfg.DerpMagicIPAddr + isDerp := src.ap.Addr() == tailcfg.DerpMagicIPAddr sp, ok := de.sentPing[m.TxID] if !ok { @@ -1568,7 +1707,7 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip knownTxID = true // for naked returns below de.removeSentDiscoPingLocked(m.TxID, sp, discoPongReceived) - pktLen := int(pingSizeToPktLen(sp.size, sp.to.Addr().Is6())) + pktLen := int(pingSizeToPktLen(sp.size, src)) if sp.size != 0 { m := getPeerMTUsProbedMetric(tstun.WireMTU(pktLen)) m.Add(1) @@ -1580,25 +1719,27 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip now := mono.Now() latency := now.Sub(sp.at) - if !isDerp { - st, ok := de.endpointState[sp.to] + if !isDerp && !src.vni.IsSet() { + // Note: we check vni.isSet() as relay [epAddr]'s are not stored in + // endpointState, they are either de.bestAddr or not. + st, ok := de.endpointState[sp.to.ap] if !ok { // This is no longer an endpoint we care about. return } - de.c.peerMap.setNodeKeyForIPPort(src, de.publicKey) + de.c.peerMap.setNodeKeyForEpAddr(src, de.publicKey) st.addPongReplyLocked(pongReply{ latency: latency, pongAt: now, - from: src, + from: src.ap, pongSrc: m.Src, }) } if sp.purpose != pingHeartbeat && sp.purpose != pingHeartbeatForUDPLifetime { - de.c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got pong tx=%x latency=%v pktlen=%v pong.src=%v%v", de.c.discoShort, de.discoShort(), de.publicKey.ShortString(), src, m.TxID[:6], latency.Round(time.Millisecond), pktLen, m.Src, logger.ArgWriter(func(bw *bufio.Writer) { + de.c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got pong tx=%x latency=%v pktlen=%v pong.src=%v%v", de.c.discoAtomic.Short(), de.discoShort(), de.publicKey.ShortString(), src, m.TxID[:6], latency.Round(time.Millisecond), pktLen, m.Src, logger.ArgWriter(func(bw *bufio.Writer) { if sp.to != src { fmt.Fprintf(bw, " ping.to=%v", sp.to) } @@ -1616,21 +1757,30 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip // Promote this pong response to our current best address if it's lower latency. // TODO(bradfitz): decide how latency vs. preference order affects decision if !isDerp { - thisPong := addrQuality{sp.to, latency, tstun.WireMTU(pingSizeToPktLen(sp.size, sp.to.Addr().Is6()))} + thisPong := addrQuality{ + epAddr: sp.to, + latency: latency, + wireMTU: pingSizeToPktLen(sp.size, sp.to), + } + // TODO(jwhited): consider checking de.trustBestAddrUntil as well. If + // de.bestAddr is untrusted we may want to clear it, otherwise we could + // get stuck with a forever untrusted bestAddr that blackholes, since + // we don't clear direct UDP paths on disco ping timeout (see + // discoPingTimeout). if betterAddr(thisPong, de.bestAddr) { de.c.logf("magicsock: disco: node %v %v now using %v mtu=%v tx=%x", de.publicKey.ShortString(), de.discoShort(), sp.to, thisPong.wireMTU, m.TxID[:6]) de.debugUpdates.Add(EndpointChange{ When: time.Now(), - What: "handlePingLocked-bestAddr-update", + What: "handlePongConnLocked-bestAddr-update", From: de.bestAddr, To: thisPong, }) de.setBestAddrLocked(thisPong) } - if de.bestAddr.AddrPort == thisPong.AddrPort { + if de.bestAddr.epAddr == thisPong.epAddr { de.debugUpdates.Add(EndpointChange{ When: time.Now(), - What: "handlePingLocked-bestAddr-latency", + What: "handlePongConnLocked-bestAddr-latency", From: de.bestAddr, To: thisPong, }) @@ -1642,20 +1792,43 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip return } -// addrQuality is an IPPort with an associated latency and path mtu. +// epAddr is a [netip.AddrPort] with an optional Geneve header (RFC8926) +// [packet.VirtualNetworkID]. +type epAddr struct { + ap netip.AddrPort // if ap == tailcfg.DerpMagicIPAddr then vni is never set + vni packet.VirtualNetworkID // vni.IsSet() indicates if this [epAddr] involves a Geneve header +} + +// isDirect returns true if e.ap is valid and not tailcfg.DerpMagicIPAddr, +// and a VNI is not set. +func (e epAddr) isDirect() bool { + return e.ap.IsValid() && e.ap.Addr() != tailcfg.DerpMagicIPAddr && !e.vni.IsSet() +} + +func (e epAddr) String() string { + if !e.vni.IsSet() { + return e.ap.String() + } + return fmt.Sprintf("%v:vni:%d", e.ap.String(), e.vni.Get()) +} + +// addrQuality is an [epAddr], an optional [key.DiscoPublic] if a relay server +// is associated, a round-trip latency measurement, and path mtu. type addrQuality struct { - netip.AddrPort - latency time.Duration - wireMTU tstun.WireMTU + epAddr + relayServerDisco key.DiscoPublic // only relevant if epAddr.vni.isSet(), otherwise zero value + latency time.Duration + wireMTU tstun.WireMTU } func (a addrQuality) String() string { - return fmt.Sprintf("%v@%v+%v", a.AddrPort, a.latency, a.wireMTU) + // TODO(jwhited): consider including relayServerDisco + return fmt.Sprintf("%v@%v+%v", a.epAddr, a.latency, a.wireMTU) } // betterAddr reports whether a is a better addr to use than b. func betterAddr(a, b addrQuality) bool { - if a.AddrPort == b.AddrPort { + if a.epAddr == b.epAddr { if a.wireMTU > b.wireMTU { // TODO(val): Think harder about the case of lower // latency and smaller or unknown MTU, and higher @@ -1666,10 +1839,19 @@ func betterAddr(a, b addrQuality) bool { } return false } - if !b.IsValid() { + if !b.ap.IsValid() { return true } - if !a.IsValid() { + if !a.ap.IsValid() { + return false + } + + // Geneve-encapsulated paths (UDP relay servers) are lower preference in + // relation to non. + if !a.vni.IsSet() && b.vni.IsSet() { + return true + } + if a.vni.IsSet() && !b.vni.IsSet() { return false } @@ -1693,27 +1875,27 @@ func betterAddr(a, b addrQuality) bool { // addresses, and prefer link-local unicast addresses over other types // of private IP addresses since it's definitionally more likely that // they'll be on the same network segment than a general private IP. - if a.Addr().IsLoopback() { + if a.ap.Addr().IsLoopback() { aPoints += 50 - } else if a.Addr().IsLinkLocalUnicast() { + } else if a.ap.Addr().IsLinkLocalUnicast() { aPoints += 30 - } else if a.Addr().IsPrivate() { + } else if a.ap.Addr().IsPrivate() { aPoints += 20 } - if b.Addr().IsLoopback() { + if b.ap.Addr().IsLoopback() { bPoints += 50 - } else if b.Addr().IsLinkLocalUnicast() { + } else if b.ap.Addr().IsLinkLocalUnicast() { bPoints += 30 - } else if b.Addr().IsPrivate() { + } else if b.ap.Addr().IsPrivate() { bPoints += 20 } // Prefer IPv6 for being a bit more robust, as long as // the latencies are roughly equivalent. - if a.Addr().Is6() { + if a.ap.Addr().Is6() { aPoints += 10 } - if b.Addr().Is6() { + if b.ap.Addr().Is6() { bPoints += 10 } @@ -1797,7 +1979,25 @@ func (de *endpoint) handleCallMeMaybe(m *disco.CallMeMaybe) { for _, st := range de.endpointState { st.lastPing = 0 } - de.sendDiscoPingsLocked(mono.Now(), false) + monoNow := mono.Now() + de.sendDiscoPingsLocked(monoNow, false) + + // This hook is required to trigger peer relay path discovery around + // disco "tailscale ping" initiated by de. We may be configured with peer + // relay servers that differ from de. + // + // The only other peer relay path discovery hook is in [endpoint.heartbeat], + // which is kicked off around outbound WireGuard packet flow, or if you are + // the "tailscale ping" initiator. Disco "tailscale ping" does not propagate + // into wireguard-go. + // + // We choose not to hook this around disco ping reception since peer relay + // path discovery can also trigger disco ping transmission, which *could* + // lead to an infinite loop of peer relay path discovery between two peers, + // absent intended triggers. + if de.wantUDPRelayPathDiscoveryLocked(monoNow) { + de.discoverUDPRelayPathsLocked(monoNow) + } } func (de *endpoint) populatePeerStatus(ps *ipnstate.PeerStatus) { @@ -1814,8 +2014,12 @@ func (de *endpoint) populatePeerStatus(ps *ipnstate.PeerStatus) { ps.LastWrite = de.lastSendExt.WallTime() ps.Active = now.Sub(de.lastSendExt) < sessionActiveTimeout - if udpAddr, derpAddr, _ := de.addrForSendLocked(now); udpAddr.IsValid() && !derpAddr.IsValid() { - ps.CurAddr = udpAddr.String() + if udpAddr, derpAddr, _ := de.addrForSendLocked(now); udpAddr.ap.IsValid() && !derpAddr.IsValid() { + if udpAddr.vni.IsSet() { + ps.PeerRelay = udpAddr.String() + } else { + ps.CurAddr = udpAddr.String() + } } } @@ -1863,14 +2067,22 @@ func (de *endpoint) resetLocked() { } } de.probeUDPLifetime.resetCycleEndpointLocked() + de.c.relayManager.stopWork(de) } func (de *endpoint) numStopAndReset() int64 { return atomic.LoadInt64(&de.numStopAndResetAtomic) } +// setDERPHome sets the provided regionID as home for de. Calls to setDERPHome +// must never run concurrent to [Conn.updateRelayServersSet], otherwise +// [candidatePeerRelay] DERP home changes may be missed from the perspective of +// [relayManager]. func (de *endpoint) setDERPHome(regionID uint16) { de.mu.Lock() defer de.mu.Unlock() de.derpAddr = netip.AddrPortFrom(tailcfg.DerpMagicIPAddr, uint16(regionID)) + if de.c.hasPeerRelayServers.Load() { + de.c.relayManager.handleDERPHomeChange(de.publicKey, regionID) + } } diff --git a/vendor/tailscale.com/wgengine/magicsock/endpoint_tracker.go b/vendor/tailscale.com/wgengine/magicsock/endpoint_tracker.go index 5caddd1..e95852d 100644 --- a/vendor/tailscale.com/wgengine/magicsock/endpoint_tracker.go +++ b/vendor/tailscale.com/wgengine/magicsock/endpoint_tracker.go @@ -6,9 +6,9 @@ package magicsock import ( "net/netip" "slices" - "sync" "time" + "tailscale.com/syncs" "tailscale.com/tailcfg" "tailscale.com/tempfork/heap" "tailscale.com/util/mak" @@ -107,7 +107,7 @@ func (eh endpointHeap) Min() *endpointTrackerEntry { // // See tailscale/tailscale#7877 for more information. type endpointTracker struct { - mu sync.Mutex + mu syncs.Mutex endpoints map[netip.Addr]*endpointHeap } diff --git a/vendor/tailscale.com/wgengine/magicsock/magicsock.go b/vendor/tailscale.com/wgengine/magicsock/magicsock.go index e8e9665..8fbd070 100644 --- a/vendor/tailscale.com/wgengine/magicsock/magicsock.go +++ b/vendor/tailscale.com/wgengine/magicsock/magicsock.go @@ -9,8 +9,8 @@ import ( "bufio" "bytes" "context" + "encoding/binary" "errors" - "expvar" "fmt" "io" "net" @@ -25,23 +25,26 @@ import ( "time" "github.com/tailscale/wireguard-go/conn" + "github.com/tailscale/wireguard-go/device" "go4.org/mem" "golang.org/x/net/ipv6" - "tailscale.com/control/controlknobs" "tailscale.com/disco" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" + "tailscale.com/feature/condlite/expvar" "tailscale.com/health" "tailscale.com/hostinfo" "tailscale.com/ipn/ipnstate" - "tailscale.com/net/connstats" + "tailscale.com/net/batching" "tailscale.com/net/netcheck" "tailscale.com/net/neterror" "tailscale.com/net/netmon" "tailscale.com/net/netns" "tailscale.com/net/packet" "tailscale.com/net/ping" - "tailscale.com/net/portmapper" + "tailscale.com/net/portmapper/portmappertype" + "tailscale.com/net/sockopts" "tailscale.com/net/sockstats" "tailscale.com/net/stun" "tailscale.com/net/tstun" @@ -52,15 +55,20 @@ import ( "tailscale.com/types/key" "tailscale.com/types/lazy" "tailscale.com/types/logger" + "tailscale.com/types/netlogfunc" "tailscale.com/types/netmap" "tailscale.com/types/nettype" "tailscale.com/types/views" "tailscale.com/util/clientmetric" + "tailscale.com/util/cloudinfo" + "tailscale.com/util/eventbus" "tailscale.com/util/mak" - "tailscale.com/util/ringbuffer" + "tailscale.com/util/ringlog" "tailscale.com/util/set" "tailscale.com/util/testenv" "tailscale.com/util/usermetric" + "tailscale.com/wgengine/filter" + "tailscale.com/wgengine/router" "tailscale.com/wgengine/wgint" ) @@ -83,9 +91,11 @@ const ( type Path string const ( - PathDirectIPv4 Path = "direct_ipv4" - PathDirectIPv6 Path = "direct_ipv6" - PathDERP Path = "derp" + PathDirectIPv4 Path = "direct_ipv4" + PathDirectIPv6 Path = "direct_ipv6" + PathDERP Path = "derp" + PathPeerRelayIPv4 Path = "peer_relay_ipv4" + PathPeerRelayIPv6 Path = "peer_relay_ipv6" ) type pathLabel struct { @@ -93,6 +103,8 @@ type pathLabel struct { // - direct_ipv4 // - direct_ipv6 // - derp + // - peer_relay_ipv4 + // - peer_relay_ipv6 Path Path } @@ -104,27 +116,35 @@ type pathLabel struct { type metrics struct { // inboundPacketsTotal is the total number of inbound packets received, // labeled by the path the packet took. - inboundPacketsIPv4Total expvar.Int - inboundPacketsIPv6Total expvar.Int - inboundPacketsDERPTotal expvar.Int + inboundPacketsIPv4Total expvar.Int + inboundPacketsIPv6Total expvar.Int + inboundPacketsDERPTotal expvar.Int + inboundPacketsPeerRelayIPv4Total expvar.Int + inboundPacketsPeerRelayIPv6Total expvar.Int // inboundBytesTotal is the total number of inbound bytes received, // labeled by the path the packet took. - inboundBytesIPv4Total expvar.Int - inboundBytesIPv6Total expvar.Int - inboundBytesDERPTotal expvar.Int + inboundBytesIPv4Total expvar.Int + inboundBytesIPv6Total expvar.Int + inboundBytesDERPTotal expvar.Int + inboundBytesPeerRelayIPv4Total expvar.Int + inboundBytesPeerRelayIPv6Total expvar.Int // outboundPacketsTotal is the total number of outbound packets sent, // labeled by the path the packet took. - outboundPacketsIPv4Total expvar.Int - outboundPacketsIPv6Total expvar.Int - outboundPacketsDERPTotal expvar.Int + outboundPacketsIPv4Total expvar.Int + outboundPacketsIPv6Total expvar.Int + outboundPacketsDERPTotal expvar.Int + outboundPacketsPeerRelayIPv4Total expvar.Int + outboundPacketsPeerRelayIPv6Total expvar.Int // outboundBytesTotal is the total number of outbound bytes sent, // labeled by the path the packet took. - outboundBytesIPv4Total expvar.Int - outboundBytesIPv6Total expvar.Int - outboundBytesDERPTotal expvar.Int + outboundBytesIPv4Total expvar.Int + outboundBytesIPv6Total expvar.Int + outboundBytesDERPTotal expvar.Int + outboundBytesPeerRelayIPv4Total expvar.Int + outboundBytesPeerRelayIPv6Total expvar.Int // outboundPacketsDroppedErrors is the total number of outbound packets // dropped due to errors. @@ -136,6 +156,8 @@ type Conn struct { // This block mirrors the contents and field order of the Options // struct. Initialized once at construction, then constant. + eventBus *eventbus.Bus + eventClient *eventbus.Client logf logger.Logf epFunc func([]tailcfg.Endpoint) derpActiveFunc func() @@ -155,6 +177,12 @@ type Conn struct { connCtxCancel func() // closes connCtx donec <-chan struct{} // connCtx.Done()'s to avoid context.cancelCtx.Done()'s mutex per call + // A publisher for synchronization points to ensure correct ordering of + // config changes between magicsock and wireguard. + syncPub *eventbus.Publisher[syncPoint] + allocRelayEndpointPub *eventbus.Publisher[UDPRelayAllocReq] + portUpdatePub *eventbus.Publisher[router.PortUpdate] + // pconn4 and pconn6 are the underlying UDP sockets used to // send/receive packets for wireguard and other magicsock // protocols. @@ -175,11 +203,8 @@ type Conn struct { // portMapper is the NAT-PMP/PCP/UPnP prober/client, for requesting // port mappings from NAT devices. - portMapper *portmapper.Client - - // portMapperLogfUnregister is the function to call to unregister - // the portmapper log limiter. - portMapperLogfUnregister func() + // If nil, the portmapper is disabled. + portMapper portmappertype.Client // derpRecvCh is used by receiveDERP to read DERP messages. // It must have buffer size > 0; see issue 3736. @@ -189,7 +214,7 @@ type Conn struct { bind *connBind // cloudInfo is used to query cloud metadata services. - cloudInfo *cloudInfo + cloudInfo *cloudinfo.CloudInfo // ============================================================ // Fields that must be accessed via atomic load/stores. @@ -237,26 +262,26 @@ type Conn struct { //lint:ignore U1000 used on Linux/Darwin only peerMTUEnabled atomic.Bool - // stats maintains per-connection counters. - stats atomic.Pointer[connstats.Statistics] + // connCounter maintains per-connection counters. + connCounter syncs.AtomicValue[netlogfunc.ConnectionCounter] // captureHook, if non-nil, is the pcap logging callback when capturing. captureHook syncs.AtomicValue[packet.CaptureCallback] - // discoPrivate is the private naclbox key used for active - // discovery traffic. It is always present, and immutable. - discoPrivate key.DiscoPrivate - // public of discoPrivate. It is always present and immutable. - discoPublic key.DiscoPublic - // ShortString of discoPublic (to save logging work later). It is always - // present and immutable. - discoShort string + // hasPeerRelayServers is whether [relayManager] is configured with at least + // one peer relay server via [relayManager.handleRelayServersSet]. It exists + // to suppress calls into [relayManager] leading to wasted work involving + // channel operations and goroutine creation. + hasPeerRelayServers atomic.Bool + + // discoAtomic is the current disco private and public keypair for this conn. + discoAtomic discoAtomic // ============================================================ // mu guards all following fields; see userspaceEngine lock // ordering rules against the engine. For derphttp, mu must // be held before derphttp.Client.mu. - mu sync.Mutex + mu syncs.Mutex muCond *sync.Cond onlyTCP443 atomic.Bool @@ -313,7 +338,11 @@ type Conn struct { // by node key, node ID, and discovery key. peerMap peerMap - // discoInfo is the state for an active DiscoKey. + // relayManager manages allocation and handshaking of + // [tailscale.com/net/udprelay.Server] endpoints. + relayManager relayManager + + // discoInfo is the state for an active peer DiscoKey. discoInfo map[key.DiscoPublic]*discoInfo // netInfoFunc is a callback that provides a tailcfg.NetInfo when @@ -331,17 +360,19 @@ type Conn struct { // magicsock could do with any complexity reduction it can get. netInfoLast *tailcfg.NetInfo - derpMap *tailcfg.DERPMap // nil (or zero regions/nodes) means DERP is disabled - peers views.Slice[tailcfg.NodeView] // from last SetNetworkMap update - lastFlags debugFlags // at time of last SetNetworkMap - firstAddrForTest netip.Addr // from last SetNetworkMap update; for tests only - privateKey key.NodePrivate // WireGuard private key for this node - everHadKey bool // whether we ever had a non-zero private key - myDerp int // nearest DERP region ID; 0 means none/unknown - homeless bool // if true, don't try to find & stay conneted to a DERP home (myDerp will stay 0) - derpStarted chan struct{} // closed on first connection to DERP; for tests & cleaner Close - activeDerp map[int]activeDerp // DERP regionID -> connection to a node in that region - prevDerp map[int]*syncs.WaitGroupChan + derpMap *tailcfg.DERPMap // nil (or zero regions/nodes) means DERP is disabled + self tailcfg.NodeView // from last onNodeViewsUpdate + peers views.Slice[tailcfg.NodeView] // from last onNodeViewsUpdate, sorted by Node.ID; Note: [netmap.NodeMutation]'s rx'd in onNodeMutationsUpdate are never applied + filt *filter.Filter // from last onFilterUpdate + relayClientEnabled bool // whether we can allocate UDP relay endpoints on UDP relay servers or receive CallMeMaybeVia messages from peers + lastFlags debugFlags // at time of last onNodeViewsUpdate + privateKey key.NodePrivate // WireGuard private key for this node + everHadKey bool // whether we ever had a non-zero private key + myDerp int // nearest DERP region ID; 0 means none/unknown + homeless bool // if true, don't try to find & stay conneted to a DERP home (myDerp will stay 0) + derpStarted chan struct{} // closed on first connection to DERP; for tests & cleaner Close + activeDerp map[int]activeDerp // DERP regionID -> connection to a node in that region + prevDerp map[int]*syncs.WaitGroupChan // derpRoute contains optional alternate routes to use as an // optimization instead of contacting a peer via their home @@ -359,10 +390,6 @@ type Conn struct { // wgPinger is the WireGuard only pinger used for latency measurements. wgPinger lazy.SyncValue[*ping.Pinger] - // onPortUpdate is called with the new port when magicsock rebinds to - // a new port. - onPortUpdate func(port uint16, network string) - // getPeerByKey optionally specifies a function to look up a peer's // wireguard state by its public key. If nil, it's not used. getPeerByKey func(key.NodePublic) (_ wgint.Peer, ok bool) @@ -379,6 +406,10 @@ type Conn struct { // metrics contains the metrics for the magicsock instance. metrics *metrics + + // homeDERPGauge is the usermetric gauge for the home DERP region ID. + // This can be nil when [Options.Metrics] are not enabled. + homeDERPGauge *usermetric.Gauge } // SetDebugLoggingEnabled controls whether spammy debug logging is enabled. @@ -401,8 +432,13 @@ func (c *Conn) dlogf(format string, a ...any) { // Options contains options for Listen. type Options struct { - // Logf optionally provides a log function to use. - // Must not be nil. + // EventBus, if non-nil, is used for event publication and subscription by + // each Conn created from these Options. It must not be nil outside of + // tests. + EventBus *eventbus.Bus + + // Logf provides a log function to use. It must not be nil. + // Use [logger.Discard] to disrcard logs. Logf logger.Logf // Port is the port to listen on. @@ -428,7 +464,8 @@ type Options struct { // NoteRecvActivity, if provided, is a func for magicsock to call // whenever it receives a packet from a a peer if it's been more // than ~10 seconds since the last one. (10 seconds is somewhat - // arbitrary; the sole user just doesn't need or want it called on + // arbitrary; the sole user, lazy WireGuard configuration, + // just doesn't need or want it called on // every packet, just every minute or two for WireGuard timeouts, // and 10 seconds seems like a good trade-off between often enough // and not too often.) @@ -452,10 +489,6 @@ type Options struct { // If nil, they're ignored and not updated. ControlKnobs *controlknobs.Knobs - // OnPortUpdate is called with the new port when magicsock rebinds to - // a new port. - OnPortUpdate func(port uint16, network string) - // PeerByKeyFunc optionally specifies a function to look up a peer's // WireGuard state by its public key. If nil, it's not used. // In regular use, this will be wgengine.(*userspaceEngine).PeerByKey. @@ -487,6 +520,77 @@ func (o *Options) derpActiveFunc() func() { return o.DERPActiveFunc } +// NodeViewsUpdate represents an update event of [tailcfg.NodeView] for all +// nodes. This event is published over an [eventbus.Bus]. It may be published +// with an invalid SelfNode, and/or zero/nil Peers. [magicsock.Conn] is the sole +// subscriber as of 2025-06. If you are adding more subscribers consider moving +// this type out of magicsock. +type NodeViewsUpdate struct { + SelfNode tailcfg.NodeView + Peers []tailcfg.NodeView // sorted by Node.ID +} + +// NodeMutationsUpdate represents an update event of one or more +// [netmap.NodeMutation]. This event is published over an [eventbus.Bus]. +// [magicsock.Conn] is the sole subscriber as of 2025-06. If you are adding more +// subscribers consider moving this type out of magicsock. +type NodeMutationsUpdate struct { + Mutations []netmap.NodeMutation +} + +// FilterUpdate represents an update event for a [*filter.Filter]. This event is +// signaled over an [eventbus.Bus]. [magicsock.Conn] is the sole subscriber as +// of 2025-06. If you are adding more subscribers consider moving this type out +// of magicsock. +type FilterUpdate struct { + *filter.Filter +} + +// syncPoint is an event published over an [eventbus.Bus] by [Conn.Synchronize]. +// It serves as a synchronization point, allowing to wait until magicsock +// has processed all pending events. +type syncPoint chan struct{} + +// Wait blocks until [syncPoint.Signal] is called. +func (s syncPoint) Wait() { + <-s +} + +// Signal signals the sync point, unblocking the [syncPoint.Wait] call. +func (s syncPoint) Signal() { + close(s) +} + +// UDPRelayAllocReq represents a [*disco.AllocateUDPRelayEndpointRequest] +// reception event. This is signaled over an [eventbus.Bus] from +// [magicsock.Conn] towards [relayserver.extension]. +type UDPRelayAllocReq struct { + // RxFromNodeKey is the unauthenticated (DERP server claimed src) node key + // of the transmitting party, noted at disco message reception time over + // DERP. This node key is unambiguously-aligned with RxFromDiscoKey being + // that the disco message is received over DERP. + RxFromNodeKey key.NodePublic + // RxFromDiscoKey is the disco key of the transmitting party, noted and + // authenticated at reception time. + RxFromDiscoKey key.DiscoPublic + // Message is the disco message. + Message *disco.AllocateUDPRelayEndpointRequest +} + +// UDPRelayAllocResp represents a [*disco.AllocateUDPRelayEndpointResponse] +// that is yet to be transmitted over DERP (or delivered locally if +// ReqRxFromNodeKey is self). This is signaled over an [eventbus.Bus] from +// [relayserver.extension] towards [magicsock.Conn]. +type UDPRelayAllocResp struct { + // ReqRxFromNodeKey is copied from [UDPRelayAllocReq.RxFromNodeKey]. It + // enables peer lookup leading up to transmission over DERP. + ReqRxFromNodeKey key.NodePublic + // ReqRxFromDiscoKey is copied from [UDPRelayAllocReq.RxFromDiscoKey]. + ReqRxFromDiscoKey key.DiscoPublic + // Message is the disco message. + Message *disco.AllocateUDPRelayEndpointResponse +} + // newConn is the error-free, network-listening-side-effect-free based // of NewConn. Mostly for tests. func newConn(logf logger.Logf) *Conn { @@ -498,17 +602,15 @@ func newConn(logf logger.Logf) *Conn { peerLastDerp: make(map[key.NodePublic]int), peerMap: newPeerMap(), discoInfo: make(map[key.DiscoPublic]*discoInfo), - discoPrivate: discoPrivate, - discoPublic: discoPrivate.Public(), - cloudInfo: newCloudInfo(logf), + cloudInfo: cloudinfo.New(logf), } - c.discoShort = c.discoPublic.ShortString() + c.discoAtomic.Set(discoPrivate) c.bind = &connBind{Conn: c, closed: true} c.receiveBatchPool = sync.Pool{New: func() any { msgs := make([]ipv6.Message, c.bind.BatchSize()) for i := range msgs { msgs[i].Buffers = make([][]byte, 1) - msgs[i].OOB = make([]byte, controlMessageSize) + msgs[i].OOB = make([]byte, batching.MinControlMessageSize()) } batch := &receiveBatch{ msgs: msgs, @@ -520,15 +622,65 @@ func newConn(logf logger.Logf) *Conn { return c } +func (c *Conn) onUDPRelayAllocResp(allocResp UDPRelayAllocResp) { + c.mu.Lock() + defer c.mu.Unlock() + ep, ok := c.peerMap.endpointForNodeKey(allocResp.ReqRxFromNodeKey) + if !ok { + // If it's not a peer, it might be for self (we can peer relay through + // ourselves), in which case we want to hand it down to [relayManager] + // now versus taking a network round-trip through DERP. + selfNodeKey := c.publicKeyAtomic.Load() + if selfNodeKey.Compare(allocResp.ReqRxFromNodeKey) == 0 && + allocResp.ReqRxFromDiscoKey.Compare(c.discoAtomic.Public()) == 0 { + c.relayManager.handleRxDiscoMsg(c, allocResp.Message, selfNodeKey, allocResp.ReqRxFromDiscoKey, epAddr{}) + metricLocalDiscoAllocUDPRelayEndpointResponse.Add(1) + } + return + } + disco := ep.disco.Load() + if disco == nil { + return + } + if disco.key.Compare(allocResp.ReqRxFromDiscoKey) != 0 { + return + } + ep.mu.Lock() + defer ep.mu.Unlock() + derpAddr := ep.derpAddr + if derpAddr.IsValid() { + go c.sendDiscoMessage(epAddr{ap: derpAddr}, ep.publicKey, disco.key, allocResp.Message, discoVerboseLog) + } +} + +// Synchronize waits for all [eventbus] events published +// prior to this call to be processed by the receiver. +func (c *Conn) Synchronize() { + if c.syncPub == nil { + // Eventbus is not used; no need to synchronize (in certain tests). + return + } + sp := syncPoint(make(chan struct{})) + c.syncPub.Publish(sp) + select { + case <-sp: + case <-c.donec: + } +} + // NewConn creates a magic Conn listening on opts.Port. // As the set of possible endpoints for a Conn changes, the // callback opts.EndpointsFunc is called. func NewConn(opts Options) (*Conn, error) { - if opts.NetMon == nil { + switch { + case opts.NetMon == nil: return nil, errors.New("magicsock.Options.NetMon must be non-nil") + case opts.EventBus == nil: + return nil, errors.New("magicsock.Options.EventBus must be non-nil") } c := newConn(opts.logf()) + c.eventBus = opts.EventBus c.port.Store(uint32(opts.Port)) c.controlKnobs = opts.ControlKnobs c.epFunc = opts.endpointsFunc() @@ -537,26 +689,55 @@ func NewConn(opts Options) (*Conn, error) { c.testOnlyPacketListener = opts.TestOnlyPacketListener c.noteRecvActivity = opts.NoteRecvActivity + // Set up publishers and subscribers. Subscribe calls must return before + // NewConn otherwise published events can be missed. + ec := c.eventBus.Client("magicsock.Conn") + c.eventClient = ec + c.syncPub = eventbus.Publish[syncPoint](ec) + c.allocRelayEndpointPub = eventbus.Publish[UDPRelayAllocReq](ec) + c.portUpdatePub = eventbus.Publish[router.PortUpdate](ec) + eventbus.SubscribeFunc(ec, c.onPortMapChanged) + eventbus.SubscribeFunc(ec, c.onFilterUpdate) + eventbus.SubscribeFunc(ec, c.onNodeViewsUpdate) + eventbus.SubscribeFunc(ec, c.onNodeMutationsUpdate) + eventbus.SubscribeFunc(ec, func(sp syncPoint) { + c.dlogf("magicsock: received sync point after reconfig") + sp.Signal() + }) + eventbus.SubscribeFunc(ec, c.onUDPRelayAllocResp) + + c.connCtx, c.connCtxCancel = context.WithCancel(context.Background()) + c.donec = c.connCtx.Done() + // Don't log the same log messages possibly every few seconds in our // portmapper. - portmapperLogf := logger.WithPrefix(c.logf, "portmapper: ") - portmapperLogf, c.portMapperLogfUnregister = netmon.LinkChangeLogLimiter(portmapperLogf, opts.NetMon) - portMapOpts := &portmapper.DebugKnobs{ - DisableAll: func() bool { return opts.DisablePortMapper || c.onlyTCP443.Load() }, + if buildfeatures.HasPortMapper && !opts.DisablePortMapper { + portmapperLogf := logger.WithPrefix(c.logf, "portmapper: ") + portmapperLogf = netmon.LinkChangeLogLimiter(c.connCtx, portmapperLogf, opts.NetMon) + var disableUPnP func() bool + if c.controlKnobs != nil { + disableUPnP = c.controlKnobs.DisableUPnP.Load + } + newPortMapper, ok := portmappertype.HookNewPortMapper.GetOk() + if ok { + c.portMapper = newPortMapper(portmapperLogf, opts.EventBus, opts.NetMon, disableUPnP, c.onlyTCP443.Load) + } + // If !ok, the HookNewPortMapper hook is not set (so feature/portmapper + // isn't linked), but the build tag to explicitly omit the portmapper + // isn't set either. This should only happen to js/wasm builds, where + // the portmapper is a no-op even if linked (but it's no longer linked, + // since the move to feature/portmapper), or if people are wiring up + // their own Tailscale build from pieces. } - c.portMapper = portmapper.NewClient(portmapperLogf, opts.NetMon, portMapOpts, opts.ControlKnobs, c.onPortMapChanged) - c.portMapper.SetGatewayLookupFunc(opts.NetMon.GatewayAndSelfIP) + c.netMon = opts.NetMon c.health = opts.HealthTracker - c.onPortUpdate = opts.OnPortUpdate c.getPeerByKey = opts.PeerByKeyFunc if err := c.rebind(keepCurrentPort); err != nil { return nil, err } - c.connCtx, c.connCtxCancel = context.WithCancel(context.Background()) - c.donec = c.connCtx.Done() c.netChecker = &netcheck.Client{ Logf: logger.WithPrefix(c.logf, "netcheck: "), NetMon: c.netMon, @@ -567,6 +748,9 @@ func NewConn(opts Options) (*Conn, error) { } c.metrics = registerMetrics(opts.Metrics) + if opts.Metrics != nil { + c.homeDERPGauge = opts.Metrics.NewGauge("tailscaled_home_derp_region_id", "DERP region ID of this node's home relay server") + } if d4, err := c.listenRawDisco("ip4"); err == nil { c.logf("[v1] using BPF disco receiver for IPv4") @@ -581,7 +765,7 @@ func NewConn(opts Options) (*Conn, error) { c.logf("[v1] couldn't create raw v6 disco listener, using regular listener instead: %v", err) } - c.logf("magicsock: disco key = %v", c.discoShort) + c.logf("magicsock: disco key = %v", c.discoAtomic.Short()) return c, nil } @@ -592,6 +776,8 @@ func registerMetrics(reg *usermetric.Registry) *metrics { pathDirectV4 := pathLabel{Path: PathDirectIPv4} pathDirectV6 := pathLabel{Path: PathDirectIPv6} pathDERP := pathLabel{Path: PathDERP} + pathPeerRelayV4 := pathLabel{Path: PathPeerRelayIPv4} + pathPeerRelayV6 := pathLabel{Path: PathPeerRelayIPv6} inboundPacketsTotal := usermetric.NewMultiLabelMapWithRegistry[pathLabel]( reg, "tailscaled_inbound_packets_total", @@ -624,25 +810,52 @@ func registerMetrics(reg *usermetric.Registry) *metrics { metricRecvDataPacketsIPv4.Register(&m.inboundPacketsIPv4Total) metricRecvDataPacketsIPv6.Register(&m.inboundPacketsIPv6Total) metricRecvDataPacketsDERP.Register(&m.inboundPacketsDERPTotal) + metricRecvDataPacketsPeerRelayIPv4.Register(&m.inboundPacketsPeerRelayIPv4Total) + metricRecvDataPacketsPeerRelayIPv6.Register(&m.inboundPacketsPeerRelayIPv6Total) + metricRecvDataBytesIPv4.Register(&m.inboundBytesIPv4Total) + metricRecvDataBytesIPv6.Register(&m.inboundBytesIPv6Total) + metricRecvDataBytesDERP.Register(&m.inboundBytesDERPTotal) + metricRecvDataBytesPeerRelayIPv4.Register(&m.inboundBytesPeerRelayIPv4Total) + metricRecvDataBytesPeerRelayIPv6.Register(&m.inboundBytesPeerRelayIPv6Total) + metricSendDataPacketsIPv4.Register(&m.outboundPacketsIPv4Total) + metricSendDataPacketsIPv6.Register(&m.outboundPacketsIPv6Total) + metricSendDataPacketsDERP.Register(&m.outboundPacketsDERPTotal) + metricSendDataPacketsPeerRelayIPv4.Register(&m.outboundPacketsPeerRelayIPv4Total) + metricSendDataPacketsPeerRelayIPv6.Register(&m.outboundPacketsPeerRelayIPv6Total) + metricSendDataBytesIPv4.Register(&m.outboundBytesIPv4Total) + metricSendDataBytesIPv6.Register(&m.outboundBytesIPv6Total) + metricSendDataBytesDERP.Register(&m.outboundBytesDERPTotal) + metricSendDataBytesPeerRelayIPv4.Register(&m.outboundBytesPeerRelayIPv4Total) + metricSendDataBytesPeerRelayIPv6.Register(&m.outboundBytesPeerRelayIPv6Total) metricSendUDP.Register(&m.outboundPacketsIPv4Total) metricSendUDP.Register(&m.outboundPacketsIPv6Total) metricSendDERP.Register(&m.outboundPacketsDERPTotal) + metricSendPeerRelay.Register(&m.outboundPacketsPeerRelayIPv4Total) + metricSendPeerRelay.Register(&m.outboundPacketsPeerRelayIPv6Total) inboundPacketsTotal.Set(pathDirectV4, &m.inboundPacketsIPv4Total) inboundPacketsTotal.Set(pathDirectV6, &m.inboundPacketsIPv6Total) inboundPacketsTotal.Set(pathDERP, &m.inboundPacketsDERPTotal) + inboundPacketsTotal.Set(pathPeerRelayV4, &m.inboundPacketsPeerRelayIPv4Total) + inboundPacketsTotal.Set(pathPeerRelayV6, &m.inboundPacketsPeerRelayIPv6Total) inboundBytesTotal.Set(pathDirectV4, &m.inboundBytesIPv4Total) inboundBytesTotal.Set(pathDirectV6, &m.inboundBytesIPv6Total) inboundBytesTotal.Set(pathDERP, &m.inboundBytesDERPTotal) + inboundBytesTotal.Set(pathPeerRelayV4, &m.inboundBytesPeerRelayIPv4Total) + inboundBytesTotal.Set(pathPeerRelayV6, &m.inboundBytesPeerRelayIPv6Total) outboundPacketsTotal.Set(pathDirectV4, &m.outboundPacketsIPv4Total) outboundPacketsTotal.Set(pathDirectV6, &m.outboundPacketsIPv6Total) outboundPacketsTotal.Set(pathDERP, &m.outboundPacketsDERPTotal) + outboundPacketsTotal.Set(pathPeerRelayV4, &m.outboundPacketsPeerRelayIPv4Total) + outboundPacketsTotal.Set(pathPeerRelayV6, &m.outboundPacketsPeerRelayIPv6Total) outboundBytesTotal.Set(pathDirectV4, &m.outboundBytesIPv4Total) outboundBytesTotal.Set(pathDirectV6, &m.outboundBytesIPv6Total) outboundBytesTotal.Set(pathDERP, &m.outboundBytesDERPTotal) + outboundBytesTotal.Set(pathPeerRelayV4, &m.outboundBytesPeerRelayIPv4Total) + outboundBytesTotal.Set(pathPeerRelayV6, &m.outboundBytesPeerRelayIPv6Total) outboundPacketsDroppedErrors.Set(usermetric.DropLabels{Reason: usermetric.ReasonError}, &m.outboundPacketsDroppedErrors) @@ -651,12 +864,30 @@ func registerMetrics(reg *usermetric.Registry) *metrics { // deregisterMetrics unregisters the underlying usermetrics expvar counters // from clientmetrics. -func deregisterMetrics(m *metrics) { +func deregisterMetrics() { metricRecvDataPacketsIPv4.UnregisterAll() metricRecvDataPacketsIPv6.UnregisterAll() metricRecvDataPacketsDERP.UnregisterAll() + metricRecvDataPacketsPeerRelayIPv4.UnregisterAll() + metricRecvDataPacketsPeerRelayIPv6.UnregisterAll() + metricRecvDataBytesIPv4.UnregisterAll() + metricRecvDataBytesIPv6.UnregisterAll() + metricRecvDataBytesDERP.UnregisterAll() + metricRecvDataBytesPeerRelayIPv4.UnregisterAll() + metricRecvDataBytesPeerRelayIPv6.UnregisterAll() + metricSendDataPacketsIPv4.UnregisterAll() + metricSendDataPacketsIPv6.UnregisterAll() + metricSendDataPacketsDERP.UnregisterAll() + metricSendDataPacketsPeerRelayIPv4.UnregisterAll() + metricSendDataPacketsPeerRelayIPv6.UnregisterAll() + metricSendDataBytesIPv4.UnregisterAll() + metricSendDataBytesIPv6.UnregisterAll() + metricSendDataBytesDERP.UnregisterAll() + metricSendDataBytesPeerRelayIPv4.UnregisterAll() + metricSendDataBytesPeerRelayIPv6.UnregisterAll() metricSendUDP.UnregisterAll() metricSendDERP.UnregisterAll() + metricSendPeerRelay.UnregisterAll() } // InstallCaptureHook installs a callback which is called to @@ -664,6 +895,9 @@ func deregisterMetrics(m *metrics) { // can be called with a nil argument to uninstall the capture // hook. func (c *Conn) InstallCaptureHook(cb packet.CaptureCallback) { + if !buildfeatures.HasCapture { + return + } c.captureHook.Store(cb) } @@ -719,7 +953,7 @@ func (c *Conn) updateEndpoints(why string) { c.muCond.Broadcast() }() c.dlogf("[v1] magicsock: starting endpoint update (%s)", why) - if c.noV4Send.Load() && runtime.GOOS != "js" && !c.onlyTCP443.Load() { + if c.noV4Send.Load() && runtime.GOOS != "js" && !c.onlyTCP443.Load() && !hostinfo.IsInVM86() { c.mu.Lock() closed := c.closed c.mu.Unlock() @@ -789,6 +1023,7 @@ func (c *Conn) setEndpoints(endpoints []tailcfg.Endpoint) (changed bool) { func (c *Conn) SetStaticEndpoints(ep views.Slice[netip.AddrPort]) { c.mu.Lock() if reflect.DeepEqual(c.staticEndpoints.AsSlice(), ep.AsSlice()) { + c.mu.Unlock() return } c.staticEndpoints = ep @@ -852,7 +1087,9 @@ func (c *Conn) updateNetInfo(ctx context.Context) (*netcheck.Report, error) { UPnP: report.UPnP, PMP: report.PMP, PCP: report.PCP, - HavePortMap: c.portMapper.HaveMapping(), + } + if c.portMapper != nil { + ni.HavePortMap = c.portMapper.HaveMapping() } for rid, d := range report.RegionV4Latency { ni.DERPLatency[fmt.Sprintf("%d-v4", rid)] = d.Seconds() @@ -902,7 +1139,7 @@ func (c *Conn) callNetInfoCallbackLocked(ni *tailcfg.NetInfo) { func (c *Conn) addValidDiscoPathForTest(nodeKey key.NodePublic, addr netip.AddrPort) { c.mu.Lock() defer c.mu.Unlock() - c.peerMap.setNodeKeyForIPPort(addr, nodeKey) + c.peerMap.setNodeKeyForEpAddr(epAddr{ap: addr}, nodeKey) } // SetNetInfoCallback sets the func to be called whenever the network conditions @@ -971,13 +1208,17 @@ func (c *Conn) Ping(peer tailcfg.NodeView, res *ipnstate.PingResult, size int, c } // c.mu must be held -func (c *Conn) populateCLIPingResponseLocked(res *ipnstate.PingResult, latency time.Duration, ep netip.AddrPort) { +func (c *Conn) populateCLIPingResponseLocked(res *ipnstate.PingResult, latency time.Duration, ep epAddr) { res.LatencySeconds = latency.Seconds() - if ep.Addr() != tailcfg.DerpMagicIPAddr { - res.Endpoint = ep.String() + if ep.ap.Addr() != tailcfg.DerpMagicIPAddr { + if ep.vni.IsSet() { + res.PeerRelay = ep.String() + } else { + res.Endpoint = ep.String() + } return } - regionID := int(ep.Port()) + regionID := int(ep.ap.Port()) res.DERPRegionID = regionID res.DERPRegionCode = c.derpRegionCodeLocked(regionID) } @@ -1003,19 +1244,44 @@ func (c *Conn) GetEndpointChanges(peer tailcfg.NodeView) ([]EndpointChange, erro // DiscoPublicKey returns the discovery public key. func (c *Conn) DiscoPublicKey() key.DiscoPublic { - return c.discoPublic + return c.discoAtomic.Public() +} + +// RotateDiscoKey generates a new discovery key pair and updates the connection +// to use it. This invalidates all existing disco sessions and will cause peers +// to re-establish discovery sessions with the new key. +// +// This is primarily for debugging and testing purposes, a future enhancement +// should provide a mechanism for seamless rotation by supporting short term use +// of the old key. +func (c *Conn) RotateDiscoKey() { + oldShort := c.discoAtomic.Short() + newPrivate := key.NewDisco() + + c.mu.Lock() + c.discoAtomic.Set(newPrivate) + newShort := c.discoAtomic.Short() + c.discoInfo = make(map[key.DiscoPublic]*discoInfo) + connCtx := c.connCtx + c.mu.Unlock() + + c.logf("magicsock: rotated disco key from %v to %v", oldShort, newShort) + + if connCtx != nil { + c.ReSTUN("disco-key-rotation") + } } // determineEndpoints returns the machine's endpoint addresses. It does a STUN -// lookup (via netcheck) to determine its public address. Additionally any -// static enpoints provided by user are always added to the returned endpoints +// lookup (via netcheck) to determine its public address. Additionally, any +// static endpoints provided by user are always added to the returned endpoints // without validating if the node can be reached via those endpoints. // // c.mu must NOT be held. func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, error) { var havePortmap bool var portmapExt netip.AddrPort - if runtime.GOOS != "js" { + if runtime.GOOS != "js" && c.portMapper != nil { portmapExt, havePortmap = c.portMapper.GetCachedMappingOrStartCreatingOne() } @@ -1055,7 +1321,7 @@ func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, erro } // If we didn't have a portmap earlier, maybe it's done by now. - if !havePortmap { + if !havePortmap && c.portMapper != nil { portmapExt, havePortmap = c.portMapper.GetCachedMappingOrStartCreatingOne() } if havePortmap { @@ -1216,8 +1482,8 @@ func (c *Conn) networkDown() bool { return !c.networkUp.Load() } // Send implements conn.Bind. // -// See https://pkg.go.dev/golang.zx2c4.com/wireguard/conn#Bind.Send -func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint) (err error) { +// See https://pkg.go.dev/github.com/tailscale/wireguard-go/conn#Bind.Send +func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint, offset int) (err error) { n := int64(len(buffs)) defer func() { if err != nil { @@ -1229,12 +1495,18 @@ func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint) (err error) { metricSendDataNetworkDown.Add(n) return errNetworkDown } - if ep, ok := ep.(*endpoint); ok { - return ep.send(buffs) + switch ep := ep.(type) { + case *endpoint: + return ep.send(buffs, offset) + case *lazyEndpoint: + // A [*lazyEndpoint] may end up on this TX codepath when wireguard-go is + // deemed "under handshake load" and ends up transmitting a cookie reply + // using the received [conn.Endpoint] in [device.SendHandshakeCookie]. + if ep.src.ap.Addr().Is6() { + return c.pconn6.WriteWireGuardBatchTo(buffs, ep.src, offset) + } + return c.pconn4.WriteWireGuardBatchTo(buffs, ep.src, offset) } - // If it's not of type *endpoint, it's probably *lazyEndpoint, which means - // we don't actually know who the peer is and we're waiting for wireguard-go - // to switch the endpoint. See go/corp/20732. return nil } @@ -1246,19 +1518,19 @@ var errNoUDP = errors.New("no UDP available on platform") var errUnsupportedConnType = errors.New("unsupported connection type") -func (c *Conn) sendUDPBatch(addr netip.AddrPort, buffs [][]byte) (sent bool, err error) { +func (c *Conn) sendUDPBatch(addr epAddr, buffs [][]byte, offset int) (sent bool, err error) { isIPv6 := false switch { - case addr.Addr().Is4(): - case addr.Addr().Is6(): + case addr.ap.Addr().Is4(): + case addr.ap.Addr().Is6(): isIPv6 = true default: panic("bogus sendUDPBatch addr type") } if isIPv6 { - err = c.pconn6.WriteBatchTo(buffs, addr) + err = c.pconn6.WriteWireGuardBatchTo(buffs, addr, offset) } else { - err = c.pconn4.WriteBatchTo(buffs, addr) + err = c.pconn4.WriteWireGuardBatchTo(buffs, addr, offset) } if err != nil { var errGSO neterror.ErrUDPGSODisabled @@ -1274,23 +1546,37 @@ func (c *Conn) sendUDPBatch(addr netip.AddrPort, buffs [][]byte) (sent bool, err // sendUDP sends UDP packet b to ipp. // See sendAddr's docs on the return value meanings. -func (c *Conn) sendUDP(ipp netip.AddrPort, b []byte, isDisco bool) (sent bool, err error) { +func (c *Conn) sendUDP(ipp netip.AddrPort, b []byte, isDisco bool, isGeneveEncap bool) (sent bool, err error) { if runtime.GOOS == "js" { return false, errNoUDP } sent, err = c.sendUDPStd(ipp, b) if err != nil { - metricSendUDPError.Add(1) + if isGeneveEncap { + metricSendPeerRelayError.Add(1) + } else { + metricSendUDPError.Add(1) + } c.maybeRebindOnError(err) } else { if sent && !isDisco { switch { case ipp.Addr().Is4(): - c.metrics.outboundPacketsIPv4Total.Add(1) - c.metrics.outboundBytesIPv4Total.Add(int64(len(b))) + if isGeneveEncap { + c.metrics.outboundPacketsPeerRelayIPv4Total.Add(1) + c.metrics.outboundBytesPeerRelayIPv4Total.Add(int64(len(b))) + } else { + c.metrics.outboundPacketsIPv4Total.Add(1) + c.metrics.outboundBytesIPv4Total.Add(int64(len(b))) + } case ipp.Addr().Is6(): - c.metrics.outboundPacketsIPv6Total.Add(1) - c.metrics.outboundBytesIPv6Total.Add(int64(len(b))) + if isGeneveEncap { + c.metrics.outboundPacketsPeerRelayIPv6Total.Add(1) + c.metrics.outboundBytesPeerRelayIPv6Total.Add(int64(len(b))) + } else { + c.metrics.outboundPacketsIPv6Total.Add(1) + c.metrics.outboundBytesIPv6Total.Add(int64(len(b))) + } } } } @@ -1307,6 +1593,7 @@ func (c *Conn) maybeRebindOnError(err error) { if c.lastErrRebind.Load().Before(time.Now().Add(-5 * time.Second)) { c.logf("magicsock: performing rebind due to %q", reason) + c.lastErrRebind.Store(time.Now()) c.Rebind() go c.ReSTUN(reason) } else { @@ -1365,9 +1652,9 @@ func (c *Conn) sendUDPStd(addr netip.AddrPort, b []byte) (sent bool, err error) // An example of when they might be different: sending to an // IPv6 address when the local machine doesn't have IPv6 support // returns (false, nil); it's not an error, but nothing was sent. -func (c *Conn) sendAddr(addr netip.AddrPort, pubKey key.NodePublic, b []byte, isDisco bool) (sent bool, err error) { +func (c *Conn) sendAddr(addr netip.AddrPort, pubKey key.NodePublic, b []byte, isDisco bool, isGeneveEncap bool) (sent bool, err error) { if addr.Addr() != tailcfg.DerpMagicIPAddr { - return c.sendUDP(addr, b, isDisco) + return c.sendUDP(addr, b, isDisco, isGeneveEncap) } regionID := int(addr.Port()) @@ -1384,18 +1671,27 @@ func (c *Conn) sendAddr(addr netip.AddrPort, pubKey key.NodePublic, b []byte, is // internal locks. pkt := bytes.Clone(b) - select { - case <-c.donec: - metricSendDERPErrorClosed.Add(1) - return false, errConnClosed - case ch <- derpWriteRequest{addr, pubKey, pkt, isDisco}: - metricSendDERPQueued.Add(1) - return true, nil - default: - metricSendDERPErrorQueue.Add(1) - // Too many writes queued. Drop packet. - return false, errDropDerpPacket + wr := derpWriteRequest{addr, pubKey, pkt, isDisco} + for range 3 { + select { + case <-c.donec: + metricSendDERPErrorClosed.Add(1) + return false, errConnClosed + case ch <- wr: + metricSendDERPQueued.Add(1) + return true, nil + default: + select { + case <-ch: + metricSendDERPDropped.Add(1) + default: + } + } } + // gave up after 3 write attempts + metricSendDERPErrorQueue.Add(1) + // Too many writes queued. Drop packet. + return false, errDropDerpPacket } type receiveBatch struct { @@ -1421,7 +1717,9 @@ func (c *Conn) putReceiveBatch(batch *receiveBatch) { func (c *Conn) receiveIPv4() conn.ReceiveFunc { return c.mkReceiveFunc(&c.pconn4, c.health.ReceiveFuncStats(health.ReceiveIPv4), &c.metrics.inboundPacketsIPv4Total, + &c.metrics.inboundPacketsPeerRelayIPv4Total, &c.metrics.inboundBytesIPv4Total, + &c.metrics.inboundBytesPeerRelayIPv4Total, ) } @@ -1429,18 +1727,20 @@ func (c *Conn) receiveIPv4() conn.ReceiveFunc { func (c *Conn) receiveIPv6() conn.ReceiveFunc { return c.mkReceiveFunc(&c.pconn6, c.health.ReceiveFuncStats(health.ReceiveIPv6), &c.metrics.inboundPacketsIPv6Total, + &c.metrics.inboundPacketsPeerRelayIPv6Total, &c.metrics.inboundBytesIPv6Total, + &c.metrics.inboundBytesPeerRelayIPv6Total, ) } // mkReceiveFunc creates a ReceiveFunc reading from ruc. // The provided healthItem and metrics are updated if non-nil. -func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFuncStats, packetMetric, bytesMetric *expvar.Int) conn.ReceiveFunc { - // epCache caches an IPPort->endpoint for hot flows. - var epCache ippEndpointCache +func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFuncStats, directPacketMetric, peerRelayPacketMetric, directBytesMetric, peerRelayBytesMetric *expvar.Int) conn.ReceiveFunc { + // epCache caches an epAddr->endpoint for hot flows. + var epCache epAddrEndpointCache return func(buffs [][]byte, sizes []int, eps []conn.Endpoint) (_ int, retErr error) { - if healthItem != nil { + if buildfeatures.HasHealth && healthItem != nil { healthItem.Enter() defer healthItem.Exit() defer func() { @@ -1471,15 +1771,24 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu continue } ipp := msg.Addr.(*net.UDPAddr).AddrPort() - if ep, ok := c.receiveIP(msg.Buffers[0][:msg.N], ipp, &epCache); ok { - if packetMetric != nil { - packetMetric.Add(1) - } - if bytesMetric != nil { - bytesMetric.Add(int64(msg.N)) + if ep, size, isGeneveEncap, ok := c.receiveIP(msg.Buffers[0][:msg.N], ipp, &epCache); ok { + if isGeneveEncap { + if peerRelayPacketMetric != nil { + peerRelayPacketMetric.Add(1) + } + if peerRelayBytesMetric != nil { + peerRelayBytesMetric.Add(int64(msg.N)) + } + } else { + if directPacketMetric != nil { + directPacketMetric.Add(1) + } + if directBytesMetric != nil { + directBytesMetric.Add(int64(msg.N)) + } } eps[i] = ep - sizes[i] = msg.N + sizes[i] = size reportToCaller = true } else { sizes[i] = 0 @@ -1492,49 +1801,114 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu } } +// looksLikeInitiationMsg returns true if b looks like a WireGuard initiation +// message, otherwise it returns false. +func looksLikeInitiationMsg(b []byte) bool { + return len(b) == device.MessageInitiationSize && + binary.LittleEndian.Uint32(b) == device.MessageInitiationType +} + // receiveIP is the shared bits of ReceiveIPv4 and ReceiveIPv6. // +// size is the length of 'b' to report up to wireguard-go (only relevant if +// 'ok' is true). +// +// isGeneveEncap is whether 'b' is encapsulated by a Geneve header (only +// relevant if 'ok' is true). +// // ok is whether this read should be reported up to wireguard-go (our // caller). -func (c *Conn) receiveIP(b []byte, ipp netip.AddrPort, cache *ippEndpointCache) (_ conn.Endpoint, ok bool) { +func (c *Conn) receiveIP(b []byte, ipp netip.AddrPort, cache *epAddrEndpointCache) (_ conn.Endpoint, size int, isGeneveEncap bool, ok bool) { var ep *endpoint - if stun.Is(b) { + size = len(b) + + var geneve packet.GeneveHeader + pt, isGeneveEncap := packetLooksLike(b) + src := epAddr{ap: ipp} + if isGeneveEncap { + err := geneve.Decode(b) + if err != nil { + // Decode only returns an error when 'b' is too short, and + // 'isGeneveEncap' indicates it's a sufficient length. + c.logf("[unexpected] geneve header decoding error: %v", err) + return nil, 0, false, false + } + src.vni = geneve.VNI + } + switch pt { + case packetLooksLikeDisco: + if isGeneveEncap { + b = b[packet.GeneveFixedHeaderLength:] + } + // The Geneve header control bit should only be set for relay handshake + // messages terminating on or originating from a UDP relay server. We + // have yet to open the encrypted disco payload to determine the + // [disco.MessageType], but we assert it should be handshake-related. + shouldByRelayHandshakeMsg := geneve.Control == true + c.handleDiscoMessage(b, src, shouldByRelayHandshakeMsg, key.NodePublic{}, discoRXPathUDP) + return nil, 0, false, false + case packetLooksLikeSTUNBinding: c.netChecker.ReceiveSTUNPacket(b, ipp) - return nil, false - } - if c.handleDiscoMessage(b, ipp, key.NodePublic{}, discoRXPathUDP) { - return nil, false + return nil, 0, false, false + default: + // Fall through for all other packet types as they are assumed to + // be potentially WireGuard. } + if !c.havePrivateKey.Load() { // If we have no private key, we're logged out or // stopped. Don't try to pass these wireguard packets // up to wireguard-go; it'll just complain (issue 1167). - return nil, false + return nil, 0, false, false } - if cache.ipp == ipp && cache.de != nil && cache.gen == cache.de.numStopAndReset() { + + // geneveInclusivePacketLen holds the packet length prior to any potential + // Geneve header stripping. + geneveInclusivePacketLen := len(b) + if src.vni.IsSet() { + // Strip away the Geneve header before returning the packet to + // wireguard-go. + // + // TODO(jwhited): update [github.com/tailscale/wireguard-go/conn.ReceiveFunc] + // to support returning start offset in order to get rid of this memmove perf + // penalty. + size = copy(b, b[packet.GeneveFixedHeaderLength:]) + b = b[:size] + } + + if cache.epAddr == src && cache.de != nil && cache.gen == cache.de.numStopAndReset() { ep = cache.de } else { c.mu.Lock() - de, ok := c.peerMap.endpointForIPPort(ipp) + de, ok := c.peerMap.endpointForEpAddr(src) c.mu.Unlock() if !ok { - if c.controlKnobs != nil && c.controlKnobs.DisableCryptorouting.Load() { - return nil, false - } - return &lazyEndpoint{c: c, src: ipp}, true + // TODO(jwhited): reuse [lazyEndpoint] across calls to receiveIP() + // for the same batch & [epAddr] src. + return &lazyEndpoint{c: c, src: src}, size, isGeneveEncap, true } - cache.ipp = ipp + cache.epAddr = src cache.de = de cache.gen = de.numStopAndReset() ep = de } now := mono.Now() ep.lastRecvUDPAny.StoreAtomic(now) - ep.noteRecvActivity(ipp, now) - if stats := c.stats.Load(); stats != nil { - stats.UpdateRxPhysical(ep.nodeAddr, ipp, 1, len(b)) + connNoted := ep.noteRecvActivity(src, now) + if buildfeatures.HasNetLog { + if update := c.connCounter.Load(); update != nil { + update(0, netip.AddrPortFrom(ep.nodeAddr, 0), ipp, 1, geneveInclusivePacketLen, true) + } } - return ep, true + if src.vni.IsSet() && (connNoted || looksLikeInitiationMsg(b)) { + // connNoted is periodic, but we also want to verify if the peer is who + // we believe for all initiation messages, otherwise we could get + // unlucky and fail to JIT configure the "correct" peer. + // TODO(jwhited): relax this to include direct connections + // See http://go/corp/29422 & http://go/corp/30042 + return &lazyEndpoint{c: c, maybeEP: ep, src: src}, size, isGeneveEncap, true + } + return ep, size, isGeneveEncap, true } // discoLogLevel controls the verbosity of discovery log messages. @@ -1555,29 +1929,89 @@ const ( // speeds. var debugIPv4DiscoPingPenalty = envknob.RegisterDuration("TS_DISCO_PONG_IPV4_DELAY") +// sendDiscoAllocateUDPRelayEndpointRequest is primarily an alias for +// sendDiscoMessage, but it will alternatively send m over the eventbus if dst +// is a DERP IP:port, and dstKey is self. This saves a round-trip through DERP +// when we are attempting to allocate on a self (in-process) peer relay server. +func (c *Conn) sendDiscoAllocateUDPRelayEndpointRequest(dst epAddr, dstKey key.NodePublic, dstDisco key.DiscoPublic, allocReq *disco.AllocateUDPRelayEndpointRequest, logLevel discoLogLevel) (sent bool, err error) { + isDERP := dst.ap.Addr() == tailcfg.DerpMagicIPAddr + selfNodeKey := c.publicKeyAtomic.Load() + if isDERP && dstKey.Compare(selfNodeKey) == 0 { + c.allocRelayEndpointPub.Publish(UDPRelayAllocReq{ + RxFromNodeKey: selfNodeKey, + RxFromDiscoKey: c.discoAtomic.Public(), + Message: allocReq, + }) + metricLocalDiscoAllocUDPRelayEndpointRequest.Add(1) + return true, nil + } + return c.sendDiscoMessage(dst, dstKey, dstDisco, allocReq, logLevel) +} + // sendDiscoMessage sends discovery message m to dstDisco at dst. // -// If dst is a DERP IP:port, then dstKey must be non-zero. +// If dst.ap is a DERP IP:port, then dstKey must be non-zero. +// +// If dst.vni.isSet(), the [disco.Message] will be preceded by a Geneve header +// with the VNI field set to the value returned by vni.get(). // // The dstKey should only be non-zero if the dstDisco key // unambiguously maps to exactly one peer. -func (c *Conn) sendDiscoMessage(dst netip.AddrPort, dstKey key.NodePublic, dstDisco key.DiscoPublic, m disco.Message, logLevel discoLogLevel) (sent bool, err error) { - isDERP := dst.Addr() == tailcfg.DerpMagicIPAddr - if _, isPong := m.(*disco.Pong); isPong && !isDERP && dst.Addr().Is4() { +func (c *Conn) sendDiscoMessage(dst epAddr, dstKey key.NodePublic, dstDisco key.DiscoPublic, m disco.Message, logLevel discoLogLevel) (sent bool, err error) { + isDERP := dst.ap.Addr() == tailcfg.DerpMagicIPAddr + if _, isPong := m.(*disco.Pong); isPong && !isDERP && dst.ap.Addr().Is4() { time.Sleep(debugIPv4DiscoPingPenalty()) } + isRelayHandshakeMsg := false + switch m.(type) { + case *disco.BindUDPRelayEndpoint, *disco.BindUDPRelayEndpointAnswer: + isRelayHandshakeMsg = true + } + c.mu.Lock() if c.closed { c.mu.Unlock() return false, errConnClosed } - pkt := make([]byte, 0, 512) // TODO: size it correctly? pool? if it matters. - pkt = append(pkt, disco.Magic...) - pkt = c.discoPublic.AppendTo(pkt) - di := c.discoInfoLocked(dstDisco) + var di *discoInfo + switch { + case isRelayHandshakeMsg: + var ok bool + di, ok = c.relayManager.discoInfo(dstDisco) + if !ok { + c.mu.Unlock() + return false, errors.New("unknown relay server") + } + case c.peerMap.knownPeerDiscoKey(dstDisco): + di = c.discoInfoForKnownPeerLocked(dstDisco) + default: + // This is an attempt to send to an unknown peer that is not a relay + // server. This can happen when a call to the current function, which is + // often via a new goroutine, races with applying a change in the + // netmap, e.g. the associated peer(s) for dstDisco goes away. + c.mu.Unlock() + return false, errors.New("unknown peer") + } c.mu.Unlock() + pkt := make([]byte, 0, 512) // TODO: size it correctly? pool? if it matters. + if dst.vni.IsSet() { + gh := packet.GeneveHeader{ + Version: 0, + Protocol: packet.GeneveProtocolDisco, + VNI: dst.vni, + Control: isRelayHandshakeMsg, + } + pkt = append(pkt, make([]byte, packet.GeneveFixedHeaderLength)...) + err := gh.Encode(pkt) + if err != nil { + return false, err + } + } + pkt = append(pkt, disco.Magic...) + pkt = c.discoAtomic.Public().AppendTo(pkt) + if isDERP { metricSendDiscoDERP.Add(1) } else { @@ -1587,14 +2021,14 @@ func (c *Conn) sendDiscoMessage(dst netip.AddrPort, dstKey key.NodePublic, dstDi box := di.sharedKey.Seal(m.AppendMarshal(nil)) pkt = append(pkt, box...) const isDisco = true - sent, err = c.sendAddr(dst, dstKey, pkt, isDisco) + sent, err = c.sendAddr(dst.ap, dstKey, pkt, isDisco, dst.vni.IsSet()) if sent { if logLevel == discoLog || (logLevel == discoVerboseLog && debugDisco()) { node := "?" if !dstKey.IsZero() { node = dstKey.ShortString() } - c.dlogf("[v1] magicsock: disco: %v->%v (%v, %v) sent %v len %v\n", c.discoShort, dstDisco.ShortString(), node, derpStr(dst.String()), disco.MessageSummary(m), len(pkt)) + c.dlogf("[v1] magicsock: disco: %v->%v (%v, %v) sent %v len %v\n", c.discoAtomic.Short(), dstDisco.ShortString(), node, derpStr(dst.String()), disco.MessageSummary(m), len(pkt)) } if isDERP { metricSentDiscoDERP.Add(1) @@ -1608,12 +2042,22 @@ func (c *Conn) sendDiscoMessage(dst netip.AddrPort, dstKey key.NodePublic, dstDi metricSentDiscoPong.Add(1) case *disco.CallMeMaybe: metricSentDiscoCallMeMaybe.Add(1) + case *disco.CallMeMaybeVia: + metricSentDiscoCallMeMaybeVia.Add(1) + case *disco.BindUDPRelayEndpoint: + metricSentDiscoBindUDPRelayEndpoint.Add(1) + case *disco.BindUDPRelayEndpointAnswer: + metricSentDiscoBindUDPRelayEndpointAnswer.Add(1) + case *disco.AllocateUDPRelayEndpointRequest: + metricSentDiscoAllocUDPRelayEndpointRequest.Add(1) + case *disco.AllocateUDPRelayEndpointResponse: + metricSentDiscoAllocUDPRelayEndpointResponse.Add(1) } } else if err == nil { // Can't send. (e.g. no IPv6 locally) } else { if !c.networkDown() && pmtuShouldLogDiscoTxErr(m, err) { - c.logf("magicsock: disco: failed to send %v to %v: %v", disco.MessageSummary(m), dst, err) + c.logf("magicsock: disco: failed to send %v to %v %s: %v", disco.MessageSummary(m), dst, dstKey.ShortString(), err) } } return sent, err @@ -1627,8 +2071,98 @@ const ( discoRXPathRawSocket discoRXPath = "raw socket" ) -// handleDiscoMessage handles a discovery message and reports whether -// msg was a Tailscale inter-node discovery message. +const discoHeaderLen = len(disco.Magic) + key.DiscoPublicRawLen + +type packetLooksLikeType int + +const ( + packetLooksLikeWireGuard packetLooksLikeType = iota + packetLooksLikeSTUNBinding + packetLooksLikeDisco +) + +// packetLooksLike reports a [packetsLooksLikeType] for 'msg', and whether +// 'msg' is encapsulated by a Geneve header (or naked). +// +// [packetLooksLikeSTUNBinding] is never Geneve-encapsulated. +// +// Naked STUN binding, Naked Disco, Geneve followed by Disco, naked WireGuard, +// and Geneve followed by WireGuard can be confidently distinguished based on +// the following: +// +// 1. STUN binding @ msg[1] (0x01) is sufficiently non-overlapping with the +// Geneve header where the LSB is always 0 (part of 6 "reserved" bits). +// +// 2. STUN binding @ msg[1] (0x01) is sufficiently non-overlapping with naked +// WireGuard, which is always a 0 byte value (WireGuard message type +// occupies msg[0:4], and msg[1:4] are always 0). +// +// 3. STUN binding @ msg[1] (0x01) is sufficiently non-overlapping with the +// second byte of [disco.Magic] (0x53). +// +// 4. [disco.Magic] @ msg[2:4] (0xf09f) is sufficiently non-overlapping with a +// Geneve protocol field value of [packet.GeneveProtocolDisco] or +// [packet.GeneveProtocolWireGuard] . +// +// 5. [disco.Magic] @ msg[0] (0x54) is sufficiently non-overlapping with the +// first byte of a WireGuard packet (0x01-0x04). +// +// 6. [packet.GeneveHeader] with a Geneve protocol field value of +// [packet.GeneveProtocolDisco] or [packet.GeneveProtocolWireGuard] +// (msg[2:4]) is sufficiently non-overlapping with the second 2 bytes of a +// WireGuard packet which are always 0x0000. +func packetLooksLike(msg []byte) (t packetLooksLikeType, isGeneveEncap bool) { + if stun.Is(msg) && + msg[1] == 0x01 { // method binding + return packetLooksLikeSTUNBinding, false + } + + // TODO(jwhited): potentially collapse into disco.LooksLikeDiscoWrapper() + // if safe to do so. + looksLikeDisco := func(msg []byte) bool { + if len(msg) >= discoHeaderLen && string(msg[:len(disco.Magic)]) == disco.Magic { + return true + } + return false + } + + // Do we have a Geneve header? + if len(msg) >= packet.GeneveFixedHeaderLength && + msg[0]&0xC0 == 0 && // version bits that we always transmit as 0s + msg[1]&0x3F == 0 && // reserved bits that we always transmit as 0s + msg[7] == 0 { // reserved byte that we always transmit as 0 + switch binary.BigEndian.Uint16(msg[2:4]) { + case packet.GeneveProtocolDisco: + if looksLikeDisco(msg[packet.GeneveFixedHeaderLength:]) { + return packetLooksLikeDisco, true + } else { + // The Geneve header is well-formed, and it indicated this + // was disco, but it's not. The evaluated bytes at this point + // are always distinct from naked WireGuard (msg[2:4] are always + // 0x0000) and naked Disco (msg[2:4] are always 0xf09f), but + // maintain pre-Geneve behavior and fall back to assuming it's + // naked WireGuard. + return packetLooksLikeWireGuard, false + } + case packet.GeneveProtocolWireGuard: + return packetLooksLikeWireGuard, true + default: + // The Geneve header is well-formed, but the protocol field value is + // unknown to us. The evaluated bytes at this point are not + // necessarily distinct from naked WireGuard or naked Disco, fall + // through. + } + } + + if looksLikeDisco(msg) { + return packetLooksLikeDisco, false + } else { + return packetLooksLikeWireGuard, false + } +} + +// handleDiscoMessage handles a discovery message. The caller is assumed to have +// verified 'msg' returns [packetLooksLikeDisco] from packetLooksLike(). // // A discovery message has the form: // @@ -1637,23 +2171,18 @@ const ( // - nonce [24]byte // - naclbox of payload (see tailscale.com/disco package for inner payload format) // -// For messages received over DERP, the src.Addr() will be derpMagicIP (with -// src.Port() being the region ID) and the derpNodeSrc will be the node key +// For messages received over DERP, the src.ap.Addr() will be derpMagicIP (with +// src.ap.Port() being the region ID) and the derpNodeSrc will be the node key // it was received from at the DERP layer. derpNodeSrc is zero when received // over UDP. -func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc key.NodePublic, via discoRXPath) (isDiscoMsg bool) { - const headerLen = len(disco.Magic) + key.DiscoPublicRawLen - if len(msg) < headerLen || string(msg[:len(disco.Magic)]) != disco.Magic { - return false - } - - // If the first four parts are the prefix of disco.Magic - // (0x5453f09f) then it's definitely not a valid WireGuard - // packet (which starts with little-endian uint32 1, 2, 3, 4). - // Use naked returns for all following paths. - isDiscoMsg = true - - sender := key.DiscoPublicFromRaw32(mem.B(msg[len(disco.Magic):headerLen])) +// +// If 'msg' was encapsulated by a Geneve header it is assumed to have already +// been stripped. +// +// 'shouldBeRelayHandshakeMsg' will be true if 'msg' was encapsulated +// by a Geneve header with the control bit set. +func (c *Conn) handleDiscoMessage(msg []byte, src epAddr, shouldBeRelayHandshakeMsg bool, derpNodeSrc key.NodePublic, via discoRXPath) { + sender := key.DiscoPublicFromRaw32(mem.B(msg[len(disco.Magic):discoHeaderLen])) c.mu.Lock() defer c.mu.Unlock() @@ -1666,11 +2195,23 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke } if c.privateKey.IsZero() { // Ignore disco messages when we're stopped. - // Still return true, to not pass it down to wireguard. return } - if !c.peerMap.knownPeerDiscoKey(sender) { + var di *discoInfo + switch { + case shouldBeRelayHandshakeMsg: + var ok bool + di, ok = c.relayManager.discoInfo(sender) + if !ok { + if debugDisco() { + c.logf("magicsock: disco: ignoring disco-looking relay handshake frame, no active handshakes with key %v over %v", sender.ShortString(), src) + } + return + } + case c.peerMap.knownPeerDiscoKey(sender): + di = c.discoInfoForKnownPeerLocked(sender) + default: metricRecvDiscoBadPeer.Add(1) if debugDisco() { c.logf("magicsock: disco: ignoring disco-looking frame, don't know of key %v", sender.ShortString()) @@ -1678,26 +2219,22 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke return } - isDERP := src.Addr() == tailcfg.DerpMagicIPAddr - if !isDERP { + isDERP := src.ap.Addr() == tailcfg.DerpMagicIPAddr + if !isDERP && !shouldBeRelayHandshakeMsg { // Record receive time for UDP transport packets. - pi, ok := c.peerMap.byIPPort[src] + pi, ok := c.peerMap.byEpAddr[src] if ok { pi.ep.lastRecvUDPAny.StoreAtomic(mono.Now()) } } - // We're now reasonably sure we're expecting communication from - // this peer, do the heavy crypto lifting to see what they want. - // - // From here on, peerNode and de are non-nil. + // We're now reasonably sure we're expecting communication from 'sender', + // do the heavy crypto lifting to see what they want. - di := c.discoInfoLocked(sender) - - sealedBox := msg[headerLen:] + sealedBox := msg[discoHeaderLen:] payload, ok := di.sharedKey.Open(sealedBox) if !ok { - // This might be have been intended for a previous + // This might have been intended for a previous // disco key. When we restart we get a new disco key // and old packets might've still been in flight (or // scheduled). This is particularly the case for LANs @@ -1717,7 +2254,8 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke // Emit information about the disco frame into the pcap stream // if a capture hook is installed. if cb := c.captureHook.Load(); cb != nil { - cb(packet.PathDisco, time.Now(), disco.ToPCAPFrame(src, derpNodeSrc, payload), packet.CaptureMeta{}) + // TODO(jwhited): include VNI context? + cb(packet.PathDisco, time.Now(), disco.ToPCAPFrame(src.ap, derpNodeSrc, payload), packet.CaptureMeta{}) } dm, err := disco.Parse(payload) @@ -1740,6 +2278,20 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke metricRecvDiscoUDP.Add(1) } + if shouldBeRelayHandshakeMsg { + challenge, ok := dm.(*disco.BindUDPRelayEndpointChallenge) + if !ok { + // We successfully parsed the disco message, but it wasn't a + // challenge. We should never receive other message types + // from a relay server with the Geneve header control bit set. + c.logf("[unexpected] %T packets should not come from a relay server with Geneve control bit set", dm) + return + } + c.relayManager.handleRxDiscoMsg(c, challenge, key.NodePublic{}, di.discoKey, src) + metricRecvDiscoBindUDPRelayEndpointChallenge.Add(1) + return + } + switch dm := dm.(type) { case *disco.Ping: metricRecvDiscoPing.Add(1) @@ -1749,24 +2301,65 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke // There might be multiple nodes for the sender's DiscoKey. // Ask each to handle it, stopping once one reports that // the Pong's TxID was theirs. + knownTxID := false c.peerMap.forEachEndpointWithDiscoKey(sender, func(ep *endpoint) (keepGoing bool) { if ep.handlePongConnLocked(dm, di, src) { + knownTxID = true return false } return true }) - case *disco.CallMeMaybe: - metricRecvDiscoCallMeMaybe.Add(1) + if !knownTxID && src.vni.IsSet() { + // If it's an unknown TxID, and it's Geneve-encapsulated, then + // make [relayManager] aware. It might be in the middle of probing + // src. + c.relayManager.handleRxDiscoMsg(c, dm, key.NodePublic{}, di.discoKey, src) + } + case *disco.CallMeMaybe, *disco.CallMeMaybeVia: + var via *disco.CallMeMaybeVia + isVia := false + msgType := "CallMeMaybe" + cmm, ok := dm.(*disco.CallMeMaybe) + if ok { + metricRecvDiscoCallMeMaybe.Add(1) + } else { + metricRecvDiscoCallMeMaybeVia.Add(1) + via = dm.(*disco.CallMeMaybeVia) + msgType = "CallMeMaybeVia" + isVia = true + } + if !isDERP || derpNodeSrc.IsZero() { - // CallMeMaybe messages should only come via DERP. - c.logf("[unexpected] CallMeMaybe packets should only come via DERP") + // CallMeMaybe{Via} messages should only come via DERP. + c.logf("[unexpected] %s packets should only come via DERP", msgType) return } nodeKey := derpNodeSrc ep, ok := c.peerMap.endpointForNodeKey(nodeKey) if !ok { - metricRecvDiscoCallMeMaybeBadNode.Add(1) - c.logf("magicsock: disco: ignoring CallMeMaybe from %v; %v is unknown", sender.ShortString(), derpNodeSrc.ShortString()) + if isVia { + metricRecvDiscoCallMeMaybeViaBadNode.Add(1) + } else { + metricRecvDiscoCallMeMaybeBadNode.Add(1) + } + c.logf("magicsock: disco: ignoring %s from %v; %v is unknown", msgType, sender.ShortString(), derpNodeSrc.ShortString()) + return + } + // If the "disable-relay-client" node attr is set for this node, it + // can't be a UDP relay client, so drop any CallMeMaybeVia messages it + // receives. + if isVia && !c.relayClientEnabled { + c.logf("magicsock: disco: ignoring %s from %v; disable-relay-client node attr is set", msgType, sender.ShortString()) + return + } + + ep.mu.Lock() + relayCapable := ep.relayCapable + lastBest := ep.bestAddr + lastBestIsTrusted := mono.Now().Before(ep.trustBestAddrUntil) + ep.mu.Unlock() + if isVia && !relayCapable { + c.logf("magicsock: disco: ignoring %s from %v; %v is not known to be relay capable", msgType, sender.ShortString(), sender.ShortString()) return } epDisco := ep.disco.Load() @@ -1774,15 +2367,119 @@ func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc ke return } if epDisco.key != di.discoKey { - metricRecvDiscoCallMeMaybeBadDisco.Add(1) - c.logf("[unexpected] CallMeMaybe from peer via DERP whose netmap discokey != disco source") + if isVia { + metricRecvDiscoCallMeMaybeViaBadDisco.Add(1) + } else { + metricRecvDiscoCallMeMaybeBadDisco.Add(1) + } + c.logf("[unexpected] %s from peer via DERP whose netmap discokey != disco source", msgType) return } - c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got call-me-maybe, %d endpoints", - c.discoShort, epDisco.short, - ep.publicKey.ShortString(), derpStr(src.String()), - len(dm.MyNumber)) - go ep.handleCallMeMaybe(dm) + if isVia { + c.dlogf("[v1] magicsock: disco: %v<-%v via %v (%v, %v) got call-me-maybe-via, %d endpoints", + c.discoAtomic.Short(), epDisco.short, via.ServerDisco.ShortString(), + ep.publicKey.ShortString(), derpStr(src.String()), + len(via.AddrPorts)) + c.relayManager.handleCallMeMaybeVia(ep, lastBest, lastBestIsTrusted, via) + } else { + c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got call-me-maybe, %d endpoints", + c.discoAtomic.Short(), epDisco.short, + ep.publicKey.ShortString(), derpStr(src.String()), + len(cmm.MyNumber)) + go ep.handleCallMeMaybe(cmm) + } + case *disco.AllocateUDPRelayEndpointRequest, *disco.AllocateUDPRelayEndpointResponse: + var resp *disco.AllocateUDPRelayEndpointResponse + isResp := false + msgType := "AllocateUDPRelayEndpointRequest" + req, ok := dm.(*disco.AllocateUDPRelayEndpointRequest) + if ok { + metricRecvDiscoAllocUDPRelayEndpointRequest.Add(1) + } else { + metricRecvDiscoAllocUDPRelayEndpointResponse.Add(1) + resp = dm.(*disco.AllocateUDPRelayEndpointResponse) + msgType = "AllocateUDPRelayEndpointResponse" + isResp = true + } + + if !isDERP { + // These messages should only come via DERP. + c.logf("[unexpected] %s packets should only come via DERP", msgType) + return + } + nodeKey := derpNodeSrc + ep, ok := c.peerMap.endpointForNodeKey(nodeKey) + if !ok { + c.logf("magicsock: disco: ignoring %s from %v; %v is unknown", msgType, sender.ShortString(), derpNodeSrc.ShortString()) + return + } + epDisco := ep.disco.Load() + if epDisco == nil { + return + } + if epDisco.key != di.discoKey { + if isResp { + metricRecvDiscoAllocUDPRelayEndpointResponseBadDisco.Add(1) + } else { + metricRecvDiscoAllocUDPRelayEndpointRequestBadDisco.Add(1) + } + c.logf("[unexpected] %s from peer via DERP whose netmap discokey != disco source", msgType) + return + } + + if isResp { + c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got %s, %d endpoints", + c.discoAtomic.Short(), epDisco.short, + ep.publicKey.ShortString(), derpStr(src.String()), + msgType, + len(resp.AddrPorts)) + c.relayManager.handleRxDiscoMsg(c, resp, nodeKey, di.discoKey, src) + return + } else if sender.Compare(req.ClientDisco[0]) != 0 && sender.Compare(req.ClientDisco[1]) != 0 { + // An allocation request must contain the sender's disco key in + // ClientDisco. One of the relay participants must be the sender. + c.logf("magicsock: disco: %s from %v; %v does not contain sender's disco key", + msgType, sender.ShortString(), derpNodeSrc.ShortString()) + return + } else { + c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got %s disco[0]=%v disco[1]=%v", + c.discoAtomic.Short(), epDisco.short, + ep.publicKey.ShortString(), derpStr(src.String()), + msgType, + req.ClientDisco[0].ShortString(), req.ClientDisco[1].ShortString()) + } + + if c.filt == nil { + return + } + // Binary search of peers is O(log n) while c.mu is held. + // TODO: We might be able to use ep.nodeAddr instead of all addresses, + // or we might be able to release c.mu before doing this work. Keep it + // simple and slow for now. c.peers.AsSlice is a copy. We may need to + // write our own binary search for a [views.Slice]. + peerI, ok := slices.BinarySearchFunc(c.peers.AsSlice(), ep.nodeID, func(peer tailcfg.NodeView, target tailcfg.NodeID) int { + if peer.ID() < target { + return -1 + } else if peer.ID() > target { + return 1 + } + return 0 + }) + if !ok { + // unexpected + return + } + if !nodeHasCap(c.filt, c.peers.At(peerI), c.self, tailcfg.PeerCapabilityRelay) { + return + } + // [Conn.mu] must not be held while publishing, or [Conn.onUDPRelayAllocResp] + // can deadlock as the req sub and resp pub are the same goroutine. + // See #17830. + go c.allocRelayEndpointPub.Publish(UDPRelayAllocReq{ + RxFromDiscoKey: sender, + RxFromNodeKey: nodeKey, + Message: req, + }) } return } @@ -1827,25 +2524,45 @@ func (c *Conn) unambiguousNodeKeyOfPingLocked(dm *disco.Ping, dk key.DiscoPublic // di is the discoInfo of the source of the ping. // derpNodeSrc is non-zero if the ping arrived via DERP. -func (c *Conn) handlePingLocked(dm *disco.Ping, src netip.AddrPort, di *discoInfo, derpNodeSrc key.NodePublic) { +func (c *Conn) handlePingLocked(dm *disco.Ping, src epAddr, di *discoInfo, derpNodeSrc key.NodePublic) { likelyHeartBeat := src == di.lastPingFrom && time.Since(di.lastPingTime) < 5*time.Second di.lastPingFrom = src di.lastPingTime = time.Now() - isDerp := src.Addr() == tailcfg.DerpMagicIPAddr + isDerp := src.ap.Addr() == tailcfg.DerpMagicIPAddr + + if src.vni.IsSet() { + if isDerp { + c.logf("[unexpected] got Geneve-encapsulated disco ping from %v/%v over DERP", src, derpNodeSrc) + return + } + + // [relayManager] is always responsible for handling (replying) to + // Geneve-encapsulated [disco.Ping] messages in the interest of + // simplicity. It might be in the middle of probing src, so it must be + // made aware. + c.relayManager.handleRxDiscoMsg(c, dm, key.NodePublic{}, di.discoKey, src) + return + } + + // This is a naked [disco.Ping] without a VNI. // If we can figure out with certainty which node key this disco - // message is for, eagerly update our IP<>node and disco<>node + // message is for, eagerly update our [epAddr]<>node and disco<>node // mappings to make p2p path discovery faster in simple // cases. Without this, disco would still work, but would be // reliant on DERP call-me-maybe to establish the disco<>node // mapping, and on subsequent disco handlePongConnLocked to establish - // the IP<>disco mapping. + // the IP:port<>disco mapping. if nk, ok := c.unambiguousNodeKeyOfPingLocked(dm, di.discoKey, derpNodeSrc); ok { if !isDerp { - c.peerMap.setNodeKeyForIPPort(src, nk) + c.peerMap.setNodeKeyForEpAddr(src, nk) } } + // numNodes tracks how many nodes (node keys) are associated with the disco + // key tied to this inbound ping. Multiple nodes may share the same disco + // key in the case of node sharing and users switching accounts. + var numNodes int // If we got a ping over DERP, then derpNodeSrc is non-zero and we reply // over DERP (in which case ipDst is also a DERP address). // But if the ping was over UDP (ipDst is not a DERP address), then dstKey @@ -1854,18 +2571,14 @@ func (c *Conn) handlePingLocked(dm *disco.Ping, src netip.AddrPort, di *discoInf dstKey := derpNodeSrc // Remember this route if not present. - var numNodes int var dup bool if isDerp { - if ep, ok := c.peerMap.endpointForNodeKey(derpNodeSrc); ok { - if ep.addCandidateEndpoint(src, dm.TxID) { - return - } + if _, ok := c.peerMap.endpointForNodeKey(derpNodeSrc); ok { numNodes = 1 } } else { c.peerMap.forEachEndpointWithDiscoKey(di.discoKey, func(ep *endpoint) (keepGoing bool) { - if ep.addCandidateEndpoint(src, dm.TxID) { + if ep.addCandidateEndpoint(src.ap, dm.TxID) { dup = true return false } @@ -1895,14 +2608,14 @@ func (c *Conn) handlePingLocked(dm *disco.Ping, src netip.AddrPort, di *discoInf if numNodes > 1 { pingNodeSrcStr = "[one-of-multi]" } - c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got ping tx=%x padding=%v", c.discoShort, di.discoShort, pingNodeSrcStr, src, dm.TxID[:6], dm.Padding) + c.dlogf("[v1] magicsock: disco: %v<-%v (%v, %v) got ping tx=%x padding=%v", c.discoAtomic.Short(), di.discoShort, pingNodeSrcStr, src, dm.TxID[:6], dm.Padding) } ipDst := src discoDest := di.discoKey go c.sendDiscoMessage(ipDst, dstKey, discoDest, &disco.Pong{ TxID: dm.TxID, - Src: src, + Src: src.ap, }, discoVerboseLog) } @@ -1945,25 +2658,30 @@ func (c *Conn) enqueueCallMeMaybe(derpAddr netip.AddrPort, de *endpoint) { for _, ep := range c.lastEndpoints { eps = append(eps, ep.Addr) } - go de.c.sendDiscoMessage(derpAddr, de.publicKey, epDisco.key, &disco.CallMeMaybe{MyNumber: eps}, discoLog) + go de.c.sendDiscoMessage(epAddr{ap: derpAddr}, de.publicKey, epDisco.key, &disco.CallMeMaybe{MyNumber: eps}, discoLog) if debugSendCallMeUnknownPeer() { // Send a callMeMaybe packet to a non-existent peer unknownKey := key.NewNode().Public() c.logf("magicsock: sending CallMeMaybe to unknown peer per TS_DEBUG_SEND_CALLME_UNKNOWN_PEER") - go de.c.sendDiscoMessage(derpAddr, unknownKey, epDisco.key, &disco.CallMeMaybe{MyNumber: eps}, discoLog) + go de.c.sendDiscoMessage(epAddr{ap: derpAddr}, unknownKey, epDisco.key, &disco.CallMeMaybe{MyNumber: eps}, discoLog) } } -// discoInfoLocked returns the previous or new discoInfo for k. +// discoInfoForKnownPeerLocked returns the previous or new discoInfo for k. +// +// Callers must only pass key.DiscoPublic's that are present in and +// lifetime-managed via [Conn].peerMap. UDP relay server disco keys are discovered +// at relay endpoint allocation time or [disco.CallMeMaybeVia] reception time +// and therefore must never pass through this method. // // c.mu must be held. -func (c *Conn) discoInfoLocked(k key.DiscoPublic) *discoInfo { +func (c *Conn) discoInfoForKnownPeerLocked(k key.DiscoPublic) *discoInfo { di, ok := c.discoInfo[k] if !ok { di = &discoInfo{ discoKey: k, discoShort: k.ShortString(), - sharedKey: c.discoPrivate.Shared(k), + sharedKey: c.discoAtomic.Private().Shared(k), } c.discoInfo[k] = di } @@ -1983,7 +2701,9 @@ func (c *Conn) SetNetworkUp(up bool) { if up { c.startDerpHomeConnectLocked() } else { - c.portMapper.NoteNetworkDown() + if c.portMapper != nil { + c.portMapper.NoteNetworkDown() + } c.closeAllDerpLocked("network-down") } } @@ -2166,34 +2886,184 @@ func (c *Conn) SetProbeUDPLifetime(v bool) { }) } -// SetNetworkMap is called when the control client gets a new network -// map from the control server. It must always be non-nil. +// capVerIsRelayCapable returns true if version is relay client and server +// capable, otherwise it returns false. +func capVerIsRelayCapable(version tailcfg.CapabilityVersion) bool { + return version >= 121 +} + +// onFilterUpdate is called when a [FilterUpdate] is received over the +// [eventbus.Bus]. +func (c *Conn) onFilterUpdate(f FilterUpdate) { + c.mu.Lock() + c.filt = f.Filter + self := c.self + peers := c.peers + relayClientEnabled := c.relayClientEnabled + c.mu.Unlock() // release c.mu before potentially calling c.updateRelayServersSet which is O(m * n) + + if !relayClientEnabled { + // Early return if we cannot operate as a relay client. + return + } + + // The filter has changed, and we are operating as a relay server client. + // Re-evaluate it in order to produce an updated relay server set. + c.updateRelayServersSet(f.Filter, self, peers) +} + +// updateRelayServersSet iterates all peers and self, evaluating filt for each +// one in order to determine which are relay server candidates. filt, self, and +// peers are passed as args (vs c.mu-guarded fields) to enable callers to +// release c.mu before calling as this is O(m * n) (we iterate all cap rules 'm' +// in filt for every peer 'n'). // -// It should not use the DERPMap field of NetworkMap; that's -// conditionally sent to SetDERPMap instead. -func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { +// Calls to updateRelayServersSet must never run concurrent to +// [endpoint.setDERPHome], otherwise [candidatePeerRelay] DERP home changes may +// be missed from the perspective of [relayManager]. +// +// TODO: Optimize this so that it's not O(m * n). This might involve: +// 1. Changes to [filter.Filter], e.g. adding a CapsWithValues() to check for +// a given capability instead of building and returning a map of all of +// them. +// 2. Moving this work upstream into [nodeBackend] or similar, and publishing +// the computed result over the eventbus instead. +func (c *Conn) updateRelayServersSet(filt *filter.Filter, self tailcfg.NodeView, peers views.Slice[tailcfg.NodeView]) { + relayServers := make(set.Set[candidatePeerRelay]) + nodes := append(peers.AsSlice(), self) + for _, maybeCandidate := range nodes { + if maybeCandidate.ID() != self.ID() && !capVerIsRelayCapable(maybeCandidate.Cap()) { + // If maybeCandidate's [tailcfg.CapabilityVersion] is not relay-capable, + // we skip it. If maybeCandidate happens to be self, then this check is + // unnecessary as self is always capable from this point (the statically + // compiled [tailcfg.CurrentCapabilityVersion]) forward. + continue + } + if !nodeHasCap(filt, maybeCandidate, self, tailcfg.PeerCapabilityRelayTarget) { + continue + } + relayServers.Add(candidatePeerRelay{ + nodeKey: maybeCandidate.Key(), + discoKey: maybeCandidate.DiscoKey(), + derpHomeRegionID: uint16(maybeCandidate.HomeDERP()), + }) + } + c.relayManager.handleRelayServersSet(relayServers) + if len(relayServers) > 0 { + c.hasPeerRelayServers.Store(true) + } else { + c.hasPeerRelayServers.Store(false) + } +} + +// nodeHasCap returns true if src has cap on dst, otherwise it returns false. +func nodeHasCap(filt *filter.Filter, src, dst tailcfg.NodeView, cap tailcfg.PeerCapability) bool { + if filt == nil || + !src.Valid() || + !dst.Valid() { + return false + } + for _, srcPrefix := range src.Addresses().All() { + if !srcPrefix.IsSingleIP() { + continue + } + srcAddr := srcPrefix.Addr() + for _, dstPrefix := range dst.Addresses().All() { + if !dstPrefix.IsSingleIP() { + continue + } + dstAddr := dstPrefix.Addr() + if dstAddr.BitLen() == srcAddr.BitLen() { // same address family + // [nodeBackend.peerCapsLocked] only returns/considers the + // [tailcfg.PeerCapMap] between the passed src and the _first_ + // host (/32 or /128) address for self. We are consistent with + // that behavior here. If src and dst host addresses are of the + // same address family they either have the capability or not. + // We do not check against additional host addresses of the same + // address family. + return filt.CapsWithValues(srcAddr, dstAddr).HasCapability(cap) + } + } + } + return false +} + +// candidatePeerRelay represents the identifiers and DERP home region ID for a +// peer relay server. +type candidatePeerRelay struct { + nodeKey key.NodePublic + discoKey key.DiscoPublic + derpHomeRegionID uint16 +} + +func (c *candidatePeerRelay) isValid() bool { + return !c.nodeKey.IsZero() && !c.discoKey.IsZero() +} + +// onNodeViewsUpdate is called when a [NodeViewsUpdate] is received over the +// [eventbus.Bus]. +func (c *Conn) onNodeViewsUpdate(update NodeViewsUpdate) { + peersChanged := c.updateNodes(update) + + relayClientEnabled := update.SelfNode.Valid() && + !update.SelfNode.HasCap(tailcfg.NodeAttrDisableRelayClient) && + !update.SelfNode.HasCap(tailcfg.NodeAttrOnlyTCP443) + + c.mu.Lock() + relayClientChanged := c.relayClientEnabled != relayClientEnabled + c.relayClientEnabled = relayClientEnabled + filt := c.filt + self := c.self + peers := c.peers + isClosed := c.closed + c.mu.Unlock() // release c.mu before potentially calling c.updateRelayServersSet which is O(m * n) + + if isClosed { + return // nothing to do here, the conn is closed and the update is no longer relevant + } + + if peersChanged || relayClientChanged { + if !relayClientEnabled { + c.relayManager.handleRelayServersSet(nil) + c.hasPeerRelayServers.Store(false) + } else { + c.updateRelayServersSet(filt, self, peers) + } + } +} + +// updateNodes updates [Conn] to reflect the [tailcfg.NodeView]'s contained +// in update. It returns true if update.Peers was unequal to c.peers, otherwise +// false. +func (c *Conn) updateNodes(update NodeViewsUpdate) (peersChanged bool) { c.mu.Lock() defer c.mu.Unlock() if c.closed { - return + return false } priorPeers := c.peers - metricNumPeers.Set(int64(len(nm.Peers))) + metricNumPeers.Set(int64(len(update.Peers))) - // Update c.netMap regardless, before the following early return. - curPeers := views.SliceOf(nm.Peers) + // Update c.self & c.peers regardless, before the following early return. + c.self = update.SelfNode + curPeers := views.SliceOf(update.Peers) c.peers = curPeers + // [debugFlags] are mutable in [Conn.SetSilentDisco] & + // [Conn.SetProbeUDPLifetime]. These setters are passed [controlknobs.Knobs] + // values by [ipnlocal.LocalBackend] around netmap reception. + // [controlknobs.Knobs] are simply self [tailcfg.NodeCapability]'s. They are + // useful as a global view of notable feature toggles, but the magicsock + // setters are completely unnecessary as we have the same values right here + // (update.SelfNode.Capabilities) at a time they are considered most + // up-to-date. + // TODO: mutate [debugFlags] here instead of in various [Conn] setters. flags := c.debugFlagsLocked() - if addrs := nm.GetAddresses(); addrs.Len() > 0 { - c.firstAddrForTest = addrs.At(0).Addr() - } else { - c.firstAddrForTest = netip.Addr{} - } - if nodesEqual(priorPeers, curPeers) && c.lastFlags == flags { + peersChanged = !nodesEqual(priorPeers, curPeers) + if !peersChanged && c.lastFlags == flags { // The rest of this function is all adjusting state for peers that have // changed. But if the set of peers is equal and the debug flags (for // silent disco and probe UDP lifetime) haven't changed, there is no @@ -2203,16 +3073,16 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { c.lastFlags = flags - c.logf("[v1] magicsock: got updated network map; %d peers", len(nm.Peers)) + c.logf("[v1] magicsock: got updated network map; %d peers", len(update.Peers)) - entriesPerBuffer := debugRingBufferSize(len(nm.Peers)) + entriesPerBuffer := debugRingBufferSize(len(update.Peers)) // Try a pass of just upserting nodes and creating missing // endpoints. If the set of nodes is the same, this is an // efficient alloc-free update. If the set of nodes is different, // we'll fall through to the next pass, which allocates but can // handle full set updates. - for _, n := range nm.Peers { + for _, n := range update.Peers { if n.ID() == 0 { devPanicf("node with zero ID") continue @@ -2289,7 +3159,7 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { // ~1MB on mobile but we never used the data so the memory was just // wasted. default: - ep.debugUpdates = ringbuffer.New[EndpointChange](entriesPerBuffer) + ep.debugUpdates = ringlog.New[EndpointChange](entriesPerBuffer) } if n.Addresses().Len() > 0 { ep.nodeAddr = n.Addresses().At(0).Addr() @@ -2312,14 +3182,14 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { c.peerMap.upsertEndpoint(ep, key.DiscoPublic{}) } - // If the set of nodes changed since the last SetNetworkMap, the + // If the set of nodes changed since the last onNodeViewsUpdate, the // upsert loop just above made c.peerMap contain the union of the // old and new peers - which will be larger than the set from the // current netmap. If that happens, go through the allocful // deletion path to clean up moribund nodes. - if c.peerMap.nodeCount() != len(nm.Peers) { + if c.peerMap.nodeCount() != len(update.Peers) { keep := set.Set[key.NodePublic]{} - for _, n := range nm.Peers { + for _, n := range update.Peers { keep.Add(n.Key()) } c.peerMap.forEachEndpoint(func(ep *endpoint) { @@ -2335,6 +3205,8 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) { delete(c.discoInfo, dk) } } + + return peersChanged } func devPanicf(format string, a ...any) { @@ -2479,6 +3351,13 @@ func (c *connBind) isClosed() bool { // // Only the first close does anything. Any later closes return nil. func (c *Conn) Close() error { + // Close the [eventbus.Client] to wait for subscribers to + // return before acquiring c.mu: + // 1. Event handlers also acquire c.mu, they can deadlock with c.Close(). + // 2. Event handlers may not guard against undesirable post/in-progress + // Conn.Close() behaviors. + c.eventClient.Close() + c.mu.Lock() defer c.mu.Unlock() if c.closed { @@ -2489,8 +3368,9 @@ func (c *Conn) Close() error { c.derpCleanupTimer.Stop() } c.stopPeriodicReSTUNTimerLocked() - c.portMapper.Close() - c.portMapperLogfUnregister() + if c.portMapper != nil { + c.portMapper.Close() + } c.peerMap.forEachEndpoint(func(ep *endpoint) { ep.stopAndReset() @@ -2509,7 +3389,6 @@ func (c *Conn) Close() error { if c.closeDisco6 != nil { c.closeDisco6.Close() } - // Wait on goroutines updating right at the end, once everything is // already closed. We want everything else in the Conn to be // consistently in the closed state before we release mu to wait @@ -2522,7 +3401,7 @@ func (c *Conn) Close() error { pinger.Close() } - deregisterMetrics(c.metrics) + deregisterMetrics() return nil } @@ -2574,7 +3453,7 @@ func (c *Conn) shouldDoPeriodicReSTUNLocked() bool { return true } -func (c *Conn) onPortMapChanged() { c.ReSTUN("portmap-changed") } +func (c *Conn) onPortMapChanged(portmappertype.Mapping) { c.ReSTUN("portmap-changed") } // ReSTUN triggers an address discovery. // The provided why string is for debug logging only. @@ -2631,9 +3510,9 @@ func (c *Conn) listenPacket(network string, port uint16) (nettype.PacketConn, er return nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf, c.netMon)).ListenPacket(ctx, network, addr) } -// bindSocket initializes rucPtr if necessary and binds a UDP socket to it. +// bindSocket binds a UDP socket to ruc. // Network indicates the UDP socket type; it must be "udp4" or "udp6". -// If rucPtr had an existing UDP socket bound, it closes that socket. +// If ruc had an existing UDP socket bound, it closes that socket. // The caller is responsible for informing the portMapper of any changes. // If curPortFate is set to dropCurrentPort, no attempt is made to reuse // the current port. @@ -2691,7 +3570,7 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur c.logf("magicsock: unable to bind %v port %d: %v", network, port, err) continue } - if c.onPortUpdate != nil { + if c.portUpdatePub.ShouldPublish() { _, gotPortStr, err := net.SplitHostPort(pconn.LocalAddr().String()) if err != nil { c.logf("could not parse port from %s: %w", pconn.LocalAddr().String(), err) @@ -2700,11 +3579,13 @@ func (c *Conn) bindSocket(ruc *RebindingUDPConn, network string, curPortFate cur if err != nil { c.logf("could not parse port from %s: %w", gotPort, err) } else { - c.onPortUpdate(uint16(gotPort), network) + c.portUpdatePub.Publish(router.PortUpdate{ + UDPPort: uint16(gotPort), + EndpointNetwork: network, + }) } } } - trySetSocketBuffer(pconn, c.logf) trySetUDPSocketOptions(pconn, c.logf) // Success. @@ -2745,7 +3626,9 @@ func (c *Conn) rebind(curPortFate currentPortFate) error { if err := c.bindSocket(&c.pconn4, "udp4", curPortFate); err != nil { return fmt.Errorf("magicsock: Rebind IPv4 failed: %w", err) } - c.portMapper.SetLocalPort(c.LocalPort()) + if c.portMapper != nil { + c.portMapper.SetLocalPort(c.LocalPort()) + } c.UpdatePMTUD() return nil } @@ -2767,7 +3650,9 @@ func (c *Conn) Rebind() { c.logf("Rebind; defIf=%q, ips=%v", defIf, ifIPs) } - c.maybeCloseDERPsOnRebind(ifIPs) + if len(ifIPs) > 0 { + c.maybeCloseDERPsOnRebind(ifIPs) + } c.resetEndpointStates() } @@ -2839,12 +3724,13 @@ func simpleDur(d time.Duration) time.Duration { return d.Round(time.Minute) } -// UpdateNetmapDelta implements controlclient.NetmapDeltaUpdater. -func (c *Conn) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) { +// onNodeMutationsUpdate is called when a [NodeMutationsUpdate] is received over +// the [eventbus.Bus]. Note: It does not apply these mutations to c.peers. +func (c *Conn) onNodeMutationsUpdate(update NodeMutationsUpdate) { c.mu.Lock() defer c.mu.Unlock() - for _, m := range muts { + for _, m := range update.Mutations { nodeID := m.NodeIDBeingMutated() ep, ok := c.peerMap.endpointForNodeID(nodeID) if !ok { @@ -2859,10 +3745,9 @@ func (c *Conn) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) { ep.mu.Unlock() } } - return true } -// UpdateStatus implements the interface nede by ipnstate.StatusBuilder. +// UpdateStatus implements the interface needed by ipnstate.StatusBuilder. // // This method adds in the magicsock-specific information only. Most // of the status is otherwise populated by LocalBackend. @@ -2897,10 +3782,12 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) { }) } -// SetStatistics specifies a per-connection statistics aggregator. +// SetConnectionCounter specifies a per-connection statistics aggregator. // Nil may be specified to disable statistics gathering. -func (c *Conn) SetStatistics(stats *connstats.Statistics) { - c.stats.Store(stats) +func (c *Conn) SetConnectionCounter(fn netlogfunc.ConnectionCounter) { + if buildfeatures.HasNetLog { + c.connCounter.Store(fn) + } } // SetHomeless sets whether magicsock should idle harder and not have a DERP @@ -2928,9 +3815,17 @@ const ( // keep NAT mappings alive. sessionActiveTimeout = 45 * time.Second - // upgradeInterval is how often we try to upgrade to a better path - // even if we have some non-DERP route that works. - upgradeInterval = 1 * time.Minute + // upgradeUDPDirectInterval is how often we try to upgrade to a better, + // direct UDP path even if we have some direct UDP path that works. + upgradeUDPDirectInterval = 1 * time.Minute + + // upgradeUDPRelayInterval is how often we try to discover UDP relay paths + // even if we have a UDP relay path that works. + upgradeUDPRelayInterval = 1 * time.Minute + + // discoverUDPRelayPathsInterval is the minimum time between UDP relay path + // discovery. + discoverUDPRelayPathsInterval = 30 * time.Second // heartbeatInterval is how often pings to the best UDP address // are sent. @@ -3015,40 +3910,48 @@ func (c *Conn) DebugForcePreferDERP(n int) { c.netChecker.SetForcePreferredDERP(n) } -// portableTrySetSocketBuffer sets SO_SNDBUF and SO_RECVBUF on pconn to socketBufferSize, -// logging an error if it occurs. -func portableTrySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) { - if c, ok := pconn.(*net.UDPConn); ok { - // Attempt to increase the buffer size, and allow failures. - if err := c.SetReadBuffer(socketBufferSize); err != nil { - logf("magicsock: failed to set UDP read buffer size to %d: %v", socketBufferSize, err) +func trySetUDPSocketOptions(pconn nettype.PacketConn, logf logger.Logf) { + directions := []sockopts.BufferDirection{sockopts.ReadDirection, sockopts.WriteDirection} + for _, direction := range directions { + forceErr, portableErr := sockopts.SetBufferSize(pconn, direction, socketBufferSize) + if forceErr != nil { + logf("magicsock: [warning] failed to force-set UDP %v buffer size to %d: %v; using kernel default values (impacts throughput only)", direction, socketBufferSize, forceErr) } - if err := c.SetWriteBuffer(socketBufferSize); err != nil { - logf("magicsock: failed to set UDP write buffer size to %d: %v", socketBufferSize, err) + if portableErr != nil { + logf("magicsock: failed to set UDP %v buffer size to %d: %v", direction, socketBufferSize, portableErr) } } + + err := sockopts.SetICMPErrImmunity(pconn) + if err != nil { + logf("magicsock: %v", err) + } } // derpStr replaces DERP IPs in s with "derp-". func derpStr(s string) string { return strings.ReplaceAll(s, "127.3.3.40:", "derp-") } -// ippEndpointCache is a mutex-free single-element cache, mapping from -// a single netip.AddrPort to a single endpoint. -type ippEndpointCache struct { - ipp netip.AddrPort - gen int64 - de *endpoint +// epAddrEndpointCache is a mutex-free single-element cache, mapping from +// a single [epAddr] to a single [*endpoint]. +type epAddrEndpointCache struct { + epAddr epAddr + gen int64 + de *endpoint } // discoInfo is the info and state for the DiscoKey -// in the Conn.discoInfo map key. +// in the [Conn.discoInfo] and [relayManager.discoInfoByServerDisco] map keys. +// +// When the disco protocol is used to handshake with a peer relay server, the +// corresponding discoInfo is held in [relayManager.discoInfoByServerDisco] +// instead of [Conn.discoInfo]. // // Note that a DiscoKey does not necessarily map to exactly one // node. In the case of shared nodes and users switching accounts, two // nodes in the NetMap may legitimately have the same DiscoKey. As // such, no fields in here should be considered node-specific. type discoInfo struct { - // discoKey is the same as the Conn.discoInfo map key, + // discoKey is the same as the corresponding map key, // just so you can pass around a *discoInfo alone. // Not modified once initialized. discoKey key.DiscoPublic @@ -3059,14 +3962,16 @@ type discoInfo struct { // sharedKey is the precomputed key for communication with the // peer that has the DiscoKey used to look up this *discoInfo in - // Conn.discoInfo. + // the corresponding map. // Not modified once initialized. sharedKey key.DiscoShared - // Mutable fields follow, owned by Conn.mu: + // Mutable fields follow, owned by [Conn.mu]. These are irrelevant when + // discoInfo is a peer relay server disco key in the + // [relayManager.discoInfoByServerDisco] map: // lastPingFrom is the src of a ping for discoKey. - lastPingFrom netip.AddrPort + lastPingFrom epAddr // lastPingTime is the last time of a ping for discoKey. lastPingTime time.Time @@ -3085,41 +3990,85 @@ var ( metricSendDERPErrorChan = clientmetric.NewCounter("magicsock_send_derp_error_chan") metricSendDERPErrorClosed = clientmetric.NewCounter("magicsock_send_derp_error_closed") metricSendDERPErrorQueue = clientmetric.NewCounter("magicsock_send_derp_error_queue") - metricSendUDP = clientmetric.NewAggregateCounter("magicsock_send_udp") + metricSendDERPDropped = clientmetric.NewCounter("magicsock_send_derp_dropped") metricSendUDPError = clientmetric.NewCounter("magicsock_send_udp_error") - metricSendDERP = clientmetric.NewAggregateCounter("magicsock_send_derp") + metricSendPeerRelayError = clientmetric.NewCounter("magicsock_send_peer_relay_error") metricSendDERPError = clientmetric.NewCounter("magicsock_send_derp_error") + // Sends (data) + // + // Note: Prior to v1.78 metricSendUDP & metricSendDERP counted sends of data + // AND disco packets. They were updated in v1.78 to only count data packets. + // metricSendPeerRelay was added in v1.86 and has always counted only data + // packets. + metricSendUDP = clientmetric.NewAggregateCounter("magicsock_send_udp") + metricSendPeerRelay = clientmetric.NewAggregateCounter("magicsock_send_peer_relay") + metricSendDERP = clientmetric.NewAggregateCounter("magicsock_send_derp") + // Data packets (non-disco) - metricSendData = clientmetric.NewCounter("magicsock_send_data") - metricSendDataNetworkDown = clientmetric.NewCounter("magicsock_send_data_network_down") - metricRecvDataPacketsDERP = clientmetric.NewAggregateCounter("magicsock_recv_data_derp") - metricRecvDataPacketsIPv4 = clientmetric.NewAggregateCounter("magicsock_recv_data_ipv4") - metricRecvDataPacketsIPv6 = clientmetric.NewAggregateCounter("magicsock_recv_data_ipv6") + metricSendData = clientmetric.NewCounter("magicsock_send_data") + metricSendDataNetworkDown = clientmetric.NewCounter("magicsock_send_data_network_down") + metricRecvDataPacketsDERP = clientmetric.NewAggregateCounter("magicsock_recv_data_derp") + metricRecvDataPacketsIPv4 = clientmetric.NewAggregateCounter("magicsock_recv_data_ipv4") + metricRecvDataPacketsIPv6 = clientmetric.NewAggregateCounter("magicsock_recv_data_ipv6") + metricRecvDataPacketsPeerRelayIPv4 = clientmetric.NewAggregateCounter("magicsock_recv_data_peer_relay_ipv4") + metricRecvDataPacketsPeerRelayIPv6 = clientmetric.NewAggregateCounter("magicsock_recv_data_peer_relay_ipv6") + metricSendDataPacketsDERP = clientmetric.NewAggregateCounter("magicsock_send_data_derp") + metricSendDataPacketsIPv4 = clientmetric.NewAggregateCounter("magicsock_send_data_ipv4") + metricSendDataPacketsIPv6 = clientmetric.NewAggregateCounter("magicsock_send_data_ipv6") + metricSendDataPacketsPeerRelayIPv4 = clientmetric.NewAggregateCounter("magicsock_send_data_peer_relay_ipv4") + metricSendDataPacketsPeerRelayIPv6 = clientmetric.NewAggregateCounter("magicsock_send_data_peer_relay_ipv6") + + // Data bytes (non-disco) + metricRecvDataBytesDERP = clientmetric.NewAggregateCounter("magicsock_recv_data_bytes_derp") + metricRecvDataBytesIPv4 = clientmetric.NewAggregateCounter("magicsock_recv_data_bytes_ipv4") + metricRecvDataBytesIPv6 = clientmetric.NewAggregateCounter("magicsock_recv_data_bytes_ipv6") + metricRecvDataBytesPeerRelayIPv4 = clientmetric.NewAggregateCounter("magicsock_recv_data_bytes_peer_relay_ipv4") + metricRecvDataBytesPeerRelayIPv6 = clientmetric.NewAggregateCounter("magicsock_recv_data_bytes_peer_relay_ipv6") + metricSendDataBytesDERP = clientmetric.NewAggregateCounter("magicsock_send_data_bytes_derp") + metricSendDataBytesIPv4 = clientmetric.NewAggregateCounter("magicsock_send_data_bytes_ipv4") + metricSendDataBytesIPv6 = clientmetric.NewAggregateCounter("magicsock_send_data_bytes_ipv6") + metricSendDataBytesPeerRelayIPv4 = clientmetric.NewAggregateCounter("magicsock_send_data_bytes_peer_relay_ipv4") + metricSendDataBytesPeerRelayIPv6 = clientmetric.NewAggregateCounter("magicsock_send_data_bytes_peer_relay_ipv6") // Disco packets - metricSendDiscoUDP = clientmetric.NewCounter("magicsock_disco_send_udp") - metricSendDiscoDERP = clientmetric.NewCounter("magicsock_disco_send_derp") - metricSentDiscoUDP = clientmetric.NewCounter("magicsock_disco_sent_udp") - metricSentDiscoDERP = clientmetric.NewCounter("magicsock_disco_sent_derp") - metricSentDiscoPing = clientmetric.NewCounter("magicsock_disco_sent_ping") - metricSentDiscoPong = clientmetric.NewCounter("magicsock_disco_sent_pong") - metricSentDiscoPeerMTUProbes = clientmetric.NewCounter("magicsock_disco_sent_peer_mtu_probes") - metricSentDiscoPeerMTUProbeBytes = clientmetric.NewCounter("magicsock_disco_sent_peer_mtu_probe_bytes") - metricSentDiscoCallMeMaybe = clientmetric.NewCounter("magicsock_disco_sent_callmemaybe") - metricRecvDiscoBadPeer = clientmetric.NewCounter("magicsock_disco_recv_bad_peer") - metricRecvDiscoBadKey = clientmetric.NewCounter("magicsock_disco_recv_bad_key") - metricRecvDiscoBadParse = clientmetric.NewCounter("magicsock_disco_recv_bad_parse") + metricSendDiscoUDP = clientmetric.NewCounter("magicsock_disco_send_udp") + metricSendDiscoDERP = clientmetric.NewCounter("magicsock_disco_send_derp") + metricSentDiscoUDP = clientmetric.NewCounter("magicsock_disco_sent_udp") + metricSentDiscoDERP = clientmetric.NewCounter("magicsock_disco_sent_derp") + metricSentDiscoPing = clientmetric.NewCounter("magicsock_disco_sent_ping") + metricSentDiscoPong = clientmetric.NewCounter("magicsock_disco_sent_pong") + metricSentDiscoPeerMTUProbes = clientmetric.NewCounter("magicsock_disco_sent_peer_mtu_probes") + metricSentDiscoPeerMTUProbeBytes = clientmetric.NewCounter("magicsock_disco_sent_peer_mtu_probe_bytes") + metricSentDiscoCallMeMaybe = clientmetric.NewCounter("magicsock_disco_sent_callmemaybe") + metricSentDiscoCallMeMaybeVia = clientmetric.NewCounter("magicsock_disco_sent_callmemaybevia") + metricSentDiscoBindUDPRelayEndpoint = clientmetric.NewCounter("magicsock_disco_sent_bind_udp_relay_endpoint") + metricSentDiscoBindUDPRelayEndpointAnswer = clientmetric.NewCounter("magicsock_disco_sent_bind_udp_relay_endpoint_answer") + metricSentDiscoAllocUDPRelayEndpointRequest = clientmetric.NewCounter("magicsock_disco_sent_alloc_udp_relay_endpoint_request") + metricLocalDiscoAllocUDPRelayEndpointRequest = clientmetric.NewCounter("magicsock_disco_local_alloc_udp_relay_endpoint_request") + metricSentDiscoAllocUDPRelayEndpointResponse = clientmetric.NewCounter("magicsock_disco_sent_alloc_udp_relay_endpoint_response") + metricRecvDiscoBadPeer = clientmetric.NewCounter("magicsock_disco_recv_bad_peer") + metricRecvDiscoBadKey = clientmetric.NewCounter("magicsock_disco_recv_bad_key") + metricRecvDiscoBadParse = clientmetric.NewCounter("magicsock_disco_recv_bad_parse") - metricRecvDiscoUDP = clientmetric.NewCounter("magicsock_disco_recv_udp") - metricRecvDiscoDERP = clientmetric.NewCounter("magicsock_disco_recv_derp") - metricRecvDiscoPing = clientmetric.NewCounter("magicsock_disco_recv_ping") - metricRecvDiscoPong = clientmetric.NewCounter("magicsock_disco_recv_pong") - metricRecvDiscoCallMeMaybe = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe") - metricRecvDiscoCallMeMaybeBadNode = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe_bad_node") - metricRecvDiscoCallMeMaybeBadDisco = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe_bad_disco") - metricRecvDiscoDERPPeerNotHere = clientmetric.NewCounter("magicsock_disco_recv_derp_peer_not_here") - metricRecvDiscoDERPPeerGoneUnknown = clientmetric.NewCounter("magicsock_disco_recv_derp_peer_gone_unknown") + metricRecvDiscoUDP = clientmetric.NewCounter("magicsock_disco_recv_udp") + metricRecvDiscoDERP = clientmetric.NewCounter("magicsock_disco_recv_derp") + metricRecvDiscoPing = clientmetric.NewCounter("magicsock_disco_recv_ping") + metricRecvDiscoPong = clientmetric.NewCounter("magicsock_disco_recv_pong") + metricRecvDiscoCallMeMaybe = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe") + metricRecvDiscoCallMeMaybeVia = clientmetric.NewCounter("magicsock_disco_recv_callmemaybevia") + metricRecvDiscoCallMeMaybeBadNode = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe_bad_node") + metricRecvDiscoCallMeMaybeViaBadNode = clientmetric.NewCounter("magicsock_disco_recv_callmemaybevia_bad_node") + metricRecvDiscoCallMeMaybeBadDisco = clientmetric.NewCounter("magicsock_disco_recv_callmemaybe_bad_disco") + metricRecvDiscoCallMeMaybeViaBadDisco = clientmetric.NewCounter("magicsock_disco_recv_callmemaybevia_bad_disco") + metricRecvDiscoBindUDPRelayEndpointChallenge = clientmetric.NewCounter("magicsock_disco_recv_bind_udp_relay_endpoint_challenge") + metricRecvDiscoAllocUDPRelayEndpointRequest = clientmetric.NewCounter("magicsock_disco_recv_alloc_udp_relay_endpoint_request") + metricRecvDiscoAllocUDPRelayEndpointRequestBadDisco = clientmetric.NewCounter("magicsock_disco_recv_alloc_udp_relay_endpoint_request_bad_disco") + metricRecvDiscoAllocUDPRelayEndpointResponseBadDisco = clientmetric.NewCounter("magicsock_disco_recv_alloc_udp_relay_endpoint_response_bad_disco") + metricRecvDiscoAllocUDPRelayEndpointResponse = clientmetric.NewCounter("magicsock_disco_recv_alloc_udp_relay_endpoint_response") + metricLocalDiscoAllocUDPRelayEndpointResponse = clientmetric.NewCounter("magicsock_disco_local_alloc_udp_relay_endpoint_response") + metricRecvDiscoDERPPeerNotHere = clientmetric.NewCounter("magicsock_disco_recv_derp_peer_not_here") + metricRecvDiscoDERPPeerGoneUnknown = clientmetric.NewCounter("magicsock_disco_recv_derp_peer_gone_unknown") // metricDERPHomeChange is how many times our DERP home region DI has // changed from non-zero to a different non-zero. metricDERPHomeChange = clientmetric.NewCounter("derp_home_change") @@ -3163,6 +4112,11 @@ var ( metricUDPLifetimeCycleCompleteAt10sCliff = newUDPLifetimeCounter("magicsock_udp_lifetime_cycle_complete_at_10s_cliff") metricUDPLifetimeCycleCompleteAt30sCliff = newUDPLifetimeCounter("magicsock_udp_lifetime_cycle_complete_at_30s_cliff") metricUDPLifetimeCycleCompleteAt60sCliff = newUDPLifetimeCounter("magicsock_udp_lifetime_cycle_complete_at_60s_cliff") + + // TSMP disco key exchange + metricTSMPDiscoKeyAdvertisementReceived = clientmetric.NewCounter("magicsock_tsmp_disco_key_advertisement_received") + metricTSMPDiscoKeyAdvertisementApplied = clientmetric.NewCounter("magicsock_tsmp_disco_key_advertisement_applied") + metricTSMPDiscoKeyAdvertisementUnchanged = clientmetric.NewCounter("magicsock_tsmp_disco_key_advertisement_unchanged") ) // newUDPLifetimeCounter returns a new *clientmetric.Metric with the provided @@ -3193,34 +4147,170 @@ func (c *Conn) SetLastNetcheckReportForTest(ctx context.Context, report *netchec c.lastNetCheckReport.Store(report) } -// lazyEndpoint is a wireguard conn.Endpoint for when magicsock received a +// lazyEndpoint is a wireguard [conn.Endpoint] for when magicsock received a // non-disco (presumably WireGuard) packet from a UDP address from which we -// can't map to a Tailscale peer. But Wireguard most likely can, once it -// decrypts it. So we implement the conn.PeerAwareEndpoint interface -// from https://github.com/tailscale/wireguard-go/pull/27 to allow WireGuard -// to tell us who it is later and get the correct conn.Endpoint. +// can't map to a Tailscale peer. But WireGuard most likely can, once it +// decrypts it. So we implement the [conn.InitiationAwareEndpoint] and +// [conn.PeerAwareEndpoint] interfaces, to allow WireGuard to tell us who it is +// later, just-in-time to configure the peer, and set the associated [epAddr] +// in the [peerMap]. Future receives on the associated [epAddr] will then +// resolve directly to an [*endpoint]. +// +// We also sometimes (see [Conn.receiveIP]) return a [*lazyEndpoint] to +// wireguard-go to verify an [epAddr] resolves to the [*endpoint] (maybeEP) we +// believe it to be, to resolve [epAddr] collisions across peers. [epAddr] +// collisions have a higher chance of occurrence for packets received over peer +// relays versus direct connections, as peer relay connections do not upsert +// into [peerMap] around disco packet reception, but direct connections do. type lazyEndpoint struct { - c *Conn - src netip.AddrPort + c *Conn + maybeEP *endpoint // or nil if unknown + src epAddr } +var _ conn.InitiationAwareEndpoint = (*lazyEndpoint)(nil) var _ conn.PeerAwareEndpoint = (*lazyEndpoint)(nil) var _ conn.Endpoint = (*lazyEndpoint)(nil) -func (le *lazyEndpoint) ClearSrc() {} -func (le *lazyEndpoint) SrcIP() netip.Addr { return le.src.Addr() } -func (le *lazyEndpoint) DstIP() netip.Addr { return netip.Addr{} } -func (le *lazyEndpoint) SrcToString() string { return le.src.String() } -func (le *lazyEndpoint) DstToString() string { return "dst" } -func (le *lazyEndpoint) DstToBytes() []byte { return nil } -func (le *lazyEndpoint) GetPeerEndpoint(peerPublicKey [32]byte) conn.Endpoint { +// InitiationMessagePublicKey implements [conn.InitiationAwareEndpoint]. +// wireguard-go calls us here if we passed it a [*lazyEndpoint] for an +// initiation message, for which it might not have the relevant peer configured, +// enabling us to just-in-time configure it and note its activity via +// [*endpoint.noteRecvActivity], before it performs peer lookup and attempts +// decryption. +// +// Reception of all other WireGuard message types implies pre-existing knowledge +// of the peer by wireguard-go for it to do useful work. See +// [userspaceEngine.maybeReconfigWireguardLocked] & +// [userspaceEngine.noteRecvActivity] for more details around just-in-time +// wireguard-go peer (de)configuration. +func (le *lazyEndpoint) InitiationMessagePublicKey(peerPublicKey [32]byte) { pubKey := key.NodePublicFromRaw32(mem.B(peerPublicKey[:])) + if le.maybeEP != nil && pubKey.Compare(le.maybeEP.publicKey) == 0 { + return + } + le.c.mu.Lock() + ep, ok := le.c.peerMap.endpointForNodeKey(pubKey) + // [Conn.mu] must not be held while [Conn.noteRecvActivity] is called, which + // [endpoint.noteRecvActivity] can end up calling. See + // [Options.NoteRecvActivity] docs. + le.c.mu.Unlock() + if !ok { + return + } + now := mono.Now() + ep.lastRecvUDPAny.StoreAtomic(now) + ep.noteRecvActivity(le.src, now) + // [ep.noteRecvActivity] may end up JIT configuring the peer, but we don't + // update [peerMap] as wireguard-go hasn't decrypted the initiation + // message yet. wireguard-go will call us below in [lazyEndpoint.FromPeer] + // if it successfully decrypts the message, at which point it's safe to + // insert le.src into the [peerMap] for ep. +} + +func (le *lazyEndpoint) ClearSrc() {} +func (le *lazyEndpoint) SrcIP() netip.Addr { return netip.Addr{} } + +// DstIP returns the remote address of the peer. +// +// Note: DstIP is used internally by wireguard-go as part of handshake DoS +// mitigation. +func (le *lazyEndpoint) DstIP() netip.Addr { return le.src.ap.Addr() } + +func (le *lazyEndpoint) SrcToString() string { return "" } +func (le *lazyEndpoint) DstToString() string { return le.src.String() } + +// DstToBytes returns a binary representation of the remote address of the peer. +// +// Note: DstToBytes is used internally by wireguard-go as part of handshake DoS +// mitigation. +func (le *lazyEndpoint) DstToBytes() []byte { + b, _ := le.src.ap.MarshalBinary() + return b +} + +// FromPeer implements [conn.PeerAwareEndpoint]. We return a [*lazyEndpoint] in +// [Conn.receiveIP] when we are unable to identify the peer at WireGuard +// packet reception time, pre-decryption, or we want wireguard-go to verify who +// we believe it to be (le.maybeEP). If wireguard-go successfully decrypts the +// packet it calls us here, and we update our [peerMap] to associate le.src with +// peerPublicKey. +func (le *lazyEndpoint) FromPeer(peerPublicKey [32]byte) { + pubKey := key.NodePublicFromRaw32(mem.B(peerPublicKey[:])) + if le.maybeEP != nil && pubKey.Compare(le.maybeEP.publicKey) == 0 { + return + } le.c.mu.Lock() defer le.c.mu.Unlock() ep, ok := le.c.peerMap.endpointForNodeKey(pubKey) if !ok { - return nil + return } - le.c.logf("magicsock: lazyEndpoint.GetPeerEndpoint(%v) found: %v", pubKey.ShortString(), ep.nodeAddr) - return ep + // TODO(jwhited): Consider [lazyEndpoint] effectiveness as a means to make + // this the sole call site for setNodeKeyForEpAddr. If this is the sole + // call site, and we always update the mapping based on successful + // Cryptokey Routing identification events, then we can go ahead and make + // [epAddr]s singular per peer (like they are for Geneve-encapsulated ones + // already). + // See http://go/corp/29422 & http://go/corp/30042 + le.c.peerMap.setNodeKeyForEpAddr(le.src, pubKey) + le.c.logf("magicsock: lazyEndpoint.FromPeer(%v) setting epAddr(%v) in peerMap for node(%v)", pubKey.ShortString(), le.src, ep.nodeAddr) +} + +// PeerRelays returns the current set of candidate peer relays. +func (c *Conn) PeerRelays() set.Set[netip.Addr] { + candidatePeerRelays := c.relayManager.getServers() + servers := make(set.Set[netip.Addr], len(candidatePeerRelays)) + c.mu.Lock() + defer c.mu.Unlock() + for relay := range candidatePeerRelays { + pi, ok := c.peerMap.byNodeKey[relay.nodeKey] + if !ok { + if c.self.Key().Compare(relay.nodeKey) == 0 { + if c.self.Addresses().Len() > 0 { + servers.Add(c.self.Addresses().At(0).Addr()) + } + } + continue + } + servers.Add(pi.ep.nodeAddr) + } + return servers +} + +// HandleDiscoKeyAdvertisement processes a TSMP disco key update. +// The update may be solicited (in response to a request) or unsolicited. +// node is the Tailscale tailcfg.NodeView of the peer that sent the update. +func (c *Conn) HandleDiscoKeyAdvertisement(node tailcfg.NodeView, update packet.TSMPDiscoKeyAdvertisement) { + discoKey := update.Key + c.logf("magicsock: received disco key update %v from %v", discoKey.ShortString(), node.StableID()) + metricTSMPDiscoKeyAdvertisementReceived.Add(1) + + c.mu.Lock() + defer c.mu.Unlock() + nodeKey := node.Key() + + ep, ok := c.peerMap.endpointForNodeKey(nodeKey) + if !ok { + c.logf("magicsock: endpoint not found for node %v", nodeKey.ShortString()) + return + } + + oldDiscoKey := key.DiscoPublic{} + if epDisco := ep.disco.Load(); epDisco != nil { + oldDiscoKey = epDisco.key + } + // If the key did not change, count it and return. + if oldDiscoKey.Compare(discoKey) == 0 { + metricTSMPDiscoKeyAdvertisementUnchanged.Add(1) + return + } + c.discoInfoForKnownPeerLocked(discoKey) + ep.disco.Store(&endpointDisco{ + key: discoKey, + short: discoKey.ShortString(), + }) + c.peerMap.upsertEndpoint(ep, oldDiscoKey) + c.logf("magicsock: updated disco key for peer %v to %v", nodeKey.ShortString(), discoKey.ShortString()) + metricTSMPDiscoKeyAdvertisementApplied.Add(1) } diff --git a/vendor/tailscale.com/wgengine/magicsock/magicsock_default.go b/vendor/tailscale.com/wgengine/magicsock/magicsock_default.go index 7614c64..88759d3 100644 --- a/vendor/tailscale.com/wgengine/magicsock/magicsock_default.go +++ b/vendor/tailscale.com/wgengine/magicsock/magicsock_default.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !linux +//go:build !linux || ts_omit_listenrawdisco package magicsock @@ -9,19 +9,8 @@ import ( "errors" "fmt" "io" - - "tailscale.com/types/logger" - "tailscale.com/types/nettype" ) func (c *Conn) listenRawDisco(family string) (io.Closer, error) { return nil, fmt.Errorf("raw disco listening not supported on this OS: %w", errors.ErrUnsupported) } - -func trySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) { - portableTrySetSocketBuffer(pconn, logf) -} - -const ( - controlMessageSize = 0 -) diff --git a/vendor/tailscale.com/wgengine/magicsock/magicsock_linux.go b/vendor/tailscale.com/wgengine/magicsock/magicsock_linux.go index c5df555..f37e191 100644 --- a/vendor/tailscale.com/wgengine/magicsock/magicsock_linux.go +++ b/vendor/tailscale.com/wgengine/magicsock/magicsock_linux.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build linux && !ts_omit_listenrawdisco + package magicsock import ( @@ -13,7 +15,6 @@ import ( "net" "net/netip" "strings" - "syscall" "time" "github.com/mdlayher/socket" @@ -28,7 +29,6 @@ import ( "tailscale.com/types/ipproto" "tailscale.com/types/key" "tailscale.com/types/logger" - "tailscale.com/types/nettype" ) const ( @@ -66,10 +66,10 @@ var ( // fragmented, and we don't want to handle reassembly. bpf.LoadAbsolute{Off: 6, Size: 2}, // More Fragments bit set means this is part of a fragmented packet. - bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x2000, SkipTrue: 7, SkipFalse: 0}, + bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x2000, SkipTrue: 8, SkipFalse: 0}, // Non-zero fragment offset with MF=0 means this is the last // fragment of packet. - bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x1fff, SkipTrue: 6, SkipFalse: 0}, + bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 0x1fff, SkipTrue: 7, SkipFalse: 0}, // Load IP header length into X register. bpf.LoadMemShift{Off: 0}, @@ -453,7 +453,13 @@ func (c *Conn) receiveDisco(pc *socket.Conn, isIPV6 bool) { metricRecvDiscoPacketIPv4.Add(1) } - c.handleDiscoMessage(payload, srcAddr, key.NodePublic{}, discoRXPathRawSocket) + pt, isGeneveEncap := packetLooksLike(payload) + if pt == packetLooksLikeDisco && !isGeneveEncap { + // The BPF program matching on disco does not currently support + // Geneve encapsulation. isGeneveEncap should not return true if + // payload is disco. + c.handleDiscoMessage(payload, epAddr{ap: srcAddr}, false, key.NodePublic{}, discoRXPathRawSocket) + } } } @@ -483,38 +489,3 @@ func printSockaddr(sa unix.Sockaddr) string { return fmt.Sprintf("unknown(%T)", sa) } } - -// trySetSocketBuffer attempts to set SO_SNDBUFFORCE and SO_RECVBUFFORCE which -// can overcome the limit of net.core.{r,w}mem_max, but require CAP_NET_ADMIN. -// It falls back to the portable implementation if that fails, which may be -// silently capped to net.core.{r,w}mem_max. -func trySetSocketBuffer(pconn nettype.PacketConn, logf logger.Logf) { - if c, ok := pconn.(*net.UDPConn); ok { - var errRcv, errSnd error - rc, err := c.SyscallConn() - if err == nil { - rc.Control(func(fd uintptr) { - errRcv = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_RCVBUFFORCE, socketBufferSize) - if errRcv != nil { - logf("magicsock: [warning] failed to force-set UDP read buffer size to %d: %v; using kernel default values (impacts throughput only)", socketBufferSize, errRcv) - } - errSnd = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_SNDBUFFORCE, socketBufferSize) - if errSnd != nil { - logf("magicsock: [warning] failed to force-set UDP write buffer size to %d: %v; using kernel default values (impacts throughput only)", socketBufferSize, errSnd) - } - }) - } - - if err != nil || errRcv != nil || errSnd != nil { - portableTrySetSocketBuffer(pconn, logf) - } - } -} - -var controlMessageSize = -1 // bomb if used for allocation before init - -func init() { - // controlMessageSize is set to hold a UDP_GRO or UDP_SEGMENT control - // message. These contain a single uint16 of data. - controlMessageSize = unix.CmsgSpace(2) -} diff --git a/vendor/tailscale.com/wgengine/magicsock/peermap.go b/vendor/tailscale.com/wgengine/magicsock/peermap.go index e1c7db1..1363535 100644 --- a/vendor/tailscale.com/wgengine/magicsock/peermap.go +++ b/vendor/tailscale.com/wgengine/magicsock/peermap.go @@ -4,8 +4,6 @@ package magicsock import ( - "net/netip" - "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/util/set" @@ -15,17 +13,17 @@ import ( // peer. type peerInfo struct { ep *endpoint // always non-nil. - // ipPorts is an inverted version of peerMap.byIPPort (below), so + // epAddrs is an inverted version of peerMap.byEpAddr (below), so // that when we're deleting this node, we can rapidly find out the - // keys that need deleting from peerMap.byIPPort without having to - // iterate over every IPPort known for any peer. - ipPorts set.Set[netip.AddrPort] + // keys that need deleting from peerMap.byEpAddr without having to + // iterate over every epAddr known for any peer. + epAddrs set.Set[epAddr] } func newPeerInfo(ep *endpoint) *peerInfo { return &peerInfo{ ep: ep, - ipPorts: set.Set[netip.AddrPort]{}, + epAddrs: set.Set[epAddr]{}, } } @@ -35,9 +33,21 @@ func newPeerInfo(ep *endpoint) *peerInfo { // It doesn't do any locking; all access must be done with Conn.mu held. type peerMap struct { byNodeKey map[key.NodePublic]*peerInfo - byIPPort map[netip.AddrPort]*peerInfo + byEpAddr map[epAddr]*peerInfo byNodeID map[tailcfg.NodeID]*peerInfo + // relayEpAddrByNodeKey ensures we only hold a single relay + // [epAddr] (vni.isSet()) for a given node key in byEpAddr, vs letting them + // grow unbounded. Relay [epAddr]'s are dynamically created by + // [relayManager] during path discovery, and are only useful to track in + // peerMap so long as they are the endpoint.bestAddr. [relayManager] handles + // all creation and initial probing responsibilities otherwise, and it does + // not depend on [peerMap]. + // + // Note: This doesn't address unbounded growth of non-relay epAddr's in + // byEpAddr. That issue is being tracked in http://go/corp/29422. + relayEpAddrByNodeKey map[key.NodePublic]epAddr + // nodesOfDisco contains the set of nodes that are using a // DiscoKey. Usually those sets will be just one node. nodesOfDisco map[key.DiscoPublic]set.Set[key.NodePublic] @@ -45,10 +55,11 @@ type peerMap struct { func newPeerMap() peerMap { return peerMap{ - byNodeKey: map[key.NodePublic]*peerInfo{}, - byIPPort: map[netip.AddrPort]*peerInfo{}, - byNodeID: map[tailcfg.NodeID]*peerInfo{}, - nodesOfDisco: map[key.DiscoPublic]set.Set[key.NodePublic]{}, + byNodeKey: map[key.NodePublic]*peerInfo{}, + byEpAddr: map[epAddr]*peerInfo{}, + byNodeID: map[tailcfg.NodeID]*peerInfo{}, + relayEpAddrByNodeKey: map[key.NodePublic]epAddr{}, + nodesOfDisco: map[key.DiscoPublic]set.Set[key.NodePublic]{}, } } @@ -88,10 +99,10 @@ func (m *peerMap) endpointForNodeID(nodeID tailcfg.NodeID) (ep *endpoint, ok boo return nil, false } -// endpointForIPPort returns the endpoint for the peer we -// believe to be at ipp, or nil if we don't know of any such peer. -func (m *peerMap) endpointForIPPort(ipp netip.AddrPort) (ep *endpoint, ok bool) { - if info, ok := m.byIPPort[ipp]; ok { +// endpointForEpAddr returns the endpoint for the peer we +// believe to be at addr, or nil if we don't know of any such peer. +func (m *peerMap) endpointForEpAddr(addr epAddr) (ep *endpoint, ok bool) { + if info, ok := m.byEpAddr[addr]; ok { return info.ep, true } return nil, false @@ -148,10 +159,10 @@ func (m *peerMap) upsertEndpoint(ep *endpoint, oldDiscoKey key.DiscoPublic) { // TODO(raggi,catzkorn): this could mean that if a "isWireguardOnly" // peer has, say, 192.168.0.2 and so does a tailscale peer, the // wireguard one will win. That may not be the outcome that we want - - // perhaps we should prefer bestAddr.AddrPort if it is set? + // perhaps we should prefer bestAddr.epAddr.ap if it is set? // see tailscale/tailscale#7994 for ipp := range ep.endpointState { - m.setNodeKeyForIPPort(ipp, ep.publicKey) + m.setNodeKeyForEpAddr(epAddr{ap: ipp}, ep.publicKey) } return } @@ -163,20 +174,31 @@ func (m *peerMap) upsertEndpoint(ep *endpoint, oldDiscoKey key.DiscoPublic) { discoSet.Add(ep.publicKey) } -// setNodeKeyForIPPort makes future peer lookups by ipp return the +// setNodeKeyForEpAddr makes future peer lookups by addr return the // same endpoint as a lookup by nk. // -// This should only be called with a fully verified mapping of ipp to +// This should only be called with a fully verified mapping of addr to // nk, because calling this function defines the endpoint we hand to -// WireGuard for packets received from ipp. -func (m *peerMap) setNodeKeyForIPPort(ipp netip.AddrPort, nk key.NodePublic) { - if pi := m.byIPPort[ipp]; pi != nil { - delete(pi.ipPorts, ipp) - delete(m.byIPPort, ipp) +// WireGuard for packets received from addr. +func (m *peerMap) setNodeKeyForEpAddr(addr epAddr, nk key.NodePublic) { + if pi := m.byEpAddr[addr]; pi != nil { + delete(pi.epAddrs, addr) + delete(m.byEpAddr, addr) + if addr.vni.IsSet() { + delete(m.relayEpAddrByNodeKey, pi.ep.publicKey) + } } if pi, ok := m.byNodeKey[nk]; ok { - pi.ipPorts.Add(ipp) - m.byIPPort[ipp] = pi + if addr.vni.IsSet() { + relay, ok := m.relayEpAddrByNodeKey[nk] + if ok { + delete(pi.epAddrs, relay) + delete(m.byEpAddr, relay) + } + m.relayEpAddrByNodeKey[nk] = addr + } + pi.epAddrs.Add(addr) + m.byEpAddr[addr] = pi } } @@ -203,7 +225,8 @@ func (m *peerMap) deleteEndpoint(ep *endpoint) { // Unexpected. But no logger plumbed here to log so. return } - for ip := range pi.ipPorts { - delete(m.byIPPort, ip) + for ip := range pi.epAddrs { + delete(m.byEpAddr, ip) } + delete(m.relayEpAddrByNodeKey, ep.publicKey) } diff --git a/vendor/tailscale.com/wgengine/magicsock/rebinding_conn.go b/vendor/tailscale.com/wgengine/magicsock/rebinding_conn.go index c27abba..c98e645 100644 --- a/vendor/tailscale.com/wgengine/magicsock/rebinding_conn.go +++ b/vendor/tailscale.com/wgengine/magicsock/rebinding_conn.go @@ -5,14 +5,17 @@ package magicsock import ( "errors" + "fmt" "net" "net/netip" - "sync" "sync/atomic" "syscall" "golang.org/x/net/ipv6" + "tailscale.com/net/batching" "tailscale.com/net/netaddr" + "tailscale.com/net/packet" + "tailscale.com/syncs" "tailscale.com/types/nettype" ) @@ -28,7 +31,7 @@ type RebindingUDPConn struct { // Neither is expected to be nil, sockets are bound on creation. pconnAtomic atomic.Pointer[nettype.PacketConn] - mu sync.Mutex // held while changing pconn (and pconnAtomic) + mu syncs.Mutex // held while changing pconn (and pconnAtomic) pconn nettype.PacketConn port uint16 } @@ -40,7 +43,7 @@ type RebindingUDPConn struct { // disrupting surrounding code that assumes nettype.PacketConn is a // *net.UDPConn. func (c *RebindingUDPConn) setConnLocked(p nettype.PacketConn, network string, batchSize int) { - upc := tryUpgradeToBatchingConn(p, network, batchSize) + upc := batching.TryUpgradeToConn(p, network, batchSize) c.pconn = upc c.pconnAtomic.Store(&upc) c.port = uint16(c.localAddrLocked().Port) @@ -70,21 +73,39 @@ func (c *RebindingUDPConn) ReadFromUDPAddrPort(b []byte) (int, netip.AddrPort, e return c.readFromWithInitPconn(*c.pconnAtomic.Load(), b) } -// WriteBatchTo writes buffs to addr. -func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) error { +// WriteWireGuardBatchTo writes buffs to addr. It serves primarily as an alias +// for [batching.Conn.WriteBatchTo], with fallback to single packet operations +// if c.pconn is not a [batching.Conn]. +// +// WriteWireGuardBatchTo assumes buffs are WireGuard packets, which is notable +// for Geneve encapsulation: Geneve protocol is set to [packet.GeneveProtocolWireGuard], +// and the control bit is left unset. +func (c *RebindingUDPConn) WriteWireGuardBatchTo(buffs [][]byte, addr epAddr, offset int) error { + if offset != packet.GeneveFixedHeaderLength { + return fmt.Errorf("RebindingUDPConn.WriteWireGuardBatchTo: [unexpected] offset (%d) != Geneve header length (%d)", offset, packet.GeneveFixedHeaderLength) + } + gh := packet.GeneveHeader{ + Protocol: packet.GeneveProtocolWireGuard, + VNI: addr.vni, + } for { pconn := *c.pconnAtomic.Load() - b, ok := pconn.(batchingConn) + b, ok := pconn.(batching.Conn) if !ok { for _, buf := range buffs { - _, err := c.writeToUDPAddrPortWithInitPconn(pconn, buf, addr) + if gh.VNI.IsSet() { + gh.Encode(buf) + } else { + buf = buf[offset:] + } + _, err := c.writeToUDPAddrPortWithInitPconn(pconn, buf, addr.ap) if err != nil { return err } } return nil } - err := b.WriteBatchTo(buffs, addr) + err := b.WriteBatchTo(buffs, addr.ap, gh, offset) if err != nil { if pconn != c.currentConn() { continue @@ -95,13 +116,12 @@ func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort) err } } -// ReadBatch reads messages from c into msgs. It returns the number of messages -// the caller should evaluate for nonzero len, as a zero len message may fall -// on either side of a nonzero. +// ReadBatch is an alias for [batching.Conn.ReadBatch] with fallback to single +// packet operations if c.pconn is not a [batching.Conn]. func (c *RebindingUDPConn) ReadBatch(msgs []ipv6.Message, flags int) (int, error) { for { pconn := *c.pconnAtomic.Load() - b, ok := pconn.(batchingConn) + b, ok := pconn.(batching.Conn) if !ok { n, ap, err := c.readFromWithInitPconn(pconn, msgs[0].Buffers[0]) if err == nil { diff --git a/vendor/tailscale.com/wgengine/magicsock/relaymanager.go b/vendor/tailscale.com/wgengine/magicsock/relaymanager.go new file mode 100644 index 0000000..69831a4 --- /dev/null +++ b/vendor/tailscale.com/wgengine/magicsock/relaymanager.go @@ -0,0 +1,1071 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package magicsock + +import ( + "context" + "errors" + "fmt" + "net/netip" + "sync" + "time" + + "tailscale.com/disco" + "tailscale.com/net/packet" + "tailscale.com/net/stun" + udprelay "tailscale.com/net/udprelay/endpoint" + "tailscale.com/syncs" + "tailscale.com/tailcfg" + "tailscale.com/tstime" + "tailscale.com/types/key" + "tailscale.com/util/set" +) + +// relayManager manages allocation, handshaking, and initial probing (disco +// ping/pong) of [tailscale.com/net/udprelay.Server] endpoints. The zero value +// is ready for use. +// +// [relayManager] methods can be called by [Conn] and [endpoint] while their .mu +// mutexes are held. Therefore, in order to avoid deadlocks, [relayManager] must +// never attempt to acquire those mutexes synchronously from its runLoop(), +// including synchronous calls back towards [Conn] or [endpoint] methods that +// acquire them. +type relayManager struct { + initOnce sync.Once + + // =================================================================== + // The following fields are owned by a single goroutine, runLoop(). + serversByNodeKey map[key.NodePublic]candidatePeerRelay + allocWorkByCandidatePeerRelayByEndpoint map[*endpoint]map[candidatePeerRelay]*relayEndpointAllocWork + allocWorkByDiscoKeysByServerNodeKey map[key.NodePublic]map[key.SortedPairOfDiscoPublic]*relayEndpointAllocWork + handshakeWorkByServerDiscoByEndpoint map[*endpoint]map[key.DiscoPublic]*relayHandshakeWork + handshakeWorkByServerDiscoVNI map[serverDiscoVNI]*relayHandshakeWork + handshakeWorkAwaitingPong map[*relayHandshakeWork]addrPortVNI + addrPortVNIToHandshakeWork map[addrPortVNI]*relayHandshakeWork + handshakeGeneration uint32 + allocGeneration uint32 + + // =================================================================== + // The following chan fields serve event inputs to a single goroutine, + // runLoop(). + startDiscoveryCh chan endpointWithLastBest + allocateWorkDoneCh chan relayEndpointAllocWorkDoneEvent + handshakeWorkDoneCh chan relayEndpointHandshakeWorkDoneEvent + cancelWorkCh chan *endpoint + newServerEndpointCh chan newRelayServerEndpointEvent + rxDiscoMsgCh chan relayDiscoMsgEvent + serversCh chan set.Set[candidatePeerRelay] + getServersCh chan chan set.Set[candidatePeerRelay] + derpHomeChangeCh chan derpHomeChangeEvent + + discoInfoMu syncs.Mutex // guards the following field + discoInfoByServerDisco map[key.DiscoPublic]*relayHandshakeDiscoInfo + + // runLoopStoppedCh is written to by runLoop() upon return, enabling event + // writers to restart it when they are blocked (see + // relayManagerInputEvent()). + runLoopStoppedCh chan struct{} +} + +// serverDiscoVNI represents a [tailscale.com/net/udprelay.Server] disco key +// and Geneve header VNI value for a given [udprelay.ServerEndpoint]. +type serverDiscoVNI struct { + serverDisco key.DiscoPublic + vni uint32 +} + +// relayHandshakeWork serves to track in-progress relay handshake work for a +// [udprelay.ServerEndpoint]. This structure is immutable once initialized. +type relayHandshakeWork struct { + wlb endpointWithLastBest + se udprelay.ServerEndpoint + server candidatePeerRelay + + handshakeGen uint32 + + // handshakeServerEndpoint() always writes to doneCh (len 1) when it + // returns. It may end up writing the same event afterward to + // relayManager.handshakeWorkDoneCh if runLoop() can receive it. runLoop() + // must select{} read on doneCh to prevent deadlock when attempting to write + // to rxDiscoMsgCh. + rxDiscoMsgCh chan relayDiscoMsgEvent + doneCh chan relayEndpointHandshakeWorkDoneEvent + + ctx context.Context + cancel context.CancelFunc +} + +func (r *relayHandshakeWork) dlogf(format string, args ...any) { + if !r.wlb.ep.c.debugLogging.Load() { + return + } + var relay string + if r.server.nodeKey.IsZero() { + relay = "from-call-me-maybe-via" + } else { + relay = r.server.nodeKey.ShortString() + } + r.wlb.ep.c.logf("%s node=%v relay=%v handshakeGen=%d disco[0]=%v disco[1]=%v", + fmt.Sprintf(format, args...), + r.wlb.ep.publicKey.ShortString(), + relay, + r.handshakeGen, + r.se.ClientDisco[0].ShortString(), + r.se.ClientDisco[1].ShortString(), + ) +} + +// newRelayServerEndpointEvent indicates a new [udprelay.ServerEndpoint] has +// become known either via allocation with a relay server, or via +// [disco.CallMeMaybeVia] reception. This structure is immutable once +// initialized. +type newRelayServerEndpointEvent struct { + wlb endpointWithLastBest + se udprelay.ServerEndpoint + server candidatePeerRelay // zero value if learned via [disco.CallMeMaybeVia] +} + +// relayEndpointAllocWorkDoneEvent indicates relay server endpoint allocation +// work for an [*endpoint] has completed. This structure is immutable once +// initialized. +type relayEndpointAllocWorkDoneEvent struct { + work *relayEndpointAllocWork + allocated udprelay.ServerEndpoint // !allocated.ServerDisco.IsZero() if allocation succeeded +} + +// relayEndpointHandshakeWorkDoneEvent indicates relay server endpoint handshake +// work for an [*endpoint] has completed. This structure is immutable once +// initialized. +type relayEndpointHandshakeWorkDoneEvent struct { + work *relayHandshakeWork + pongReceivedFrom netip.AddrPort // or zero value if handshake or ping/pong did not complete + latency time.Duration // only relevant if pongReceivedFrom.IsValid() +} + +// hasActiveWorkRunLoop returns true if there is outstanding allocation or +// handshaking work for any endpoint, otherwise it returns false. +func (r *relayManager) hasActiveWorkRunLoop() bool { + return len(r.allocWorkByCandidatePeerRelayByEndpoint) > 0 || len(r.handshakeWorkByServerDiscoByEndpoint) > 0 +} + +// hasActiveWorkForEndpointRunLoop returns true if there is outstanding +// allocation or handshaking work for the provided endpoint, otherwise it +// returns false. +func (r *relayManager) hasActiveWorkForEndpointRunLoop(ep *endpoint) bool { + _, handshakeWork := r.handshakeWorkByServerDiscoByEndpoint[ep] + _, allocWork := r.allocWorkByCandidatePeerRelayByEndpoint[ep] + return handshakeWork || allocWork +} + +// derpHomeChangeEvent represents a change in the DERP home region for the +// node identified by nodeKey. This structure is immutable once initialized. +type derpHomeChangeEvent struct { + nodeKey key.NodePublic + regionID uint16 +} + +// handleDERPHomeChange handles a DERP home change event for nodeKey and +// regionID. +func (r *relayManager) handleDERPHomeChange(nodeKey key.NodePublic, regionID uint16) { + relayManagerInputEvent(r, nil, &r.derpHomeChangeCh, derpHomeChangeEvent{ + nodeKey: nodeKey, + regionID: regionID, + }) +} + +func (r *relayManager) handleDERPHomeChangeRunLoop(event derpHomeChangeEvent) { + c, ok := r.serversByNodeKey[event.nodeKey] + if ok { + c.derpHomeRegionID = event.regionID + r.serversByNodeKey[event.nodeKey] = c + } +} + +// runLoop is a form of event loop. It ensures exclusive access to most of +// [relayManager] state. +func (r *relayManager) runLoop() { + defer func() { + r.runLoopStoppedCh <- struct{}{} + }() + + for { + select { + case startDiscovery := <-r.startDiscoveryCh: + if !r.hasActiveWorkForEndpointRunLoop(startDiscovery.ep) { + r.allocateAllServersRunLoop(startDiscovery) + } + if !r.hasActiveWorkRunLoop() { + return + } + case done := <-r.allocateWorkDoneCh: + r.handleAllocWorkDoneRunLoop(done) + if !r.hasActiveWorkRunLoop() { + return + } + case ep := <-r.cancelWorkCh: + r.stopWorkRunLoop(ep) + if !r.hasActiveWorkRunLoop() { + return + } + case newServerEndpoint := <-r.newServerEndpointCh: + r.handleNewServerEndpointRunLoop(newServerEndpoint) + if !r.hasActiveWorkRunLoop() { + return + } + case done := <-r.handshakeWorkDoneCh: + r.handleHandshakeWorkDoneRunLoop(done) + if !r.hasActiveWorkRunLoop() { + return + } + case discoMsgEvent := <-r.rxDiscoMsgCh: + r.handleRxDiscoMsgRunLoop(discoMsgEvent) + if !r.hasActiveWorkRunLoop() { + return + } + case serversUpdate := <-r.serversCh: + r.handleServersUpdateRunLoop(serversUpdate) + if !r.hasActiveWorkRunLoop() { + return + } + case getServersCh := <-r.getServersCh: + r.handleGetServersRunLoop(getServersCh) + if !r.hasActiveWorkRunLoop() { + return + } + case derpHomeChange := <-r.derpHomeChangeCh: + r.handleDERPHomeChangeRunLoop(derpHomeChange) + if !r.hasActiveWorkRunLoop() { + return + } + } + } +} + +func (r *relayManager) handleGetServersRunLoop(getServersCh chan set.Set[candidatePeerRelay]) { + servers := make(set.Set[candidatePeerRelay], len(r.serversByNodeKey)) + for _, v := range r.serversByNodeKey { + servers.Add(v) + } + getServersCh <- servers +} + +func (r *relayManager) getServers() set.Set[candidatePeerRelay] { + ch := make(chan set.Set[candidatePeerRelay]) + relayManagerInputEvent(r, nil, &r.getServersCh, ch) + return <-ch +} + +func (r *relayManager) handleServersUpdateRunLoop(update set.Set[candidatePeerRelay]) { + for _, v := range r.serversByNodeKey { + if !update.Contains(v) { + delete(r.serversByNodeKey, v.nodeKey) + } + } + for _, v := range update.Slice() { + r.serversByNodeKey[v.nodeKey] = v + } +} + +type relayDiscoMsgEvent struct { + conn *Conn // for access to [Conn] if there is no associated [relayHandshakeWork] + msg disco.Message + relayServerNodeKey key.NodePublic // nonzero if msg is a [*disco.AllocateUDPRelayEndpointResponse] + disco key.DiscoPublic + from netip.AddrPort + vni uint32 + at time.Time +} + +// relayEndpointAllocWork serves to track in-progress relay endpoint allocation +// for an [*endpoint]. This structure is immutable once initialized. +type relayEndpointAllocWork struct { + wlb endpointWithLastBest + discoKeys key.SortedPairOfDiscoPublic + candidatePeerRelay candidatePeerRelay // zero value if learned via [disco.CallMeMaybeVia] + + allocGen uint32 + + // allocateServerEndpoint() always writes to doneCh (len 1) when it + // returns. It may end up writing the same event afterward to + // [relayManager.allocateWorkDoneCh] if runLoop() can receive it. runLoop() + // must select{} read on doneCh to prevent deadlock when attempting to write + // to rxDiscoMsgCh. + rxDiscoMsgCh chan *disco.AllocateUDPRelayEndpointResponse + doneCh chan relayEndpointAllocWorkDoneEvent + + ctx context.Context + cancel context.CancelFunc +} + +func (r *relayEndpointAllocWork) dlogf(format string, args ...any) { + if !r.wlb.ep.c.debugLogging.Load() { + return + } + r.wlb.ep.c.logf("%s node=%v relay=%v allocGen=%d disco[0]=%v disco[1]=%v", + fmt.Sprintf(format, args...), + r.wlb.ep.publicKey.ShortString(), + r.candidatePeerRelay.nodeKey.ShortString(), + r.allocGen, + r.discoKeys.Get()[0].ShortString(), + r.discoKeys.Get()[1].ShortString(), + ) +} + +// init initializes [relayManager] if it is not already initialized. +func (r *relayManager) init() { + r.initOnce.Do(func() { + r.discoInfoByServerDisco = make(map[key.DiscoPublic]*relayHandshakeDiscoInfo) + r.serversByNodeKey = make(map[key.NodePublic]candidatePeerRelay) + r.allocWorkByCandidatePeerRelayByEndpoint = make(map[*endpoint]map[candidatePeerRelay]*relayEndpointAllocWork) + r.allocWorkByDiscoKeysByServerNodeKey = make(map[key.NodePublic]map[key.SortedPairOfDiscoPublic]*relayEndpointAllocWork) + r.handshakeWorkByServerDiscoByEndpoint = make(map[*endpoint]map[key.DiscoPublic]*relayHandshakeWork) + r.handshakeWorkByServerDiscoVNI = make(map[serverDiscoVNI]*relayHandshakeWork) + r.handshakeWorkAwaitingPong = make(map[*relayHandshakeWork]addrPortVNI) + r.addrPortVNIToHandshakeWork = make(map[addrPortVNI]*relayHandshakeWork) + r.startDiscoveryCh = make(chan endpointWithLastBest) + r.allocateWorkDoneCh = make(chan relayEndpointAllocWorkDoneEvent) + r.handshakeWorkDoneCh = make(chan relayEndpointHandshakeWorkDoneEvent) + r.cancelWorkCh = make(chan *endpoint) + r.newServerEndpointCh = make(chan newRelayServerEndpointEvent) + r.rxDiscoMsgCh = make(chan relayDiscoMsgEvent) + r.serversCh = make(chan set.Set[candidatePeerRelay]) + r.getServersCh = make(chan chan set.Set[candidatePeerRelay]) + r.derpHomeChangeCh = make(chan derpHomeChangeEvent) + r.runLoopStoppedCh = make(chan struct{}, 1) + r.runLoopStoppedCh <- struct{}{} + }) +} + +// relayHandshakeDiscoInfo serves to cache a [*discoInfo] for outstanding +// [*relayHandshakeWork] against a given relay server. +type relayHandshakeDiscoInfo struct { + work set.Set[*relayHandshakeWork] // guarded by relayManager.discoInfoMu + di *discoInfo // immutable once initialized +} + +// ensureDiscoInfoFor ensures a [*discoInfo] will be returned by discoInfo() for +// the server disco key associated with 'work'. Callers must also call +// derefDiscoInfoFor() when 'work' is complete. +func (r *relayManager) ensureDiscoInfoFor(work *relayHandshakeWork) { + r.discoInfoMu.Lock() + defer r.discoInfoMu.Unlock() + di, ok := r.discoInfoByServerDisco[work.se.ServerDisco] + if !ok { + di = &relayHandshakeDiscoInfo{} + di.work.Make() + r.discoInfoByServerDisco[work.se.ServerDisco] = di + } + di.work.Add(work) + if di.di == nil { + di.di = &discoInfo{ + discoKey: work.se.ServerDisco, + discoShort: work.se.ServerDisco.ShortString(), + sharedKey: work.wlb.ep.c.discoAtomic.Private().Shared(work.se.ServerDisco), + } + } +} + +// derefDiscoInfoFor decrements the reference count of the [*discoInfo] +// associated with 'work'. +func (r *relayManager) derefDiscoInfoFor(work *relayHandshakeWork) { + r.discoInfoMu.Lock() + defer r.discoInfoMu.Unlock() + di, ok := r.discoInfoByServerDisco[work.se.ServerDisco] + if !ok { + // TODO(jwhited): unexpected + return + } + di.work.Delete(work) + if di.work.Len() == 0 { + delete(r.discoInfoByServerDisco, work.se.ServerDisco) + } +} + +// discoInfo returns a [*discoInfo] for 'serverDisco' if there is an +// active/ongoing handshake with it, otherwise it returns nil, false. +func (r *relayManager) discoInfo(serverDisco key.DiscoPublic) (_ *discoInfo, ok bool) { + r.discoInfoMu.Lock() + defer r.discoInfoMu.Unlock() + di, ok := r.discoInfoByServerDisco[serverDisco] + if ok { + return di.di, ok + } + return nil, false +} + +func (r *relayManager) handleCallMeMaybeVia(ep *endpoint, lastBest addrQuality, lastBestIsTrusted bool, dm *disco.CallMeMaybeVia) { + se := udprelay.ServerEndpoint{ + ServerDisco: dm.ServerDisco, + ClientDisco: dm.ClientDisco, + LamportID: dm.LamportID, + AddrPorts: dm.AddrPorts, + VNI: dm.VNI, + } + se.BindLifetime.Duration = dm.BindLifetime + se.SteadyStateLifetime.Duration = dm.SteadyStateLifetime + relayManagerInputEvent(r, nil, &r.newServerEndpointCh, newRelayServerEndpointEvent{ + wlb: endpointWithLastBest{ + ep: ep, + lastBest: lastBest, + lastBestIsTrusted: lastBestIsTrusted, + }, + se: se, + }) +} + +// handleRxDiscoMsg handles reception of disco messages that [relayManager] +// may be interested in. This includes all Geneve-encapsulated disco messages +// and [*disco.AllocateUDPRelayEndpointResponse]. If dm is a +// [*disco.AllocateUDPRelayEndpointResponse] then relayServerNodeKey must be +// nonzero. +func (r *relayManager) handleRxDiscoMsg(conn *Conn, dm disco.Message, relayServerNodeKey key.NodePublic, discoKey key.DiscoPublic, src epAddr) { + relayManagerInputEvent(r, nil, &r.rxDiscoMsgCh, relayDiscoMsgEvent{ + conn: conn, + msg: dm, + relayServerNodeKey: relayServerNodeKey, + disco: discoKey, + from: src.ap, + vni: src.vni.Get(), + at: time.Now(), + }) +} + +// handleRelayServersSet handles an update of the complete relay server set. +func (r *relayManager) handleRelayServersSet(servers set.Set[candidatePeerRelay]) { + relayManagerInputEvent(r, nil, &r.serversCh, servers) +} + +// relayManagerInputEvent initializes [relayManager] if necessary, starts +// relayManager.runLoop() if it is not running, and writes 'event' on 'eventCh'. +// +// [relayManager] initialization will make `*eventCh`, so it must be passed as +// a pointer to a channel. +// +// 'ctx' can be used for returning when runLoop is waiting for the calling +// goroutine to return, i.e. the calling goroutine was birthed by runLoop and is +// cancelable via 'ctx'. 'ctx' may be nil. +func relayManagerInputEvent[T any](r *relayManager, ctx context.Context, eventCh *chan T, event T) { + r.init() + var ctxDoneCh <-chan struct{} + if ctx != nil { + ctxDoneCh = ctx.Done() + } + for { + select { + case <-ctxDoneCh: + return + case *eventCh <- event: + return + case <-r.runLoopStoppedCh: + go r.runLoop() + } + } +} + +// endpointWithLastBest represents an [*endpoint], its last bestAddr, and if +// the last bestAddr was trusted (see endpoint.trustBestAddrUntil) at the time +// of init. This structure is immutable once initialized. +type endpointWithLastBest struct { + ep *endpoint + lastBest addrQuality + lastBestIsTrusted bool +} + +// startUDPRelayPathDiscoveryFor starts UDP relay path discovery for ep on all +// known relay servers if ep has no in-progress work. +func (r *relayManager) startUDPRelayPathDiscoveryFor(ep *endpoint, lastBest addrQuality, lastBestIsTrusted bool) { + relayManagerInputEvent(r, nil, &r.startDiscoveryCh, endpointWithLastBest{ + ep: ep, + lastBest: lastBest, + lastBestIsTrusted: lastBestIsTrusted, + }) +} + +// stopWork stops all outstanding allocation & handshaking work for 'ep'. +func (r *relayManager) stopWork(ep *endpoint) { + relayManagerInputEvent(r, nil, &r.cancelWorkCh, ep) +} + +// stopWorkRunLoop cancels & clears outstanding allocation and handshaking +// work for 'ep'. +func (r *relayManager) stopWorkRunLoop(ep *endpoint) { + byDiscoKeys, ok := r.allocWorkByCandidatePeerRelayByEndpoint[ep] + if ok { + for _, work := range byDiscoKeys { + work.cancel() + done := <-work.doneCh + r.handleAllocWorkDoneRunLoop(done) + } + } + byServerDisco, ok := r.handshakeWorkByServerDiscoByEndpoint[ep] + if ok { + for _, handshakeWork := range byServerDisco { + handshakeWork.cancel() + done := <-handshakeWork.doneCh + r.handleHandshakeWorkDoneRunLoop(done) + } + } +} + +// addrPortVNI represents a combined netip.AddrPort and Geneve header virtual +// network identifier. +type addrPortVNI struct { + addrPort netip.AddrPort + vni uint32 +} + +func (r *relayManager) handleRxDiscoMsgRunLoop(event relayDiscoMsgEvent) { + var ( + work *relayHandshakeWork + ok bool + ) + apv := addrPortVNI{event.from, event.vni} + switch msg := event.msg.(type) { + case *disco.AllocateUDPRelayEndpointResponse: + sorted := key.NewSortedPairOfDiscoPublic(msg.ClientDisco[0], msg.ClientDisco[1]) + byDiscoKeys, ok := r.allocWorkByDiscoKeysByServerNodeKey[event.relayServerNodeKey] + if !ok { + // No outstanding work tied to this relay sever, discard. + return + } + allocWork, ok := byDiscoKeys[sorted] + if !ok { + // No outstanding work tied to these disco keys, discard. + return + } + select { + case done := <-allocWork.doneCh: + // allocateServerEndpoint returned, clean up its state + r.handleAllocWorkDoneRunLoop(done) + return + case allocWork.rxDiscoMsgCh <- msg: + return + } + case *disco.BindUDPRelayEndpointChallenge: + work, ok = r.handshakeWorkByServerDiscoVNI[serverDiscoVNI{event.disco, event.vni}] + if !ok { + // No outstanding work tied to this challenge, discard. + return + } + _, ok = r.handshakeWorkAwaitingPong[work] + if ok { + // We've seen a challenge for this relay endpoint previously, + // discard. Servers only respond to the first src ip:port they see + // binds from. + return + } + _, ok = r.addrPortVNIToHandshakeWork[apv] + if ok { + // There is existing work for the same [addrPortVNI] that is not + // 'work'. If both instances happen to be on the same server we + // could attempt to resolve event order using LamportID. For now + // just leave both work instances alone and take no action other + // than to discard this challenge msg. + return + } + // Update state so that future ping/pong will route to 'work'. + r.handshakeWorkAwaitingPong[work] = apv + r.addrPortVNIToHandshakeWork[apv] = work + case *disco.Ping: + // Always TX a pong. We might not have any associated work if ping + // reception raced with our call to [endpoint.udpRelayEndpointReady()], so + // err on the side of enabling the remote side to use this path. + // + // Conn.handlePingLocked() makes efforts to suppress duplicate pongs + // where the same ping can be received both via raw socket and UDP + // socket on Linux. We make no such efforts here as the raw socket BPF + // program does not support Geneve-encapsulated disco, and is also + // disabled by default. + vni := packet.VirtualNetworkID{} + vni.Set(event.vni) + go event.conn.sendDiscoMessage(epAddr{ap: event.from, vni: vni}, key.NodePublic{}, event.disco, &disco.Pong{ + TxID: msg.TxID, + Src: event.from, + }, discoVerboseLog) + + work, ok = r.addrPortVNIToHandshakeWork[apv] + if !ok { + // No outstanding work tied to this [addrPortVNI], return early. + return + } + case *disco.Pong: + work, ok = r.addrPortVNIToHandshakeWork[apv] + if !ok { + // No outstanding work tied to this [addrPortVNI], discard. + return + } + default: + // Unexpected message type, discard. + return + } + select { + case done := <-work.doneCh: + // handshakeServerEndpoint() returned, clean up its state. + r.handleHandshakeWorkDoneRunLoop(done) + return + case work.rxDiscoMsgCh <- event: + return + } +} + +func (r *relayManager) handleAllocWorkDoneRunLoop(done relayEndpointAllocWorkDoneEvent) { + byCandidatePeerRelay, ok := r.allocWorkByCandidatePeerRelayByEndpoint[done.work.wlb.ep] + if !ok { + return + } + work, ok := byCandidatePeerRelay[done.work.candidatePeerRelay] + if !ok || work != done.work { + return + } + delete(byCandidatePeerRelay, done.work.candidatePeerRelay) + if len(byCandidatePeerRelay) == 0 { + delete(r.allocWorkByCandidatePeerRelayByEndpoint, done.work.wlb.ep) + } + byDiscoKeys, ok := r.allocWorkByDiscoKeysByServerNodeKey[done.work.candidatePeerRelay.nodeKey] + if !ok { + // unexpected + return + } + delete(byDiscoKeys, done.work.discoKeys) + if len(byDiscoKeys) == 0 { + delete(r.allocWorkByDiscoKeysByServerNodeKey, done.work.candidatePeerRelay.nodeKey) + } + if !done.allocated.ServerDisco.IsZero() { + r.handleNewServerEndpointRunLoop(newRelayServerEndpointEvent{ + wlb: done.work.wlb, + se: done.allocated, + server: done.work.candidatePeerRelay, + }) + } +} + +func (r *relayManager) handleHandshakeWorkDoneRunLoop(done relayEndpointHandshakeWorkDoneEvent) { + byServerDisco, ok := r.handshakeWorkByServerDiscoByEndpoint[done.work.wlb.ep] + if !ok { + return + } + work, ok := byServerDisco[done.work.se.ServerDisco] + if !ok || work != done.work { + return + } + delete(byServerDisco, done.work.se.ServerDisco) + if len(byServerDisco) == 0 { + delete(r.handshakeWorkByServerDiscoByEndpoint, done.work.wlb.ep) + } + delete(r.handshakeWorkByServerDiscoVNI, serverDiscoVNI{done.work.se.ServerDisco, done.work.se.VNI}) + apv, ok := r.handshakeWorkAwaitingPong[work] + if ok { + delete(r.handshakeWorkAwaitingPong, work) + delete(r.addrPortVNIToHandshakeWork, apv) + } + if !done.pongReceivedFrom.IsValid() { + // The handshake or ping/pong probing timed out. + return + } + // This relay endpoint is functional. + vni := packet.VirtualNetworkID{} + vni.Set(done.work.se.VNI) + addr := epAddr{ap: done.pongReceivedFrom, vni: vni} + // ep.udpRelayEndpointReady() must be called in a new goroutine to prevent + // deadlocks as it acquires [endpoint] & [Conn] mutexes. See [relayManager] + // docs for details. + go done.work.wlb.ep.udpRelayEndpointReady(addrQuality{ + epAddr: addr, + relayServerDisco: done.work.se.ServerDisco, + latency: done.latency, + wireMTU: pingSizeToPktLen(0, addr), + }) +} + +func (r *relayManager) handleNewServerEndpointRunLoop(newServerEndpoint newRelayServerEndpointEvent) { + // Check for duplicate work by server disco + VNI. + sdv := serverDiscoVNI{newServerEndpoint.se.ServerDisco, newServerEndpoint.se.VNI} + existingWork, ok := r.handshakeWorkByServerDiscoVNI[sdv] + if ok { + // There's in-progress handshake work for the server disco + VNI, which + // uniquely identify a [udprelay.ServerEndpoint]. Compare Lamport + // IDs to determine which is newer. + if existingWork.se.LamportID >= newServerEndpoint.se.LamportID { + // The existing work is a duplicate or newer. Return early. + return + } + + // The existing work is no longer valid, clean it up. + existingWork.cancel() + done := <-existingWork.doneCh + r.handleHandshakeWorkDoneRunLoop(done) + } + + // Check for duplicate work by [*endpoint] + server disco. + byServerDisco, ok := r.handshakeWorkByServerDiscoByEndpoint[newServerEndpoint.wlb.ep] + if ok { + existingWork, ok := byServerDisco[newServerEndpoint.se.ServerDisco] + if ok { + if newServerEndpoint.se.LamportID <= existingWork.se.LamportID { + // The "new" server endpoint is outdated or duplicate in + // consideration against existing handshake work. Return early. + return + } + // Cancel existing handshake that has a lower lamport ID. + existingWork.cancel() + done := <-existingWork.doneCh + r.handleHandshakeWorkDoneRunLoop(done) + } + } + + // We're now reasonably sure we're dealing with the latest + // [udprelay.ServerEndpoint] from a server event order perspective + // (LamportID). + + if newServerEndpoint.server.isValid() { + // Send a [disco.CallMeMaybeVia] to the remote peer if we allocated this + // endpoint, regardless of if we start a handshake below. + go r.sendCallMeMaybeVia(newServerEndpoint.wlb.ep, newServerEndpoint.se) + } + + lastBestMatchingServer := newServerEndpoint.se.ServerDisco.Compare(newServerEndpoint.wlb.lastBest.relayServerDisco) == 0 + if lastBestMatchingServer && newServerEndpoint.wlb.lastBestIsTrusted { + // This relay server endpoint is the same as [endpoint]'s bestAddr at + // the time UDP relay path discovery was started, and it was also a + // trusted path (see endpoint.trustBestAddrUntil), so return early. + // + // If we were to start a new handshake, there is a chance that we + // cause [endpoint] to blackhole some packets on its bestAddr if we end + // up shifting to a new address family or src, e.g. IPv4 to IPv6, due to + // the window of time between the handshake completing, and our call to + // udpRelayEndpointReady(). The relay server can only forward packets + // from us on a single [epAddr]. + return + } + + // TODO(jwhited): if lastBest is untrusted, consider some strategies + // to reduce the chance we blackhole if it were to transition to + // trusted during/before the new handshake: + // 1. Start by attempting a handshake with only lastBest.epAddr. If + // that fails then try the remaining [epAddr]s. + // 2. Signal bestAddr trust transitions between [endpoint] and + // [relayManager] in order to prevent a handshake from starting + // and/or stop one that is running. + + // We're ready to start a new handshake. + ctx, cancel := context.WithCancel(context.Background()) + work := &relayHandshakeWork{ + wlb: newServerEndpoint.wlb, + se: newServerEndpoint.se, + server: newServerEndpoint.server, + rxDiscoMsgCh: make(chan relayDiscoMsgEvent), + doneCh: make(chan relayEndpointHandshakeWorkDoneEvent, 1), + ctx: ctx, + cancel: cancel, + } + // We must look up byServerDisco again. The previous value may have been + // deleted from the outer map when cleaning up duplicate work. + byServerDisco, ok = r.handshakeWorkByServerDiscoByEndpoint[newServerEndpoint.wlb.ep] + if !ok { + byServerDisco = make(map[key.DiscoPublic]*relayHandshakeWork) + r.handshakeWorkByServerDiscoByEndpoint[newServerEndpoint.wlb.ep] = byServerDisco + } + byServerDisco[newServerEndpoint.se.ServerDisco] = work + r.handshakeWorkByServerDiscoVNI[sdv] = work + + r.handshakeGeneration++ + if r.handshakeGeneration == 0 { // generation must be nonzero + r.handshakeGeneration++ + } + work.handshakeGen = r.handshakeGeneration + + go r.handshakeServerEndpoint(work) +} + +// sendCallMeMaybeVia sends a [disco.CallMeMaybeVia] to ep over DERP. It must be +// called as part of a goroutine independent from runLoop(), for 2 reasons: +// 1. it acquires ep.mu (refer to [relayManager] docs for reasoning) +// 2. it makes a networking syscall, which can introduce unwanted backpressure +func (r *relayManager) sendCallMeMaybeVia(ep *endpoint, se udprelay.ServerEndpoint) { + ep.mu.Lock() + derpAddr := ep.derpAddr + ep.mu.Unlock() + epDisco := ep.disco.Load() + if epDisco == nil || !derpAddr.IsValid() { + return + } + callMeMaybeVia := &disco.CallMeMaybeVia{ + UDPRelayEndpoint: disco.UDPRelayEndpoint{ + ServerDisco: se.ServerDisco, + ClientDisco: se.ClientDisco, + LamportID: se.LamportID, + VNI: se.VNI, + BindLifetime: se.BindLifetime.Duration, + SteadyStateLifetime: se.SteadyStateLifetime.Duration, + AddrPorts: se.AddrPorts, + }, + } + ep.c.sendDiscoMessage(epAddr{ap: derpAddr}, ep.publicKey, epDisco.key, callMeMaybeVia, discoVerboseLog) +} + +func (r *relayManager) handshakeServerEndpoint(work *relayHandshakeWork) { + done := relayEndpointHandshakeWorkDoneEvent{work: work} + r.ensureDiscoInfoFor(work) + + defer func() { + r.derefDiscoInfoFor(work) + work.doneCh <- done + relayManagerInputEvent(r, work.ctx, &r.handshakeWorkDoneCh, done) + work.cancel() + }() + + ep := work.wlb.ep + epDisco := ep.disco.Load() + if epDisco == nil { + return + } + + common := disco.BindUDPRelayEndpointCommon{ + VNI: work.se.VNI, + Generation: work.handshakeGen, + RemoteKey: epDisco.key, + } + + work.dlogf("[v1] magicsock: relayManager: starting handshake addrPorts=%v", + work.se.AddrPorts, + ) + sentBindAny := false + bind := &disco.BindUDPRelayEndpoint{ + BindUDPRelayEndpointCommon: common, + } + vni := packet.VirtualNetworkID{} + vni.Set(work.se.VNI) + for _, addrPort := range work.se.AddrPorts { + if addrPort.IsValid() { + sentBindAny = true + go ep.c.sendDiscoMessage(epAddr{ap: addrPort, vni: vni}, key.NodePublic{}, work.se.ServerDisco, bind, discoVerboseLog) + } + } + if !sentBindAny { + return + } + + // Limit goroutine lifetime to a reasonable duration. This is intentionally + // detached and independent of 'BindLifetime' to prevent relay server + // (mis)configuration from negatively impacting client resource usage. + const maxHandshakeLifetime = time.Second * 30 + timer := time.NewTimer(min(work.se.BindLifetime.Duration, maxHandshakeLifetime)) + defer timer.Stop() + + // Limit the number of pings we will transmit. Inbound pings trigger + // outbound pings, so we want to be a little defensive. + const limitPings = 10 + + var ( + handshakeState disco.BindUDPRelayHandshakeState = disco.BindUDPRelayHandshakeStateBindSent + sentPingAt = make(map[stun.TxID]time.Time) + ) + + txPing := func(to netip.AddrPort, withAnswer *[32]byte) { + if len(sentPingAt) == limitPings { + return + } + txid := stun.NewTxID() + sentPingAt[txid] = time.Now() + ping := &disco.Ping{ + TxID: txid, + NodeKey: ep.c.publicKeyAtomic.Load(), + } + go func() { + if withAnswer != nil { + answer := &disco.BindUDPRelayEndpointAnswer{BindUDPRelayEndpointCommon: common} + answer.Challenge = *withAnswer + ep.c.sendDiscoMessage(epAddr{ap: to, vni: vni}, key.NodePublic{}, work.se.ServerDisco, answer, discoVerboseLog) + } + ep.c.sendDiscoMessage(epAddr{ap: to, vni: vni}, key.NodePublic{}, epDisco.key, ping, discoVerboseLog) + }() + } + + validateVNIAndRemoteKey := func(common disco.BindUDPRelayEndpointCommon) error { + if common.VNI != work.se.VNI { + return errors.New("mismatching VNI") + } + if common.RemoteKey.Compare(epDisco.key) != 0 { + return errors.New("mismatching RemoteKey") + } + return nil + } + + // This for{select{}} is responsible for handshaking and tx'ing ping/pong + // when the handshake is complete. + for { + select { + case <-work.ctx.Done(): + work.dlogf("[v1] magicsock: relayManager: handshake canceled") + return + case msgEvent := <-work.rxDiscoMsgCh: + switch msg := msgEvent.msg.(type) { + case *disco.BindUDPRelayEndpointChallenge: + err := validateVNIAndRemoteKey(msg.BindUDPRelayEndpointCommon) + if err != nil { + continue + } + if handshakeState >= disco.BindUDPRelayHandshakeStateAnswerSent { + continue + } + work.dlogf("[v1] magicsock: relayManager: got handshake challenge from %v", msgEvent.from) + txPing(msgEvent.from, &msg.Challenge) + handshakeState = disco.BindUDPRelayHandshakeStateAnswerSent + case *disco.Ping: + if handshakeState < disco.BindUDPRelayHandshakeStateAnswerSent { + continue + } + work.dlogf("[v1] magicsock: relayManager: got relayed ping from %v", msgEvent.from) + // An inbound ping from the remote peer indicates we completed a + // handshake with the relay server (our answer msg was + // received). Chances are our ping was dropped before the remote + // handshake was complete. We need to rx a pong to determine + // latency, so send another ping. Since the handshake is + // complete we do not need to send an answer in front of this + // one. + // + // We don't need to TX a pong, that was already handled for us + // in handleRxDiscoMsgRunLoop(). + txPing(msgEvent.from, nil) + case *disco.Pong: + at, ok := sentPingAt[msg.TxID] + if !ok { + continue + } + // The relay server endpoint is functional! Record the + // round-trip latency and return. + done.pongReceivedFrom = msgEvent.from + done.latency = time.Since(at) + work.dlogf("[v1] magicsock: relayManager: got relayed pong from %v latency=%v", + msgEvent.from, + done.latency.Round(time.Millisecond), + ) + return + default: + // unexpected message type, silently discard + continue + } + case <-timer.C: + // The handshake timed out. + work.dlogf("[v1] magicsock: relayManager: handshake timed out") + return + } + } +} + +const allocateUDPRelayEndpointRequestTimeout = time.Second * 10 + +func (r *relayManager) allocateServerEndpoint(work *relayEndpointAllocWork) { + done := relayEndpointAllocWorkDoneEvent{work: work} + + defer func() { + work.doneCh <- done + relayManagerInputEvent(r, work.ctx, &r.allocateWorkDoneCh, done) + work.cancel() + }() + + dm := &disco.AllocateUDPRelayEndpointRequest{ + ClientDisco: work.discoKeys.Get(), + Generation: work.allocGen, + } + + sendAllocReq := func() { + work.wlb.ep.c.sendDiscoAllocateUDPRelayEndpointRequest( + epAddr{ + ap: netip.AddrPortFrom(tailcfg.DerpMagicIPAddr, work.candidatePeerRelay.derpHomeRegionID), + }, + work.candidatePeerRelay.nodeKey, + work.candidatePeerRelay.discoKey, + dm, + discoVerboseLog, + ) + work.dlogf("[v1] magicsock: relayManager: sent alloc request") + } + go sendAllocReq() + + returnAfterTimer := time.NewTimer(allocateUDPRelayEndpointRequestTimeout) + defer returnAfterTimer.Stop() + // While connections to DERP are over TCP, they can be lossy on the DERP + // server when data moves between the two independent streams. Also, the + // peer relay server may not be "ready" (see [tailscale.com/net/udprelay.ErrServerNotReady]). + // So, start a timer to retry once if needed. + retryAfterTimer := time.NewTimer(udprelay.ServerRetryAfter) + defer retryAfterTimer.Stop() + + for { + select { + case <-work.ctx.Done(): + work.dlogf("[v1] magicsock: relayManager: alloc request canceled") + return + case <-returnAfterTimer.C: + work.dlogf("[v1] magicsock: relayManager: alloc request timed out") + return + case <-retryAfterTimer.C: + go sendAllocReq() + case resp := <-work.rxDiscoMsgCh: + if resp.Generation != work.allocGen || + !work.discoKeys.Equal(key.NewSortedPairOfDiscoPublic(resp.ClientDisco[0], resp.ClientDisco[1])) { + continue + } + work.dlogf("[v1] magicsock: relayManager: got alloc response") + done.allocated = udprelay.ServerEndpoint{ + ServerDisco: resp.ServerDisco, + ClientDisco: resp.ClientDisco, + LamportID: resp.LamportID, + AddrPorts: resp.AddrPorts, + VNI: resp.VNI, + BindLifetime: tstime.GoDuration{Duration: resp.BindLifetime}, + SteadyStateLifetime: tstime.GoDuration{Duration: resp.SteadyStateLifetime}, + } + return + } + } +} + +func (r *relayManager) allocateAllServersRunLoop(wlb endpointWithLastBest) { + if len(r.serversByNodeKey) == 0 { + return + } + remoteDisco := wlb.ep.disco.Load() + if remoteDisco == nil { + return + } + discoKeys := key.NewSortedPairOfDiscoPublic(wlb.ep.c.discoAtomic.Public(), remoteDisco.key) + for _, v := range r.serversByNodeKey { + byDiscoKeys, ok := r.allocWorkByDiscoKeysByServerNodeKey[v.nodeKey] + if !ok { + byDiscoKeys = make(map[key.SortedPairOfDiscoPublic]*relayEndpointAllocWork) + r.allocWorkByDiscoKeysByServerNodeKey[v.nodeKey] = byDiscoKeys + } else { + _, ok = byDiscoKeys[discoKeys] + if ok { + // If there is an existing key, a disco key collision may have + // occurred across peers ([*endpoint]). Do not overwrite the + // existing work, let it finish. + wlb.ep.c.logf("[unexpected] magicsock: relayManager: suspected disco key collision on server %v for keys: %v", v.nodeKey.ShortString(), discoKeys) + continue + } + } + ctx, cancel := context.WithCancel(context.Background()) + started := &relayEndpointAllocWork{ + wlb: wlb, + discoKeys: discoKeys, + candidatePeerRelay: v, + rxDiscoMsgCh: make(chan *disco.AllocateUDPRelayEndpointResponse), + doneCh: make(chan relayEndpointAllocWorkDoneEvent, 1), + ctx: ctx, + cancel: cancel, + } + byDiscoKeys[discoKeys] = started + byCandidatePeerRelay, ok := r.allocWorkByCandidatePeerRelayByEndpoint[wlb.ep] + if !ok { + byCandidatePeerRelay = make(map[candidatePeerRelay]*relayEndpointAllocWork) + r.allocWorkByCandidatePeerRelayByEndpoint[wlb.ep] = byCandidatePeerRelay + } + byCandidatePeerRelay[v] = started + r.allocGeneration++ + started.allocGen = r.allocGeneration + go r.allocateServerEndpoint(started) + } +} diff --git a/vendor/tailscale.com/wgengine/netlog/logger.go b/vendor/tailscale.com/wgengine/netlog/logger.go deleted file mode 100644 index 3a696b2..0000000 --- a/vendor/tailscale.com/wgengine/netlog/logger.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package netlog provides a logger that monitors a TUN device and -// periodically records any traffic into a log stream. -package netlog - -import ( - "context" - "encoding/json" - "fmt" - "io" - "log" - "net/http" - "net/netip" - "sync" - "time" - - "tailscale.com/health" - "tailscale.com/logpolicy" - "tailscale.com/logtail" - "tailscale.com/net/connstats" - "tailscale.com/net/netmon" - "tailscale.com/net/sockstats" - "tailscale.com/net/tsaddr" - "tailscale.com/tailcfg" - "tailscale.com/types/logid" - "tailscale.com/types/netlogtype" - "tailscale.com/util/multierr" - "tailscale.com/wgengine/router" -) - -// pollPeriod specifies how often to poll for network traffic. -const pollPeriod = 5 * time.Second - -// Device is an abstraction over a tunnel device or a magic socket. -// Both *tstun.Wrapper and *magicsock.Conn implement this interface. -type Device interface { - SetStatistics(*connstats.Statistics) -} - -type noopDevice struct{} - -func (noopDevice) SetStatistics(*connstats.Statistics) {} - -// Logger logs statistics about every connection. -// At present, it only logs connections within a tailscale network. -// Exit node traffic is not logged for privacy reasons. -// The zero value is ready for use. -type Logger struct { - mu sync.Mutex // protects all fields below - - logger *logtail.Logger - stats *connstats.Statistics - tun Device - sock Device - - addrs map[netip.Addr]bool - prefixes map[netip.Prefix]bool -} - -// Running reports whether the logger is running. -func (nl *Logger) Running() bool { - nl.mu.Lock() - defer nl.mu.Unlock() - return nl.logger != nil -} - -var testClient *http.Client - -// Startup starts an asynchronous network logger that monitors -// statistics for the provided tun and/or sock device. -// -// The tun Device captures packets within the tailscale network, -// where at least one address is a tailscale IP address. -// The source is always from the perspective of the current node. -// If one of the other endpoint is not a tailscale IP address, -// then it suggests the use of a subnet router or exit node. -// For example, when using a subnet router, the source address is -// the tailscale IP address of the current node, and -// the destination address is an IP address within the subnet range. -// In contrast, when acting as a subnet router, the source address is -// an IP address within the subnet range, and the destination is a -// tailscale IP address that initiated the subnet proxy connection. -// In this case, the node acting as a subnet router is acting on behalf -// of some remote endpoint within the subnet range. -// The tun is used to populate the VirtualTraffic, SubnetTraffic, -// and ExitTraffic fields in Message. -// -// The sock Device captures packets at the magicsock layer. -// The source is always a tailscale IP address and the destination -// is a non-tailscale IP address to contact for that particular tailscale node. -// The IP protocol and source port are always zero. -// The sock is used to populated the PhysicalTraffic field in Message. -// The netMon parameter is optional; if non-nil it's used to do faster interface lookups. -func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID logid.PrivateID, tun, sock Device, netMon *netmon.Monitor, health *health.Tracker, logExitFlowEnabledEnabled bool) error { - nl.mu.Lock() - defer nl.mu.Unlock() - if nl.logger != nil { - return fmt.Errorf("network logger already running for %v", nl.logger.PrivateID().Public()) - } - - // Startup a log stream to Tailscale's logging service. - logf := log.Printf - httpc := &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, netMon, health, logf)} - if testClient != nil { - httpc = testClient - } - nl.logger = logtail.NewLogger(logtail.Config{ - Collection: "tailtraffic.log.tailscale.io", - PrivateID: nodeLogID, - CopyPrivateID: domainLogID, - Stderr: io.Discard, - CompressLogs: true, - HTTPC: httpc, - // TODO(joetsai): Set Buffer? Use an in-memory buffer for now. - - // Include process sequence numbers to identify missing samples. - IncludeProcID: true, - IncludeProcSequence: true, - }, logf) - nl.logger.SetSockstatsLabel(sockstats.LabelNetlogLogger) - - // Startup a data structure to track per-connection statistics. - // There is a maximum size for individual log messages that logtail - // can upload to the Tailscale log service, so stay below this limit. - const maxLogSize = 256 << 10 - const maxConns = (maxLogSize - netlogtype.MaxMessageJSONSize) / netlogtype.MaxConnectionCountsJSONSize - nl.stats = connstats.NewStatistics(pollPeriod, maxConns, func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts) { - nl.mu.Lock() - addrs := nl.addrs - prefixes := nl.prefixes - nl.mu.Unlock() - recordStatistics(nl.logger, nodeID, start, end, virtual, physical, addrs, prefixes, logExitFlowEnabledEnabled) - }) - - // Register the connection tracker into the TUN device. - if tun == nil { - tun = noopDevice{} - } - nl.tun = tun - nl.tun.SetStatistics(nl.stats) - - // Register the connection tracker into magicsock. - if sock == nil { - sock = noopDevice{} - } - nl.sock = sock - nl.sock.SetStatistics(nl.stats) - - return nil -} - -func recordStatistics(logger *logtail.Logger, nodeID tailcfg.StableNodeID, start, end time.Time, connstats, sockStats map[netlogtype.Connection]netlogtype.Counts, addrs map[netip.Addr]bool, prefixes map[netip.Prefix]bool, logExitFlowEnabled bool) { - m := netlogtype.Message{NodeID: nodeID, Start: start.UTC(), End: end.UTC()} - - classifyAddr := func(a netip.Addr) (isTailscale, withinRoute bool) { - // NOTE: There could be mis-classifications where an address is treated - // as a Tailscale IP address because the subnet range overlaps with - // the subnet range that Tailscale IP addresses are allocated from. - // This should never happen for IPv6, but could happen for IPv4. - withinRoute = addrs[a] - for p := range prefixes { - if p.Contains(a) && p.Bits() > 0 { - withinRoute = true - break - } - } - return withinRoute && tsaddr.IsTailscaleIP(a), withinRoute && !tsaddr.IsTailscaleIP(a) - } - - exitTraffic := make(map[netlogtype.Connection]netlogtype.Counts) - for conn, cnts := range connstats { - srcIsTailscaleIP, srcWithinSubnet := classifyAddr(conn.Src.Addr()) - dstIsTailscaleIP, dstWithinSubnet := classifyAddr(conn.Dst.Addr()) - switch { - case srcIsTailscaleIP && dstIsTailscaleIP: - m.VirtualTraffic = append(m.VirtualTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) - case srcWithinSubnet || dstWithinSubnet: - m.SubnetTraffic = append(m.SubnetTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) - default: - const anonymize = true - if anonymize && !logExitFlowEnabled { - // Only preserve the address if it is a Tailscale IP address. - srcOrig, dstOrig := conn.Src, conn.Dst - conn = netlogtype.Connection{} // scrub everything by default - if srcIsTailscaleIP { - conn.Src = netip.AddrPortFrom(srcOrig.Addr(), 0) - } - if dstIsTailscaleIP { - conn.Dst = netip.AddrPortFrom(dstOrig.Addr(), 0) - } - } - exitTraffic[conn] = exitTraffic[conn].Add(cnts) - } - } - for conn, cnts := range exitTraffic { - m.ExitTraffic = append(m.ExitTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) - } - for conn, cnts := range sockStats { - m.PhysicalTraffic = append(m.PhysicalTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) - } - - if len(m.VirtualTraffic)+len(m.SubnetTraffic)+len(m.ExitTraffic)+len(m.PhysicalTraffic) > 0 { - if b, err := json.Marshal(m); err != nil { - logger.Logf("json.Marshal error: %v", err) - } else { - logger.Logf("%s", b) - } - } -} - -func makeRouteMaps(cfg *router.Config) (addrs map[netip.Addr]bool, prefixes map[netip.Prefix]bool) { - addrs = make(map[netip.Addr]bool) - for _, p := range cfg.LocalAddrs { - if p.IsSingleIP() { - addrs[p.Addr()] = true - } - } - prefixes = make(map[netip.Prefix]bool) - insertPrefixes := func(rs []netip.Prefix) { - for _, p := range rs { - if p.IsSingleIP() { - addrs[p.Addr()] = true - } else { - prefixes[p] = true - } - } - } - insertPrefixes(cfg.Routes) - insertPrefixes(cfg.SubnetRoutes) - return addrs, prefixes -} - -// ReconfigRoutes configures the network logger with updated routes. -// The cfg is used to classify the types of connections captured by -// the tun Device passed to Startup. -func (nl *Logger) ReconfigRoutes(cfg *router.Config) { - nl.mu.Lock() - defer nl.mu.Unlock() - // TODO(joetsai): There is a race where deleted routes are not known at - // the time of extraction. We need to keep old routes around for a bit. - nl.addrs, nl.prefixes = makeRouteMaps(cfg) -} - -// Shutdown shuts down the network logger. -// This attempts to flush out all pending log messages. -// Even if an error is returned, the logger is still shut down. -func (nl *Logger) Shutdown(ctx context.Context) error { - nl.mu.Lock() - defer nl.mu.Unlock() - if nl.logger == nil { - return nil - } - - // Shutdown in reverse order of Startup. - // Do not hold lock while shutting down since this may flush one last time. - nl.mu.Unlock() - nl.sock.SetStatistics(nil) - nl.tun.SetStatistics(nil) - err1 := nl.stats.Shutdown(ctx) - err2 := nl.logger.Shutdown(ctx) - nl.mu.Lock() - - // Purge state. - nl.logger = nil - nl.stats = nil - nl.tun = nil - nl.sock = nil - nl.addrs = nil - nl.prefixes = nil - - return multierr.New(err1, err2) -} diff --git a/vendor/tailscale.com/wgengine/netlog/netlog.go b/vendor/tailscale.com/wgengine/netlog/netlog.go new file mode 100644 index 0000000..12fe9c7 --- /dev/null +++ b/vendor/tailscale.com/wgengine/netlog/netlog.go @@ -0,0 +1,494 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_netlog && !ts_omit_logtail + +// Package netlog provides a logger that monitors a TUN device and +// periodically records any traffic into a log stream. +package netlog + +import ( + "cmp" + "context" + "fmt" + "io" + "log" + "net/http" + "net/netip" + "time" + + "tailscale.com/health" + "tailscale.com/logpolicy" + "tailscale.com/logtail" + "tailscale.com/net/netmon" + "tailscale.com/net/sockstats" + "tailscale.com/net/tsaddr" + "tailscale.com/syncs" + "tailscale.com/types/ipproto" + "tailscale.com/types/logger" + "tailscale.com/types/logid" + "tailscale.com/types/netlogfunc" + "tailscale.com/types/netlogtype" + "tailscale.com/types/netmap" + "tailscale.com/util/eventbus" + "tailscale.com/util/set" + "tailscale.com/wgengine/router" + + jsonv2 "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" +) + +// pollPeriod specifies how often to poll for network traffic. +const pollPeriod = 5 * time.Second + +// Device is an abstraction over a tunnel device or a magic socket. +// Both *tstun.Wrapper and *magicsock.Conn implement this interface. +type Device interface { + SetConnectionCounter(netlogfunc.ConnectionCounter) +} + +type noopDevice struct{} + +func (noopDevice) SetConnectionCounter(netlogfunc.ConnectionCounter) {} + +// Logger logs statistics about every connection. +// At present, it only logs connections within a tailscale network. +// By default, exit node traffic is not logged for privacy reasons +// unless the Tailnet administrator opts-into explicit logging. +// The zero value is ready for use. +type Logger struct { + mu syncs.Mutex // protects all fields below + logf logger.Logf + + // shutdownLocked shuts down the logger. + // The mutex must be held when calling. + shutdownLocked func(context.Context) error + + record record // the current record of network connection flows + recordLen int // upper bound on JSON length of record + recordsChan chan record // set to nil when shutdown + flushTimer *time.Timer // fires when record should flush to recordsChan + + // Information about Tailscale nodes. + // These are read-only once updated by ReconfigNetworkMap. + selfNode nodeUser + allNodes map[netip.Addr]nodeUser // includes selfNode; nodeUser values are always valid + + // Information about routes. + // These are read-only once updated by ReconfigRoutes. + routeAddrs set.Set[netip.Addr] + routePrefixes []netip.Prefix +} + +// Running reports whether the logger is running. +func (nl *Logger) Running() bool { + nl.mu.Lock() + defer nl.mu.Unlock() + return nl.shutdownLocked != nil +} + +var testClient *http.Client + +// Startup starts an asynchronous network logger that monitors +// statistics for the provided tun and/or sock device. +// +// The tun [Device] captures packets within the tailscale network, +// where at least one address is usually a tailscale IP address. +// The source is usually from the perspective of the current node. +// If one of the other endpoint is not a tailscale IP address, +// then it suggests the use of a subnet router or exit node. +// For example, when using a subnet router, the source address is +// the tailscale IP address of the current node, and +// the destination address is an IP address within the subnet range. +// In contrast, when acting as a subnet router, the source address is +// an IP address within the subnet range, and the destination is a +// tailscale IP address that initiated the subnet proxy connection. +// In this case, the node acting as a subnet router is acting on behalf +// of some remote endpoint within the subnet range. +// The tun is used to populate the VirtualTraffic, SubnetTraffic, +// and ExitTraffic fields in [netlogtype.Message]. +// +// The sock [Device] captures packets at the magicsock layer. +// The source is always a tailscale IP address and the destination +// is a non-tailscale IP address to contact for that particular tailscale node. +// The IP protocol and source port are always zero. +// The sock is used to populated the PhysicalTraffic field in [netlogtype.Message]. +// +// The netMon parameter is optional; if non-nil it's used to do faster interface lookups. +func (nl *Logger) Startup(logf logger.Logf, nm *netmap.NetworkMap, nodeLogID, domainLogID logid.PrivateID, tun, sock Device, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus, logExitFlowEnabledEnabled bool) error { + nl.mu.Lock() + defer nl.mu.Unlock() + + if nl.shutdownLocked != nil { + return fmt.Errorf("network logger already running") + } + nl.selfNode, nl.allNodes = makeNodeMaps(nm) + + // Startup a log stream to Tailscale's logging service. + if logf == nil { + logf = log.Printf + } + httpc := &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, netMon, health, logf)} + if testClient != nil { + httpc = testClient + } + logger := logtail.NewLogger(logtail.Config{ + Collection: "tailtraffic.log.tailscale.io", + PrivateID: nodeLogID, + CopyPrivateID: domainLogID, + Bus: bus, + Stderr: io.Discard, + CompressLogs: true, + HTTPC: httpc, + // TODO(joetsai): Set Buffer? Use an in-memory buffer for now. + + // Include process sequence numbers to identify missing samples. + IncludeProcID: true, + IncludeProcSequence: true, + }, logf) + logger.SetSockstatsLabel(sockstats.LabelNetlogLogger) + + // Register the connection tracker into the TUN device. + tun = cmp.Or[Device](tun, noopDevice{}) + tun.SetConnectionCounter(nl.updateVirtConn) + + // Register the connection tracker into magicsock. + sock = cmp.Or[Device](sock, noopDevice{}) + sock.SetConnectionCounter(nl.updatePhysConn) + + // Startup a goroutine to record log messages. + // This is done asynchronously so that the cost of serializing + // the network flow log message never stalls processing of packets. + nl.record = record{} + nl.recordLen = 0 + nl.recordsChan = make(chan record, 100) + recorderDone := make(chan struct{}) + go func(recordsChan chan record) { + defer close(recorderDone) + for rec := range recordsChan { + msg := rec.toMessage(false, !logExitFlowEnabledEnabled) + if b, err := jsonv2.Marshal(msg, jsontext.AllowInvalidUTF8(true)); err != nil { + if nl.logf != nil { + nl.logf("netlog: json.Marshal error: %v", err) + } + } else { + logger.Logf("%s", b) + } + } + }(nl.recordsChan) + + // Register the mechanism for shutting down. + nl.shutdownLocked = func(ctx context.Context) error { + tun.SetConnectionCounter(nil) + sock.SetConnectionCounter(nil) + + // Flush and process all pending records. + nl.flushRecordLocked() + close(nl.recordsChan) + nl.recordsChan = nil + <-recorderDone + recorderDone = nil + + // Try to upload all pending records. + err := logger.Shutdown(ctx) + + // Purge state. + nl.shutdownLocked = nil + nl.selfNode = nodeUser{} + nl.allNodes = nil + nl.routeAddrs = nil + nl.routePrefixes = nil + + return err + } + + return nil +} + +var ( + tailscaleServiceIPv4 = tsaddr.TailscaleServiceIP() + tailscaleServiceIPv6 = tsaddr.TailscaleServiceIPv6() +) + +func (nl *Logger) updateVirtConn(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, recv bool) { + // Network logging is defined as traffic between two Tailscale nodes. + // Traffic with the internal Tailscale service is not with another node + // and should not be logged. It also happens to be a high volume + // amount of discrete traffic flows (e.g., DNS lookups). + switch dst.Addr() { + case tailscaleServiceIPv4, tailscaleServiceIPv6: + return + } + + nl.mu.Lock() + defer nl.mu.Unlock() + + // Lookup the connection and increment the counts. + nl.initRecordLocked() + conn := netlogtype.Connection{Proto: proto, Src: src, Dst: dst} + cnts, found := nl.record.virtConns[conn] + if !found { + cnts.connType = nl.addNewVirtConnLocked(conn) + } + if recv { + cnts.RxPackets += uint64(packets) + cnts.RxBytes += uint64(bytes) + } else { + cnts.TxPackets += uint64(packets) + cnts.TxBytes += uint64(bytes) + } + nl.record.virtConns[conn] = cnts +} + +// addNewVirtConnLocked adds the first insertion of a physical connection. +// The [Logger.mu] must be held. +func (nl *Logger) addNewVirtConnLocked(c netlogtype.Connection) connType { + // Check whether this is the first insertion of the src and dst node. + // If so, compute the additional JSON bytes that would be added + // to the record for the node information. + var srcNodeLen, dstNodeLen int + srcNode, srcSeen := nl.record.seenNodes[c.Src.Addr()] + if !srcSeen { + srcNode = nl.allNodes[c.Src.Addr()] + if srcNode.Valid() { + srcNodeLen = srcNode.jsonLen() + } + } + dstNode, dstSeen := nl.record.seenNodes[c.Dst.Addr()] + if !dstSeen { + dstNode = nl.allNodes[c.Dst.Addr()] + if dstNode.Valid() { + dstNodeLen = dstNode.jsonLen() + } + } + + // Check whether the additional [netlogtype.ConnectionCounts] + // and [netlogtype.Node] information would exceed [maxLogSize]. + if nl.recordLen+netlogtype.MaxConnectionCountsJSONSize+srcNodeLen+dstNodeLen > maxLogSize { + nl.flushRecordLocked() + nl.initRecordLocked() + } + + // Insert newly seen src and/or dst nodes. + if !srcSeen && srcNode.Valid() { + nl.record.seenNodes[c.Src.Addr()] = srcNode + } + if !dstSeen && dstNode.Valid() { + nl.record.seenNodes[c.Dst.Addr()] = dstNode + } + nl.recordLen += netlogtype.MaxConnectionCountsJSONSize + srcNodeLen + dstNodeLen + + // Classify the traffic type. + var srcIsSelfNode bool + if nl.selfNode.Valid() { + srcIsSelfNode = nl.selfNode.Addresses().ContainsFunc(func(p netip.Prefix) bool { + return c.Src.Addr() == p.Addr() && p.IsSingleIP() + }) + } + switch { + case srcIsSelfNode && dstNode.Valid(): + return virtualTraffic + case srcIsSelfNode: + // TODO: Should we swap src for the node serving as the proxy? + // It is relatively useless always using the self IP address. + if nl.withinRoutesLocked(c.Dst.Addr()) { + return subnetTraffic // a client using another subnet router + } else { + return exitTraffic // a client using exit an exit node + } + case dstNode.Valid(): + if nl.withinRoutesLocked(c.Src.Addr()) { + return subnetTraffic // serving as a subnet router + } else { + return exitTraffic // serving as an exit node + } + default: + return unknownTraffic + } +} + +func (nl *Logger) updatePhysConn(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, recv bool) { + nl.mu.Lock() + defer nl.mu.Unlock() + + // Lookup the connection and increment the counts. + nl.initRecordLocked() + conn := netlogtype.Connection{Proto: proto, Src: src, Dst: dst} + cnts, found := nl.record.physConns[conn] + if !found { + nl.addNewPhysConnLocked(conn) + } + if recv { + cnts.RxPackets += uint64(packets) + cnts.RxBytes += uint64(bytes) + } else { + cnts.TxPackets += uint64(packets) + cnts.TxBytes += uint64(bytes) + } + nl.record.physConns[conn] = cnts +} + +// addNewPhysConnLocked adds the first insertion of a physical connection. +// The [Logger.mu] must be held. +func (nl *Logger) addNewPhysConnLocked(c netlogtype.Connection) { + // Check whether this is the first insertion of the src node. + var srcNodeLen int + srcNode, srcSeen := nl.record.seenNodes[c.Src.Addr()] + if !srcSeen { + srcNode = nl.allNodes[c.Src.Addr()] + if srcNode.Valid() { + srcNodeLen = srcNode.jsonLen() + } + } + + // Check whether the additional [netlogtype.ConnectionCounts] + // and [netlogtype.Node] information would exceed [maxLogSize]. + if nl.recordLen+netlogtype.MaxConnectionCountsJSONSize+srcNodeLen > maxLogSize { + nl.flushRecordLocked() + nl.initRecordLocked() + } + + // Insert newly seen src and/or dst nodes. + if !srcSeen && srcNode.Valid() { + nl.record.seenNodes[c.Src.Addr()] = srcNode + } + nl.recordLen += netlogtype.MaxConnectionCountsJSONSize + srcNodeLen +} + +// initRecordLocked initialize the current record if uninitialized. +// The [Logger.mu] must be held. +func (nl *Logger) initRecordLocked() { + if nl.recordLen != 0 { + return + } + nl.record = record{ + selfNode: nl.selfNode, + start: time.Now().UTC(), + seenNodes: make(map[netip.Addr]nodeUser), + virtConns: make(map[netlogtype.Connection]countsType), + physConns: make(map[netlogtype.Connection]netlogtype.Counts), + } + nl.recordLen = netlogtype.MinMessageJSONSize + nl.selfNode.jsonLen() + + // Start a time to auto-flush the record. + // Avoid tickers since continually waking up a goroutine + // is expensive on battery powered devices. + nl.flushTimer = time.AfterFunc(pollPeriod, func() { + nl.mu.Lock() + defer nl.mu.Unlock() + if !nl.record.start.IsZero() && time.Since(nl.record.start) > pollPeriod/2 { + nl.flushRecordLocked() + } + }) +} + +// flushRecordLocked flushes the current record if initialized. +// The [Logger.mu] must be held. +func (nl *Logger) flushRecordLocked() { + if nl.recordLen == 0 { + return + } + nl.record.end = time.Now().UTC() + if nl.recordsChan != nil { + select { + case nl.recordsChan <- nl.record: + default: + if nl.logf != nil { + nl.logf("netlog: dropped record due to processing backlog") + } + } + } + if nl.flushTimer != nil { + nl.flushTimer.Stop() + nl.flushTimer = nil + } + nl.record = record{} + nl.recordLen = 0 +} + +func makeNodeMaps(nm *netmap.NetworkMap) (selfNode nodeUser, allNodes map[netip.Addr]nodeUser) { + if nm == nil { + return + } + allNodes = make(map[netip.Addr]nodeUser) + if nm.SelfNode.Valid() { + selfNode = nodeUser{nm.SelfNode, nm.UserProfiles[nm.SelfNode.User()]} + for _, addr := range nm.SelfNode.Addresses().All() { + if addr.IsSingleIP() { + allNodes[addr.Addr()] = selfNode + } + } + } + for _, peer := range nm.Peers { + if peer.Valid() { + for _, addr := range peer.Addresses().All() { + if addr.IsSingleIP() { + allNodes[addr.Addr()] = nodeUser{peer, nm.UserProfiles[peer.User()]} + } + } + } + } + return selfNode, allNodes +} + +// ReconfigNetworkMap configures the network logger with an updated netmap. +func (nl *Logger) ReconfigNetworkMap(nm *netmap.NetworkMap) { + selfNode, allNodes := makeNodeMaps(nm) // avoid holding lock while making maps + nl.mu.Lock() + nl.selfNode, nl.allNodes = selfNode, allNodes + nl.mu.Unlock() +} + +func makeRouteMaps(cfg *router.Config) (addrs set.Set[netip.Addr], prefixes []netip.Prefix) { + addrs = make(set.Set[netip.Addr]) + insertPrefixes := func(rs []netip.Prefix) { + for _, p := range rs { + if p.IsSingleIP() { + addrs.Add(p.Addr()) + } else { + prefixes = append(prefixes, p) + } + } + } + insertPrefixes(cfg.LocalAddrs) + insertPrefixes(cfg.Routes) + insertPrefixes(cfg.SubnetRoutes) + return addrs, prefixes +} + +// ReconfigRoutes configures the network logger with updated routes. +// The cfg is used to classify the types of connections captured by +// the tun Device passed to Startup. +func (nl *Logger) ReconfigRoutes(cfg *router.Config) { + addrs, prefixes := makeRouteMaps(cfg) // avoid holding lock while making maps + nl.mu.Lock() + nl.routeAddrs, nl.routePrefixes = addrs, prefixes + nl.mu.Unlock() +} + +// withinRoutesLocked reports whether a is within the configured routes, +// which should only contain Tailscale addresses and subnet routes. +// The [Logger.mu] must be held. +func (nl *Logger) withinRoutesLocked(a netip.Addr) bool { + if nl.routeAddrs.Contains(a) { + return true + } + for _, p := range nl.routePrefixes { + if p.Contains(a) && p.Bits() > 0 { + return true + } + } + return false +} + +// Shutdown shuts down the network logger. +// This attempts to flush out all pending log messages. +// Even if an error is returned, the logger is still shut down. +func (nl *Logger) Shutdown(ctx context.Context) error { + nl.mu.Lock() + defer nl.mu.Unlock() + if nl.shutdownLocked == nil { + return nil + } + return nl.shutdownLocked(ctx) +} diff --git a/vendor/tailscale.com/wgengine/netlog/netlog_omit.go b/vendor/tailscale.com/wgengine/netlog/netlog_omit.go new file mode 100644 index 0000000..03610a1 --- /dev/null +++ b/vendor/tailscale.com/wgengine/netlog/netlog_omit.go @@ -0,0 +1,14 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_netlog || ts_omit_logtail + +package netlog + +type Logger struct{} + +func (*Logger) Startup(...any) error { return nil } +func (*Logger) Running() bool { return false } +func (*Logger) Shutdown(any) error { return nil } +func (*Logger) ReconfigNetworkMap(any) {} +func (*Logger) ReconfigRoutes(any) {} diff --git a/vendor/tailscale.com/wgengine/netlog/record.go b/vendor/tailscale.com/wgengine/netlog/record.go new file mode 100644 index 0000000..25b6b11 --- /dev/null +++ b/vendor/tailscale.com/wgengine/netlog/record.go @@ -0,0 +1,218 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build !ts_omit_netlog && !ts_omit_logtail + +package netlog + +import ( + "cmp" + "net/netip" + "slices" + "strings" + "time" + "unicode/utf8" + + "tailscale.com/tailcfg" + "tailscale.com/types/bools" + "tailscale.com/types/netlogtype" + "tailscale.com/util/set" +) + +// maxLogSize is the maximum number of bytes for a log message. +const maxLogSize = 256 << 10 + +// record is the in-memory representation of a [netlogtype.Message]. +// It uses maps to efficiently look-up addresses and connections. +// In contrast, [netlogtype.Message] is designed to be JSON serializable, +// where complex keys types are not well support in JSON objects. +type record struct { + selfNode nodeUser + + start time.Time + end time.Time + + seenNodes map[netip.Addr]nodeUser + + virtConns map[netlogtype.Connection]countsType + physConns map[netlogtype.Connection]netlogtype.Counts +} + +// nodeUser is a node with additional user profile information. +type nodeUser struct { + tailcfg.NodeView + user tailcfg.UserProfileView // UserProfileView for NodeView.User +} + +// countsType is a counts with classification information about the connection. +type countsType struct { + netlogtype.Counts + connType connType +} + +type connType uint8 + +const ( + unknownTraffic connType = iota + virtualTraffic + subnetTraffic + exitTraffic +) + +// toMessage converts a [record] into a [netlogtype.Message]. +func (r record) toMessage(excludeNodeInfo, anonymizeExitTraffic bool) netlogtype.Message { + if !r.selfNode.Valid() { + return netlogtype.Message{} + } + + m := netlogtype.Message{ + NodeID: r.selfNode.StableID(), + Start: r.start.UTC(), + End: r.end.UTC(), + } + + // Convert node fields. + if !excludeNodeInfo { + m.SrcNode = r.selfNode.toNode() + seenIDs := set.Of(r.selfNode.ID()) + for _, node := range r.seenNodes { + if _, ok := seenIDs[node.ID()]; !ok && node.Valid() { + m.DstNodes = append(m.DstNodes, node.toNode()) + seenIDs.Add(node.ID()) + } + } + slices.SortFunc(m.DstNodes, func(x, y netlogtype.Node) int { + return cmp.Compare(x.NodeID, y.NodeID) + }) + } + + // Converter traffic fields. + anonymizedExitTraffic := make(map[netlogtype.Connection]netlogtype.Counts) + for conn, cnts := range r.virtConns { + switch cnts.connType { + case virtualTraffic: + m.VirtualTraffic = append(m.VirtualTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts.Counts}) + case subnetTraffic: + m.SubnetTraffic = append(m.SubnetTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts.Counts}) + default: + if anonymizeExitTraffic { + conn = netlogtype.Connection{ // scrub the IP protocol type + Src: netip.AddrPortFrom(conn.Src.Addr(), 0), // scrub the port number + Dst: netip.AddrPortFrom(conn.Dst.Addr(), 0), // scrub the port number + } + if !r.seenNodes[conn.Src.Addr()].Valid() { + conn.Src = netip.AddrPort{} // not a Tailscale node, so scrub the address + } + if !r.seenNodes[conn.Dst.Addr()].Valid() { + conn.Dst = netip.AddrPort{} // not a Tailscale node, so scrub the address + } + anonymizedExitTraffic[conn] = anonymizedExitTraffic[conn].Add(cnts.Counts) + continue + } + m.ExitTraffic = append(m.ExitTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts.Counts}) + } + } + for conn, cnts := range anonymizedExitTraffic { + m.ExitTraffic = append(m.ExitTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) + } + for conn, cnts := range r.physConns { + m.PhysicalTraffic = append(m.PhysicalTraffic, netlogtype.ConnectionCounts{Connection: conn, Counts: cnts}) + } + + // Sort the connections for deterministic results. + slices.SortFunc(m.VirtualTraffic, compareConnCnts) + slices.SortFunc(m.SubnetTraffic, compareConnCnts) + slices.SortFunc(m.ExitTraffic, compareConnCnts) + slices.SortFunc(m.PhysicalTraffic, compareConnCnts) + + return m +} + +func compareConnCnts(x, y netlogtype.ConnectionCounts) int { + return cmp.Or( + netip.AddrPort.Compare(x.Src, y.Src), + netip.AddrPort.Compare(x.Dst, y.Dst), + cmp.Compare(x.Proto, y.Proto)) +} + +// jsonLen computes an upper-bound on the size of the JSON representation. +func (nu nodeUser) jsonLen() (n int) { + if !nu.Valid() { + return len(`{"nodeId":""}`) + } + n += len(`{}`) + n += len(`"nodeId":`) + jsonQuotedLen(string(nu.StableID())) + len(`,`) + if len(nu.Name()) > 0 { + n += len(`"name":`) + jsonQuotedLen(nu.Name()) + len(`,`) + } + if nu.Addresses().Len() > 0 { + n += len(`"addresses":[]`) + for _, addr := range nu.Addresses().All() { + n += bools.IfElse(addr.Addr().Is4(), len(`"255.255.255.255"`), len(`"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"`)) + len(",") + } + } + if nu.Hostinfo().Valid() && len(nu.Hostinfo().OS()) > 0 { + n += len(`"os":`) + jsonQuotedLen(nu.Hostinfo().OS()) + len(`,`) + } + if nu.Tags().Len() > 0 { + n += len(`"tags":[]`) + for _, tag := range nu.Tags().All() { + n += jsonQuotedLen(tag) + len(",") + } + } else if nu.user.Valid() && nu.user.ID() == nu.User() && len(nu.user.LoginName()) > 0 { + n += len(`"user":`) + jsonQuotedLen(nu.user.LoginName()) + len(",") + } + return n +} + +// toNode converts the [nodeUser] into a [netlogtype.Node]. +func (nu nodeUser) toNode() netlogtype.Node { + if !nu.Valid() { + return netlogtype.Node{} + } + n := netlogtype.Node{ + NodeID: nu.StableID(), + Name: strings.TrimSuffix(nu.Name(), "."), + } + var ipv4, ipv6 netip.Addr + for _, addr := range nu.Addresses().All() { + switch { + case addr.IsSingleIP() && addr.Addr().Is4(): + ipv4 = addr.Addr() + case addr.IsSingleIP() && addr.Addr().Is6(): + ipv6 = addr.Addr() + } + } + n.Addresses = []netip.Addr{ipv4, ipv6} + n.Addresses = slices.DeleteFunc(n.Addresses, func(a netip.Addr) bool { return !a.IsValid() }) + if nu.Hostinfo().Valid() { + n.OS = nu.Hostinfo().OS() + } + if nu.Tags().Len() > 0 { + n.Tags = nu.Tags().AsSlice() + slices.Sort(n.Tags) + n.Tags = slices.Compact(n.Tags) + } else if nu.user.Valid() && nu.user.ID() == nu.User() { + n.User = nu.user.LoginName() + } + return n +} + +// jsonQuotedLen computes the length of the JSON serialization of s +// according to [jsontext.AppendQuote]. +func jsonQuotedLen(s string) int { + n := len(`"`) + len(s) + len(`"`) + for i, r := range s { + switch { + case r == '\b', r == '\t', r == '\n', r == '\f', r == '\r', r == '"', r == '\\': + n += len(`\X`) - 1 + case r < ' ': + n += len(`\uXXXX`) - 1 + case r == utf8.RuneError: + if _, m := utf8.DecodeRuneInString(s[i:]); m == 1 { // exactly an invalid byte + n += len("�") - 1 + } + } + } + return n +} diff --git a/vendor/tailscale.com/wgengine/netstack/gro/gro.go b/vendor/tailscale.com/wgengine/netstack/gro/gro.go index 654d170..c8e5e56 100644 --- a/vendor/tailscale.com/wgengine/netstack/gro/gro.go +++ b/vendor/tailscale.com/wgengine/netstack/gro/gro.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_netstack + // Package gro implements GRO for the receive (write) path into gVisor. package gro diff --git a/vendor/tailscale.com/wgengine/netstack/gro/gro_default.go b/vendor/tailscale.com/wgengine/netstack/gro/gro_default.go index f92ee15..c70e19f 100644 --- a/vendor/tailscale.com/wgengine/netstack/gro/gro_default.go +++ b/vendor/tailscale.com/wgengine/netstack/gro/gro_default.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !ios +//go:build !ios && !ts_omit_gro package gro diff --git a/vendor/tailscale.com/wgengine/netstack/gro/gro_ios.go b/vendor/tailscale.com/wgengine/netstack/gro/gro_disabled.go similarity index 59% rename from vendor/tailscale.com/wgengine/netstack/gro/gro_ios.go rename to vendor/tailscale.com/wgengine/netstack/gro/gro_disabled.go index 627b42d..d7ffbd9 100644 --- a/vendor/tailscale.com/wgengine/netstack/gro/gro_ios.go +++ b/vendor/tailscale.com/wgengine/netstack/gro/gro_disabled.go @@ -1,22 +1,27 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build ios +//go:build ios || ts_omit_gro package gro import ( - "gvisor.dev/gvisor/pkg/tcpip/stack" + "runtime" + "tailscale.com/net/packet" ) type GRO struct{} func NewGRO() *GRO { - panic("unsupported on iOS") + if runtime.GOOS == "ios" { + panic("unsupported on iOS") + } + panic("GRO disabled in build") + } -func (g *GRO) SetDispatcher(_ stack.NetworkDispatcher) {} +func (g *GRO) SetDispatcher(any) {} func (g *GRO) Enqueue(_ *packet.Parsed) {} diff --git a/vendor/tailscale.com/clientupdate/clientupdate_notwindows.go b/vendor/tailscale.com/wgengine/netstack/gro/netstack_disabled.go similarity index 56% rename from vendor/tailscale.com/clientupdate/clientupdate_notwindows.go rename to vendor/tailscale.com/wgengine/netstack/gro/netstack_disabled.go index edadc21..a0f56fa 100644 --- a/vendor/tailscale.com/clientupdate/clientupdate_notwindows.go +++ b/vendor/tailscale.com/wgengine/netstack/gro/netstack_disabled.go @@ -1,10 +1,10 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !windows +//go:build ts_omit_netstack -package clientupdate +package gro -func (up *Updater) updateWindows() error { +func RXChecksumOffload(any) any { panic("unreachable") } diff --git a/vendor/tailscale.com/wgengine/netstack/link_endpoint.go b/vendor/tailscale.com/wgengine/netstack/link_endpoint.go index 39da64b..c5a9dbc 100644 --- a/vendor/tailscale.com/wgengine/netstack/link_endpoint.go +++ b/vendor/tailscale.com/wgengine/netstack/link_endpoint.go @@ -10,6 +10,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/stack" + "tailscale.com/feature/buildfeatures" "tailscale.com/net/packet" "tailscale.com/types/ipproto" "tailscale.com/wgengine/netstack/gro" @@ -125,24 +126,24 @@ func newLinkEndpoint(size int, mtu uint32, linkAddr tcpip.LinkAddress, supported return le } -// gro attempts to enqueue p on g if l supports a GRO kind matching the +// gro attempts to enqueue p on g if ep supports a GRO kind matching the // transport protocol carried in p. gro may allocate g if it is nil. gro can // either return the existing g, a newly allocated one, or nil. Callers are // responsible for calling Flush() on the returned value if it is non-nil once // they have finished iterating through all GRO candidates for a given vector. -// If gro allocates a *gro.GRO it will have l's stack.NetworkDispatcher set via +// If gro allocates a *gro.GRO it will have ep's stack.NetworkDispatcher set via // SetDispatcher(). -func (l *linkEndpoint) gro(p *packet.Parsed, g *gro.GRO) *gro.GRO { - if l.supportedGRO == groNotSupported || p.IPProto != ipproto.TCP { +func (ep *linkEndpoint) gro(p *packet.Parsed, g *gro.GRO) *gro.GRO { + if !buildfeatures.HasGRO || ep.supportedGRO == groNotSupported || p.IPProto != ipproto.TCP { // IPv6 may have extension headers preceding a TCP header, but we trade // for a fast path and assume p cannot be coalesced in such a case. - l.injectInbound(p) + ep.injectInbound(p) return g } if g == nil { - l.mu.RLock() - d := l.dispatcher - l.mu.RUnlock() + ep.mu.RLock() + d := ep.dispatcher + ep.mu.RUnlock() g = gro.NewGRO() g.SetDispatcher(d) } @@ -153,40 +154,40 @@ func (l *linkEndpoint) gro(p *packet.Parsed, g *gro.GRO) *gro.GRO { // Close closes l. Further packet injections will return an error, and all // pending packets are discarded. Close may be called concurrently with // WritePackets. -func (l *linkEndpoint) Close() { - l.mu.Lock() - l.dispatcher = nil - l.mu.Unlock() - l.q.Close() - l.Drain() +func (ep *linkEndpoint) Close() { + ep.mu.Lock() + ep.dispatcher = nil + ep.mu.Unlock() + ep.q.Close() + ep.Drain() } // Read does non-blocking read one packet from the outbound packet queue. -func (l *linkEndpoint) Read() *stack.PacketBuffer { - return l.q.Read() +func (ep *linkEndpoint) Read() *stack.PacketBuffer { + return ep.q.Read() } // ReadContext does blocking read for one packet from the outbound packet queue. // It can be cancelled by ctx, and in this case, it returns nil. -func (l *linkEndpoint) ReadContext(ctx context.Context) *stack.PacketBuffer { - return l.q.ReadContext(ctx) +func (ep *linkEndpoint) ReadContext(ctx context.Context) *stack.PacketBuffer { + return ep.q.ReadContext(ctx) } // Drain removes all outbound packets from the channel and counts them. -func (l *linkEndpoint) Drain() int { - return l.q.Drain() +func (ep *linkEndpoint) Drain() int { + return ep.q.Drain() } // NumQueued returns the number of packets queued for outbound. -func (l *linkEndpoint) NumQueued() int { - return l.q.Num() +func (ep *linkEndpoint) NumQueued() int { + return ep.q.Num() } -func (l *linkEndpoint) injectInbound(p *packet.Parsed) { - l.mu.RLock() - d := l.dispatcher - l.mu.RUnlock() - if d == nil { +func (ep *linkEndpoint) injectInbound(p *packet.Parsed) { + ep.mu.RLock() + d := ep.dispatcher + ep.mu.RUnlock() + if d == nil || !buildfeatures.HasNetstack { return } pkt := gro.RXChecksumOffload(p) @@ -199,35 +200,35 @@ func (l *linkEndpoint) injectInbound(p *packet.Parsed) { // Attach saves the stack network-layer dispatcher for use later when packets // are injected. -func (l *linkEndpoint) Attach(dispatcher stack.NetworkDispatcher) { - l.mu.Lock() - defer l.mu.Unlock() - l.dispatcher = dispatcher +func (ep *linkEndpoint) Attach(dispatcher stack.NetworkDispatcher) { + ep.mu.Lock() + defer ep.mu.Unlock() + ep.dispatcher = dispatcher } // IsAttached implements stack.LinkEndpoint.IsAttached. -func (l *linkEndpoint) IsAttached() bool { - l.mu.RLock() - defer l.mu.RUnlock() - return l.dispatcher != nil +func (ep *linkEndpoint) IsAttached() bool { + ep.mu.RLock() + defer ep.mu.RUnlock() + return ep.dispatcher != nil } // MTU implements stack.LinkEndpoint.MTU. -func (l *linkEndpoint) MTU() uint32 { - l.mu.RLock() - defer l.mu.RUnlock() - return l.mtu +func (ep *linkEndpoint) MTU() uint32 { + ep.mu.RLock() + defer ep.mu.RUnlock() + return ep.mtu } // SetMTU implements stack.LinkEndpoint.SetMTU. -func (l *linkEndpoint) SetMTU(mtu uint32) { - l.mu.Lock() - defer l.mu.Unlock() - l.mtu = mtu +func (ep *linkEndpoint) SetMTU(mtu uint32) { + ep.mu.Lock() + defer ep.mu.Unlock() + ep.mtu = mtu } // Capabilities implements stack.LinkEndpoint.Capabilities. -func (l *linkEndpoint) Capabilities() stack.LinkEndpointCapabilities { +func (ep *linkEndpoint) Capabilities() stack.LinkEndpointCapabilities { // We are required to offload RX checksum validation for the purposes of // GRO. return stack.CapabilityRXChecksumOffload @@ -241,8 +242,8 @@ func (*linkEndpoint) GSOMaxSize() uint32 { } // SupportedGSO implements stack.GSOEndpoint. -func (l *linkEndpoint) SupportedGSO() stack.SupportedGSO { - return l.SupportedGSOKind +func (ep *linkEndpoint) SupportedGSO() stack.SupportedGSO { + return ep.SupportedGSOKind } // MaxHeaderLength returns the maximum size of the link layer header. Given it @@ -252,22 +253,22 @@ func (*linkEndpoint) MaxHeaderLength() uint16 { } // LinkAddress returns the link address of this endpoint. -func (l *linkEndpoint) LinkAddress() tcpip.LinkAddress { - l.mu.RLock() - defer l.mu.RUnlock() - return l.linkAddr +func (ep *linkEndpoint) LinkAddress() tcpip.LinkAddress { + ep.mu.RLock() + defer ep.mu.RUnlock() + return ep.linkAddr } // SetLinkAddress implements stack.LinkEndpoint.SetLinkAddress. -func (l *linkEndpoint) SetLinkAddress(addr tcpip.LinkAddress) { - l.mu.Lock() - defer l.mu.Unlock() - l.linkAddr = addr +func (ep *linkEndpoint) SetLinkAddress(addr tcpip.LinkAddress) { + ep.mu.Lock() + defer ep.mu.Unlock() + ep.linkAddr = addr } // WritePackets stores outbound packets into the channel. // Multiple concurrent calls are permitted. -func (l *linkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) { +func (ep *linkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) { n := 0 // TODO(jwhited): evaluate writing a stack.PacketBufferList instead of a // single packet. We can split 2 x 64K GSO across @@ -277,7 +278,7 @@ func (l *linkEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Err // control MTU (and by effect TCP MSS in gVisor) we *shouldn't* expect to // ever overflow 128 slots (see wireguard-go/tun.ErrTooManySegments usage). for _, pkt := range pkts.AsSlice() { - if err := l.q.Write(pkt); err != nil { + if err := ep.q.Write(pkt); err != nil { if _, ok := err.(*tcpip.ErrNoBufferSpace); !ok && n == 0 { return 0, err } diff --git a/vendor/tailscale.com/wgengine/netstack/netstack.go b/vendor/tailscale.com/wgengine/netstack/netstack.go index 591bedd..c2b5d8a 100644 --- a/vendor/tailscale.com/wgengine/netstack/netstack.go +++ b/vendor/tailscale.com/wgengine/netstack/netstack.go @@ -33,11 +33,13 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/transport/udp" "gvisor.dev/gvisor/pkg/waiter" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn/ipnlocal" "tailscale.com/metrics" "tailscale.com/net/dns" "tailscale.com/net/ipset" "tailscale.com/net/netaddr" + "tailscale.com/net/netx" "tailscale.com/net/packet" "tailscale.com/net/tsaddr" "tailscale.com/net/tsdial" @@ -208,7 +210,7 @@ type Impl struct { // TCP connection to another host (e.g. in subnet router mode). // // This is currently only used in tests. - forwardDialFunc func(context.Context, string, string) (net.Conn, error) + forwardDialFunc netx.DialFunc // forwardInFlightPerClientDropped is a metric that tracks how many // in-flight TCP forward requests were dropped due to the per-client @@ -326,10 +328,15 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi if tcpipErr != nil { return nil, fmt.Errorf("could not disable TCP RACK: %v", tcpipErr) } - cubicOpt := tcpip.CongestionControlOption("cubic") - tcpipErr = ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &cubicOpt) + // gVisor defaults to reno at the time of writing. We explicitly set reno + // congestion control in order to prevent unexpected changes. Netstack + // has an int overflow in sender congestion window arithmetic that is more + // prone to trigger with cubic congestion control. + // See https://github.com/google/gvisor/issues/11632 + renoOpt := tcpip.CongestionControlOption("reno") + tcpipErr = ipstack.SetTransportProtocolOption(tcp.ProtocolNumber, &renoOpt) if tcpipErr != nil { - return nil, fmt.Errorf("could not set cubic congestion control: %v", tcpipErr) + return nil, fmt.Errorf("could not set reno congestion control: %v", tcpipErr) } err := setTCPBufSizes(ipstack) if err != nil { @@ -337,7 +344,7 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi } supportedGSOKind := stack.GSONotSupported supportedGROKind := groNotSupported - if runtime.GOOS == "linux" { + if runtime.GOOS == "linux" && buildfeatures.HasGRO { // TODO(jwhited): add Windows support https://github.com/tailscale/corp/issues/21874 supportedGROKind = tcpGROSupported supportedGSOKind = stack.HostGSOSupported @@ -571,9 +578,16 @@ func (ns *Impl) decrementInFlightTCPForward(tei stack.TransportEndpointID, remot } } +// LocalBackend is a fake name for *ipnlocal.LocalBackend to avoid an import cycle. +type LocalBackend = any + // Start sets up all the handlers so netstack can start working. Implements // wgengine.FakeImpl. -func (ns *Impl) Start(lb *ipnlocal.LocalBackend) error { +func (ns *Impl) Start(b LocalBackend) error { + if b == nil { + panic("nil LocalBackend interface") + } + lb := b.(*ipnlocal.LocalBackend) if lb == nil { panic("nil LocalBackend") } @@ -637,13 +651,15 @@ func (ns *Impl) UpdateNetstackIPs(nm *netmap.NetworkMap) { var selfNode tailcfg.NodeView var serviceAddrSet set.Set[netip.Addr] if nm != nil { - vipServiceIPMap := nm.GetVIPServiceIPMap() - serviceAddrSet = make(set.Set[netip.Addr], len(vipServiceIPMap)*2) - for _, addrs := range vipServiceIPMap { - serviceAddrSet.AddSlice(addrs) - } ns.atomicIsLocalIPFunc.Store(ipset.NewContainsIPFunc(nm.GetAddresses())) - ns.atomicIsVIPServiceIPFunc.Store(serviceAddrSet.Contains) + if buildfeatures.HasServe { + vipServiceIPMap := nm.GetVIPServiceIPMap() + serviceAddrSet = make(set.Set[netip.Addr], len(vipServiceIPMap)*2) + for _, addrs := range vipServiceIPMap { + serviceAddrSet.AddSlice(addrs) + } + ns.atomicIsVIPServiceIPFunc.Store(serviceAddrSet.Contains) + } selfNode = nm.SelfNode } else { ns.atomicIsLocalIPFunc.Store(ipset.FalseContainsIPFunc()) @@ -1026,6 +1042,9 @@ func (ns *Impl) isLocalIP(ip netip.Addr) bool { // isVIPServiceIP reports whether ip is an IP address that's // assigned to a VIP service. func (ns *Impl) isVIPServiceIP(ip netip.Addr) bool { + if !buildfeatures.HasServe { + return false + } return ns.atomicIsVIPServiceIPFunc.Load()(ip) } @@ -1068,7 +1087,7 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool { return true } } - if isService { + if buildfeatures.HasServe && isService { if p.IsEchoRequest() { return true } @@ -1429,6 +1448,13 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) { } } +// tcpCloser is an interface to abstract around various TCPConn types that +// allow closing of the read and write streams independently of each other. +type tcpCloser interface { + CloseRead() error + CloseWrite() error +} + func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet.TCPConn, clientRemoteIP netip.Addr, wq *waiter.Queue, dialAddr netip.AddrPort) (handled bool) { dialAddrStr := dialAddr.String() if debugNetstack() { @@ -1457,7 +1483,7 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet. }() // Attempt to dial the outbound connection before we accept the inbound one. - var dialFunc func(context.Context, string, string) (net.Conn, error) + var dialFunc netx.DialFunc if ns.forwardDialFunc != nil { dialFunc = ns.forwardDialFunc } else { @@ -1495,18 +1521,48 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet. } defer client.Close() + // As of 2025-07-03, backend is always either a net.TCPConn + // from stdDialer.DialContext (which has the requisite functions), + // or nil from hangDialer in tests (in which case we would have + // errored out by now), so this conversion should always succeed. + backendTCPCloser, backendIsTCPCloser := backend.(tcpCloser) connClosed := make(chan error, 2) go func() { _, err := io.Copy(backend, client) + if err != nil { + err = fmt.Errorf("client -> backend: %w", err) + } connClosed <- err + err = nil + if backendIsTCPCloser { + err = backendTCPCloser.CloseWrite() + } + err = errors.Join(err, client.CloseRead()) + if err != nil { + ns.logf("client -> backend close connection: %v", err) + } }() go func() { _, err := io.Copy(client, backend) + if err != nil { + err = fmt.Errorf("backend -> client: %w", err) + } connClosed <- err + err = nil + if backendIsTCPCloser { + err = backendTCPCloser.CloseRead() + } + err = errors.Join(err, client.CloseWrite()) + if err != nil { + ns.logf("backend -> client close connection: %v", err) + } }() - err = <-connClosed - if err != nil { - ns.logf("proxy connection closed with error: %v", err) + // Wait for both ends of the connection to close. + for range 2 { + err = <-connClosed + if err != nil { + ns.logf("proxy connection closed with error: %v", err) + } } ns.logf("[v2] netstack: forwarder connection to %s closed", dialAddrStr) return @@ -1849,7 +1905,6 @@ func (ns *Impl) ExpVar() expvar.Var { {"option_unknown_received", ipStats.OptionUnknownReceived}, } for _, metric := range ipMetrics { - metric := metric m.Set("counter_ip_"+metric.name, expvar.Func(func() any { return readStatCounter(metric.field) })) @@ -1876,7 +1931,6 @@ func (ns *Impl) ExpVar() expvar.Var { {"errors", fwdStats.Errors}, } for _, metric := range fwdMetrics { - metric := metric m.Set("counter_ip_forward_"+metric.name, expvar.Func(func() any { return readStatCounter(metric.field) })) @@ -1920,7 +1974,6 @@ func (ns *Impl) ExpVar() expvar.Var { {"forward_max_in_flight_drop", tcpStats.ForwardMaxInFlightDrop}, } for _, metric := range tcpMetrics { - metric := metric m.Set("counter_tcp_"+metric.name, expvar.Func(func() any { return readStatCounter(metric.field) })) @@ -1947,7 +2000,6 @@ func (ns *Impl) ExpVar() expvar.Var { {"checksum_errors", udpStats.ChecksumErrors}, } for _, metric := range udpMetrics { - metric := metric m.Set("counter_udp_"+metric.name, expvar.Func(func() any { return readStatCounter(metric.field) })) diff --git a/vendor/tailscale.com/wgengine/netstack/netstack_userping.go b/vendor/tailscale.com/wgengine/netstack/netstack_userping.go index ee635bd..b35a6ec 100644 --- a/vendor/tailscale.com/wgengine/netstack/netstack_userping.go +++ b/vendor/tailscale.com/wgengine/netstack/netstack_userping.go @@ -13,6 +13,7 @@ import ( "runtime" "time" + "tailscale.com/feature/buildfeatures" "tailscale.com/version/distro" ) @@ -20,7 +21,7 @@ import ( // CAP_NET_RAW from tailscaled's binary. var setAmbientCapsRaw func(*exec.Cmd) -var isSynology = runtime.GOOS == "linux" && distro.Get() == distro.Synology +var isSynology = runtime.GOOS == "linux" && buildfeatures.HasSynology && distro.Get() == distro.Synology // sendOutboundUserPing sends a non-privileged ICMP (or ICMPv6) ping to dstIP with the given timeout. func (ns *Impl) sendOutboundUserPing(dstIP netip.Addr, timeout time.Duration) error { @@ -61,7 +62,7 @@ func (ns *Impl) sendOutboundUserPing(dstIP netip.Addr, timeout time.Duration) er ping = "/bin/ping" } cmd := exec.Command(ping, "-c", "1", "-W", "3", dstIP.String()) - if isSynology && os.Getuid() != 0 { + if buildfeatures.HasSynology && isSynology && os.Getuid() != 0 { // On DSM7 we run as non-root and need to pass // CAP_NET_RAW if our binary has it. setAmbientCapsRaw(cmd) diff --git a/vendor/tailscale.com/wgengine/pendopen.go b/vendor/tailscale.com/wgengine/pendopen.go index 28d1f4f..7eaf43e 100644 --- a/vendor/tailscale.com/wgengine/pendopen.go +++ b/vendor/tailscale.com/wgengine/pendopen.go @@ -1,6 +1,8 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause +//go:build !ts_omit_debug + package wgengine import ( @@ -20,6 +22,8 @@ import ( "tailscale.com/wgengine/filter" ) +type flowtrackTuple = flowtrack.Tuple + const tcpTimeoutBeforeDebug = 5 * time.Second type pendingOpenFlow struct { @@ -56,6 +60,10 @@ func (e *userspaceEngine) noteFlowProblemFromPeer(f flowtrack.Tuple, problem pac of.problem = problem } +func tsRejectFlow(rh packet.TailscaleRejectedHeader) flowtrack.Tuple { + return flowtrack.MakeTuple(rh.Proto, rh.Src, rh.Dst) +} + func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.Wrapper) (res filter.Response) { res = filter.Accept // always @@ -66,8 +74,8 @@ func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.Wrapp return } if rh.MaybeBroken { - e.noteFlowProblemFromPeer(rh.Flow(), rh.Reason) - } else if f := rh.Flow(); e.removeFlow(f) { + e.noteFlowProblemFromPeer(tsRejectFlow(rh), rh.Reason) + } else if f := tsRejectFlow(rh); e.removeFlow(f) { e.logf("open-conn-track: flow %v %v > %v rejected due to %v", rh.Proto, rh.Src, rh.Dst, rh.Reason) } return diff --git a/vendor/tailscale.com/wgengine/pendopen_omit.go b/vendor/tailscale.com/wgengine/pendopen_omit.go new file mode 100644 index 0000000..013425d --- /dev/null +++ b/vendor/tailscale.com/wgengine/pendopen_omit.go @@ -0,0 +1,24 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ts_omit_debug + +package wgengine + +import ( + "tailscale.com/net/packet" + "tailscale.com/net/tstun" + "tailscale.com/wgengine/filter" +) + +type flowtrackTuple = struct{} + +type pendingOpenFlow struct{} + +func (*userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.Wrapper) (res filter.Response) { + panic("unreachable") +} + +func (*userspaceEngine) trackOpenPostFilterOut(pp *packet.Parsed, t *tstun.Wrapper) (res filter.Response) { + panic("unreachable") +} diff --git a/vendor/tailscale.com/wgengine/router/callback.go b/vendor/tailscale.com/wgengine/router/callback.go index 1d90912..c183853 100644 --- a/vendor/tailscale.com/wgengine/router/callback.go +++ b/vendor/tailscale.com/wgengine/router/callback.go @@ -56,13 +56,6 @@ func (r *CallbackRouter) Set(rcfg *Config) error { return r.SetBoth(r.rcfg, r.dcfg) } -// UpdateMagicsockPort implements the Router interface. This implementation -// does nothing and returns nil because this router does not currently need -// to know what the magicsock UDP port is. -func (r *CallbackRouter) UpdateMagicsockPort(_ uint16, _ string) error { - return nil -} - // SetDNS implements dns.OSConfigurator. func (r *CallbackRouter) SetDNS(dcfg dns.OSConfig) error { r.mu.Lock() diff --git a/vendor/tailscale.com/wgengine/router/ifconfig_windows.go b/vendor/tailscale.com/wgengine/router/ifconfig_windows.go deleted file mode 100644 index 40e9dc6..0000000 --- a/vendor/tailscale.com/wgengine/router/ifconfig_windows.go +++ /dev/null @@ -1,834 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package router - -import ( - "errors" - "fmt" - "log" - "net/netip" - "slices" - "sort" - "time" - - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/net/tsaddr" - "tailscale.com/net/tstun" - "tailscale.com/util/multierr" - "tailscale.com/wgengine/winnet" - - ole "github.com/go-ole/go-ole" - "github.com/tailscale/wireguard-go/tun" - "go4.org/netipx" - "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" -) - -// monitorDefaultRoutes subscribes to route change events and updates -// the Tailscale tunnel interface's MTU to match that of the -// underlying default route. -// -// This is an attempt at making the MTU mostly correct, but in -// practice this entire piece of code ends up just using the 1280 -// value passed in at device construction time. This code might make -// the MTU go lower due to very low-MTU IPv4 interfaces. -// -// TODO: this code is insufficient to control the MTU correctly. The -// correct way to do it is per-peer PMTU discovery, and synthesizing -// ICMP fragmentation-needed messages within tailscaled. This code may -// address a few rare corner cases, but is unlikely to significantly -// help with MTU issues compared to a static 1280B implementation. -func monitorDefaultRoutes(tun *tun.NativeTun) (*winipcfg.RouteChangeCallback, error) { - ourLuid := winipcfg.LUID(tun.LUID()) - lastMtu := uint32(0) - doIt := func() error { - mtu, err := getDefaultRouteMTU() - if err != nil { - return fmt.Errorf("error getting default route MTU: %w", err) - } - - if mtu > 0 && (lastMtu == 0 || lastMtu != mtu) { - iface, err := ourLuid.IPInterface(windows.AF_INET) - if err != nil { - if !errors.Is(err, windows.ERROR_NOT_FOUND) { - return fmt.Errorf("getting v4 interface: %w", err) - } - } else { - iface.NLMTU = mtu - 80 - // If the TUN device was created with a smaller MTU, - // though, such as 1280, we don't want to go bigger - // than configured. (See the comment on minimalMTU in - // the wgengine package.) - if min, err := tun.MTU(); err == nil && min < int(iface.NLMTU) { - iface.NLMTU = uint32(min) - } - if iface.NLMTU < 576 { - iface.NLMTU = 576 - } - err = iface.Set() - if err != nil { - return fmt.Errorf("error setting v4 MTU: %w", err) - } - tun.ForceMTU(int(iface.NLMTU)) - } - iface, err = ourLuid.IPInterface(windows.AF_INET6) - if err != nil { - if !errors.Is(err, windows.ERROR_NOT_FOUND) { - return fmt.Errorf("error getting v6 interface: %w", err) - } - } else { - iface.NLMTU = mtu - 80 - if iface.NLMTU < 1280 { - iface.NLMTU = 1280 - } - err = iface.Set() - if err != nil { - return fmt.Errorf("error setting v6 MTU: %w", err) - } - } - lastMtu = mtu - } - return nil - } - err := doIt() - if err != nil { - return nil, err - } - cb, err := winipcfg.RegisterRouteChangeCallback(func(notificationType winipcfg.MibNotificationType, route *winipcfg.MibIPforwardRow2) { - //fmt.Printf("MonitorDefaultRoutes: changed: %v\n", route.DestinationPrefix) - if route.DestinationPrefix.PrefixLength == 0 { - _ = doIt() - } - }) - if err != nil { - return nil, err - } - return cb, nil -} - -func getDefaultRouteMTU() (uint32, error) { - mtus, err := netmon.NonTailscaleMTUs() - if err != nil { - return 0, err - } - - routes, err := winipcfg.GetIPForwardTable2(windows.AF_INET) - if err != nil { - return 0, err - } - best := ^uint32(0) - mtu := uint32(0) - for _, route := range routes { - if route.DestinationPrefix.PrefixLength != 0 { - continue - } - routeMTU := mtus[route.InterfaceLUID] - if routeMTU == 0 { - continue - } - if route.Metric < best { - best = route.Metric - mtu = routeMTU - } - } - - routes, err = winipcfg.GetIPForwardTable2(windows.AF_INET6) - if err != nil { - return 0, err - } - best = ^uint32(0) - for _, route := range routes { - if route.DestinationPrefix.PrefixLength != 0 { - continue - } - routeMTU := mtus[route.InterfaceLUID] - if routeMTU == 0 { - continue - } - if route.Metric < best { - best = route.Metric - if routeMTU < mtu { - mtu = routeMTU - } - } - } - - return mtu, nil -} - -// setPrivateNetwork marks the provided network adapter's category to private. -// It returns (false, nil) if the adapter was not found. -func setPrivateNetwork(ifcLUID winipcfg.LUID) (bool, error) { - // NLM_NETWORK_CATEGORY values. - const ( - categoryPublic = 0 - categoryPrivate = 1 - categoryDomain = 2 - ) - - ifcGUID, err := ifcLUID.GUID() - if err != nil { - return false, fmt.Errorf("ifcLUID.GUID: %v", err) - } - - // aaron: DO NOT call Initialize() or Uninitialize() on c! - // We've already handled that process-wide. - var c ole.Connection - - m, err := winnet.NewNetworkListManager(&c) - if err != nil { - return false, fmt.Errorf("winnet.NewNetworkListManager: %v", err) - } - defer m.Release() - - cl, err := m.GetNetworkConnections() - if err != nil { - return false, fmt.Errorf("m.GetNetworkConnections: %v", err) - } - defer cl.Release() - - for _, nco := range cl { - aid, err := nco.GetAdapterId() - if err != nil { - return false, fmt.Errorf("nco.GetAdapterId: %v", err) - } - if aid != ifcGUID.String() { - continue - } - - n, err := nco.GetNetwork() - if err != nil { - return false, fmt.Errorf("GetNetwork: %v", err) - } - defer n.Release() - - cat, err := n.GetCategory() - if err != nil { - return false, fmt.Errorf("GetCategory: %v", err) - } - - if cat != categoryPrivate && cat != categoryDomain { - if err := n.SetCategory(categoryPrivate); err != nil { - return false, fmt.Errorf("SetCategory: %v", err) - } - } - return true, nil - } - - return false, nil -} - -// interfaceFromLUID returns IPAdapterAddresses with specified LUID. -func interfaceFromLUID(luid winipcfg.LUID, flags winipcfg.GAAFlags) (*winipcfg.IPAdapterAddresses, error) { - addresses, err := winipcfg.GetAdaptersAddresses(windows.AF_UNSPEC, flags) - if err != nil { - return nil, err - } - for _, addr := range addresses { - if addr.LUID == luid { - return addr, nil - } - } - return nil, fmt.Errorf("interfaceFromLUID: interface with LUID %v not found", luid) -} - -var networkCategoryWarnable = health.Register(&health.Warnable{ - Code: "set-network-category-failed", - Severity: health.SeverityMedium, - Title: "Windows network configuration failed", - Text: func(args health.Args) string { - return fmt.Sprintf("Failed to set the network category to private on the Tailscale adapter. This may prevent Tailscale from working correctly. Error: %s", args[health.ArgError]) - }, - MapDebugFlag: "warn-network-category-unhealthy", -}) - -func configureInterface(cfg *Config, tun *tun.NativeTun, ht *health.Tracker) (retErr error) { - var mtu = tstun.DefaultTUNMTU() - luid := winipcfg.LUID(tun.LUID()) - iface, err := interfaceFromLUID(luid, - // Issue 474: on early boot, when the network is still - // coming up, if the Tailscale service comes up first, - // the Tailscale adapter it finds might not have the - // IPv4 service available yet? Try this flag: - winipcfg.GAAFlagIncludeAllInterfaces, - ) - if err != nil { - return fmt.Errorf("getting interface: %w", err) - } - - // Send non-nil return errors to retErrc, to interrupt our background - // setPrivateNetwork goroutine. - retErrc := make(chan error, 1) - defer func() { - if retErr != nil { - retErrc <- retErr - } - }() - - go func() { - // It takes a weirdly long time for Windows to notice the - // new interface has come up. Poll periodically until it - // does. - const tries = 20 - for i := range tries { - found, err := setPrivateNetwork(luid) - if err != nil { - ht.SetUnhealthy(networkCategoryWarnable, health.Args{health.ArgError: err.Error()}) - log.Printf("setPrivateNetwork(try=%d): %v", i, err) - } else { - ht.SetHealthy(networkCategoryWarnable) - if found { - if i > 0 { - log.Printf("setPrivateNetwork(try=%d): success", i) - } - return - } - log.Printf("setPrivateNetwork(try=%d): not found", i) - } - select { - case <-time.After(time.Second): - case <-retErrc: - return - } - } - log.Printf("setPrivateNetwork: adapter LUID %v not found after %d tries, giving up", luid, tries) - }() - - // Figure out which of IPv4 and IPv6 are available. Both protocols - // can be disabled on a per-interface basis by the user, as well - // as globally via a registry policy. We skip programming anything - // related to the disabled protocols, since by definition they're - // unusable. - ipif4, err := iface.LUID.IPInterface(windows.AF_INET) - if err != nil { - if !errors.Is(err, windows.ERROR_NOT_FOUND) { - return fmt.Errorf("getting AF_INET interface: %w", err) - } - log.Printf("AF_INET interface not found on Tailscale adapter, skipping IPv4 programming") - ipif4 = nil - } - ipif6, err := iface.LUID.IPInterface(windows.AF_INET6) - if err != nil { - if !errors.Is(err, windows.ERROR_NOT_FOUND) { - return fmt.Errorf("getting AF_INET6 interface: %w", err) - } - log.Printf("AF_INET6 interface not found on Tailscale adapter, skipping IPv6 programming") - ipif6 = nil - } - - // Windows requires routes to have a nexthop. Routes created using - // the interface's local IP address or an unspecified IP address - // ("0.0.0.0" or "::") as the nexthop are considered on-link routes. - // - // Notably, Windows treats on-link subnet routes differently, reserving the last - // IP in the range as the broadcast IP and therefore prohibiting TCP connections - // to it, resulting in WSA error 10049: "The requested address is not valid in its context." - // This does not happen with single-host routes, such as routes to Tailscale IP addresses, - // but becomes a problem with advertised subnets when all IPs in the range should be reachable. - // See https://github.com/tailscale/support-escalations/issues/57 for details. - // - // For routes such as ours where the nexthop is meaningless, we can use an - // arbitrary nexthop address, such as TailscaleServiceIP, to prevent the - // routes from being marked as on-link. We can still create on-link routes - // for single-host Tailscale routes, but we shouldn't attempt to create a - // route for the interface's own IP. - var localAddr4, localAddr6 netip.Addr - var gatewayAddr4, gatewayAddr6 netip.Addr - addresses := make([]netip.Prefix, 0, len(cfg.LocalAddrs)) - for _, addr := range cfg.LocalAddrs { - if (addr.Addr().Is4() && ipif4 == nil) || (addr.Addr().Is6() && ipif6 == nil) { - // Can't program addresses for disabled protocol. - continue - } - addresses = append(addresses, addr) - if addr.Addr().Is4() && !gatewayAddr4.IsValid() { - localAddr4 = addr.Addr() - gatewayAddr4 = tsaddr.TailscaleServiceIP() - } else if addr.Addr().Is6() && !gatewayAddr6.IsValid() { - localAddr6 = addr.Addr() - gatewayAddr6 = tsaddr.TailscaleServiceIPv6() - } - } - - var routes []*routeData - foundDefault4 := false - foundDefault6 := false - for _, route := range cfg.Routes { - if (route.Addr().Is4() && ipif4 == nil) || (route.Addr().Is6() && ipif6 == nil) { - // Can't program routes for disabled protocol. - continue - } - - if route.Addr().Is6() && !gatewayAddr6.IsValid() { - // Windows won't let us set IPv6 routes without having an - // IPv6 local address set. However, when we've configured - // a default route, we want to forcibly grab IPv6 traffic - // even if the v6 overlay network isn't configured. To do - // that, we add a dummy local IPv6 address to serve as a - // route source. - ip := tsaddr.Tailscale4To6Placeholder() - addresses = append(addresses, netip.PrefixFrom(ip, ip.BitLen())) - gatewayAddr6 = ip - } else if route.Addr().Is4() && !gatewayAddr4.IsValid() { - // TODO: do same dummy behavior as v6? - return errors.New("due to a Windows limitation, one cannot have interface routes without an interface address") - } - - var gateway, localAddr netip.Addr - if route.Addr().Is4() { - localAddr = localAddr4 - gateway = gatewayAddr4 - } else if route.Addr().Is6() { - localAddr = localAddr6 - gateway = gatewayAddr6 - } - - switch destAddr := route.Addr().Unmap(); { - case destAddr == localAddr: - // no need to add a route for the interface's - // own IP. The kernel does that for us. - // If we try to replace it, we'll fail to - // add the route unless NextHop is set, but - // then the interface's IP won't be pingable. - continue - case route.IsSingleIP() && (destAddr == gateway || tsaddr.IsTailscaleIP(destAddr)): - // add an on-link route if the destination - // is the nexthop itself or a single Tailscale IP. - gateway = localAddr - } - - r := &routeData{ - RouteData: winipcfg.RouteData{ - Destination: route, - NextHop: gateway, - Metric: 0, - }, - } - - if route.Addr().Is4() { - if route.Bits() == 0 { - foundDefault4 = true - } - } else if route.Addr().Is6() { - if route.Bits() == 0 { - foundDefault6 = true - } - } - routes = append(routes, r) - } - - err = syncAddresses(iface, addresses) - if err != nil { - return fmt.Errorf("syncAddresses: %w", err) - } - - slices.SortFunc(routes, (*routeData).Compare) - - deduplicatedRoutes := []*routeData{} - for i := range len(routes) { - // There's only one way to get to a given IP+Mask, so delete - // all matches after the first. - if i > 0 && routes[i].Destination == routes[i-1].Destination { - continue - } - deduplicatedRoutes = append(deduplicatedRoutes, routes[i]) - } - - // Re-read interface after syncAddresses. - iface, err = interfaceFromLUID(luid, - // Issue 474: on early boot, when the network is still - // coming up, if the Tailscale service comes up first, - // the Tailscale adapter it finds might not have the - // IPv4 service available yet? Try this flag: - winipcfg.GAAFlagIncludeAllInterfaces, - ) - if err != nil { - return fmt.Errorf("getting interface: %w", err) - } - - var errAcc error - err = syncRoutes(iface, deduplicatedRoutes, cfg.LocalAddrs) - if err != nil && errAcc == nil { - log.Printf("setroutes: %v", err) - errAcc = err - } - - if ipif4 != nil { - ipif4, err = iface.LUID.IPInterface(windows.AF_INET) - if err != nil { - return fmt.Errorf("getting AF_INET interface: %w", err) - } - if foundDefault4 { - ipif4.UseAutomaticMetric = false - ipif4.Metric = 0 - } - if mtu > 0 { - ipif4.NLMTU = uint32(mtu) - tun.ForceMTU(int(ipif4.NLMTU)) - } - err = ipif4.Set() - if err != nil && errAcc == nil { - errAcc = err - } - } - - if ipif6 != nil { - ipif6, err = iface.LUID.IPInterface(windows.AF_INET6) - if err != nil { - return fmt.Errorf("getting AF_INET6 interface: %w", err) - } else { - if foundDefault6 { - ipif6.UseAutomaticMetric = false - ipif6.Metric = 0 - } - if mtu > 0 { - ipif6.NLMTU = uint32(mtu) - } - ipif6.DadTransmits = 0 - ipif6.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled - err = ipif6.Set() - if err != nil && errAcc == nil { - errAcc = err - } - } - } - - return errAcc -} - -func netCompare(a, b netip.Prefix) int { - aip, bip := a.Addr().Unmap(), b.Addr().Unmap() - v := aip.Compare(bip) - if v != 0 { - return v - } - - if a.Bits() == b.Bits() { - return 0 - } - // narrower first - if a.Bits() > b.Bits() { - return -1 - } - return 1 -} - -func sortNets(s []netip.Prefix) { - sort.Slice(s, func(i, j int) bool { - return netCompare(s[i], s[j]) == -1 - }) -} - -// deltaNets returns the changes to turn a into b. -func deltaNets(a, b []netip.Prefix) (add, del []netip.Prefix) { - add = make([]netip.Prefix, 0, len(b)) - del = make([]netip.Prefix, 0, len(a)) - sortNets(a) - sortNets(b) - - i := 0 - j := 0 - for i < len(a) && j < len(b) { - switch netCompare(a[i], b[j]) { - case -1: - // a < b, delete - del = append(del, a[i]) - i++ - case 0: - // a == b, no diff - i++ - j++ - case 1: - // a > b, add missing entry - add = append(add, b[j]) - j++ - default: - panic("unexpected compare result") - } - } - del = append(del, a[i:]...) - add = append(add, b[j:]...) - return -} - -func isIPv6LinkLocal(a netip.Prefix) bool { - return a.Addr().Is6() && a.Addr().IsLinkLocalUnicast() -} - -// ipAdapterUnicastAddressToPrefix converts windows.IpAdapterUnicastAddress to netip.Prefix -func ipAdapterUnicastAddressToPrefix(u *windows.IpAdapterUnicastAddress) netip.Prefix { - ip, _ := netip.AddrFromSlice(u.Address.IP()) - return netip.PrefixFrom(ip.Unmap(), int(u.OnLinkPrefixLength)) -} - -// unicastIPNets returns all unicast net.IPNet for ifc interface. -func unicastIPNets(ifc *winipcfg.IPAdapterAddresses) []netip.Prefix { - var nets []netip.Prefix - for addr := ifc.FirstUnicastAddress; addr != nil; addr = addr.Next { - nets = append(nets, ipAdapterUnicastAddressToPrefix(addr)) - } - return nets -} - -// syncAddresses incrementally sets the interface's unicast IP addresses, -// doing the minimum number of AddAddresses & DeleteAddress calls. -// This avoids the full FlushAddresses. -// -// Any IPv6 link-local addresses are not deleted out of caution as some -// configurations may repeatedly re-add them. Link-local addresses are adjusted -// to set SkipAsSource. SkipAsSource prevents the addresses from being added to -// DNS locally or remotely and from being picked as a source address for -// outgoing packets with unspecified sources. See #4647 and -// https://web.archive.org/web/20200912120956/https://devblogs.microsoft.com/scripting/use-powershell-to-change-ip-behavior-with-skipassource/ -func syncAddresses(ifc *winipcfg.IPAdapterAddresses, want []netip.Prefix) error { - var erracc error - - got := unicastIPNets(ifc) - add, del := deltaNets(got, want) - - ll := make([]netip.Prefix, 0) - for _, a := range del { - // do not delete link-local addresses, and collect them for later - // applying SkipAsSource. - if isIPv6LinkLocal(a) { - ll = append(ll, a) - continue - } - - err := ifc.LUID.DeleteIPAddress(a) - if err != nil { - erracc = fmt.Errorf("deleting IP %q: %w", a, err) - } - } - - for _, a := range add { - err := ifc.LUID.AddIPAddress(a) - if err != nil { - erracc = fmt.Errorf("adding IP %q: %w", a, err) - } - } - - for _, a := range ll { - mib, err := ifc.LUID.IPAddress(a.Addr()) - if err != nil { - erracc = fmt.Errorf("setting skip-as-source on IP %q: unable to retrieve MIB: %w", a, err) - continue - } - if !mib.SkipAsSource { - mib.SkipAsSource = true - if err := mib.Set(); err != nil { - erracc = fmt.Errorf("setting skip-as-source on IP %q: unable to set MIB: %w", a, err) - } - } - } - - return erracc -} - -// routeData wraps winipcfg.RouteData with an additional field that permits -// caching of the associated MibIPForwardRow2; by keeping it around, we can -// avoid unnecessary (and slow) lookups of information that we already have. -type routeData struct { - winipcfg.RouteData - Row *winipcfg.MibIPforwardRow2 -} - -func (rd *routeData) Less(other *routeData) bool { - return rd.Compare(other) < 0 -} - -func (rd *routeData) Compare(other *routeData) int { - v := rd.Destination.Addr().Compare(other.Destination.Addr()) - if v != 0 { - return v - } - - // Narrower masks first - b1, b2 := rd.Destination.Bits(), other.Destination.Bits() - if b1 != b2 { - if b1 > b2 { - return -1 - } - return 1 - } - - // No nexthop before non-empty nexthop - v = rd.NextHop.Compare(other.NextHop) - if v != 0 { - return v - } - - // Lower metrics first - if rd.Metric < other.Metric { - return -1 - } else if rd.Metric > other.Metric { - return 1 - } - - return 0 -} - -func deltaRouteData(a, b []*routeData) (add, del []*routeData) { - add = make([]*routeData, 0, len(b)) - del = make([]*routeData, 0, len(a)) - slices.SortFunc(a, (*routeData).Compare) - slices.SortFunc(b, (*routeData).Compare) - - i := 0 - j := 0 - for i < len(a) && j < len(b) { - switch a[i].Compare(b[j]) { - case -1: - // a < b, delete - del = append(del, a[i]) - i++ - case 0: - // a == b, no diff - i++ - j++ - case 1: - // a > b, add missing entry - add = append(add, b[j]) - j++ - default: - panic("unexpected compare result") - } - } - del = append(del, a[i:]...) - add = append(add, b[j:]...) - return -} - -// getInterfaceRoutes returns all the interface's routes. -// Corresponds to GetIpForwardTable2 function, but filtered by interface. -func getInterfaceRoutes(ifc *winipcfg.IPAdapterAddresses, family winipcfg.AddressFamily) (matches []*winipcfg.MibIPforwardRow2, err error) { - routes, err := winipcfg.GetIPForwardTable2(family) - if err != nil { - return nil, err - } - for i := range routes { - if routes[i].InterfaceLUID == ifc.LUID { - matches = append(matches, &routes[i]) - } - } - return -} - -func getAllInterfaceRoutes(ifc *winipcfg.IPAdapterAddresses) ([]*routeData, error) { - routes4, err := getInterfaceRoutes(ifc, windows.AF_INET) - if err != nil { - return nil, err - } - - routes6, err := getInterfaceRoutes(ifc, windows.AF_INET6) - if err != nil { - // TODO: what if v6 unavailable? - return nil, err - } - - rd := make([]*routeData, 0, len(routes4)+len(routes6)) - for _, r := range routes4 { - rd = append(rd, &routeData{ - RouteData: winipcfg.RouteData{ - Destination: r.DestinationPrefix.Prefix(), - NextHop: r.NextHop.Addr(), - Metric: r.Metric, - }, - Row: r, - }) - } - - for _, r := range routes6 { - rd = append(rd, &routeData{ - RouteData: winipcfg.RouteData{ - Destination: r.DestinationPrefix.Prefix(), - NextHop: r.NextHop.Addr(), - Metric: r.Metric, - }, - Row: r, - }) - } - return rd, nil -} - -// filterRoutes removes routes that have been added by Windows and should not -// be managed by us. -func filterRoutes(routes []*routeData, dontDelete []netip.Prefix) []*routeData { - ddm := make(map[netip.Prefix]bool) - for _, dd := range dontDelete { - // See issue 1448: we don't want to touch the routes added - // by Windows for our interface addresses. - ddm[dd] = true - } - for _, r := range routes { - // We don't want to touch broadcast routes that Windows adds. - nr := r.Destination - if !nr.IsValid() { - continue - } - if nr.IsSingleIP() { - continue - } - lastIP := netipx.RangeOfPrefix(nr).To() - ddm[netip.PrefixFrom(lastIP, lastIP.BitLen())] = true - } - filtered := make([]*routeData, 0, len(routes)) - for _, r := range routes { - rr := r.Destination - if rr.IsValid() && ddm[rr] { - continue - } - filtered = append(filtered, r) - } - return filtered -} - -// syncRoutes incrementally sets multiples routes on an interface. -// This avoids a full ifc.FlushRoutes call. -// dontDelete is a list of interface address routes that the -// synchronization logic should never delete. -func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*routeData, dontDelete []netip.Prefix) error { - existingRoutes, err := getAllInterfaceRoutes(ifc) - if err != nil { - return err - } - got := filterRoutes(existingRoutes, dontDelete) - - add, del := deltaRouteData(got, want) - - var errs []error - for _, a := range del { - var err error - if a.Row == nil { - // DeleteRoute requires a routing table lookup, so only do that if - // a does not already have the row. - err = ifc.LUID.DeleteRoute(a.Destination, a.NextHop) - } else { - // Otherwise, delete the row directly. - err = a.Row.Delete() - } - if err != nil { - dstStr := a.Destination.String() - if dstStr == "169.254.255.255/32" { - // Issue 785. Ignore these routes - // failing to delete. Harmless. - // TODO(maisem): do we still need this? - continue - } - errs = append(errs, fmt.Errorf("deleting route %v: %w", dstStr, err)) - } - } - - for _, a := range add { - err := ifc.LUID.AddRoute(a.Destination, a.NextHop, a.Metric) - if err != nil { - errs = append(errs, fmt.Errorf("adding route %v: %w", &a.Destination, err)) - } - } - - return multierr.New(errs...) -} diff --git a/vendor/tailscale.com/wgengine/router/router.go b/vendor/tailscale.com/wgengine/router/router.go index 4230089..04cc898 100644 --- a/vendor/tailscale.com/wgengine/router/router.go +++ b/vendor/tailscale.com/wgengine/router/router.go @@ -6,14 +6,21 @@ package router import ( + "errors" + "fmt" "net/netip" "reflect" + "runtime" + "slices" "github.com/tailscale/wireguard-go/tun" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/net/netmon" "tailscale.com/types/logger" "tailscale.com/types/preftype" + "tailscale.com/util/eventbus" ) // Router is responsible for managing the system network stack. @@ -28,33 +35,70 @@ type Router interface { // implementation should handle gracefully. Set(*Config) error - // UpdateMagicsockPort tells the OS network stack what port magicsock - // is currently listening on, so it can be threaded through firewalls - // and such. This is distinct from Set() since magicsock may rebind - // ports independently from the Config changing. - // - // network should be either "udp4" or "udp6". - UpdateMagicsockPort(port uint16, network string) error - // Close closes the router. Close() error } +// NewOpts are the options passed to the NewUserspaceRouter hook. +type NewOpts struct { + Logf logger.Logf // required + Tun tun.Device // required + NetMon *netmon.Monitor // optional + Health *health.Tracker // required (but TODO: support optional later) + Bus *eventbus.Bus // required +} + +// PortUpdate is an eventbus value, reporting the port and address family +// magicsock is currently listening on, so it can be threaded through firewalls +// and such. +type PortUpdate struct { + UDPPort uint16 + EndpointNetwork string // either "udp4" or "udp6". +} + +// HookNewUserspaceRouter is the registration point for router implementations +// to register a constructor for userspace routers. It's meant for implementations +// in wgengine/router/osrouter. +// +// If no implementation is registered, [New] will return an error. +var HookNewUserspaceRouter feature.Hook[func(NewOpts) (Router, error)] + // New returns a new Router for the current platform, using the // provided tun device. // // If netMon is nil, it's not used. It's currently (2021-07-20) only // used on Linux in some situations. -func New(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { +func New(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, + health *health.Tracker, bus *eventbus.Bus, +) (Router, error) { logf = logger.WithPrefix(logf, "router: ") - return newUserspaceRouter(logf, tundev, netMon, health) + if f, ok := HookNewUserspaceRouter.GetOk(); ok { + return f(NewOpts{ + Logf: logf, + Tun: tundev, + NetMon: netMon, + Health: health, + Bus: bus, + }) + } + if !buildfeatures.HasOSRouter { + return nil, errors.New("router: tailscaled was built without OSRouter support") + } + return nil, fmt.Errorf("unsupported OS %q", runtime.GOOS) } +// HookCleanUp is the optional registration point for router implementations +// to register a cleanup function for [CleanUp] to use. It's meant for +// implementations in wgengine/router/osrouter. +var HookCleanUp feature.Hook[func(_ logger.Logf, _ *netmon.Monitor, ifName string)] + // CleanUp restores the system network configuration to its original state // in case the Tailscale daemon terminated without closing the router. // No other state needs to be instantiated before this runs. func CleanUp(logf logger.Logf, netMon *netmon.Monitor, interfaceName string) { - cleanUp(logf, interfaceName) + if f, ok := HookCleanUp.GetOk(); ok { + f(logf, netMon, interfaceName) + } } // Config is the subset of Tailscale configuration that is relevant to @@ -91,7 +135,7 @@ type Config struct { SNATSubnetRoutes bool // SNAT traffic to local subnets StatefulFiltering bool // Apply stateful filtering to inbound connections NetfilterMode preftype.NetfilterMode // how much to manage netfilter rules - NetfilterKind string // what kind of netfilter to use (nftables, iptables) + NetfilterKind string // what kind of netfilter to use ("nftables", "iptables", or "" to auto-detect) } func (a *Config) Equal(b *Config) bool { @@ -104,7 +148,14 @@ func (a *Config) Equal(b *Config) bool { return reflect.DeepEqual(a, b) } -// shutdownConfig is a routing configuration that removes all router -// state from the OS. It's the config used when callers pass in a nil -// Config. -var shutdownConfig = Config{} +func (c *Config) Clone() *Config { + if c == nil { + return nil + } + c2 := *c + c2.LocalAddrs = slices.Clone(c.LocalAddrs) + c2.Routes = slices.Clone(c.Routes) + c2.LocalRoutes = slices.Clone(c.LocalRoutes) + c2.SubnetRoutes = slices.Clone(c.SubnetRoutes) + return &c2 +} diff --git a/vendor/tailscale.com/wgengine/router/router_darwin.go b/vendor/tailscale.com/wgengine/router/router_darwin.go deleted file mode 100644 index 73e394b..0000000 --- a/vendor/tailscale.com/wgengine/router/router_darwin.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package router - -import ( - "github.com/tailscale/wireguard-go/tun" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - return newUserspaceBSDRouter(logf, tundev, netMon, health) -} - -func cleanUp(logger.Logf, string) { - // Nothing to do. -} diff --git a/vendor/tailscale.com/wgengine/router/router_default.go b/vendor/tailscale.com/wgengine/router/router_default.go deleted file mode 100644 index 1e675d1..0000000 --- a/vendor/tailscale.com/wgengine/router/router_default.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !windows && !linux && !darwin && !openbsd && !freebsd - -package router - -import ( - "fmt" - "runtime" - - "github.com/tailscale/wireguard-go/tun" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - return nil, fmt.Errorf("unsupported OS %q", runtime.GOOS) -} - -func cleanUp(logf logger.Logf, interfaceName string) { - // Nothing to do here. -} diff --git a/vendor/tailscale.com/wgengine/router/router_fake.go b/vendor/tailscale.com/wgengine/router/router_fake.go index 549867e..db35fc9 100644 --- a/vendor/tailscale.com/wgengine/router/router_fake.go +++ b/vendor/tailscale.com/wgengine/router/router_fake.go @@ -27,11 +27,6 @@ func (r fakeRouter) Set(cfg *Config) error { return nil } -func (r fakeRouter) UpdateMagicsockPort(_ uint16, _ string) error { - r.logf("[v1] warning: fakeRouter.UpdateMagicsockPort: not implemented.") - return nil -} - func (r fakeRouter) Close() error { r.logf("[v1] warning: fakeRouter.Close: not implemented.") return nil diff --git a/vendor/tailscale.com/wgengine/router/router_freebsd.go b/vendor/tailscale.com/wgengine/router/router_freebsd.go deleted file mode 100644 index 40523b4..0000000 --- a/vendor/tailscale.com/wgengine/router/router_freebsd.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package router - -import ( - "github.com/tailscale/wireguard-go/tun" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -// For now this router only supports the userspace WireGuard implementations. -// -// Work is currently underway for an in-kernel FreeBSD implementation of wireguard -// https://svnweb.freebsd.org/base?view=revision&revision=357986 - -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - return newUserspaceBSDRouter(logf, tundev, netMon, health) -} - -func cleanUp(logf logger.Logf, interfaceName string) { - // If the interface was left behind, ifconfig down will not remove it. - // In fact, this will leave a system in a tainted state where starting tailscaled - // will result in "interface tailscale0 already exists" - // until the defunct interface is ifconfig-destroyed. - ifup := []string{"ifconfig", interfaceName, "destroy"} - if out, err := cmd(ifup...).CombinedOutput(); err != nil { - logf("ifconfig destroy: %v\n%s", err, out) - } -} diff --git a/vendor/tailscale.com/wgengine/router/router_linux.go b/vendor/tailscale.com/wgengine/router/router_linux.go deleted file mode 100644 index 80191b2..0000000 --- a/vendor/tailscale.com/wgengine/router/router_linux.go +++ /dev/null @@ -1,1594 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package router - -import ( - "errors" - "fmt" - "net" - "net/netip" - "os" - "os/exec" - "strconv" - "strings" - "sync/atomic" - "syscall" - "time" - - "github.com/tailscale/netlink" - "github.com/tailscale/wireguard-go/tun" - "go4.org/netipx" - "golang.org/x/sys/unix" - "golang.org/x/time/rate" - "tailscale.com/envknob" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" - "tailscale.com/types/opt" - "tailscale.com/types/preftype" - "tailscale.com/util/linuxfw" - "tailscale.com/util/multierr" - "tailscale.com/version/distro" -) - -var getDistroFunc = distro.Get - -const ( - netfilterOff = preftype.NetfilterOff - netfilterNoDivert = preftype.NetfilterNoDivert - netfilterOn = preftype.NetfilterOn -) - -type linuxRouter struct { - closed atomic.Bool - logf func(fmt string, args ...any) - tunname string - netMon *netmon.Monitor - health *health.Tracker - unregNetMon func() - addrs map[netip.Prefix]bool - routes map[netip.Prefix]bool - localRoutes map[netip.Prefix]bool - snatSubnetRoutes bool - statefulFiltering bool - netfilterMode preftype.NetfilterMode - netfilterKind string - - // ruleRestorePending is whether a timer has been started to - // restore deleted ip rules. - ruleRestorePending atomic.Bool - ipRuleFixLimiter *rate.Limiter - - // Various feature checks for the network stack. - ipRuleAvailable bool // whether kernel was built with IP_MULTIPLE_TABLES - v6Available bool // whether the kernel supports IPv6 - fwmaskWorksLazy opt.Bool // whether we can use 'ip rule...fwmark /'; set lazily - - // ipPolicyPrefBase is the base priority at which ip rules are installed. - ipPolicyPrefBase int - - cmd commandRunner - nfr linuxfw.NetfilterRunner - - magicsockPortV4 uint16 - magicsockPortV6 uint16 -} - -func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - tunname, err := tunDev.Name() - if err != nil { - return nil, err - } - - cmd := osCommandRunner{ - ambientCapNetAdmin: useAmbientCaps(), - } - - return newUserspaceRouterAdvanced(logf, tunname, netMon, cmd, health) -} - -func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon.Monitor, cmd commandRunner, health *health.Tracker) (Router, error) { - r := &linuxRouter{ - logf: logf, - tunname: tunname, - netfilterMode: netfilterOff, - netMon: netMon, - health: health, - - cmd: cmd, - - ipRuleFixLimiter: rate.NewLimiter(rate.Every(5*time.Second), 10), - ipPolicyPrefBase: 5200, - } - if r.useIPCommand() { - r.ipRuleAvailable = (cmd.run("ip", "rule") == nil) - } else { - if rules, err := netlink.RuleList(netlink.FAMILY_V4); err != nil { - r.logf("error querying IP rules (does kernel have IP_MULTIPLE_TABLES?): %v", err) - r.logf("warning: running without policy routing") - } else { - r.logf("[v1] policy routing available; found %d rules", len(rules)) - r.ipRuleAvailable = true - } - } - - // A common installation of OpenWRT involves use of the 'mwan3' package. - // This package installs ip-tables rules like: - // -A mwan3_fallback_policy -m mark --mark 0x0/0x3f00 -j MARK --set-xmark 0x100/0x3f00 - // - // which coupled with an ip rule: - // 2001: from all fwmark 0x100/0x3f00 lookup 1 - // - // has the effect of gobbling tailscale packets, because tailscale by default installs - // its policy routing rules at priority 52xx. - // - // As such, if we are running on openWRT, detect a mwan3 config, AND detect a rule - // with a preference 2001 (corresponding to the first interface wman3 manages), we - // shift the priority of our policies to 13xx. This effectively puts us between mwan3's - // permit-by-src-ip rules and mwan3 lookup of its own routing table which would drop - // the packet. - isMWAN3, err := checkOpenWRTUsingMWAN3() - if err != nil { - r.logf("error checking mwan3 installation: %v", err) - } else if isMWAN3 { - r.ipPolicyPrefBase = 1300 - r.logf("mwan3 on openWRT detected, switching policy base priority to 1300") - } - - r.v6Available = linuxfw.CheckIPv6(r.logf) == nil - - r.fixupWSLMTU() - - return r, nil -} - -// ipCmdSupportsFwmask returns true if the system 'ip' binary supports using a -// fwmark stanza with a mask specified. To our knowledge, everything except busybox -// pre-1.33 supports this. -func ipCmdSupportsFwmask() (bool, error) { - ipPath, err := exec.LookPath("ip") - if err != nil { - return false, fmt.Errorf("lookpath: %v", err) - } - stat, err := os.Lstat(ipPath) - if err != nil { - return false, fmt.Errorf("lstat: %v", err) - } - if stat.Mode()&os.ModeSymlink == 0 { - // Not a symlink, so can't be busybox. Must be regular ip utility. - return true, nil - } - - linkDest, err := os.Readlink(ipPath) - if err != nil { - return false, err - } - if !strings.Contains(strings.ToLower(linkDest), "busybox") { - // Not busybox, presumably supports fwmark masks. - return true, nil - } - - // If we got this far, the ip utility is a busybox version with an - // unknown version. - // We run `ip --version` and look for the busybox banner (which - // is a stable 'BusyBox vX.Y.Z ()' string) to determine - // the version. - out, err := exec.Command("ip", "--version").CombinedOutput() - if err != nil { - return false, err - } - major, minor, _, err := busyboxParseVersion(string(out)) - if err != nil { - return false, nil - } - - // Support for masks added in 1.33.0. - switch { - case major > 1: - return true, nil - case major == 1 && minor >= 33: - return true, nil - default: - return false, nil - } -} - -func busyboxParseVersion(output string) (major, minor, patch int, err error) { - bannerStart := strings.Index(output, "BusyBox v") - if bannerStart < 0 { - return 0, 0, 0, errors.New("missing BusyBox banner") - } - bannerEnd := bannerStart + len("BusyBox v") - - end := strings.Index(output[bannerEnd:], " ") - if end < 0 { - return 0, 0, 0, errors.New("missing end delimiter") - } - - elements := strings.Split(output[bannerEnd:bannerEnd+end], ".") - if len(elements) < 3 { - return 0, 0, 0, fmt.Errorf("expected 3 version elements, got %d", len(elements)) - } - - if major, err = strconv.Atoi(elements[0]); err != nil { - return 0, 0, 0, fmt.Errorf("parsing major: %v", err) - } - if minor, err = strconv.Atoi(elements[1]); err != nil { - return 0, 0, 0, fmt.Errorf("parsing minor: %v", err) - } - if patch, err = strconv.Atoi(elements[2]); err != nil { - return 0, 0, 0, fmt.Errorf("parsing patch: %v", err) - } - return major, minor, patch, nil -} - -func useAmbientCaps() bool { - if getDistroFunc() != distro.Synology { - return false - } - return distro.DSMVersion() >= 7 -} - -var forceIPCommand = envknob.RegisterBool("TS_DEBUG_USE_IP_COMMAND") - -// useIPCommand reports whether r should use the "ip" command (or its -// fake commandRunner for tests) instead of netlink. -func (r *linuxRouter) useIPCommand() bool { - if r.cmd == nil { - panic("invalid init") - } - if forceIPCommand() { - return true - } - // In the future we might need to fall back to using the "ip" - // command if, say, netlink is blocked somewhere but the ip - // command is allowed to use netlink. For now we only use the ip - // command runner in tests. - _, ok := r.cmd.(osCommandRunner) - return !ok -} - -// fwmaskWorks reports whether we can use 'ip rule...fwmark /'. -// This is computed lazily on first use. By default, we don't run the "ip" -// command, so never actually runs this. But the "ip" command is used in tests -// and can be forced. (see useIPCommand) -func (r *linuxRouter) fwmaskWorks() bool { - if v, ok := r.fwmaskWorksLazy.Get(); ok { - return v - } - // To be a good denizen of the 4-byte 'fwmark' bitspace on every packet, we try to - // only use the third byte. However, support for masking to part of the fwmark bitspace - // was only added to busybox in 1.33.0. As such, we want to detect older versions and - // not issue such a stanza. - v, err := ipCmdSupportsFwmask() - if err != nil { - r.logf("failed to determine ip command fwmask support: %v", err) - } - r.fwmaskWorksLazy.Set(v) - if v { - r.logf("[v1] ip command supports fwmark masks") - } else { - r.logf("[v1] ip command does NOT support fwmark masks") - } - return v -} - -// onIPRuleDeleted is the callback from the network monitor for when an IP -// policy rule is deleted. See Issue 1591. -// -// If an ip rule is deleted (with pref number 52xx, as Tailscale sets), then -// set a timer to restore our rules, in case they were deleted. The timer lets -// us do one fixup in response to a batch of rule deletes. It also lets us -// delay arbitrarily to prevent a high-speed fight over the rule between -// competing processes. (Although empirically, systemd doesn't fight us -// like that... yet.) -// -// Note that we don't care about the table number. We don't strictly even care -// about the priority number. We could just do this in response to any netlink -// change. Filtering by known priority ranges cuts back on some logspam. -func (r *linuxRouter) onIPRuleDeleted(table uint8, priority uint32) { - if int(priority) < r.ipPolicyPrefBase || int(priority) >= (r.ipPolicyPrefBase+100) { - // Not our rule. - return - } - if r.ruleRestorePending.Swap(true) { - // Another timer is already pending. - return - } - rr := r.ipRuleFixLimiter.Reserve() - if !rr.OK() { - r.ruleRestorePending.Swap(false) - return - } - time.AfterFunc(rr.Delay()+250*time.Millisecond, func() { - if r.ruleRestorePending.Swap(false) && !r.closed.Load() { - r.logf("somebody (likely systemd-networkd) deleted ip rules; restoring Tailscale's") - r.justAddIPRules() - } - }) -} - -func (r *linuxRouter) Up() error { - if r.unregNetMon == nil && r.netMon != nil { - r.unregNetMon = r.netMon.RegisterRuleDeleteCallback(r.onIPRuleDeleted) - } - if err := r.setNetfilterMode(netfilterOff); err != nil { - return fmt.Errorf("setting netfilter mode: %w", err) - } - if err := r.addIPRules(); err != nil { - return fmt.Errorf("adding IP rules: %w", err) - } - if err := r.upInterface(); err != nil { - return fmt.Errorf("bringing interface up: %w", err) - } - - return nil -} - -func (r *linuxRouter) Close() error { - r.closed.Store(true) - if r.unregNetMon != nil { - r.unregNetMon() - } - if err := r.downInterface(); err != nil { - return err - } - if err := r.delIPRules(); err != nil { - return err - } - if err := r.setNetfilterMode(netfilterOff); err != nil { - return err - } - if err := r.delRoutes(); err != nil { - return err - } - - r.addrs = nil - r.routes = nil - r.localRoutes = nil - - return nil -} - -// setupNetfilter initializes the NetfilterRunner in r.nfr. It expects r.nfr -// to be nil, or the current netfilter to be set to netfilterOff. -// kind should be either a linuxfw.FirewallMode, or the empty string for auto. -func (r *linuxRouter) setupNetfilter(kind string) error { - r.netfilterKind = kind - - var err error - r.nfr, err = linuxfw.New(r.logf, r.netfilterKind) - if err != nil { - return fmt.Errorf("could not create new netfilter: %w", err) - } - - return nil -} - -// Set implements the Router interface. -func (r *linuxRouter) Set(cfg *Config) error { - var errs []error - if cfg == nil { - cfg = &shutdownConfig - } - - if cfg.NetfilterKind != r.netfilterKind { - if err := r.setNetfilterMode(netfilterOff); err != nil { - err = fmt.Errorf("could not disable existing netfilter: %w", err) - errs = append(errs, err) - } else { - r.nfr = nil - if err := r.setupNetfilter(cfg.NetfilterKind); err != nil { - errs = append(errs, err) - } - } - } - - if err := r.setNetfilterMode(cfg.NetfilterMode); err != nil { - errs = append(errs, err) - } - - newLocalRoutes, err := cidrDiff("localRoute", r.localRoutes, cfg.LocalRoutes, r.addThrowRoute, r.delThrowRoute, r.logf) - if err != nil { - errs = append(errs, err) - } - r.localRoutes = newLocalRoutes - - newRoutes, err := cidrDiff("route", r.routes, cfg.Routes, r.addRoute, r.delRoute, r.logf) - if err != nil { - errs = append(errs, err) - } - r.routes = newRoutes - - newAddrs, err := cidrDiff("addr", r.addrs, cfg.LocalAddrs, r.addAddress, r.delAddress, r.logf) - if err != nil { - errs = append(errs, err) - } - r.addrs = newAddrs - - // Ensure that the SNAT rule is added or removed as needed. - switch { - case cfg.SNATSubnetRoutes == r.snatSubnetRoutes: - // state already correct, nothing to do. - case cfg.SNATSubnetRoutes: - if err := r.addSNATRule(); err != nil { - errs = append(errs, err) - } - default: - if err := r.delSNATRule(); err != nil { - errs = append(errs, err) - } - } - r.snatSubnetRoutes = cfg.SNATSubnetRoutes - - // As above, for stateful filtering - switch { - case cfg.StatefulFiltering == r.statefulFiltering: - // state already correct, nothing to do. - case cfg.StatefulFiltering: - if err := r.addStatefulRule(); err != nil { - errs = append(errs, err) - } - default: - if err := r.delStatefulRule(); err != nil { - errs = append(errs, err) - } - } - r.statefulFiltering = cfg.StatefulFiltering - r.updateStatefulFilteringWithDockerWarning(cfg) - - // Issue 11405: enable IP forwarding on gokrazy. - advertisingRoutes := len(cfg.SubnetRoutes) > 0 - if getDistroFunc() == distro.Gokrazy && advertisingRoutes { - r.enableIPForwarding() - } - - return multierr.New(errs...) -} - -var dockerStatefulFilteringWarnable = health.Register(&health.Warnable{ - Code: "docker-stateful-filtering", - Title: "Docker with stateful filtering", - Severity: health.SeverityMedium, - Text: health.StaticMessage("Stateful filtering is enabled and Docker was detected; this may prevent Docker containers on this host from resolving DNS and connecting to Tailscale nodes. See https://tailscale.com/s/stateful-docker"), -}) - -func (r *linuxRouter) updateStatefulFilteringWithDockerWarning(cfg *Config) { - // If stateful filtering is disabled, clear the warning. - if !r.statefulFiltering { - r.health.SetHealthy(dockerStatefulFilteringWarnable) - return - } - - advertisingRoutes := len(cfg.SubnetRoutes) > 0 - - // TODO(andrew-d,maisem): we might want to check if we're running in a - // container, since, if so, stateful filtering might prevent other - // containers from connecting through the Tailscale in this container. - // - // For now, just check for the case where we're running Tailscale on - // the host and Docker is also running. - - // If this node isn't a subnet router or exit node, then we would never - // have allowed traffic from a Docker container in to Tailscale, since - // there wouldn't be an AllowedIP for the container's source IP. So we - // don't need to warn in this case. - // - // cfg.SubnetRoutes contains all subnet routes for the node, including - // the default route (0.0.0.0/0 or ::/0) if this node is an exit node. - if advertisingRoutes { - // Check for the presence of a Docker interface and warn if it's found - // on the system. - // - // TODO(andrew-d): do a better job at detecting Docker, e.g. by looking - // for it in the $PATH or by checking for the presence of the Docker - // socket/daemon/etc. - ifstate := r.netMon.InterfaceState() - if _, found := ifstate.Interface["docker0"]; found { - r.health.SetUnhealthy(dockerStatefulFilteringWarnable, nil) - return - } - } - - // If we get here, then we have no warnings; clear anything existing. - r.health.SetHealthy(dockerStatefulFilteringWarnable) -} - -// UpdateMagicsockPort implements the Router interface. -func (r *linuxRouter) UpdateMagicsockPort(port uint16, network string) error { - if r.nfr == nil { - if err := r.setupNetfilter(r.netfilterKind); err != nil { - return fmt.Errorf("could not setup netfilter: %w", err) - } - } - - var magicsockPort *uint16 - switch network { - case "udp4": - magicsockPort = &r.magicsockPortV4 - case "udp6": - // Skip setting up MagicSock port if the host does not support - // IPv6. MagicSock IPv6 port needs a filter rule to function. In - // some cases (hosts with partial iptables support) filter - // tables are not supported, so skip setting up the port for - // those hosts too. - if !r.getV6FilteringAvailable() { - return nil - } - magicsockPort = &r.magicsockPortV6 - default: - return fmt.Errorf("unsupported network %s", network) - } - - // set the port, we'll make the firewall rule when netfilter turns back on - if r.netfilterMode == netfilterOff { - *magicsockPort = port - return nil - } - - if *magicsockPort == port { - return nil - } - - if *magicsockPort != 0 { - if err := r.nfr.DelMagicsockPortRule(*magicsockPort, network); err != nil { - return fmt.Errorf("del magicsock port rule: %w", err) - } - } - - if port != 0 { - if err := r.nfr.AddMagicsockPortRule(*magicsockPort, network); err != nil { - return fmt.Errorf("add magicsock port rule: %w", err) - } - } - - *magicsockPort = port - return nil -} - -// setNetfilterMode switches the router to the given netfilter -// mode. Netfilter state is created or deleted appropriately to -// reflect the new mode, and r.snatSubnetRoutes is updated to reflect -// the current state of subnet SNATing. -func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error { - if !platformCanNetfilter() { - mode = netfilterOff - } - - if r.nfr == nil { - var err error - r.nfr, err = linuxfw.New(r.logf, r.netfilterKind) - if err != nil { - return err - } - } - - if r.netfilterMode == mode { - return nil - } - - // Depending on the netfilter mode we switch from and to, we may - // have created the Tailscale netfilter chains. If so, we have to - // go back through existing router state, and add the netfilter - // rules for that state. - // - // This bool keeps track of whether the current state transition - // is one that requires adding rules of existing state. - reprocess := false - - switch mode { - case netfilterOff: - switch r.netfilterMode { - case netfilterNoDivert: - if err := r.nfr.DelBase(); err != nil { - return err - } - if err := r.nfr.DelChains(); err != nil { - r.logf("note: %v", err) - // harmless, continue. - // This can happen if someone left a ref to - // this table somewhere else. - } - case netfilterOn: - if err := r.nfr.DelHooks(r.logf); err != nil { - return err - } - if err := r.nfr.DelBase(); err != nil { - return err - } - if err := r.nfr.DelChains(); err != nil { - r.logf("note: %v", err) - // harmless, continue. - // This can happen if someone left a ref to - // this table somewhere else. - } - } - r.snatSubnetRoutes = false - case netfilterNoDivert: - switch r.netfilterMode { - case netfilterOff: - reprocess = true - if err := r.nfr.AddChains(); err != nil { - return err - } - if err := r.nfr.AddBase(r.tunname); err != nil { - return err - } - if r.magicsockPortV4 != 0 { - if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV4, "udp4"); err != nil { - return fmt.Errorf("could not add magicsock port rule v4: %w", err) - } - } - if r.magicsockPortV6 != 0 && r.getV6FilteringAvailable() { - if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil { - return fmt.Errorf("could not add magicsock port rule v6: %w", err) - } - } - r.snatSubnetRoutes = false - case netfilterOn: - if err := r.nfr.DelHooks(r.logf); err != nil { - return err - } - } - case netfilterOn: - // Because of bugs in old version of iptables-compat, - // we can't add a "-j ts-forward" rule to FORWARD - // while ts-forward contains an "-m mark" rule. But - // we can add the row *before* populating ts-forward. - // So we have to delBase, then add the hooks, - // then re-addBase, just in case. - switch r.netfilterMode { - case netfilterOff: - reprocess = true - if err := r.nfr.AddChains(); err != nil { - return err - } - if err := r.nfr.DelBase(); err != nil { - return err - } - // AddHooks adds the ts loopback rule. - if err := r.nfr.AddHooks(); err != nil { - return err - } - // AddBase adds base ts rules - if err := r.nfr.AddBase(r.tunname); err != nil { - return err - } - if r.magicsockPortV4 != 0 { - if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV4, "udp4"); err != nil { - return fmt.Errorf("could not add magicsock port rule v4: %w", err) - } - } - if r.magicsockPortV6 != 0 && r.getV6FilteringAvailable() { - if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil { - return fmt.Errorf("could not add magicsock port rule v6: %w", err) - } - } - r.snatSubnetRoutes = false - case netfilterNoDivert: - reprocess = true - if err := r.nfr.DelBase(); err != nil { - return err - } - if err := r.nfr.AddHooks(); err != nil { - return err - } - if err := r.nfr.AddBase(r.tunname); err != nil { - return err - } - r.snatSubnetRoutes = false - } - default: - panic("unhandled netfilter mode") - } - - r.netfilterMode = mode - - if !reprocess { - return nil - } - - for cidr := range r.addrs { - if err := r.addLoopbackRule(cidr.Addr()); err != nil { - return fmt.Errorf("error adding loopback rule: %w", err) - } - } - - return nil -} - -// getV6FilteringAvailable returns true if the router is able to setup the -// required tailscale filter rules for IPv6. -func (r *linuxRouter) getV6FilteringAvailable() bool { - return r.nfr.HasIPV6() && r.nfr.HasIPV6Filter() -} - -// getV6Available returns true if the host supports IPv6. -func (r *linuxRouter) getV6Available() bool { - return r.nfr.HasIPV6() -} - -// addAddress adds an IP/mask to the tunnel interface. Fails if the -// address is already assigned to the interface, or if the addition -// fails. -func (r *linuxRouter) addAddress(addr netip.Prefix) error { - if !r.getV6Available() && addr.Addr().Is6() { - return nil - } - if r.useIPCommand() { - if err := r.cmd.run("ip", "addr", "add", addr.String(), "dev", r.tunname); err != nil { - return fmt.Errorf("adding address %q to tunnel interface: %w", addr, err) - } - } else { - link, err := r.link() - if err != nil { - return fmt.Errorf("adding address %v, %w", addr, err) - } - if err := netlink.AddrReplace(link, nlAddrOfPrefix(addr)); err != nil { - return fmt.Errorf("adding address %v from tunnel interface: %w", addr, err) - } - } - if err := r.addLoopbackRule(addr.Addr()); err != nil { - return err - } - return nil -} - -// delAddress removes an IP/mask from the tunnel interface. Fails if -// the address is not assigned to the interface, or if the removal -// fails. -func (r *linuxRouter) delAddress(addr netip.Prefix) error { - if !r.getV6Available() && addr.Addr().Is6() { - return nil - } - if err := r.delLoopbackRule(addr.Addr()); err != nil { - return err - } - if r.useIPCommand() { - if err := r.cmd.run("ip", "addr", "del", addr.String(), "dev", r.tunname); err != nil { - return fmt.Errorf("deleting address %q from tunnel interface: %w", addr, err) - } - } else { - link, err := r.link() - if err != nil { - return fmt.Errorf("deleting address %v, %w", addr, err) - } - if err := netlink.AddrDel(link, nlAddrOfPrefix(addr)); err != nil { - return fmt.Errorf("deleting address %v from tunnel interface: %w", addr, err) - } - } - return nil -} - -// addLoopbackRule adds a firewall rule to permit loopback traffic to -// a local Tailscale IP. -func (r *linuxRouter) addLoopbackRule(addr netip.Addr) error { - if r.netfilterMode == netfilterOff { - return nil - } - if addr.Is6() && !r.nfr.HasIPV6Filter() { - return nil - } - - if err := r.nfr.AddLoopbackRule(addr); err != nil { - return err - } - return nil -} - -// delLoopbackRule removes the firewall rule permitting loopback -// traffic to a Tailscale IP. -func (r *linuxRouter) delLoopbackRule(addr netip.Addr) error { - if r.netfilterMode == netfilterOff { - return nil - } - if addr.Is6() && !r.nfr.HasIPV6Filter() { - return nil - } - - if err := r.nfr.DelLoopbackRule(addr); err != nil { - return err - } - return nil -} - -// addRoute adds a route for cidr, pointing to the tunnel -// interface. Fails if the route already exists, or if adding the -// route fails. -func (r *linuxRouter) addRoute(cidr netip.Prefix) error { - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - if r.useIPCommand() { - return r.addRouteDef([]string{normalizeCIDR(cidr), "dev", r.tunname}, cidr) - } - linkIndex, err := r.linkIndex() - if err != nil { - return err - } - return netlink.RouteReplace(&netlink.Route{ - LinkIndex: linkIndex, - Dst: netipx.PrefixIPNet(cidr.Masked()), - Table: r.routeTable(), - }) -} - -// addThrowRoute adds a throw route for the provided cidr. -// This has the effect that lookup in the routing table is terminated -// pretending that no route was found. Fails if the route already exists, -// or if adding the route fails. -func (r *linuxRouter) addThrowRoute(cidr netip.Prefix) error { - if !r.ipRuleAvailable { - return nil - } - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - if r.useIPCommand() { - return r.addRouteDef([]string{"throw", normalizeCIDR(cidr)}, cidr) - } - err := netlink.RouteReplace(&netlink.Route{ - Dst: netipx.PrefixIPNet(cidr.Masked()), - Table: tailscaleRouteTable.Num, - Type: unix.RTN_THROW, - }) - if err != nil { - r.logf("THROW ERROR adding %v: %#v", cidr, err) - } - return err -} - -func (r *linuxRouter) addRouteDef(routeDef []string, cidr netip.Prefix) error { - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - args := append([]string{"ip", "route", "add"}, routeDef...) - if r.ipRuleAvailable { - args = append(args, "table", tailscaleRouteTable.ipCmdArg()) - } - err := r.cmd.run(args...) - if err == nil { - return nil - } - - // This is an ugly hack to detect failure to add a route that - // already exists (as happens in when we're racing to add - // kernel-maintained routes when enabling exit nodes w/o Local - // LAN access, Issue 3060). Fortunately in the common case we - // use netlink directly instead and don't exercise this code. - if errCode(err) == 2 && strings.Contains(err.Error(), "RTNETLINK answers: File exists") { - r.logf("ignoring route add of %v; already exists", cidr) - return nil - } - return err -} - -var ( - errESRCH error = syscall.ESRCH - errENOENT error = syscall.ENOENT - errEEXIST error = syscall.EEXIST -) - -// delRoute removes the route for cidr pointing to the tunnel -// interface. Fails if the route doesn't exist, or if removing the -// route fails. -func (r *linuxRouter) delRoute(cidr netip.Prefix) error { - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - if r.useIPCommand() { - return r.delRouteDef([]string{normalizeCIDR(cidr), "dev", r.tunname}, cidr) - } - linkIndex, err := r.linkIndex() - if err != nil { - return err - } - err = netlink.RouteDel(&netlink.Route{ - LinkIndex: linkIndex, - Dst: netipx.PrefixIPNet(cidr.Masked()), - Table: r.routeTable(), - }) - if errors.Is(err, errESRCH) { - // Didn't exist to begin with. - return nil - } - return err -} - -// delThrowRoute removes the throw route for the cidr. Fails if the route -// doesn't exist, or if removing the route fails. -func (r *linuxRouter) delThrowRoute(cidr netip.Prefix) error { - if !r.ipRuleAvailable { - return nil - } - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - if r.useIPCommand() { - return r.delRouteDef([]string{"throw", normalizeCIDR(cidr)}, cidr) - } - err := netlink.RouteDel(&netlink.Route{ - Dst: netipx.PrefixIPNet(cidr.Masked()), - Table: r.routeTable(), - Type: unix.RTN_THROW, - }) - if errors.Is(err, errESRCH) { - // Didn't exist to begin with. - return nil - } - return err -} - -func (r *linuxRouter) delRouteDef(routeDef []string, cidr netip.Prefix) error { - if !r.getV6Available() && cidr.Addr().Is6() { - return nil - } - args := append([]string{"ip", "route", "del"}, routeDef...) - if r.ipRuleAvailable { - args = append(args, "table", tailscaleRouteTable.ipCmdArg()) - } - err := r.cmd.run(args...) - if err != nil { - ok, err := r.hasRoute(routeDef, cidr) - if err != nil { - r.logf("warning: error checking whether %v even exists after error deleting it: %v", err) - } else { - if !ok { - r.logf("warning: tried to delete route %v but it was already gone; ignoring error", cidr) - return nil - } - } - } - return err -} - -func dashFam(ip netip.Addr) string { - if ip.Is6() { - return "-6" - } - return "-4" -} - -func (r *linuxRouter) hasRoute(routeDef []string, cidr netip.Prefix) (bool, error) { - args := append([]string{"ip", dashFam(cidr.Addr()), "route", "show"}, routeDef...) - if r.ipRuleAvailable { - args = append(args, "table", tailscaleRouteTable.ipCmdArg()) - } - out, err := r.cmd.output(args...) - if err != nil { - return false, err - } - return len(out) > 0, nil -} - -func (r *linuxRouter) link() (netlink.Link, error) { - link, err := netlink.LinkByName(r.tunname) - if err != nil { - return nil, fmt.Errorf("failed to look up link %q: %w", r.tunname, err) - } - return link, nil -} - -func (r *linuxRouter) linkIndex() (int, error) { - // TODO(bradfitz): cache this? It doesn't change often, and on start-up - // hundreds of addRoute calls to add /32s can happen quickly. - link, err := r.link() - if err != nil { - return 0, err - } - return link.Attrs().Index, nil -} - -// routeTable returns the route table to use. -func (r *linuxRouter) routeTable() int { - if r.ipRuleAvailable { - return tailscaleRouteTable.Num - } - return 0 -} - -// upInterface brings up the tunnel interface. -func (r *linuxRouter) upInterface() error { - if r.useIPCommand() { - return r.cmd.run("ip", "link", "set", "dev", r.tunname, "up") - } - link, err := r.link() - if err != nil { - return fmt.Errorf("bringing interface up, %w", err) - } - return netlink.LinkSetUp(link) -} - -func (r *linuxRouter) enableIPForwarding() { - sysctls := map[string]string{ - "net.ipv4.ip_forward": "1", - "net.ipv6.conf.all.forwarding": "1", - } - for k, v := range sysctls { - if err := writeSysctl(k, v); err != nil { - r.logf("warning: %v", k, v, err) - continue - } - r.logf("sysctl(%v=%v): ok", k, v) - } -} - -func writeSysctl(key, val string) error { - fn := "/proc/sys/" + strings.Replace(key, ".", "/", -1) - if err := os.WriteFile(fn, []byte(val), 0644); err != nil { - return fmt.Errorf("sysctl(%v=%v): %v", key, val, err) - } - return nil -} - -// downInterface sets the tunnel interface administratively down. -func (r *linuxRouter) downInterface() error { - if r.useIPCommand() { - return r.cmd.run("ip", "link", "set", "dev", r.tunname, "down") - } - link, err := r.link() - if err != nil { - return fmt.Errorf("bringing interface down, %w", err) - } - return netlink.LinkSetDown(link) -} - -// fixupWSLMTU sets the MTU on the eth0 interface to 1360 bytes if running under -// WSL, eth0 is the default route, and has the MTU 1280 bytes. -func (r *linuxRouter) fixupWSLMTU() { - if !distro.IsWSL() { - return - } - - if r.useIPCommand() { - r.logf("fixupWSLMTU: not implemented by ip command") - return - } - - link, err := netlink.LinkByName("eth0") - if err != nil { - r.logf("warning: fixupWSLMTU: could not open eth0: %v", err) - return - } - - routes, err := netlink.RouteGet(net.IPv4(8, 8, 8, 8)) - if err != nil || len(routes) == 0 { - if err == nil { - err = fmt.Errorf("none found") - } - r.logf("fixupWSLMTU: could not get default route: %v", err) - return - } - - if routes[0].LinkIndex != link.Attrs().Index { - r.logf("fixupWSLMTU: default route is not via eth0") - return - } - - if link.Attrs().MTU == 1280 { - if err := netlink.LinkSetMTU(link, 1360); err != nil { - r.logf("warning: fixupWSLMTU: could not raise eth0 MTU: %v", err) - } - } -} - -// addrFamily is an address family: IPv4 or IPv6. -type addrFamily byte - -const ( - v4 = addrFamily(4) - v6 = addrFamily(6) -) - -func (f addrFamily) dashArg() string { - switch f { - case 4: - return "-4" - case 6: - return "-6" - } - panic("illegal") -} - -func (f addrFamily) netlinkInt() int { - switch f { - case 4: - return netlink.FAMILY_V4 - case 6: - return netlink.FAMILY_V6 - } - panic("illegal") -} - -func (r *linuxRouter) addrFamilies() []addrFamily { - if r.getV6Available() { - return []addrFamily{v4, v6} - } - return []addrFamily{v4} -} - -// addIPRules adds the policy routing rule that avoids tailscaled -// routing loops. If the rule exists and appears to be a -// tailscale-managed rule, it is gracefully replaced. -func (r *linuxRouter) addIPRules() error { - if !r.ipRuleAvailable { - return nil - } - - // Clear out old rules. After that, any error adding a rule is fatal, - // because there should be no reason we add a duplicate. - if err := r.delIPRules(); err != nil { - return err - } - - return r.justAddIPRules() -} - -// RouteTable is a Linux routing table: both its name and number. -// See /etc/iproute2/rt_tables. -type RouteTable struct { - Name string - Num int -} - -var routeTableByNumber = map[int]RouteTable{} - -// IpCmdArg returns the string form of the table to pass to the "ip" command. -func (rt RouteTable) ipCmdArg() string { - if rt.Num >= 253 { - return rt.Name - } - return strconv.Itoa(rt.Num) -} - -func newRouteTable(name string, num int) RouteTable { - rt := RouteTable{name, num} - routeTableByNumber[num] = rt - return rt -} - -// MustRouteTable returns the RouteTable with the given number key. -// It panics if the number is unknown because this result is a part -// of IP rule argument and we don't want to continue with an invalid -// argument with table no exist. -func mustRouteTable(num int) RouteTable { - rt, ok := routeTableByNumber[num] - if !ok { - panic(fmt.Sprintf("unknown route table %v", num)) - } - return rt -} - -var ( - mainRouteTable = newRouteTable("main", 254) - defaultRouteTable = newRouteTable("default", 253) - - // tailscaleRouteTable is the routing table number for Tailscale - // network routes. See addIPRules for the detailed policy routing - // logic that ends up doing lookups within that table. - // - // NOTE(danderson): We chose 52 because those are the digits above the - // letters "TS" on a qwerty keyboard, and 52 is sufficiently unlikely - // to be picked by other software. - // - // NOTE(danderson): You might wonder why we didn't pick some - // high table number like 5252, to further avoid the potential - // for collisions with other software. Unfortunately, - // Busybox's `ip` implementation believes that table numbers - // are 8-bit integers, so for maximum compatibility we had to - // stay in the 0-255 range even though linux itself supports - // larger numbers. (but nowadays we use netlink directly and - // aren't affected by the busybox binary's limitations) - tailscaleRouteTable = newRouteTable("tailscale", 52) -) - -// baseIPRules are the policy routing rules that Tailscale uses, when not -// running on a UBNT device. -// -// The priority is the value represented here added to r.ipPolicyPrefBase, -// which is usually 5200. -// -// NOTE(apenwarr): We leave spaces between each pref number. -// This is so the sysadmin can override by inserting rules in -// between if they want. -// -// NOTE(apenwarr): This sequence seems complicated, right? -// If we could simply have a rule that said "match packets that -// *don't* have this fwmark", then we would only need to add one -// link to table 52 and we'd be done. Unfortunately, older kernels -// and 'ip rule' implementations (including busybox), don't support -// checking for the lack of a fwmark, only the presence. The technique -// below works even on very old kernels. -var baseIPRules = []netlink.Rule{ - // Packets from us, tagged with our fwmark, first try the kernel's - // main routing table. - { - Priority: 10, - Mark: linuxfw.TailscaleBypassMarkNum, - Table: mainRouteTable.Num, - }, - // ...and then we try the 'default' table, for correctness, - // even though it's been empty on every Linux system I've ever seen. - { - Priority: 30, - Mark: linuxfw.TailscaleBypassMarkNum, - Table: defaultRouteTable.Num, - }, - // If neither of those matched (no default route on this system?) - // then packets from us should be aborted rather than falling through - // to the tailscale routes, because that would create routing loops. - { - Priority: 50, - Mark: linuxfw.TailscaleBypassMarkNum, - Type: unix.RTN_UNREACHABLE, - }, - // If we get to this point, capture all packets and send them - // through to the tailscale route table. For apps other than us - // (ie. with no fwmark set), this is the first routing table, so - // it takes precedence over all the others, ie. VPN routes always - // beat non-VPN routes. - { - Priority: 70, - Table: tailscaleRouteTable.Num, - }, - // If that didn't match, then non-fwmark packets fall through to the - // usual rules (pref 32766 and 32767, ie. main and default). -} - -// ubntIPRules are the policy routing rules that Tailscale uses, when running -// on a UBNT device. -// -// The priority is the value represented here added to -// r.ipPolicyPrefBase, which is usually 5200. -// -// This represents an experiment that will be used to gather more information. -// If this goes well, Tailscale may opt to use this for all of Linux. -var ubntIPRules = []netlink.Rule{ - // non-fwmark packets fall through to the usual rules (pref 32766 and 32767, - // ie. main and default). - { - Priority: 70, - Invert: true, - Mark: linuxfw.TailscaleBypassMarkNum, - Table: tailscaleRouteTable.Num, - }, -} - -// ipRules returns the appropriate list of ip rules to be used by Tailscale. See -// comments on baseIPRules and ubntIPRules for more details. -func ipRules() []netlink.Rule { - if getDistroFunc() == distro.UBNT { - return ubntIPRules - } - return baseIPRules -} - -// justAddIPRules adds policy routing rule without deleting any first. -func (r *linuxRouter) justAddIPRules() error { - if !r.ipRuleAvailable { - return nil - } - if r.useIPCommand() { - return r.addIPRulesWithIPCommand() - } - var errAcc error - for _, family := range r.addrFamilies() { - - for _, ru := range ipRules() { - // Note: r is a value type here; safe to mutate it. - ru.Family = family.netlinkInt() - if ru.Mark != 0 { - ru.Mask = linuxfw.TailscaleFwmarkMaskNum - } - ru.Goto = -1 - ru.SuppressIfgroup = -1 - ru.SuppressPrefixlen = -1 - ru.Flow = -1 - ru.Priority += r.ipPolicyPrefBase - - err := netlink.RuleAdd(&ru) - if errors.Is(err, errEEXIST) { - // Ignore dups. - continue - } - if err != nil && errAcc == nil { - errAcc = err - } - } - } - return errAcc -} - -func (r *linuxRouter) addIPRulesWithIPCommand() error { - rg := newRunGroup(nil, r.cmd) - - for _, family := range r.addrFamilies() { - for _, rule := range ipRules() { - args := []string{ - "ip", family.dashArg(), - "rule", "add", - "pref", strconv.Itoa(rule.Priority + r.ipPolicyPrefBase), - } - if rule.Mark != 0 { - if r.fwmaskWorks() { - args = append(args, "fwmark", fmt.Sprintf("0x%x/%s", rule.Mark, linuxfw.TailscaleFwmarkMask)) - } else { - args = append(args, "fwmark", fmt.Sprintf("0x%x", rule.Mark)) - } - } - if rule.Table != 0 { - args = append(args, "table", mustRouteTable(rule.Table).ipCmdArg()) - } - if rule.Type == unix.RTN_UNREACHABLE { - args = append(args, "type", "unreachable") - } - rg.Run(args...) - } - } - - return rg.ErrAcc -} - -// delRoutes removes any local routes that we added that would not be -// cleaned up on interface down. -func (r *linuxRouter) delRoutes() error { - for rt := range r.localRoutes { - if err := r.delThrowRoute(rt); err != nil { - r.logf("failed to delete throw route(%q): %v", rt, err) - } - } - return nil -} - -// delIPRules removes the policy routing rules that avoid -// tailscaled routing loops, if it exists. -func (r *linuxRouter) delIPRules() error { - if !r.ipRuleAvailable { - return nil - } - if r.useIPCommand() { - return r.delIPRulesWithIPCommand() - } - var errAcc error - for _, family := range r.addrFamilies() { - for _, ru := range ipRules() { - // Note: r is a value type here; safe to mutate it. - // When deleting rules, we want to be a bit specific (mention which - // table we were routing to) but not *too* specific (fwmarks, etc). - // That leaves us some flexibility to change these values in later - // versions without having ongoing hacks for every possible - // combination. - ru.Family = family.netlinkInt() - ru.Mark = -1 - ru.Mask = -1 - ru.Goto = -1 - ru.SuppressIfgroup = -1 - ru.SuppressPrefixlen = -1 - ru.Priority += r.ipPolicyPrefBase - - err := netlink.RuleDel(&ru) - if errors.Is(err, errENOENT) { - // Didn't exist to begin with. - continue - } - if err != nil && errAcc == nil { - errAcc = err - } - } - } - return errAcc -} - -func (r *linuxRouter) delIPRulesWithIPCommand() error { - // Error codes: 'ip rule' returns error code 2 if the rule is a - // duplicate (add) or not found (del). It returns a different code - // for syntax errors. This is also true of busybox. - // - // Some older versions of iproute2 also return error code 254 for - // unknown rules during deletion. - rg := newRunGroup([]int{2, 254}, r.cmd) - - for _, family := range r.addrFamilies() { - // When deleting rules, we want to be a bit specific (mention which - // table we were routing to) but not *too* specific (fwmarks, etc). - // That leaves us some flexibility to change these values in later - // versions without having ongoing hacks for every possible - // combination. - for _, rule := range ipRules() { - args := []string{ - "ip", family.dashArg(), - "rule", "del", - "pref", strconv.Itoa(rule.Priority + r.ipPolicyPrefBase), - } - if rule.Table != 0 { - args = append(args, "table", mustRouteTable(rule.Table).ipCmdArg()) - } else { - args = append(args, "type", "unreachable") - } - rg.Run(args...) - } - } - - return rg.ErrAcc -} - -// addSNATRule adds a netfilter rule to SNAT traffic destined for -// local subnets. -func (r *linuxRouter) addSNATRule() error { - if r.netfilterMode == netfilterOff { - return nil - } - - if err := r.nfr.AddSNATRule(); err != nil { - return err - } - return nil -} - -// delSNATRule removes the netfilter rule to SNAT traffic destined for -// local subnets. Fails if the rule does not exist. -func (r *linuxRouter) delSNATRule() error { - if r.netfilterMode == netfilterOff { - return nil - } - - if err := r.nfr.DelSNATRule(); err != nil { - return err - } - return nil -} - -// addStatefulRule adds a netfilter rule to perform stateful filtering from -// subnets onto the tailnet. -func (r *linuxRouter) addStatefulRule() error { - if r.netfilterMode == netfilterOff { - return nil - } - - return r.nfr.AddStatefulRule(r.tunname) -} - -// delStatefulRule removes the netfilter rule to perform stateful filtering -// from subnets onto the tailnet. -func (r *linuxRouter) delStatefulRule() error { - if r.netfilterMode == netfilterOff { - return nil - } - - return r.nfr.DelStatefulRule(r.tunname) -} - -// cidrDiff calls add and del as needed to make the set of prefixes in -// old and new match. Returns a map reflecting the actual new state -// (which may be somewhere in between old and new if some commands -// failed), and any error encountered while reconfiguring. -func cidrDiff(kind string, old map[netip.Prefix]bool, new []netip.Prefix, add, del func(netip.Prefix) error, logf logger.Logf) (map[netip.Prefix]bool, error) { - newMap := make(map[netip.Prefix]bool, len(new)) - for _, cidr := range new { - newMap[cidr] = true - } - - // ret starts out as a copy of old, and updates as we - // add/delete. That way we can always return it and have it be the - // true state of what we've done so far. - ret := make(map[netip.Prefix]bool, len(old)) - for cidr := range old { - ret[cidr] = true - } - - // We want to add before we delete, so that if there is no overlap, we don't - // end up in a state where we have no addresses on an interface as that - // results in other kernel entities (like routes) pointing to that interface - // to also be deleted. - var addFail []error - for cidr := range newMap { - if old[cidr] { - continue - } - if err := add(cidr); err != nil { - logf("%s add failed: %v", kind, err) - addFail = append(addFail, err) - } else { - ret[cidr] = true - } - } - - if len(addFail) == 1 { - return ret, addFail[0] - } - if len(addFail) > 0 { - return ret, fmt.Errorf("%d add %s failures; first was: %w", len(addFail), kind, addFail[0]) - } - - var delFail []error - for cidr := range old { - if newMap[cidr] { - continue - } - if err := del(cidr); err != nil { - logf("%s del failed: %v", kind, err) - delFail = append(delFail, err) - } else { - delete(ret, cidr) - } - } - if len(delFail) == 1 { - return ret, delFail[0] - } - if len(delFail) > 0 { - return ret, fmt.Errorf("%d delete %s failures; first was: %w", len(delFail), kind, delFail[0]) - } - - return ret, nil -} - -// normalizeCIDR returns cidr as an ip/mask string, with the host bits -// of the IP address zeroed out. -func normalizeCIDR(cidr netip.Prefix) string { - return cidr.Masked().String() -} - -// platformCanNetfilter reports whether the current distro/environment supports -// running iptables/nftables commands. -func platformCanNetfilter() bool { - switch getDistroFunc() { - case distro.Synology: - // Synology doesn't support iptables or nftables. Attempting to run it - // just blocks for a long time while it logs about failures. - // - // See https://github.com/tailscale/tailscale/issues/11737 for one such - // prior regression where we tried to run iptables on Synology. - return false - } - return true -} - -// cleanUp removes all the rules and routes that were added by the linux router. -// The function calls cleanUp for both iptables and nftables since which ever -// netfilter runner is used, the cleanUp function for the other one doesn't do anything. -func cleanUp(logf logger.Logf, interfaceName string) { - if interfaceName != "userspace-networking" && platformCanNetfilter() { - linuxfw.IPTablesCleanUp(logf) - linuxfw.NfTablesCleanUp(logf) - } -} - -// Checks if the running openWRT system is using mwan3, based on the heuristic -// of the config file being present as well as a policy rule with a specific -// priority (2000 + 1 - first interface mwan3 manages) and non-zero mark. -func checkOpenWRTUsingMWAN3() (bool, error) { - if getDistroFunc() != distro.OpenWrt { - return false, nil - } - - if _, err := os.Stat("/etc/config/mwan3"); err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - - rules, err := netlink.RuleList(netlink.FAMILY_V4) - if err != nil { - return false, err - } - for _, r := range rules { - // We want to match on a rule like this: - // 2001: from all fwmark 0x100/0x3f00 lookup 1 - // - // We dont match on the mask because it can vary, or the - // table because I'm not sure if it can vary. - if r.Priority >= 2001 && r.Priority <= 2004 && r.Mark != 0 { - return true, nil - } - } - - return false, nil -} - -func nlAddrOfPrefix(p netip.Prefix) *netlink.Addr { - return &netlink.Addr{ - IPNet: netipx.PrefixIPNet(p), - } -} diff --git a/vendor/tailscale.com/wgengine/router/router_openbsd.go b/vendor/tailscale.com/wgengine/router/router_openbsd.go deleted file mode 100644 index 6fdd47a..0000000 --- a/vendor/tailscale.com/wgengine/router/router_openbsd.go +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package router - -import ( - "errors" - "fmt" - "log" - "net/netip" - "os/exec" - - "github.com/tailscale/wireguard-go/tun" - "go4.org/netipx" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" - "tailscale.com/util/set" -) - -// For now this router only supports the WireGuard userspace implementation. -// There is an experimental kernel version in the works for OpenBSD: -// https://git.zx2c4.com/wireguard-openbsd. - -type openbsdRouter struct { - logf logger.Logf - netMon *netmon.Monitor - tunname string - local4 netip.Prefix - local6 netip.Prefix - routes set.Set[netip.Prefix] -} - -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - tunname, err := tundev.Name() - if err != nil { - return nil, err - } - - return &openbsdRouter{ - logf: logf, - netMon: netMon, - tunname: tunname, - }, nil -} - -func cmd(args ...string) *exec.Cmd { - if len(args) == 0 { - log.Fatalf("exec.Cmd(%#v) invalid; need argv[0]", args) - } - return exec.Command(args[0], args[1:]...) -} - -func (r *openbsdRouter) Up() error { - ifup := []string{"ifconfig", r.tunname, "up"} - if out, err := cmd(ifup...).CombinedOutput(); err != nil { - r.logf("running ifconfig failed: %v\n%s", err, out) - return err - } - return nil -} - -func inet(p netip.Prefix) string { - if p.Addr().Is6() { - return "inet6" - } - return "inet" -} - -func (r *openbsdRouter) Set(cfg *Config) error { - if cfg == nil { - cfg = &shutdownConfig - } - - // TODO: support configuring multiple local addrs on interface. - if len(cfg.LocalAddrs) == 0 { - return nil - } - numIPv4 := 0 - numIPv6 := 0 - localAddr4 := netip.Prefix{} - localAddr6 := netip.Prefix{} - for _, addr := range cfg.LocalAddrs { - if addr.Addr().Is4() { - numIPv4++ - localAddr4 = addr - } - if addr.Addr().Is6() { - numIPv6++ - localAddr6 = addr - } - } - if numIPv4 > 1 || numIPv6 > 1 { - return errors.New("openbsd doesn't support setting multiple local addrs yet") - } - - var errq error - - if localAddr4 != r.local4 { - if r.local4.IsValid() { - addrdel := []string{"ifconfig", r.tunname, - "inet", r.local4.String(), "-alias"} - out, err := cmd(addrdel...).CombinedOutput() - if err != nil { - r.logf("addr del failed: %v: %v\n%s", addrdel, err, out) - if errq == nil { - errq = err - } - } - - routedel := []string{"route", "-q", "-n", - "del", "-inet", r.local4.String(), - "-iface", r.local4.Addr().String()} - if out, err := cmd(routedel...).CombinedOutput(); err != nil { - r.logf("route del failed: %v: %v\n%s", routedel, err, out) - if errq == nil { - errq = err - } - } - } - - if localAddr4.IsValid() { - addradd := []string{"ifconfig", r.tunname, - "inet", localAddr4.String(), "alias"} - out, err := cmd(addradd...).CombinedOutput() - if err != nil { - r.logf("addr add failed: %v: %v\n%s", addradd, err, out) - if errq == nil { - errq = err - } - } - - routeadd := []string{"route", "-q", "-n", - "add", "-inet", localAddr4.String(), - "-iface", localAddr4.Addr().String()} - if out, err := cmd(routeadd...).CombinedOutput(); err != nil { - r.logf("route add failed: %v: %v\n%s", routeadd, err, out) - if errq == nil { - errq = err - } - } - } - } - - if localAddr6.IsValid() { - // in https://github.com/tailscale/tailscale/issues/1307 we made - // FreeBSD use a /48 for IPv6 addresses, which is nice because we - // don't need to additionally add routing entries. Do that here too. - localAddr6 = netip.PrefixFrom(localAddr6.Addr(), 48) - } - - if localAddr6 != r.local6 { - if r.local6.IsValid() { - addrdel := []string{"ifconfig", r.tunname, - "inet6", r.local6.String(), "delete"} - out, err := cmd(addrdel...).CombinedOutput() - if err != nil { - r.logf("addr del failed: %v: %v\n%s", addrdel, err, out) - if errq == nil { - errq = err - } - } - } - - if localAddr6.IsValid() { - addradd := []string{"ifconfig", r.tunname, - "inet6", localAddr6.String()} - out, err := cmd(addradd...).CombinedOutput() - if err != nil { - r.logf("addr add failed: %v: %v\n%s", addradd, err, out) - if errq == nil { - errq = err - } - } - } - } - - newRoutes := set.Set[netip.Prefix]{} - for _, route := range cfg.Routes { - newRoutes.Add(route) - } - for route := range r.routes { - if _, keep := newRoutes[route]; !keep { - net := netipx.PrefixIPNet(route) - nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Bits()) - dst := localAddr4.Addr().String() - if route.Addr().Is6() { - dst = localAddr6.Addr().String() - } - routedel := []string{"route", "-q", "-n", - "del", "-" + inet(route), nstr, - "-iface", dst} - out, err := cmd(routedel...).CombinedOutput() - if err != nil { - r.logf("route del failed: %v: %v\n%s", routedel, err, out) - if errq == nil { - errq = err - } - } - } - } - for route := range newRoutes { - if _, exists := r.routes[route]; !exists { - net := netipx.PrefixIPNet(route) - nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Bits()) - dst := localAddr4.Addr().String() - if route.Addr().Is6() { - dst = localAddr6.Addr().String() - } - routeadd := []string{"route", "-q", "-n", - "add", "-" + inet(route), nstr, - "-iface", dst} - out, err := cmd(routeadd...).CombinedOutput() - if err != nil { - r.logf("addr add failed: %v: %v\n%s", routeadd, err, out) - if errq == nil { - errq = err - } - } - } - } - - r.local4 = localAddr4 - r.local6 = localAddr6 - r.routes = newRoutes - - return errq -} - -// UpdateMagicsockPort implements the Router interface. This implementation -// does nothing and returns nil because this router does not currently need -// to know what the magicsock UDP port is. -func (r *openbsdRouter) UpdateMagicsockPort(_ uint16, _ string) error { - return nil -} - -func (r *openbsdRouter) Close() error { - cleanUp(r.logf, r.tunname) - return nil -} - -func cleanUp(logf logger.Logf, interfaceName string) { - out, err := cmd("ifconfig", interfaceName, "down").CombinedOutput() - if err != nil { - logf("ifconfig down: %v\n%s", err, out) - } -} diff --git a/vendor/tailscale.com/wgengine/router/router_userspace_bsd.go b/vendor/tailscale.com/wgengine/router/router_userspace_bsd.go deleted file mode 100644 index 0b7e4f3..0000000 --- a/vendor/tailscale.com/wgengine/router/router_userspace_bsd.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build darwin || freebsd - -package router - -import ( - "fmt" - "log" - "net/netip" - "os/exec" - "runtime" - - "github.com/tailscale/wireguard-go/tun" - "go4.org/netipx" - "tailscale.com/health" - "tailscale.com/net/netmon" - "tailscale.com/net/tsaddr" - "tailscale.com/types/logger" - "tailscale.com/version" -) - -type userspaceBSDRouter struct { - logf logger.Logf - netMon *netmon.Monitor - health *health.Tracker - tunname string - local []netip.Prefix - routes map[netip.Prefix]bool -} - -func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - tunname, err := tundev.Name() - if err != nil { - return nil, err - } - - return &userspaceBSDRouter{ - logf: logf, - netMon: netMon, - health: health, - tunname: tunname, - }, nil -} - -func (r *userspaceBSDRouter) addrsToRemove(newLocalAddrs []netip.Prefix) (remove []netip.Prefix) { - for _, cur := range r.local { - found := false - for _, v := range newLocalAddrs { - found = (v == cur) - if found { - break - } - } - if !found { - remove = append(remove, cur) - } - } - return -} - -func (r *userspaceBSDRouter) addrsToAdd(newLocalAddrs []netip.Prefix) (add []netip.Prefix) { - for _, cur := range newLocalAddrs { - found := false - for _, v := range r.local { - found = (v == cur) - if found { - break - } - } - if !found { - add = append(add, cur) - } - } - return -} - -func cmd(args ...string) *exec.Cmd { - if len(args) == 0 { - log.Fatalf("exec.Cmd(%#v) invalid; need argv[0]", args) - } - return exec.Command(args[0], args[1:]...) -} - -func (r *userspaceBSDRouter) Up() error { - ifup := []string{"ifconfig", r.tunname, "up"} - if out, err := cmd(ifup...).CombinedOutput(); err != nil { - r.logf("running ifconfig failed: %v\n%s", err, out) - return err - } - return nil -} - -func inet(p netip.Prefix) string { - if p.Addr().Is6() { - return "inet6" - } - return "inet" -} - -func (r *userspaceBSDRouter) Set(cfg *Config) (reterr error) { - if cfg == nil { - cfg = &shutdownConfig - } - - setErr := func(err error) { - if reterr == nil { - reterr = err - } - } - addrsToRemove := r.addrsToRemove(cfg.LocalAddrs) - - // If we're removing all addresses, we need to remove and re-add all - // routes. - resetRoutes := len(r.local) > 0 && len(addrsToRemove) == len(r.local) - - // Update the addresses. - for _, addr := range addrsToRemove { - arg := []string{"ifconfig", r.tunname, inet(addr), addr.String(), "-alias"} - out, err := cmd(arg...).CombinedOutput() - if err != nil { - r.logf("addr del failed: %v => %v\n%s", arg, err, out) - setErr(err) - } - } - for _, addr := range r.addrsToAdd(cfg.LocalAddrs) { - var arg []string - if runtime.GOOS == "freebsd" && addr.Addr().Is6() && addr.Bits() == 128 { - // FreeBSD rejects tun addresses of the form fc00::1/128 -> fc00::1, - // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=218508 - // Instead add our whole /48, which works because we use a /48 route. - // Full history: https://github.com/tailscale/tailscale/issues/1307 - tmp := netip.PrefixFrom(addr.Addr(), 48) - arg = []string{"ifconfig", r.tunname, inet(tmp), tmp.String()} - } else { - arg = []string{"ifconfig", r.tunname, inet(addr), addr.String(), addr.Addr().String()} - } - out, err := cmd(arg...).CombinedOutput() - if err != nil { - r.logf("addr add failed: %v => %v\n%s", arg, err, out) - setErr(err) - } - } - - newRoutes := make(map[netip.Prefix]bool) - for _, route := range cfg.Routes { - if runtime.GOOS != "darwin" && route == tsaddr.TailscaleULARange() { - // Because we added the interface address as a /48 above, - // the kernel already created the Tailscale ULA route - // implicitly. We mustn't try to add/delete it ourselves. - continue - } - newRoutes[route] = true - } - // Delete any preexisting routes. - for route := range r.routes { - if resetRoutes || !newRoutes[route] { - net := netipx.PrefixIPNet(route) - nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Bits()) - del := "del" - if version.OS() == "macOS" { - del = "delete" - } - routedel := []string{"route", "-q", "-n", - del, "-" + inet(route), nstr, - "-iface", r.tunname} - out, err := cmd(routedel...).CombinedOutput() - if err != nil { - r.logf("route del failed: %v: %v\n%s", routedel, err, out) - setErr(err) - } - } - } - // Add the routes. - for route := range newRoutes { - if resetRoutes || !r.routes[route] { - net := netipx.PrefixIPNet(route) - nip := net.IP.Mask(net.Mask) - nstr := fmt.Sprintf("%v/%d", nip, route.Bits()) - routeadd := []string{"route", "-q", "-n", - "add", "-" + inet(route), nstr, - "-iface", r.tunname} - out, err := cmd(routeadd...).CombinedOutput() - if err != nil { - r.logf("addr add failed: %v: %v\n%s", routeadd, err, out) - setErr(err) - } - } - } - - // Store the interface and routes so we know what to change on an update. - if reterr == nil { - r.local = append([]netip.Prefix{}, cfg.LocalAddrs...) - } - r.routes = newRoutes - - return reterr -} - -// UpdateMagicsockPort implements the Router interface. This implementation -// does nothing and returns nil because this router does not currently need -// to know what the magicsock UDP port is. -func (r *userspaceBSDRouter) UpdateMagicsockPort(_ uint16, _ string) error { - return nil -} - -func (r *userspaceBSDRouter) Close() error { - return nil -} diff --git a/vendor/tailscale.com/wgengine/router/router_windows.go b/vendor/tailscale.com/wgengine/router/router_windows.go deleted file mode 100644 index 6416366..0000000 --- a/vendor/tailscale.com/wgengine/router/router_windows.go +++ /dev/null @@ -1,400 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package router - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "io" - "net/netip" - "os" - "os/exec" - "path/filepath" - "slices" - "strings" - "sync" - "syscall" - "time" - - "github.com/tailscale/wireguard-go/tun" - "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" - "tailscale.com/health" - "tailscale.com/logtail/backoff" - "tailscale.com/net/dns" - "tailscale.com/net/netmon" - "tailscale.com/types/logger" -) - -type winRouter struct { - logf func(fmt string, args ...any) - netMon *netmon.Monitor // may be nil - health *health.Tracker - nativeTun *tun.NativeTun - routeChangeCallback *winipcfg.RouteChangeCallback - firewall *firewallTweaker -} - -func newUserspaceRouter(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { - nativeTun := tundev.(*tun.NativeTun) - luid := winipcfg.LUID(nativeTun.LUID()) - guid, err := luid.GUID() - if err != nil { - return nil, err - } - - return &winRouter{ - logf: logf, - netMon: netMon, - health: health, - nativeTun: nativeTun, - firewall: &firewallTweaker{ - logf: logger.WithPrefix(logf, "firewall: "), - tunGUID: *guid, - }, - }, nil -} - -func (r *winRouter) Up() error { - r.firewall.clear() - - var err error - t0 := time.Now() - r.routeChangeCallback, err = monitorDefaultRoutes(r.nativeTun) - d := time.Since(t0).Round(time.Millisecond) - if err != nil { - return fmt.Errorf("monitorDefaultRoutes, after %v: %v", d, err) - } - r.logf("monitorDefaultRoutes done after %v", d) - return nil -} - -func (r *winRouter) Set(cfg *Config) error { - if cfg == nil { - cfg = &shutdownConfig - } - - var localAddrs []string - for _, la := range cfg.LocalAddrs { - localAddrs = append(localAddrs, la.String()) - } - r.firewall.set(localAddrs, cfg.Routes, cfg.LocalRoutes) - - err := configureInterface(cfg, r.nativeTun, r.health) - if err != nil { - r.logf("ConfigureInterface: %v", err) - return err - } - - // Flush DNS on router config change to clear cached DNS entries (solves #1430) - if err := dns.Flush(); err != nil { - r.logf("flushdns error: %v", err) - } - - return nil -} - -func hasDefaultRoute(routes []netip.Prefix) bool { - for _, route := range routes { - if route.Bits() == 0 { - return true - } - } - return false -} - -// UpdateMagicsockPort implements the Router interface. This implementation -// does nothing and returns nil because this router does not currently need -// to know what the magicsock UDP port is. -func (r *winRouter) UpdateMagicsockPort(_ uint16, _ string) error { - return nil -} - -func (r *winRouter) Close() error { - r.firewall.clear() - - if r.routeChangeCallback != nil { - r.routeChangeCallback.Unregister() - } - - return nil -} - -func cleanUp(logf logger.Logf, interfaceName string) { - // Nothing to do here. -} - -// firewallTweaker changes the Windows firewall. Normally this wouldn't be so complicated, -// but it can be REALLY SLOW to change the Windows firewall for reasons not understood. -// Like 4 minutes slow. But usually it's tens of milliseconds. -// See https://github.com/tailscale/tailscale/issues/785. -// So this tracks the desired state and runs the actual adjusting code asynchronously. -type firewallTweaker struct { - logf logger.Logf - tunGUID windows.GUID - - mu sync.Mutex - didProcRule bool - running bool // doAsyncSet goroutine is running - known bool // firewall is in known state (in lastVal) - wantLocal []string // next value we want, or "" to delete the firewall rule - lastLocal []string // last set value, if known - - localRoutes []netip.Prefix - lastLocalRoutes []netip.Prefix - - wantKillswitch bool - lastKillswitch bool - - // Only touched by doAsyncSet, so mu doesn't need to be held. - - // fwProc is a subprocess that runs the wireguard-windows firewall - // killswitch code. It is only non-nil when the default route - // killswitch is active, and may go back and forth between nil and - // non-nil any number of times during the process's lifetime. - fwProc *exec.Cmd - // stop makes fwProc exit when closed. - fwProcWriter io.WriteCloser - fwProcEncoder *json.Encoder - - // The path to the 'netsh.exe' binary, populated during the first call - // to runFirewall. - // - // not protected by mu; netshPath is only mutated inside netshPathOnce - netshPathOnce sync.Once - netshPath string -} - -func (ft *firewallTweaker) clear() { ft.set(nil, nil, nil) } - -// set takes CIDRs to allow, and the routes that point into the Tailscale tun interface. -// Empty slices remove firewall rules. -// -// set takes ownership of cidrs, but not routes. -func (ft *firewallTweaker) set(cidrs []string, routes, localRoutes []netip.Prefix) { - ft.mu.Lock() - defer ft.mu.Unlock() - - if len(cidrs) == 0 { - ft.logf("marking for removal") - } else { - ft.logf("marking allowed %v", cidrs) - } - ft.wantLocal = cidrs - ft.localRoutes = localRoutes - ft.wantKillswitch = hasDefaultRoute(routes) - if ft.running { - // The doAsyncSet goroutine will check ft.wantLocal/wantKillswitch - // before returning. - return - } - ft.logf("starting netsh goroutine") - ft.running = true - go ft.doAsyncSet() -} - -// getNetshPath returns the path that should be used to execute netsh. -// -// We've seen a report from a customer that we're triggering the "cannot run -// executable found relative to current directory" protection that was added to -// prevent running possibly attacker-controlled binaries. To mitigate this, -// first try looking up the path to netsh.exe in the System32 directory -// explicitly, and then fall back to the prior behaviour of passing "netsh" to -// os/exec.Command. -func (ft *firewallTweaker) getNetshPath() string { - ft.netshPathOnce.Do(func() { - // The default value is the old approach: just run "netsh" and - // let os/exec resolve that into a full path. - ft.netshPath = "netsh" - - path, err := windows.KnownFolderPath(windows.FOLDERID_System, 0) - if err != nil { - ft.logf("getNetshPath: error getting FOLDERID_System: %v", err) - return - } - - expath := filepath.Join(path, "netsh.exe") - if _, err := os.Stat(expath); err == nil { - ft.netshPath = expath - return - } else if !os.IsNotExist(err) { - ft.logf("getNetshPath: error checking for existence of %q: %v", expath, err) - } - - // Keep default - }) - return ft.netshPath -} - -func (ft *firewallTweaker) runFirewall(args ...string) (time.Duration, error) { - t0 := time.Now() - args = append([]string{"advfirewall", "firewall"}, args...) - cmd := exec.Command(ft.getNetshPath(), args...) - cmd.SysProcAttr = &syscall.SysProcAttr{ - CreationFlags: windows.DETACHED_PROCESS, - } - b, err := cmd.CombinedOutput() - if err != nil { - err = fmt.Errorf("%w: %v", err, string(b)) - } - return time.Since(t0).Round(time.Millisecond), err -} - -func (ft *firewallTweaker) doAsyncSet() { - bo := backoff.NewBackoff("win-firewall", ft.logf, time.Minute) - ctx := context.Background() - - ft.mu.Lock() - for { // invariant: ft.mu must be locked when beginning this block - val := ft.wantLocal - if ft.known && slices.Equal(ft.lastLocal, val) && ft.wantKillswitch == ft.lastKillswitch && slices.Equal(ft.localRoutes, ft.lastLocalRoutes) { - ft.running = false - ft.logf("ending netsh goroutine") - ft.mu.Unlock() - return - } - wantKillswitch := ft.wantKillswitch - needClear := !ft.known || len(ft.lastLocal) > 0 || len(val) == 0 - needProcRule := !ft.didProcRule - localRoutes := ft.localRoutes - ft.mu.Unlock() - - err := ft.doSet(val, wantKillswitch, needClear, needProcRule, localRoutes) - if err != nil { - ft.logf("set failed: %v", err) - } - bo.BackOff(ctx, err) - - ft.mu.Lock() - ft.lastLocal = val - ft.lastLocalRoutes = localRoutes - ft.lastKillswitch = wantKillswitch - ft.known = (err == nil) - } -} - -// doSet creates and deletes firewall rules to make the system state -// match the values of local, killswitch, clear and procRule. -// -// local is the list of local Tailscale addresses (formatted as CIDR -// prefixes) to allow through the Windows firewall. -// killswitch, if true, enables the wireguard-windows based internet -// killswitch to prevent use of non-Tailscale default routes. -// clear, if true, removes all tailscale address firewall rules before -// adding local. -// procRule, if true, installs a firewall rule that permits the Tailscale -// process to dial out as it pleases. -// -// Must only be invoked from doAsyncSet. -func (ft *firewallTweaker) doSet(local []string, killswitch bool, clear bool, procRule bool, allowedRoutes []netip.Prefix) error { - if clear { - ft.logf("clearing Tailscale-In firewall rules...") - // We ignore the error here, because netsh returns an error for - // deleting something that doesn't match. - // TODO(bradfitz): care? That'd involve querying it before/after to see - // whether it was necessary/worked. But the output format is localized, - // so can't rely on parsing English. Maybe need to use OLE, not netsh.exe? - d, _ := ft.runFirewall("delete", "rule", "name=Tailscale-In", "dir=in") - ft.logf("cleared Tailscale-In firewall rules in %v", d) - } - if procRule { - ft.logf("deleting any prior Tailscale-Process rule...") - d, err := ft.runFirewall("delete", "rule", "name=Tailscale-Process", "dir=in") // best effort - if err == nil { - ft.logf("removed old Tailscale-Process rule in %v", d) - } - var exe string - exe, err = os.Executable() - if err != nil { - ft.logf("failed to find Executable for Tailscale-Process rule: %v", err) - } else { - ft.logf("adding Tailscale-Process rule to allow UDP for %q ...", exe) - d, err = ft.runFirewall("add", "rule", "name=Tailscale-Process", - "dir=in", - "action=allow", - "edge=yes", - "program="+exe, - "protocol=udp", - "profile=any", - "enable=yes", - ) - if err != nil { - ft.logf("error adding Tailscale-Process rule: %v", err) - } else { - ft.mu.Lock() - ft.didProcRule = true - ft.mu.Unlock() - ft.logf("added Tailscale-Process rule in %v", d) - } - } - } - for _, cidr := range local { - ft.logf("adding Tailscale-In rule to allow %v ...", cidr) - var d time.Duration - d, err := ft.runFirewall("add", "rule", "name=Tailscale-In", "dir=in", "action=allow", "localip="+cidr, "profile=private,domain", "enable=yes") - if err != nil { - ft.logf("error adding Tailscale-In rule to allow %v: %v", cidr, err) - return err - } - ft.logf("added Tailscale-In rule to allow %v in %v", cidr, d) - } - - if !killswitch { - if ft.fwProc != nil { - ft.fwProcWriter.Close() - ft.fwProcWriter = nil - ft.fwProc.Wait() - ft.fwProc = nil - ft.fwProcEncoder = nil - } - return nil - } - if ft.fwProc == nil { - exe, err := os.Executable() - if err != nil { - return err - } - proc := exec.Command(exe, "/firewall", ft.tunGUID.String()) - proc.SysProcAttr = &syscall.SysProcAttr{ - CreationFlags: windows.DETACHED_PROCESS, - } - in, err := proc.StdinPipe() - if err != nil { - return err - } - out, err := proc.StdoutPipe() - if err != nil { - in.Close() - return err - } - - go func(out io.ReadCloser) { - b := bufio.NewReaderSize(out, 1<<10) - for { - line, err := b.ReadString('\n') - if err != nil { - return - } - line = strings.TrimSpace(line) - if line != "" { - ft.logf("fw-child: %s", line) - } - } - }(out) - proc.Stderr = proc.Stdout - - if err := proc.Start(); err != nil { - return err - } - ft.fwProcWriter = in - ft.fwProc = proc - ft.fwProcEncoder = json.NewEncoder(in) - } - // Note(maisem): when local lan access toggled, we need to inform the - // firewall to let the local routes through. The set of routes is passed - // in via stdin encoded in json. - return ft.fwProcEncoder.Encode(allowedRoutes) -} diff --git a/vendor/tailscale.com/wgengine/router/runner.go b/vendor/tailscale.com/wgengine/router/runner.go deleted file mode 100644 index 8fa068e..0000000 --- a/vendor/tailscale.com/wgengine/router/runner.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build linux - -package router - -import ( - "errors" - "fmt" - "os" - "os/exec" - "strconv" - "strings" - "syscall" - - "golang.org/x/sys/unix" -) - -// commandRunner abstracts helpers to run OS commands. It exists -// purely to swap out osCommandRunner (below) with a fake runner in -// tests. -type commandRunner interface { - run(...string) error - output(...string) ([]byte, error) -} - -type osCommandRunner struct { - // ambientCapNetAdmin determines whether commands are executed with - // CAP_NET_ADMIN. - // CAP_NET_ADMIN is required when running as non-root and executing cmds - // like `ip rule`. Even if our process has the capability, we need to - // explicitly grant it to the new process. - // We specifically need this for Synology DSM7 where tailscaled no longer - // runs as root. - ambientCapNetAdmin bool -} - -// errCode extracts and returns the process exit code from err, or -// zero if err is nil. -func errCode(err error) int { - if err == nil { - return 0 - } - var e *exec.ExitError - if ok := errors.As(err, &e); ok { - return e.ExitCode() - } - s := err.Error() - if strings.HasPrefix(s, "exitcode:") { - code, err := strconv.Atoi(s[9:]) - if err == nil { - return code - } - } - return -42 -} - -func (o osCommandRunner) run(args ...string) error { - _, err := o.output(args...) - return err -} - -func (o osCommandRunner) output(args ...string) ([]byte, error) { - if len(args) == 0 { - return nil, errors.New("cmd: no argv[0]") - } - - cmd := exec.Command(args[0], args[1:]...) - cmd.Env = append(os.Environ(), "LC_ALL=C") - if o.ambientCapNetAdmin { - cmd.SysProcAttr = &syscall.SysProcAttr{ - AmbientCaps: []uintptr{unix.CAP_NET_ADMIN}, - } - } - out, err := cmd.CombinedOutput() - if err != nil { - return nil, fmt.Errorf("running %q failed: %w\n%s", strings.Join(args, " "), err, out) - } - - return out, nil -} - -type runGroup struct { - OkCode []int // error codes that are acceptable, other than 0, if any - Runner commandRunner // the runner that actually runs our commands - ErrAcc error // first error encountered, if any -} - -func newRunGroup(okCode []int, runner commandRunner) *runGroup { - return &runGroup{ - OkCode: okCode, - Runner: runner, - } -} - -func (rg *runGroup) okCode(err error) bool { - got := errCode(err) - for _, want := range rg.OkCode { - if got == want { - return true - } - } - return false -} - -func (rg *runGroup) Output(args ...string) []byte { - b, err := rg.Runner.output(args...) - if rg.ErrAcc == nil && err != nil && !rg.okCode(err) { - rg.ErrAcc = err - } - return b -} - -func (rg *runGroup) Run(args ...string) { - err := rg.Runner.run(args...) - if rg.ErrAcc == nil && err != nil && !rg.okCode(err) { - rg.ErrAcc = err - } -} diff --git a/vendor/tailscale.com/wgengine/userspace.go b/vendor/tailscale.com/wgengine/userspace.go index b51b2c8..875011a 100644 --- a/vendor/tailscale.com/wgengine/userspace.go +++ b/vendor/tailscale.com/wgengine/userspace.go @@ -10,8 +10,10 @@ import ( "errors" "fmt" "io" + "maps" "math" "net/netip" + "reflect" "runtime" "slices" "strings" @@ -23,17 +25,18 @@ import ( "tailscale.com/control/controlknobs" "tailscale.com/drive" "tailscale.com/envknob" + "tailscale.com/feature" + "tailscale.com/feature/buildfeatures" "tailscale.com/health" "tailscale.com/ipn/ipnstate" "tailscale.com/net/dns" - "tailscale.com/net/flowtrack" + "tailscale.com/net/dns/resolver" "tailscale.com/net/ipset" "tailscale.com/net/netmon" "tailscale.com/net/packet" "tailscale.com/net/sockstats" "tailscale.com/net/tsaddr" "tailscale.com/net/tsdial" - "tailscale.com/net/tshttpproxy" "tailscale.com/net/tstun" "tailscale.com/syncs" "tailscale.com/tailcfg" @@ -44,8 +47,11 @@ import ( "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/types/views" + "tailscale.com/util/backoff" + "tailscale.com/util/checkchange" "tailscale.com/util/clientmetric" - "tailscale.com/util/deephash" + "tailscale.com/util/eventbus" + "tailscale.com/util/execqueue" "tailscale.com/util/mak" "tailscale.com/util/set" "tailscale.com/util/testenv" @@ -89,23 +95,29 @@ const statusPollInterval = 1 * time.Minute const networkLoggerUploadTimeout = 5 * time.Second type userspaceEngine struct { - logf logger.Logf - wgLogger *wglog.Logger //a wireguard-go logging wrapper - reqCh chan struct{} - waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool - timeNow func() mono.Time - tundev *tstun.Wrapper - wgdev *device.Device - router router.Router - confListenPort uint16 // original conf.ListenPort - dns *dns.Manager - magicConn *magicsock.Conn - netMon *netmon.Monitor - health *health.Tracker - netMonOwned bool // whether we created netMon (and thus need to close it) - netMonUnregister func() // unsubscribes from changes; used regardless of netMonOwned - birdClient BIRDClient // or nil - controlKnobs *controlknobs.Knobs // or nil + // eventBus will eventually become required, but for now may be nil. + eventBus *eventbus.Bus + eventClient *eventbus.Client + + linkChangeQueue execqueue.ExecQueue + + logf logger.Logf + wgLogger *wglog.Logger // a wireguard-go logging wrapper + reqCh chan struct{} + waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool + timeNow func() mono.Time + tundev *tstun.Wrapper + wgdev *device.Device + router router.Router + dialer *tsdial.Dialer + confListenPort uint16 // original conf.ListenPort + dns *dns.Manager + magicConn *magicsock.Conn + netMon *netmon.Monitor + health *health.Tracker + netMonOwned bool // whether we created netMon (and thus need to close it) + birdClient BIRDClient // or nil + controlKnobs *controlknobs.Knobs // or nil testMaybeReconfigHook func() // for tests; if non-nil, fires if maybeReconfigWireguardLocked called @@ -121,11 +133,11 @@ type userspaceEngine struct { wgLock sync.Mutex // serializes all wgdev operations; see lock order comment below lastCfgFull wgcfg.Config lastNMinPeers int - lastRouterSig deephash.Sum // of router.Config - lastEngineSigFull deephash.Sum // of full wireguard config - lastEngineSigTrim deephash.Sum // of trimmed wireguard config - lastDNSConfig *dns.Config - lastIsSubnetRouter bool // was the node a primary subnet router in the last run. + lastRouter *router.Config + lastEngineFull *wgcfg.Config // of full wireguard config, not trimmed + lastEngineInputs *maybeReconfigInputs + lastDNSConfig dns.ConfigView // or invalid if none + lastIsSubnetRouter bool // was the node a primary subnet router in the last run. recvActivityAt map[key.NodePublic]mono.Time trimmedNodes map[key.NodePublic]bool // set of node keys of peers currently excluded from wireguard config sentActivityAt map[netip.Addr]*mono.Time // value is accessed atomically @@ -137,9 +149,9 @@ type userspaceEngine struct { netMap *netmap.NetworkMap // or nil closing bool // Close was called (even if we're still closing) statusCallback StatusCallback - peerSequence []key.NodePublic + peerSequence views.Slice[key.NodePublic] endpoints []tailcfg.Endpoint - pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go + pendOpen map[flowtrackTuple]*pendingOpenFlow // see pendopen.go // pongCallback is the map of response handlers waiting for disco or TSMP // pong callbacks. The map key is a random slice of bytes. @@ -227,6 +239,13 @@ type Config struct { // DriveForLocal, if populated, will cause the engine to expose a Taildrive // listener at 100.100.100.100:8080. DriveForLocal drive.FileSystemForLocal + + // EventBus, if non-nil, is used for event publication and subscription by + // the Engine and its subsystems. + // + // TODO(creachadair): As of 2025-03-19 this is optional, but is intended to + // become required non-nil. + EventBus *eventbus.Bus } // NewFakeUserspaceEngine returns a new userspace engine for testing. @@ -255,6 +274,8 @@ func NewFakeUserspaceEngine(logf logger.Logf, opts ...any) (Engine, error) { conf.HealthTracker = v case *usermetric.Registry: conf.Metrics = v + case *eventbus.Bus: + conf.EventBus = v default: return nil, fmt.Errorf("unknown option type %T", v) } @@ -295,13 +316,16 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) } if conf.Dialer == nil { conf.Dialer = &tsdial.Dialer{Logf: logf} + if conf.EventBus != nil { + conf.Dialer.SetBus(conf.EventBus) + } } var tsTUNDev *tstun.Wrapper if conf.IsTAP { - tsTUNDev = tstun.WrapTAP(logf, conf.Tun, conf.Metrics) + tsTUNDev = tstun.WrapTAP(logf, conf.Tun, conf.Metrics, conf.EventBus) } else { - tsTUNDev = tstun.Wrap(logf, conf.Tun, conf.Metrics) + tsTUNDev = tstun.Wrap(logf, conf.Tun, conf.Metrics, conf.EventBus) } closePool.add(tsTUNDev) @@ -323,12 +347,14 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) } e := &userspaceEngine{ + eventBus: conf.EventBus, timeNow: mono.Now, logf: logf, reqCh: make(chan struct{}, 1), waitCh: make(chan struct{}), tundev: tsTUNDev, router: rtr, + dialer: conf.Dialer, confListenPort: conf.ListenPort, birdClient: conf.BIRDClient, controlKnobs: conf.ControlKnobs, @@ -348,7 +374,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) if conf.NetMon != nil { e.netMon = conf.NetMon } else { - mon, err := netmon.New(logf) + mon, err := netmon.New(conf.EventBus, logf) if err != nil { return nil, err } @@ -360,20 +386,14 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) tunName, _ := conf.Tun.Name() conf.Dialer.SetTUNName(tunName) conf.Dialer.SetNetMon(e.netMon) - e.dns = dns.NewManager(logf, conf.DNS, e.health, conf.Dialer, fwdDNSLinkSelector{e, tunName}, conf.ControlKnobs, runtime.GOOS) + conf.Dialer.SetBus(e.eventBus) + e.dns = dns.NewManager(logf, conf.DNS, e.health, conf.Dialer, fwdDNSLinkSelector{e, tunName}, conf.ControlKnobs, runtime.GOOS, e.eventBus) // TODO: there's probably a better place for this sockstats.SetNetMon(e.netMon) logf("link state: %+v", e.netMon.InterfaceState()) - unregisterMonWatch := e.netMon.RegisterChangeCallback(func(delta *netmon.ChangeDelta) { - tshttpproxy.InvalidateCache() - e.linkChange(delta) - }) - closePool.addFunc(unregisterMonWatch) - e.netMonUnregister = unregisterMonWatch - endpointsFn := func(endpoints []tailcfg.Endpoint) { e.mu.Lock() e.endpoints = append(e.endpoints[:0], endpoints...) @@ -381,26 +401,21 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) e.RequestStatus() } - onPortUpdate := func(port uint16, network string) { - e.logf("onPortUpdate(port=%v, network=%s)", port, network) - - if err := e.router.UpdateMagicsockPort(port, network); err != nil { - e.logf("UpdateMagicsockPort(port=%v, network=%s) failed: %v", port, network, err) - } - } magicsockOpts := magicsock.Options{ - Logf: logf, - Port: conf.ListenPort, - EndpointsFunc: endpointsFn, - DERPActiveFunc: e.RequestStatus, - IdleFunc: e.tundev.IdleDuration, - NoteRecvActivity: e.noteRecvActivity, - NetMon: e.netMon, - HealthTracker: e.health, - Metrics: conf.Metrics, - ControlKnobs: conf.ControlKnobs, - OnPortUpdate: onPortUpdate, - PeerByKeyFunc: e.PeerByKey, + EventBus: e.eventBus, + Logf: logf, + Port: conf.ListenPort, + EndpointsFunc: endpointsFn, + DERPActiveFunc: e.RequestStatus, + IdleFunc: e.tundev.IdleDuration, + NetMon: e.netMon, + HealthTracker: e.health, + Metrics: conf.Metrics, + ControlKnobs: conf.ControlKnobs, + PeerByKeyFunc: e.PeerByKey, + } + if buildfeatures.HasLazyWG { + magicsockOpts.NoteRecvActivity = e.noteRecvActivity } var err error @@ -418,7 +433,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) } e.tundev.PreFilterPacketOutboundToWireGuardEngineIntercept = e.handleLocalPackets - if envknob.BoolDefaultTrue("TS_DEBUG_CONNECT_FAILURES") { + if buildfeatures.HasDebug && envknob.BoolDefaultTrue("TS_DEBUG_CONNECT_FAILURES") { if e.tundev.PreFilterPacketInboundFromWireGuard != nil { return nil, errors.New("unexpected PreFilterIn already set") } @@ -436,6 +451,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) cb := e.pongCallback[pong.Data] e.logf("wgengine: got TSMP pong %02x, peerAPIPort=%v; cb=%v", pong.Data, pong.PeerAPIPort, cb != nil) if cb != nil { + delete(e.pongCallback, pong.Data) go cb(pong) } } @@ -449,6 +465,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) // We didn't swallow it, so let it flow to the host. return false } + delete(e.icmpEchoResponseCallback, idSeq) e.logf("wgengine: got diagnostic ICMP response %02x", idSeq) go cb() return true @@ -527,6 +544,31 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) } } + ec := e.eventBus.Client("userspaceEngine") + eventbus.SubscribeFunc(ec, func(cd netmon.ChangeDelta) { + if f, ok := feature.HookProxyInvalidateCache.GetOk(); ok { + f() + } + e.linkChangeQueue.Add(func() { e.linkChange(&cd) }) + }) + eventbus.SubscribeFunc(ec, func(update tstun.DiscoKeyAdvertisement) { + e.logf("wgengine: got TSMP disco key advertisement from %v via eventbus", update.Src) + if e.magicConn == nil { + e.logf("wgengine: no magicConn") + return + } + + pkt := packet.TSMPDiscoKeyAdvertisement{ + Key: update.Key, + } + peer, ok := e.PeerForIP(update.Src) + if !ok { + e.logf("wgengine: no peer found for %v", update.Src) + return + } + e.magicConn.HandleDiscoKeyAdvertisement(peer.Node, pkt) + }) + e.eventClient = ec e.logf("Engine created.") return e, nil } @@ -569,6 +611,17 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) return filter.Drop } } + if runtime.GOOS == "plan9" { + isLocalAddr, ok := e.isLocalAddr.LoadOk() + if ok { + if isLocalAddr(p.Dst.Addr()) { + // On Plan9's "tun" equivalent, everything goes back in and out + // the tun, even when the kernel's replying to itself. + t.InjectInboundCopy(p.Buffer()) + return filter.Drop + } + } + } return filter.Accept } @@ -672,6 +725,29 @@ func (e *userspaceEngine) isActiveSinceLocked(nk key.NodePublic, ip netip.Addr, return timePtr.LoadAtomic().After(t) } +// maybeReconfigInputs holds the inputs to the maybeReconfigWireguardLocked +// function. If these things don't change between calls, there's nothing to do. +type maybeReconfigInputs struct { + WGConfig *wgcfg.Config + TrimmedNodes map[key.NodePublic]bool + TrackNodes views.Slice[key.NodePublic] + TrackIPs views.Slice[netip.Addr] +} + +func (i *maybeReconfigInputs) Equal(o *maybeReconfigInputs) bool { + return reflect.DeepEqual(i, o) +} + +func (i *maybeReconfigInputs) Clone() *maybeReconfigInputs { + if i == nil { + return nil + } + v := *i + v.WGConfig = i.WGConfig.Clone() + v.TrimmedNodes = maps.Clone(i.TrimmedNodes) + return &v +} + // discoChanged are the set of peers whose disco keys have changed, implying they've restarted. // If a peer is in this set and was previously in the live wireguard config, // it needs to be first removed and then re-added to flush out its wireguard session key. @@ -697,15 +773,22 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node // the past 5 minutes. That's more than WireGuard's key // rotation time anyway so it's no harm if we remove it // later if it's been inactive. - activeCutoff := e.timeNow().Add(-lazyPeerIdleThreshold) + var activeCutoff mono.Time + if buildfeatures.HasLazyWG { + activeCutoff = e.timeNow().Add(-lazyPeerIdleThreshold) + } // Not all peers can be trimmed from the network map (see // isTrimmablePeer). For those that are trimmable, keep track of // their NodeKey and Tailscale IPs. These are the ones we'll need // to install tracking hooks for to watch their send/receive // activity. - trackNodes := make([]key.NodePublic, 0, len(full.Peers)) - trackIPs := make([]netip.Addr, 0, len(full.Peers)) + var trackNodes []key.NodePublic + var trackIPs []netip.Addr + if buildfeatures.HasLazyWG { + trackNodes = make([]key.NodePublic, 0, len(full.Peers)) + trackIPs = make([]netip.Addr, 0, len(full.Peers)) + } // Don't re-alloc the map; the Go compiler optimizes map clears as of // Go 1.11, so we can re-use the existing + allocated map. @@ -719,7 +802,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node for i := range full.Peers { p := &full.Peers[i] nk := p.PublicKey - if !e.isTrimmablePeer(p, len(full.Peers)) { + if !buildfeatures.HasLazyWG || !e.isTrimmablePeer(p, len(full.Peers)) { min.Peers = append(min.Peers, *p) if discoChanged[nk] { needRemoveStep = true @@ -743,16 +826,18 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node } e.lastNMinPeers = len(min.Peers) - if changed := deephash.Update(&e.lastEngineSigTrim, &struct { - WGConfig *wgcfg.Config - TrimmedNodes map[key.NodePublic]bool - TrackNodes []key.NodePublic - TrackIPs []netip.Addr - }{&min, e.trimmedNodes, trackNodes, trackIPs}); !changed { + if changed := checkchange.Update(&e.lastEngineInputs, &maybeReconfigInputs{ + WGConfig: &min, + TrimmedNodes: e.trimmedNodes, + TrackNodes: views.SliceOf(trackNodes), + TrackIPs: views.SliceOf(trackIPs), + }); !changed { return nil } - e.updateActivityMapsLocked(trackNodes, trackIPs) + if buildfeatures.HasLazyWG { + e.updateActivityMapsLocked(trackNodes, trackIPs) + } if needRemoveStep { minner := min @@ -788,6 +873,9 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node // // e.wgLock must be held. func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic, trackIPs []netip.Addr) { + if !buildfeatures.HasLazyWG { + return + } // Generate the new map of which nodekeys we want to track // receive times for. mr := map[key.NodePublic]mono.Time{} // TODO: only recreate this if set of keys changed @@ -859,6 +947,32 @@ func hasOverlap(aips, rips views.Slice[netip.Prefix]) bool { return false } +// ResetAndStop resets the engine to a clean state (like calling Reconfig +// with all pointers to zero values) and waits for it to be fully stopped, +// with no live peers or DERPs. +// +// Unlike Reconfig, it does not return ErrNoChanges. +// +// If the engine stops, returns the status. NB that this status will not be sent +// to the registered status callback, it is on the caller to ensure this status +// is handled appropriately. +func (e *userspaceEngine) ResetAndStop() (*Status, error) { + if err := e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{}); err != nil && !errors.Is(err, ErrNoChanges) { + return nil, err + } + bo := backoff.NewBackoff("UserspaceEngineResetAndStop", e.logf, 1*time.Second) + for { + st, err := e.getStatus() + if err != nil { + return nil, err + } + if len(st.Peers) == 0 && st.DERPs == 0 { + return st, nil + } + bo.BackOff(context.Background(), fmt.Errorf("waiting for engine to stop: peers=%d derps=%d", len(st.Peers), st.DERPs)) + } +} + func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *dns.Config) error { if routerCfg == nil { panic("routerCfg must not be nil") @@ -872,15 +986,17 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, e.wgLock.Lock() defer e.wgLock.Unlock() e.tundev.SetWGConfig(cfg) - e.lastDNSConfig = dnsCfg peerSet := make(set.Set[key.NodePublic], len(cfg.Peers)) + e.mu.Lock() - e.peerSequence = e.peerSequence[:0] + seq := make([]key.NodePublic, 0, len(cfg.Peers)) for _, p := range cfg.Peers { - e.peerSequence = append(e.peerSequence, p.PublicKey) + seq = append(seq, p.PublicKey) peerSet.Add(p.PublicKey) } + e.peerSequence = views.SliceOf(seq) + nm := e.netMap e.mu.Unlock() @@ -892,22 +1008,24 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, peerMTUEnable := e.magicConn.ShouldPMTUD() isSubnetRouter := false - if e.birdClient != nil && nm != nil && nm.SelfNode.Valid() { + if buildfeatures.HasBird && e.birdClient != nil && nm != nil && nm.SelfNode.Valid() { isSubnetRouter = hasOverlap(nm.SelfNode.PrimaryRoutes(), nm.SelfNode.Hostinfo().RoutableIPs()) e.logf("[v1] Reconfig: hasOverlap(%v, %v) = %v; isSubnetRouter=%v lastIsSubnetRouter=%v", nm.SelfNode.PrimaryRoutes(), nm.SelfNode.Hostinfo().RoutableIPs(), isSubnetRouter, isSubnetRouter, e.lastIsSubnetRouter) } - isSubnetRouterChanged := isSubnetRouter != e.lastIsSubnetRouter + isSubnetRouterChanged := buildfeatures.HasAdvertiseRoutes && isSubnetRouter != e.lastIsSubnetRouter + + engineChanged := checkchange.Update(&e.lastEngineFull, cfg) + routerChanged := checkchange.Update(&e.lastRouter, routerCfg) + dnsChanged := buildfeatures.HasDNS && !e.lastDNSConfig.Equal(dnsCfg.View()) + if dnsChanged { + e.lastDNSConfig = dnsCfg.View() + } - engineChanged := deephash.Update(&e.lastEngineSigFull, cfg) - routerChanged := deephash.Update(&e.lastRouterSig, &struct { - RouterConfig *router.Config - DNSConfig *dns.Config - }{routerCfg, dnsCfg}) listenPortChanged := listenPort != e.magicConn.LocalPort() peerMTUChanged := peerMTUEnable != e.magicConn.PeerMTUEnabled() - if !engineChanged && !routerChanged && !listenPortChanged && !isSubnetRouterChanged && !peerMTUChanged { + if !engineChanged && !routerChanged && !dnsChanged && !listenPortChanged && !isSubnetRouterChanged && !peerMTUChanged { return ErrNoChanges } newLogIDs := cfg.NetworkLogging @@ -916,7 +1034,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, netLogIDsWasValid := !oldLogIDs.NodeID.IsZero() && !oldLogIDs.DomainID.IsZero() netLogIDsChanged := netLogIDsNowValid && netLogIDsWasValid && newLogIDs != oldLogIDs netLogRunning := netLogIDsNowValid && !routerCfg.Equal(&router.Config{}) - if envknob.NoLogsNoSupport() { + if !buildfeatures.HasNetLog || envknob.NoLogsNoSupport() { netLogRunning = false } @@ -925,7 +1043,9 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, // instead have ipnlocal populate a map of DNS IP => linkName and // put that in the *dns.Config instead, and plumb it down to the // dns.Manager. Maybe also with isLocalAddr above. - e.isDNSIPOverTailscale.Store(ipset.NewContainsIPFunc(views.SliceOf(dnsIPsOverTailscale(dnsCfg, routerCfg)))) + if buildfeatures.HasDNS { + e.isDNSIPOverTailscale.Store(ipset.NewContainsIPFunc(views.SliceOf(dnsIPsOverTailscale(dnsCfg, routerCfg)))) + } // See if any peers have changed disco keys, which means they've restarted. // If so, we need to update the wireguard-go/device.Device in two phases: @@ -971,7 +1091,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, // Shutdown the network logger because the IDs changed. // Let it be started back up by subsequent logic. - if netLogIDsChanged && e.networkLogger.Running() { + if buildfeatures.HasNetLog && netLogIDsChanged && e.networkLogger.Running() { e.logf("wgengine: Reconfig: shutting down network logger") ctx, cancel := context.WithTimeout(context.Background(), networkLoggerUploadTimeout) defer cancel() @@ -982,12 +1102,12 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, // Startup the network logger. // Do this before configuring the router so that we capture initial packets. - if netLogRunning && !e.networkLogger.Running() { + if buildfeatures.HasNetLog && netLogRunning && !e.networkLogger.Running() { nid := cfg.NetworkLogging.NodeID tid := cfg.NetworkLogging.DomainID logExitFlowEnabled := cfg.NetworkLogging.LogExitFlowEnabled e.logf("wgengine: Reconfig: starting up network logger (node:%s tailnet:%s)", nid.Public(), tid.Public()) - if err := e.networkLogger.Startup(cfg.NodeID, nid, tid, e.tundev, e.magicConn, e.netMon, e.health, logExitFlowEnabled); err != nil { + if err := e.networkLogger.Startup(e.logf, nm, nid, tid, e.tundev, e.magicConn, e.netMon, e.health, e.eventBus, logExitFlowEnabled); err != nil { e.logf("wgengine: Reconfig: error starting up network logger: %v", err) } e.networkLogger.ReconfigRoutes(routerCfg) @@ -1001,11 +1121,30 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, if err != nil { return err } + } + + // We've historically re-set DNS even after just a router change. While + // refactoring in tailscale/tailscale#17448 and and + // tailscale/tailscale#17499, I'm erring on the side of keeping that + // historical quirk for now (2025-10-08), lest it's load bearing in + // unexpected ways + // + // TODO(bradfitz): try to do the "configuring DNS" part below only if + // dnsChanged, not routerChanged. The "resolver.ShouldUseRoutes" part + // probably needs to keep happening for both. + if buildfeatures.HasDNS && (routerChanged || dnsChanged) { + if resolver.ShouldUseRoutes(e.controlKnobs) { + e.logf("wgengine: Reconfig: user dialer") + e.dialer.SetRoutes(routerCfg.Routes, routerCfg.LocalRoutes) + } else { + e.dialer.SetRoutes(nil, nil) + } + // Keep DNS configuration after router configuration, as some // DNS managers refuse to apply settings if the device has no // assigned address. e.logf("wgengine: Reconfig: configuring DNS") - err = e.dns.Set(*dnsCfg) + err := e.dns.Set(*dnsCfg) e.health.SetDNSHealth(err) if err != nil { return err @@ -1027,7 +1166,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, } } - if isSubnetRouterChanged && e.birdClient != nil { + if buildfeatures.HasBird && isSubnetRouterChanged && e.birdClient != nil { e.logf("wgengine: Reconfig: configuring BIRD") var err error if isSubnetRouter { @@ -1112,7 +1251,7 @@ func (e *userspaceEngine) getStatus() (*Status, error) { e.mu.Lock() closing := e.closing - peerKeys := slices.Clone(e.peerSequence) + peerKeys := e.peerSequence localAddrs := slices.Clone(e.endpoints) e.mu.Unlock() @@ -1120,8 +1259,8 @@ func (e *userspaceEngine) getStatus() (*Status, error) { return nil, ErrEngineClosing } - peers := make([]ipnstate.PeerStatusLite, 0, len(peerKeys)) - for _, key := range peerKeys { + peers := make([]ipnstate.PeerStatusLite, 0, peerKeys.Len()) + for _, key := range peerKeys.All() { if status, ok := e.getPeerStatusLite(key); ok { peers = append(peers, status) } @@ -1170,6 +1309,10 @@ func (e *userspaceEngine) RequestStatus() { } func (e *userspaceEngine) Close() { + e.eventClient.Close() + // TODO(cmol): Should we wait for it too? + // Same question raised in appconnector.go. + e.linkChangeQueue.Shutdown() e.mu.Lock() if e.closing { e.mu.Unlock() @@ -1181,7 +1324,6 @@ func (e *userspaceEngine) Close() { r := bufio.NewReader(strings.NewReader("")) e.wgdev.IpcSetOperation(r) e.magicConn.Close() - e.netMonUnregister() if e.netMonOwned { e.netMon.Close() } @@ -1207,20 +1349,18 @@ func (e *userspaceEngine) Done() <-chan struct{} { } func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) { - changed := delta.Major // TODO(bradfitz): ask more specific questions? - cur := delta.New - up := cur.AnyInterfaceUp() + + up := delta.AnyInterfaceUp() if !up { - e.logf("LinkChange: all links down; pausing: %v", cur) - } else if changed { - e.logf("LinkChange: major, rebinding. New state: %v", cur) + e.logf("LinkChange: all links down; pausing: %v", delta.StateDesc()) + } else if delta.RebindLikelyRequired { + e.logf("LinkChange: major, rebinding: %v", delta.StateDesc()) } else { e.logf("[v1] LinkChange: minor") } e.health.SetAnyInterfaceUp(up) - e.magicConn.SetNetworkUp(up) - if !up || changed { + if !up || delta.RebindLikelyRequired { if err := e.dns.FlushCaches(); err != nil { e.logf("wgengine: dns flush failed after major link change: %v", err) } @@ -1230,16 +1370,27 @@ func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) { // suspend/resume or whenever NetworkManager is started, it // nukes all systemd-resolved configs. So reapply our DNS // config on major link change. - // TODO: explain why this is ncessary not just on Linux but also android - // and Apple platforms. - if changed { + // + // On Darwin (netext), we reapply the DNS config when the interface flaps + // because the change in interface can potentially change the nameservers + // for the forwarder. On Darwin netext clients, magicDNS is ~always the default + // resolver so having no nameserver to forward queries to (or one on a network we + // are not currently on) breaks DNS resolution system-wide. There are notable + // timing issues here with Darwin's network stack. It is not guaranteed that + // the forward resolver will be available immediately after the interface + // comes up. We leave it to the network extension to also poke magicDNS directly + // via [dns.Manager.RecompileDNSConfig] when it detects any change in the + // nameservers. + // + // TODO: On Android, Darwin-tailscaled, and openbsd, why do we need this? + if delta.RebindLikelyRequired && up { switch runtime.GOOS { case "linux", "android", "ios", "darwin", "openbsd": e.wgLock.Lock() dnsCfg := e.lastDNSConfig e.wgLock.Unlock() - if dnsCfg != nil { - if err := e.dns.Set(*dnsCfg); err != nil { + if dnsCfg.Valid() { + if err := e.dns.Set(*dnsCfg.AsStruct()); err != nil { e.logf("wgengine: error setting DNS config after major link change: %v", err) } else if err := e.reconfigureVPNIfNecessary(); err != nil { e.logf("wgengine: error reconfiguring VPN after major link change: %v", err) @@ -1250,22 +1401,32 @@ func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) { } } + e.magicConn.SetNetworkUp(up) + why := "link-change-minor" - if changed { + if delta.RebindLikelyRequired { why = "link-change-major" metricNumMajorChanges.Add(1) - e.magicConn.Rebind() } else { metricNumMinorChanges.Add(1) } - e.magicConn.ReSTUN(why) + + // If we're up and it's a minor change, just send a STUN ping + if up { + if delta.RebindLikelyRequired { + e.magicConn.Rebind() + } + e.magicConn.ReSTUN(why) + } } func (e *userspaceEngine) SetNetworkMap(nm *netmap.NetworkMap) { - e.magicConn.SetNetworkMap(nm) e.mu.Lock() e.netMap = nm e.mu.Unlock() + if e.networkLogger.Running() { + e.networkLogger.ReconfigNetworkMap(nm) + } } func (e *userspaceEngine) UpdateStatus(sb *ipnstate.StatusBuilder) { @@ -1311,6 +1472,7 @@ func (e *userspaceEngine) Ping(ip netip.Addr, pingType tailcfg.PingType, size in e.magicConn.Ping(peer, res, size, cb) case "TSMP": e.sendTSMPPing(ip, peer, res, cb) + e.sendTSMPDiscoAdvertisement(ip) case "ICMP": e.sendICMPEchoRequest(ip, peer, res, cb) } @@ -1431,6 +1593,29 @@ func (e *userspaceEngine) sendTSMPPing(ip netip.Addr, peer tailcfg.NodeView, res e.tundev.InjectOutbound(tsmpPing) } +func (e *userspaceEngine) sendTSMPDiscoAdvertisement(ip netip.Addr) { + srcIP, err := e.mySelfIPMatchingFamily(ip) + if err != nil { + e.logf("getting matching node: %s", err) + return + } + tdka := packet.TSMPDiscoKeyAdvertisement{ + Src: srcIP, + Dst: ip, + Key: e.magicConn.DiscoPublicKey(), + } + payload, err := tdka.Marshal() + if err != nil { + e.logf("error generating TSMP Advertisement: %s", err) + metricTSMPDiscoKeyAdvertisementError.Add(1) + } else if err := e.tundev.InjectOutbound(payload); err != nil { + e.logf("error sending TSMP Advertisement: %s", err) + metricTSMPDiscoKeyAdvertisementError.Add(1) + } else { + metricTSMPDiscoKeyAdvertisementSent.Add(1) + } +} + func (e *userspaceEngine) setTSMPPongCallback(data [8]byte, cb func(packet.TSMPPongReply)) { e.mu.Lock() defer e.mu.Unlock() @@ -1580,6 +1765,12 @@ type fwdDNSLinkSelector struct { } func (ls fwdDNSLinkSelector) PickLink(ip netip.Addr) (linkName string) { + // sandboxed macOS does not automatically bind to the loopback interface so + // we must be explicit about it. + if runtime.GOOS == "darwin" && ip.IsLoopback() { + return "lo0" + } + if ls.ue.isDNSIPOverTailscale.Load()(ip) { return ls.tunName } @@ -1591,9 +1782,15 @@ var ( metricNumMajorChanges = clientmetric.NewCounter("wgengine_major_changes") metricNumMinorChanges = clientmetric.NewCounter("wgengine_minor_changes") + + metricTSMPDiscoKeyAdvertisementSent = clientmetric.NewCounter("magicsock_tsmp_disco_key_advertisement_sent") + metricTSMPDiscoKeyAdvertisementError = clientmetric.NewCounter("magicsock_tsmp_disco_key_advertisement_error") ) func (e *userspaceEngine) InstallCaptureHook(cb packet.CaptureCallback) { + if !buildfeatures.HasCapture { + return + } e.tundev.InstallCaptureHook(cb) e.magicConn.InstallCaptureHook(cb) } diff --git a/vendor/tailscale.com/wgengine/watchdog.go b/vendor/tailscale.com/wgengine/watchdog.go index 74a1917..9cc4ed3 100644 --- a/vendor/tailscale.com/wgengine/watchdog.go +++ b/vendor/tailscale.com/wgengine/watchdog.go @@ -1,7 +1,7 @@ // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause -//go:build !js +//go:build !js && !ts_omit_debug package wgengine @@ -15,6 +15,7 @@ import ( "time" "tailscale.com/envknob" + "tailscale.com/feature/buildfeatures" "tailscale.com/ipn/ipnstate" "tailscale.com/net/dns" "tailscale.com/net/packet" @@ -123,6 +124,12 @@ func (e *watchdogEngine) watchdog(name string, fn func()) { func (e *watchdogEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *dns.Config) error { return e.watchdogErr("Reconfig", func() error { return e.wrap.Reconfig(cfg, routerCfg, dnsCfg) }) } +func (e *watchdogEngine) ResetAndStop() (st *Status, err error) { + e.watchdog("ResetAndStop", func() { + st, err = e.wrap.ResetAndStop() + }) + return st, err +} func (e *watchdogEngine) GetFilter() *filter.Filter { return e.wrap.GetFilter() } @@ -163,6 +170,9 @@ func (e *watchdogEngine) Done() <-chan struct{} { } func (e *watchdogEngine) InstallCaptureHook(cb packet.CaptureCallback) { + if !buildfeatures.HasCapture { + return + } e.wrap.InstallCaptureHook(cb) } diff --git a/vendor/tailscale.com/wgengine/watchdog_js.go b/vendor/tailscale.com/wgengine/watchdog_js.go deleted file mode 100644 index 872ce36..0000000 --- a/vendor/tailscale.com/wgengine/watchdog_js.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build js - -package wgengine - -import "tailscale.com/net/dns/resolver" - -type watchdogEngine struct { - Engine - wrap Engine -} - -func (e *watchdogEngine) GetResolver() (r *resolver.Resolver, ok bool) { - return nil, false -} diff --git a/vendor/tailscale.com/wgengine/watchdog_omit.go b/vendor/tailscale.com/wgengine/watchdog_omit.go new file mode 100644 index 0000000..1d175b4 --- /dev/null +++ b/vendor/tailscale.com/wgengine/watchdog_omit.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build js || ts_omit_debug + +package wgengine + +func NewWatchdog(e Engine) Engine { return e } diff --git a/vendor/tailscale.com/wgengine/wgcfg/config.go b/vendor/tailscale.com/wgengine/wgcfg/config.go index 154dc0a..2734f6c 100644 --- a/vendor/tailscale.com/wgengine/wgcfg/config.go +++ b/vendor/tailscale.com/wgengine/wgcfg/config.go @@ -6,8 +6,8 @@ package wgcfg import ( "net/netip" + "slices" - "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/logid" ) @@ -17,8 +17,6 @@ import ( // Config is a WireGuard configuration. // It only supports the set of things Tailscale uses. type Config struct { - Name string - NodeID tailcfg.StableNodeID PrivateKey key.NodePrivate Addresses []netip.Prefix MTU uint16 @@ -35,6 +33,18 @@ type Config struct { } } +func (c *Config) Equal(o *Config) bool { + if c == nil || o == nil { + return c == o + } + return c.PrivateKey.Equal(o.PrivateKey) && + c.MTU == o.MTU && + c.NetworkLogging == o.NetworkLogging && + slices.Equal(c.Addresses, o.Addresses) && + slices.Equal(c.DNS, o.DNS) && + slices.EqualFunc(c.Peers, o.Peers, Peer.Equal) +} + type Peer struct { PublicKey key.NodePublic DiscoKey key.DiscoPublic // present only so we can handle restarts within wgengine, not passed to WireGuard @@ -50,6 +60,24 @@ type Peer struct { WGEndpoint key.NodePublic } +func addrPtrEq(a, b *netip.Addr) bool { + if a == nil || b == nil { + return a == b + } + return *a == *b +} + +func (p Peer) Equal(o Peer) bool { + return p.PublicKey == o.PublicKey && + p.DiscoKey == o.DiscoKey && + slices.Equal(p.AllowedIPs, o.AllowedIPs) && + p.IsJailed == o.IsJailed && + p.PersistentKeepalive == o.PersistentKeepalive && + addrPtrEq(p.V4MasqAddr, o.V4MasqAddr) && + addrPtrEq(p.V6MasqAddr, o.V6MasqAddr) && + p.WGEndpoint == o.WGEndpoint +} + // PeerWithKey returns the Peer with key k and reports whether it was found. func (config Config) PeerWithKey(k key.NodePublic) (Peer, bool) { for _, p := range config.Peers { diff --git a/vendor/tailscale.com/wgengine/wgcfg/device.go b/vendor/tailscale.com/wgengine/wgcfg/device.go index 80fa159..ee7eb91 100644 --- a/vendor/tailscale.com/wgengine/wgcfg/device.go +++ b/vendor/tailscale.com/wgengine/wgcfg/device.go @@ -4,6 +4,7 @@ package wgcfg import ( + "errors" "io" "sort" @@ -11,7 +12,6 @@ import ( "github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/tun" "tailscale.com/types/logger" - "tailscale.com/util/multierr" ) // NewDevice returns a wireguard-go Device configured for Tailscale use. @@ -31,7 +31,7 @@ func DeviceConfig(d *device.Device) (*Config, error) { cfg, fromErr := FromUAPI(r) r.Close() getErr := <-errc - err := multierr.New(getErr, fromErr) + err := errors.Join(getErr, fromErr) if err != nil { return nil, err } @@ -64,5 +64,5 @@ func ReconfigDevice(d *device.Device, cfg *Config, logf logger.Logf) (err error) toErr := cfg.ToUAPI(logf, w, prev) w.Close() setErr := <-errc - return multierr.New(setErr, toErr) + return errors.Join(setErr, toErr) } diff --git a/vendor/tailscale.com/wgengine/wgcfg/nmcfg/nmcfg.go b/vendor/tailscale.com/wgengine/wgcfg/nmcfg/nmcfg.go index 1add608..a428273 100644 --- a/vendor/tailscale.com/wgengine/wgcfg/nmcfg/nmcfg.go +++ b/vendor/tailscale.com/wgengine/wgcfg/nmcfg/nmcfg.go @@ -5,12 +5,15 @@ package nmcfg import ( - "bytes" + "bufio" + "cmp" "fmt" "net/netip" "strings" + "tailscale.com/net/tsaddr" "tailscale.com/tailcfg" + "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/logid" "tailscale.com/types/netmap" @@ -18,16 +21,7 @@ import ( ) func nodeDebugName(n tailcfg.NodeView) string { - name := n.Name() - if name == "" { - name = n.Hostinfo().Hostname() - } - if i := strings.Index(name, "."); i != -1 { - name = name[:i] - } - if name == "" && n.Addresses().Len() != 0 { - return n.Addresses().At(0).String() - } + name, _, _ := strings.Cut(cmp.Or(n.Name(), n.Hostinfo().Hostname()), ".") return name } @@ -40,6 +34,9 @@ func cidrIsSubnet(node tailcfg.NodeView, cidr netip.Prefix) bool { if !cidr.IsSingleIP() { return true } + if tsaddr.IsTailscaleIP(cidr.Addr()) { + return false + } for _, selfCIDR := range node.Addresses().All() { if cidr == selfCIDR { return false @@ -49,17 +46,15 @@ func cidrIsSubnet(node tailcfg.NodeView, cidr netip.Prefix) bool { } // WGCfg returns the NetworkMaps's WireGuard configuration. -func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, exitNode tailcfg.StableNodeID) (*wgcfg.Config, error) { +func WGCfg(pk key.NodePrivate, nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, exitNode tailcfg.StableNodeID) (*wgcfg.Config, error) { cfg := &wgcfg.Config{ - Name: "tailscale", - PrivateKey: nm.PrivateKey, + PrivateKey: pk, Addresses: nm.GetAddresses().AsSlice(), Peers: make([]wgcfg.Peer, 0, len(nm.Peers)), } // Setup log IDs for data plane audit logging. if nm.SelfNode.Valid() { - cfg.NodeID = nm.SelfNode.StableID() canNetworkLog := nm.SelfNode.HasCap(tailcfg.CapabilityDataPlaneAuditLogs) logExitFlowEnabled := nm.SelfNode.HasCap(tailcfg.NodeAttrLogExitFlows) if canNetworkLog && nm.SelfNode.DataPlaneAuditLogID() != "" && nm.DomainAuditLogID != "" { @@ -79,10 +74,7 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, } } - // Logging buffers - skippedUnselected := new(bytes.Buffer) - skippedSubnets := new(bytes.Buffer) - skippedExpired := new(bytes.Buffer) + var skippedExitNode, skippedSubnetRouter, skippedExpired []tailcfg.NodeView for _, peer := range nm.Peers { if peer.DiscoKey().IsZero() && peer.HomeDERP() == 0 && !peer.IsWireGuardOnly() { @@ -95,16 +87,7 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, // anyway, since control intentionally breaks node keys for // expired peers so that we can't discover endpoints via DERP. if peer.Expired() { - if skippedExpired.Len() >= 1<<10 { - if !bytes.HasSuffix(skippedExpired.Bytes(), []byte("...")) { - skippedExpired.WriteString("...") - } - } else { - if skippedExpired.Len() > 0 { - skippedExpired.WriteString(", ") - } - fmt.Fprintf(skippedExpired, "%s/%v", peer.StableID(), peer.Key().ShortString()) - } + skippedExpired = append(skippedExpired, peer) continue } @@ -114,28 +97,22 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, }) cpeer := &cfg.Peers[len(cfg.Peers)-1] - didExitNodeWarn := false + didExitNodeLog := false cpeer.V4MasqAddr = peer.SelfNodeV4MasqAddrForThisPeer().Clone() cpeer.V6MasqAddr = peer.SelfNodeV6MasqAddrForThisPeer().Clone() cpeer.IsJailed = peer.IsJailed() for _, allowedIP := range peer.AllowedIPs().All() { if allowedIP.Bits() == 0 && peer.StableID() != exitNode { - if didExitNodeWarn { + if didExitNodeLog { // Don't log about both the IPv4 /0 and IPv6 /0. continue } - didExitNodeWarn = true - if skippedUnselected.Len() > 0 { - skippedUnselected.WriteString(", ") - } - fmt.Fprintf(skippedUnselected, "%q (%v)", nodeDebugName(peer), peer.Key().ShortString()) + didExitNodeLog = true + skippedExitNode = append(skippedExitNode, peer) continue } else if cidrIsSubnet(peer, allowedIP) { if (flags & netmap.AllowSubnetRoutes) == 0 { - if skippedSubnets.Len() > 0 { - skippedSubnets.WriteString(", ") - } - fmt.Fprintf(skippedSubnets, "%v from %q (%v)", allowedIP, nodeDebugName(peer), peer.Key().ShortString()) + skippedSubnetRouter = append(skippedSubnetRouter, peer) continue } } @@ -143,14 +120,27 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, } } - if skippedUnselected.Len() > 0 { - logf("[v1] wgcfg: skipped unselected default routes from: %s", skippedUnselected.Bytes()) - } - if skippedSubnets.Len() > 0 { - logf("[v1] wgcfg: did not accept subnet routes: %s", skippedSubnets) - } - if skippedExpired.Len() > 0 { - logf("[v1] wgcfg: skipped expired peer: %s", skippedExpired) + logList := func(title string, nodes []tailcfg.NodeView) { + if len(nodes) == 0 { + return + } + logf("[v1] wgcfg: %s from %d nodes: %s", title, len(nodes), logger.ArgWriter(func(bw *bufio.Writer) { + const max = 5 + for i, n := range nodes { + if i == max { + fmt.Fprintf(bw, "... +%d", len(nodes)-max) + return + } + if i > 0 { + bw.WriteString(", ") + } + fmt.Fprintf(bw, "%s (%s)", nodeDebugName(n), n.StableID()) + } + })) } + logList("skipped unselected exit nodes", skippedExitNode) + logList("did not accept subnet routes", skippedSubnetRouter) + logList("skipped expired peers", skippedExpired) + return cfg, nil } diff --git a/vendor/tailscale.com/wgengine/wgcfg/wgcfg_clone.go b/vendor/tailscale.com/wgengine/wgcfg/wgcfg_clone.go index 749d8d8..9f3cabd 100644 --- a/vendor/tailscale.com/wgengine/wgcfg/wgcfg_clone.go +++ b/vendor/tailscale.com/wgengine/wgcfg/wgcfg_clone.go @@ -8,7 +8,6 @@ package wgcfg import ( "net/netip" - "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/types/logid" "tailscale.com/types/ptr" @@ -35,8 +34,6 @@ func (src *Config) Clone() *Config { // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _ConfigCloneNeedsRegeneration = Config(struct { - Name string - NodeID tailcfg.StableNodeID PrivateKey key.NodePrivate Addresses []netip.Prefix MTU uint16 diff --git a/vendor/tailscale.com/wgengine/wgengine.go b/vendor/tailscale.com/wgengine/wgengine.go index 6aaf567..be78731 100644 --- a/vendor/tailscale.com/wgengine/wgengine.go +++ b/vendor/tailscale.com/wgengine/wgengine.go @@ -69,6 +69,13 @@ type Engine interface { // The returned error is ErrNoChanges if no changes were made. Reconfig(*wgcfg.Config, *router.Config, *dns.Config) error + // ResetAndStop resets the engine to a clean state (like calling Reconfig + // with all pointers to zero values) and waits for it to be fully stopped, + // with no live peers or DERPs. + // + // Unlike Reconfig, it does not return ErrNoChanges. + ResetAndStop() (*Status, error) + // PeerForIP returns the node to which the provided IP routes, // if any. If none is found, (nil, false) is returned. PeerForIP(netip.Addr) (_ PeerForIP, ok bool) diff --git a/vendor/tailscale.com/wgengine/winnet/winnet.go b/vendor/tailscale.com/wgengine/winnet/winnet.go deleted file mode 100644 index e04e6f5..0000000 --- a/vendor/tailscale.com/wgengine/winnet/winnet.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -//go:build windows - -// Package winnet contains Windows-specific networking code. -package winnet - -import ( - "fmt" - "syscall" - "unsafe" - - "github.com/go-ole/go-ole" - "github.com/go-ole/go-ole/oleutil" -) - -const CLSID_NetworkListManager = "{DCB00C01-570F-4A9B-8D69-199FDBA5723B}" - -var IID_INetwork = ole.NewGUID("{8A40A45D-055C-4B62-ABD7-6D613E2CEAEC}") -var IID_INetworkConnection = ole.NewGUID("{DCB00005-570F-4A9B-8D69-199FDBA5723B}") - -type NetworkListManager struct { - d *ole.Dispatch -} - -type INetworkConnection struct { - ole.IDispatch -} - -type ConnectionList []*INetworkConnection - -type INetworkConnectionVtbl struct { - ole.IDispatchVtbl - GetNetwork uintptr - Get_IsConnectedToInternet uintptr - Get_IsConnected uintptr - GetConnectivity uintptr - GetConnectionId uintptr - GetAdapterId uintptr - GetDomainType uintptr -} - -type INetwork struct { - ole.IDispatch -} - -type INetworkVtbl struct { - ole.IDispatchVtbl - GetName uintptr - SetName uintptr - GetDescription uintptr - SetDescription uintptr - GetNetworkId uintptr - GetDomainType uintptr - GetNetworkConnections uintptr - GetTimeCreatedAndConnected uintptr - Get_IsConnectedToInternet uintptr - Get_IsConnected uintptr - GetConnectivity uintptr - GetCategory uintptr - SetCategory uintptr -} - -func NewNetworkListManager(c *ole.Connection) (*NetworkListManager, error) { - err := c.Create(CLSID_NetworkListManager) - if err != nil { - return nil, err - } - defer c.Release() - - d, err := c.Dispatch() - if err != nil { - return nil, err - } - - return &NetworkListManager{ - d: d, - }, nil -} - -func (m *NetworkListManager) Release() { - m.d.Release() -} - -func (cl ConnectionList) Release() { - for _, v := range cl { - v.Release() - } -} - -func asIID(u ole.UnknownLike, iid *ole.GUID) (*ole.IDispatch, error) { - if u == nil { - return nil, fmt.Errorf("asIID: nil UnknownLike") - } - - d, err := u.QueryInterface(iid) - u.Release() - if err != nil { - return nil, err - } - return d, nil -} - -func (m *NetworkListManager) GetNetworkConnections() (ConnectionList, error) { - ncraw, err := m.d.Call("GetNetworkConnections") - if err != nil { - return nil, err - } - - nli := ncraw.ToIDispatch() - if nli == nil { - return nil, fmt.Errorf("GetNetworkConnections: not IDispatch") - } - - cl := ConnectionList{} - - err = oleutil.ForEach(nli, func(v *ole.VARIANT) error { - nc, err := asIID(v.ToIUnknown(), IID_INetworkConnection) - if err != nil { - return err - } - nco := (*INetworkConnection)(unsafe.Pointer(nc)) - cl = append(cl, nco) - return nil - }) - - if err != nil { - cl.Release() - return nil, err - } - return cl, nil -} - -func (n *INetwork) GetName() (string, error) { - v, err := n.CallMethod("GetName") - if err != nil { - return "", err - } - return v.ToString(), err -} - -func (n *INetwork) GetCategory() (int32, error) { - var result int32 - - r, _, _ := syscall.SyscallN( - n.VTable().GetCategory, - uintptr(unsafe.Pointer(n)), - uintptr(unsafe.Pointer(&result)), - ) - if int32(r) < 0 { - return 0, ole.NewError(r) - } - - return result, nil -} - -func (n *INetwork) SetCategory(v int32) error { - r, _, _ := syscall.SyscallN( - n.VTable().SetCategory, - uintptr(unsafe.Pointer(n)), - uintptr(v), - ) - if int32(r) < 0 { - return ole.NewError(r) - } - - return nil -} - -func (n *INetwork) VTable() *INetworkVtbl { - return (*INetworkVtbl)(unsafe.Pointer(n.RawVTable)) -} - -func (v *INetworkConnection) VTable() *INetworkConnectionVtbl { - return (*INetworkConnectionVtbl)(unsafe.Pointer(v.RawVTable)) -} - -func (v *INetworkConnection) GetNetwork() (*INetwork, error) { - var result *INetwork - - r, _, _ := syscall.SyscallN( - v.VTable().GetNetwork, - uintptr(unsafe.Pointer(v)), - uintptr(unsafe.Pointer(&result)), - ) - if int32(r) < 0 { - return nil, ole.NewError(r) - } - - return result, nil -} diff --git a/vendor/tailscale.com/wgengine/winnet/winnet_windows.go b/vendor/tailscale.com/wgengine/winnet/winnet_windows.go deleted file mode 100644 index 283ce5a..0000000 --- a/vendor/tailscale.com/wgengine/winnet/winnet_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package winnet - -import ( - "fmt" - "syscall" - "unsafe" - - "github.com/go-ole/go-ole" -) - -func (v *INetworkConnection) GetAdapterId() (string, error) { - buf := ole.GUID{} - hr, _, _ := syscall.Syscall( - v.VTable().GetAdapterId, - 2, - uintptr(unsafe.Pointer(v)), - uintptr(unsafe.Pointer(&buf)), - 0) - if hr != 0 { - return "", fmt.Errorf("GetAdapterId failed: %08x", hr) - } - return buf.String(), nil -} diff --git a/vendor/tailscale.com/wif/wif.go b/vendor/tailscale.com/wif/wif.go new file mode 100644 index 0000000..557685c --- /dev/null +++ b/vendor/tailscale.com/wif/wif.go @@ -0,0 +1,242 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package wif deals with obtaining ID tokens from provider VMs +// to be used as part of Workload Identity Federation +package wif + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" + "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/aws/smithy-go" + "tailscale.com/util/httpm" +) + +type Environment string + +const ( + EnvGitHub Environment = "github" + EnvAWS Environment = "aws" + EnvGCP Environment = "gcp" + EnvNone Environment = "none" +) + +// ObtainProviderToken tries to detect what provider the client is running in +// and then tries to obtain an ID token for the audience that is passed as an argument +// To detect the environment, we do it in the following intentional order: +// 1. GitHub Actions (strongest env signals; may run atop any cloud) +// 2. AWS via IMDSv2 token endpoint (does not require env vars) +// 3. GCP via metadata header semantics +// 4. Azure via metadata endpoint +func ObtainProviderToken(ctx context.Context, audience string) (string, error) { + env := detectEnvironment(ctx) + + switch env { + case EnvGitHub: + return acquireGitHubActionsIDToken(ctx, audience) + case EnvAWS: + return acquireAWSWebIdentityToken(ctx, audience) + case EnvGCP: + return acquireGCPMetadataIDToken(ctx, audience) + default: + return "", errors.New("could not detect environment; provide --id-token explicitly") + } +} + +func detectEnvironment(ctx context.Context) Environment { + if os.Getenv("ACTIONS_ID_TOKEN_REQUEST_URL") != "" && + os.Getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN") != "" { + return EnvGitHub + } + + client := httpClient() + if detectAWSIMDSv2(ctx, client) { + return EnvAWS + } + if detectGCPMetadata(ctx, client) { + return EnvGCP + } + return EnvNone +} + +func httpClient() *http.Client { + return &http.Client{ + Timeout: time.Second * 5, + } +} + +func detectAWSIMDSv2(ctx context.Context, client *http.Client) bool { + req, err := http.NewRequestWithContext(ctx, httpm.PUT, "http://169.254.169.254/latest/api/token", nil) + if err != nil { + return false + } + req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "1") + + resp, err := client.Do(req) + if err != nil { + return false + } + defer resp.Body.Close() + + return resp.StatusCode == http.StatusOK +} + +func detectGCPMetadata(ctx context.Context, client *http.Client) bool { + req, err := http.NewRequestWithContext(ctx, httpm.GET, "http://metadata.google.internal", nil) + if err != nil { + return false + } + req.Header.Set("Metadata-Flavor", "Google") + + resp, err := client.Do(req) + if err != nil { + return false + } + defer resp.Body.Close() + + return resp.Header.Get("Metadata-Flavor") == "Google" +} + +type githubOIDCResponse struct { + Value string `json:"value"` +} + +func acquireGitHubActionsIDToken(ctx context.Context, audience string) (string, error) { + reqURL := os.Getenv("ACTIONS_ID_TOKEN_REQUEST_URL") + reqTok := os.Getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN") + if reqURL == "" || reqTok == "" { + return "", errors.New("missing ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN (ensure workflow has permissions: id-token: write)") + } + + u, err := url.Parse(reqURL) + if err != nil { + return "", fmt.Errorf("parse ACTIONS_ID_TOKEN_REQUEST_URL: %w", err) + } + if strings.TrimSpace(audience) != "" { + q := u.Query() + q.Set("audience", strings.TrimSpace(audience)) + u.RawQuery = q.Encode() + } + + req, err := http.NewRequestWithContext(ctx, httpm.GET, u.String(), nil) + if err != nil { + return "", fmt.Errorf("build request: %w", err) + } + req.Header.Set("Authorization", "Bearer "+reqTok) + req.Header.Set("Accept", "application/json") + + client := httpClient() + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("request github oidc token: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode/100 != 2 { + b, _ := io.ReadAll(io.LimitReader(resp.Body, 2048)) + return "", fmt.Errorf("github oidc token endpoint returned %s: %s", resp.Status, strings.TrimSpace(string(b))) + } + + var tr githubOIDCResponse + if err := json.NewDecoder(resp.Body).Decode(&tr); err != nil { + return "", fmt.Errorf("decode github oidc response: %w", err) + } + if strings.TrimSpace(tr.Value) == "" { + return "", errors.New("github oidc response contained empty token") + } + + // GitHub response doesn't provide exp directly; caller can parse JWT if needed. + return tr.Value, nil +} + +func acquireAWSWebIdentityToken(ctx context.Context, audience string) (string, error) { + // LoadDefaultConfig wires up the default credential chain (incl. IMDS). + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + return "", fmt.Errorf("load aws config: %w", err) + } + + // Verify credentials are available before proceeding. + if _, err := cfg.Credentials.Retrieve(ctx); err != nil { + return "", fmt.Errorf("AWS credentials unavailable (instance profile/IMDS?): %w", err) + } + + imdsClient := imds.NewFromConfig(cfg) + region, err := imdsClient.GetRegion(ctx, &imds.GetRegionInput{}) + if err != nil { + return "", fmt.Errorf("couldn't get AWS region: %w", err) + } + cfg.Region = region.Region + + stsClient := sts.NewFromConfig(cfg) + in := &sts.GetWebIdentityTokenInput{ + Audience: []string{strings.TrimSpace(audience)}, + SigningAlgorithm: aws.String("ES384"), + DurationSeconds: aws.Int32(300), // 5 minutes + } + + out, err := stsClient.GetWebIdentityToken(ctx, in) + if err != nil { + var apiErr smithy.APIError + if errors.As(err, &apiErr) { + return "", fmt.Errorf("aws sts:GetWebIdentityToken failed (%s): %w", apiErr.ErrorCode(), err) + } + return "", fmt.Errorf("aws sts:GetWebIdentityToken failed: %w", err) + } + + if out.WebIdentityToken == nil || strings.TrimSpace(*out.WebIdentityToken) == "" { + return "", fmt.Errorf("aws sts:GetWebIdentityToken returned empty token") + } + + return *out.WebIdentityToken, nil +} + +func acquireGCPMetadataIDToken(ctx context.Context, audience string) (string, error) { + u := "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity" + v := url.Values{} + v.Set("audience", strings.TrimSpace(audience)) + v.Set("format", "full") + fullURL := u + "?" + v.Encode() + + req, err := http.NewRequestWithContext(ctx, httpm.GET, fullURL, nil) + if err != nil { + return "", fmt.Errorf("build request: %w", err) + } + req.Header.Set("Metadata-Flavor", "Google") + + client := httpClient() + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("call gcp metadata identity endpoint: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode/100 != 2 { + b, _ := io.ReadAll(io.LimitReader(resp.Body, 2048)) + return "", fmt.Errorf("gcp metadata identity endpoint returned %s: %s", resp.Status, strings.TrimSpace(string(b))) + } + + b, err := io.ReadAll(io.LimitReader(resp.Body, 1024*1024)) + if err != nil { + return "", fmt.Errorf("read gcp id token: %w", err) + } + jwt := strings.TrimSpace(string(b)) + if jwt == "" { + return "", fmt.Errorf("gcp metadata returned empty token") + } + + return jwt, nil +}